refactored DecodeHeader function to gophercloud package; updated tests
diff --git a/acceptance/openstack/objectstorage/v1/accounts_test.go b/acceptance/openstack/objectstorage/v1/accounts_test.go
index 9effe58..24cc62b 100644
--- a/acceptance/openstack/objectstorage/v1/accounts_test.go
+++ b/acceptance/openstack/objectstorage/v1/accounts_test.go
@@ -17,7 +17,10 @@
// Update an account's metadata.
updateres := accounts.Update(client, accounts.UpdateOpts{Metadata: metadata})
- th.AssertNoErr(t, updateres.Err)
+ t.Logf("Update Account Response: %+v\n", updateres)
+ updateHeaders, err := updateres.Extract()
+ th.AssertNoErr(t, err)
+ t.Logf("Update Account Response Headers: %+v\n", updateHeaders)
// Defer the deletion of the metadata set above.
defer func() {
diff --git a/acceptance/rackspace/objectstorage/v1/accounts_test.go b/acceptance/rackspace/objectstorage/v1/accounts_test.go
index 145e4e0..cde534b 100644
--- a/acceptance/rackspace/objectstorage/v1/accounts_test.go
+++ b/acceptance/rackspace/objectstorage/v1/accounts_test.go
@@ -14,8 +14,9 @@
th.AssertNoErr(t, err)
updateres := raxAccounts.Update(c, raxAccounts.UpdateOpts{Metadata: map[string]string{"white": "mountains"}})
- th.AssertNoErr(t, updateres.Err)
- t.Logf("Headers from Update Account request: %+v\n", updateres.Header)
+ updateHeaders, err := updateres.Extract()
+ th.AssertNoErr(t, err)
+ t.Logf("Update Account Response Headers: %+v\n", updateHeaders)
defer func() {
updateres = raxAccounts.Update(c, raxAccounts.UpdateOpts{Metadata: map[string]string{"white": ""}})
th.AssertNoErr(t, updateres.Err)
diff --git a/acceptance/rackspace/objectstorage/v1/objects_test.go b/acceptance/rackspace/objectstorage/v1/objects_test.go
index 462f284..96a7d8c 100644
--- a/acceptance/rackspace/objectstorage/v1/objects_test.go
+++ b/acceptance/rackspace/objectstorage/v1/objects_test.go
@@ -21,6 +21,7 @@
th.AssertNoErr(t, res.Err)
defer func() {
+ t.Logf("Deleting container...")
res := raxContainers.Delete(c, "gophercloud-test")
th.AssertNoErr(t, res.Err)
}()
@@ -30,6 +31,7 @@
createres := raxObjects.Create(c, "gophercloud-test", "o1", content, options)
th.AssertNoErr(t, createres.Err)
defer func() {
+ t.Logf("Deleting object o1...")
res := raxObjects.Delete(c, "gophercloud-test", "o1", nil)
th.AssertNoErr(t, res.Err)
}()
@@ -80,6 +82,7 @@
copyres := raxObjects.Copy(c, "gophercloud-test", "o1", &raxObjects.CopyOpts{Destination: "gophercloud-test/o2"})
th.AssertNoErr(t, copyres.Err)
defer func() {
+ t.Logf("Deleting object o2...")
res := raxObjects.Delete(c, "gophercloud-test", "o2", nil)
th.AssertNoErr(t, res.Err)
}()
@@ -99,7 +102,7 @@
metadata, err := raxObjects.Get(c, "gophercloud-test", "o2", nil).ExtractMetadata()
th.AssertNoErr(t, err)
t.Logf("Metadata from Get Account request (after update reverted): %+v\n", metadata)
- th.CheckEquals(t, metadata["White"], "")
+ th.CheckEquals(t, "", metadata["White"])
}()
getres := raxObjects.Get(c, "gophercloud-test", "o2", nil)
@@ -108,5 +111,5 @@
metadata, err := getres.ExtractMetadata()
th.AssertNoErr(t, err)
t.Logf("Metadata from Get Account request (after update): %+v\n", metadata)
- th.CheckEquals(t, metadata["White"], "mountains")
+ th.CheckEquals(t, "mountains", metadata["White"])
}
diff --git a/openstack/objectstorage/v1/accounts/results.go b/openstack/objectstorage/v1/accounts/results.go
index 5837e0b..4833a8b 100644
--- a/openstack/objectstorage/v1/accounts/results.go
+++ b/openstack/objectstorage/v1/accounts/results.go
@@ -4,7 +4,6 @@
"strings"
"time"
- "github.com/mitchellh/mapstructure"
"github.com/rackspace/gophercloud"
)
@@ -29,7 +28,7 @@
return uh, ur.Err
}
- if err := mapstructure.Decode(ur.Header, &uh); err != nil {
+ if err := gophercloud.DecodeHeader(ur.Header, &uh); err != nil {
return uh, err
}
@@ -68,7 +67,7 @@
return gh, gr.Err
}
- if err := mapstructure.Decode(gr.Header, &gh); err != nil {
+ if err := gophercloud.DecodeHeader(gr.Header, &gh); err != nil {
return gh, err
}
diff --git a/openstack/objectstorage/v1/containers/results.go b/openstack/objectstorage/v1/containers/results.go
index 4c27ec6..66939fa 100644
--- a/openstack/objectstorage/v1/containers/results.go
+++ b/openstack/objectstorage/v1/containers/results.go
@@ -120,7 +120,7 @@
return gh, gr.Err
}
- if err := mapstructure.Decode(gr.Header, &gh); err != nil {
+ if err := gophercloud.DecodeHeader(gr.Header, &gh); err != nil {
return gh, err
}
@@ -174,7 +174,7 @@
return ch, cr.Err
}
- if err := mapstructure.Decode(cr.Header, &ch); err != nil {
+ if err := gophercloud.DecodeHeader(cr.Header, &ch); err != nil {
return ch, err
}
@@ -212,7 +212,7 @@
return uh, ur.Err
}
- if err := mapstructure.Decode(ur.Header, &uh); err != nil {
+ if err := gophercloud.DecodeHeader(ur.Header, &uh); err != nil {
return uh, err
}
@@ -250,7 +250,7 @@
return dh, dr.Err
}
- if err := mapstructure.Decode(dr.Header, &dh); err != nil {
+ if err := gophercloud.DecodeHeader(dr.Header, &dh); err != nil {
return dh, err
}
diff --git a/openstack/objectstorage/v1/objects/results.go b/openstack/objectstorage/v1/objects/results.go
index b9b4084..e29e3a8 100644
--- a/openstack/objectstorage/v1/objects/results.go
+++ b/openstack/objectstorage/v1/objects/results.go
@@ -139,7 +139,7 @@
return dh, dr.Err
}
- if err := mapstructure.Decode(dr.Header, &dh); err != nil {
+ if err := gophercloud.DecodeHeader(dr.Header, &dh); err != nil {
return dh, err
}
@@ -207,7 +207,7 @@
return gh, gr.Err
}
- if err := mapstructure.Decode(gr.Header, &gh); err != nil {
+ if err := gophercloud.DecodeHeader(gr.Header, &gh); err != nil {
return gh, err
}
@@ -269,7 +269,7 @@
return ch, cr.Err
}
- if err := mapstructure.Decode(cr.Header, &ch); err != nil {
+ if err := gophercloud.DecodeHeader(cr.Header, &ch); err != nil {
return ch, err
}
@@ -313,7 +313,7 @@
return uh, ur.Err
}
- if err := mapstructure.Decode(ur.Header, &uh); err != nil {
+ if err := gophercloud.DecodeHeader(ur.Header, &uh); err != nil {
return uh, err
}
@@ -349,7 +349,7 @@
return dh, dr.Err
}
- if err := mapstructure.Decode(dr.Header, &dh); err != nil {
+ if err := gophercloud.DecodeHeader(dr.Header, &dh); err != nil {
return dh, err
}
@@ -389,7 +389,7 @@
return ch, cr.Err
}
- if err := mapstructure.Decode(cr.Header, &ch); err != nil {
+ if err := gophercloud.DecodeHeader(cr.Header, &ch); err != nil {
return ch, err
}
diff --git a/results.go b/results.go
index 3fd5029..7c86ce4 100644
--- a/results.go
+++ b/results.go
@@ -3,6 +3,9 @@
import (
"encoding/json"
"net/http"
+ "reflect"
+
+ "github.com/mitchellh/mapstructure"
)
/*
@@ -82,6 +85,31 @@
return hr.Header, hr.Err
}
+// DecodeHeader is a function that decodes a header (usually of type map[string]interface{}) to
+// another type (usually a struct). This function is used by the objectstorage package to give
+// users access to response headers without having to query a map. A DecodeHookFunction is used,
+// because OpenStack-based clients return header values as arrays (Go slices).
+func DecodeHeader(from, to interface{}) error {
+ config := &mapstructure.DecoderConfig{
+ DecodeHook: func(from, to reflect.Kind, data interface{}) (interface{}, error) {
+ if from == reflect.Slice {
+ return data.([]string)[0], nil
+ }
+ return data, nil
+ },
+ Result: to,
+ WeaklyTypedInput: true,
+ }
+ decoder, err := mapstructure.NewDecoder(config)
+ if err != nil {
+ return err
+ }
+ if err := decoder.Decode(from); err != nil {
+ return err
+ }
+ return nil
+}
+
// RFC3339Milli describes a common time format used by some API responses.
const RFC3339Milli = "2006-01-02T15:04:05.999999Z"