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