Refactor compute acceptance tests to prep for extensions tests
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)
+}