Rework the compute acceptance tests.
diff --git a/acceptance/openstack/compute/v2/compute_test.go b/acceptance/openstack/compute/v2/compute_test.go
index 2310858..f5d0a65 100644
--- a/acceptance/openstack/compute/v2/compute_test.go
+++ b/acceptance/openstack/compute/v2/compute_test.go
@@ -1,370 +1,102 @@
// +build acceptance
-package compute
+package v2
import (
"fmt"
"os"
- "testing"
+ "strings"
+ "github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/acceptance/tools"
- "github.com/rackspace/gophercloud/openstack/compute/v2/flavors"
- "github.com/rackspace/gophercloud/openstack/compute/v2/images"
+ "github.com/rackspace/gophercloud/openstack"
"github.com/rackspace/gophercloud/openstack/compute/v2/servers"
+ "github.com/rackspace/gophercloud/openstack/utils"
)
-var service = "compute"
-
-func TestListServers(t *testing.T) {
- ts, err := tools.SetupForList(service)
+func newClient() (*gophercloud.ServiceClient, error) {
+ ao, err := utils.AuthOptions()
if err != nil {
- t.Error(err)
- return
+ return nil, err
}
- fmt.Fprintln(ts.W, "ID\tRegion\tName\tStatus\tIPv4\tIPv6\t")
+ client, err := openstack.AuthenticatedClient(ao)
+ if err != nil {
+ return nil, err
+ }
- region := os.Getenv("OS_REGION_NAME")
- n := 0
- for _, ep := range ts.EPs {
- if (region != "") && (region != ep.Region) {
- continue
- }
+ return openstack.NewComputeV2(client, gophercloud.EndpointOpts{
+ Region: os.Getenv("OS_REGION_NAME"),
+ })
+}
- client := servers.NewClient(ep.PublicURL, ts.A, ts.O)
-
- listResults, err := servers.List(client)
+func waitForStatus(client *gophercloud.ServiceClient, server *servers.Server, status string) error {
+ return tools.WaitFor(func() (bool, error) {
+ response, err := servers.Get(client, server.ID)
if err != nil {
- t.Error(err)
- return
+ return false, err
}
-
- svrs, err := servers.GetServers(listResults)
+ latest, err := servers.ExtractServer(response)
if err != nil {
- t.Error(err)
- return
+ return false, err
}
- 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)
+ if latest.Status == status {
+ // Success!
+ return true, nil
}
- }
- ts.W.Flush()
- fmt.Printf("--------\n%d servers listed.\n", n)
+
+ return false, nil
+ })
}
-func TestListImages(t *testing.T) {
- ts, err := tools.SetupForList(service)
- if err != nil {
- t.Error(err)
- return
- }
+// ComputeChoices contains image and flavor selections for use by the acceptance tests.
+type ComputeChoices struct {
+ // ImageID contains the ID of a valid image.
+ ImageID string
- fmt.Fprintln(ts.W, "ID\tRegion\tName\tStatus\tCreated\t")
+ // FlavorID contains the ID of a valid flavor.
+ FlavorID string
- 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)
+ // FlavorIDResize contains the ID of a different flavor available on the same OpenStack installation, that is distinct
+ // from FlavorID.
+ FlavorIDResize string
}
-func TestListFlavors(t *testing.T) {
- ts, err := tools.SetupForList(service)
- if err != nil {
- t.Error(err)
- return
+// ComputeChoicesFromEnv populates a ComputeChoices struct from environment variables.
+// If any required state is missing, an `error` will be returned that enumerates the missing properties.
+func ComputeChoicesFromEnv() (*ComputeChoices, error) {
+ imageID := os.Getenv("OS_IMAGE_ID")
+ flavorID := os.Getenv("OS_FLAVOR_ID")
+ flavorIDResize := os.Getenv("OS_FLAVOR_ID_RESIZE")
+
+ missing := make([]string, 0, 3)
+ if imageID == "" {
+ missing = append(missing, "OS_IMAGE_ID")
+ }
+ if flavorID == "" {
+ missing = append(missing, "OS_FLAVOR_ID")
+ }
+ if flavorIDResize == "" {
+ missing = append(missing, "OS_FLAVOR_ID_RESIZE")
}
- fmt.Fprintln(ts.W, "ID\tRegion\tName\tRAM\tDisk\tVCPUs\t")
+ notDistinct := ""
+ if flavorID == flavorIDResize {
+ notDistinct = "OS_FLAVOR_ID and OS_FLAVOR_ID_RESIZE must be distinct."
+ }
- region := os.Getenv("OS_REGION_NAME")
- n := 0
- for _, ep := range ts.EPs {
- if (region != "") && (region != ep.Region) {
- continue
+ if len(missing) > 0 || notDistinct != "" {
+ text := "You're missing some important setup:\n"
+ if len(missing) > 0 {
+ text += " * These environment variables must be provided: " + strings.Join(missing, ", ") + "\n"
+ }
+ if notDistinct != "" {
+ text += " * " + notDistinct + "\n"
}
- 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)
+ return nil, fmt.Errorf(text)
}
- 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)
- }
+ return &ComputeChoices{ImageID: imageID, FlavorID: flavorID, FlavorIDResize: flavorIDResize}, nil
}