github.com/lusis/distribution@v2.0.1+incompatible/notifications/listener_test.go (about) 1 package notifications 2 3 import ( 4 "io" 5 "reflect" 6 "testing" 7 8 "github.com/docker/distribution" 9 "github.com/docker/distribution/digest" 10 "github.com/docker/distribution/manifest" 11 "github.com/docker/distribution/registry/storage" 12 "github.com/docker/distribution/registry/storage/cache" 13 "github.com/docker/distribution/registry/storage/driver/inmemory" 14 "github.com/docker/distribution/testutil" 15 "github.com/docker/libtrust" 16 "golang.org/x/net/context" 17 ) 18 19 func TestListener(t *testing.T) { 20 registry := storage.NewRegistryWithDriver(inmemory.New(), cache.NewInMemoryLayerInfoCache()) 21 tl := &testListener{ 22 ops: make(map[string]int), 23 } 24 ctx := context.Background() 25 repository, err := registry.Repository(ctx, "foo/bar") 26 if err != nil { 27 t.Fatalf("unexpected error getting repo: %v", err) 28 } 29 repository = Listen(repository, tl) 30 31 // Now take the registry through a number of operations 32 checkExerciseRepository(t, repository) 33 34 expectedOps := map[string]int{ 35 "manifest:push": 1, 36 "manifest:pull": 2, 37 // "manifest:delete": 0, // deletes not supported for now 38 "layer:push": 2, 39 "layer:pull": 2, 40 // "layer:delete": 0, // deletes not supported for now 41 } 42 43 if !reflect.DeepEqual(tl.ops, expectedOps) { 44 t.Fatalf("counts do not match:\n%v\n !=\n%v", tl.ops, expectedOps) 45 } 46 47 } 48 49 type testListener struct { 50 ops map[string]int 51 } 52 53 func (tl *testListener) ManifestPushed(repo distribution.Repository, sm *manifest.SignedManifest) error { 54 tl.ops["manifest:push"]++ 55 56 return nil 57 } 58 59 func (tl *testListener) ManifestPulled(repo distribution.Repository, sm *manifest.SignedManifest) error { 60 tl.ops["manifest:pull"]++ 61 return nil 62 } 63 64 func (tl *testListener) ManifestDeleted(repo distribution.Repository, sm *manifest.SignedManifest) error { 65 tl.ops["manifest:delete"]++ 66 return nil 67 } 68 69 func (tl *testListener) LayerPushed(repo distribution.Repository, layer distribution.Layer) error { 70 tl.ops["layer:push"]++ 71 return nil 72 } 73 74 func (tl *testListener) LayerPulled(repo distribution.Repository, layer distribution.Layer) error { 75 tl.ops["layer:pull"]++ 76 return nil 77 } 78 79 func (tl *testListener) LayerDeleted(repo distribution.Repository, layer distribution.Layer) error { 80 tl.ops["layer:delete"]++ 81 return nil 82 } 83 84 // checkExerciseRegistry takes the registry through all of its operations, 85 // carrying out generic checks. 86 func checkExerciseRepository(t *testing.T, repository distribution.Repository) { 87 // TODO(stevvooe): This would be a nice testutil function. Basically, it 88 // takes the registry through a common set of operations. This could be 89 // used to make cross-cutting updates by changing internals that affect 90 // update counts. Basically, it would make writing tests a lot easier. 91 92 tag := "thetag" 93 m := manifest.Manifest{ 94 Versioned: manifest.Versioned{ 95 SchemaVersion: 1, 96 }, 97 Name: repository.Name(), 98 Tag: tag, 99 } 100 101 layers := repository.Layers() 102 for i := 0; i < 2; i++ { 103 rs, ds, err := testutil.CreateRandomTarFile() 104 if err != nil { 105 t.Fatalf("error creating test layer: %v", err) 106 } 107 dgst := digest.Digest(ds) 108 upload, err := layers.Upload() 109 if err != nil { 110 t.Fatalf("error creating layer upload: %v", err) 111 } 112 113 // Use the resumes, as well! 114 upload, err = layers.Resume(upload.UUID()) 115 if err != nil { 116 t.Fatalf("error resuming layer upload: %v", err) 117 } 118 119 io.Copy(upload, rs) 120 121 if _, err := upload.Finish(dgst); err != nil { 122 t.Fatalf("unexpected error finishing upload: %v", err) 123 } 124 125 m.FSLayers = append(m.FSLayers, manifest.FSLayer{ 126 BlobSum: dgst, 127 }) 128 129 // Then fetch the layers 130 if _, err := layers.Fetch(dgst); err != nil { 131 t.Fatalf("error fetching layer: %v", err) 132 } 133 } 134 135 pk, err := libtrust.GenerateECP256PrivateKey() 136 if err != nil { 137 t.Fatalf("unexpected error generating key: %v", err) 138 } 139 140 sm, err := manifest.Sign(&m, pk) 141 if err != nil { 142 t.Fatalf("unexpected error signing manifest: %v", err) 143 } 144 145 manifests := repository.Manifests() 146 147 if err := manifests.Put(sm); err != nil { 148 t.Fatalf("unexpected error putting the manifest: %v", err) 149 } 150 151 p, err := sm.Payload() 152 if err != nil { 153 t.Fatalf("unexpected error getting manifest payload: %v", err) 154 } 155 156 dgst, err := digest.FromBytes(p) 157 if err != nil { 158 t.Fatalf("unexpected error digesting manifest payload: %v", err) 159 } 160 161 fetchedByManifest, err := manifests.Get(dgst) 162 if err != nil { 163 t.Fatalf("unexpected error fetching manifest: %v", err) 164 } 165 166 if fetchedByManifest.Tag != sm.Tag { 167 t.Fatalf("retrieved unexpected manifest: %v", err) 168 } 169 170 fetched, err := manifests.GetByTag(tag) 171 if err != nil { 172 t.Fatalf("unexpected error fetching manifest: %v", err) 173 } 174 175 if fetched.Tag != fetchedByManifest.Tag { 176 t.Fatalf("retrieved unexpected manifest: %v", err) 177 } 178 }