blob: 90a153b8178ef95a065e5c0cbfd5893294fdce1c [file] [log] [blame]
Justin Shepherd0d9bbd12011-08-11 12:57:44 -05001# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
3# Copyright 2011 OpenStack, LLC
4# All Rights Reserved.
5#
6# Licensed under the Apache License, Version 2.0 (the "License"); you may
7# not use this file except in compliance with the License. You may obtain
8# a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15# License for the specific language governing permissions and limitations
16# under the License.
17
18"""Functional test case against the OpenStack Nova API server"""
19
20import json
21import os
Justin Shepherd0d9bbd12011-08-11 12:57:44 -050022import httplib2
Justin Shepherd0d9bbd12011-08-11 12:57:44 -050023import time
Justin Shepherd0d9bbd12011-08-11 12:57:44 -050024
25from pprint import pprint
26
Soren Hansenec3f7092011-09-08 13:03:42 +020027from kong import tests
Justin Shepherd0d9bbd12011-08-11 12:57:44 -050028
29
30class TestNovaAPI(tests.FunctionalTest):
31 def build_check(self, id):
32 self.result = {}
33 """
34 This is intended to check that a server completes the build process
35 and enters an active state upon creation. Due to reporting errors in
36 the API we are also testing ping and ssh
37 """
38 count = 0
39 path = "http://%s:%s/%s/servers/%s" % (self.nova['host'],
40 self.nova['port'],
41 self.nova['ver'],
42 id)
43 http = httplib2.Http()
44 headers = {'X-Auth-User': '%s' % (self.nova['user']),
45 'X-Auth-Token': '%s' % (self.nova['X-Auth-Token'])}
46 response, content = http.request(path, 'GET', headers=headers)
Justin Shepherd5778a252011-08-18 12:15:37 -050047 self.assertEqual(response.status, 200)
Justin Shepherd0d9bbd12011-08-11 12:57:44 -050048 data = json.loads(content)
49
50 # Get Server status exit when active
51 while (data['server']['status'] != 'ACTIVE'):
52 response, content = http.request(path, 'GET', headers=headers)
53 data = json.loads(content)
54 time.sleep(5)
55 count = count + 5
56 self.result['serverid'] = id
57 self.result['status'] = data['server']['status']
58
59 # Get IP Address of newly created server
Justin Shepherdf4457092011-08-17 09:33:20 -050060 addr_name = "private"
61 if 'vmnet' in data['server']['addresses']:
62 ref = data['server']['addresses']['vmnet']
63 if len(ref) > 0:
Soren Hansen826d5df2011-08-29 11:30:40 +020064 addr_name = 'vmnet'
Justin Shepherdf4457092011-08-17 09:33:20 -050065 if 'public' in data['server']['addresses']:
66 ref = data['server']['addresses']['public']
67 if len(ref) > 0:
Soren Hansen826d5df2011-08-29 11:30:40 +020068 addr_name = 'public'
Justin Shepherdf4457092011-08-17 09:33:20 -050069 ref = data['server']['addresses'][addr_name]
70 netaddr = ref[0]['addr']
Justin Shepherd0d9bbd12011-08-11 12:57:44 -050071
72 r = "" . join(os.popen('ping -c5 %s' % (netaddr)).readlines())
73 if r.find('64 bytes') > 1:
74 self.result['ping'] = True
75 else:
76 self.result['ping'] = False
77
78 return self.result
79
80 def test_002_verify_nova_auth(self):
81 if 'keystone' in self.config:
82 path = "http://%s:%s/%s" % (self.keystone['host'],
83 self.keystone['port'],
84 self.keystone['apiver'])
85 headers = {'X-Auth-User': self.keystone['user'],
86 'X-Auth-Key': self.keystone['pass']}
87 else:
88 path = "http://%s:%s/%s" % (self.nova['host'],
89 self.nova['port'],
90 self.nova['ver'])
91 headers = {'X-Auth-User': self.nova['user'],
92 'X-Auth-Key': self.nova['key']}
93
94 http = httplib2.Http()
95 response, content = http.request(path, 'HEAD', headers=headers)
Justin Shepherd5778a252011-08-18 12:15:37 -050096 self.assertEqual(response.status, 204)
Justin Shepherd0d9bbd12011-08-11 12:57:44 -050097 self.assertNotEqual(response['x-auth-token'], '')
98 self.assertNotEqual(response['x-server-management-url'], '')
99
100 # Set up Auth Token for all future API interactions
101 self.nova['X-Auth-Token'] = response['x-auth-token']
102 test_002_verify_nova_auth.tags = ['nova', 'nova-api']
103
104 def test_101_verify_version_selection_default(self):
105 path = "http://%s:%s/" % (self.nova['host'],
106 self.nova['port'])
107 http = httplib2.Http()
108 headers = {'X-Auth-Token': self.nova['X-Auth-Token']}
109 response, content = http.request(path, 'GET', headers=headers)
Justin Shepherd5778a252011-08-18 12:15:37 -0500110 self.assertEqual(response.status, 200)
Justin Shepherd0d9bbd12011-08-11 12:57:44 -0500111 data = json.loads(content)
112 self.assertEqual(len(data['versions']), 2)
113 test_101_verify_version_selection_default.tags = ['nova', 'nova-api']
114
115 def test_102_verify_version_selection_json(self):
116 path = "http://%s:%s/.json" % (self.nova['host'],
117 self.nova['port'])
118 http = httplib2.Http()
119 headers = {'X-Auth-Token': self.nova['X-Auth-Token']}
120 response, content = http.request(path, 'GET', headers=headers)
Justin Shepherd5778a252011-08-18 12:15:37 -0500121 self.assertEqual(response.status, 200)
Justin Shepherd0d9bbd12011-08-11 12:57:44 -0500122 data = json.loads(content)
123 self.assertEqual(len(data['versions']), 2)
124 test_102_verify_version_selection_json.tags = ['nova', 'nova-api']
125
126 def test_103_verify_version_selection_xml(self):
127 path = "http://%s:%s/.xml" % (self.nova['host'],
128 self.nova['port'])
129 http = httplib2.Http()
130 headers = {'X-Auth-Token': self.nova['X-Auth-Token']}
131 response, content = http.request(path, 'GET', headers=headers)
Justin Shepherd5778a252011-08-18 12:15:37 -0500132 self.assertEqual(response.status, 200)
Justin Shepherd0d9bbd12011-08-11 12:57:44 -0500133 self.assertTrue('<versions>' in content)
134 test_103_verify_version_selection_xml.tags = ['nova', 'nova-api']
135
136 def test_104_bad_user_bad_key(self):
137 if 'keystone' in self.config:
138 path = "http://%s:%s/%s" % (self.keystone['host'],
139 self.keystone['port'],
140 self.keystone['apiver'])
141 else:
142 path = "http://%s:%s/%s" % (self.nova['host'],
143 self.nova['port'],
144 self.nova['ver'])
145 http = httplib2.Http()
146 headers = {'X-Auth-User': 'unknown_auth_user',
147 'X-Auth-Key': 'unknown_auth_key'}
148 response, content = http.request(path, 'GET', headers=headers)
149 self.assertEqual(response.status, 401)
150 test_104_bad_user_bad_key.tags = ['nova', 'nova-api']
151
152 def test_105_bad_user_good_key(self):
153 if 'keystone' in self.config:
154 path = "http://%s:%s/%s" % (self.keystone['host'],
155 self.keystone['port'],
156 self.keystone['apiver'])
157 else:
158 path = "http://%s:%s/%s" % (self.nova['host'],
159 self.nova['port'],
160 self.nova['ver'])
161 http = httplib2.Http()
162 headers = {'X-Auth-User': 'unknown_auth_user',
163 'X-Auth-Key': self.nova['key']}
164 response, content = http.request(path, 'GET', headers=headers)
165 self.assertEqual(response.status, 401)
166 test_105_bad_user_good_key.tags = ['nova', 'nova-api']
167
168 def test_106_good_user_bad_key(self):
169 if 'keystone' in self.config:
170 path = "http://%s:%s/%s" % (self.keystone['host'],
171 self.keystone['port'],
172 self.keystone['apiver'])
173 else:
174 path = "http://%s:%s/%s" % (self.nova['host'],
175 self.nova['port'],
176 self.nova['ver'])
177 http = httplib2.Http()
178 headers = {'X-Auth-User': self.nova['user'],
179 'X-Auth-Key': 'unknown_auth_key'}
180 response, content = http.request(path, 'GET', headers=headers)
181 self.assertEqual(response.status, 401)
182 test_106_good_user_bad_key.tags = ['nova', 'nova-api']
183
184 def test_107_no_key(self):
185 if 'keystone' in self.config:
186 path = "http://%s:%s/%s" % (self.keystone['host'],
187 self.keystone['port'],
188 self.keystone['apiver'])
189 else:
190 path = "http://%s:%s/%s" % (self.nova['host'],
191 self.nova['port'],
192 self.nova['ver'])
193 http = httplib2.Http()
194 headers = {'X-Auth-User': self.nova['user']}
195 response, content = http.request(path, 'GET', headers=headers)
196 self.assertEqual(response.status, 401)
197 test_107_no_key.tags = ['nova', 'nova-api']
198
199 def test_108_bad_token(self):
200 if 'keystone' in self.config:
201 path = "http://%s:%s/%s" % (self.keystone['host'],
202 self.keystone['port'],
203 self.keystone['apiver'])
204 else:
205 path = "http://%s:%s/%s" % (self.nova['host'],
206 self.nova['port'],
207 self.nova['ver'])
208 http = httplib2.Http()
209 headers = {'X-Auth-Token': 'unknown_token'}
210 response, content = http.request(path, 'GET', headers=headers)
211 self.assertEqual(response.status, 401)
212 test_108_bad_token.tags = ['nova', 'nova-api']
213
214 def test_109_verify_blank_limits(self):
215 path = "http://%s:%s/%s/limits" % (self.nova['host'],
216 self.nova['port'],
217 self.nova['ver'])
218
219 http = httplib2.Http()
220 headers = {'X-Auth-User': '%s' % (self.nova['user']),
221 'X-Auth-Token': '%s' % (self.nova['X-Auth-Token'])}
222 response, content = http.request(path, 'GET', headers=headers)
Justin Shepherd5778a252011-08-18 12:15:37 -0500223 self.assertEqual(response.status, 200)
224 self.assertNotEqual(content, '{"limits": []}')
Justin Shepherd0d9bbd12011-08-11 12:57:44 -0500225 test_109_verify_blank_limits.tags = ['nova', 'nova-api']
226
227 def test_110_list_flavors_v1_1(self):
228 path = "http://%s:%s/%s/flavors" % (self.nova['host'],
229 self.nova['port'],
230 self.nova['ver'])
231 http = httplib2.Http()
232 headers = {'X-Auth-User': '%s' % (self.nova['user']),
233 'X-Auth-Token': '%s' % (self.nova['X-Auth-Token'])}
234 response, content = http.request(path, 'GET', headers=headers)
Justin Shepherd5778a252011-08-18 12:15:37 -0500235 self.assertEqual(response.status, 200)
236 self.assertNotEqual(content, '{"flavors": []}')
Justin Shepherd0d9bbd12011-08-11 12:57:44 -0500237 test_110_list_flavors_v1_1.tags = ['nova', 'nova-api']
238
239 def test_111_verify_kernel_active_v1_1(self):
240 # for testing purposes change self.glance['kernel_id'] to an active
241 # kernel image allow for skipping glance tests
242 if not 'kernel_id' in self.glance:
243 self.glance['kernel_id'] = "61"
244
245 path = "http://%s:%s/%s/images/%s" % (self.nova['host'],
246 self.nova['port'],
247 self.nova['ver'],
248 self.glance['kernel_id'])
249 http = httplib2.Http()
250 headers = {'X-Auth-User': '%s' % (self.nova['user']),
251 'X-Auth-Token': '%s' % (self.nova['X-Auth-Token'])}
252 response, content = http.request(path, 'GET', headers=headers)
Justin Shepherd5778a252011-08-18 12:15:37 -0500253 self.assertEqual(response.status, 200)
Justin Shepherd0d9bbd12011-08-11 12:57:44 -0500254 data = json.loads(content)
255 self.assertEqual(data['image']['status'], 'ACTIVE')
256 test_111_verify_kernel_active_v1_1.tags = ['nova']
257
258 def test_112_verify_ramdisk_active_v1_1(self):
259 # for testing purposes change self.glance['ramdisk_id'] to an active
260 # ramdisk image, allows you to skip glance tests
261 if not 'ramdisk_id' in self.glance:
262 self.glance['ramdisk_id'] = "62"
263
264 path = "http://%s:%s/%s/images/%s" % (self.nova['host'],
265 self.nova['port'],
266 self.nova['ver'],
267 self.glance['ramdisk_id'])
268 http = httplib2.Http()
269 headers = {'X-Auth-User': '%s' % (self.nova['user']),
270 'X-Auth-Token': '%s' % (self.nova['X-Auth-Token'])}
271 response, content = http.request(path, 'GET', headers=headers)
Justin Shepherd5778a252011-08-18 12:15:37 -0500272 self.assertEqual(response.status, 200)
Justin Shepherd0d9bbd12011-08-11 12:57:44 -0500273 data = json.loads(content)
274 self.assertEqual(data['image']['status'], 'ACTIVE')
275 test_112_verify_ramdisk_active_v1_1.tags = ['nova']
276
277 def test_113_verify_image_active_v1_1(self):
278 # for testing purposes change self.glance['image_id'] to an active
279 # image id allows for skipping glance tests
280 if not 'image_id' in self.glance:
281 self.glance['image_id'] = "63"
282
283 path = "http://%s:%s/%s/images/%s" % (self.nova['host'],
284 self.nova['port'],
285 self.nova['ver'],
286 self.glance['image_id'])
287 http = httplib2.Http()
288 headers = {'X-Auth-User': '%s' % (self.nova['user']),
289 'X-Auth-Token': '%s' % (self.nova['X-Auth-Token'])}
290 response, content = http.request(path, 'GET', headers=headers)
Justin Shepherd5778a252011-08-18 12:15:37 -0500291 self.assertEqual(response.status, 200)
Justin Shepherd0d9bbd12011-08-11 12:57:44 -0500292 data = json.loads(content)
293 self.assertEqual(data['image']['status'], 'ACTIVE')
294 test_113_verify_image_active_v1_1.tags = ['nova']
295
296 def test_200_create_server(self):
297 path = "http://%s:%s/%s/servers" % (self.nova['host'],
298 self.nova['port'],
299 self.nova['ver'])
300 http = httplib2.Http()
301 headers = {'X-Auth-User': '%s' % (self.nova['user']),
302 'X-Auth-Token': '%s' % (self.nova['X-Auth-Token']),
303 'Content-Type': 'application/json'}
304
305 # Change imageRef to self.glance['image_id']
306 json_str = {"server":
307 {
308 "name": "testing server creation",
309 "flavorRef": "http://%s:%s/%s/flavors/2" % (self.nova['host'],
310 self.nova['port'],
311 self.nova['ver']),
312 "imageRef": self.glance['image_id']
313# "imageRef": "http://%s:%s/%s/images/%s" % (self.nova['host'],
314# self.nova['port'],
315# self.nova['ver'],
316# self.glance['image_id'])
317 }
318 }
319 data = json.dumps(json_str)
320 response, content = http.request(path, 'POST', headers=headers,
321 body=data)
322 json_return = json.loads(content)
Justin Shepherd5778a252011-08-18 12:15:37 -0500323 self.assertEqual(response.status, 200)
Justin Shepherd0d9bbd12011-08-11 12:57:44 -0500324 self.assertEqual(json_return['server']['status'], "BUILD")
325 self.nova['single_server_id'] = json_return['server']['id']
326 time.sleep(5)
327 build_result = self.build_check(self.nova['single_server_id'])
328 self.assertEqual(build_result['status'], "ACTIVE")
329 self.assertEqual(build_result['ping'], True)
330 test_200_create_server.tags = ['nova']
331
332 def test_201_get_server_details(self):
333 path = "http://%s:%s/%s/servers/%s" % (self.nova['host'],
334 self.nova['port'],
335 self.nova['ver'],
336 self.nova['single_server_id'])
337
338 http = httplib2.Http()
339 headers = {'X-Auth-User': '%s' % (self.nova['user']),
340 'X-Auth-Token': '%s' % (self.nova['X-Auth-Token'])}
341
342 response, content = http.request(path, 'GET', headers=headers)
Justin Shepherd5778a252011-08-18 12:15:37 -0500343 self.assertEqual(response.status, 200)
Justin Shepherd0d9bbd12011-08-11 12:57:44 -0500344 test_201_get_server_details.tags = ['nova']
345
346 # MOVING TO 999 because it can kill the API
347 # Uncomment next line for testing
348 # def create_multi(self):
349 def test_999_create_multiple(self):
350 self.nova['multi_server'] = {}
351 path = "http://%s:%s/%s/servers" % (self.nova['host'],
352 self.nova['port'],
353 self.nova['ver'])
354 http = httplib2.Http()
355 headers = {'X-Auth-User': '%s' % (self.nova['user']),
356 'X-Auth-Token': '%s' % (self.nova['X-Auth-Token']),
357 'Content-Type': 'application/json'}
358
359 for i in range(1, 10):
360 # Change imageRef to self.glance['image_id']
361 json_str = {"server":
362 {
363 "name": "test %s" % (i),
364 "flavorRef": "http://%s:%s/%s/flavors/2" % (
365 self.nova['host'],
366 self.nova['port'],
367 self.nova['ver']),
368 "imageRef": self.glance['image_id']
369# "imageRef": "http://%s:%s/%s/images/%s" % (
370# self.nova['host'],
371# self.nova['port'],
372# self.nova['ver'],
373# self.glance['image_id'])
374 }
375 }
376 data = json.dumps(json_str)
377 response, content = http.request(path, 'POST', headers=headers,
378 body=data)
379 json_return = json.loads(content)
Justin Shepherd5778a252011-08-18 12:15:37 -0500380 self.assertEqual(response.status, 200)
Justin Shepherd0d9bbd12011-08-11 12:57:44 -0500381 self.assertEqual(json_return['server']['status'], "BUILD")
382 self.nova['multi_server']["test %s" % (i)] = \
383 json_return['server']['id']
384 time.sleep(30)
385
386 for k, v in self.nova['multi_server'].iteritems():
387 build_result = self.build_check(v)
388 self.assertEqual(build_result['ping'], True)
389 test_999_create_multiple.tags = ['nova']