openstack update stack op and unit test
diff --git a/openstack/orchestration/v1/stacks/fixtures.go b/openstack/orchestration/v1/stacks/fixtures.go
index 092f60e..6b00d9b 100644
--- a/openstack/orchestration/v1/stacks/fixtures.go
+++ b/openstack/orchestration/v1/stacks/fixtures.go
@@ -140,3 +140,88 @@
 		}
 	})
 }
+
+// GetExpected represents the expected object from a Get request.
+var GetExpected = &RetrievedStack{
+	DisableRollback: true,
+	Description:     "Simple template to test heat commands",
+	Parameters: map[string]string{
+		"flavor":         "m1.tiny",
+		"OS::stack_name": "postman_stack",
+		"OS::stack_id":   "16ef0584-4458-41eb-87c8-0dc8d5f66c87",
+	},
+	StatusReason: "Stack CREATE completed successfully",
+	Name:         "postman_stack",
+	Outputs:      []map[string]interface{}{},
+	CreationTime: time.Date(2015, 2, 3, 20, 7, 39, 0, time.UTC),
+	Links: []gophercloud.Link{
+		gophercloud.Link{
+			Href: "http://166.76.160.117:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c87",
+			Rel:  "self",
+		},
+	},
+	Capabilities:        []interface{}{},
+	NotificationTopics:  []interface{}{},
+	Status:              "CREATE_COMPLETE",
+	ID:                  "16ef0584-4458-41eb-87c8-0dc8d5f66c87",
+	TemplateDescription: "Simple template to test heat commands",
+}
+
+// GetOutput represents the response body from a Get request.
+const GetOutput = `
+{
+  "stack": {
+    "disable_rollback": true,
+    "description": "Simple template to test heat commands",
+    "parameters": {
+      "flavor": "m1.tiny",
+      "OS::stack_name": "postman_stack",
+      "OS::stack_id": "16ef0584-4458-41eb-87c8-0dc8d5f66c87"
+    },
+    "stack_status_reason": "Stack CREATE completed successfully",
+    "stack_name": "postman_stack",
+    "outputs": [],
+    "creation_time": "2015-02-03T20:07:39Z",
+    "links": [
+    {
+      "href": "http://166.76.160.117:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c87",
+      "rel": "self"
+    }
+    ],
+    "capabilities": [],
+    "notification_topics": [],
+    "timeout_mins": null,
+    "stack_status": "CREATE_COMPLETE",
+    "updated_time": null,
+    "id": "16ef0584-4458-41eb-87c8-0dc8d5f66c87",
+    "template_description": "Simple template to test heat commands"
+  }
+}
+`
+
+// HandleGetSuccessfully creates an HTTP handler at `/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c87`
+// on the test handler mux that responds with a `Get` response.
+func HandleGetSuccessfully(t *testing.T, output string) {
+	th.Mux.HandleFunc("/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c87", 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")
+		w.WriteHeader(http.StatusOK)
+		fmt.Fprintf(w, output)
+	})
+}
+
+// HandleUpdateSuccessfully creates an HTTP handler at `/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c87`
+// on the test handler mux that responds with an `Update` response.
+func HandleUpdateSuccessfully(t *testing.T) {
+	th.Mux.HandleFunc("/stacks/gophercloud-test-stack-2/db6977b2-27aa-4775-9ae7-6213212d4ada", func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "PUT")
+		th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
+		th.TestHeader(t, r, "Accept", "application/json")
+
+		w.Header().Set("Content-Type", "application/json")
+		w.WriteHeader(http.StatusAccepted)
+	})
+}
diff --git a/openstack/orchestration/v1/stacks/requests_test.go b/openstack/orchestration/v1/stacks/requests_test.go
index 0bf1101..8316caa 100644
--- a/openstack/orchestration/v1/stacks/requests_test.go
+++ b/openstack/orchestration/v1/stacks/requests_test.go
@@ -115,3 +115,50 @@
 	th.AssertNoErr(t, err)
 	th.CheckEquals(t, count, 1)
 }
+
+func TestGetStack(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	HandleGetSuccessfully(t, GetOutput)
+
+	actual, err := Get(fake.ServiceClient(), "postman_stack", "16ef0584-4458-41eb-87c8-0dc8d5f66c87").Extract()
+	th.AssertNoErr(t, err)
+
+	expected := GetExpected
+	th.AssertDeepEquals(t, expected, actual)
+}
+
+func TestUpdateStack(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	HandleUpdateSuccessfully(t)
+
+	updateOpts := UpdateOpts{
+		Template: `
+    {
+      "heat_template_version": "2013-05-23",
+      "description": "Simple template to test heat commands",
+      "parameters": {
+        "flavor": {
+          "default": "m1.tiny",
+          "type": "string"
+        }
+      },
+      "resources": {
+        "hello_world": {
+          "type":"OS::Nova::Server",
+          "properties": {
+            "key_name": "heat_key",
+            "flavor": {
+              "get_param": "flavor"
+            },
+            "image": "ad091b52-742f-469e-8f3c-fd81cadf0743",
+            "user_data": "#!/bin/bash -xv\necho \"hello world\" > /root/hello-world.txt\n"
+          }
+        }
+      }
+    }`,
+	}
+	err := Update(fake.ServiceClient(), "gophercloud-test-stack-2", "db6977b2-27aa-4775-9ae7-6213212d4ada", updateOpts).ExtractErr()
+	th.AssertNoErr(t, err)
+}
diff --git a/openstack/orchestration/v1/stacks/results.go b/openstack/orchestration/v1/stacks/results.go
index 8866425..d69031c 100644
--- a/openstack/orchestration/v1/stacks/results.go
+++ b/openstack/orchestration/v1/stacks/results.go
@@ -8,15 +8,19 @@
 	"github.com/rackspace/gophercloud/pagination"
 )
 
