distribution/docs/middleware/migration/migration_test.go
2016-09-28 14:25:04 -07:00

275 lines
8.7 KiB
Go

package migration
import (
"fmt"
"reflect"
"testing"
"github.com/docker/dhe-deploy/registry/middleware/mocks"
"github.com/docker/distribution"
"github.com/docker/distribution/context"
"github.com/docker/distribution/registry/storage"
"github.com/docker/distribution/registry/storage/cache/memory"
"github.com/docker/distribution/registry/storage/driver"
"github.com/docker/distribution/registry/storage/driver/inmemory"
"github.com/stretchr/testify/mock"
)
const root = "/docker/registry/v2/"
type env struct {
registry distribution.Namespace
driver driver.StorageDriver
ctx context.Context
}
func setupRegistry(t *testing.T) *env {
d := inmemory.New()
ctx := context.Background()
registry, err := storage.NewRegistry(
ctx,
d,
storage.BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider()),
storage.EnableRedirect,
)
if err != nil {
t.Fatalf("error iunstantiating registry: %v", err)
}
// Add data to registry
var prefix = root + "repositories/admin/"
data := map[string]interface{}{
"content": map[string]string{
// REPOSITORIES
//a
prefix + "a-repo/_layers/sha256/1f8d6e1edee77de035d79ca992df4e5cc8d358ec38f527077a84945a79907566/link": "sha256:1f8d6e1edee77de035d79ca992df4e5cc8d358ec38f527077a84945a79907566",
prefix + "a-repo/_layers/sha256/6bf8e372a8396bbf22c0b2e0eebdad5ac3da97357621fe68de694bd4de23639d/link": "sha256:6bf8e372a8396bbf22c0b2e0eebdad5ac3da97357621fe68de694bd4de23639d",
prefix + "a-repo/_manifests/revisions/sha256/1f8d6e1edee77de035d79ca992df4e5cc8d358ec38f527077a84945a79907566/link": "sha256:1f8d6e1edee77de035d79ca992df4e5cc8d358ec38f527077a84945a79907566",
prefix + "a-repo/_manifests/tags/a-tag/current/link": "sha256:1f8d6e1edee77de035d79ca992df4e5cc8d358ec38f527077a84945a79907566",
prefix + "a-repo/_manifests/tags/a-tag/index/sha256/1f8d6e1edee77de035d79ca992df4e5cc8d358ec38f527077a84945a79907566/link": "sha256:1f8d6e1edee77de035d79ca992df4e5cc8d358ec38f527077a84945a79907566",
//b
prefix + "b-repo/_layers/sha256/1f8d6e1edee77de035d79ca992df4e5cc8d358ec38f527077a84945a79907566/link": "sha256:1f8d6e1edee77de035d79ca992df4e5cc8d358ec38f527077a84945a79907566",
prefix + "b-repo/_layers/sha256/6bf8e372a8396bbf22c0b2e0eebdad5ac3da97357621fe68de694bd4de23639d/link": "sha256:6bf8e372a8396bbf22c0b2e0eebdad5ac3da97357621fe68de694bd4de23639d",
prefix + "b-repo/_manifests/revisions/sha256/1f8d6e1edee77de035d79ca992df4e5cc8d358ec38f527077a84945a79907566/link": "sha256:1f8d6e1edee77de035d79ca992df4e5cc8d358ec38f527077a84945a79907566",
prefix + "b-repo/_manifests/tags/b-tag/current/link": "sha256:1f8d6e1edee77de035d79ca992df4e5cc8d358ec38f527077a84945a79907566",
prefix + "b-repo/_manifests/tags/b-tag/index/sha256/1f8d6e1edee77de035d79ca992df4e5cc8d358ec38f527077a84945a79907566/link": "sha256:1f8d6e1edee77de035d79ca992df4e5cc8d358ec38f527077a84945a79907566",
// MANIFESTS
root + "blobs/sha256/1f/1f8d6e1edee77de035d79ca992df4e5cc8d358ec38f527077a84945a79907566/data": V2_MANIFEST_1,
root + "blobs/sha256/6b/6bf8e372a8396bbf22c0b2e0eebdad5ac3da97357621fe68de694bd4de23639d/data": V2_MANIFEST_CONFIG_1,
},
}
for path, blob := range data["content"].(map[string]string) {
d.PutContent(ctx, path, []byte(blob))
}
return &env{
registry,
d,
ctx,
}
}
func TestMigrateResumes(t *testing.T) {
env := setupRegistry(t)
tests := []struct {
migration *migration
expectedRepos []string
}{
{
migration: &migration{
reg: env.registry,
isFromResume: false,
},
expectedRepos: []string{"admin/a-repo", "admin/b-repo"},
},
{
migration: &migration{
reg: env.registry,
isFromResume: true,
currentRepo: "admin/b-repo",
},
expectedRepos: []string{"admin/b-repo"},
},
}
for _, test := range tests {
// Iterate through the repositories, storing each repository name within
// iteratedRepos. We can then compare which repos were passed to onTagFunc
// to check resumes
iteratedRepos := []string{}
onTagFunc := func(ctx context.Context, repo distribution.Repository, tagName string, tag distribution.Descriptor) error {
iteratedRepos = append(iteratedRepos, repo.Named().Name())
return nil
}
test.migration.enumerator = NewEnumerator(onTagFunc)
if _, err := test.migration.Migrate(env.ctx); err != nil {
t.Fatalf("error migrating: %s", err)
}
if !reflect.DeepEqual(iteratedRepos, test.expectedRepos) {
t.Fatalf("resume failed, expected vs actual repo iteration: %s vs %s", test.expectedRepos, iteratedRepos)
}
}
}
// This is a basic test asserting that there are no obvious errors with
// the migration logic.
func TestAddTagAndManifest(t *testing.T) {
env := setupRegistry(t)
store := mocks.NewStore()
migration := NewMigration(env.registry, store)
store.TagStore.On(
"PutTag",
mock.AnythingOfType("*context.valueCtx"),
mock.AnythingOfTypeArgument("*storage.repository"),
mock.AnythingOfType("string"),
mock.AnythingOfType("distribution.Descriptor"),
).Return(nil).Run(func(a mock.Arguments) {
fmt.Printf("%#v", a)
})
store.ManifestStore.On(
"PutManifest",
mock.AnythingOfType("*context.valueCtx"),
mock.AnythingOfType("string"),
mock.AnythingOfType("string"),
mock.AnythingOfType("*schema2.DeserializedManifest"),
).Return(nil).Run(func(a mock.Arguments) {
fmt.Printf("%#v", a)
})
_, err := migration.Migrate(env.ctx)
if err != nil {
t.Fatalf("unexpected error during migration: %s", err)
}
}
// Assert that failing during a migration returns no error
// and instead only logs the error
func TestAddTagAndManifestReturnsNil(t *testing.T) {
env := setupRegistry(t)
store := mocks.NewStore()
migration := NewMigration(env.registry, store)
// When we get admin/a-repo we can fail fast.
store.TagStore.On(
"PutTag",
mock.AnythingOfType("*context.valueCtx"),
mock.AnythingOfTypeArgument("*storage.repository"),
mock.AnythingOfType("string"),
mock.AnythingOfType("distribution.Descriptor"),
).Return(nil)
store.ManifestStore.On(
"PutManifest",
mock.AnythingOfType("*context.valueCtx"),
mock.AnythingOfType("string"),
mock.AnythingOfType("string"),
mock.AnythingOfType("*schema2.DeserializedManifest"),
).Return(nil)
_, err := migration.Migrate(env.ctx)
if err != nil {
t.Fatalf("unexpected error during migration: %v", err)
}
}
const V2_MANIFEST_1 = `
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 1473,
"digest": "sha256:6bf8e372a8396bbf22c0b2e0eebdad5ac3da97357621fe68de694bd4de23639d"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 146,
"digest": "sha256:c170e8502f05562c30101cd65993e514cf63d242d6f14af6ca49896168c59ffd"
}
]
}
`
const V2_MANIFEST_CONFIG_1 = `
{
"architecture": "amd64",
"config": {
"Hostname": "9aec87ce8e45",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/true"
],
"Image": "sha256:bbadf13f1e9e0d1629c07ad1e7eedcc5a6383300b7701c131a6f0beac49866ad",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
}
},
"container": "dab58e1226ef3b699c25b7befc7cec562707a959135d130f667a039e18e63f72",
"container_config": {
"Hostname": "9aec87ce8e45",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) CMD [\"/true\"]"
],
"Image": "sha256:bbadf13f1e9e0d1629c07ad1e7eedcc5a6383300b7701c131a6f0beac49866ad",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
}
},
"created": "2016-05-19T20:38:48.345518736Z",
"docker_version": "1.11.1",
"history": [
{
"created": "2016-05-19T20:38:48.277232795Z",
"created_by": "/bin/sh -c #(nop) ADD file:513005a00bb6ce26c9eb571d6f16e0c12378ba40f8e3100bcb484db53008e3b2 in /true"
},
{
"created": "2016-05-19T20:38:48.345518736Z",
"created_by": "/bin/sh -c #(nop) CMD [\"/true\"]",
"empty_layer": true
}
],
"os": "linux",
"rootfs": {
"type": "layers",
"diff_ids": [
"sha256:af593d271f82964b57d51cc5e647c6076fb160bf8620f605848130110f0ed647"
]
}
}
`