Skip to content
This repository was archived by the owner on Aug 1, 2023. It is now read-only.

Commit 16d90e4

Browse files
James FisherSamuel Ortiz
authored andcommitted
fix test
1 parent 920bd13 commit 16d90e4

File tree

5 files changed

+143
-34
lines changed

5 files changed

+143
-34
lines changed

openstack/imageservice/v2/fixtures.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313

1414
func HandleImageCreationSuccessfully(t *testing.T) {
1515
th.Mux.HandleFunc("/images", func(w http.ResponseWriter, r *http.Request) {
16-
// TODO
1716
th.TestMethod(t, r, "POST")
1817
th.TestHeader(t, r, "X-Auth-Token", fakeclient.TokenID)
1918
th.TestJSONRequest(t, r, `{

openstack/imageservice/v2/requests.go

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -21,77 +21,89 @@ func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateRes
2121
res.Err = err
2222
return res
2323
}
24-
response, err := client.Post(createURL(client), body, &res.Body, nil)
24+
_, err = client.Post(createURL(client), body, &res.Body, &gophercloud.RequestOpts{OkCodes: []int{200}})
2525
// TODO check response..?
2626
return res
2727
}
2828

2929
// CreateOptsBuilder describes struct types that can be accepted by the Create call.
3030
// The CreateOpts struct in this package does.
3131
type CreateOptsBuilder interface {
32-
// Returns value that implements json.Marshaler
32+
// Returns value that can be passed to json.Marshal
3333
ToImageCreateMap() (map[string]interface{}, error)
3434
}
3535

3636
// implements CreateOptsBuilder
3737
type CreateOpts struct {
3838
// Name [required] is the name of the new image.
39-
Name string
39+
Name *string
4040

4141
// Id [optional] is the the image ID.
42-
Id string
42+
Id *string
4343

4444
// Visibility [optional] defines who can see/use the image.
45-
Visibility ImageVisibility
45+
Visibility *ImageVisibility
4646

4747
// Tags [optional] is a set of image tags.
4848
Tags []string
4949

5050
// ContainerFormat [optional] is the format of the
5151
// container. Valid values are ami, ari, aki, bare, and ovf.
52-
ContainerFormat string
52+
ContainerFormat *string
5353

5454
// DiskFormat [optional] is the format of the disk. If set,
5555
// valid values are ami, ari, aki, vhd, vmdk, raw, qcow2, vdi,
5656
// and iso.
57-
DiskFormat string
57+
DiskFormat *string
5858

5959
// MinDiskGigabytes [optional] is the amount of disk space in
6060
// GB that is required to boot the image.
61-
MinDiskGigabytes int
61+
MinDiskGigabytes *int
6262

6363
// MinRamMegabytes [optional] is the amount of RAM in MB that
6464
// is required to boot the image.
65-
MinRamMegabytes int
65+
MinRamMegabytes *int
6666

6767
// protected [optional] is whether the image is not deletable.
68-
Protected bool
68+
Protected *bool
6969

7070
// properties [optional] is a set of properties, if any, that
7171
// are associated with the image.
7272
Properties map[string]string
7373
}
7474

75-
func setIfNotNil(m map[string]interface{}, k string, v interface{}) {
76-
if v != nil {
77-
m[k] = v
78-
}
79-
}
80-
8175
// ToImageCreateMap assembles a request body based on the contents of
8276
// a CreateOpts.
8377
func (opts CreateOpts) ToImageCreateMap() (map[string]interface{}, error) {
8478
body := map[string]interface{}{}
8579
body["name"] = opts.Name
86-
setIfNotNil(body, "id", opts.Id)
87-
setIfNotNil(body, "visibility", opts.Visibility)
88-
setIfNotNil(body, "tags", opts.Tags)
89-
setIfNotNil(body, "container_format", opts.ContainerFormat)
90-
setIfNotNil(body, "disk_format", opts.DiskFormat)
91-
setIfNotNil(body, "min_disk", opts.MinDiskGigabytes)
92-
setIfNotNil(body, "min_ram", opts.MinRamMegabytes)
93-
setIfNotNil(body, "protected", opts.Protected)
94-
setIfNotNil(body, "properties", opts.Properties)
80+
if opts.Id != nil {
81+
body["id"] = opts.Id
82+
}
83+
if opts.Visibility != nil {
84+
body["visibility"] = opts.Visibility
85+
}
86+
if opts.Tags != nil {
87+
body["tags"] = opts.Tags
88+
}
89+
if opts.ContainerFormat != nil {
90+
body["container_format"] = opts.ContainerFormat
91+
}
92+
if opts.DiskFormat != nil {
93+
body["disk_format"] = opts.DiskFormat
94+
}
95+
if opts.MinDiskGigabytes != nil {
96+
body["min_disk"] = opts.MinDiskGigabytes
97+
}
98+
if opts.MinRamMegabytes != nil {
99+
body["min_ram"] = opts.MinRamMegabytes
100+
}
101+
if opts.Protected != nil {
102+
body["protected"] = opts.Protected
103+
}
104+
if opts.Properties != nil {
105+
body["properties"] = opts.Properties
106+
}
95107
return body, nil
96108
}
97109

openstack/imageservice/v2/requests_test.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,21 @@ func TestCreateImage(t *testing.T) {
1616

1717
HandleImageCreationSuccessfully(t)
1818

19+
id := "e7db3b45-8db7-47ad-8109-3fb55c2c24fd"
20+
name := "Ubuntu 12.10"
21+
1922
actualImage, err := Create(fakeclient.ServiceClient(), CreateOpts{
20-
Name: "Ubuntu 12.10",
21-
Id: "e7db3b45-8db7-47ad-8109-3fb55c2c24fd",
23+
Id: &id,
24+
Name: &name,
2225
Tags: []string{"ubuntu", "quantal"},
2326
}).Extract()
2427

2528
th.AssertNoErr(t, err)
2629

2730
expectedImage := Image{
28-
Name: "Ubuntu 12.10",
2931
Id: "e7db3b45-8db7-47ad-8109-3fb55c2c24fd",
32+
Name: "Ubuntu 12.10",
33+
Status: ImageStatusQueued,
3034
Tags: []string{"ubuntu", "quantal"},
3135
}
3236

openstack/imageservice/v2/results.go

Lines changed: 98 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package v2
22

33
import (
4+
"errors"
5+
"fmt"
6+
47
"github.com/rackspace/gophercloud"
58
//"github.com/rackspace/gophercloud/pagination"
69

@@ -10,13 +13,13 @@ import (
1013
// does not include the literal image data; just metadata.
1114
// returned by listing images, and by fetching a specific image.
1215
type Image struct {
13-
Id string `mapstructure:"id"`
16+
Id string
1417

15-
Name string `mapstructure:"name"`
18+
Name string
1619

17-
Status ImageStatus `mapstructure:"status"`
20+
Status ImageStatus
1821

19-
Tags []string `mapstructure:"tags"`
22+
Tags []string
2023

2124
ContainerFormat string `mapstructure:"container_format"`
2225
DiskFormat string `mapstructure:"disk_format"`
@@ -46,12 +49,102 @@ type CreateResult struct {
4649
gophercloud.ErrResult
4750
}
4851

49-
// The response to `POST /images` follows the same schema as `GET /images/:id`.
52+
func asString(any interface{}) (string, error) {
53+
if str, ok := any.(string); ok {
54+
return str, nil
55+
} else {
56+
return "", errors.New(fmt.Sprintf("expected string value, but found: %#v", any))
57+
}
58+
}
59+
60+
func extractStringAtKey(m map[string]interface{}, k string) (string, error) {
61+
if any, ok := m[k]; ok {
62+
return asString(any)
63+
} else {
64+
return "", errors.New(fmt.Sprintf("expected key \"%s\" in map, but this key is not present", k))
65+
}
66+
}
67+
68+
func extractStringSliceAtKey(m map[string]interface{}, k string) ([]string, error) {
69+
if any, ok := m[k]; ok {
70+
if slice, ok := any.([]interface{}); ok {
71+
res := make([]string, len(slice))
72+
for k, v := range slice {
73+
var err error
74+
if res[k], err = asString(v); err != nil {
75+
return nil, err
76+
}
77+
}
78+
return res, nil
79+
} else {
80+
return nil, errors.New(fmt.Sprintf("expected slice as \"%s\" value, but found: %#v", k, any))
81+
}
82+
} else {
83+
return nil, errors.New(fmt.Sprintf("expected key \"%s\" in map, but this key is not present", k))
84+
}
85+
}
86+
87+
func stringToImageStatus(s string) (ImageStatus, error) {
88+
if s == "queued" {
89+
return ImageStatusQueued, nil
90+
} else if s == "active" {
91+
return ImageStatusActive, nil
92+
} else {
93+
return "", errors.New(fmt.Sprintf("expected \"active\" as image status, but found: \"%s\"", s))
94+
}
95+
}
96+
97+
func extractImageStatusAtKey(m map[string]interface{}, k string) (ImageStatus, error) {
98+
if any, ok := m[k]; ok {
99+
if str, ok := any.(string); ok {
100+
return stringToImageStatus(str)
101+
} else {
102+
return "", errors.New(fmt.Sprintf("expected string as \"%s\" value, but found: %#v", k, any))
103+
}
104+
} else {
105+
return "", errors.New(fmt.Sprintf("expected key \"%s\" in map, but this key is not present", k))
106+
}
107+
}
108+
50109
func extractImage(res gophercloud.ErrResult) (*Image, error) {
51110
if res.Err != nil {
52111
return nil, res.Err
53112
}
54113

114+
body, ok := res.Body.(map[string]interface{})
115+
if !ok {
116+
return nil, errors.New(fmt.Sprintf("expected map as result body, but found: %#v", res.Body))
117+
}
118+
119+
var image Image
120+
121+
var err error
122+
123+
if image.Id, err = extractStringAtKey(body, "id"); err != nil {
124+
return nil, err
125+
}
126+
127+
if image.Name, err = extractStringAtKey(body, "name"); err != nil {
128+
return nil, err
129+
}
130+
131+
if image.Status, err = extractImageStatusAtKey(body, "status"); err != nil {
132+
return nil, err
133+
}
134+
135+
if image.Tags, err = extractStringSliceAtKey(body, "tags"); err != nil {
136+
return nil, err
137+
}
138+
139+
return &image, nil
140+
}
141+
142+
// The response to `POST /images` follows the same schema as `GET /images/:id`.
143+
func extractImageOld(res gophercloud.ErrResult) (*Image, error) {
144+
if res.Err != nil {
145+
return nil, res.Err
146+
}
147+
55148
var image Image
56149

57150
err := mapstructure.Decode(res.Body, &image)

openstack/imageservice/v2/types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package v2
22

33
type ImageStatus string
44
const (
5+
ImageStatusQueued ImageStatus = "queued"
56
ImageStatusActive ImageStatus = "active"
67
// TODO
78
)

0 commit comments

Comments
 (0)