diff --git a/acceptance/openstack/compute_test.go b/acceptance/openstack/compute_test.go
index 5b35b8f..3cccbc1 100644
--- a/acceptance/openstack/compute_test.go
+++ b/acceptance/openstack/compute_test.go
@@ -6,53 +6,9 @@
 	"github.com/rackspace/gophercloud/openstack/compute/servers"
 	"github.com/rackspace/gophercloud/openstack/compute/images"
 	"github.com/rackspace/gophercloud/openstack/compute/flavors"
-	"github.com/rackspace/gophercloud/openstack/identity"
-	"github.com/rackspace/gophercloud/openstack/utils"
 	"os"
-	"text/tabwriter"
-	"time"
-	"crypto/rand"
 )
 
-type testState struct {
-	o	identity.AuthOptions
-	a	identity.AuthResults
-	sc	*identity.ServiceCatalog
-	eps	[]identity.Endpoint
-	w	*tabwriter.Writer
-}
-
-func setupForList() (*testState, error) {
-	var err error
-
-	ts := new(testState)
-
-	ts.o, err = utils.AuthOptions()
-	if err != nil {
-		return ts, err
-	}
-
-	ts.a, err = identity.Authenticate(ts.o)
-	if err != nil {
-		return ts, err
-	}
-
-	ts.sc, err = identity.GetServiceCatalog(ts.a)
-	if err != nil {
-		return ts, err
-	}
-
-	ts.eps, err = findAllComputeEndpoints(ts.sc)
-	if err != nil {
-		return ts, err
-	}
-
-	ts.w = new(tabwriter.Writer)
-	ts.w.Init(os.Stdout, 2, 8, 2, ' ', 0)
-
-	return ts, nil
-}
-
 func TestListServers(t *testing.T) {
 	ts, err := setupForList()
 	if err != nil {
@@ -173,264 +129,57 @@
 	fmt.Printf("--------\n%d images listed.\n", n)
 }
 
-func findAllComputeEndpoints(sc *identity.ServiceCatalog) ([]identity.Endpoint, error) {
-	ces, err := sc.CatalogEntries()
-	if err != nil {
-		return nil, err
-	}
-
-	for _, ce := range ces {
-		if ce.Type == "compute" {
-			return ce.Endpoints, nil
-		}
-	}
-
-	return nil, fmt.Errorf("Compute endpoint not found.")
-}
-
-func findEndpointForRegion(eps []identity.Endpoint, r string) (string, error) {
-	for _, ep := range eps {
-		if ep.Region == r {
-			return ep.PublicURL, nil
-		}
-	}
-	return "", fmt.Errorf("Unknown region %s", r)
-}
-
 func TestCreateDestroyServer(t *testing.T) {
-	ts, err := setupForList()
+	ts, err := setupForCRUD()
 	if err != nil {
 		t.Error(err)
 		return
 	}
 
-	imageId := os.Getenv("OS_IMAGE_ID")
-	if imageId == "" {
-		t.Error("Expected OS_IMAGE_ID environment variable to be set")
-		return
-	}
-
-	flavorId := os.Getenv("OS_FLAVOR_ID")
-	if flavorId == "" {
-		t.Error("Expected OS_FLAVOR_ID environment variable to be set")
-		return
-	}
-
-	region := os.Getenv("OS_REGION_NAME")
-	if region == "" {
-		region = ts.eps[0].Region
-	}
-
-	ep, err := findEndpointForRegion(ts.eps, region)
+	err = createServer(ts)
 	if err != nil {
 		t.Error(err)
 		return
 	}
 
-	serverName := randomString("ACPTTEST", 16)
-	fmt.Printf("Attempting to create server: %s\n", serverName)
-
-	client := servers.NewClient(ep, ts.a, ts.o)
-
-	cr, err := servers.Create(client, map[string]interface{}{
-		"flavorRef": flavorId,
-		"imageRef": imageId,
-		"name": serverName,
-	})
-	if err != nil {
-		t.Error(err)
-		return
-	}
-
-	createdServer, err := servers.GetServer(cr)
-	if err != nil {
-		t.Error(err)
-		return
-	}
+	// We put this in a defer so that it gets executed even in the face of errors or panics.
 	defer func() {
-		servers.Delete(client, createdServer.Id)
+		servers.Delete(ts.client, ts.createdServer.Id)
 	}()
 
-	timeout := 300
-	for ; timeout > 0; timeout-- {
-		gr, err := servers.GetDetail(client, createdServer.Id)
-		if err != nil {
-			t.Error(err)
-			return
-		}
-
-		gottenServer, err := servers.GetServer(gr)
-		if err != nil {
-			t.Error(err)
-			return
-		}
-
-		if gottenServer.Id != createdServer.Id {
-			t.Error("Created server ID (%s) != gotten server ID (%s)", createdServer.Id, gottenServer.Id)
-			return
-		}
-
-		if gottenServer.Status == "ACTIVE" {
-			fmt.Printf("Server created after %d seconds (approximately)\n", 300-timeout)
-			break
-		}
-		time.Sleep(1*time.Second)
-	}
-	if timeout < 1 {
-		fmt.Printf("I'm not waiting around.\n")
+	err = waitForStatus(ts, "ACTIVE")
+	if err != nil {
+		t.Error(err)
 	}
 }
 
 func TestUpdateServer(t *testing.T) {
-	ts, err := setupForList()
+	ts, err := setupForCRUD()
 	if err != nil {
 		t.Error(err)
 		return
 	}
 
-	imageId := os.Getenv("OS_IMAGE_ID")
-	if imageId == "" {
-		t.Error("Expected OS_IMAGE_ID environment variable to be set")
-		return
-	}
-
-	flavorId := os.Getenv("OS_FLAVOR_ID")
-	if flavorId == "" {
-		t.Error("Expected OS_FLAVOR_ID environment variable to be set")
-		return
-	}
-
-	region := os.Getenv("OS_REGION_NAME")
-	if region == "" {
-		region = ts.eps[0].Region
-	}
-
-	ep, err := findEndpointForRegion(ts.eps, region)
+	err = createServer(ts)
 	if err != nil {
 		t.Error(err)
 		return
 	}
 
-	serverName := randomString("ACPTTEST", 16)
-	fmt.Printf("Attempting to create server: %s\n", serverName)
-
-	client := servers.NewClient(ep, ts.a, ts.o)
-
-	cr, err := servers.Create(client, map[string]interface{}{
-		"flavorRef": flavorId,
-		"imageRef": imageId,
-		"name": serverName,
-	})
-	if err != nil {
-		t.Error(err)
-		return
-	}
-
-	createdServer, err := servers.GetServer(cr)
-	if err != nil {
-		t.Error(err)
-		return
-	}
 	defer func() {
-		servers.Delete(client, createdServer.Id)
+		servers.Delete(ts.client, ts.createdServer.Id)
 	}()
 
-	timeout := 300
-	for ; timeout > 0; timeout-- {
-		gr, err := servers.GetDetail(client, createdServer.Id)
-		if err != nil {
-			t.Error(err)
-			return
-		}
-
-		gottenServer, err := servers.GetServer(gr)
-		if err != nil {
-			t.Error(err)
-			return
-		}
-
-		if gottenServer.Id != createdServer.Id {
-			t.Error("Created server ID (%s) != gotten server ID (%s)", createdServer.Id, gottenServer.Id)
-			return
-		}
-
-		if gottenServer.Status == "ACTIVE" {
-			fmt.Printf("Server created after %d seconds (approximately)\n", 300-timeout)
-			break
-		}
-		time.Sleep(1*time.Second)
-	}
-	if timeout < 1 {
-		fmt.Printf("I'm not waiting around.\n")
-	}
-
-	alternateName := randomString("ACPTTEST", 16)
-	for alternateName == serverName {
-		alternateName = randomString("ACPTTEST", 16)
-	}
-
-	fmt.Println("Attempting to change server name")
-
-	ur, err := servers.Update(client, createdServer.Id, map[string]interface{}{
-		"name": alternateName,
-	})
+	err = waitForStatus(ts, "ACTIVE")
 	if err != nil {
 		t.Error(err)
 		return
 	}
 
-	updatedServer, err := servers.GetServer(ur)
+	err = changeServerName(ts)
 	if err != nil {
 		t.Error(err)
 		return
 	}
-
-	if updatedServer.Id != createdServer.Id {
-		t.Error("Expected updated and created server to share the same ID")
-		return
-	}
-
-	timeout = 300
-	for ; timeout > 0; timeout-- {
-		gr, err := servers.GetDetail(client, createdServer.Id)
-		if err != nil {
-			t.Error(err)
-			return
-		}
-
-		gottenServer, err := servers.GetServer(gr)
-		if err != nil {
-			t.Error(err)
-			return
-		}
-
-		if gottenServer.Id != updatedServer.Id {
-			t.Error("Updated server ID (%s) != gotten server ID (%s)", updatedServer.Id, gottenServer.Id)
-			return
-		}
-
-		if gottenServer.Name == alternateName {
-			fmt.Printf("Server updated after %d seconds (approximately)\n", 300-timeout)
-			break
-		}
-		time.Sleep(1*time.Second)
-	}
-	if timeout < 1 {
-		fmt.Printf("I'm not waiting around.\n")
-	}
-}
-
-// randomString generates a string of given length, but random content.
-// All content will be within the ASCII graphic character set.
-// (Implementation from Even Shaw's contribution on
-// http://stackoverflow.com/questions/12771930/what-is-the-fastest-way-to-generate-a-long-random-string-in-go).
-func randomString(prefix string, n int) string {
-	const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
-	var bytes = make([]byte, n)
-	rand.Read(bytes)
-	for i, b := range bytes {
-		bytes[i] = alphanum[b%byte(len(alphanum))]
-	}
-	return prefix + string(bytes)
 }
 
diff --git a/acceptance/openstack/tools_test.go b/acceptance/openstack/tools_test.go
new file mode 100644
index 0000000..dc2cde8
--- /dev/null
+++ b/acceptance/openstack/tools_test.go
@@ -0,0 +1,243 @@
+package openstack
+
+import (
+	"fmt"
+	"github.com/rackspace/gophercloud/openstack/compute/servers"
+	"github.com/rackspace/gophercloud/openstack/identity"
+	"github.com/rackspace/gophercloud/openstack/utils"
+	"os"
+	"text/tabwriter"
+	"time"
+	"crypto/rand"
+)
+
+var errTimeout = fmt.Errorf("Timeout.")
+
+type testState struct {
+	o	identity.AuthOptions
+	a	identity.AuthResults
+	sc	*identity.ServiceCatalog
+	eps	[]identity.Endpoint
+	w	*tabwriter.Writer
+	imageId	string
+	flavorId string
+	region string
+	ep string
+	client *servers.Client
+	createdServer *servers.Server
+	gottenServer *servers.Server
+	updatedServer *servers.Server
+	serverName string
+	alternateName string
+}
+
+func setupForList() (*testState, error) {
+	var err error
+
+	ts := new(testState)
+
+	ts.o, err = utils.AuthOptions()
+	if err != nil {
+		return ts, err
+	}
+
+	ts.a, err = identity.Authenticate(ts.o)
+	if err != nil {
+		return ts, err
+	}
+
+	ts.sc, err = identity.GetServiceCatalog(ts.a)
+	if err != nil {
+		return ts, err
+	}
+
+	ts.eps, err = findAllComputeEndpoints(ts.sc)
+	if err != nil {
+		return ts, err
+	}
+
+	ts.w = new(tabwriter.Writer)
+	ts.w.Init(os.Stdout, 2, 8, 2, ' ', 0)
+
+	return ts, nil
+}
+
+func setupForCRUD() (*testState, error) {
+	ts, err := setupForList()
+	if err != nil {
+		return ts, err
+	}
+
+	ts.imageId = os.Getenv("OS_IMAGE_ID")
+	if ts.imageId == "" {
+		return ts, fmt.Errorf("Expected OS_IMAGE_ID environment variable to be set")
+	}
+
+	ts.flavorId = os.Getenv("OS_FLAVOR_ID")
+	if ts.flavorId == "" {
+		return ts, fmt.Errorf("Expected OS_FLAVOR_ID environment variable to be set")
+	}
+
+	ts.region = os.Getenv("OS_REGION_NAME")
+	if ts.region == "" {
+		ts.region = ts.eps[0].Region
+	}
+
+	ts.ep, err = findEndpointForRegion(ts.eps, ts.region)
+	if err != nil {
+		return ts, err
+	}
+
+	return ts, err
+}
+
+func findAllComputeEndpoints(sc *identity.ServiceCatalog) ([]identity.Endpoint, error) {
+	ces, err := sc.CatalogEntries()
+	if err != nil {
+		return nil, err
+	}
+
+	for _, ce := range ces {
+		if ce.Type == "compute" {
+			return ce.Endpoints, nil
+		}
+	}
+
+	return nil, fmt.Errorf("Compute endpoint not found.")
+}
+
+func findEndpointForRegion(eps []identity.Endpoint, r string) (string, error) {
+	for _, ep := range eps {
+		if ep.Region == r {
+			return ep.PublicURL, nil
+		}
+	}
+	return "", fmt.Errorf("Unknown region %s", r)
+}
+
+func countDown(ts *testState, timeout int) (bool, int, error) {
+	if timeout < 1 {
+		return false, 0, errTimeout
+	}
+	time.Sleep(1 * time.Second)
+	timeout--
+
+	gr, err := servers.GetDetail(ts.client, ts.createdServer.Id)
+	if err != nil {
+		return false, timeout, err
+	}
+
+	ts.gottenServer, err = servers.GetServer(gr)
+	if err != nil {
+		return false, timeout, err
+	}
+
+	return true, timeout, nil
+}
+
+func createServer(ts *testState) error {
+	ts.serverName = randomString("ACPTTEST", 16)
+	fmt.Printf("Attempting to create server: %s\n", ts.serverName)
+
+	ts.client = servers.NewClient(ts.ep, ts.a, ts.o)
+
+	cr, err := servers.Create(ts.client, map[string]interface{}{
+		"flavorRef": ts.flavorId,
+		"imageRef": ts.imageId,
+		"name": ts.serverName,
+	})
+	if err != nil {
+		return err
+	}
+
+	ts.createdServer, err = servers.GetServer(cr)
+	return err
+}
+
+func waitForStatus(ts *testState, s string) error {
+	var (
+		inProgress bool
+		timeout int
+		err error
+	)
+
+	for inProgress, timeout, err = countDown(ts, 300) ; inProgress ; inProgress, timeout, err = countDown(ts, timeout) {
+		if ts.gottenServer.Id != ts.createdServer.Id {
+			return fmt.Errorf("created server id (%s) != gotten server id (%s)", ts.createdServer.Id, ts.gottenServer.Id)
+		}
+
+		if ts.gottenServer.Status == s {
+			fmt.Printf("Server created after %d seconds (approximately)\n", 300-timeout)
+			break
+		}
+	}
+
+	if err == errTimeout {
+		fmt.Printf("I'm not waiting around.\n")
+		err = nil
+	}
+
+	return err
+}
+
+func changeServerName(ts *testState) error {
+	var (
+		inProgress bool
+		timeout int
+	)
+
+	ts.alternateName = randomString("ACPTTEST", 16)
+	for ts.alternateName == ts.serverName {
+		ts.alternateName = randomString("ACPTTEST", 16)
+	}
+	fmt.Println("Attempting to change server name")
+
+	ur, err := servers.Update(ts.client, ts.createdServer.Id, map[string]interface{}{
+		"name": ts.alternateName,
+	})
+	if err != nil {
+		return err
+	}
+
+	ts.updatedServer, err = servers.GetServer(ur)
+	if err != nil {
+		return err
+	}
+
+	if ts.updatedServer.Id != ts.createdServer.Id {
+		return fmt.Errorf("Expected updated and created server to share the same ID")
+	}
+
+	for inProgress, timeout, err = countDown(ts, 300) ; inProgress ; inProgress, timeout, err = countDown(ts, timeout) {
+		if ts.gottenServer.Id != ts.updatedServer.Id {
+			return fmt.Errorf("Updated server ID (%s) != gotten server ID (%s)", ts.updatedServer.Id, ts.gottenServer.Id)
+		}
+
+		if ts.gottenServer.Name == ts.alternateName {
+			fmt.Printf("Server updated after %d seconds (approximately)\n", 300-timeout)
+			break
+		}
+	}
+
+	if err == errTimeout {
+		fmt.Printf("I'm not waiting around.\n")
+		err = nil
+	}
+
+	return err
+}
+
+// randomString generates a string of given length, but random content.
+// All content will be within the ASCII graphic character set.
+// (Implementation from Even Shaw's contribution on
+// http://stackoverflow.com/questions/12771930/what-is-the-fastest-way-to-generate-a-long-random-string-in-go).
+func randomString(prefix string, n int) string {
+	const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+	var bytes = make([]byte, n)
+	rand.Read(bytes)
+	for i, b := range bytes {
+		bytes[i] = alphanum[b%byte(len(alphanum))]
+	}
+	return prefix + string(bytes)
+}
+
