1// Package v2 contains common functions for creating db resources for use
2// in acceptance tests. See the `*_test.go` files for example usages.
3package v1
4
5import (
6	"fmt"
7	"testing"
8
9	"github.com/gophercloud/gophercloud"
10	"github.com/gophercloud/gophercloud/acceptance/clients"
11	"github.com/gophercloud/gophercloud/acceptance/tools"
12	"github.com/gophercloud/gophercloud/openstack/db/v1/databases"
13	"github.com/gophercloud/gophercloud/openstack/db/v1/instances"
14	"github.com/gophercloud/gophercloud/openstack/db/v1/users"
15)
16
17// CreateDatabase will create a database with a randomly generated name.
18// An error will be returned if the database was unable to be created.
19func CreateDatabase(t *testing.T, client *gophercloud.ServiceClient, instanceID string) error {
20	name := tools.RandomString("ACPTTEST", 8)
21	t.Logf("Attempting to create database: %s", name)
22
23	createOpts := databases.BatchCreateOpts{
24		databases.CreateOpts{
25			Name: name,
26		},
27	}
28
29	return databases.Create(client, instanceID, createOpts).ExtractErr()
30}
31
32// CreateInstance will create an instance with a randomly generated name.
33// The flavor of the instance will be the value of the OS_FLAVOR_ID
34// environment variable. The Datastore will be pulled from the
35// OS_DATASTORE_TYPE_ID environment variable.
36// An error will be returned if the instance was unable to be created.
37func CreateInstance(t *testing.T, client *gophercloud.ServiceClient) (*instances.Instance, error) {
38	if testing.Short() {
39		t.Skip("Skipping test that requires instance creation in short mode.")
40	}
41
42	choices, err := clients.AcceptanceTestChoicesFromEnv()
43	if err != nil {
44		return nil, err
45	}
46
47	name := tools.RandomString("ACPTTEST", 8)
48	t.Logf("Attempting to create instance: %s", name)
49
50	createOpts := instances.CreateOpts{
51		FlavorRef: choices.FlavorID,
52		Size:      1,
53		Name:      name,
54		Datastore: &instances.DatastoreOpts{
55			Type:    choices.DBDatastoreType,
56			Version: choices.DBDatastoreVersion,
57		},
58	}
59
60	instance, err := instances.Create(client, createOpts).Extract()
61	if err != nil {
62		return instance, err
63	}
64
65	if err := WaitForInstanceStatus(client, instance, "ACTIVE"); err != nil {
66		return instance, err
67	}
68
69	return instances.Get(client, instance.ID).Extract()
70}
71
72// CreateUser will create a user with a randomly generated name.
73// An error will be returned if the user was unable to be created.
74func CreateUser(t *testing.T, client *gophercloud.ServiceClient, instanceID string) error {
75	name := tools.RandomString("ACPTTEST", 8)
76	password := tools.RandomString("", 8)
77	t.Logf("Attempting to create user: %s", name)
78
79	createOpts := users.BatchCreateOpts{
80		users.CreateOpts{
81			Name:     name,
82			Password: password,
83		},
84	}
85
86	return users.Create(client, instanceID, createOpts).ExtractErr()
87}
88
89// DeleteDatabase deletes a database. A fatal error will occur if the database
90// failed to delete. This works best when used as a deferred function.
91func DeleteDatabase(t *testing.T, client *gophercloud.ServiceClient, instanceID, name string) {
92	t.Logf("Attempting to delete database: %s", name)
93	err := databases.Delete(client, instanceID, name).ExtractErr()
94	if err != nil {
95		t.Fatalf("Unable to delete database %s: %s", name, err)
96	}
97
98	t.Logf("Deleted database: %s", name)
99}
100
101// DeleteInstance deletes an instance. A fatal error will occur if the instance
102// failed to delete. This works best when used as a deferred function.
103func DeleteInstance(t *testing.T, client *gophercloud.ServiceClient, id string) {
104	t.Logf("Attempting to delete instance: %s", id)
105	err := instances.Delete(client, id).ExtractErr()
106	if err != nil {
107		t.Fatalf("Unable to delete instance %s: %s", id, err)
108	}
109
110	t.Logf("Deleted instance: %s", id)
111}
112
113// DeleteUser deletes a user. A fatal error will occur if the user
114// failed to delete. This works best when used as a deferred function.
115func DeleteUser(t *testing.T, client *gophercloud.ServiceClient, instanceID, name string) {
116	t.Logf("Attempting to delete user: %s", name)
117	err := users.Delete(client, instanceID, name).ExtractErr()
118	if err != nil {
119		t.Fatalf("Unable to delete users %s: %s", name, err)
120	}
121
122	t.Logf("Deleted users: %s", name)
123}
124
125// WaitForInstanceState will poll an instance's status until it either matches
126// the specified status or the status becomes ERROR.
127func WaitForInstanceStatus(
128	client *gophercloud.ServiceClient, instance *instances.Instance, status string) error {
129	return tools.WaitFor(func() (bool, error) {
130		latest, err := instances.Get(client, instance.ID).Extract()
131		if err != nil {
132			return false, err
133		}
134
135		if latest.Status == status {
136			return true, nil
137		}
138
139		if latest.Status == "ERROR" {
140			return false, fmt.Errorf("Instance in ERROR state")
141		}
142
143		return false, nil
144	})
145}
146