+// CreatedStack represents the object extracted from a Create operation.
 type CreatedStack struct {
 	ID    string             `mapstructure:"id"`
 	Links []gophercloud.Link `mapstructure:"links"`
 }
 
+// CreateResult represents the result of a Create operation.
 type CreateResult struct {
 	gophercloud.Result
 }
 
+// Extract returns a pointer to a CreatedStack object and is called after a
+// Create operation.
 func (r CreateResult) Extract() (*CreatedStack, error) {
 	if r.Err != nil {
 		return nil, r.Err
@@ -33,6 +37,8 @@
 	return res.Stack, nil
 }
 
+// AdoptResult represents the result of an Adopt operation. AdoptResult has the
+// same form as CreateResult.
 type AdoptResult struct {
 	CreateResult
 }
@@ -51,6 +57,7 @@
 	return len(stacks) == 0, nil
 }
 
+// ListedStack represents an element in the slice extracted from a List operation.
 type ListedStack struct {
 	CreationTime time.Time          `mapstructure:"-"`
 	Description  string             `mapstructure:"description"`
@@ -62,7 +69,7 @@
 	UpdatedTime  time.Time          `mapstructure:"-"`
 }
 
-// ExtractStacks extracts and returns a slice of Stacks. It is used while iterating
+// ExtractStacks extracts and returns a slice of ListedStack. It is used while iterating
 // over a stacks.List call.
 func ExtractStacks(page pagination.Page) ([]ListedStack, error) {
 	var res struct {
@@ -98,28 +105,32 @@
 	return res.Stacks, nil
 }
 
+// RetrievedStack represents the object extracted from a Get operation.
 type RetrievedStack struct {
-	Capabilities        []interface{}       `mapstructure:"capabilities"`
-	CreationTime        time.Time           `mapstructure:"-"`
-	Description         string              `mapstructure:"description"`
-	DisableRollback     bool                `mapstructure:"disable_rollback"`
-	ID                  string              `mapstructure:"id"`
-	Links               []gophercloud.Link  `mapstructure:"links"`
-	NotificationTopics  []interface{}       `mapstructure:"notification_topics"`
-	Outputs             []map[string]string `mapstructure:"outputs"`
-	Parameters          map[string]string   `mapstructure:"parameters"`
-	Name                string              `mapstructure:"stack_name"`
-	Status              string              `mapstructure:"stack_status"`
-	StausReason         string              `mapstructure:"stack_status_reason"`
-	TemplateDescription string              `mapstructure:"template_description"`
-	Timeout             int                 `mapstructure:"timeout_mins"`
-	UpdatedTime         time.Time           `mapstructure:"-"`
+	Capabilities        []interface{}            `mapstructure:"capabilities"`
+	CreationTime        time.Time                `mapstructure:"-"`
+	Description         string                   `mapstructure:"description"`
+	DisableRollback     bool                     `mapstructure:"disable_rollback"`
+	ID                  string                   `mapstructure:"id"`
+	Links               []gophercloud.Link       `mapstructure:"links"`
+	NotificationTopics  []interface{}            `mapstructure:"notification_topics"`
+	Outputs             []map[string]interface{} `mapstructure:"outputs"`
+	Parameters          map[string]string        `mapstructure:"parameters"`
+	Name                string                   `mapstructure:"stack_name"`
+	Status              string                   `mapstructure:"stack_status"`
+	StatusReason        string                   `mapstructure:"stack_status_reason"`
+	TemplateDescription string                   `mapstructure:"template_description"`
+	Timeout             int                      `mapstructure:"timeout_mins"`
+	UpdatedTime         time.Time                `mapstructure:"-"`
 }
 
+// GetResult represents the result of a Get operation.
 type GetResult struct {
 	gophercloud.Result
 }
 
+// Extract returns a pointer to a RetrievedStack object and is called after a
+// Get operation.
 func (r GetResult) Extract() (*RetrievedStack, error) {
 	if r.Err != nil {
 		return nil, r.Err
@@ -163,10 +174,12 @@
 	return res.Stack, err
 }
 
+// UpdateResult represents the result of a Update operation.
 type UpdateResult struct {
 	gophercloud.ErrResult
 }
 
+// DeleteResult represents the result of a Delete operation.
 type DeleteResult struct {
 	gophercloud.ErrResult
 }