Block Storage Acceptance Test Cleanup (#43)
diff --git a/acceptance/openstack/blockstorage/v1/.blockstorage.go.swp b/acceptance/openstack/blockstorage/v1/.blockstorage.go.swp
new file mode 100644
index 0000000..0b710e7
--- /dev/null
+++ b/acceptance/openstack/blockstorage/v1/.blockstorage.go.swp
Binary files differ
diff --git a/acceptance/openstack/blockstorage/v1/blockstorage.go b/acceptance/openstack/blockstorage/v1/blockstorage.go
new file mode 100644
index 0000000..3d4c9f1
--- /dev/null
+++ b/acceptance/openstack/blockstorage/v1/blockstorage.go
@@ -0,0 +1,183 @@
+// Package v1 contains common functions for creating block storage based
+// resources for use in acceptance tests. See the `*_test.go` files for
+// example usages.
+package v1
+
+import (
+ "testing"
+
+ "github.com/gophercloud/gophercloud"
+ "github.com/gophercloud/gophercloud/acceptance/tools"
+ "github.com/gophercloud/gophercloud/openstack/blockstorage/v1/snapshots"
+ "github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes"
+ "github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumetypes"
+)
+
+// CreateSnapshot will create a volume snapshot based off of a given volume and
+// with a random name. An error will be returned if the snapshot failed to be
+// created.
+func CreateSnapshot(t *testing.T, client *gophercloud.ServiceClient, volume *volumes.Volume) (*snapshots.Snapshot, error) {
+ if testing.Short() {
+ t.Skip("Skipping test that requires snapshot creation in short mode.")
+ }
+
+ snapshotName := tools.RandomString("ACPTTEST", 16)
+ t.Logf("Attempting to create snapshot %s based on volume %s", snapshotName, volume.ID)
+
+ createOpts := snapshots.CreateOpts{
+ Name: snapshotName,
+ VolumeID: volume.ID,
+ }
+
+ snapshot, err := snapshots.Create(client, createOpts).Extract()
+ if err != nil {
+ return snapshot, err
+ }
+
+ err = snapshots.WaitForStatus(client, snapshot.ID, "available", 60)
+ if err != nil {
+ return snapshot, err
+ }
+
+ return snapshot, nil
+}
+
+// CreateVolume will create a volume with a random name and size of 1GB. An
+// error will be returned if the volume was unable to be created.
+func CreateVolume(t *testing.T, client *gophercloud.ServiceClient) (*volumes.Volume, error) {
+ if testing.Short() {
+ t.Skip("Skipping test that requires volume creation in short mode.")
+ }
+
+ volumeName := tools.RandomString("ACPTTEST", 16)
+ t.Logf("Attempting to create volume: %s", volumeName)
+
+ createOpts := volumes.CreateOpts{
+ Size: 1,
+ Name: volumeName,
+ }
+
+ volume, err := volumes.Create(client, createOpts).Extract()
+ if err != nil {
+ return volume, err
+ }
+
+ err = volumes.WaitForStatus(client, volume.ID, "available", 60)
+ if err != nil {
+ return volume, err
+ }
+
+ return volume, nil
+}
+
+// CreateVolumeType will create a volume type with a random name. An error will
+// be returned if the volume type was unable to be created.
+func CreateVolumeType(t *testing.T, client *gophercloud.ServiceClient) (*volumetypes.VolumeType, error) {
+ volumeTypeName := tools.RandomString("ACPTTEST", 16)
+ t.Logf("Attempting to create volume type: %s", volumeTypeName)
+
+ createOpts := volumetypes.CreateOpts{
+ Name: volumeTypeName,
+ ExtraSpecs: map[string]interface{}{
+ "capabilities": "ssd",
+ "priority": 3,
+ },
+ }
+
+ volumeType, err := volumetypes.Create(client, createOpts).Extract()
+ if err != nil {
+ return volumeType, err
+ }
+
+ return volumeType, nil
+}
+
+// DeleteSnapshot will delete a snapshot. A fatal error will occur if the
+// snapshot failed to be deleted. This works best when used as a deferred
+// function.
+func DeleteSnapshotshot(t *testing.T, client *gophercloud.ServiceClient, snapshot *snapshots.Snapshot) {
+ err := snapshots.Delete(client, snapshot.ID).ExtractErr()
+ if err != nil {
+ t.Fatalf("Unable to delete snapshot %s: %v", snapshot.ID, err)
+ }
+
+ // Volumes can't be deleted until their snapshots have been,
+ // so block up to 120 seconds for the snapshot to delete.
+ err = gophercloud.WaitFor(120, func() (bool, error) {
+ _, err := snapshots.Get(client, snapshot.ID).Extract()
+ if err != nil {
+ return true, nil
+ }
+
+ return false, nil
+ })
+ if err != nil {
+ t.Fatalf("Unable to wait for snapshot to delete: %v", err)
+ }
+
+ t.Logf("Deleted snapshot: %s", snapshot.ID)
+}
+
+// DeleteVolume will delete a volume. A fatal error will occur if the volume
+// failed to be deleted. This works best when used as a deferred function.
+func DeleteVolume(t *testing.T, client *gophercloud.ServiceClient, volume *volumes.Volume) {
+ err := volumes.Delete(client, volume.ID).ExtractErr()
+ if err != nil {
+ t.Fatalf("Unable to delete volume %s: %v", volume.ID, err)
+ }
+
+ t.Logf("Deleted volume: %s", volume.ID)
+}
+
+// DeleteVolumeType will delete a volume type. A fatal error will occur if the
+// volume type failed to be deleted. This works best when used as a deferred
+// function.
+func DeleteVolumeType(t *testing.T, client *gophercloud.ServiceClient, volumeType *volumetypes.VolumeType) {
+ err := volumetypes.Delete(client, volumeType.ID).ExtractErr()
+ if err != nil {
+ t.Fatalf("Unable to delete volume type %s: %v", volumeType.ID, err)
+ }
+
+ t.Logf("Deleted volume type: %s", volumeType.ID)
+}
+
+// PrintVolume will print a volume and all of its attributes.
+func PrintVolume(t *testing.T, volume *volumes.Volume) {
+ t.Logf("ID: %s", volume.ID)
+ t.Logf("Status: %s", volume.Status)
+ t.Logf("Name: %s", volume.Name)
+ t.Logf("AvailabilityZone: %s", volume.AvailabilityZone)
+ t.Logf("Bootable: %s", volume.Bootable)
+ t.Logf("CreatedAt: %v", volume.CreatedAt)
+ t.Logf("Description: %s", volume.Description)
+ t.Logf("VolumeType: %s", volume.VolumeType)
+ t.Logf("SnapshotID: %s", volume.SnapshotID)
+ t.Logf("SourceVolID: %s", volume.SourceVolID)
+ t.Logf("Size: %d", volume.Size)
+ t.Logf("Metadata: %#v", volume.Metadata)
+ t.Logf("Attachments: %#v", volume.Attachments)
+}
+
+// PrintVolumeType will print a volume type and all of its attributes.
+func PrintVolumeType(t *testing.T, volumeType *volumetypes.VolumeType) {
+ t.Logf("ID: %s", volumeType.ID)
+ t.Logf("Name: %s", volumeType.Name)
+ t.Logf("ExtraSpecs: %#v", volumeType.ExtraSpecs)
+}
+
+// PrintSnapshot will print a snapshot and all of its attributes.
+func PrintSnapshot(t *testing.T, snapshot *snapshots.Snapshot) {
+ t.Logf("ID: %s", snapshot.ID)
+ t.Logf("Status: %s", snapshot.Status)
+ t.Logf("Name: %s", snapshot.Name)
+ t.Logf("AvailabilityZone: %s", snapshot.AvailabilityZone)
+ t.Logf("Bootable: %s", snapshot.Bootable)
+ t.Logf("CreatedAt: %v", snapshot.CreatedAt)
+ t.Logf("Description: %s", snapshot.Description)
+ t.Logf("VolumeType: %s", snapshot.VolumeType)
+ t.Logf("SnapshotID: %s", snapshot.SnapshotID)
+ t.Logf("VolumeID: %s", snapshot.VolumeID)
+ t.Logf("Size: %d", snapshot.Size)
+ t.Logf("Metadata: %#v", snapshot.Metadata)
+ t.Logf("Attachments: %#v", snapshot.Attachments)
+}
diff --git a/acceptance/openstack/blockstorage/v1/snapshots_test.go b/acceptance/openstack/blockstorage/v1/snapshots_test.go
index 2b737e7..2dc58db 100644
--- a/acceptance/openstack/blockstorage/v1/snapshots_test.go
+++ b/acceptance/openstack/blockstorage/v1/snapshots_test.go
@@ -1,70 +1,57 @@
-// +build acceptance
+// +build acceptance blockstorage
package v1
import (
"testing"
- "github.com/gophercloud/gophercloud"
+ "github.com/gophercloud/gophercloud/acceptance/clients"
"github.com/gophercloud/gophercloud/openstack/blockstorage/v1/snapshots"
- "github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes"
- th "github.com/gophercloud/gophercloud/testhelper"
)
-func TestSnapshots(t *testing.T) {
+func TestSnapshotsList(t *testing.T) {
+ client, err := clients.NewBlockStorageV1Client()
+ if err != nil {
+ t.Fatalf("Unable to create a blockstorage client: %v", err)
+ }
- client, err := newClient(t)
- th.AssertNoErr(t, err)
+ allPages, err := snapshots.List(client, snapshots.ListOpts{}).AllPages()
+ if err != nil {
+ t.Fatalf("Unable to retrieve snapshots: %v", err)
+ }
- v, err := volumes.Create(client, &volumes.CreateOpts{
- Name: "gophercloud-test-volume",
- Size: 1,
- }).Extract()
- th.AssertNoErr(t, err)
+ allSnapshots, err := snapshots.ExtractSnapshots(allPages)
+ if err != nil {
+ t.Fatalf("Unable to extract snapshots: %v", err)
+ }
- err = volumes.WaitForStatus(client, v.ID, "available", 120)
- th.AssertNoErr(t, err)
+ for _, snapshot := range allSnapshots {
+ PrintSnapshot(t, &snapshot)
+ }
+}
- t.Logf("Created volume: %v\n", v)
+func TestSnapshotsCreateDelete(t *testing.T) {
+ client, err := clients.NewBlockStorageV1Client()
+ if err != nil {
+ t.Fatalf("Unable to create a blockstorage client: %v", err)
+ }
- ss, err := snapshots.Create(client, &snapshots.CreateOpts{
- Name: "gophercloud-test-snapshot",
- VolumeID: v.ID,
- }).Extract()
- th.AssertNoErr(t, err)
+ volume, err := CreateVolume(t, client)
+ if err != nil {
+ t.Fatalf("Unable to create volume: %v", err)
+ }
+ defer DeleteVolume(t, client, volume)
- err = snapshots.WaitForStatus(client, ss.ID, "available", 120)
- th.AssertNoErr(t, err)
+ snapshot, err := CreateSnapshot(t, client, volume)
+ if err != nil {
+ t.Fatalf("Unable to create snapshot: %v", err)
+ }
+ defer DeleteSnapshotshot(t, client, snapshot)
- t.Logf("Created snapshot: %+v\n", ss)
+ newSnapshot, err := snapshots.Get(client, snapshot.ID).Extract()
+ if err != nil {
+ t.Errorf("Unable to retrieve snapshot: %v", err)
+ }
- err = snapshots.Delete(client, ss.ID).ExtractErr()
- th.AssertNoErr(t, err)
-
- err = gophercloud.WaitFor(120, func() (bool, error) {
- _, err := snapshots.Get(client, ss.ID).Extract()
- if err != nil {
- return true, nil
- }
-
- return false, nil
- })
- th.AssertNoErr(t, err)
-
- t.Log("Deleted snapshot\n")
-
- err = volumes.Delete(client, v.ID).ExtractErr()
- th.AssertNoErr(t, err)
-
- err = gophercloud.WaitFor(120, func() (bool, error) {
- _, err := volumes.Get(client, v.ID).Extract()
- if err != nil {
- return true, nil
- }
-
- return false, nil
- })
- th.AssertNoErr(t, err)
-
- t.Log("Deleted volume\n")
+ PrintSnapshot(t, newSnapshot)
}
diff --git a/acceptance/openstack/blockstorage/v1/volumes_test.go b/acceptance/openstack/blockstorage/v1/volumes_test.go
index a7bf123..e375c59 100644
--- a/acceptance/openstack/blockstorage/v1/volumes_test.go
+++ b/acceptance/openstack/blockstorage/v1/volumes_test.go
@@ -3,61 +3,49 @@
package v1
import (
- "os"
"testing"
- "github.com/gophercloud/gophercloud"
- "github.com/gophercloud/gophercloud/openstack"
+ "github.com/gophercloud/gophercloud/acceptance/clients"
"github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes"
- "github.com/gophercloud/gophercloud/pagination"
- th "github.com/gophercloud/gophercloud/testhelper"
)
-func newClient(t *testing.T) (*gophercloud.ServiceClient, error) {
- ao, err := openstack.AuthOptionsFromEnv()
- th.AssertNoErr(t, err)
-
- client, err := openstack.AuthenticatedClient(ao)
- th.AssertNoErr(t, err)
-
- return openstack.NewBlockStorageV1(client, gophercloud.EndpointOpts{
- Region: os.Getenv("OS_REGION_NAME"),
- })
-}
-
-func TestVolumes(t *testing.T) {
- client, err := newClient(t)
- th.AssertNoErr(t, err)
-
- cv, err := volumes.Create(client, &volumes.CreateOpts{
- Size: 1,
- Name: "gophercloud-test-volume",
- }).Extract()
- th.AssertNoErr(t, err)
- defer func() {
- err = volumes.WaitForStatus(client, cv.ID, "available", 60)
- th.AssertNoErr(t, err)
- err = volumes.Delete(client, cv.ID).ExtractErr()
- th.AssertNoErr(t, err)
- }()
-
- _, err = volumes.Update(client, cv.ID, &volumes.UpdateOpts{
- Name: "gophercloud-updated-volume",
- }).Extract()
- th.AssertNoErr(t, err)
-
- v, err := volumes.Get(client, cv.ID).Extract()
- th.AssertNoErr(t, err)
- t.Logf("Got volume: %+v\n", v)
-
- if v.Name != "gophercloud-updated-volume" {
- t.Errorf("Unable to update volume: Expected name: gophercloud-updated-volume\nActual name: %s", v.Name)
+func TestVolumesList(t *testing.T) {
+ client, err := clients.NewBlockStorageV1Client()
+ if err != nil {
+ t.Fatalf("Unable to create a blockstorage client: %v", err)
}
- err = volumes.List(client, &volumes.ListOpts{Name: "gophercloud-updated-volume"}).EachPage(func(page pagination.Page) (bool, error) {
- vols, err := volumes.ExtractVolumes(page)
- th.CheckEquals(t, 1, len(vols))
- return true, err
- })
- th.AssertNoErr(t, err)
+ allPages, err := volumes.List(client, volumes.ListOpts{}).AllPages()
+ if err != nil {
+ t.Fatalf("Unable to retrieve volumes: %v", err)
+ }
+
+ allVolumes, err := volumes.ExtractVolumes(allPages)
+ if err != nil {
+ t.Fatalf("Unable to extract volumes: %v", err)
+ }
+
+ for _, volume := range allVolumes {
+ PrintVolume(t, &volume)
+ }
+}
+
+func TestVolumesCreateDestroy(t *testing.T) {
+ client, err := clients.NewBlockStorageV1Client()
+ if err != nil {
+ t.Fatalf("Unable to create blockstorage client: %v", err)
+ }
+
+ volume, err := CreateVolume(t, client)
+ if err != nil {
+ t.Fatalf("Unable to create volume: %v", err)
+ }
+ defer DeleteVolume(t, client, volume)
+
+ newVolume, err := volumes.Get(client, volume.ID).Extract()
+ if err != nil {
+ t.Errorf("Unable to retrieve volume: %v", err)
+ }
+
+ PrintVolume(t, newVolume)
}
diff --git a/acceptance/openstack/blockstorage/v1/volumetypes_test.go b/acceptance/openstack/blockstorage/v1/volumetypes_test.go
index ebfa3de..843ea21 100644
--- a/acceptance/openstack/blockstorage/v1/volumetypes_test.go
+++ b/acceptance/openstack/blockstorage/v1/volumetypes_test.go
@@ -1,49 +1,46 @@
-// +build acceptance
+// +build acceptance blockstorage
package v1
import (
"testing"
- "time"
+ "github.com/gophercloud/gophercloud/acceptance/clients"
"github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumetypes"
- "github.com/gophercloud/gophercloud/pagination"
- th "github.com/gophercloud/gophercloud/testhelper"
)
-func TestVolumeTypes(t *testing.T) {
- client, err := newClient(t)
- th.AssertNoErr(t, err)
+func TestVolumeTypesList(t *testing.T) {
+ client, err := clients.NewBlockStorageV1Client()
+ if err != nil {
+ t.Fatalf("Unable to create a blockstorage client: %v", err)
+ }
- vt, err := volumetypes.Create(client, &volumetypes.CreateOpts{
- ExtraSpecs: map[string]interface{}{
- "capabilities": "gpu",
- "priority": 3,
- },
- Name: "gophercloud-test-volumeType",
- }).Extract()
- th.AssertNoErr(t, err)
- defer func() {
- time.Sleep(10000 * time.Millisecond)
- err = volumetypes.Delete(client, vt.ID).ExtractErr()
- if err != nil {
- t.Error(err)
- return
- }
- }()
- t.Logf("Created volume type: %+v\n", vt)
+ allPages, err := volumetypes.List(client).AllPages()
+ if err != nil {
+ t.Fatalf("Unable to retrieve volume types: %v", err)
+ }
- vt, err = volumetypes.Get(client, vt.ID).Extract()
- th.AssertNoErr(t, err)
- t.Logf("Got volume type: %+v\n", vt)
+ allVolumeTypes, err := volumetypes.ExtractVolumeTypes(allPages)
+ if err != nil {
+ t.Fatalf("Unable to extract volume types: %v", err)
+ }
- err = volumetypes.List(client).EachPage(func(page pagination.Page) (bool, error) {
- volTypes, err := volumetypes.ExtractVolumeTypes(page)
- if len(volTypes) != 1 {
- t.Errorf("Expected 1 volume type, got %d", len(volTypes))
- }
- t.Logf("Listing volume types: %+v\n", volTypes)
- return true, err
- })
- th.AssertNoErr(t, err)
+ for _, volumeType := range allVolumeTypes {
+ PrintVolumeType(t, &volumeType)
+ }
+}
+
+func TestVolumeTypesCreateDestroy(t *testing.T) {
+ client, err := clients.NewBlockStorageV1Client()
+ if err != nil {
+ t.Fatalf("Unable to create a blockstorage client: %v", err)
+ }
+
+ volumeType, err := CreateVolumeType(t, client)
+ if err != nil {
+ t.Fatalf("Unable to create volume type: %v", err)
+ }
+ defer DeleteVolumeType(t, client, volumeType)
+
+ PrintVolumeType(t, volumeType)
}