volumetypes unit tests; 'Extract' method for consistency; rename blockStorage to blockstorage and volumeTypes to volumetypes
diff --git a/acceptance/openstack/blockStorage/v1/blockstorage_test.go.bak b/acceptance/openstack/blockstorage/v1/blockstorage_test.go.bak
similarity index 100%
rename from acceptance/openstack/blockStorage/v1/blockstorage_test.go.bak
rename to acceptance/openstack/blockstorage/v1/blockstorage_test.go.bak
diff --git a/acceptance/openstack/blockStorage/v1/snapshots_test.go b/acceptance/openstack/blockstorage/v1/snapshots_test.go
similarity index 100%
rename from acceptance/openstack/blockStorage/v1/snapshots_test.go
rename to acceptance/openstack/blockstorage/v1/snapshots_test.go
diff --git a/acceptance/openstack/blockStorage/v1/volumes_test.go b/acceptance/openstack/blockstorage/v1/volumes_test.go
similarity index 100%
rename from acceptance/openstack/blockStorage/v1/volumes_test.go
rename to acceptance/openstack/blockstorage/v1/volumes_test.go
diff --git a/acceptance/openstack/blockStorage/v1/volumeTypes_test.go b/acceptance/openstack/blockstorage/v1/volumetypes_test.go
similarity index 94%
rename from acceptance/openstack/blockStorage/v1/volumeTypes_test.go
rename to acceptance/openstack/blockstorage/v1/volumetypes_test.go
index 0317768..be0d2d8 100644
--- a/acceptance/openstack/blockStorage/v1/volumeTypes_test.go
+++ b/acceptance/openstack/blockstorage/v1/volumetypes_test.go
@@ -6,7 +6,7 @@
"testing"
"time"
- "github.com/rackspace/gophercloud/openstack/blockStorage/v1/volumeTypes"
+ "github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes"
"github.com/rackspace/gophercloud/pagination"
)
diff --git a/openstack/blockStorage/v1/volumeTypes/requests.go b/openstack/blockStorage/v1/volumeTypes/requests.go
deleted file mode 100644
index 42c4a8b..0000000
--- a/openstack/blockStorage/v1/volumeTypes/requests.go
+++ /dev/null
@@ -1,79 +0,0 @@
-package volumeTypes
-
-import (
- "github.com/racker/perigee"
- "github.com/rackspace/gophercloud"
- "github.com/rackspace/gophercloud/openstack/utils"
- "github.com/rackspace/gophercloud/pagination"
-)
-
-type CreateOpts struct {
- ExtraSpecs map[string]interface{}
- Name string
-}
-
-func Create(client *gophercloud.ServiceClient, opts CreateOpts) (*VolumeType, error) {
- type volumeType struct {
- ExtraSpecs map[string]interface{} `json:"extra_specs,omitempty"`
- Name *string `json:"name,omitempty"`
- }
-
- type request struct {
- VolumeType volumeType `json:"volume_type"`
- }
-
- reqBody := request{
- VolumeType: volumeType{},
- }
-
- reqBody.VolumeType.Name = utils.MaybeString(opts.Name)
- reqBody.VolumeType.ExtraSpecs = opts.ExtraSpecs
-
- type response struct {
- VolumeType VolumeType `json:"volume_type"`
- }
-
- var respBody response
-
- _, err := perigee.Request("POST", volumeTypesURL(client), perigee.Options{
- MoreHeaders: client.Provider.AuthenticatedHeaders(),
- OkCodes: []int{200},
- ReqBody: &reqBody,
- Results: &respBody,
- })
- if err != nil {
- return nil, err
- }
-
- return &respBody.VolumeType, nil
-
-}
-
-func Delete(client *gophercloud.ServiceClient, id string) error {
- _, err := perigee.Request("DELETE", volumeTypeURL(client, id), perigee.Options{
- MoreHeaders: client.Provider.AuthenticatedHeaders(),
- OkCodes: []int{202},
- })
- return err
-}
-
-func Get(client *gophercloud.ServiceClient, id string) GetResult {
- var gr GetResult
- _, gr.Err = perigee.Request("GET", volumeTypeURL(client, id), perigee.Options{
- Results: &gr.Resp,
- MoreHeaders: client.Provider.AuthenticatedHeaders(),
- })
- return gr
-}
-
-// ListOpts holds options for listing volumes. It is passed to the volumes.List function.
-type ListOpts struct {
-}
-
-func List(client *gophercloud.ServiceClient, opts ListOpts) pagination.Pager {
- createPage := func(r pagination.LastHTTPResponse) pagination.Page {
- return ListResult{pagination.SinglePageBase(r)}
- }
-
- return pagination.NewPager(client, volumeTypesURL(client), createPage)
-}
diff --git a/openstack/blockStorage/v1/volumeTypes/requests_test.go b/openstack/blockStorage/v1/volumeTypes/requests_test.go
deleted file mode 100644
index 3051821..0000000
--- a/openstack/blockStorage/v1/volumeTypes/requests_test.go
+++ /dev/null
@@ -1 +0,0 @@
-package volumeTypes
diff --git a/openstack/blockStorage/v1/volumeTypes/urls.go b/openstack/blockStorage/v1/volumeTypes/urls.go
deleted file mode 100644
index 8df75cd..0000000
--- a/openstack/blockStorage/v1/volumeTypes/urls.go
+++ /dev/null
@@ -1,11 +0,0 @@
-package volumeTypes
-
-import "github.com/rackspace/gophercloud"
-
-func volumeTypesURL(c *gophercloud.ServiceClient) string {
- return c.ServiceURL("types")
-}
-
-func volumeTypeURL(c *gophercloud.ServiceClient, id string) string {
- return c.ServiceURL("types", id)
-}
diff --git a/openstack/blockStorage/v1/volumeTypes/urls_test.go b/openstack/blockStorage/v1/volumeTypes/urls_test.go
deleted file mode 100644
index 492f6e7..0000000
--- a/openstack/blockStorage/v1/volumeTypes/urls_test.go
+++ /dev/null
@@ -1,26 +0,0 @@
-package volumeTypes
-
-import (
- "testing"
-
- "github.com/rackspace/gophercloud"
- th "github.com/rackspace/gophercloud/testhelper"
-)
-
-const endpoint = "http://localhost:57909"
-
-func endpointClient() *gophercloud.ServiceClient {
- return &gophercloud.ServiceClient{Endpoint: endpoint}
-}
-
-func TestVolumeTypesURL(t *testing.T) {
- actual := volumeTypesURL(endpointClient())
- expected := endpoint + "types"
- th.AssertEquals(t, expected, actual)
-}
-
-func TestVolumeTypeURL(t *testing.T) {
- actual := volumeTypeURL(endpointClient(), "foo")
- expected := endpoint + "types/foo"
- th.AssertEquals(t, expected, actual)
-}
diff --git a/openstack/blockStorage/v1/snapshots/requests.go b/openstack/blockstorage/v1/snapshots/requests.go
similarity index 100%
rename from openstack/blockStorage/v1/snapshots/requests.go
rename to openstack/blockstorage/v1/snapshots/requests.go
diff --git a/openstack/blockStorage/v1/snapshots/requests_test.go b/openstack/blockstorage/v1/snapshots/requests_test.go
similarity index 100%
rename from openstack/blockStorage/v1/snapshots/requests_test.go
rename to openstack/blockstorage/v1/snapshots/requests_test.go
diff --git a/openstack/blockStorage/v1/snapshots/results.go b/openstack/blockstorage/v1/snapshots/results.go
similarity index 100%
rename from openstack/blockStorage/v1/snapshots/results.go
rename to openstack/blockstorage/v1/snapshots/results.go
diff --git a/openstack/blockStorage/v1/snapshots/urls.go b/openstack/blockstorage/v1/snapshots/urls.go
similarity index 100%
rename from openstack/blockStorage/v1/snapshots/urls.go
rename to openstack/blockstorage/v1/snapshots/urls.go
diff --git a/openstack/blockStorage/v1/snapshots/urls_test.go b/openstack/blockstorage/v1/snapshots/urls_test.go
similarity index 100%
rename from openstack/blockStorage/v1/snapshots/urls_test.go
rename to openstack/blockstorage/v1/snapshots/urls_test.go
diff --git a/openstack/blockStorage/v1/volumes/requests.go b/openstack/blockstorage/v1/volumes/requests.go
similarity index 100%
rename from openstack/blockStorage/v1/volumes/requests.go
rename to openstack/blockstorage/v1/volumes/requests.go
diff --git a/openstack/blockStorage/v1/volumes/requests_test.go b/openstack/blockstorage/v1/volumes/requests_test.go
similarity index 100%
rename from openstack/blockStorage/v1/volumes/requests_test.go
rename to openstack/blockstorage/v1/volumes/requests_test.go
diff --git a/openstack/blockStorage/v1/volumes/results.go b/openstack/blockstorage/v1/volumes/results.go
similarity index 100%
rename from openstack/blockStorage/v1/volumes/results.go
rename to openstack/blockstorage/v1/volumes/results.go
diff --git a/openstack/blockStorage/v1/volumes/urls.go b/openstack/blockstorage/v1/volumes/urls.go
similarity index 100%
rename from openstack/blockStorage/v1/volumes/urls.go
rename to openstack/blockstorage/v1/volumes/urls.go
diff --git a/openstack/blockStorage/v1/volumes/urls_test.go b/openstack/blockstorage/v1/volumes/urls_test.go
similarity index 100%
rename from openstack/blockStorage/v1/volumes/urls_test.go
rename to openstack/blockstorage/v1/volumes/urls_test.go
diff --git a/openstack/blockstorage/v1/volumetypes/requests.go b/openstack/blockstorage/v1/volumetypes/requests.go
new file mode 100644
index 0000000..be6bf09
--- /dev/null
+++ b/openstack/blockstorage/v1/volumetypes/requests.go
@@ -0,0 +1,71 @@
+package volumetypes
+
+import (
+ "fmt"
+ "github.com/racker/perigee"
+ "github.com/rackspace/gophercloud"
+ "github.com/rackspace/gophercloud/openstack/utils"
+ "github.com/rackspace/gophercloud/pagination"
+)
+
+type CreateOpts struct {
+ ExtraSpecs map[string]interface{}
+ Name string
+}
+
+func Create(client *gophercloud.ServiceClient, opts CreateOpts) CreateResult {
+ type volumeType struct {
+ ExtraSpecs map[string]interface{} `json:"extra_specs,omitempty"`
+ Name *string `json:"name,omitempty"`
+ }
+
+ type request struct {
+ VolumeType volumeType `json:"volume_type"`
+ }
+
+ reqBody := request{
+ VolumeType: volumeType{},
+ }
+
+ reqBody.VolumeType.Name = utils.MaybeString(opts.Name)
+ reqBody.VolumeType.ExtraSpecs = opts.ExtraSpecs
+
+ var res CreateResult
+ _, res.Err = perigee.Request("POST", createURL(client), perigee.Options{
+ MoreHeaders: client.Provider.AuthenticatedHeaders(),
+ OkCodes: []int{200},
+ ReqBody: &reqBody,
+ Results: &res.Resp,
+ })
+ return res
+}
+
+func Delete(client *gophercloud.ServiceClient, id string) DeleteResult {
+ var res DeleteResult
+ _, err := perigee.Request("DELETE", deleteURL(client, id), perigee.Options{
+ MoreHeaders: client.Provider.AuthenticatedHeaders(),
+ OkCodes: []int{202},
+ })
+ res.Err = err
+ return res
+}
+
+func Get(client *gophercloud.ServiceClient, id string) GetResult {
+ var res GetResult
+ resp, err := perigee.Request("GET", getURL(client, id), perigee.Options{
+ MoreHeaders: client.Provider.AuthenticatedHeaders(),
+ OkCodes: []int{200},
+ Results: &res.Resp,
+ })
+ res.Err = err
+ fmt.Printf("resp: %+v\n", resp)
+ return res
+}
+
+func List(client *gophercloud.ServiceClient) pagination.Pager {
+ createPage := func(r pagination.LastHTTPResponse) pagination.Page {
+ return ListResult{pagination.SinglePageBase(r)}
+ }
+
+ return pagination.NewPager(client, listURL(client), createPage)
+}
diff --git a/openstack/blockstorage/v1/volumetypes/requests_test.go b/openstack/blockstorage/v1/volumetypes/requests_test.go
new file mode 100644
index 0000000..5f83e04
--- /dev/null
+++ b/openstack/blockstorage/v1/volumetypes/requests_test.go
@@ -0,0 +1,174 @@
+package volumetypes
+
+import (
+ "fmt"
+ "net/http"
+ "testing"
+
+ "github.com/rackspace/gophercloud"
+ "github.com/rackspace/gophercloud/pagination"
+ th "github.com/rackspace/gophercloud/testhelper"
+)
+
+const TokenID = "123"
+
+func ServiceClient() *gophercloud.ServiceClient {
+ return &gophercloud.ServiceClient{
+ Provider: &gophercloud.ProviderClient{
+ TokenID: TokenID,
+ },
+ Endpoint: th.Endpoint(),
+ }
+}
+
+func TestList(t *testing.T) {
+ th.SetupHTTP()
+ defer th.TeardownHTTP()
+
+ th.Mux.HandleFunc("/types", func(w http.ResponseWriter, r *http.Request) {
+ th.TestMethod(t, r, "GET")
+ th.TestHeader(t, r, "X-Auth-Token", TokenID)
+
+ w.Header().Add("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+
+ fmt.Fprintf(w, `
+ {
+ "volume_types": [
+ {
+ "id": "289da7f8-6440-407c-9fb4-7db01ec49164",
+ "name": "vol-type-001",
+ "extra_specs": {
+ "capabilities": "gpu"
+ }
+ },
+ {
+ "id": "96c3bda7-c82a-4f50-be73-ca7621794835",
+ "name": "vol-type-002",
+ "extra_specs": {}
+ }
+ ]
+ }
+ `)
+ })
+
+ client := ServiceClient()
+ count := 0
+
+ List(client).EachPage(func(page pagination.Page) (bool, error) {
+ count++
+ actual, err := ExtractVolumeTypes(page)
+ if err != nil {
+ t.Errorf("Failed to extract volume types: %v", err)
+ return false, err
+ }
+
+ expected := []VolumeType{
+ VolumeType{
+ ID: "289da7f8-6440-407c-9fb4-7db01ec49164",
+ Name: "vol-type-001",
+ ExtraSpecs: map[string]interface{}{
+ "capabilities": "gpu",
+ },
+ },
+ VolumeType{
+ ID: "96c3bda7-c82a-4f50-be73-ca7621794835",
+ Name: "vol-type-002",
+ ExtraSpecs: map[string]interface{}{},
+ },
+ }
+
+ th.CheckDeepEquals(t, expected, actual)
+
+ return true, nil
+ })
+
+ if count != 1 {
+ t.Errorf("Expected 1 page, got %d", count)
+ }
+}
+
+func TestGet(t *testing.T) {
+ th.SetupHTTP()
+ defer th.TeardownHTTP()
+
+ th.Mux.HandleFunc("/types/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) {
+ th.TestMethod(t, r, "GET")
+ th.TestHeader(t, r, "X-Auth-Token", TokenID)
+
+ w.Header().Add("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+ fmt.Fprintf(w, `
+{
+ "volume_type": {
+ "name": "vol-type-001",
+ "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22"
+ "extra_specs": {
+ "serverNumber": 2
+ }
+ }
+}
+ `)
+ })
+
+ vt, err := Get(ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract()
+ th.AssertNoErr(t, err)
+
+ t.Logf("vt: %+v\n", vt)
+ th.AssertDeepEquals(t, vt.ExtraSpecs, map[string]interface{}{"serverNumber": 2})
+ th.AssertEquals(t, vt.Name, "vol-type-001")
+ th.AssertEquals(t, vt.ID, "d32019d3-bc6e-4319-9c1d-6722fc136a22")
+}
+
+func TestCreate(t *testing.T) {
+ th.SetupHTTP()
+ defer th.TeardownHTTP()
+
+ th.Mux.HandleFunc("/types", func(w http.ResponseWriter, r *http.Request) {
+ th.TestMethod(t, r, "POST")
+ th.TestHeader(t, r, "X-Auth-Token", TokenID)
+ th.TestHeader(t, r, "Content-Type", "application/json")
+ th.TestHeader(t, r, "Accept", "application/json")
+ th.TestJSONRequest(t, r, `
+{
+ "volume_type": {
+ "name": "vol-type-001",
+ "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22"
+ }
+}
+ `)
+
+ w.Header().Add("Content-Type", "application/json")
+ w.WriteHeader(http.StatusCreated)
+
+ fmt.Fprintf(w, `
+{
+ "volume_type": {
+ "name": "vol-type-001",
+ "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22"
+ }
+}
+ `)
+ })
+
+ options := CreateOpts{Name: "vol-type-001"}
+ n, err := Create(ServiceClient(), options).Extract()
+ th.AssertNoErr(t, err)
+
+ th.AssertEquals(t, n.Name, "vol-type-001")
+ th.AssertEquals(t, n.ID, "d32019d3-bc6e-4319-9c1d-6722fc136a22")
+}
+
+func TestDelete(t *testing.T) {
+ th.SetupHTTP()
+ defer th.TeardownHTTP()
+
+ th.Mux.HandleFunc("/types/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) {
+ th.TestMethod(t, r, "DELETE")
+ th.TestHeader(t, r, "X-Auth-Token", TokenID)
+ w.WriteHeader(http.StatusNoContent)
+ })
+
+ res := Delete(ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22")
+ th.AssertNoErr(t, res.Err)
+}
diff --git a/openstack/blockStorage/v1/volumeTypes/results.go b/openstack/blockstorage/v1/volumetypes/results.go
similarity index 63%
rename from openstack/blockStorage/v1/volumeTypes/results.go
rename to openstack/blockstorage/v1/volumetypes/results.go
index 83583b8..54847be 100644
--- a/openstack/blockStorage/v1/volumeTypes/results.go
+++ b/openstack/blockstorage/v1/volumetypes/results.go
@@ -1,4 +1,4 @@
-package volumeTypes
+package volumetypes
import (
"fmt"
@@ -10,8 +10,8 @@
type VolumeType struct {
ExtraSpecs map[string]interface{} `json:"extra_specs" mapstructure:"extra_specs"`
- ID string `json:"id" mapstructure:"id"`
- Name string `json:"name" mapstructure:"name"`
+ ID string `json:"id" mapstructure:"id"`
+ Name string `json:"name" mapstructure:"name"`
}
// ListResult is a *http.Response that is returned from a call to the List function.
@@ -38,20 +38,33 @@
return response.VolumeTypes, err
}
-type GetResult struct {
+type commonResult struct {
gophercloud.CommonResult
}
-func (gr GetResult) ExtractVolumeType() (*VolumeType, error) {
- if gr.Err != nil {
- return nil, gr.Err
+func (r commonResult) Extract() (*VolumeType, error) {
+ if r.Err != nil {
+ return nil, r.Err
}
- var response struct {
- VolumeType *VolumeType `mapstructure:"volume_type"`
+
+ var res struct {
+ VolumeType *VolumeType `json:"volume_type" mapstructure:"volume_type"`
}
- err := mapstructure.Decode(gr, &response)
+
+ err := mapstructure.Decode(r.Resp, &res)
if err != nil {
- return nil, fmt.Errorf("volumeTypes: Error decoding volumeTypes.GetResult: %v", err)
+ return nil, fmt.Errorf("Error decoding Volume Type: %v", err)
}
- return response.VolumeType, nil
+
+ return res.VolumeType, nil
}
+
+type GetResult struct {
+ commonResult
+}
+
+type CreateResult struct {
+ commonResult
+}
+
+type DeleteResult commonResult
diff --git a/openstack/blockstorage/v1/volumetypes/urls.go b/openstack/blockstorage/v1/volumetypes/urls.go
new file mode 100644
index 0000000..cf8367b
--- /dev/null
+++ b/openstack/blockstorage/v1/volumetypes/urls.go
@@ -0,0 +1,19 @@
+package volumetypes
+
+import "github.com/rackspace/gophercloud"
+
+func listURL(c *gophercloud.ServiceClient) string {
+ return c.ServiceURL("types")
+}
+
+func createURL(c *gophercloud.ServiceClient) string {
+ return listURL(c)
+}
+
+func getURL(c *gophercloud.ServiceClient, id string) string {
+ return c.ServiceURL("types", id)
+}
+
+func deleteURL(c *gophercloud.ServiceClient, id string) string {
+ return getURL(c, id)
+}
diff --git a/openstack/blockstorage/v1/volumetypes/urls_test.go b/openstack/blockstorage/v1/volumetypes/urls_test.go
new file mode 100644
index 0000000..44016e2
--- /dev/null
+++ b/openstack/blockstorage/v1/volumetypes/urls_test.go
@@ -0,0 +1,38 @@
+package volumetypes
+
+import (
+ "testing"
+
+ "github.com/rackspace/gophercloud"
+ th "github.com/rackspace/gophercloud/testhelper"
+)
+
+const endpoint = "http://localhost:57909"
+
+func endpointClient() *gophercloud.ServiceClient {
+ return &gophercloud.ServiceClient{Endpoint: endpoint}
+}
+
+func TestListURL(t *testing.T) {
+ actual := listURL(endpointClient())
+ expected := endpoint + "types"
+ th.AssertEquals(t, expected, actual)
+}
+
+func TestCreateURL(t *testing.T) {
+ actual := createURL(endpointClient())
+ expected := endpoint + "types"
+ th.AssertEquals(t, expected, actual)
+}
+
+func TestGetURL(t *testing.T) {
+ actual := getURL(endpointClient(), "foo")
+ expected := endpoint + "types/foo"
+ th.AssertEquals(t, expected, actual)
+}
+
+func TestDeleteURL(t *testing.T) {
+ actual := deleteURL(endpointClient(), "foo")
+ expected := endpoint + "types/foo"
+ th.AssertEquals(t, expected, actual)
+}