move unit tests into 'testing' directories
diff --git a/openstack/compute/v2/extensions/floatingips/testing/doc.go b/openstack/compute/v2/extensions/floatingips/testing/doc.go
new file mode 100644
index 0000000..7603f83
--- /dev/null
+++ b/openstack/compute/v2/extensions/floatingips/testing/doc.go
@@ -0,0 +1 @@
+package testing
diff --git a/openstack/compute/v2/extensions/floatingips/testing/fixtures.go b/openstack/compute/v2/extensions/floatingips/testing/fixtures.go
new file mode 100644
index 0000000..e372606
--- /dev/null
+++ b/openstack/compute/v2/extensions/floatingips/testing/fixtures.go
@@ -0,0 +1,192 @@
+package testing
+
+import (
+	"fmt"
+	"net/http"
+	"testing"
+
+	"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips"
+	th "github.com/gophercloud/gophercloud/testhelper"
+	"github.com/gophercloud/gophercloud/testhelper/client"
+)
+
+// ListOutput is a sample response to a List call.
+const ListOutput = `
+{
+    "floating_ips": [
+        {
+            "fixed_ip": null,
+            "id": "1",
+            "instance_id": null,
+            "ip": "10.10.10.1",
+            "pool": "nova"
+        },
+        {
+            "fixed_ip": "166.78.185.201",
+            "id": "2",
+            "instance_id": "4d8c3732-a248-40ed-bebc-539a6ffd25c0",
+            "ip": "10.10.10.2",
+            "pool": "nova"
+        }
+    ]
+}
+`
+
+// GetOutput is a sample response to a Get call.
+const GetOutput = `
+{
+    "floating_ip": {
+        "fixed_ip": "166.78.185.201",
+        "id": "2",
+        "instance_id": "4d8c3732-a248-40ed-bebc-539a6ffd25c0",
+        "ip": "10.10.10.2",
+        "pool": "nova"
+    }
+}
+`
+
+// CreateOutput is a sample response to a Post call
+const CreateOutput = `
+{
+    "floating_ip": {
+        "fixed_ip": null,
+        "id": "1",
+        "instance_id": null,
+        "ip": "10.10.10.1",
+        "pool": "nova"
+    }
+}
+`
+
+// FirstFloatingIP is the first result in ListOutput.
+var FirstFloatingIP = floatingips.FloatingIP{
+	ID:   "1",
+	IP:   "10.10.10.1",
+	Pool: "nova",
+}
+
+// SecondFloatingIP is the first result in ListOutput.
+var SecondFloatingIP = floatingips.FloatingIP{
+	FixedIP:    "166.78.185.201",
+	ID:         "2",
+	InstanceID: "4d8c3732-a248-40ed-bebc-539a6ffd25c0",
+	IP:         "10.10.10.2",
+	Pool:       "nova",
+}
+
+// ExpectedFloatingIPsSlice is the slice of results that should be parsed
+// from ListOutput, in the expected order.
+var ExpectedFloatingIPsSlice = []floatingips.FloatingIP{FirstFloatingIP, SecondFloatingIP}
+
+// CreatedFloatingIP is the parsed result from CreateOutput.
+var CreatedFloatingIP = floatingips.FloatingIP{
+	ID:   "1",
+	IP:   "10.10.10.1",
+	Pool: "nova",
+}
+
+// HandleListSuccessfully configures the test server to respond to a List request.
+func HandleListSuccessfully(t *testing.T) {
+	th.Mux.HandleFunc("/os-floating-ips", func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "GET")
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
+
+		w.Header().Add("Content-Type", "application/json")
+		fmt.Fprintf(w, ListOutput)
+	})
+}
+
+// HandleGetSuccessfully configures the test server to respond to a Get request
+// for an existing floating ip
+func HandleGetSuccessfully(t *testing.T) {
+	th.Mux.HandleFunc("/os-floating-ips/2", func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "GET")
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
+
+		w.Header().Add("Content-Type", "application/json")
+		fmt.Fprintf(w, GetOutput)
+	})
+}
+
+// HandleCreateSuccessfully configures the test server to respond to a Create request
+// for a new floating ip
+func HandleCreateSuccessfully(t *testing.T) {
+	th.Mux.HandleFunc("/os-floating-ips", func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "POST")
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
+		th.TestJSONRequest(t, r, `
+{
+	"pool": "nova"
+}
+`)
+
+		w.Header().Add("Content-Type", "application/json")
+		fmt.Fprintf(w, CreateOutput)
+	})
+}
+
+// HandleDeleteSuccessfully configures the test server to respond to a Delete request for a
+// an existing floating ip
+func HandleDeleteSuccessfully(t *testing.T) {
+	th.Mux.HandleFunc("/os-floating-ips/1", func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "DELETE")
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
+
+		w.WriteHeader(http.StatusAccepted)
+	})
+}
+
+// HandleAssociateSuccessfully configures the test server to respond to a Post request
+// to associate an allocated floating IP
+func HandleAssociateSuccessfully(t *testing.T) {
+	th.Mux.HandleFunc("/servers/4d8c3732-a248-40ed-bebc-539a6ffd25c0/action", func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "POST")
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
+		th.TestJSONRequest(t, r, `
+{
+	"addFloatingIp": {
+		"address": "10.10.10.2"
+	}
+}
+`)
+
+		w.WriteHeader(http.StatusAccepted)
+	})
+}
+
+// HandleFixedAssociateSucessfully configures the test server to respond to a Post request
+// to associate an allocated floating IP with a specific fixed IP address
+func HandleAssociateFixedSuccessfully(t *testing.T) {
+	th.Mux.HandleFunc("/servers/4d8c3732-a248-40ed-bebc-539a6ffd25c0/action", func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "POST")
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
+		th.TestJSONRequest(t, r, `
+{
+	"addFloatingIp": {
+		"address": "10.10.10.2",
+		"fixed_address": "166.78.185.201"
+	}
+}
+`)
+
+		w.WriteHeader(http.StatusAccepted)
+	})
+}
+
+// HandleDisassociateSuccessfully configures the test server to respond to a Post request
+// to disassociate an allocated floating IP
+func HandleDisassociateSuccessfully(t *testing.T) {
+	th.Mux.HandleFunc("/servers/4d8c3732-a248-40ed-bebc-539a6ffd25c0/action", func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "POST")
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
+		th.TestJSONRequest(t, r, `
+{
+	"removeFloatingIp": {
+		"address": "10.10.10.2"
+	}
+}
+`)
+
+		w.WriteHeader(http.StatusAccepted)
+	})
+}
diff --git a/openstack/compute/v2/extensions/floatingips/testing/requests_test.go b/openstack/compute/v2/extensions/floatingips/testing/requests_test.go
new file mode 100644
index 0000000..e53da91
--- /dev/null
+++ b/openstack/compute/v2/extensions/floatingips/testing/requests_test.go
@@ -0,0 +1,99 @@
+package testing
+
+import (
+	"testing"
+
+	"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips"
+	"github.com/gophercloud/gophercloud/pagination"
+	th "github.com/gophercloud/gophercloud/testhelper"
+	"github.com/gophercloud/gophercloud/testhelper/client"
+)
+
+func TestList(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	HandleListSuccessfully(t)
+
+	count := 0
+	err := floatingips.List(client.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) {
+		count++
+		actual, err := floatingips.ExtractFloatingIPs(page)
+		th.AssertNoErr(t, err)
+		th.CheckDeepEquals(t, ExpectedFloatingIPsSlice, actual)
+
+		return true, nil
+	})
+	th.AssertNoErr(t, err)
+	th.CheckEquals(t, 1, count)
+}
+
+func TestCreate(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	HandleCreateSuccessfully(t)
+
+	actual, err := floatingips.Create(client.ServiceClient(), floatingips.CreateOpts{
+		Pool: "nova",
+	}).Extract()
+	th.AssertNoErr(t, err)
+	th.CheckDeepEquals(t, &CreatedFloatingIP, actual)
+}
+
+func TestGet(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	HandleGetSuccessfully(t)
+
+	actual, err := floatingips.Get(client.ServiceClient(), "2").Extract()
+	th.AssertNoErr(t, err)
+	th.CheckDeepEquals(t, &SecondFloatingIP, actual)
+}
+
+func TestDelete(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	HandleDeleteSuccessfully(t)
+
+	err := floatingips.Delete(client.ServiceClient(), "1").ExtractErr()
+	th.AssertNoErr(t, err)
+}
+
+func TestAssociate(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	HandleAssociateSuccessfully(t)
+
+	associateOpts := floatingips.AssociateOpts{
+		FloatingIP: "10.10.10.2",
+	}
+
+	err := floatingips.AssociateInstance(client.ServiceClient(), "4d8c3732-a248-40ed-bebc-539a6ffd25c0", associateOpts).ExtractErr()
+	th.AssertNoErr(t, err)
+}
+
+func TestAssociateFixed(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	HandleAssociateFixedSuccessfully(t)
+
+	associateOpts := floatingips.AssociateOpts{
+		FloatingIP: "10.10.10.2",
+		FixedIP:    "166.78.185.201",
+	}
+
+	err := floatingips.AssociateInstance(client.ServiceClient(), "4d8c3732-a248-40ed-bebc-539a6ffd25c0", associateOpts).ExtractErr()
+	th.AssertNoErr(t, err)
+}
+
+func TestDisassociateInstance(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	HandleDisassociateSuccessfully(t)
+
+	disassociateOpts := floatingips.DisassociateOpts{
+		FloatingIP: "10.10.10.2",
+	}
+
+	err := floatingips.DisassociateInstance(client.ServiceClient(), "4d8c3732-a248-40ed-bebc-539a6ffd25c0", disassociateOpts).ExtractErr()
+	th.AssertNoErr(t, err)
+}