images service v2 port from rackpsace/gophercloud (#171)

* CheckByteArrayEquals funcs

* direct port from rackspace/gophercloud with minor additions to get unit tests passing

* new package for uploading and downloading image data

* updates to make imageservice v2 consistent with the rest of gophercloud/gophercloud

* add image service v2 client
diff --git a/openstack/imageservice/v2/imagedata/testing/fixtures.go b/openstack/imageservice/v2/imagedata/testing/fixtures.go
new file mode 100644
index 0000000..fe93fc9
--- /dev/null
+++ b/openstack/imageservice/v2/imagedata/testing/fixtures.go
@@ -0,0 +1,40 @@
+package testing
+
+import (
+	"io/ioutil"
+	"net/http"
+	"testing"
+
+	th "github.com/gophercloud/gophercloud/testhelper"
+	fakeclient "github.com/gophercloud/gophercloud/testhelper/client"
+)
+
+// HandlePutImageDataSuccessfully setup
+func HandlePutImageDataSuccessfully(t *testing.T) {
+	th.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/file", func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "PUT")
+		th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID)
+
+		b, err := ioutil.ReadAll(r.Body)
+		if err != nil {
+			t.Errorf("Unable to read request body: %v", err)
+		}
+
+		th.AssertByteArrayEquals(t, []byte{5, 3, 7, 24}, b)
+
+		w.WriteHeader(http.StatusNoContent)
+	})
+}
+
+// HandleGetImageDataSuccessfully setup
+func HandleGetImageDataSuccessfully(t *testing.T) {
+	th.Mux.HandleFunc("/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/file", func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "GET")
+		th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID)
+
+		w.WriteHeader(http.StatusOK)
+
+		_, err := w.Write([]byte{34, 87, 0, 23, 23, 23, 56, 255, 254, 0})
+		th.AssertNoErr(t, err)
+	})
+}