From 718f12131fed6b6a1bc45ea0b582a0e2bd5499d1 Mon Sep 17 00:00:00 2001 From: mpl Date: Fri, 24 Apr 2015 19:06:45 +0200 Subject: [PATCH] cloudstorage: allow config file for test parameters Makes it easier to run the tests, compared with having to pass all the OAuth stuff on the CLI. I also removed the bucket name restrictions, and instead added a check for the bucket emptyness. Change-Id: I1079541089ba304b152886121711ea5ba0208819 --- .../google/cloudstorage/cloudstorage_test.go | 101 ++++++++++++------ 1 file changed, 69 insertions(+), 32 deletions(-) diff --git a/pkg/blobserver/google/cloudstorage/cloudstorage_test.go b/pkg/blobserver/google/cloudstorage/cloudstorage_test.go index f039c7d59..064d18a6a 100644 --- a/pkg/blobserver/google/cloudstorage/cloudstorage_test.go +++ b/pkg/blobserver/google/cloudstorage/cloudstorage_test.go @@ -17,7 +17,9 @@ limitations under the License. package cloudstorage import ( + "encoding/json" "flag" + "io/ioutil" "log" "path" "strings" @@ -36,9 +38,8 @@ import ( ) var ( - // TODO(mpl): use a config file generated with the help of googinit, like for googlestorage tests. - // And remove the 'camlistore-*-test' naming requirement ? - bucket = flag.String("bucket", "", "Bucket name to use for testing. If empty, testing is skipped. If non-empty, it must begin with 'camlistore-' and end in '-test' and have zero items in it.") + configFile = flag.String("config", "", "Path to a configuration JSON file. If given, all other configuration flags are ignored. Use \"camtool googinit --type=cloud\" to generate the auth parameters.") + bucket = flag.String("bucket", "", "Bucket name to use for testing. If empty, and --config blank too, testing is skipped. The bucket must be empty.") clientID = flag.String("client_id", "", "OAuth2 client_id for testing") clientSecret = flag.String("client_secret", "", "OAuth2 client secret for testing") tokenCache = flag.String("token_cache", ".tokencache", "Token cache file.") @@ -53,39 +54,67 @@ func TestStorageWithBucketDir(t *testing.T) { testStorage(t, "/bl/obs/") } +type Config struct { + Auth AuthConfig `json:"auth"` + Bucket string `json:"bucket"` +} + +type AuthConfig struct { + ClientID string `json:"client_id"` + ClientSecret string `json:"client_secret"` + RefreshToken string `json:"refresh_token"` +} + func testStorage(t *testing.T, bucketDir string) { - if *bucket == "" { - t.Skip("Skipping test without --bucket flag") + if *bucket == "" && *configFile == "" { + t.Skip("Skipping test without --bucket or --config flag") } - if !strings.HasPrefix(*bucket, "camlistore-") || !strings.HasSuffix(*bucket, "-test") { - t.Fatalf("bogus bucket name %q; must begin with 'camlistore-' and end in '-test'", *bucket) + var refreshToken string + if *configFile != "" { + data, err := ioutil.ReadFile(*configFile) + if err != nil { + t.Fatalf("Error reading config file %v: %v", *configFile, err) + } + var conf Config + if err := json.Unmarshal(data, &conf); err != nil { + t.Fatalf("Error decoding config file %v: %v", *configFile, err) + } + *clientID = conf.Auth.ClientID + *clientSecret = conf.Auth.ClientSecret + refreshToken = conf.Auth.RefreshToken + *bucket = conf.Bucket + } + if *bucket == "" { + t.Fatal("bucket not provided in config file or as a flag.") } if *clientID == "" || *clientSecret == "" { - t.Fatal("--client_id and --client_secret required. Obtain from https://console.developers.google.com/ > Project > APIs & Auth > Credentials. Should be a 'native' or 'Installed application'") + t.Fatal("client ID and client secret required. Obtain from https://console.developers.google.com/ > Project > APIs & Auth > Credentials. Should be a 'native' or 'Installed application'") } - - config := &oauth2.Config{ - Scopes: []string{googlestorage.Scope}, - Endpoint: google.Endpoint, - ClientID: *clientID, - ClientSecret: *clientSecret, - RedirectURL: oauthutil.TitleBarRedirectURL, - } - token, err := oauth2.ReuseTokenSource(nil, - &oauthutil.TokenSource{ - Config: config, - CacheFile: *tokenCache, - AuthCode: func() string { - if *authCode == "" { - t.Skipf("Re-run using --auth_code= with the value obtained from %s", - config.AuthCodeURL("", oauth2.AccessTypeOffline, oauth2.ApprovalForce)) - return "" - } - return *authCode - }, - }).Token() - if err != nil { - t.Fatalf("could not acquire token: %v", err) + if *configFile == "" { + config := &oauth2.Config{ + Scopes: []string{googlestorage.Scope}, + Endpoint: google.Endpoint, + ClientID: *clientID, + ClientSecret: *clientSecret, + RedirectURL: oauthutil.TitleBarRedirectURL, + } + token, err := oauth2.ReuseTokenSource(nil, + &oauthutil.TokenSource{ + Config: config, + CacheFile: *tokenCache, + AuthCode: func() string { + if *authCode == "" { + t.Skipf("Re-run using --auth_code= with the value obtained from %s", + config.AuthCodeURL("", oauth2.AccessTypeOffline, oauth2.ApprovalForce)) + return "" + } + return *authCode + }, + }).Token() + if err != nil { + t.Fatalf("could not acquire token: %v", err) + } + refreshToken = token.RefreshToken } bucketWithDir := path.Join(*bucket, bucketDir) @@ -97,7 +126,7 @@ func testStorage(t *testing.T, bucketDir string) { "auth": map[string]interface{}{ "client_id": *clientID, "client_secret": *clientSecret, - "refresh_token": token.RefreshToken, + "refresh_token": refreshToken, }, }) if err != nil { @@ -106,6 +135,14 @@ func testStorage(t *testing.T, bucketDir string) { if !testing.Short() { log.Printf("Warning: this test does many serial operations. Without the go test -short flag, this test will be very slow.") } + // Bail if bucket is not empty + objs, err := sto.(*Storage).client.EnumerateObjects(*bucket, "", 1) + if err != nil { + t.Fatalf("Error checking if bucket is empty: %v", err) + } + if len(objs) != 0 { + t.Fatalf("Refusing to run test: bucket %v is not empty", *bucket) + } if bucketWithDir != *bucket { // Adding "a", and "c" objects in the bucket to make sure objects out of the // "directory" are not touched and have no influence.