func TestGCWithMissingManifests(t *testing.T) { ctx := context.Background() d := inmemory.New() registry := createRegistry(t, d) repo := makeRepository(t, registry, "testrepo") uploadRandomSchema1Image(t, repo) // Simulate a missing _manifests directory revPath, err := pathFor(manifestRevisionsPathSpec{"testrepo"}) if err != nil { t.Fatal(err) } _manifestsPath := path.Dir(revPath) err = d.Delete(ctx, _manifestsPath) if err != nil { t.Fatal(err) } err = MarkAndSweep(context.Background(), d, registry, false) if err != nil { t.Fatalf("Failed mark and sweep: %v", err) } blobs := allBlobs(t, registry) if len(blobs) > 0 { t.Errorf("unexpected blobs after gc") } }
func TestCatalog(t *testing.T) { var m testutil.RequestResponseMap addTestCatalog( "/v2/_catalog?n=5", []byte("{\"repositories\":[\"foo\", \"bar\", \"baz\"]}"), "", &m) e, c := testServer(m) defer c() entries := make([]string, 5) r, err := NewRegistry(context.Background(), e, nil) if err != nil { t.Fatal(err) } ctx := context.Background() numFilled, err := r.Repositories(ctx, entries, "") if err != io.EOF { t.Fatal(err) } if numFilled != 3 { t.Fatalf("Got wrong number of repos") } }
func (c *ComposeWrapper) execStartStop(start bool, services ...string) error { if start { return c.project.Start(context.Background(), services...) } options := options.Down{} return c.project.Down(context.Background(), options, services...) }
func init() { bucket := os.Getenv("REGISTRY_STORAGE_GCS_BUCKET") credentials := os.Getenv("GOOGLE_APPLICATION_CREDENTIALS") // Skip GCS storage driver tests if environment variable parameters are not provided skipGCS = func() string { if bucket == "" || credentials == "" { return "The following environment variables must be set to enable these tests: REGISTRY_STORAGE_GCS_BUCKET, GOOGLE_APPLICATION_CREDENTIALS" } return "" } if skipGCS() != "" { return } root, err := ioutil.TempDir("", "driver-") if err != nil { panic(err) } defer os.Remove(root) var ts oauth2.TokenSource var email string var privateKey []byte ts, err = google.DefaultTokenSource(ctx.Background(), storage.ScopeFullControl) if err != nil { // Assume that the file contents are within the environment variable since it exists // but does not contain a valid file path jwtConfig, err := google.JWTConfigFromJSON([]byte(credentials), storage.ScopeFullControl) if err != nil { panic(fmt.Sprintf("Error reading JWT config : %s", err)) } email = jwtConfig.Email privateKey = []byte(jwtConfig.PrivateKey) if len(privateKey) == 0 { panic("Error reading JWT config : missing private_key property") } if email == "" { panic("Error reading JWT config : missing client_email property") } ts = jwtConfig.TokenSource(ctx.Background()) } gcsDriverConstructor = func(rootDirectory string) (storagedriver.StorageDriver, error) { parameters := driverParameters{ bucket: bucket, rootDirectory: root, email: email, privateKey: privateKey, client: oauth2.NewClient(ctx.Background(), ts), } return New(parameters) } testsuites.RegisterSuite(func() (storagedriver.StorageDriver, error) { return gcsDriverConstructor(root) }, skipGCS) }
func TestManifestFetch(t *testing.T) { ctx := context.Background() repo := "test.example.com/repo" m1, dgst := newRandomSchemaV1Manifest(repo, "latest", 6) var m testutil.RequestResponseMap addTestManifest(repo, dgst.String(), m1.Raw, &m) e, c := testServer(m) defer c() r, err := NewRepository(context.Background(), repo, e, nil) if err != nil { t.Fatal(err) } ms, err := r.Manifests(ctx) if err != nil { t.Fatal(err) } ok, err := ms.Exists(dgst) if err != nil { t.Fatal(err) } if !ok { t.Fatal("Manifest does not exist") } manifest, err := ms.Get(dgst) if err != nil { t.Fatal(err) } if err := checkEqualManifest(manifest, m1); err != nil { t.Fatal(err) } }
func TestManifestFetchWithEtag(t *testing.T) { repo := "test.example.com/repo/by/tag" m1, d1 := newRandomSchemaV1Manifest(repo, "latest", 6) var m testutil.RequestResponseMap addTestManifestWithEtag(repo, "latest", m1.Raw, &m, d1.String()) e, c := testServer(m) defer c() r, err := NewRepository(context.Background(), repo, e, nil) if err != nil { t.Fatal(err) } ctx := context.Background() ms, err := r.Manifests(ctx) if err != nil { t.Fatal(err) } m2, err := ms.GetByTag("latest", AddEtagToTag("latest", d1.String())) if err != nil { t.Fatal(err) } if m2 != nil { t.Fatal("Expected empty manifest for matching etag") } }
func TestV1ManifestFetch(t *testing.T) { ctx := context.Background() repo := "test.example.com/repo" m1, dgst, _ := newRandomSchemaV1Manifest(repo, "latest", 6) var m testutil.RequestResponseMap _, pl, err := m1.Payload() if err != nil { t.Fatal(err) } addTestManifest(repo, dgst.String(), pl, &m) addTestManifest(repo, "latest", pl, &m) e, c := testServer(m) defer c() r, err := NewRepository(context.Background(), repo, e, nil) if err != nil { t.Fatal(err) } ms, err := r.Manifests(ctx) if err != nil { t.Fatal(err) } ok, err := ms.Exists(ctx, dgst) if err != nil { t.Fatal(err) } if !ok { t.Fatal("Manifest does not exist") } manifest, err := ms.Get(ctx, dgst) if err != nil { t.Fatal(err) } v1manifest, ok := manifest.(*schema1.SignedManifest) if !ok { t.Fatalf("Unexpected manifest type from Get: %T", manifest) } if err := checkEqualManifest(v1manifest, m1); err != nil { t.Fatal(err) } manifest, err = ms.Get(ctx, dgst, WithTag("latest")) if err != nil { t.Fatal(err) } v1manifest, ok = manifest.(*schema1.SignedManifest) if !ok { t.Fatalf("Unexpected manifest type from Get: %T", manifest) } if err = checkEqualManifest(v1manifest, m1); err != nil { t.Fatal(err) } }
func TestRestoreOld(t *testing.T) { ref1, ref2, _ := testRefs(t) remainingRepos := map[string]bool{ ref1.String(): true, ref2.String(): true, } deleteFunc := func(r reference.Reference) error { if r.String() == ref1.String() && len(remainingRepos) == 2 { t.Errorf("ref1 should be removed first") } _, ok := remainingRepos[r.String()] if !ok { t.Fatalf("Trying to remove nonexistent repo: %s", r) } delete(remainingRepos, r.String()) return nil } timeUnit := time.Millisecond serialized, err := json.Marshal(&map[string]schedulerEntry{ ref1.String(): { Expiry: time.Now().Add(1 * timeUnit), Key: ref1.String(), EntryType: 0, }, ref2.String(): { Expiry: time.Now().Add(-3 * timeUnit), // TTL passed, should be removed first Key: ref2.String(), EntryType: 0, }, }) if err != nil { t.Fatalf("Error serializing test data: %s", err.Error()) } ctx := context.Background() pathToStatFile := "/ttl" fs := inmemory.New() err = fs.PutContent(ctx, pathToStatFile, serialized) if err != nil { t.Fatal("Unable to write serialized data to fs") } s := New(context.Background(), fs, "/ttl") s.onBlobExpire = deleteFunc err = s.Start() if err != nil { t.Fatalf("Error starting ttlExpirationScheduler: %s", err) } <-time.After(50 * timeUnit) if len(remainingRepos) != 0 { t.Fatalf("Repositories remaining: %#v", remainingRepos) } }
func TestManifestTags(t *testing.T) { repo := "test.example.com/repo/tags/list" tagsList := []byte(strings.TrimSpace(` { "name": "test.example.com/repo/tags/list", "tags": [ "tag1", "tag2", "funtag" ] } `)) var m testutil.RequestResponseMap m = append(m, testutil.RequestResponseMapping{ Request: testutil.Request{ Method: "GET", Route: "/v2/" + repo + "/tags/list", }, Response: testutil.Response{ StatusCode: http.StatusOK, Body: tagsList, Headers: http.Header(map[string][]string{ "Content-Length": {fmt.Sprint(len(tagsList))}, "Last-Modified": {time.Now().Add(-1 * time.Second).Format(time.ANSIC)}, }), }, }) e, c := testServer(m) defer c() r, err := NewRepository(context.Background(), repo, e, nil) if err != nil { t.Fatal(err) } ctx := context.Background() ms, err := r.Manifests(ctx) if err != nil { t.Fatal(err) } tags, err := ms.Tags() if err != nil { t.Fatal(err) } if len(tags) != 3 { t.Fatalf("Wrong number of tags returned: %d, expected 3", len(tags)) } // TODO(dmcgowan): Check array // TODO(dmcgowan): Check for error cases }
func TestStopRestore(t *testing.T) { ref1, ref2, _ := testRefs(t) timeUnit := time.Millisecond remainingRepos := map[string]bool{ ref1.String(): true, ref2.String(): true, } var mu sync.Mutex deleteFunc := func(r reference.Reference) error { mu.Lock() delete(remainingRepos, r.String()) mu.Unlock() return nil } fs := inmemory.New() pathToStateFile := "/ttl" s := New(context.Background(), fs, pathToStateFile) s.onBlobExpire = deleteFunc err := s.Start() if err != nil { t.Fatalf(err.Error()) } s.add(ref1, 300*timeUnit, entryTypeBlob) s.add(ref2, 100*timeUnit, entryTypeBlob) // Start and stop before all operations complete // state will be written to fs s.Stop() time.Sleep(10 * time.Millisecond) // v2 will restore state from fs s2 := New(context.Background(), fs, pathToStateFile) s2.onBlobExpire = deleteFunc err = s2.Start() if err != nil { t.Fatalf("Error starting v2: %s", err.Error()) } <-time.After(500 * timeUnit) mu.Lock() defer mu.Unlock() if len(remainingRepos) != 0 { t.Fatalf("Repositories remaining: %#v", remainingRepos) } }
func TestListener(t *testing.T) { ctx := context.Background() registry := storage.NewRegistryWithDriver(ctx, inmemory.New(), memory.NewInMemoryBlobDescriptorCacheProvider(), true, true) tl := &testListener{ ops: make(map[string]int), } repository, err := registry.Repository(ctx, "foo/bar") if err != nil { t.Fatalf("unexpected error getting repo: %v", err) } repository = Listen(repository, tl) // Now take the registry through a number of operations checkExerciseRepository(t, repository) expectedOps := map[string]int{ "manifest:push": 1, "manifest:pull": 2, // "manifest:delete": 0, // deletes not supported for now "layer:push": 2, "layer:pull": 2, // "layer:delete": 0, // deletes not supported for now } if !reflect.DeepEqual(tl.ops, expectedOps) { t.Fatalf("counts do not match:\n%v\n !=\n%v", tl.ops, expectedOps) } }
func TestBlobExists(t *testing.T) { d1, b1 := newRandomBlob(1024) var m testutil.RequestResponseMap addTestFetch("test.example.com/repo1", d1, b1, &m) e, c := testServer(m) defer c() ctx := context.Background() r, err := NewRepository(ctx, "test.example.com/repo1", e, nil) if err != nil { t.Fatal(err) } l := r.Blobs(ctx) stat, err := l.Stat(ctx, d1) if err != nil { t.Fatal(err) } if stat.Digest != d1 { t.Fatalf("Unexpected digest: %s, expected %s", stat.Digest, d1) } if stat.Size != int64(len(b1)) { t.Fatalf("Unexpected length: %d, expected %d", stat.Size, len(b1)) } // TODO(dmcgowan): Test error cases and ErrBlobUnknown case }
func testFS(t *testing.T) (driver.StorageDriver, map[string]string, context.Context) { d := inmemory.New() ctx := context.Background() expected := map[string]string{ "/a": "dir", "/a/b": "dir", "/a/b/c": "dir", "/a/b/c/d": "file", "/a/b/c/e": "file", "/a/b/f": "dir", "/a/b/f/g": "file", "/a/b/f/h": "file", "/a/b/f/i": "file", "/z": "dir", "/z/y": "file", } for p, typ := range expected { if typ != "file" { continue } if err := d.PutContent(ctx, p, []byte(p)); err != nil { t.Fatalf("unable to put content into fixture: %v", err) } } return d, expected, ctx }
func TestBlobDelete(t *testing.T) { dgst, _ := newRandomBlob(1024) var m testutil.RequestResponseMap repo := "test.example.com/repo1" m = append(m, testutil.RequestResponseMapping{ Request: testutil.Request{ Method: "DELETE", Route: "/v2/" + repo + "/blobs/" + dgst.String(), }, Response: testutil.Response{ StatusCode: http.StatusAccepted, Headers: http.Header(map[string][]string{ "Content-Length": {"0"}, }), }, }) e, c := testServer(m) defer c() ctx := context.Background() r, err := NewRepository(ctx, repo, e, nil) if err != nil { t.Fatal(err) } l := r.Blobs(ctx) err = l.Delete(ctx, dgst) if err != nil { t.Errorf("Error deleting blob: %s", err.Error()) } }
func TestBlobFetch(t *testing.T) { d1, b1 := newRandomBlob(1024) var m testutil.RequestResponseMap addTestFetch("test.example.com/repo1", d1, b1, &m) e, c := testServer(m) defer c() ctx := context.Background() r, err := NewRepository(ctx, "test.example.com/repo1", e, nil) if err != nil { t.Fatal(err) } l := r.Blobs(ctx) b, err := l.Get(ctx, d1) if err != nil { t.Fatal(err) } if bytes.Compare(b, b1) != 0 { t.Fatalf("Wrong bytes values fetched: [%d]byte != [%d]byte", len(b), len(b1)) } // TODO(dmcgowan): Test for unknown blob case }
func checkRepo(registry distribution.Namespace, repoName string) error { ctx := context.Background() repo, err := registry.Repository(ctx, repoName) if err != nil { return fmt.Errorf("unexpected error getting repository: %v", err) } manifests, err := repo.Manifests(ctx) if err != nil { return fmt.Errorf("unexpected error getting manifests: %v", err) } tags, err := manifests.Tags() if err != nil { return fmt.Errorf("unexpected error getting tags: %v", err) } fmt.Fprintf(os.Stderr, "checking repo %s (%d tags)\n", repoName) for _, tag := range tags { mnfst, err := manifests.GetByTag(tag) if err != nil { return fmt.Errorf("unexpected error getting manifest by tag: %v", err) } if err = checkManifest(repoName, mnfst); err != nil { return err } } return nil }
func TestManifestDelete(t *testing.T) { repo := "test.example.com/repo/delete" _, dgst1 := newRandomSchemaV1Manifest(repo, "latest", 6) _, dgst2 := newRandomSchemaV1Manifest(repo, "latest", 6) var m testutil.RequestResponseMap m = append(m, testutil.RequestResponseMapping{ Request: testutil.Request{ Method: "DELETE", Route: "/v2/" + repo + "/manifests/" + dgst1.String(), }, Response: testutil.Response{ StatusCode: http.StatusOK, Headers: http.Header(map[string][]string{ "Content-Length": {"0"}, }), }, }) e, c := testServer(m) defer c() r, err := NewRepository(context.Background(), repo, e, nil) if err != nil { t.Fatal(err) } ms := r.Manifests() if err := ms.Delete(dgst1); err != nil { t.Fatal(err) } if err := ms.Delete(dgst2); err == nil { t.Fatal("Expected error deleting unknown manifest") } // TODO(dmcgowan): Check for specific unknown error }
func simpleUpload(t *testing.T, bs distribution.BlobIngester, blob []byte, expectedDigest digest.Digest) { ctx := context.Background() wr, err := bs.Create(ctx) if err != nil { t.Fatalf("unexpected error starting upload: %v", err) } nn, err := io.Copy(wr, bytes.NewReader(blob)) if err != nil { t.Fatalf("error copying into blob writer: %v", err) } if nn != 0 { t.Fatalf("unexpected number of bytes copied: %v > 0", nn) } dgst, err := digest.FromReader(bytes.NewReader(blob)) if err != nil { t.Fatalf("error getting digest: %v", err) } if dgst != expectedDigest { // sanity check on zero digest t.Fatalf("digest not as expected: %v != %v", dgst, expectedDigest) } desc, err := wr.Commit(ctx, distribution.Descriptor{Digest: dgst}) if err != nil { t.Fatalf("unexpected error committing write: %v", err) } if desc.Digest != dgst { t.Fatalf("unexpected digest: %v != %v", desc.Digest, dgst) } }
// CheckBlobDescriptorCache takes a cache implementation through a common set // of operations. If adding new tests, please add them here so new // implementations get the benefit. This should be used for unit tests. func CheckBlobDescriptorCache(t *testing.T, provider cache.BlobDescriptorCacheProvider) { ctx := context.Background() checkBlobDescriptorCacheEmptyRepository(ctx, t, provider) checkBlobDescriptorCacheSetAndRead(ctx, t, provider) checkBlobDescriptorCacheClear(ctx, t, provider) }
func TestSillyAccessController(t *testing.T) { ac := &accessController{ realm: "test-realm", service: "test-service", } server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ctx := context.WithRequest(context.Background(), r) authCtx, err := ac.Authorized(ctx) if err != nil { switch err := err.(type) { case auth.Challenge: err.SetHeaders(w) w.WriteHeader(http.StatusUnauthorized) return default: t.Fatalf("unexpected error authorizing request: %v", err) } } userInfo, ok := authCtx.Value(auth.UserKey).(auth.UserInfo) if !ok { t.Fatal("silly accessController did not set auth.user context") } if userInfo.Name != "silly" { t.Fatalf("expected user name %q, got %q", "silly", userInfo.Name) } w.WriteHeader(http.StatusNoContent) })) resp, err := http.Get(server.URL) if err != nil { t.Fatalf("unexpected error during GET: %v", err) } defer resp.Body.Close() // Request should not be authorized if resp.StatusCode != http.StatusUnauthorized { t.Fatalf("unexpected response status: %v != %v", resp.StatusCode, http.StatusUnauthorized) } req, err := http.NewRequest("GET", server.URL, nil) if err != nil { t.Fatalf("unexpected error creating new request: %v", err) } req.Header.Set("Authorization", "seriously, anything") resp, err = http.DefaultClient.Do(req) if err != nil { t.Fatalf("unexpected error during GET: %v", err) } defer resp.Body.Close() // Request should not be authorized if resp.StatusCode != http.StatusNoContent { t.Fatalf("unexpected response status: %v != %v", resp.StatusCode, http.StatusNoContent) } }
func newManifestStoreTestEnv(t *testing.T, name, tag string) *manifestStoreTestEnv { nameRef, err := reference.ParseNamed(name) if err != nil { t.Fatalf("unable to parse reference: %s", err) } ctx := context.Background() truthRegistry, err := storage.NewRegistry(ctx, inmemory.New(), storage.BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider())) if err != nil { t.Fatalf("error creating registry: %v", err) } truthRepo, err := truthRegistry.Repository(ctx, nameRef) if err != nil { t.Fatalf("unexpected error getting repo: %v", err) } tr, err := truthRepo.Manifests(ctx) if err != nil { t.Fatal(err.Error()) } truthManifests := statsManifest{ manifests: tr, stats: make(map[string]int), } manifestDigest, err := populateRepo(t, ctx, truthRepo, name, tag) if err != nil { t.Fatalf(err.Error()) } localRegistry, err := storage.NewRegistry(ctx, inmemory.New(), storage.BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider()), storage.EnableRedirect, storage.DisableDigestResumption) if err != nil { t.Fatalf("error creating registry: %v", err) } localRepo, err := localRegistry.Repository(ctx, nameRef) if err != nil { t.Fatalf("unexpected error getting repo: %v", err) } lr, err := localRepo.Manifests(ctx) if err != nil { t.Fatal(err.Error()) } localManifests := statsManifest{ manifests: lr, stats: make(map[string]int), } s := scheduler.New(ctx, inmemory.New(), "/scheduler-state.json") return &manifestStoreTestEnv{ manifestDigest: manifestDigest, manifests: proxyManifestStore{ ctx: ctx, localManifests: localManifests, remoteManifests: truthManifests, scheduler: s, repositoryName: nameRef, authChallenger: &mockChallenger{}, }, } }
func TestManifestPut(t *testing.T) { repo := "test.example.com/repo/delete" m1, dgst := newRandomSchemaV1Manifest(repo, "other", 6) var m testutil.RequestResponseMap m = append(m, testutil.RequestResponseMapping{ Request: testutil.Request{ Method: "PUT", Route: "/v2/" + repo + "/manifests/other", Body: m1.Raw, }, Response: testutil.Response{ StatusCode: http.StatusAccepted, Headers: http.Header(map[string][]string{ "Content-Length": {"0"}, "Docker-Content-Digest": {dgst.String()}, }), }, }) e, c := testServer(m) defer c() r, err := NewRepository(context.Background(), repo, e, nil) if err != nil { t.Fatal(err) } ms := r.Manifests() if err := ms.Put(m1); err != nil { t.Fatal(err) } // TODO(dmcgowan): Check for invalid input error }
// TestMoveDirectory checks that moving a directory returns an error. func TestMoveDirectory(t *testing.T) { if skipGCS() != "" { t.Skip(skipGCS()) } validRoot, err := ioutil.TempDir("", "driver-") if err != nil { t.Fatalf("unexpected error creating temporary directory: %v", err) } defer os.Remove(validRoot) driver, err := gcsDriverConstructor(validRoot) if err != nil { t.Fatalf("unexpected error creating rooted driver: %v", err) } ctx := ctx.Background() contents := []byte("contents") // Create a regular file. err = driver.PutContent(ctx, "/parent/dir/foo", contents) if err != nil { t.Fatalf("unexpected error creating content: %v", err) } defer func() { err := driver.Delete(ctx, "/parent") if err != nil { t.Fatalf("failed to remove /parent due to %v\n", err) } }() err = driver.Move(ctx, "/parent/dir", "/parent/other") if err == nil { t.Fatalf("Moving directory /parent/dir /parent/other should have return a non-nil error\n") } }
func setupFS(t *testing.T) *setupEnv { d := inmemory.New() ctx := context.Background() registry, err := NewRegistry(ctx, d, BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider()), EnableRedirect) if err != nil { t.Fatalf("error creating registry: %v", err) } repos := []string{ "foo/a", "foo/b", "bar/c", "bar/d", "foo/d/in", } for _, repo := range repos { makeRepo(t, ctx, repo, registry) } expected := []string{ "bar/c", "bar/d", "foo/a", "foo/b", "foo/d/in", } return &setupEnv{ ctx: ctx, driver: d, expected: expected, registry: registry, } }
func (suite *S3DriverSuite) TestEmptyRootList(c *check.C) { validRoot, err := ioutil.TempDir("", "driver-") c.Assert(err, check.IsNil) defer os.Remove(validRoot) rootedDriver, err := suite.Constructor(validRoot) c.Assert(err, check.IsNil) emptyRootDriver, err := suite.Constructor("") c.Assert(err, check.IsNil) slashRootDriver, err := suite.Constructor("/") c.Assert(err, check.IsNil) filename := "/test" contents := []byte("contents") ctx := context.Background() err = rootedDriver.PutContent(ctx, filename, contents) c.Assert(err, check.IsNil) defer rootedDriver.Delete(ctx, filename) keys, err := emptyRootDriver.List(ctx, "/") for _, path := range keys { c.Assert(storagedriver.PathRegexp.MatchString(path), check.Equals, true) } keys, err = slashRootDriver.List(ctx, "/") for _, path := range keys { c.Assert(storagedriver.PathRegexp.MatchString(path), check.Equals, true) } }
// RegisterSuite registers an in-process storage driver test suite with // the go test runner. func RegisterSuite(driverConstructor DriverConstructor, skipCheck SkipCheck) { check.Suite(&DriverSuite{ Constructor: driverConstructor, SkipCheck: skipCheck, ctx: context.Background(), }) }
func TestManifestFetchWithEtag(t *testing.T) { repo, _ := reference.ParseNamed("test.example.com/repo/by/tag") _, d1, p1 := newRandomSchemaV1Manifest(repo, "latest", 6) var m testutil.RequestResponseMap addTestManifestWithEtag(repo, "latest", p1, &m, d1.String()) e, c := testServer(m) defer c() ctx := context.Background() r, err := NewRepository(ctx, repo, e, nil) if err != nil { t.Fatal(err) } ms, err := r.Manifests(ctx) if err != nil { t.Fatal(err) } clientManifestService, ok := ms.(*manifests) if !ok { panic("wrong type for client manifest service") } _, err = clientManifestService.Get(ctx, d1, distribution.WithTag("latest"), AddEtagToTag("latest", d1.String())) if err != distribution.ErrManifestNotModified { t.Fatal(err) } }
func TestListener(t *testing.T) { ctx := context.Background() registry, err := storage.NewRegistry(ctx, inmemory.New(), storage.BlobDescriptorCacheProvider(memory.NewInMemoryBlobDescriptorCacheProvider()), storage.EnableDelete, storage.EnableRedirect) if err != nil { t.Fatalf("error creating registry: %v", err) } tl := &testListener{ ops: make(map[string]int), } repoRef, _ := reference.ParseNamed("foo/bar") repository, err := registry.Repository(ctx, repoRef) if err != nil { t.Fatalf("unexpected error getting repo: %v", err) } repository = Listen(repository, tl) // Now take the registry through a number of operations checkExerciseRepository(t, repository) expectedOps := map[string]int{ "manifest:push": 1, "manifest:pull": 1, "manifest:delete": 1, "layer:push": 2, "layer:pull": 2, "layer:delete": 2, } if !reflect.DeepEqual(tl.ops, expectedOps) { t.Fatalf("counts do not match:\n%v\n !=\n%v", tl.ops, expectedOps) } }
func TestOverThousandBlobs(t *testing.T) { if skipS3() != "" { t.Skip(skipS3()) } rootDir, err := ioutil.TempDir("", "driver-") if err != nil { t.Fatalf("unexpected error creating temporary directory: %v", err) } defer os.Remove(rootDir) standardDriver, err := s3DriverConstructor(rootDir, s3.StorageClassStandard) if err != nil { t.Fatalf("unexpected error creating driver with standard storage: %v", err) } ctx := context.Background() for i := 0; i < 1005; i++ { filename := "/thousandfiletest/file" + strconv.Itoa(i) contents := []byte("contents") err = standardDriver.PutContent(ctx, filename, contents) if err != nil { t.Fatalf("unexpected error creating content: %v", err) } } // cant actually verify deletion because read-after-delete is inconsistent, but can ensure no errors err = standardDriver.Delete(ctx, "/thousandfiletest") if err != nil { t.Fatalf("unexpected error deleting thousand files: %v", err) } }
func newTestEnvWithConfig(t *testing.T, config *configuration.Configuration) *testEnv { ctx := context.Background() app := NewApp(ctx, config) server := httptest.NewServer(handlers.CombinedLoggingHandler(os.Stderr, app)) builder, err := v2.NewURLBuilderFromString(server.URL + config.HTTP.Prefix) if err != nil { t.Fatalf("error creating url builder: %v", err) } pk, err := libtrust.GenerateECP256PrivateKey() if err != nil { t.Fatalf("unexpected error generating private key: %v", err) } return &testEnv{ pk: pk, ctx: ctx, config: *config, app: app, server: server, builder: builder, } }