blob: 2b97b90e014a22024e2c6635200071e0535db778 [file] [log] [blame]
Brian Waldonbbb1cfb2011-10-27 18:04:37 -04001import httplib2
Soren Hansenbc1d3a02011-09-08 13:33:17 +02002import json
3import os
Aaron Lee35b8c922011-10-18 17:07:19 -05004import re
Soren Hansenbc1d3a02011-09-08 13:33:17 +02005
Soren Hansenbc1d3a02011-09-08 13:33:17 +02006from kong import openstack
Soren Hansen6adacc82011-09-09 13:34:35 +02007from kong import tests
Soren Hansenbc1d3a02011-09-08 13:33:17 +02008
9
Brian Waldonbbb1cfb2011-10-27 18:04:37 -040010class TestImagesThroughCompute(tests.FunctionalTest):
Soren Hansenbc1d3a02011-09-08 13:33:17 +020011
12 def setUp(self):
Brian Waldonbbb1cfb2011-10-27 18:04:37 -040013 super(TestImagesThroughCompute, self).setUp()
Soren Hansend6b047a2011-09-09 13:39:32 +020014 self.os = openstack.Manager(self.nova)
Soren Hansenbc1d3a02011-09-08 13:33:17 +020015
Soren Hansenbc1d3a02011-09-08 13:33:17 +020016 def _assert_image_links(self, image):
17 image_id = str(image['id'])
18
Soren Hansen5f4ad832011-09-09 14:08:19 +020019 mgmt_url = self.os.nova.management_url
20 bmk_url = re.sub(r'v1.1\/', r'', mgmt_url)
Aaron Lee35b8c922011-10-18 17:07:19 -050021 self_link = {'rel': 'self',
22 'href': os.path.join(mgmt_url, 'images', image_id)}
23 bookmark_link = {'rel': 'bookmark',
24 'href': os.path.join(bmk_url, 'images', image_id)}
Soren Hansen5f4ad832011-09-09 14:08:19 +020025
Aaron Lee35b8c922011-10-18 17:07:19 -050026 self.assertIn(bookmark_link, image['links'])
27 self.assertIn(self_link, image['links'])
Soren Hansenbc1d3a02011-09-08 13:33:17 +020028
29 def _assert_image_entity_basic(self, image):
30 actual_keys = set(image.keys())
31 expected_keys = set((
32 'id',
33 'name',
34 'links',
35 ))
36 self.assertEqual(actual_keys, expected_keys)
37
38 self._assert_image_links(image)
39
40 def _assert_image_entity_detailed(self, image):
41 keys = image.keys()
42 if 'server' in keys:
43 keys.remove('server')
44 actual_keys = set(keys)
45 expected_keys = set((
Aaron Lee35b8c922011-10-18 17:07:19 -050046 'created',
Soren Hansenbc1d3a02011-09-08 13:33:17 +020047 'id',
Aaron Lee35b8c922011-10-18 17:07:19 -050048 'links',
49 'metadata',
50 'minDisk',
51 'minRam',
Soren Hansenbc1d3a02011-09-08 13:33:17 +020052 'name',
53 'progress',
Soren Hansenbc1d3a02011-09-08 13:33:17 +020054 'status',
Aaron Lee35b8c922011-10-18 17:07:19 -050055 'updated',
Soren Hansenbc1d3a02011-09-08 13:33:17 +020056 ))
57 self.assertEqual(actual_keys, expected_keys)
58
59 self._assert_image_links(image)
60
61 def test_index(self):
62 """List all images"""
63
64 response, body = self.os.nova.request('GET', '/images')
65
66 self.assertEqual(response['status'], '200')
67 resp_body = json.loads(body)
68 self.assertEqual(resp_body.keys(), ['images'])
69
70 for image in resp_body['images']:
71 self._assert_image_entity_basic(image)
Soren Hansenfce58c52011-09-09 16:07:13 +020072 test_index.tags = ['nova', 'glance']
Soren Hansenbc1d3a02011-09-08 13:33:17 +020073
74 def test_detail(self):
75 """List all images in detail"""
76
77 response, body = self.os.nova.request('GET', '/images/detail')
Soren Hansenbc1d3a02011-09-08 13:33:17 +020078 self.assertEqual(response['status'], '200')
79 resp_body = json.loads(body)
80 self.assertEqual(resp_body.keys(), ['images'])
81
82 for image in resp_body['images']:
83 self._assert_image_entity_detailed(image)
Soren Hansenfce58c52011-09-09 16:07:13 +020084 test_detail.tags = ['nova', 'glance']
Brian Waldonbbb1cfb2011-10-27 18:04:37 -040085
86
87class TestGlanceAPI(tests.FunctionalTest):
88
89 def setUp(self):
90 super(TestGlanceAPI, self).setUp()
91 self.base_url = "http://%s:%s/%s/images" % (self.glance['host'],
Dolph Mathewsc3bc0962011-11-13 21:05:19 -060092 self.glance['port'],
Brian Waldonbbb1cfb2011-10-27 18:04:37 -040093 self.glance['apiver'])
94
95 def test_upload_ami_style_image(self):
96 """Uploads a three-part ami-style image"""
97 aki_location = self.config['environment']['aki_location']
98 headers = {'x-image-meta-is-public': 'true',
99 'x-image-meta-name': 'test-kernel',
100 'x-image-meta-disk-format': 'aki',
101 'x-image-meta-container-format': 'aki',
102 'Content-Length': '%d' % os.path.getsize(aki_location),
103 'Content-Type': 'application/octet-stream'}
104 image_file = open(aki_location, "rb")
105 http = httplib2.Http()
106 response, content = http.request(self.base_url, 'POST',
107 headers=headers,body=image_file)
108 image_file.close()
109 self.assertEqual(201, response.status)
110 data = json.loads(content)
111 self.assertEqual(data['image']['name'], "test-kernel")
112 self.assertEqual(data['image']['checksum'],
113 self._md5sum_file(aki_location))
114 kernel_id = data['image']['id']
115
116 ari_location = self.config['environment'].get('ari_location')
117 if ari_location:
118 headers = {'x-image-meta-is-public': 'true',
119 'x-image-meta-name': 'test-ramdisk',
120 'x-image-meta-disk-format': 'ari',
121 'x-image-meta-container-format': 'ari',
122 'Content-Length': '%d' % os.path.getsize(ari_location),
123 'Content-Type': 'application/octet-stream'}
124 image_file = open(ari_location, "rb")
125 http = httplib2.Http()
126 response, content = http.request(self.base_url, 'POST',
127 headers=headers, body=image_file)
128 image_file.close()
129 self.assertEqual(201, response.status)
130 data = json.loads(content)
131 self.assertEqual(data['image']['name'], "test-ramdisk")
132 self.assertEqual(data['image']['checksum'],
133 self._md5sum_file(ari_location))
134 ramdisk_id = data['image']['id']
135 else:
136 ramdisk_id = None
137
138 ami_location = self.config['environment']['ami_location']
139 upload_data = ""
140 for chunk in self._read_in_chunks(ami_location):
141 upload_data += chunk
142 headers = {'x-image-meta-is-public': 'true',
143 'x-image-meta-name': 'test-image',
144 'x-image-meta-disk-format': 'ami',
145 'x-image-meta-container-format': 'ami',
Dean Troyerb61ce962011-11-11 00:01:17 +0000146 'x-image-meta-property-kernel_id': str(kernel_id),
Brian Waldonbbb1cfb2011-10-27 18:04:37 -0400147 'Content-Length': '%d' % os.path.getsize(ami_location),
148 'Content-Type': 'application/octet-stream'}
149
150 if ari_location:
Dean Troyerb61ce962011-11-11 00:01:17 +0000151 headers['x-image-meta-property-ramdisk_id'] = str(ramdisk_id)
Brian Waldonbbb1cfb2011-10-27 18:04:37 -0400152
153 http = httplib2.Http()
154 response, content = http.request(self.base_url, 'POST',
155 headers=headers, body=upload_data)
156 self.assertEqual(201, response.status)
157 data = json.loads(content)
158 self.assertEqual(data['image']['name'], "test-image")
Brian Waldon34ffa7e2011-11-01 14:35:05 -0400159 self.assertEqual(data['image']['checksum'],
Brian Waldonbbb1cfb2011-10-27 18:04:37 -0400160 self._md5sum_file(ami_location))
161 machine_id = data['image']['id']
162
163 # now ensure we can modify the image properties
164 headers = {'X-Image-Meta-Property-distro': 'Ubuntu',
165 'X-Image-Meta-Property-arch': 'x86_64',
Dean Troyerb61ce962011-11-11 00:01:17 +0000166 'X-Image-Meta-Property-kernel_id': str(kernel_id)}
Brian Waldonbbb1cfb2011-10-27 18:04:37 -0400167 if ari_location:
Dean Troyerb61ce962011-11-11 00:01:17 +0000168 headers['X-Image-Meta-Property-ramdisk_id'] = str(ramdisk_id)
Brian Waldonbbb1cfb2011-10-27 18:04:37 -0400169
170 http = httplib2.Http()
171 url = '%s/%s' % (self.base_url, machine_id)
172 response, content = http.request(url, 'PUT', headers=headers)
173 self.assertEqual(response.status, 200)
174 data = json.loads(content)
175 properties = data['image']['properties']
176 self.assertEqual(properties['arch'], "x86_64")
177 self.assertEqual(properties['distro'], "Ubuntu")
Dean Troyerb61ce962011-11-11 00:01:17 +0000178 self.assertEqual(properties['kernel_id'], str(kernel_id))
Brian Waldonbbb1cfb2011-10-27 18:04:37 -0400179 if ari_location:
Dean Troyerb61ce962011-11-11 00:01:17 +0000180 self.assertEqual(properties['ramdisk_id'], str(ramdisk_id))
Brian Waldonbbb1cfb2011-10-27 18:04:37 -0400181
182 # list the metadata to ensure the new values stuck
183 http = httplib2.Http()
184 response, content = http.request(url, 'HEAD')
185 self.assertEqual(response.status, 200)
186 self.assertEqual(response['x-image-meta-name'], "test-image")
187 self.assertEqual(response['x-image-meta-checksum'],
188 self._md5sum_file(ami_location))
189 self.assertEqual(response['x-image-meta-container_format'], "ami")
190 self.assertEqual(response['x-image-meta-disk_format'], "ami")
191 self.assertEqual(response['x-image-meta-property-arch'], "x86_64")
192 self.assertEqual(response['x-image-meta-property-distro'], "Ubuntu")
193 self.assertEqual(response['x-image-meta-property-kernel_id'],
Dean Troyerb61ce962011-11-11 00:01:17 +0000194 str(kernel_id))
Brian Waldonbbb1cfb2011-10-27 18:04:37 -0400195 if ari_location:
196 self.assertEqual(response['x-image-meta-property-ramdisk_id'],
Dean Troyerb61ce962011-11-11 00:01:17 +0000197 str(ramdisk_id))
Brian Waldonbbb1cfb2011-10-27 18:04:37 -0400198
199 # delete images for which we have non-None ids
200 delete_ids = filter(lambda x: x, (kernel_id, ramdisk_id, machine_id))
201 for image_id in delete_ids:
202 http = httplib2.Http()
203 url = '%s/%s' % (self.base_url, image_id)
204 response, content = http.request(url, 'DELETE')
205
206 test_upload_ami_style_image.tags = ['glance']