blob: 5b35b8fdf079f344c92412b11f1d87e28952ad90 [file] [log] [blame]
Samuel A. Falvo IIf370dc72014-02-13 15:05:34 -08001package openstack
2
3import (
4 "testing"
5 "fmt"
6 "github.com/rackspace/gophercloud/openstack/compute/servers"
7 "github.com/rackspace/gophercloud/openstack/compute/images"
Samuel A. Falvo II10decf92014-02-13 17:05:35 -08008 "github.com/rackspace/gophercloud/openstack/compute/flavors"
Samuel A. Falvo IIf370dc72014-02-13 15:05:34 -08009 "github.com/rackspace/gophercloud/openstack/identity"
10 "github.com/rackspace/gophercloud/openstack/utils"
11 "os"
12 "text/tabwriter"
Samuel A. Falvo IIce000732014-02-13 18:53:53 -080013 "time"
14 "crypto/rand"
Samuel A. Falvo IIf370dc72014-02-13 15:05:34 -080015)
16
Samuel A. Falvo IIdb020882014-02-13 15:37:57 -080017type testState struct {
18 o identity.AuthOptions
19 a identity.AuthResults
20 sc *identity.ServiceCatalog
21 eps []identity.Endpoint
22 w *tabwriter.Writer
23}
24
Samuel A. Falvo IIce000732014-02-13 18:53:53 -080025func setupForList() (*testState, error) {
Samuel A. Falvo IIdb020882014-02-13 15:37:57 -080026 var err error
27
28 ts := new(testState)
29
30 ts.o, err = utils.AuthOptions()
31 if err != nil {
32 return ts, err
33 }
34
35 ts.a, err = identity.Authenticate(ts.o)
36 if err != nil {
37 return ts, err
38 }
39
40 ts.sc, err = identity.GetServiceCatalog(ts.a)
41 if err != nil {
42 return ts, err
43 }
44
45 ts.eps, err = findAllComputeEndpoints(ts.sc)
46 if err != nil {
47 return ts, err
48 }
49
50 ts.w = new(tabwriter.Writer)
51 ts.w.Init(os.Stdout, 2, 8, 2, ' ', 0)
52
53 return ts, nil
54}
55
Samuel A. Falvo IIf370dc72014-02-13 15:05:34 -080056func TestListServers(t *testing.T) {
Samuel A. Falvo IIce000732014-02-13 18:53:53 -080057 ts, err := setupForList()
Samuel A. Falvo IIf370dc72014-02-13 15:05:34 -080058 if err != nil {
59 t.Error(err)
60 return
61 }
62
Samuel A. Falvo IIce000732014-02-13 18:53:53 -080063 fmt.Fprintln(ts.w, "ID\tRegion\tName\tStatus\tIPv4\tIPv6\t")
Samuel A. Falvo IIf370dc72014-02-13 15:05:34 -080064
65 region := os.Getenv("OS_REGION_NAME")
66 n := 0
Samuel A. Falvo IIdb020882014-02-13 15:37:57 -080067 for _, ep := range ts.eps {
Samuel A. Falvo IIf370dc72014-02-13 15:05:34 -080068 if (region != "") && (region != ep.Region) {
69 continue
70 }
71
Samuel A. Falvo IIdb020882014-02-13 15:37:57 -080072 client := servers.NewClient(ep.PublicURL, ts.a, ts.o)
Samuel A. Falvo IIf370dc72014-02-13 15:05:34 -080073
74 listResults, err := servers.List(client)
75 if err != nil {
76 t.Error(err)
77 return
78 }
79
80 svrs, err := servers.GetServers(listResults)
81 if err != nil {
82 t.Error(err)
83 return
84 }
85
86 n = n + len(svrs)
87
88 for _, s := range svrs {
Samuel A. Falvo IIce000732014-02-13 18:53:53 -080089 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)
Samuel A. Falvo IIf370dc72014-02-13 15:05:34 -080090 }
91 }
Samuel A. Falvo IIdb020882014-02-13 15:37:57 -080092 ts.w.Flush()
Samuel A. Falvo IIf370dc72014-02-13 15:05:34 -080093 fmt.Printf("--------\n%d servers listed.\n", n)
94}
95
Samuel A. Falvo IIf370dc72014-02-13 15:05:34 -080096func TestListImages(t *testing.T) {
Samuel A. Falvo IIce000732014-02-13 18:53:53 -080097 ts, err := setupForList()
Samuel A. Falvo IIf370dc72014-02-13 15:05:34 -080098 if err != nil {
99 t.Error(err)
100 return
101 }
102
Samuel A. Falvo IIdb020882014-02-13 15:37:57 -0800103 fmt.Fprintln(ts.w, "ID\tRegion\tName\tStatus\tCreated\t")
Samuel A. Falvo IIf370dc72014-02-13 15:05:34 -0800104
105 region := os.Getenv("OS_REGION_NAME")
106 n := 0
Samuel A. Falvo IIdb020882014-02-13 15:37:57 -0800107 for _, ep := range ts.eps {
Samuel A. Falvo IIf370dc72014-02-13 15:05:34 -0800108 if (region != "") && (region != ep.Region) {
109 continue
110 }
111
Samuel A. Falvo IIdb020882014-02-13 15:37:57 -0800112 client := images.NewClient(ep.PublicURL, ts.a, ts.o)
Samuel A. Falvo IIf370dc72014-02-13 15:05:34 -0800113
114 listResults, err := images.List(client)
115 if err != nil {
116 t.Error(err)
117 return
118 }
119
120 imgs, err := images.GetImages(listResults)
121 if err != nil {
122 t.Error(err)
123 return
124 }
125
126 n = n + len(imgs)
127
128 for _, i := range imgs {
Samuel A. Falvo IIdb020882014-02-13 15:37:57 -0800129 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)
Samuel A. Falvo IIf370dc72014-02-13 15:05:34 -0800130 }
131 }
Samuel A. Falvo IIdb020882014-02-13 15:37:57 -0800132 ts.w.Flush()
Samuel A. Falvo IIf370dc72014-02-13 15:05:34 -0800133 fmt.Printf("--------\n%d images listed.\n", n)
134}
135
Samuel A. Falvo IIdb020882014-02-13 15:37:57 -0800136func TestListFlavors(t *testing.T) {
Samuel A. Falvo IIce000732014-02-13 18:53:53 -0800137 ts, err := setupForList()
Samuel A. Falvo IIdb020882014-02-13 15:37:57 -0800138 if err != nil {
139 t.Error(err)
140 return
141 }
142
Samuel A. Falvo II10decf92014-02-13 17:05:35 -0800143 fmt.Fprintln(ts.w, "ID\tRegion\tName\tRAM\tDisk\tVCPUs\t")
Samuel A. Falvo IIdb020882014-02-13 15:37:57 -0800144
145 region := os.Getenv("OS_REGION_NAME")
146 n := 0
147 for _, ep := range ts.eps {
148 if (region != "") && (region != ep.Region) {
149 continue
150 }
151
152 client := flavors.NewClient(ep.PublicURL, ts.a, ts.o)
153
154 listResults, err := flavors.List(client)
155 if err != nil {
156 t.Error(err)
157 return
158 }
159
160 flavs, err := flavors.GetFlavors(listResults)
161 if err != nil {
162 t.Error(err)
163 return
164 }
165
166 n = n + len(flavs)
167
168 for _, f := range flavs {
Samuel A. Falvo II10decf92014-02-13 17:05:35 -0800169 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)
Samuel A. Falvo IIdb020882014-02-13 15:37:57 -0800170 }
171 }
172 ts.w.Flush()
173 fmt.Printf("--------\n%d images listed.\n", n)
174}
175
176func findAllComputeEndpoints(sc *identity.ServiceCatalog) ([]identity.Endpoint, error) {
177 ces, err := sc.CatalogEntries()
178 if err != nil {
179 return nil, err
180 }
181
182 for _, ce := range ces {
183 if ce.Type == "compute" {
184 return ce.Endpoints, nil
185 }
186 }
187
188 return nil, fmt.Errorf("Compute endpoint not found.")
189}
190
Samuel A. Falvo IIce000732014-02-13 18:53:53 -0800191func findEndpointForRegion(eps []identity.Endpoint, r string) (string, error) {
192 for _, ep := range eps {
193 if ep.Region == r {
194 return ep.PublicURL, nil
195 }
196 }
197 return "", fmt.Errorf("Unknown region %s", r)
198}
199
200func TestCreateDestroyServer(t *testing.T) {
201 ts, err := setupForList()
202 if err != nil {
203 t.Error(err)
204 return
205 }
206
207 imageId := os.Getenv("OS_IMAGE_ID")
208 if imageId == "" {
209 t.Error("Expected OS_IMAGE_ID environment variable to be set")
210 return
211 }
212
213 flavorId := os.Getenv("OS_FLAVOR_ID")
214 if flavorId == "" {
215 t.Error("Expected OS_FLAVOR_ID environment variable to be set")
216 return
217 }
218
219 region := os.Getenv("OS_REGION_NAME")
220 if region == "" {
221 region = ts.eps[0].Region
222 }
223
224 ep, err := findEndpointForRegion(ts.eps, region)
225 if err != nil {
226 t.Error(err)
227 return
228 }
229
230 serverName := randomString("ACPTTEST", 16)
231 fmt.Printf("Attempting to create server: %s\n", serverName)
232
233 client := servers.NewClient(ep, ts.a, ts.o)
234
235 cr, err := servers.Create(client, map[string]interface{}{
236 "flavorRef": flavorId,
237 "imageRef": imageId,
238 "name": serverName,
239 })
240 if err != nil {
241 t.Error(err)
242 return
243 }
244
245 createdServer, err := servers.GetServer(cr)
246 if err != nil {
247 t.Error(err)
248 return
249 }
250 defer func() {
251 servers.Delete(client, createdServer.Id)
252 }()
253
254 timeout := 300
255 for ; timeout > 0; timeout-- {
256 gr, err := servers.GetDetail(client, createdServer.Id)
257 if err != nil {
258 t.Error(err)
259 return
260 }
261
262 gottenServer, err := servers.GetServer(gr)
263 if err != nil {
264 t.Error(err)
265 return
266 }
267
268 if gottenServer.Id != createdServer.Id {
269 t.Error("Created server ID (%s) != gotten server ID (%s)", createdServer.Id, gottenServer.Id)
270 return
271 }
272
273 if gottenServer.Status == "ACTIVE" {
274 fmt.Printf("Server created after %d seconds (approximately)\n", 300-timeout)
275 break
276 }
277 time.Sleep(1*time.Second)
278 }
279 if timeout < 1 {
280 fmt.Printf("I'm not waiting around.\n")
281 }
282}
283
Samuel A. Falvo II22d3b772014-02-13 19:27:05 -0800284func TestUpdateServer(t *testing.T) {
285 ts, err := setupForList()
286 if err != nil {
287 t.Error(err)
288 return
289 }
290
291 imageId := os.Getenv("OS_IMAGE_ID")
292 if imageId == "" {
293 t.Error("Expected OS_IMAGE_ID environment variable to be set")
294 return
295 }
296
297 flavorId := os.Getenv("OS_FLAVOR_ID")
298 if flavorId == "" {
299 t.Error("Expected OS_FLAVOR_ID environment variable to be set")
300 return
301 }
302
303 region := os.Getenv("OS_REGION_NAME")
304 if region == "" {
305 region = ts.eps[0].Region
306 }
307
308 ep, err := findEndpointForRegion(ts.eps, region)
309 if err != nil {
310 t.Error(err)
311 return
312 }
313
314 serverName := randomString("ACPTTEST", 16)
315 fmt.Printf("Attempting to create server: %s\n", serverName)
316
317 client := servers.NewClient(ep, ts.a, ts.o)
318
319 cr, err := servers.Create(client, map[string]interface{}{
320 "flavorRef": flavorId,
321 "imageRef": imageId,
322 "name": serverName,
323 })
324 if err != nil {
325 t.Error(err)
326 return
327 }
328
329 createdServer, err := servers.GetServer(cr)
330 if err != nil {
331 t.Error(err)
332 return
333 }
334 defer func() {
335 servers.Delete(client, createdServer.Id)
336 }()
337
338 timeout := 300
339 for ; timeout > 0; timeout-- {
340 gr, err := servers.GetDetail(client, createdServer.Id)
341 if err != nil {
342 t.Error(err)
343 return
344 }
345
346 gottenServer, err := servers.GetServer(gr)
347 if err != nil {
348 t.Error(err)
349 return
350 }
351
352 if gottenServer.Id != createdServer.Id {
353 t.Error("Created server ID (%s) != gotten server ID (%s)", createdServer.Id, gottenServer.Id)
354 return
355 }
356
357 if gottenServer.Status == "ACTIVE" {
358 fmt.Printf("Server created after %d seconds (approximately)\n", 300-timeout)
359 break
360 }
361 time.Sleep(1*time.Second)
362 }
363 if timeout < 1 {
364 fmt.Printf("I'm not waiting around.\n")
365 }
366
367 alternateName := randomString("ACPTTEST", 16)
368 for alternateName == serverName {
369 alternateName = randomString("ACPTTEST", 16)
370 }
371
372 fmt.Println("Attempting to change server name")
373
374 ur, err := servers.Update(client, createdServer.Id, map[string]interface{}{
375 "name": alternateName,
376 })
377 if err != nil {
378 t.Error(err)
379 return
380 }
381
382 updatedServer, err := servers.GetServer(ur)
383 if err != nil {
384 t.Error(err)
385 return
386 }
387
388 if updatedServer.Id != createdServer.Id {
389 t.Error("Expected updated and created server to share the same ID")
390 return
391 }
392
393 timeout = 300
394 for ; timeout > 0; timeout-- {
395 gr, err := servers.GetDetail(client, createdServer.Id)
396 if err != nil {
397 t.Error(err)
398 return
399 }
400
401 gottenServer, err := servers.GetServer(gr)
402 if err != nil {
403 t.Error(err)
404 return
405 }
406
407 if gottenServer.Id != updatedServer.Id {
408 t.Error("Updated server ID (%s) != gotten server ID (%s)", updatedServer.Id, gottenServer.Id)
409 return
410 }
411
412 if gottenServer.Name == alternateName {
413 fmt.Printf("Server updated after %d seconds (approximately)\n", 300-timeout)
414 break
415 }
416 time.Sleep(1*time.Second)
417 }
418 if timeout < 1 {
419 fmt.Printf("I'm not waiting around.\n")
420 }
421}
422
Samuel A. Falvo IIce000732014-02-13 18:53:53 -0800423// randomString generates a string of given length, but random content.
424// All content will be within the ASCII graphic character set.
425// (Implementation from Even Shaw's contribution on
426// http://stackoverflow.com/questions/12771930/what-is-the-fastest-way-to-generate-a-long-random-string-in-go).
427func randomString(prefix string, n int) string {
428 const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
429 var bytes = make([]byte, n)
430 rand.Read(bytes)
431 for i, b := range bytes {
432 bytes[i] = alphanum[b%byte(len(alphanum))]
433 }
434 return prefix + string(bytes)
435}
436