2 # -*- coding: utf-8 -*-
5 # Copyright 2015 Telefónica Investigación y Desarrollo, S.A.U.
6 # This file is part of openmano
9 # Licensed under the Apache License, Version 2.0 (the "License"); you may
10 # not use this file except in compliance with the License. You may obtain
11 # a copy of the License at
13 # http://www.apache.org/licenses/LICENSE-2.0
15 # Unless required by applicable law or agreed to in writing, software
16 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
18 # License for the specific language governing permissions and limitations
21 # For those usages not covered by the Apache License, Version 2.0 please
22 # contact with: nfvlabs@tid.es
26 Module for testing openmano functionality. It uses openmanoclient.py for invoking openmano
28 __author__
="Pablo Montes"
29 __date__
="$16-Feb-2017 17:08:16$"
31 version_date
="Feb 2017"
36 from optparse
import OptionParser
49 global scenario_test_folder
50 global test_image_name
51 global management_network
54 def check_instance_scenario_active(uuid
):
55 instance
= client
.get_instance(uuid
=uuid
)
57 for net
in instance
['nets']:
58 status
= net
['status']
59 if status
!= 'ACTIVE':
60 return (False, status
)
62 for vnf
in instance
['vnfs']:
65 if status
!= 'ACTIVE':
66 return (False, status
)
72 All unittest classes for code based tests must have prefix 'test_' in order to be taken into account for tests
74 class test_tenant_operations(unittest
.TestCase
):
81 logger
.info("{}. {}".format(test_number
, cls
.__name
__))
84 def tearDownClass(cls
):
85 globals().__setitem
__('test_number', globals().__getitem
__('test_number') + 1)
88 exec_info
= sys
.exc_info()
89 if exec_info
== (None, None, None):
90 logger
.info(self
.__class
__.test_text
+" -> TEST OK")
92 logger
.warning(self
.__class
__.test_text
+" -> TEST NOK")
93 error_trace
= traceback
.format_exception(exec_info
[0], exec_info
[1], exec_info
[2])
95 for line
in error_trace
:
97 logger
.critical("{}".format(msg
))
99 def test_000_create_RO_tenant(self
):
100 self
.__class
__.tenant_name
= _get_random_string(20)
101 self
.__class
__.test_text
= "{}.{}. TEST {}".format(test_number
, self
.__class
__.test_index
,
102 inspect
.currentframe().f_code
.co_name
)
103 self
.__class
__.test_index
+= 1
104 tenant
= client
.create_tenant(name
=self
.__class
__.tenant_name
, description
=self
.__class
__.tenant_name
)
105 logger
.debug("{}".format(tenant
))
106 self
.assertEqual(tenant
.get('tenant', {}).get('name', ''), self
.__class
__.tenant_name
)
108 def test_010_list_RO_tenant(self
):
109 self
.__class
__.test_text
= "{}.{}. TEST {}".format(test_number
, self
.__class
__.test_index
,
110 inspect
.currentframe().f_code
.co_name
)
111 self
.__class
__.test_index
+= 1
112 tenant
= client
.get_tenant(name
=self
.__class
__.tenant_name
)
113 logger
.debug("{}".format(tenant
))
114 self
.assertEqual(tenant
.get('tenant', {}).get('name', ''), self
.__class
__.tenant_name
)
116 def test_020_delete_RO_tenant(self
):
117 self
.__class
__.test_text
= "{}.{}. TEST {}".format(test_number
, self
.__class
__.test_index
,
118 inspect
.currentframe().f_code
.co_name
)
119 self
.__class
__.test_index
+= 1
120 tenant
= client
.delete_tenant(name
=self
.__class
__.tenant_name
)
121 logger
.debug("{}".format(tenant
))
122 assert('deleted' in tenant
.get('result',""))
124 class test_datacenter_operations(unittest
.TestCase
):
126 datacenter_name
= None
131 logger
.info("{}. {}".format(test_number
, cls
.__name
__))
134 def tearDownClass(cls
):
135 globals().__setitem
__('test_number', globals().__getitem
__('test_number') + 1)
138 exec_info
= sys
.exc_info()
139 if exec_info
== (None, None, None):
140 logger
.info(self
.__class
__.test_text
+" -> TEST OK")
142 logger
.warning(self
.__class
__.test_text
+" -> TEST NOK")
143 error_trace
= traceback
.format_exception(exec_info
[0], exec_info
[1], exec_info
[2])
145 for line
in error_trace
:
147 logger
.critical("{}".format(msg
))
149 def test_000_create_datacenter(self
):
150 self
.__class
__.test_text
= "{}.{}. TEST {}".format(test_number
, self
.__class
__.test_index
,
151 inspect
.currentframe().f_code
.co_name
)
152 self
.__class
__.datacenter_name
= _get_random_string(20)
153 self
.__class
__.test_index
+= 1
154 self
.datacenter
= client
.create_datacenter(name
=self
.__class
__.datacenter_name
, vim_url
="http://fakeurl/fake")
155 logger
.debug("{}".format(self
.datacenter
))
156 self
.assertEqual (self
.datacenter
.get('datacenter', {}).get('name',''), self
.__class
__.datacenter_name
)
158 def test_010_list_datacenter(self
):
159 self
.__class
__.test_text
= "{}.{}. TEST {}".format(test_number
, self
.__class
__.test_index
,
160 inspect
.currentframe().f_code
.co_name
)
162 self
.__class
__.test_index
+= 1
163 self
.datacenter
= client
.get_datacenter(all_tenants
=True, name
=self
.__class
__.datacenter_name
)
164 logger
.debug("{}".format(self
.datacenter
))
165 self
.assertEqual (self
.datacenter
.get('datacenter', {}).get('name', ''), self
.__class
__.datacenter_name
)
167 def test_020_attach_datacenter(self
):
168 self
.__class
__.test_text
= "{}.{}. TEST {}".format(test_number
, self
.__class
__.test_index
,
169 inspect
.currentframe().f_code
.co_name
)
171 self
.__class
__.test_index
+= 1
172 self
.datacenter
= client
.attach_datacenter(name
=self
.__class
__.datacenter_name
, vim_tenant_name
='fake')
173 logger
.debug("{}".format(self
.datacenter
))
174 assert ('vim_tenants' in self
.datacenter
.get('datacenter', {}))
176 def test_030_list_attached_datacenter(self
):
177 self
.__class
__.test_text
= "{}.{}. TEST {}".format(test_number
, self
.__class
__.test_index
,
178 inspect
.currentframe().f_code
.co_name
)
180 self
.__class
__.test_index
+= 1
181 self
.datacenter
= client
.get_datacenter(all_tenants
=False, name
=self
.__class
__.datacenter_name
)
182 logger
.debug("{}".format(self
.datacenter
))
183 self
.assertEqual (self
.datacenter
.get('datacenter', {}).get('name', ''), self
.__class
__.datacenter_name
)
185 def test_040_detach_datacenter(self
):
186 self
.__class
__.test_text
= "{}.{}. TEST {}".format(test_number
, self
.__class
__.test_index
,
187 inspect
.currentframe().f_code
.co_name
)
189 self
.__class
__.test_index
+= 1
190 self
.datacenter
= client
.detach_datacenter(name
=self
.__class
__.datacenter_name
)
191 logger
.debug("{}".format(self
.datacenter
))
192 assert ('detached' in self
.datacenter
.get('result', ""))
194 def test_050_delete_datacenter(self
):
195 self
.__class
__.test_text
= "{}.{}. TEST {}".format(test_number
, self
.__class
__.test_index
,
196 inspect
.currentframe().f_code
.co_name
)
198 self
.__class
__.test_index
+= 1
199 self
.datacenter
= client
.delete_datacenter(name
=self
.__class
__.datacenter_name
)
200 logger
.debug("{}".format(self
.datacenter
))
201 assert('deleted' in self
.datacenter
.get('result',""))
203 class test_VIM_network_operations(unittest
.TestCase
):
205 vim_network_name
= None
207 vim_network_uuid
= None
211 logger
.info("{}. {}".format(test_number
, cls
.__name
__))
214 def tearDownClass(cls
):
215 globals().__setitem
__('test_number', globals().__getitem
__('test_number') + 1)
218 exec_info
= sys
.exc_info()
219 if exec_info
== (None, None, None):
220 logger
.info(self
.__class
__.test_text
+ " -> TEST OK")
222 logger
.warning(self
.__class
__.test_text
+ " -> TEST NOK")
223 error_trace
= traceback
.format_exception(exec_info
[0], exec_info
[1], exec_info
[2])
225 for line
in error_trace
:
227 logger
.critical("{}".format(msg
))
229 def test_000_create_VIM_network(self
):
230 self
.__class
__.test_text
= "{}.{}. TEST {}".format(test_number
, self
.__class
__.test_index
,
231 inspect
.currentframe().f_code
.co_name
)
232 self
.__class
__.vim_network_name
= _get_random_string(20)
233 self
.__class
__.test_index
+= 1
234 network
= client
.vim_action("create", "networks", name
=self
.__class
__.vim_network_name
)
235 logger
.debug("{}".format(network
))
236 self
.__class
__.vim_network_uuid
= network
["network"]["id"]
237 self
.assertEqual(network
.get('network', {}).get('name', ''), self
.__class
__.vim_network_name
)
239 def test_010_list_VIM_networks(self
):
240 self
.__class
__.test_text
= "{}.{}. TEST {}".format(test_number
, self
.__class
__.test_index
,
241 inspect
.currentframe().f_code
.co_name
)
242 self
.__class
__.test_index
+= 1
243 networks
= client
.vim_action("list", "networks")
244 logger
.debug("{}".format(networks
))
246 def test_020_get_VIM_network_by_uuid(self
):
247 self
.__class
__.test_text
= "{}.{}. TEST {}".format(test_number
, self
.__class
__.test_index
,
248 inspect
.currentframe().f_code
.co_name
)
250 self
.__class
__.test_index
+= 1
251 network
= client
.vim_action("show", "networks", uuid
=self
.__class
__.vim_network_uuid
)
252 logger
.debug("{}".format(network
))
253 self
.assertEqual(network
.get('network', {}).get('name', ''), self
.__class
__.vim_network_name
)
255 def test_030_delete_VIM_network_by_uuid(self
):
256 self
.__class
__.test_text
= "{}.{}. TEST {}".format(test_number
, self
.__class
__.test_index
,
257 inspect
.currentframe().f_code
.co_name
)
259 self
.__class
__.test_index
+= 1
260 network
= client
.vim_action("delete", "networks", uuid
=self
.__class
__.vim_network_uuid
)
261 logger
.debug("{}".format(network
))
262 assert ('deleted' in network
.get('result', ""))
264 class test_VIM_image_operations(unittest
.TestCase
):
270 logger
.info("{}. {}".format(test_number
, cls
.__name
__))
273 def tearDownClass(cls
):
274 globals().__setitem
__('test_number', globals().__getitem
__('test_number') + 1)
277 exec_info
= sys
.exc_info()
278 if exec_info
== (None, None, None):
279 logger
.info(self
.__class
__.test_text
+ " -> TEST OK")
281 logger
.warning(self
.__class
__.test_text
+ " -> TEST NOK")
282 error_trace
= traceback
.format_exception(exec_info
[0], exec_info
[1], exec_info
[2])
284 for line
in error_trace
:
286 logger
.critical("{}".format(msg
))
288 def test_000_list_VIM_images(self
):
289 self
.__class
__.test_text
= "{}.{}. TEST {}".format(test_number
, self
.__class
__.test_index
,
290 inspect
.currentframe().f_code
.co_name
)
291 self
.__class
__.test_index
+= 1
292 images
= client
.vim_action("list", "images")
293 logger
.debug("{}".format(images
))
296 The following is a non critical test that will fail most of the times.
297 In case of OpenStack datacenter these tests will only success if RO has access to the admin endpoint
298 This test will only be executed in case it is specifically requested by the user
300 class test_VIM_tenant_operations(unittest
.TestCase
):
302 vim_tenant_name
= None
304 vim_tenant_uuid
= None
308 logger
.info("{}. {}".format(test_number
, cls
.__name
__))
309 logger
.warning("In case of OpenStack datacenter these tests will only success "
310 "if RO has access to the admin endpoint")
313 def tearDownClass(cls
):
314 globals().__setitem
__('test_number', globals().__getitem
__('test_number') + 1)
317 exec_info
= sys
.exc_info()
318 if exec_info
== (None, None, None):
319 logger
.info(self
.__class
__.test_text
+ " -> TEST OK")
321 logger
.warning(self
.__class
__.test_text
+ " -> TEST NOK")
322 error_trace
= traceback
.format_exception(exec_info
[0], exec_info
[1], exec_info
[2])
324 for line
in error_trace
:
326 logger
.critical("{}".format(msg
))
328 def test_000_create_VIM_tenant(self
):
329 self
.__class
__.test_text
= "{}.{}. TEST {}".format(test_number
, self
.__class
__.test_index
,
330 inspect
.currentframe().f_code
.co_name
)
331 self
.__class
__.vim_tenant_name
= _get_random_string(20)
332 self
.__class
__.test_index
+= 1
333 tenant
= client
.vim_action("create", "tenants", name
=self
.__class
__.vim_tenant_name
)
334 logger
.debug("{}".format(tenant
))
335 self
.__class
__.vim_tenant_uuid
= tenant
["tenant"]["id"]
336 self
.assertEqual(tenant
.get('tenant', {}).get('name', ''), self
.__class
__.vim_tenant_name
)
338 def test_010_list_VIM_tenants(self
):
339 self
.__class
__.test_text
= "{}.{}. TEST {}".format(test_number
, self
.__class
__.test_index
,
340 inspect
.currentframe().f_code
.co_name
)
341 self
.__class
__.test_index
+= 1
342 tenants
= client
.vim_action("list", "tenants")
343 logger
.debug("{}".format(tenants
))
345 def test_020_get_VIM_tenant_by_uuid(self
):
346 self
.__class
__.test_text
= "{}.{}. TEST {}".format(test_number
, self
.__class
__.test_index
,
347 inspect
.currentframe().f_code
.co_name
)
349 self
.__class
__.test_index
+= 1
350 tenant
= client
.vim_action("show", "tenants", uuid
=self
.__class
__.vim_tenant_uuid
)
351 logger
.debug("{}".format(tenant
))
352 self
.assertEqual(tenant
.get('tenant', {}).get('name', ''), self
.__class
__.vim_tenant_name
)
354 def test_030_delete_VIM_tenant_by_uuid(self
):
355 self
.__class
__.test_text
= "{}.{}. TEST {}".format(test_number
, self
.__class
__.test_index
,
356 inspect
.currentframe().f_code
.co_name
)
358 self
.__class
__.test_index
+= 1
359 tenant
= client
.vim_action("delete", "tenants", uuid
=self
.__class
__.vim_tenant_uuid
)
360 logger
.debug("{}".format(tenant
))
361 assert ('deleted' in tenant
.get('result', ""))
365 The following unittest class does not have the 'test_' on purpose. This test is the one used for the
366 scenario based tests.
368 class descriptor_based_scenario_test(unittest
.TestCase
):
371 scenario_test_path
= None
373 instance_scenario_uuid
= None
379 cls
.to_delete_list
= []
380 cls
.scenario_test_path
= test_directory
+ '/' + scenario_test_folder
381 logger
.info("{}. {} {}".format(test_number
, cls
.__name
__, scenario_test_folder
))
384 def tearDownClass(cls
):
385 globals().__setitem
__('test_number', globals().__getitem
__('test_number') + 1)
388 exec_info
= sys
.exc_info()
389 if exec_info
== (None, None, None):
390 logger
.info(self
.__class
__.test_text
+ " -> TEST OK")
392 logger
.warning(self
.__class
__.test_text
+ " -> TEST NOK")
393 error_trace
= traceback
.format_exception(exec_info
[0], exec_info
[1], exec_info
[2])
395 for line
in error_trace
:
397 logger
.critical("{}".format(msg
))
400 def test_000_load_scenario(self
):
401 self
.__class
__.test_text
= "{}.{}. TEST {} {}".format(test_number
, self
.__class
__.test_index
,
402 inspect
.currentframe().f_code
.co_name
,
403 scenario_test_folder
)
404 self
.__class
__.test_index
+= 1
405 vnfd_files
= glob
.glob(self
.__class
__.scenario_test_path
+'/vnfd_*.yaml')
406 scenario_file
= glob
.glob(self
.__class
__.scenario_test_path
+ '/scenario_*.yaml')
407 if len(vnfd_files
) == 0 or len(scenario_file
) > 1:
408 raise Exception('Test '+scenario_test_folder
+' not valid. It must contain an scenario file and at least one'
412 for vnfd
in vnfd_files
:
413 with
open(vnfd
, 'r') as stream
:
414 vnf_descriptor
= yaml
.load(stream
)
416 vnfc_list
= vnf_descriptor
['vnf']['VNFC']
417 for vnfc
in vnfc_list
:
418 vnfc
['image name'] = test_image_name
419 devices
= vnfc
.get('devices',[])
420 for device
in devices
:
421 if device
['type'] == 'disk' and 'image name' in device
:
422 device
['image name'] = test_image_name
424 logger
.debug("VNF descriptor: {}".format(vnf_descriptor
))
425 vnf
= client
.create_vnf(descriptor
=vnf_descriptor
)
427 self
.__class
__.to_delete_list
.insert(0, {"item": "vnf", "function": client
.delete_vnf
,
428 "params": {"uuid": vnf
['vnf']['uuid']}})
430 #load the scenario definition
431 with
open(scenario_file
[0], 'r') as stream
:
432 scenario_descriptor
= yaml
.load(stream
)
433 networks
= scenario_descriptor
['scenario']['networks']
434 networks
[management_network
] = networks
.pop('mgmt')
435 logger
.debug("Scenario descriptor: {}".format(scenario_descriptor
))
436 scenario
= client
.create_scenario(descriptor
=scenario_descriptor
)
437 logger
.debug(scenario
)
438 self
.__class
__.to_delete_list
.insert(0,{"item": "scenario", "function": client
.delete_scenario
,
439 "params":{"uuid": scenario
['scenario']['uuid']} })
440 self
.__class
__.scenario_uuid
= scenario
['scenario']['uuid']
442 def test_010_instantiate_scenario(self
):
443 self
.__class
__.test_text
= "{}.{}. TEST {} {}".format(test_number
, self
.__class
__.test_index
,
444 inspect
.currentframe().f_code
.co_name
,
445 scenario_test_folder
)
446 self
.__class
__.test_index
+= 1
448 instance
= client
.create_instance(scenario_id
=self
.__class
__.scenario_uuid
, name
=self
.__class
__.test_text
)
449 self
.__class
__.instance_scenario_uuid
= instance
['uuid']
450 logger
.debug(instance
)
451 self
.__class
__.to_delete_list
.insert(0, {"item": "instance", "function": client
.delete_instance
,
452 "params": {"uuid": instance
['uuid']}})
454 def test_020_check_deployent(self
):
455 self
.__class
__.test_text
= "{}.{}. TEST {} {}".format(test_number
, self
.__class
__.test_index
,
456 inspect
.currentframe().f_code
.co_name
,
457 scenario_test_folder
)
458 self
.__class
__.test_index
+= 1
461 raw_input('Scenario has been deployed. Perform manual check and press any key to resume')
465 instance_active
= False
467 result
= check_instance_scenario_active(self
.__class
__.instance_scenario_uuid
)
470 elif 'ERROR' in result
[1]:
471 msg
= 'Got error while waiting for the instance to get active: '+result
[1]
478 if keep_waiting
== 0:
479 msg
= 'Timeout reached while waiting instance scenario to get active'
483 def test_030_clean_deployment(self
):
484 self
.__class
__.test_text
= "{}.{}. TEST {} {}".format(test_number
, self
.__class
__.test_index
,
485 inspect
.currentframe().f_code
.co_name
,
486 scenario_test_folder
)
487 self
.__class
__.test_index
+= 1
488 #At the moment if you delete an scenario right after creating it, in openstack datacenters
489 #sometimes scenario ports get orphaned. This sleep is just a dirty workaround
491 for item
in self
.__class
__.to_delete_list
:
492 response
= item
["function"](**item
["params"])
493 logger
.debug(response
)
495 def _get_random_string(maxLength
):
496 '''generates a string with random characters string.letters and string.digits
497 with a random length up to maxLength characters. If maxLength is <15 it will be changed automatically to 15
501 minLength
= min_string
- len(prefix
)
502 if maxLength
< min_string
: maxLength
= min_string
503 maxLength
-= len(prefix
)
504 length
= random
.randint(minLength
,maxLength
)
505 return 'testing_'+"".join([random
.choice(string
.letters
+string
.digits
) for i
in xrange(length
)])
507 if __name__
=="__main__":
508 sys
.path
.append(os
.path
.dirname(os
.path
.dirname(os
.path
.abspath(__file__
))))
509 import openmanoclient
511 parser
= OptionParser()
514 parser
.add_option("-v",'--version', help='Show current version', dest
='version', action
="store_true", default
=False)
515 parser
.add_option('--debug', help='Set logs to debug level', dest
='debug', action
="store_true", default
=False)
516 parser
.add_option('--failed', help='Set logs to show only failed tests. --debug disables this option',
517 dest
='failed', action
="store_true", default
=False)
518 parser
.add_option('-u', '--url', dest
='endpoint_url', help='Set the openmano server url. By default '
519 'http://localhost:9090/openmano',
520 default
='http://localhost:9090/openmano')
521 default_logger_file
= os
.path
.dirname(__file__
)+'/'+os
.path
.splitext(os
.path
.basename(__file__
))[0]+'.log'
522 parser
.add_option('--logger_file', dest
='logger_file', help='Set the logger file. By default '+default_logger_file
,
523 default
=default_logger_file
)
524 parser
.add_option('--list-tests', help='List all available tests', dest
='list-tests', action
="store_true",
526 parser
.add_option('-m', '--manual-check', help='Pause execution once deployed to allow manual checking of the deployed instance scenario', dest
='manual', action
="store_true", default
=False)
527 parser
.add_option('--test', '--tests', help='Specify the tests to run', dest
='tests', default
=None)
530 parser
.add_option("-t", '--tenant', dest
='tenant_name', help='MANDATORY. Set the tenant name to test')
531 parser
.add_option('-d', '--datacenter', dest
='datacenter_name', help='MANDATORY, Set the datacenter name to test')
532 parser
.add_option("-i", '--image-name', dest
='image-name', help='MANDATORY. Image name of an Ubuntu 16.04 image '
533 'that will be used for testing available in the '
535 parser
.add_option("-n", '--mgmt-net-name', dest
='mgmt-net', help='MANDATORY. Set the tenant name to test')
537 (options
, args
) = parser
.parse_args()
539 # default logger level is INFO. Options --debug and --failed override this, being --debug prioritary
540 logger_level
= 'INFO'
541 if options
.__dict
__['debug']:
542 logger_level
= 'DEBUG'
543 elif options
.__dict
__['failed']:
544 logger_level
= 'WARNING'
545 logger_name
= os
.path
.basename(__file__
)
546 logger
= logging
.getLogger(logger_name
)
547 logger
.setLevel(logger_level
)
549 # Configure a logging handler to store in a logging file
550 fileHandler
= logging
.FileHandler(options
.__dict
__['logger_file'])
551 formatter_fileHandler
= logging
.Formatter('%(asctime)s %(name)s %(levelname)s: %(message)s')
552 fileHandler
.setFormatter(formatter_fileHandler
)
553 logger
.addHandler(fileHandler
)
555 # Configure a handler to print to stdout
556 consoleHandler
= logging
.StreamHandler(sys
.stdout
)
557 formatter_consoleHandler
= logging
.Formatter('%(message)s')
558 consoleHandler
.setFormatter(formatter_consoleHandler
)
559 logger
.addHandler(consoleHandler
)
561 logger
.debug('Program started with the following arguments: ' + str(options
.__dict
__))
563 #If version is required print it and exit
564 if options
.__dict
__['version']:
565 logger
.info("{}".format((sys
.argv
[0], __version__
+" version", version_date
)))
566 logger
.info ("(c) Copyright Telefonica")
569 test_directory
= os
.path
.dirname(__file__
) + "/RO_tests"
570 test_directory_content
= os
.listdir(test_directory
)
571 clsmembers
= inspect
.getmembers(sys
.modules
[__name__
], inspect
.isclass
)
573 # If only want to obtain a tests list print it and exit
574 if options
.__dict
__['list-tests']:
576 for cls
in clsmembers
:
577 if cls
[0].startswith('test_'):
578 tests_names
.append(cls
[0])
580 msg
= "The code based tests are:\n\t" + ', '.join(sorted(tests_names
))+'\n'+\
581 "The descriptor based tests are:\n\t"+ ', '.join(sorted(test_directory_content
))+'\n'+\
582 "NOTE: The test test_VIM_tenant_operations will fail in case the used datacenter is type OpenStack " \
583 "unless RO has access to the admin endpoint. Therefore this test is excluded by default"
588 #Make sure required arguments are present
589 required
= "tenant_name datacenter_name image-name mgmt-net".split()
592 if options
.__dict
__[r
] is None:
593 print "ERROR: parameter "+r
+" is required"
599 # set test image name and management network
600 test_image_name
= options
.__dict
__['image-name']
601 management_network
= options
.__dict
__['mgmt-net']
602 manual
= options
.__dict
__['manual']
604 #Create the list of tests to be run
605 descriptor_based_tests
= []
606 code_based_tests
= []
607 if options
.__dict
__['tests'] != None:
608 tests
= sorted(options
.__dict
__['tests'].split(','))
610 matches_code_based_tests
= [item
for item
in clsmembers
if item
[0] == test
]
611 if test
in test_directory_content
:
612 descriptor_based_tests
.append(test
)
613 elif len(matches_code_based_tests
) > 0:
614 code_based_tests
.append(matches_code_based_tests
[0][1])
616 logger
.critical("Test {} is not among the possible ones".format(test
))
620 descriptor_based_tests
= test_directory_content
621 for cls
in clsmembers
:
622 #We exclude 'test_VIM_tenant_operations' unless it is specifically requested by the user
623 if cls
[0].startswith('test_') and cls
[0] != 'test_VIM_tenant_operations':
624 code_based_tests
.append(cls
[1])
626 logger
.debug("descriptor_based_tests to be executed: {}".format(descriptor_based_tests
))
627 logger
.debug("code_based_tests to be executed: {}".format(code_based_tests
))
629 # import openmanoclient from relative path
630 client
= openmanoclient
.openmanoclient(
631 endpoint_url
=options
.__dict
__['endpoint_url'],
632 tenant_name
=options
.__dict
__['tenant_name'],
633 datacenter_name
= options
.__dict
__['datacenter_name'],
634 debug
= options
.__dict
__['debug'], logger
= logger_name
)
636 # TextTestRunner stream is set to /dev/null in order to avoid the method to directly print the result of tests.
637 # This is handled in the tests using logging.
638 stream
= open('/dev/null', 'w')
643 #Run code based tests
644 basic_tests_suite
= unittest
.TestSuite()
645 for test
in code_based_tests
:
646 basic_tests_suite
.addTest(unittest
.makeSuite(test
))
647 result
= unittest
.TextTestRunner(stream
=stream
).run(basic_tests_suite
)
648 executed
+= result
.testsRun
649 failed
+= len(result
.failures
) + len(result
.errors
)
650 if len(result
.failures
) > 0:
651 logger
.debug("failures : {}".format(result
.failures
))
652 if len(result
.errors
) > 0:
653 logger
.debug("errors : {}".format(result
.errors
))
655 # Additionally to the previous tests, scenario based tests will be executed.
656 # This scenario based tests are defined as directories inside the directory defined in 'test_directory'
657 for test
in descriptor_based_tests
:
658 scenario_test_folder
= test
659 test_suite
= unittest
.TestSuite()
660 test_suite
.addTest(unittest
.makeSuite(descriptor_based_scenario_test
))
661 result
= unittest
.TextTestRunner(stream
=stream
).run(test_suite
)
662 executed
+= result
.testsRun
663 failed
+= len(result
.failures
) + len(result
.errors
)
664 if len(result
.failures
) > 0:
665 logger
.debug("failures : {}".format(result
.failures
))
666 if len(result
.errors
) > 0:
667 logger
.debug("errors : {}".format(result
.errors
))
670 logger
.warning("Total number of tests: {}; Total number of failures/errors: {}".format(executed
, failed
))