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)
 }
 
