mirror of
https://github.com/docker/docs.git
synced 2026-11-05 00:14:17 +03:00
Merge pull request #572 from docker/per-metadata-type-mutation
Per metadata type mutation tests
This commit is contained in:
@@ -811,6 +811,36 @@ var waysToMessUpServer = []swizzleExpectations{
|
||||
}},
|
||||
}
|
||||
|
||||
var _waysToMessUpServerRoot []swizzleExpectations
|
||||
|
||||
// We also want to remove a every role from root once, or remove the role's keys.
|
||||
// This function generates once and caches the result for later re-use.
|
||||
func waysToMessUpServerRoot() []swizzleExpectations {
|
||||
if _waysToMessUpServerRoot == nil {
|
||||
_waysToMessUpServerRoot = waysToMessUpServer
|
||||
for _, roleName := range data.BaseRoles {
|
||||
_waysToMessUpServerRoot = append(_waysToMessUpServerRoot,
|
||||
swizzleExpectations{
|
||||
desc: fmt.Sprintf("no %s keys", roleName),
|
||||
expectErrs: []interface{}{
|
||||
&certs.ErrValidationFail{}, signed.ErrRoleThreshold{}},
|
||||
swizzle: func(s *testutils.MetadataSwizzler, role string) error {
|
||||
return s.MutateRoot(func(r *data.Root) {
|
||||
r.Roles[roleName].KeyIDs = []string{}
|
||||
})
|
||||
}},
|
||||
swizzleExpectations{
|
||||
desc: fmt.Sprintf("no %s role", roleName),
|
||||
expectErrs: []interface{}{data.ErrInvalidRole{}},
|
||||
swizzle: func(s *testutils.MetadataSwizzler, role string) error {
|
||||
return s.MutateRoot(func(r *data.Root) { delete(r.Roles, roleName) })
|
||||
}},
|
||||
)
|
||||
}
|
||||
}
|
||||
return _waysToMessUpServerRoot
|
||||
}
|
||||
|
||||
// If there's no local cache, we go immediately to check the remote server for
|
||||
// root, and if it invalid (corrupted), we cannot update. This happens
|
||||
// with and without a force check (update for write).
|
||||
@@ -818,7 +848,8 @@ func TestUpdateRootRemoteCorruptedNoLocalCache(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping test in short mode")
|
||||
}
|
||||
for _, testData := range waysToMessUpServer {
|
||||
|
||||
for _, testData := range waysToMessUpServerRoot() {
|
||||
if testData.desc == "insufficient signatures" {
|
||||
// Currently if we download the root during the bootstrap phase,
|
||||
// we don't check for enough signatures to meet the threshold. We
|
||||
@@ -842,7 +873,11 @@ func TestUpdateRootRemoteCorruptedNoLocalCache(t *testing.T) {
|
||||
// because the fact that the timestamp hasn't changed should mean that we don't
|
||||
// have to re-download the root.
|
||||
func TestUpdateRootRemoteCorruptedCanUseLocalCache(t *testing.T) {
|
||||
for _, testData := range waysToMessUpServer {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping test in short mode")
|
||||
}
|
||||
|
||||
for _, testData := range waysToMessUpServerRoot() {
|
||||
testUpdateRemoteCorruptValidChecksum(t, updateOpts{
|
||||
localCache: true,
|
||||
forWrite: false,
|
||||
@@ -862,7 +897,7 @@ func TestUpdateRootRemoteCorruptedCannotUseLocalCache(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping test in short mode")
|
||||
}
|
||||
for _, testData := range waysToMessUpServer {
|
||||
for _, testData := range waysToMessUpServerRoot() {
|
||||
testUpdateRemoteCorruptValidChecksum(t, updateOpts{
|
||||
serverHasNewData: true,
|
||||
localCache: true,
|
||||
@@ -878,6 +913,69 @@ func TestUpdateRootRemoteCorruptedCannotUseLocalCache(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func waysToMessUpServerNonRootPerRole(t *testing.T) map[string][]swizzleExpectations {
|
||||
perRoleSwizzling := make(map[string][]swizzleExpectations)
|
||||
for _, missing := range []string{data.CanonicalRootRole, data.CanonicalTargetsRole} {
|
||||
perRoleSwizzling[data.CanonicalSnapshotRole] = append(
|
||||
perRoleSwizzling[data.CanonicalSnapshotRole],
|
||||
swizzleExpectations{
|
||||
desc: fmt.Sprintf("snapshot missing root meta checksum"),
|
||||
expectErrs: []interface{}{client.ErrMissingMeta{}},
|
||||
swizzle: func(s *testutils.MetadataSwizzler, role string) error {
|
||||
return s.MutateSnapshot(func(sn *data.Snapshot) {
|
||||
delete(sn.Meta, missing)
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
perRoleSwizzling[data.CanonicalTargetsRole] = []swizzleExpectations{{
|
||||
desc: fmt.Sprintf("target missing delegations data"),
|
||||
expectErrs: []interface{}{client.ErrChecksumMismatch{}},
|
||||
swizzle: func(s *testutils.MetadataSwizzler, role string) error {
|
||||
return s.MutateTargets(func(tg *data.Targets) {
|
||||
tg.Delegations.Roles = tg.Delegations.Roles[1:]
|
||||
})
|
||||
},
|
||||
}}
|
||||
perRoleSwizzling[data.CanonicalTimestampRole] = []swizzleExpectations{{
|
||||
desc: fmt.Sprintf("timestamp missing snapshot meta checksum"),
|
||||
expectErrs: []interface{}{client.ErrMissingMeta{}},
|
||||
swizzle: func(s *testutils.MetadataSwizzler, role string) error {
|
||||
return s.MutateTimestamp(func(ts *data.Timestamp) {
|
||||
delete(ts.Meta, data.CanonicalSnapshotRole)
|
||||
})
|
||||
},
|
||||
}}
|
||||
perRoleSwizzling["targets/a"] = []swizzleExpectations{{
|
||||
desc: fmt.Sprintf("delegation has invalid role"),
|
||||
expectErrs: []interface{}{client.ErrMissingMeta{}},
|
||||
swizzle: func(s *testutils.MetadataSwizzler, role string) error {
|
||||
return s.MutateTargets(func(tg *data.Targets) {
|
||||
var keyIDs []string
|
||||
for k := range tg.Delegations.Keys {
|
||||
keyIDs = append(keyIDs, k)
|
||||
}
|
||||
// add the keys from root too
|
||||
rootMeta, err := s.MetadataCache.GetMeta(data.CanonicalRootRole, -1)
|
||||
require.NoError(t, err)
|
||||
|
||||
signedRoot := &data.SignedRoot{}
|
||||
require.NoError(t, json.Unmarshal(rootMeta, signedRoot))
|
||||
|
||||
for k := range signedRoot.Signed.Keys {
|
||||
keyIDs = append(keyIDs, k)
|
||||
}
|
||||
|
||||
// add an invalid role (root) to delegation
|
||||
tg.Delegations.Roles = append(tg.Delegations.Roles,
|
||||
&data.Role{RootRole: data.RootRole{KeyIDs: keyIDs, Threshold: 1},
|
||||
Name: data.CanonicalRootRole})
|
||||
})
|
||||
},
|
||||
}}
|
||||
return perRoleSwizzling
|
||||
}
|
||||
|
||||
// If there's no local cache, we just download from the server and if anything
|
||||
// is corrupt, we cannot update.
|
||||
func TestUpdateNonRootRemoteCorruptedNoLocalCache(t *testing.T) {
|
||||
@@ -894,6 +992,32 @@ func TestUpdateNonRootRemoteCorruptedNoLocalCache(t *testing.T) {
|
||||
}, testData, true)
|
||||
}
|
||||
}
|
||||
for role, expectations := range waysToMessUpServerNonRootPerRole(t) {
|
||||
for _, testData := range expectations {
|
||||
switch role {
|
||||
case data.CanonicalSnapshotRole:
|
||||
testUpdateRemoteCorruptValidChecksum(t, updateOpts{
|
||||
role: role,
|
||||
}, testData, true)
|
||||
case data.CanonicalTargetsRole:
|
||||
// if there are no delegation target roles, we're fine, we just don't
|
||||
// download them
|
||||
testUpdateRemoteCorruptValidChecksum(t, updateOpts{
|
||||
role: role,
|
||||
}, testData, false)
|
||||
case data.CanonicalTimestampRole:
|
||||
testUpdateRemoteCorruptValidChecksum(t, updateOpts{
|
||||
role: role,
|
||||
}, testData, true)
|
||||
case "targets/a":
|
||||
// TODO: Bug where invalid (non-delegation) roles in delegations
|
||||
// are accepted
|
||||
testUpdateRemoteCorruptValidChecksum(t, updateOpts{
|
||||
role: role,
|
||||
}, testData, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Having a local cache, if the server has the same data (timestamp has not changed),
|
||||
@@ -916,6 +1040,37 @@ func TestUpdateNonRootRemoteCorruptedCanUseLocalCache(t *testing.T) {
|
||||
}, testData, false)
|
||||
}
|
||||
}
|
||||
for role, expectations := range waysToMessUpServerNonRootPerRole(t) {
|
||||
for _, testData := range expectations {
|
||||
|
||||
switch role {
|
||||
case data.CanonicalSnapshotRole:
|
||||
testUpdateRemoteCorruptValidChecksum(t, updateOpts{
|
||||
localCache: true,
|
||||
role: role,
|
||||
}, testData, false)
|
||||
case data.CanonicalTargetsRole:
|
||||
testUpdateRemoteCorruptValidChecksum(t, updateOpts{
|
||||
localCache: true,
|
||||
role: role,
|
||||
}, testData, false)
|
||||
case data.CanonicalTimestampRole:
|
||||
// TODO: Bug: this should succeed, because it's an invalid timestamp metadata
|
||||
// and hence should fall back on the the local cached timestamp. It's not
|
||||
// succeeding now because the failure occurs on downloading the snapshot,
|
||||
// not during the validation of the timestamp.
|
||||
testUpdateRemoteCorruptValidChecksum(t, updateOpts{
|
||||
localCache: true,
|
||||
role: role,
|
||||
}, testData, true)
|
||||
case "targets/a":
|
||||
testUpdateRemoteCorruptValidChecksum(t, updateOpts{
|
||||
localCache: true,
|
||||
role: role,
|
||||
}, testData, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Having a local cache, if the server has new same data should fail in all cases
|
||||
@@ -944,6 +1099,41 @@ func TestUpdateNonRootRemoteCorruptedCannotUseLocalCache(t *testing.T) {
|
||||
}, testData, shouldFail)
|
||||
}
|
||||
}
|
||||
|
||||
for role, expectations := range waysToMessUpServerNonRootPerRole(t) {
|
||||
for _, testData := range expectations {
|
||||
switch role {
|
||||
case data.CanonicalSnapshotRole:
|
||||
testUpdateRemoteCorruptValidChecksum(t, updateOpts{
|
||||
serverHasNewData: true,
|
||||
localCache: true,
|
||||
role: role,
|
||||
}, testData, true)
|
||||
case data.CanonicalTargetsRole:
|
||||
// if there are no delegation target roles, we're fine, we just don't
|
||||
// download them
|
||||
testUpdateRemoteCorruptValidChecksum(t, updateOpts{
|
||||
serverHasNewData: true,
|
||||
localCache: true,
|
||||
role: role,
|
||||
}, testData, false)
|
||||
case data.CanonicalTimestampRole:
|
||||
testUpdateRemoteCorruptValidChecksum(t, updateOpts{
|
||||
serverHasNewData: true,
|
||||
localCache: true,
|
||||
role: role,
|
||||
}, testData, true)
|
||||
case "targets/a":
|
||||
// TODO: Bug where invalid (non-delegation) roles in delegations
|
||||
// are accepted
|
||||
testUpdateRemoteCorruptValidChecksum(t, updateOpts{
|
||||
serverHasNewData: true,
|
||||
localCache: true,
|
||||
role: role,
|
||||
}, testData, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testUpdateRemoteCorruptValidChecksum(t *testing.T, opts updateOpts, expt swizzleExpectations, shouldErr bool) {
|
||||
@@ -977,10 +1167,16 @@ func testUpdateRemoteCorruptValidChecksum(t *testing.T, opts updateOpts, expt sw
|
||||
isSignatureSwizzle := expt.desc == "invalid signatures" || expt.desc == "meta signed by wrong key"
|
||||
// just try to do these - if they fail (probably because they've been swizzled), that's fine
|
||||
if opts.role != data.CanonicalSnapshotRole || !isSignatureSwizzle {
|
||||
serverSwizzler.UpdateSnapshotHashes()
|
||||
// if we are purposely editing out some snapshot metadata, don't re-generate
|
||||
if !strings.HasPrefix(expt.desc, "snapshot missing") {
|
||||
serverSwizzler.UpdateSnapshotHashes()
|
||||
}
|
||||
}
|
||||
if opts.role != data.CanonicalTimestampRole || !isSignatureSwizzle {
|
||||
serverSwizzler.UpdateTimestampHash()
|
||||
// if we are purposely editing out some timestamp metadata, don't re-generate
|
||||
if !strings.HasPrefix(expt.desc, "timestamp missing") {
|
||||
serverSwizzler.UpdateTimestampHash()
|
||||
}
|
||||
}
|
||||
}
|
||||
_, err := repo.Update(opts.forWrite)
|
||||
|
||||
@@ -128,8 +128,10 @@ func (c *Client) downloadRoot() error {
|
||||
var size int64 = -1
|
||||
var expectedSha256 []byte
|
||||
if c.local.Snapshot != nil {
|
||||
size = c.local.Snapshot.Signed.Meta[role].Length
|
||||
expectedSha256 = c.local.Snapshot.Signed.Meta[role].Hashes["sha256"]
|
||||
if prevRootMeta, ok := c.local.Snapshot.Signed.Meta[role]; ok {
|
||||
size = prevRootMeta.Length
|
||||
expectedSha256 = prevRootMeta.Hashes["sha256"]
|
||||
}
|
||||
}
|
||||
|
||||
// if we're bootstrapping we may not have a cached root, an
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/docker/notary/cryptoservice"
|
||||
"github.com/docker/notary/passphrase"
|
||||
"github.com/docker/notary/trustmanager"
|
||||
"github.com/docker/notary/tuf"
|
||||
"github.com/docker/notary/tuf/data"
|
||||
"github.com/docker/notary/tuf/signed"
|
||||
"github.com/docker/notary/tuf/store"
|
||||
@@ -41,7 +42,11 @@ func getPubKeys(cs signed.CryptoService, s *data.Signed, role string) ([]data.Pu
|
||||
if err := json.Unmarshal(s.Signed, root); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, pubKeyID := range root.Roles[data.CanonicalRootRole].KeyIDs {
|
||||
rootRole, ok := root.Roles[data.CanonicalRootRole]
|
||||
if !ok || rootRole == nil {
|
||||
return nil, tuf.ErrNotLoaded{}
|
||||
}
|
||||
for _, pubKeyID := range rootRole.KeyIDs {
|
||||
pubKeys = append(pubKeys, root.Keys[pubKeyID])
|
||||
}
|
||||
} else {
|
||||
@@ -532,3 +537,137 @@ func (m *MetadataSwizzler) UpdateTimestampHash() error {
|
||||
}
|
||||
return m.MetadataCache.SetMeta(data.CanonicalTimestampRole, metaBytes)
|
||||
}
|
||||
|
||||
// MutateRoot takes a function that mutates the root metadata - once done, it
|
||||
// serializes the root again
|
||||
func (m *MetadataSwizzler) MutateRoot(mutate func(*data.Root)) error {
|
||||
signedThing, err := signedFromStore(m.MetadataCache, data.CanonicalRootRole)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var root data.Root
|
||||
if err := json.Unmarshal(signedThing.Signed, &root); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// get the original keys, in case the mutation messes with the signing keys
|
||||
oldPubKeys, err := getPubKeys(m.CryptoService, signedThing, data.CanonicalRootRole)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mutate(&root)
|
||||
|
||||
signedThing, err = data.SignedRoot{Signed: root, Signatures: signedThing.Signatures}.ToSigned()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pubKeys, err := getPubKeys(m.CryptoService, signedThing, data.CanonicalRootRole)
|
||||
if err != nil || len(pubKeys) == 0 { // we have to sign it somehow - might as well use the old keys
|
||||
pubKeys = oldPubKeys
|
||||
}
|
||||
|
||||
metaBytes, err := serializeMetadata(m.CryptoService, signedThing, data.CanonicalRootRole, pubKeys...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return m.MetadataCache.SetMeta(data.CanonicalRootRole, metaBytes)
|
||||
}
|
||||
|
||||
// MutateTimestamp takes a function that mutates the timestamp metadata - once done, it
|
||||
// serializes the timestamp again
|
||||
func (m *MetadataSwizzler) MutateTimestamp(mutate func(*data.Timestamp)) error {
|
||||
signedThing, err := signedFromStore(m.MetadataCache, data.CanonicalTimestampRole)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var timestamp data.Timestamp
|
||||
if err := json.Unmarshal(signedThing.Signed, ×tamp); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mutate(×tamp)
|
||||
|
||||
signedThing, err = data.SignedTimestamp{Signed: timestamp, Signatures: signedThing.Signatures}.ToSigned()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pubKeys, err := getPubKeys(m.CryptoService, signedThing, data.CanonicalTimestampRole)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
metaBytes, err := serializeMetadata(m.CryptoService, signedThing, data.CanonicalTimestampRole, pubKeys...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return m.MetadataCache.SetMeta(data.CanonicalTimestampRole, metaBytes)
|
||||
}
|
||||
|
||||
// MutateSnapshot takes a function that mutates the snapshot metadata - once done, it
|
||||
// serializes the snapshot again
|
||||
func (m *MetadataSwizzler) MutateSnapshot(mutate func(*data.Snapshot)) error {
|
||||
signedThing, err := signedFromStore(m.MetadataCache, data.CanonicalSnapshotRole)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var snapshot data.Snapshot
|
||||
if err := json.Unmarshal(signedThing.Signed, &snapshot); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mutate(&snapshot)
|
||||
|
||||
signedThing, err = data.SignedSnapshot{Signed: snapshot, Signatures: signedThing.Signatures}.ToSigned()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pubKeys, err := getPubKeys(m.CryptoService, signedThing, data.CanonicalSnapshotRole)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
metaBytes, err := serializeMetadata(m.CryptoService, signedThing, data.CanonicalSnapshotRole, pubKeys...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return m.MetadataCache.SetMeta(data.CanonicalSnapshotRole, metaBytes)
|
||||
}
|
||||
|
||||
// MutateTargets takes a function that mutates the targets metadata - once done, it
|
||||
// serializes the targets again
|
||||
func (m *MetadataSwizzler) MutateTargets(mutate func(*data.Targets)) error {
|
||||
signedThing, err := signedFromStore(m.MetadataCache, data.CanonicalTargetsRole)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var targets data.Targets
|
||||
if err := json.Unmarshal(signedThing.Signed, &targets); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mutate(&targets)
|
||||
|
||||
signedThing, err = data.SignedTargets{Signed: targets, Signatures: signedThing.Signatures}.ToSigned()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pubKeys, err := getPubKeys(m.CryptoService, signedThing, data.CanonicalTargetsRole)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
metaBytes, err := serializeMetadata(m.CryptoService, signedThing, data.CanonicalTargetsRole, pubKeys...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return m.MetadataCache.SetMeta(data.CanonicalTargetsRole, metaBytes)
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"github.com/docker/notary/tuf/data"
|
||||
"github.com/docker/notary/tuf/signed"
|
||||
"github.com/docker/notary/tuf/store"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
@@ -577,3 +578,95 @@ func TestMissingSigningKey(t *testing.T) {
|
||||
require.IsType(t, ErrNoKeyForRole{}, f.UpdateSnapshotHashes())
|
||||
require.IsType(t, ErrNoKeyForRole{}, f.UpdateTimestampHash())
|
||||
}
|
||||
|
||||
// This mutates the root
|
||||
func TestSwizzlerMutateRoot(t *testing.T) {
|
||||
f, origMeta := createNewSwizzler(t)
|
||||
|
||||
assert.NoError(t, f.MutateRoot(func(r *data.Root) { r.Roles["hello"] = nil }))
|
||||
|
||||
for role, metaBytes := range origMeta {
|
||||
newMeta, err := f.MetadataCache.GetMeta(role, -1)
|
||||
require.NoError(t, err)
|
||||
|
||||
if role != data.CanonicalRootRole {
|
||||
require.True(t, bytes.Equal(metaBytes, newMeta), "bytes have changed for role %s", role)
|
||||
} else {
|
||||
require.False(t, bytes.Equal(metaBytes, newMeta))
|
||||
origSigned, newSigned := &data.SignedRoot{}, &data.SignedRoot{}
|
||||
require.NoError(t, json.Unmarshal(metaBytes, origSigned))
|
||||
require.NoError(t, json.Unmarshal(newMeta, newSigned))
|
||||
require.Len(t, origSigned.Signed.Roles, 4)
|
||||
require.Len(t, newSigned.Signed.Roles, 5)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This mutates the timestamp
|
||||
func TestSwizzlerMutateTimestamp(t *testing.T) {
|
||||
f, origMeta := createNewSwizzler(t)
|
||||
|
||||
assert.NoError(t, f.MutateTimestamp(func(t *data.Timestamp) { t.Meta["hello"] = data.FileMeta{} }))
|
||||
|
||||
for role, metaBytes := range origMeta {
|
||||
newMeta, err := f.MetadataCache.GetMeta(role, -1)
|
||||
require.NoError(t, err)
|
||||
|
||||
if role != data.CanonicalTimestampRole {
|
||||
require.True(t, bytes.Equal(metaBytes, newMeta), "bytes have changed for role %s", role)
|
||||
} else {
|
||||
require.False(t, bytes.Equal(metaBytes, newMeta))
|
||||
origSigned, newSigned := &data.SignedTimestamp{}, &data.SignedTimestamp{}
|
||||
require.NoError(t, json.Unmarshal(metaBytes, origSigned))
|
||||
require.NoError(t, json.Unmarshal(newMeta, newSigned))
|
||||
require.Len(t, origSigned.Signed.Meta, 1)
|
||||
require.Len(t, newSigned.Signed.Meta, 2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This mutates the snapshot
|
||||
func TestSwizzlerMutateSnapshot(t *testing.T) {
|
||||
f, origMeta := createNewSwizzler(t)
|
||||
|
||||
assert.NoError(t, f.MutateSnapshot(func(s *data.Snapshot) { s.Meta["hello"] = data.FileMeta{} }))
|
||||
|
||||
for role, metaBytes := range origMeta {
|
||||
newMeta, err := f.MetadataCache.GetMeta(role, -1)
|
||||
require.NoError(t, err)
|
||||
|
||||
if role != data.CanonicalSnapshotRole {
|
||||
require.True(t, bytes.Equal(metaBytes, newMeta), "bytes have changed for role %s", role)
|
||||
} else {
|
||||
require.False(t, bytes.Equal(metaBytes, newMeta))
|
||||
origSigned, newSigned := &data.SignedSnapshot{}, &data.SignedSnapshot{}
|
||||
require.NoError(t, json.Unmarshal(metaBytes, origSigned))
|
||||
require.NoError(t, json.Unmarshal(newMeta, newSigned))
|
||||
require.Len(t, origSigned.Signed.Meta, 4)
|
||||
require.Len(t, newSigned.Signed.Meta, 5)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This mutates the targets
|
||||
func TestSwizzlerMutateTargets(t *testing.T) {
|
||||
f, origMeta := createNewSwizzler(t)
|
||||
|
||||
assert.NoError(t, f.MutateTargets(func(t *data.Targets) { t.Targets["hello"] = data.FileMeta{} }))
|
||||
|
||||
for role, metaBytes := range origMeta {
|
||||
newMeta, err := f.MetadataCache.GetMeta(role, -1)
|
||||
require.NoError(t, err)
|
||||
|
||||
if role != data.CanonicalTargetsRole {
|
||||
require.True(t, bytes.Equal(metaBytes, newMeta), "bytes have changed for role %s", role)
|
||||
} else {
|
||||
require.False(t, bytes.Equal(metaBytes, newMeta))
|
||||
origSigned, newSigned := &data.SignedTargets{}, &data.SignedTargets{}
|
||||
require.NoError(t, json.Unmarshal(metaBytes, origSigned))
|
||||
require.NoError(t, json.Unmarshal(newMeta, newSigned))
|
||||
require.Len(t, origSigned.Signed.Targets, 0)
|
||||
require.Len(t, newSigned.Signed.Targets, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user