func TestChooseVersionFromSuffix(t *testing.T) { testhelper.SetupHTTP() defer testhelper.TeardownHTTP() v2 := &Version{ID: "v2.0", Priority: 2, Suffix: "/v2.0/"} v3 := &Version{ID: "v3.0", Priority: 3, Suffix: "/v3.0/"} c := &gophercloud.ProviderClient{ IdentityBase: testhelper.Endpoint(), IdentityEndpoint: testhelper.Endpoint() + "v2.0/", } v, endpoint, err := ChooseVersion(c, []*Version{v2, v3}) if err != nil { t.Fatalf("Unexpected error from ChooseVersion: %v", err) } if v != v2 { t.Errorf("Expected %#v to win, but %#v did instead", v2, v) } expected := testhelper.Endpoint() + "v2.0/" if endpoint != expected { t.Errorf("Expected endpoint [%s], but was [%s] instead", expected, endpoint) } }
func registerRoot() { th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { "versions": { "values": [ { "status": "experimental", "id": "v3.0", "links": [ { "href": "%s", "rel": "self" } ] }, { "status": "stable", "id": "v2.0", "links": [ { "href": "%s", "rel": "self" } ] } ] } } `, th.Endpoint()+"v3/", th.Endpoint()+"v2.0/") }) }
func TestURLs(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() th.AssertEquals(t, th.Endpoint()+"v2.0/lbaas/loadbalancers", rootURL(fake.ServiceClient())) th.AssertEquals(t, th.Endpoint()+"v2.0/lbaas/loadbalancers/foo", resourceURL(fake.ServiceClient(), "foo")) }
func TestURLs(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() th.AssertEquals(t, th.Endpoint()+"v2.0/security-groups", rootURL(fake.ServiceClient())) th.AssertEquals(t, th.Endpoint()+"v2.0/security-groups/foo", resourceURL(fake.ServiceClient(), "foo")) }
func registerCinderApi(s *CollectorSuite) { th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) fmt.Fprintf(w, ` { "versions": [ { "id": "v1.0", "links": [ { "href": "%s", "rel": "self" } ], "status": "SUPPORTED", "updated": "2014-06-28T12:20:21Z" }, { "id": "v2.0", "links": [ { "href": "%s", "rel": "self" } ], "status": "CURRENT", "updated": "2012-11-21T11:33:21Z" } ] } `, th.Endpoint()+"v1", th.Endpoint()+"v2") }) }
func TestTokenURL(t *testing.T) { testhelper.SetupHTTP() defer testhelper.TeardownHTTP() client := gophercloud.ServiceClient{Endpoint: testhelper.Endpoint()} expected := testhelper.Endpoint() + "auth/tokens" actual := tokenURL(&client) if actual != expected { t.Errorf("Expected URL %s, but was %s", expected, actual) } }
func TestAuthenticatedClientV2(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() th.Mux.HandleFunc("/v2.0/tokens", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { "access": { "token": { "id": "01234567890", "expires": "2014-10-01T10:00:00.000000Z" }, "serviceCatalog": [] } } `) }) options := gophercloud.AuthOptions{ Username: "******", APIKey: "09876543210", IdentityEndpoint: th.Endpoint() + "v2.0/", } client, err := AuthenticatedClient(options) th.AssertNoErr(t, err) th.CheckEquals(t, "01234567890", client.TokenID) }
func (s *CinderV2Suite) TestGetVolumes() { Convey("Given Cinder volumes are requested", s.T(), func() { Convey("When authentication is required", func() { provider, err := openstackintel.Authenticate(th.Endpoint(), "me", "secret", "tenant") th.AssertNoErr(s.T(), err) th.CheckEquals(s.T(), s.Token, provider.TokenID) Convey("and GetVolumes called", func() { dispatch := ServiceV2{} volumes, err := dispatch.GetVolumes(provider) Convey("Then proper limits values are returned", func() { So(len(volumes), ShouldEqual, 2) So(volumes[s.Tenant1ID].Bytes, ShouldEqual, s.Vol1Size*1024*1024*1024) So(volumes[s.Tenant2ID].Bytes, ShouldEqual, s.Vol2Size*1024*1024*1024) So(volumes[s.Tenant1ID].Count, ShouldEqual, 1) So(volumes[s.Tenant2ID].Count, ShouldEqual, 1) }) Convey("and no error reported", func() { So(err, ShouldBeNil) }) }) }) }) }
func TestGetRequest(t *testing.T) { testhelper.SetupHTTP() defer testhelper.TeardownHTTP() client := gophercloud.ServiceClient{ ProviderClient: &gophercloud.ProviderClient{ TokenID: "12345abcdef", }, Endpoint: testhelper.Endpoint(), } testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { testhelper.TestMethod(t, r, "GET") testhelper.TestHeader(t, r, "Content-Type", "") testhelper.TestHeader(t, r, "Accept", "application/json") testhelper.TestHeader(t, r, "X-Auth-Token", "12345abcdef") testhelper.TestHeader(t, r, "X-Subject-Token", "abcdef12345") w.WriteHeader(http.StatusOK) fmt.Fprintf(w, ` { "token": { "expires_at": "2014-08-29T13:10:01.000000Z" } } `) }) token, err := Get(&client, "abcdef12345").Extract() if err != nil { t.Errorf("Info returned an error: %v", err) } expected, _ := time.Parse(time.UnixDate, "Fri Aug 29 13:10:01 UTC 2014") if token.ExpiresAt != expected { t.Errorf("Expected expiration time %s, but was %s", expected.Format(time.UnixDate), token.ExpiresAt.Format(time.UnixDate)) } }
func TestCreateExtractsTokenFromResponse(t *testing.T) { testhelper.SetupHTTP() defer testhelper.TeardownHTTP() client := gophercloud.ServiceClient{ ProviderClient: &gophercloud.ProviderClient{}, Endpoint: testhelper.Endpoint(), } testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { w.Header().Add("X-Subject-Token", "aaa111") w.WriteHeader(http.StatusCreated) fmt.Fprintf(w, `{ "token": { "expires_at": "2014-10-02T13:45:00.000000Z" } }`) }) options := gophercloud.AuthOptions{UserID: "me", Password: "******"} token, err := Create(&client, options, nil).Extract() if err != nil { t.Fatalf("Create returned an error: %v", err) } if token.ID != "aaa111" { t.Errorf("Expected token to be aaa111, but was %s", token.ID) } }
// authTokenPost verifies that providing certain AuthOptions and Scope results in an expected JSON structure. func authTokenPost(t *testing.T, options gophercloud.AuthOptions, scope *tokens.Scope, requestJSON string) { testhelper.SetupHTTP() defer testhelper.TeardownHTTP() client := gophercloud.ServiceClient{ ProviderClient: &gophercloud.ProviderClient{ TokenID: options.TokenID, }, Endpoint: testhelper.Endpoint(), } testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { testhelper.TestMethod(t, r, "POST") testhelper.TestHeader(t, r, "Content-Type", "application/json") testhelper.TestHeader(t, r, "Accept", "application/json") testhelper.TestJSONRequest(t, r, requestJSON) w.WriteHeader(http.StatusCreated) fmt.Fprintf(w, `{ "token": { "expires_at": "2014-10-02T13:45:00.000000Z" } }`) }) _, err := tokens.Create(&client, AuthOptionsExt{AuthOptions: tokens.AuthOptions{options}, TrustID: "123456"}, scope).Extract() if err != nil { t.Errorf("Create returned an error: %v", err) } }
func TestAuthenticatedClientV3(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() const ID = "0123456789" th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { "versions": { "values": [ { "status": "stable", "id": "v3.0", "links": [ { "href": "%s", "rel": "self" } ] }, { "status": "stable", "id": "v2.0", "links": [ { "href": "%s", "rel": "self" } ] } ] } } `, th.Endpoint()+"v3/", th.Endpoint()+"v2.0/") }) th.Mux.HandleFunc("/v3/auth/tokens", func(w http.ResponseWriter, r *http.Request) { w.Header().Add("X-Subject-Token", ID) w.WriteHeader(http.StatusCreated) fmt.Fprintf(w, `{ "token": { "expires_at": "2013-02-02T18:30:59.000000Z" } }`) }) options := gophercloud.AuthOptions{ UserID: "me", Password: "******", IdentityEndpoint: th.Endpoint(), } client, err := AuthenticatedClient(options) th.AssertNoErr(t, err) th.CheckEquals(t, ID, client.TokenID) }
func TestChooseVersionOpinionatedLink(t *testing.T) { testhelper.SetupHTTP() defer testhelper.TeardownHTTP() setupVersionHandler() v2 := &Version{ID: "v2.0", Priority: 2, Suffix: "nope"} v3 := &Version{ID: "v3.0", Priority: 3, Suffix: "northis"} v, endpoint, err := ChooseVersion(testhelper.Endpoint(), testhelper.Endpoint()+"v2.0/", []*Version{v2, v3}) if err != nil { t.Fatalf("Unexpected error from ChooseVersion: %v", err) } if v != v2 { t.Errorf("Expected %#v to win, but %#v did instead", v2, v) } expected := testhelper.Endpoint() + "v2.0/" if endpoint != expected { t.Errorf("Expected endpoint [%s], but was [%s] instead", expected, endpoint) } }
func (s *CommonSuite) TestGetTenants() { Convey("Given tenants are requested", s.T(), func() { c := Common{} Convey("When Gettenants is called", func() { tenants, err := c.GetTenants(th.Endpoint(), "me", "secret") Convey("Then list of available tenats is returned", func() { So(len(tenants), ShouldEqual, 2) So(tenants[s.Tenant1ID], ShouldEqual, s.Tenant1Name) So(tenants[s.Tenant2ID], ShouldEqual, s.Tenant2Name) So(err, ShouldBeNil) }) }) }) }
func TestKeystoneLogin(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() const ID = "0123456789" th.Mux.HandleFunc("/v3/auth/tokens", func(w http.ResponseWriter, r *http.Request) { w.Header().Add("X-Subject-Token", ID) type AuthRequest struct { Auth struct { Identity struct { Password struct { User struct { Domain struct{ Name string } Name string Password string } } } } } var x AuthRequest body, _ := ioutil.ReadAll(r.Body) json.Unmarshal(body, &x) domainName := x.Auth.Identity.Password.User.Domain.Name userName := x.Auth.Identity.Password.User.Name password := x.Auth.Identity.Password.User.Password if domainName == "default" && userName == "testuser" && password == "testpw" { w.WriteHeader(http.StatusCreated) fmt.Fprintf(w, `{ "token": { "expires_at": "2020-02-02T18:30:59.000000Z" } }`) } else { w.WriteHeader(http.StatusUnauthorized) } }) keystoneAuth := New("keystone_auth", th.Endpoint(), http.DefaultTransport, "default", &TestUserIdentityMapper{}) _, ok, err := keystoneAuth.AuthenticatePassword("testuser", "testpw") th.AssertNoErr(t, err) th.CheckEquals(t, ok, true) _, ok, err = keystoneAuth.AuthenticatePassword("testuser", "badpw") th.AssertNoErr(t, err) th.CheckEquals(t, ok, false) _, ok, err = keystoneAuth.AuthenticatePassword("testuser", "") th.AssertNoErr(t, err) th.CheckEquals(t, ok, false) }
func authTokenPostErr(t *testing.T, options gophercloud.AuthOptions, scope *tokens.Scope, includeToken bool, expectedErr error) { testhelper.SetupHTTP() defer testhelper.TeardownHTTP() client := gophercloud.ServiceClient{ ProviderClient: &gophercloud.ProviderClient{}, Endpoint: testhelper.Endpoint(), } if includeToken { client.TokenID = "abcdef123456" } _, err := tokens.Create(&client, AuthOptionsExt{AuthOptions: tokens.AuthOptions{options}, TrustID: "123456"}, scope).Extract() if err == nil { t.Errorf("Create did NOT return an error") } if err != expectedErr { t.Errorf("Create returned an unexpected error: wanted %v, got %v", expectedErr, err) } }
func prepareAuthTokenHandler(t *testing.T, expectedMethod string, status int) gophercloud.ServiceClient { client := gophercloud.ServiceClient{ ProviderClient: &gophercloud.ProviderClient{ TokenID: "12345abcdef", }, Endpoint: testhelper.Endpoint(), } testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { testhelper.TestMethod(t, r, expectedMethod) testhelper.TestHeader(t, r, "Content-Type", "") testhelper.TestHeader(t, r, "Accept", "application/json") testhelper.TestHeader(t, r, "X-Auth-Token", "12345abcdef") testhelper.TestHeader(t, r, "X-Subject-Token", "abcdef12345") w.WriteHeader(status) }) return client }
func (s *CinderV2Suite) TestGetLimits() { Convey("Given Cinder absolute limits are requested", s.T(), func() { Convey("When authentication is required", func() { provider, err := openstackintel.Authenticate(th.Endpoint(), "me", "secret", "tenant") th.AssertNoErr(s.T(), err) th.CheckEquals(s.T(), s.Token, provider.TokenID) Convey("and GetLimits called", func() { dispatch := ServiceV2{} limits, err := dispatch.GetLimits(provider) Convey("Then proper limits values are returned", func() { So(limits.MaxTotalVolumes, ShouldEqual, s.MaxTotalVolumes) So(limits.MaxTotalVolumeGigabytes, ShouldEqual, s.MaxTotalVolumeGigabytes) }) Convey("and no error reported", func() { So(err, ShouldBeNil) }) }) }) }) }
func TestURLs(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() th.AssertEquals(t, th.Endpoint()+"v2.0/fw/firewalls", rootURL(fake.ServiceClient())) }
func (s *CommonSuite) TestGetAPI() { Convey("Given api versions are requested", s.T(), func() { c := Common{} Convey("When GetAPIVersions is called", func() { provider, err := Authenticate(th.Endpoint(), "me", "secret", "tenant") th.AssertNoErr(s.T(), err) th.CheckEquals(s.T(), s.Token, provider.TokenID) server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) fmt.Fprintf(w, ` { "versions": [ { "id": "v1.0", "links": [ { "href": "http://192.168.20.2:8776/v1/", "rel": "self" } ], "status": "SUPPORTED", "updated": "2014-06-28T12:20:21Z" }, { "id": "v2.0", "links": [ { "href": "http://192.168.20.2:8776/v2/", "rel": "self" } ], "status": "CURRENT", "updated": "2012-11-21T11:33:21Z" } ] } `) })) defer server.Close() transport := &http.Transport{ Proxy: func(req *http.Request) (*url.URL, error) { return url.Parse(server.URL) }, } httpClient := http.Client{Transport: transport} provider.HTTPClient = httpClient apis, err := c.GetApiVersions(provider) Convey("Then list of available versions is returned", func() { So(len(apis), ShouldEqual, 2) So(apis[0], ShouldEqual, "v1.0") So(apis[1], ShouldEqual, "v2.0") So(err, ShouldBeNil) }) }) }) }
func TestURLs(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() th.AssertEquals(t, th.Endpoint()+"v2.0/lbaas/healthmonitors", rootURL(fake.ServiceClient())) }
func TestAuthenticatedClientV2(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { "versions": { "values": [ { "status": "experimental", "id": "v3.0", "links": [ { "href": "%s", "rel": "self" } ] }, { "status": "stable", "id": "v2.0", "links": [ { "href": "%s", "rel": "self" } ] } ] } } `, th.Endpoint()+"v3/", th.Endpoint()+"v2.0/") }) th.Mux.HandleFunc("/v2.0/tokens", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { "access": { "token": { "id": "01234567890", "expires": "2014-10-01T10:00:00.000000Z" }, "serviceCatalog": [ { "name": "Cloud Servers", "type": "compute", "endpoints": [ { "tenantId": "t1000", "publicURL": "https://compute.north.host.com/v1/t1000", "internalURL": "https://compute.north.internal/v1/t1000", "region": "North", "versionId": "1", "versionInfo": "https://compute.north.host.com/v1/", "versionList": "https://compute.north.host.com/" }, { "tenantId": "t1000", "publicURL": "https://compute.north.host.com/v1.1/t1000", "internalURL": "https://compute.north.internal/v1.1/t1000", "region": "North", "versionId": "1.1", "versionInfo": "https://compute.north.host.com/v1.1/", "versionList": "https://compute.north.host.com/" } ], "endpoints_links": [] }, { "name": "Cloud Files", "type": "object-store", "endpoints": [ { "tenantId": "t1000", "publicURL": "https://storage.north.host.com/v1/t1000", "internalURL": "https://storage.north.internal/v1/t1000", "region": "North", "versionId": "1", "versionInfo": "https://storage.north.host.com/v1/", "versionList": "https://storage.north.host.com/" }, { "tenantId": "t1000", "publicURL": "https://storage.south.host.com/v1/t1000", "internalURL": "https://storage.south.internal/v1/t1000", "region": "South", "versionId": "1", "versionInfo": "https://storage.south.host.com/v1/", "versionList": "https://storage.south.host.com/" } ] } ] } } `) }) options := gophercloud.AuthOptions{ Username: "******", Password: "******", IdentityEndpoint: th.Endpoint(), } client, err := AuthenticatedClient(options) th.AssertNoErr(t, err) th.CheckEquals(t, "01234567890", client.TokenID) }
func registerIdentityToken(s *CollectorSuite, r *mux.Router) { r.HandleFunc("/v2.0/tokens", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { "access": { "metadata": { "is_admin": 0, "roles": [ "3083d61996d648ca88d6ff420542f324" ] }, "serviceCatalog": [ { "endpoints": [ { "adminURL": "%s", "id": "3ffe125aa59547029ed774c10b932349", "internalURL": "%s", "publicURL": "%s", "region": "RegionOne" } ], "endpoints_links": [], "name": "cinderv2", "type": "volumev2" }, { "endpoints": [ { "adminURL": "%s", "id": "a056ce874d414393a946e42e920ce157", "internalURL": "%s", "publicURL": "%s", "region": "RegionOne" } ], "endpoints_links": [], "name": "cinder", "type": "volume" } ], "token": { "expires": "2016-02-21T14:28:30Z", "id": "%s", "issued_at": "2016-02-21T13:28:30.656527", "tenant": { "description": null, "enabled": true, "id": "97ea299c37bb4e04b3779039ea8aba44", "name": "tenant" } } } } `, th.Endpoint()+s.V2, th.Endpoint()+s.V2, th.Endpoint()+s.V2, th.Endpoint()+s.V1, th.Endpoint()+s.V1, th.Endpoint()+s.V1, s.Token) }) }
// ServiceClient returns a generic service client for use in tests. func ServiceClient() *gophercloud.ServiceClient { return &gophercloud.ServiceClient{ ProviderClient: &gophercloud.ProviderClient{TokenID: TokenID}, Endpoint: testhelper.Endpoint(), } }
func createClient() *gophercloud.ServiceClient { return &gophercloud.ServiceClient{ ProviderClient: &gophercloud.ProviderClient{TokenID: "abc123"}, Endpoint: testhelper.Endpoint(), } }
// this client's Get method first changes the URL given to point to // testhelper's (th) endpoints. This is done because the http Mux does not seem // to work for fqdns with the `file` scheme func (c fakeClient) Get(url string) (*http.Response, error) { newurl := strings.Replace(url, "file://", th.Endpoint(), 1) return c.BaseClient.Get(newurl) }