Fixed test for security groups when checking for project/tenant ID
[snaps.git] / snaps / unit_test_suite.py
1 # Copyright (c) 2016 Cable Television Laboratories, Inc. ("CableLabs")
2 #                    and others.  All rights reserved.
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 import argparse
16 import json
17 import logging
18 import os
19 import unittest
20
21 from snaps import test_suite_builder
22
23 __author__ = 'spisarski'
24
25 logger = logging.getLogger('unit_test_suite')
26
27 ARG_NOT_SET = "argument not set"
28 LOG_LEVELS = {'FATAL': logging.FATAL, 'CRITICAL': logging.CRITICAL, 'ERROR': logging.ERROR, 'WARN': logging.WARN,
29               'INFO': logging.INFO, 'DEBUG': logging.DEBUG}
30
31
32 def __create_test_suite(source_filename, ext_net_name, proxy_settings, ssh_proxy_cmd, run_unit_tests, flavor_metadata,
33                         use_keystone, use_floating_ips, log_level):
34     """
35     Compiles the tests that should run
36     :param source_filename: the OpenStack credentials file (required)
37     :param ext_net_name: the name of the external network to use for floating IPs (required)
38     :param run_unit_tests: when true, the tests not requiring OpenStack will be added to the test suite
39     :param proxy_settings: <host>:<port> of the proxy server (optional)
40     :param ssh_proxy_cmd: the command used to connect via SSH over some proxy server (optional)
41     :param flavor_metadata: dict() object containing the metadata for flavors created for test VM instance
42     :param use_keystone: when true, tests creating users and projects will be exercised and must be run on a host that
43                          has access to the cloud's administrative network
44     :param use_floating_ips: when true, tests requiring floating IPs will be executed
45     :param log_level: the logging level
46     :return:
47     """
48     suite = unittest.TestSuite()
49
50     # Tests that do not require a remote connection to an OpenStack cloud
51     if run_unit_tests:
52         test_suite_builder.add_unit_tests(suite)
53
54     # Basic connection tests
55     test_suite_builder.add_openstack_client_tests(suite, source_filename, ext_net_name, use_keystone=use_keystone,
56                                                   http_proxy_str=proxy_settings, log_level=log_level)
57
58     # Tests the OpenStack API calls
59     test_suite_builder.add_openstack_api_tests(suite, source_filename, ext_net_name, use_keystone=use_keystone,
60                                                http_proxy_str=proxy_settings, log_level=log_level)
61
62     # Long running integration type tests
63     test_suite_builder.add_openstack_integration_tests(suite, source_filename, ext_net_name, use_keystone=use_keystone,
64                                                        proxy_settings=proxy_settings, ssh_proxy_cmd=ssh_proxy_cmd,
65                                                        flavor_metadata=flavor_metadata,
66                                                        use_floating_ips=use_floating_ips, log_level=log_level)
67     return suite
68
69
70 def main(arguments):
71     """
72     Begins running unit tests.
73     argv[1] if used must be the source filename else os_env.yaml will be leveraged instead
74     argv[2] if used must be the proxy server <host>:<port>
75     """
76     logger.info('Starting test suite')
77
78     log_level = LOG_LEVELS.get(arguments.log_level, logging.DEBUG)
79
80     flavor_metadata = None
81
82     if arguments.flavor_metadata:
83         flavor_metadata = json.loads(arguments.flavor_metadata)
84
85     suite = None
86     if arguments.env and arguments.ext_net:
87         suite = __create_test_suite(arguments.env, arguments.ext_net, arguments.proxy, arguments.ssh_proxy_cmd,
88                                     arguments.include_units != ARG_NOT_SET,
89                                     flavor_metadata,
90                                     arguments.use_keystone != ARG_NOT_SET,
91                                     arguments.no_floating_ips == ARG_NOT_SET, log_level)
92     else:
93         logger.error('Environment file or external network not defined')
94         exit(1)
95
96     # To ensure any files referenced via a relative path will begin from the diectory in which this file resides
97     os.chdir(os.path.dirname(os.path.realpath(__file__)))
98
99     result = unittest.TextTestRunner(verbosity=2).run(suite)
100
101     if result.errors:
102         logger.error('Number of errors in test suite - ' + str(len(result.errors)))
103         for test, message in result.errors:
104             logger.error(str(test) + " ERROR with " + message)
105
106     if result.failures:
107         logger.error('Number of failures in test suite - ' + str(len(result.failures)))
108         for test, message in result.failures:
109             logger.error(str(test) + " FAILED with " + message)
110
111     if (result.errors and len(result.errors) > 0) or (result.failures and len(result.failures) > 0):
112         logger.error('See above for test failures')
113         exit(1)
114     else:
115         logger.info('All tests completed successfully')
116
117     exit(0)
118
119
120 if __name__ == '__main__':
121     parser = argparse.ArgumentParser()
122     parser.add_argument('-e', '--env', dest='env', required=True, help='OpenStack credentials file')
123     parser.add_argument('-n', '--net', dest='ext_net', required=True, help='External network name')
124     parser.add_argument('-p', '--proxy', dest='proxy', nargs='?', default=None,
125                         help='Optonal HTTP proxy socket (<host>:<port>)')
126     parser.add_argument('-s', '--ssh-proxy-cmd', dest='ssh_proxy_cmd', nargs='?', default=None,
127                         help='Optonal SSH proxy command value')
128     parser.add_argument('-l', '--log-level', dest='log_level', default='INFO',
129                         help='Logging Level (FATAL|CRITICAL|ERROR|WARN|INFO|DEBUG)')
130     parser.add_argument('-k', '--use-keystone', dest='use_keystone', default=ARG_NOT_SET, nargs='?',
131                         help='When argument is set, the tests will exercise the keystone APIs and must be run on a ' +
132                              'machine that has access to the admin network' +
133                              ' and is able to create users and groups')
134     parser.add_argument('-f', '--no-floating-ips', dest='no_floating_ips', default=ARG_NOT_SET, nargs='?',
135                         help='When argument is set, all tests requiring Floating IPs will not be executed')
136     parser.add_argument('-u', '--include-units', dest='include_units', default=ARG_NOT_SET, nargs='?',
137                         help='When argument is set, all tests not requiring OpenStack will be executed')
138     parser.add_argument('-fm', '--flavor-meta', dest='flavor_metadata', required=False,
139                         default='{\"hw:mem_page_size\": \"any\"}',
140                         help='JSON string to be used as flavor metadata for all test instances created')
141     args = parser.parse_args()
142
143     main(args)