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