diff --git a/acceptance/openstack/compute/compute_test.go b/acceptance/openstack/compute/compute_test.go
new file mode 100644
index 0000000..7473f13
--- /dev/null
+++ b/acceptance/openstack/compute/compute_test.go
@@ -0,0 +1,369 @@
+// +build acceptance
+
+package compute
+
+import (
+	"fmt"
+	"github.com/rackspace/gophercloud/openstack/compute/flavors"
+	"github.com/rackspace/gophercloud/openstack/compute/images"
+	"github.com/rackspace/gophercloud/openstack/compute/servers"
+	"os"
+	"testing"
+	"github.com/rackspace/gophercloud/acceptance/tools"
+)
+
+var service = "compute"
+
+func TestListServers(t *testing.T) {
+	ts, err := tools.SetupForList(service)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	fmt.Fprintln(ts.W, "ID\tRegion\tName\tStatus\tIPv4\tIPv6\t")
+
+	region := os.Getenv("OS_REGION_NAME")
+	n := 0
+	for _, ep := range ts.EPs {
+		if (region != "") && (region != ep.Region) {
+			continue
+		}
+
+		client := servers.NewClient(ep.PublicURL, ts.A, ts.O)
+
+		listResults, err := servers.List(client)
+		if err != nil {
+			t.Error(err)
+			return
+		}
+
+		svrs, err := servers.GetServers(listResults)
+		if err != nil {
+			t.Error(err)
+			return
+		}
+
+		n = n + len(svrs)
+
+		for _, s := range svrs {
+			fmt.Fprintf(ts.W, "%s\t%s\t%s\t%s\t%s\t%s\t\n", s.Id, s.Name, ep.Region, s.Status, s.AccessIPv4, s.AccessIPv6)
+		}
+	}
+	ts.W.Flush()
+	fmt.Printf("--------\n%d servers listed.\n", n)
+}
+
+func TestListImages(t *testing.T) {
+	ts, err := tools.SetupForList(service)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	fmt.Fprintln(ts.W, "ID\tRegion\tName\tStatus\tCreated\t")
+
+	region := os.Getenv("OS_REGION_NAME")
+	n := 0
+	for _, ep := range ts.EPs {
+		if (region != "") && (region != ep.Region) {
+			continue
+		}
+
+		client := images.NewClient(ep.PublicURL, ts.A, ts.O)
+
+		listResults, err := images.List(client)
+		if err != nil {
+			t.Error(err)
+			return
+		}
+
+		imgs, err := images.GetImages(listResults)
+		if err != nil {
+			t.Error(err)
+			return
+		}
+
+		n = n + len(imgs)
+
+		for _, i := range imgs {
+			fmt.Fprintf(ts.W, "%s\t%s\t%s\t%s\t%s\t\n", i.Id, ep.Region, i.Name, i.Status, i.Created)
+		}
+	}
+	ts.W.Flush()
+	fmt.Printf("--------\n%d images listed.\n", n)
+}
+
+func TestListFlavors(t *testing.T) {
+	ts, err := tools.SetupForList(service)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	fmt.Fprintln(ts.W, "ID\tRegion\tName\tRAM\tDisk\tVCPUs\t")
+
+	region := os.Getenv("OS_REGION_NAME")
+	n := 0
+	for _, ep := range ts.EPs {
+		if (region != "") && (region != ep.Region) {
+			continue
+		}
+
+		client := flavors.NewClient(ep.PublicURL, ts.A, ts.O)
+
+		listResults, err := flavors.List(client, flavors.ListFilterOptions{})
+		if err != nil {
+			t.Error(err)
+			return
+		}
+
+		flavs, err := flavors.GetFlavors(listResults)
+		if err != nil {
+			t.Error(err)
+			return
+		}
+
+		n = n + len(flavs)
+
+		for _, f := range flavs {
+			fmt.Fprintf(ts.W, "%s\t%s\t%s\t%d\t%d\t%d\t\n", f.Id, ep.Region, f.Name, f.Ram, f.Disk, f.VCpus)
+		}
+	}
+	ts.W.Flush()
+	fmt.Printf("--------\n%d flavors listed.\n", n)
+}
+
+func TestGetFlavor(t *testing.T) {
+	ts, err := tools.SetupForCRUD()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	region := os.Getenv("OS_REGION_NAME")
+	for _, ep := range ts.EPs {
+		if (region != "") && (region != ep.Region) {
+			continue
+		}
+		client := flavors.NewClient(ep.PublicURL, ts.A, ts.O)
+
+		getResults, err := flavors.Get(client, ts.FlavorId)
+		if err != nil {
+			t.Fatal(err)
+		}
+		flav, err := flavors.GetFlavor(getResults)
+		if err != nil {
+			t.Fatal(err)
+		}
+		fmt.Printf("%#v\n", flav)
+	}
+}
+
+func TestCreateDestroyServer(t *testing.T) {
+	ts, err := tools.SetupForCRUD()
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	err = tools.CreateServer(ts)
+	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(ts.Client, ts.CreatedServer.Id)
+	}()
+
+	err = tools.WaitForStatus(ts, "ACTIVE")
+	if err != nil {
+		t.Error(err)
+	}
+}
+
+func TestUpdateServer(t *testing.T) {
+	ts, err := tools.SetupForCRUD()
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	err = tools.CreateServer(ts)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	defer func() {
+		servers.Delete(ts.Client, ts.CreatedServer.Id)
+	}()
+
+	err = tools.WaitForStatus(ts, "ACTIVE")
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	err = tools.ChangeServerName(ts)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+}
+
+func TestActionChangeAdminPassword(t *testing.T) {
+	t.Parallel()
+
+	ts, err := tools.SetupForCRUD()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = tools.CreateServer(ts)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	defer func(){
+		servers.Delete(ts.Client, ts.CreatedServer.Id)
+	}()
+
+	err = tools.WaitForStatus(ts, "ACTIVE")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = tools.ChangeAdminPassword(ts)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestActionReboot(t *testing.T) {
+	t.Parallel()
+
+	ts, err := tools.SetupForCRUD()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = tools.CreateServer(ts)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	defer func(){
+		servers.Delete(ts.Client, ts.CreatedServer.Id)
+	}()
+
+	err = tools.WaitForStatus(ts, "ACTIVE")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = servers.Reboot(ts.Client, ts.CreatedServer.Id, "aldhjflaskhjf")
+	if err == nil {
+		t.Fatal("Expected the SDK to provide an ArgumentError here")
+	}
+
+	err = tools.RebootServer(ts)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestActionRebuild(t *testing.T) {
+	t.Parallel()
+
+	ts, err := tools.SetupForCRUD()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = tools.CreateServer(ts)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	defer func(){
+		servers.Delete(ts.Client, ts.CreatedServer.Id)
+	}()
+
+	err = tools.WaitForStatus(ts, "ACTIVE")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = tools.RebuildServer(ts)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestActionResizeConfirm(t *testing.T) {
+	t.Parallel()
+	
+	ts, err := tools.SetupForCRUD()
+	if err != nil {
+		t.Fatal(err)
+	}
+	
+	err = tools.CreateServer(ts)
+	if err != nil {
+		t.Fatal(err)
+	}
+	
+	defer func(){
+		servers.Delete(ts.Client, ts.CreatedServer.Id)
+	}()
+	
+	err = tools.WaitForStatus(ts, "ACTIVE")
+	if err != nil {
+		t.Fatal(err)
+	}
+	
+	err = tools.ResizeServer(ts)
+	if err != nil {
+		t.Fatal(err)
+	}
+	
+	err = tools.ConfirmResize(ts)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestActionResizeRevert(t *testing.T) {
+	t.Parallel()
+	
+	ts, err := tools.SetupForCRUD()
+	if err != nil {
+		t.Fatal(err)
+	}
+	
+	err = tools.CreateServer(ts)
+	if err != nil {
+		t.Fatal(err)
+	}
+	
+	defer func(){
+		servers.Delete(ts.Client, ts.CreatedServer.Id)
+	}()
+	
+	err = tools.WaitForStatus(ts, "ACTIVE")
+	if err != nil {
+		t.Fatal(err)
+	}
+	
+	err = tools.ResizeServer(ts)
+	if err != nil {
+		t.Fatal(err)
+	}
+	
+	err = tools.RevertResize(ts)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
diff --git a/acceptance/openstack/compute/pkg.go b/acceptance/openstack/compute/pkg.go
new file mode 100644
index 0000000..a887fe9
--- /dev/null
+++ b/acceptance/openstack/compute/pkg.go
@@ -0,0 +1 @@
+package compute
diff --git a/acceptance/openstack/compute/test.go b/acceptance/openstack/compute/test.go
new file mode 100644
index 0000000..f03c0f9
--- /dev/null
+++ b/acceptance/openstack/compute/test.go
@@ -0,0 +1,368 @@
+// +build acceptance
+
+package openstack
+
+import (
+	"fmt"
+	"github.com/rackspace/gophercloud/openstack/compute/flavors"
+	"github.com/rackspace/gophercloud/openstack/compute/images"
+	"github.com/rackspace/gophercloud/openstack/compute/servers"
+	"os"
+	"testing"
+)
+
+var service = "compute"
+
+func TestListServers(t *testing.T) {
+	ts, err := setupForList(service)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	fmt.Fprintln(ts.w, "ID\tRegion\tName\tStatus\tIPv4\tIPv6\t")
+
+	region := os.Getenv("OS_REGION_NAME")
+	n := 0
+	for _, ep := range ts.eps {
+		if (region != "") && (region != ep.Region) {
+			continue
+		}
+
+		client := servers.NewClient(ep.PublicURL, ts.a, ts.o)
+
+		listResults, err := servers.List(client)
+		if err != nil {
+			t.Error(err)
+			return
+		}
+
+		svrs, err := servers.GetServers(listResults)
+		if err != nil {
+			t.Error(err)
+			return
+		}
+
+		n = n + len(svrs)
+
+		for _, s := range svrs {
+			fmt.Fprintf(ts.w, "%s\t%s\t%s\t%s\t%s\t%s\t\n", s.Id, s.Name, ep.Region, s.Status, s.AccessIPv4, s.AccessIPv6)
+		}
+	}
+	ts.w.Flush()
+	fmt.Printf("--------\n%d servers listed.\n", n)
+}
+
+func TestListImages(t *testing.T) {
+	ts, err := setupForList(service)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	fmt.Fprintln(ts.w, "ID\tRegion\tName\tStatus\tCreated\t")
+
+	region := os.Getenv("OS_REGION_NAME")
+	n := 0
+	for _, ep := range ts.eps {
+		if (region != "") && (region != ep.Region) {
+			continue
+		}
+
+		client := images.NewClient(ep.PublicURL, ts.a, ts.o)
+
+		listResults, err := images.List(client)
+		if err != nil {
+			t.Error(err)
+			return
+		}
+
+		imgs, err := images.GetImages(listResults)
+		if err != nil {
+			t.Error(err)
+			return
+		}
+
+		n = n + len(imgs)
+
+		for _, i := range imgs {
+			fmt.Fprintf(ts.w, "%s\t%s\t%s\t%s\t%s\t\n", i.Id, ep.Region, i.Name, i.Status, i.Created)
+		}
+	}
+	ts.w.Flush()
+	fmt.Printf("--------\n%d images listed.\n", n)
+}
+
+func TestListFlavors(t *testing.T) {
+	ts, err := setupForList(service)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	fmt.Fprintln(ts.w, "ID\tRegion\tName\tRAM\tDisk\tVCPUs\t")
+
+	region := os.Getenv("OS_REGION_NAME")
+	n := 0
+	for _, ep := range ts.eps {
+		if (region != "") && (region != ep.Region) {
+			continue
+		}
+
+		client := flavors.NewClient(ep.PublicURL, ts.a, ts.o)
+
+		listResults, err := flavors.List(client, flavors.ListFilterOptions{})
+		if err != nil {
+			t.Error(err)
+			return
+		}
+
+		flavs, err := flavors.GetFlavors(listResults)
+		if err != nil {
+			t.Error(err)
+			return
+		}
+
+		n = n + len(flavs)
+
+		for _, f := range flavs {
+			fmt.Fprintf(ts.w, "%s\t%s\t%s\t%d\t%d\t%d\t\n", f.Id, ep.Region, f.Name, f.Ram, f.Disk, f.VCpus)
+		}
+	}
+	ts.w.Flush()
+	fmt.Printf("--------\n%d flavors listed.\n", n)
+}
+
+func TestGetFlavor(t *testing.T) {
+	ts, err := setupForCRUD()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	region := os.Getenv("OS_REGION_NAME")
+	for _, ep := range ts.eps {
+		if (region != "") && (region != ep.Region) {
+			continue
+		}
+		client := flavors.NewClient(ep.PublicURL, ts.a, ts.o)
+
+		getResults, err := flavors.Get(client, ts.flavorId)
+		if err != nil {
+			t.Fatal(err)
+		}
+		flav, err := flavors.GetFlavor(getResults)
+		if err != nil {
+			t.Fatal(err)
+		}
+		fmt.Printf("%#v\n", flav)
+	}
+}
+
+func TestCreateDestroyServer(t *testing.T) {
+	ts, err := setupForCRUD()
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	err = createServer(ts)
+	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(ts.client, ts.createdServer.Id)
+	}()
+
+	err = waitForStatus(ts, "ACTIVE")
+	if err != nil {
+		t.Error(err)
+	}
+}
+
+func TestUpdateServer(t *testing.T) {
+	ts, err := setupForCRUD()
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	err = createServer(ts)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	defer func() {
+		servers.Delete(ts.client, ts.createdServer.Id)
+	}()
+
+	err = waitForStatus(ts, "ACTIVE")
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	err = changeServerName(ts)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+}
+
+func TestActionChangeAdminPassword(t *testing.T) {
+	t.Parallel()
+
+	ts, err := setupForCRUD()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = createServer(ts)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	defer func(){
+		servers.Delete(ts.client, ts.createdServer.Id)
+	}()
+
+	err = waitForStatus(ts, "ACTIVE")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = changeAdminPassword(ts)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestActionReboot(t *testing.T) {
+	t.Parallel()
+
+	ts, err := setupForCRUD()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = createServer(ts)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	defer func(){
+		servers.Delete(ts.client, ts.createdServer.Id)
+	}()
+
+	err = waitForStatus(ts, "ACTIVE")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = servers.Reboot(ts.client, ts.createdServer.Id, "aldhjflaskhjf")
+	if err == nil {
+		t.Fatal("Expected the SDK to provide an ArgumentError here")
+	}
+
+	err = rebootServer(ts)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestActionRebuild(t *testing.T) {
+	t.Parallel()
+
+	ts, err := setupForCRUD()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = createServer(ts)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	defer func(){
+		servers.Delete(ts.client, ts.createdServer.Id)
+	}()
+
+	err = waitForStatus(ts, "ACTIVE")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = rebuildServer(ts)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestActionResizeConfirm(t *testing.T) {
+	t.Parallel()
+	
+	ts, err := setupForCRUD()
+	if err != nil {
+		t.Fatal(err)
+	}
+	
+	err = createServer(ts)
+	if err != nil {
+		t.Fatal(err)
+	}
+	
+	defer func(){
+		servers.Delete(ts.client, ts.createdServer.Id)
+	}()
+	
+	err = waitForStatus(ts, "ACTIVE")
+	if err != nil {
+		t.Fatal(err)
+	}
+	
+	err = resizeServer(ts)
+	if err != nil {
+		t.Fatal(err)
+	}
+	
+	err = confirmResize(ts)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestActionResizeRevert(t *testing.T) {
+	t.Parallel()
+	
+	ts, err := setupForCRUD()
+	if err != nil {
+		t.Fatal(err)
+	}
+	
+	err = createServer(ts)
+	if err != nil {
+		t.Fatal(err)
+	}
+	
+	defer func(){
+		servers.Delete(ts.client, ts.createdServer.Id)
+	}()
+	
+	err = waitForStatus(ts, "ACTIVE")
+	if err != nil {
+		t.Fatal(err)
+	}
+	
+	err = resizeServer(ts)
+	if err != nil {
+		t.Fatal(err)
+	}
+	
+	err = revertResize(ts)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
diff --git a/acceptance/openstack/compute/tools_test.go b/acceptance/openstack/compute/tools_test.go
new file mode 100644
index 0000000..0469053
--- /dev/null
+++ b/acceptance/openstack/compute/tools_test.go
@@ -0,0 +1,364 @@
+// +build acceptance
+
+package compute
+
+import (
+	"crypto/rand"
+	"fmt"
+	"github.com/rackspace/gophercloud/openstack/compute/servers"
+	"github.com/rackspace/gophercloud/openstack/identity"
+	"github.com/rackspace/gophercloud/openstack/utils"
+	"os"
+	"text/tabwriter"
+	"time"
+)
+
+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
+	flavorIdResize string
+}
+
+func SetupForList(service string) (*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 = FindAllEndpoints(ts.sc, service)
+	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("compute")
+	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.flavorIdResize = os.Getenv("OS_FLAVOR_ID_RESIZE")
+	if ts.flavorIdResize == "" {
+		return ts, fmt.Errorf("Expected OS_FLAVOR_ID_RESIZE environment variable to be set")
+	}
+
+	if ts.flavorIdResize == ts.flavorId {
+		return ts, fmt.Errorf("OS_FLAVOR_ID and OS_FLAVOR_ID_RESIZE cannot be the same")
+	}
+
+	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 FindAllEndpoints(sc *identity.ServiceCatalog, service string) ([]identity.Endpoint, error) {
+	ces, err := sc.CatalogEntries()
+	if err != nil {
+		return nil, err
+	}
+
+	for _, ce := range ces {
+		if ce.Type == service {
+			return ce.Endpoints, nil
+		}
+	}
+
+	return nil, fmt.Errorf(service + " 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 reached state %s after %d seconds (approximately)\n", s, 300-timeout)
+			break
+		}
+	}
+
+	if err == errTimeout {
+		fmt.Printf("Time out -- 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
+}
+
+func MakeNewPassword(oldPass string) string {
+	fmt.Println("Current password: "+oldPass)
+	randomPassword := RandomString("", 16)
+	for randomPassword == oldPass {
+		randomPassword = RandomString("", 16)
+	}
+	fmt.Println("    New password: "+randomPassword)
+	return randomPassword
+}
+
+func ChangeAdminPassword(ts *testState) error {
+	randomPassword := MakeNewPassword(ts.createdServer.AdminPass)
+	
+	err := servers.ChangeAdminPassword(ts.client, ts.createdServer.Id, randomPassword)
+	if err != nil {
+		return err
+	}
+	
+	err = WaitForStatus(ts, "PASSWORD")
+	if err != nil {
+		return err
+	}
+	
+	return WaitForStatus(ts, "ACTIVE")
+}
+
+func RebootServer(ts *testState) error {
+	fmt.Println("Attempting reboot of server "+ts.createdServer.Id)
+	err := servers.Reboot(ts.client, ts.createdServer.Id, servers.OSReboot)
+	if err != nil {
+		return err
+	}
+	
+	err = WaitForStatus(ts, "REBOOT")
+	if err != nil {
+		return err
+	}
+	
+	return WaitForStatus(ts, "ACTIVE")
+}
+
+func RebuildServer(ts *testState) error {
+	fmt.Println("Attempting to rebuild server "+ts.createdServer.Id)
+
+	newPassword := MakeNewPassword(ts.createdServer.AdminPass)
+	newName := RandomString("ACPTTEST", 16)
+	sr, err := servers.Rebuild(ts.client, ts.createdServer.Id, newName, newPassword, ts.imageId, nil)
+	if err != nil {
+		return err
+	}
+	
+	s, err := servers.GetServer(sr)
+	if err != nil {
+		return err
+	}
+	if s.Id != ts.createdServer.Id {
+		return fmt.Errorf("Expected rebuilt server ID of %s; got %s", ts.createdServer.Id, s.Id)
+	}
+
+	err = WaitForStatus(ts, "REBUILD")
+	if err != nil {
+		return err
+	}
+	
+	return WaitForStatus(ts, "ACTIVE")
+}
+
+func ResizeServer(ts *testState) error {
+	fmt.Println("Attempting to resize server "+ts.createdServer.Id)
+
+	err := servers.Resize(ts.client, ts.createdServer.Id, ts.flavorIdResize)
+	if err != nil {
+		return err
+	}
+
+	err = WaitForStatus(ts, "RESIZE")
+	if err != nil {
+		return err
+	}
+
+	return WaitForStatus(ts, "VERIFY_RESIZE")
+}
+
+func ConfirmResize(ts *testState) error {
+	fmt.Println("Attempting to confirm resize for server "+ts.createdServer.Id)
+	
+	err := servers.ConfirmResize(ts.client, ts.createdServer.Id)
+	if err != nil {
+		return err
+	}
+	
+	return WaitForStatus(ts, "ACTIVE")
+}
+
+func RevertResize(ts *testState) error {
+	fmt.Println("Attempting to revert resize for server "+ts.createdServer.Id)
+	
+	err := servers.RevertResize(ts.client, ts.createdServer.Id)
+	if err != nil {
+		return err
+	}
+
+	err = WaitForStatus(ts, "REVERT_RESIZE")
+	if err != nil {
+		return err
+	}
+
+	return WaitForStatus(ts, "ACTIVE")
+}
+
+// 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)
+}
