blob: 7993914b46886e9b0a7407d88e5e957c7745746f [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
22import tempfile
23import unittest
24import httplib2
25import urllib
26import hashlib
27import time
28import os
29
30from pprint import pprint
31
32import tests
33
34
35class TestNovaAPI(tests.FunctionalTest):
36 def build_check(self, id):
37 self.result = {}
38 """
39 This is intended to check that a server completes the build process
40 and enters an active state upon creation. Due to reporting errors in
41 the API we are also testing ping and ssh
42 """
43 count = 0
44 path = "http://%s:%s/%s/servers/%s" % (self.nova['host'],
45 self.nova['port'],
46 self.nova['ver'],
47 id)
48 http = httplib2.Http()
49 headers = {'X-Auth-User': '%s' % (self.nova['user']),
50 'X-Auth-Token': '%s' % (self.nova['X-Auth-Token'])}
51 response, content = http.request(path, 'GET', headers=headers)
52 self.assertEqual(200, response.status)
53 data = json.loads(content)
54
55 # Get Server status exit when active
56 while (data['server']['status'] != 'ACTIVE'):
57 response, content = http.request(path, 'GET', headers=headers)
58 data = json.loads(content)
59 time.sleep(5)
60 count = count + 5
61 self.result['serverid'] = id
62 self.result['status'] = data['server']['status']
63
64 # Get IP Address of newly created server
Justin Shepherdf4457092011-08-17 09:33:20 -050065 addr_name = "private"
66 if 'vmnet' in data['server']['addresses']:
67 ref = data['server']['addresses']['vmnet']
68 if len(ref) > 0:
69 addr_name = 'vmnet'
70 if 'public' in data['server']['addresses']:
71 ref = data['server']['addresses']['public']
72 if len(ref) > 0:
73 addr_name = 'public'
74 ref = data['server']['addresses'][addr_name]
75 netaddr = ref[0]['addr']
Justin Shepherd0d9bbd12011-08-11 12:57:44 -050076
77 r = "" . join(os.popen('ping -c5 %s' % (netaddr)).readlines())
78 if r.find('64 bytes') > 1:
79 self.result['ping'] = True
80 else:
81 self.result['ping'] = False
82
83 return self.result
84
85 def test_002_verify_nova_auth(self):
86 if 'keystone' in self.config:
87 path = "http://%s:%s/%s" % (self.keystone['host'],
88 self.keystone['port'],
89 self.keystone['apiver'])
90 headers = {'X-Auth-User': self.keystone['user'],
91 'X-Auth-Key': self.keystone['pass']}
92 else:
93 path = "http://%s:%s/%s" % (self.nova['host'],
94 self.nova['port'],
95 self.nova['ver'])
96 headers = {'X-Auth-User': self.nova['user'],
97 'X-Auth-Key': self.nova['key']}
98
99 http = httplib2.Http()
100 response, content = http.request(path, 'HEAD', headers=headers)
101 self.assertEqual(204, response.status)
102 self.assertNotEqual(response['x-auth-token'], '')
103 self.assertNotEqual(response['x-server-management-url'], '')
104
105 # Set up Auth Token for all future API interactions
106 self.nova['X-Auth-Token'] = response['x-auth-token']
107 test_002_verify_nova_auth.tags = ['nova', 'nova-api']
108
109 def test_101_verify_version_selection_default(self):
110 path = "http://%s:%s/" % (self.nova['host'],
111 self.nova['port'])
112 http = httplib2.Http()
113 headers = {'X-Auth-Token': self.nova['X-Auth-Token']}
114 response, content = http.request(path, 'GET', headers=headers)
115 self.assertEqual(200, response.status)
116 data = json.loads(content)
117 self.assertEqual(len(data['versions']), 2)
118 test_101_verify_version_selection_default.tags = ['nova', 'nova-api']
119
120 def test_102_verify_version_selection_json(self):
121 path = "http://%s:%s/.json" % (self.nova['host'],
122 self.nova['port'])
123 http = httplib2.Http()
124 headers = {'X-Auth-Token': self.nova['X-Auth-Token']}
125 response, content = http.request(path, 'GET', headers=headers)
126 self.assertEqual(200, response.status)
127 data = json.loads(content)
128 self.assertEqual(len(data['versions']), 2)
129 test_102_verify_version_selection_json.tags = ['nova', 'nova-api']
130
131 def test_103_verify_version_selection_xml(self):
132 path = "http://%s:%s/.xml" % (self.nova['host'],
133 self.nova['port'])
134 http = httplib2.Http()
135 headers = {'X-Auth-Token': self.nova['X-Auth-Token']}
136 response, content = http.request(path, 'GET', headers=headers)
137 self.assertEqual(200, response.status)
138 self.assertTrue('<versions>' in content)
139 test_103_verify_version_selection_xml.tags = ['nova', 'nova-api']
140
141 def test_104_bad_user_bad_key(self):
142 if 'keystone' in self.config:
143 path = "http://%s:%s/%s" % (self.keystone['host'],
144 self.keystone['port'],
145 self.keystone['apiver'])
146 else:
147 path = "http://%s:%s/%s" % (self.nova['host'],
148 self.nova['port'],
149 self.nova['ver'])
150 http = httplib2.Http()
151 headers = {'X-Auth-User': 'unknown_auth_user',
152 'X-Auth-Key': 'unknown_auth_key'}
153 response, content = http.request(path, 'GET', headers=headers)
154 self.assertEqual(response.status, 401)
155 test_104_bad_user_bad_key.tags = ['nova', 'nova-api']
156
157 def test_105_bad_user_good_key(self):
158 if 'keystone' in self.config:
159 path = "http://%s:%s/%s" % (self.keystone['host'],
160 self.keystone['port'],
161 self.keystone['apiver'])
162 else:
163 path = "http://%s:%s/%s" % (self.nova['host'],
164 self.nova['port'],
165 self.nova['ver'])
166 http = httplib2.Http()
167 headers = {'X-Auth-User': 'unknown_auth_user',
168 'X-Auth-Key': self.nova['key']}
169 response, content = http.request(path, 'GET', headers=headers)
170 self.assertEqual(response.status, 401)
171 test_105_bad_user_good_key.tags = ['nova', 'nova-api']
172
173 def test_106_good_user_bad_key(self):
174 if 'keystone' in self.config:
175 path = "http://%s:%s/%s" % (self.keystone['host'],
176 self.keystone['port'],
177 self.keystone['apiver'])
178 else:
179 path = "http://%s:%s/%s" % (self.nova['host'],
180 self.nova['port'],
181 self.nova['ver'])
182 http = httplib2.Http()
183 headers = {'X-Auth-User': self.nova['user'],
184 'X-Auth-Key': 'unknown_auth_key'}
185 response, content = http.request(path, 'GET', headers=headers)
186 self.assertEqual(response.status, 401)
187 test_106_good_user_bad_key.tags = ['nova', 'nova-api']
188
189 def test_107_no_key(self):
190 if 'keystone' in self.config:
191 path = "http://%s:%s/%s" % (self.keystone['host'],
192 self.keystone['port'],
193 self.keystone['apiver'])
194 else:
195 path = "http://%s:%s/%s" % (self.nova['host'],
196 self.nova['port'],
197 self.nova['ver'])
198 http = httplib2.Http()
199 headers = {'X-Auth-User': self.nova['user']}
200 response, content = http.request(path, 'GET', headers=headers)
201 self.assertEqual(response.status, 401)
202 test_107_no_key.tags = ['nova', 'nova-api']
203
204 def test_108_bad_token(self):
205 if 'keystone' in self.config:
206 path = "http://%s:%s/%s" % (self.keystone['host'],
207 self.keystone['port'],
208 self.keystone['apiver'])
209 else:
210 path = "http://%s:%s/%s" % (self.nova['host'],
211 self.nova['port'],
212 self.nova['ver'])
213 http = httplib2.Http()
214 headers = {'X-Auth-Token': 'unknown_token'}
215 response, content = http.request(path, 'GET', headers=headers)
216 self.assertEqual(response.status, 401)
217 test_108_bad_token.tags = ['nova', 'nova-api']
218
219 def test_109_verify_blank_limits(self):
220 path = "http://%s:%s/%s/limits" % (self.nova['host'],
221 self.nova['port'],
222 self.nova['ver'])
223
224 http = httplib2.Http()
225 headers = {'X-Auth-User': '%s' % (self.nova['user']),
226 'X-Auth-Token': '%s' % (self.nova['X-Auth-Token'])}
227 response, content = http.request(path, 'GET', headers=headers)
228 self.assertEqual(200, response.status)
229 self.assertNotEqual('{"limits": []}', content)
230 test_109_verify_blank_limits.tags = ['nova', 'nova-api']
231
232 def test_110_list_flavors_v1_1(self):
233 path = "http://%s:%s/%s/flavors" % (self.nova['host'],
234 self.nova['port'],
235 self.nova['ver'])
236 http = httplib2.Http()
237 headers = {'X-Auth-User': '%s' % (self.nova['user']),
238 'X-Auth-Token': '%s' % (self.nova['X-Auth-Token'])}
239 response, content = http.request(path, 'GET', headers=headers)
240 self.assertEqual(200, response.status)
241 self.assertNotEqual('{"flavors": []}', content)
242 test_110_list_flavors_v1_1.tags = ['nova', 'nova-api']
243
244 def test_111_verify_kernel_active_v1_1(self):
245 # for testing purposes change self.glance['kernel_id'] to an active
246 # kernel image allow for skipping glance tests
247 if not 'kernel_id' in self.glance:
248 self.glance['kernel_id'] = "61"
249
250 path = "http://%s:%s/%s/images/%s" % (self.nova['host'],
251 self.nova['port'],
252 self.nova['ver'],
253 self.glance['kernel_id'])
254 http = httplib2.Http()
255 headers = {'X-Auth-User': '%s' % (self.nova['user']),
256 'X-Auth-Token': '%s' % (self.nova['X-Auth-Token'])}
257 response, content = http.request(path, 'GET', headers=headers)
258 self.assertEqual(200, response.status)
259 data = json.loads(content)
260 self.assertEqual(data['image']['status'], 'ACTIVE')
261 test_111_verify_kernel_active_v1_1.tags = ['nova']
262
263 def test_112_verify_ramdisk_active_v1_1(self):
264 # for testing purposes change self.glance['ramdisk_id'] to an active
265 # ramdisk image, allows you to skip glance tests
266 if not 'ramdisk_id' in self.glance:
267 self.glance['ramdisk_id'] = "62"
268
269 path = "http://%s:%s/%s/images/%s" % (self.nova['host'],
270 self.nova['port'],
271 self.nova['ver'],
272 self.glance['ramdisk_id'])
273 http = httplib2.Http()
274 headers = {'X-Auth-User': '%s' % (self.nova['user']),
275 'X-Auth-Token': '%s' % (self.nova['X-Auth-Token'])}
276 response, content = http.request(path, 'GET', headers=headers)
277 self.assertEqual(200, response.status)
278 data = json.loads(content)
279 self.assertEqual(data['image']['status'], 'ACTIVE')
280 test_112_verify_ramdisk_active_v1_1.tags = ['nova']
281
282 def test_113_verify_image_active_v1_1(self):
283 # for testing purposes change self.glance['image_id'] to an active
284 # image id allows for skipping glance tests
285 if not 'image_id' in self.glance:
286 self.glance['image_id'] = "63"
287
288 path = "http://%s:%s/%s/images/%s" % (self.nova['host'],
289 self.nova['port'],
290 self.nova['ver'],
291 self.glance['image_id'])
292 http = httplib2.Http()
293 headers = {'X-Auth-User': '%s' % (self.nova['user']),
294 'X-Auth-Token': '%s' % (self.nova['X-Auth-Token'])}
295 response, content = http.request(path, 'GET', headers=headers)
296 self.assertEqual(200, response.status)
297 data = json.loads(content)
298 self.assertEqual(data['image']['status'], 'ACTIVE')
299 test_113_verify_image_active_v1_1.tags = ['nova']
300
301 def test_200_create_server(self):
302 path = "http://%s:%s/%s/servers" % (self.nova['host'],
303 self.nova['port'],
304 self.nova['ver'])
305 http = httplib2.Http()
306 headers = {'X-Auth-User': '%s' % (self.nova['user']),
307 'X-Auth-Token': '%s' % (self.nova['X-Auth-Token']),
308 'Content-Type': 'application/json'}
309
310 # Change imageRef to self.glance['image_id']
311 json_str = {"server":
312 {
313 "name": "testing server creation",
314 "flavorRef": "http://%s:%s/%s/flavors/2" % (self.nova['host'],
315 self.nova['port'],
316 self.nova['ver']),
317 "imageRef": self.glance['image_id']
318# "imageRef": "http://%s:%s/%s/images/%s" % (self.nova['host'],
319# self.nova['port'],
320# self.nova['ver'],
321# self.glance['image_id'])
322 }
323 }
324 data = json.dumps(json_str)
325 response, content = http.request(path, 'POST', headers=headers,
326 body=data)
327 json_return = json.loads(content)
328 self.assertEqual(200, response.status)
329 self.assertEqual(json_return['server']['status'], "BUILD")
330 self.nova['single_server_id'] = json_return['server']['id']
331 time.sleep(5)
332 build_result = self.build_check(self.nova['single_server_id'])
333 self.assertEqual(build_result['status'], "ACTIVE")
334 self.assertEqual(build_result['ping'], True)
335 test_200_create_server.tags = ['nova']
336
337 def test_201_get_server_details(self):
338 path = "http://%s:%s/%s/servers/%s" % (self.nova['host'],
339 self.nova['port'],
340 self.nova['ver'],
341 self.nova['single_server_id'])
342
343 http = httplib2.Http()
344 headers = {'X-Auth-User': '%s' % (self.nova['user']),
345 'X-Auth-Token': '%s' % (self.nova['X-Auth-Token'])}
346
347 response, content = http.request(path, 'GET', headers=headers)
348 self.assertEqual(200, response.status)
349 test_201_get_server_details.tags = ['nova']
350
351 # MOVING TO 999 because it can kill the API
352 # Uncomment next line for testing
353 # def create_multi(self):
354 def test_999_create_multiple(self):
355 self.nova['multi_server'] = {}
356 path = "http://%s:%s/%s/servers" % (self.nova['host'],
357 self.nova['port'],
358 self.nova['ver'])
359 http = httplib2.Http()
360 headers = {'X-Auth-User': '%s' % (self.nova['user']),
361 'X-Auth-Token': '%s' % (self.nova['X-Auth-Token']),
362 'Content-Type': 'application/json'}
363
364 for i in range(1, 10):
365 # Change imageRef to self.glance['image_id']
366 json_str = {"server":
367 {
368 "name": "test %s" % (i),
369 "flavorRef": "http://%s:%s/%s/flavors/2" % (
370 self.nova['host'],
371 self.nova['port'],
372 self.nova['ver']),
373 "imageRef": self.glance['image_id']
374# "imageRef": "http://%s:%s/%s/images/%s" % (
375# self.nova['host'],
376# self.nova['port'],
377# self.nova['ver'],
378# self.glance['image_id'])
379 }
380 }
381 data = json.dumps(json_str)
382 response, content = http.request(path, 'POST', headers=headers,
383 body=data)
384 json_return = json.loads(content)
385 self.assertEqual(200, response.status)
386 self.assertEqual(json_return['server']['status'], "BUILD")
387 self.nova['multi_server']["test %s" % (i)] = \
388 json_return['server']['id']
389 time.sleep(30)
390
391 for k, v in self.nova['multi_server'].iteritems():
392 build_result = self.build_check(v)
393 self.assertEqual(build_result['ping'], True)
394 test_999_create_multiple.tags = ['nova']