openstack list stacks op and unit test
diff --git a/openstack/orchestration/v1/stacks/fixtures.go b/openstack/orchestration/v1/stacks/fixtures.go
index ca87381..092f60e 100644
--- a/openstack/orchestration/v1/stacks/fixtures.go
+++ b/openstack/orchestration/v1/stacks/fixtures.go
@@ -4,6 +4,7 @@
"fmt"
"net/http"
"testing"
+ "time"
"github.com/rackspace/gophercloud"
th "github.com/rackspace/gophercloud/testhelper"
@@ -46,3 +47,96 @@
fmt.Fprintf(w, output)
})
}
+
+// ListExpected represents the expected object from a List request.
+var ListExpected = []ListedStack{
+ ListedStack{
+ Description: "Simple template to test heat commands",
+ Links: []gophercloud.Link{
+ gophercloud.Link{
+ Href: "http://166.76.160.117:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c87",
+ Rel: "self",
+ },
+ },
+ StatusReason: "Stack CREATE completed successfully",
+ Name: "postman_stack",
+ CreationTime: time.Date(2015, 2, 3, 20, 7, 39, 0, time.UTC),
+ Status: "CREATE_COMPLETE",
+ ID: "16ef0584-4458-41eb-87c8-0dc8d5f66c87",
+ },
+ ListedStack{
+ Description: "Simple template to test heat commands",
+ Links: []gophercloud.Link{
+ gophercloud.Link{
+ Href: "http://166.76.160.117:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/gophercloud-test-stack-2/db6977b2-27aa-4775-9ae7-6213212d4ada",
+ Rel: "self",
+ },
+ },
+ StatusReason: "Stack successfully updated",
+ Name: "gophercloud-test-stack-2",
+ CreationTime: time.Date(2014, 12, 11, 17, 39, 16, 0, time.UTC),
+ UpdatedTime: time.Date(2014, 12, 11, 17, 40, 37, 0, time.UTC),
+ Status: "UPDATE_COMPLETE",
+ ID: "db6977b2-27aa-4775-9ae7-6213212d4ada",
+ },
+}
+
+// FullListOutput represents the response body from a List request without a marker.
+const FullListOutput = `
+{
+ "stacks": [
+ {
+ "description": "Simple template to test heat commands",
+ "links": [
+ {
+ "href": "http://166.76.160.117:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c87",
+ "rel": "self"
+ }
+ ],
+ "stack_status_reason": "Stack CREATE completed successfully",
+ "stack_name": "postman_stack",
+ "creation_time": "2015-02-03T20:07:39Z",
+ "updated_time": null,
+ "stack_status": "CREATE_COMPLETE",
+ "id": "16ef0584-4458-41eb-87c8-0dc8d5f66c87"
+ },
+ {
+ "description": "Simple template to test heat commands",
+ "links": [
+ {
+ "href": "http://166.76.160.117:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/gophercloud-test-stack-2/db6977b2-27aa-4775-9ae7-6213212d4ada",
+ "rel": "self"
+ }
+ ],
+ "stack_status_reason": "Stack successfully updated",
+ "stack_name": "gophercloud-test-stack-2",
+ "creation_time": "2014-12-11T17:39:16Z",
+ "updated_time": "2014-12-11T17:40:37Z",
+ "stack_status": "UPDATE_COMPLETE",
+ "id": "db6977b2-27aa-4775-9ae7-6213212d4ada"
+ }
+ ]
+}
+`
+
+// HandleListSuccessfully creates an HTTP handler at `/stacks` on the test handler mux
+// that responds with a `List` response.
+func HandleListSuccessfully(t *testing.T, output string) {
+ th.Mux.HandleFunc("/stacks", func(w http.ResponseWriter, r *http.Request) {
+ th.TestMethod(t, r, "GET")
+ th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
+ th.TestHeader(t, r, "Accept", "application/json")
+
+ w.Header().Set("Content-Type", "application/json")
+ r.ParseForm()
+ marker := r.Form.Get("marker")
+ switch marker {
+ case "":
+ fmt.Fprintf(w, output)
+ case "db6977b2-27aa-4775-9ae7-6213212d4ada":
+ fmt.Fprintf(w, `[]`)
+ default:
+ t.Fatalf("Unexpected marker: [%s]", marker)
+ }
+ })
+}
diff --git a/openstack/orchestration/v1/stacks/requests_test.go b/openstack/orchestration/v1/stacks/requests_test.go
index 74df24e..0bf1101 100644
--- a/openstack/orchestration/v1/stacks/requests_test.go
+++ b/openstack/orchestration/v1/stacks/requests_test.go
@@ -3,6 +3,7 @@
import (
"testing"
+ "github.com/rackspace/gophercloud/pagination"
th "github.com/rackspace/gophercloud/testhelper"
fake "github.com/rackspace/gophercloud/testhelper/client"
)
@@ -95,3 +96,22 @@
expected := CreateExpected
th.AssertDeepEquals(t, expected, actual)
}
+
+func TestListStack(t *testing.T) {
+ th.SetupHTTP()
+ defer th.TeardownHTTP()
+ HandleListSuccessfully(t, FullListOutput)
+
+ count := 0
+ err := List(fake.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) {
+ count++
+ actual, err := ExtractStacks(page)
+ th.AssertNoErr(t, err)
+
+ th.CheckDeepEquals(t, ListExpected, actual)
+
+ return true, nil
+ })
+ th.AssertNoErr(t, err)
+ th.CheckEquals(t, count, 1)
+}
diff --git a/openstack/orchestration/v1/stacks/results.go b/openstack/orchestration/v1/stacks/results.go
index 62f4f6b..8866425 100644
--- a/openstack/orchestration/v1/stacks/results.go
+++ b/openstack/orchestration/v1/stacks/results.go
@@ -76,17 +76,23 @@
rawStacks := (((page.(StackPage).Body).(map[string]interface{}))["stacks"]).([]interface{})
for i := range rawStacks {
- creationTime, err := time.Parse(time.RFC3339, ((rawStacks[i]).(map[string]interface{}))["creation_time"].(string))
- if err != nil {
- return res.Stacks, err
- }
- res.Stacks[i].CreationTime = creationTime
+ thisStack := (rawStacks[i]).(map[string]interface{})
- updatedTime, err := time.Parse(time.RFC3339, ((rawStacks[i]).(map[string]interface{}))["updated_time"].(string))
- if err != nil {
- return res.Stacks, err
+ if t, ok := thisStack["creation_time"].(string); ok && t != "" {
+ creationTime, err := time.Parse(time.RFC3339, t)
+ if err != nil {
+ return res.Stacks, err
+ }
+ res.Stacks[i].CreationTime = creationTime
}
- res.Stacks[i].UpdatedTime = updatedTime
+
+ if t, ok := thisStack["updated_time"].(string); ok && t != "" {
+ updatedTime, err := time.Parse(time.RFC3339, t)
+ if err != nil {
+ return res.Stacks, err
+ }
+ res.Stacks[i].UpdatedTime = updatedTime
+ }
}
return res.Stacks, nil