github.com/npaton/distribution@v2.3.1-rc.0+incompatible/registry/storage/driver/gcs/gcs_test.go (about) 1 // +build include_gcs 2 3 package gcs 4 5 import ( 6 "io/ioutil" 7 "os" 8 "testing" 9 10 "fmt" 11 ctx "github.com/docker/distribution/context" 12 storagedriver "github.com/docker/distribution/registry/storage/driver" 13 "github.com/docker/distribution/registry/storage/driver/testsuites" 14 "golang.org/x/oauth2" 15 "golang.org/x/oauth2/google" 16 "google.golang.org/api/googleapi" 17 "google.golang.org/cloud/storage" 18 "gopkg.in/check.v1" 19 ) 20 21 // Hook up gocheck into the "go test" runner. 22 func Test(t *testing.T) { check.TestingT(t) } 23 24 var gcsDriverConstructor func(rootDirectory string) (storagedriver.StorageDriver, error) 25 var skipGCS func() string 26 27 func init() { 28 bucket := os.Getenv("REGISTRY_STORAGE_GCS_BUCKET") 29 credentials := os.Getenv("GOOGLE_APPLICATION_CREDENTIALS") 30 31 // Skip GCS storage driver tests if environment variable parameters are not provided 32 skipGCS = func() string { 33 if bucket == "" || credentials == "" { 34 return "The following environment variables must be set to enable these tests: REGISTRY_STORAGE_GCS_BUCKET, GOOGLE_APPLICATION_CREDENTIALS" 35 } 36 return "" 37 } 38 39 if skipGCS() != "" { 40 return 41 } 42 43 root, err := ioutil.TempDir("", "driver-") 44 if err != nil { 45 panic(err) 46 } 47 defer os.Remove(root) 48 var ts oauth2.TokenSource 49 var email string 50 var privateKey []byte 51 52 ts, err = google.DefaultTokenSource(ctx.Background(), storage.ScopeFullControl) 53 if err != nil { 54 // Assume that the file contents are within the environment variable since it exists 55 // but does not contain a valid file path 56 jwtConfig, err := google.JWTConfigFromJSON([]byte(credentials), storage.ScopeFullControl) 57 if err != nil { 58 panic(fmt.Sprintf("Error reading JWT config : %s", err)) 59 } 60 email = jwtConfig.Email 61 privateKey = []byte(jwtConfig.PrivateKey) 62 if len(privateKey) == 0 { 63 panic("Error reading JWT config : missing private_key property") 64 } 65 if email == "" { 66 panic("Error reading JWT config : missing client_email property") 67 } 68 ts = jwtConfig.TokenSource(ctx.Background()) 69 } 70 71 gcsDriverConstructor = func(rootDirectory string) (storagedriver.StorageDriver, error) { 72 parameters := driverParameters{ 73 bucket: bucket, 74 rootDirectory: root, 75 email: email, 76 privateKey: privateKey, 77 client: oauth2.NewClient(ctx.Background(), ts), 78 } 79 80 return New(parameters) 81 } 82 83 testsuites.RegisterSuite(func() (storagedriver.StorageDriver, error) { 84 return gcsDriverConstructor(root) 85 }, skipGCS) 86 } 87 88 func TestRetry(t *testing.T) { 89 if skipGCS() != "" { 90 t.Skip(skipGCS()) 91 } 92 93 assertError := func(expected string, observed error) { 94 observedMsg := "<nil>" 95 if observed != nil { 96 observedMsg = observed.Error() 97 } 98 if observedMsg != expected { 99 t.Fatalf("expected %v, observed %v\n", expected, observedMsg) 100 } 101 } 102 103 err := retry(2, func() error { 104 return &googleapi.Error{ 105 Code: 503, 106 Message: "google api error", 107 } 108 }) 109 assertError("googleapi: Error 503: google api error", err) 110 111 err = retry(2, func() error { 112 return &googleapi.Error{ 113 Code: 404, 114 Message: "google api error", 115 } 116 }) 117 assertError("googleapi: Error 404: google api error", err) 118 119 err = retry(2, func() error { 120 return fmt.Errorf("error") 121 }) 122 assertError("error", err) 123 } 124 125 func TestEmptyRootList(t *testing.T) { 126 if skipGCS() != "" { 127 t.Skip(skipGCS()) 128 } 129 130 validRoot, err := ioutil.TempDir("", "driver-") 131 if err != nil { 132 t.Fatalf("unexpected error creating temporary directory: %v", err) 133 } 134 defer os.Remove(validRoot) 135 136 rootedDriver, err := gcsDriverConstructor(validRoot) 137 if err != nil { 138 t.Fatalf("unexpected error creating rooted driver: %v", err) 139 } 140 141 emptyRootDriver, err := gcsDriverConstructor("") 142 if err != nil { 143 t.Fatalf("unexpected error creating empty root driver: %v", err) 144 } 145 146 slashRootDriver, err := gcsDriverConstructor("/") 147 if err != nil { 148 t.Fatalf("unexpected error creating slash root driver: %v", err) 149 } 150 151 filename := "/test" 152 contents := []byte("contents") 153 ctx := ctx.Background() 154 err = rootedDriver.PutContent(ctx, filename, contents) 155 if err != nil { 156 t.Fatalf("unexpected error creating content: %v", err) 157 } 158 defer func() { 159 err := rootedDriver.Delete(ctx, filename) 160 if err != nil { 161 t.Fatalf("failed to remove %v due to %v\n", filename, err) 162 } 163 }() 164 keys, err := emptyRootDriver.List(ctx, "/") 165 for _, path := range keys { 166 if !storagedriver.PathRegexp.MatchString(path) { 167 t.Fatalf("unexpected string in path: %q != %q", path, storagedriver.PathRegexp) 168 } 169 } 170 171 keys, err = slashRootDriver.List(ctx, "/") 172 for _, path := range keys { 173 if !storagedriver.PathRegexp.MatchString(path) { 174 t.Fatalf("unexpected string in path: %q != %q", path, storagedriver.PathRegexp) 175 } 176 } 177 }