forked from ManageIQ/integration_tests
-
Notifications
You must be signed in to change notification settings - Fork 0
/
conftest.py
216 lines (182 loc) · 7.34 KB
/
conftest.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
"""
Top-level conftest.py does a couple of things:
1) Add cfme_pages repo to the sys.path automatically
2) Load a number of plugins and fixtures automatically
"""
from pkgutil import iter_modules
import pytest
import requests
from fixtures.artifactor_plugin import art_client, appliance_ip_address
from cfme.fixtures.rdb import Rdb
from fixtures.pytest_store import store
from utils import ports
from utils.appliance import ApplianceException
from utils.conf import rdb
from utils.log import logger
from utils.path import data_path
from utils.net import net_check
from utils.wait import TimedOutError
class _AppliancePoliceException(Exception):
def __init__(self, message, port, *args, **kwargs):
super(_AppliancePoliceException, self).__init__(message, port, *args, **kwargs)
self.message = message
self.port = port
def __str__(self):
return "{} (port {})".format(self.message, self.port)
@pytest.mark.tryfirst
def pytest_addoption(parser):
# Create the cfme option group for use in other plugins
parser.getgroup('cfme', 'cfme: options related to cfme/miq appliances')
# Keeping due to compatibility
parser.addoption("--no-tracer", dest="no_tracer", action="store_true", default=False,
help="Disable the function tracer (REMOVED, doesn't do anything!)")
parser.addoption("--tracer", dest="tracer", action="store_true", default=False,
help="Enable the function tracer (REMOVED, doesn't do anything!)")
def pytest_cmdline_main(config):
for opt in ['--tracer', '--no-tracer']:
if config.getoption(opt):
print("The {} option has been REMOVED, it doesn't do anything; please, stop using it!"
.format(opt))
def pytest_sessionstart(session):
try:
store.current_appliance.check_no_conflicting_providers()
except ApplianceException as e:
raise pytest.UsageError("Conflicting providers were found: {}".format(e))
@pytest.fixture(scope="session", autouse=True)
def set_session_timeout():
store.current_appliance.set_session_timeout(86400)
@pytest.fixture(scope="session", autouse=True)
def fix_merkyl_workaround():
"""Workaround around merkyl not opening an iptables port for communication"""
ssh_client = store.current_appliance.ssh_client
if ssh_client.run_command('test -s /etc/init.d/merkyl').rc != 0:
logger.info('Rudely overwriting merkyl init.d on appliance;')
local_file = data_path.join("bundles").join("merkyl").join("merkyl")
remote_file = "/etc/init.d/merkyl"
ssh_client.put_file(local_file.strpath, remote_file)
ssh_client.run_command("service merkyl restart")
art_client.fire_hook('setup_merkyl', ip=appliance_ip_address)
@pytest.fixture(scope="session", autouse=True)
def fix_missing_hostname():
"""Fix for hostname missing from the /etc/hosts file
Note: Affects RHOS-based appliances but can't hurt the others so
it's applied on all.
"""
ssh_client = store.current_appliance.ssh_client
logger.info("Checking appliance's /etc/hosts for its own hostname")
if ssh_client.run_command('grep $(hostname) /etc/hosts').rc != 0:
logger.info("Adding it's hostname to its /etc/hosts")
# Append hostname to the first line (127.0.0.1)
ret = ssh_client.run_command('sed -i "1 s/$/ $(hostname)/" /etc/hosts')
if ret.rc == 0:
logger.info("Hostname added")
else:
logger.error("Failed to add hostname")
@pytest.fixture(autouse=True, scope="function")
def appliance_police():
if not store.slave_manager:
return
try:
port_numbers = {
'ssh': ports.SSH,
'https': store.current_appliance.ui_port,
'postgres': ports.DB}
port_results = {pn: net_check(pp, force=True) for pn, pp in port_numbers.items()}
for port, result in port_results.items():
if not result:
raise _AppliancePoliceException('Unable to connect', port_numbers[port])
try:
status_code = requests.get(store.current_appliance.url, verify=False,
timeout=120).status_code
except Exception:
raise _AppliancePoliceException('Getting status code failed', port_numbers['https'])
if status_code != 200:
raise _AppliancePoliceException('Status code was {}, should be 200'.format(
status_code), port_numbers['https'])
return
except _AppliancePoliceException as e:
# special handling for known failure conditions
if e.port == 443:
# Lots of rdbs lately where evm seems to have entirely crashed
# and (sadly) the only fix is a rude restart
store.current_appliance.restart_evm_service(rude=True)
try:
store.current_appliance.wait_for_web_ui(900)
store.write_line('EVM was frozen and had to be restarted.', purple=True)
return
except TimedOutError:
pass
e_message = str(e)
except Exception as e:
e_message = str(e)
# Regardles of the exception raised, we didn't return anywhere above
# time to call a human
msg = 'Help! My appliance {} crashed with: {}'.format(store.current_appliance.url, e_message)
store.slave_manager.message(msg)
if 'appliance_police_recipients' in rdb:
rdb_kwargs = {
'subject': 'RDB Breakpoint: Appliance failure',
'recipients': rdb.appliance_police_recipients,
}
else:
rdb_kwargs = {}
Rdb(msg).set_trace(**rdb_kwargs)
store.slave_manager.message('Resuming testing following remote debugging')
def _pytest_plugins_generator(*extension_pkgs):
# Finds all submodules in pytest extension packages and loads them
for extension_pkg in extension_pkgs:
path = extension_pkg.__path__
prefix = '%s.' % extension_pkg.__name__
for importer, modname, is_package in iter_modules(path, prefix):
yield modname
pytest_plugins = (
'cfme.test_framework.sprout.plugin',
'fixtures.pytest_store',
'fixtures.portset',
'fixtures.artifactor_plugin',
'fixtures.parallelizer',
'fixtures.prov_filter',
'fixtures.single_appliance_sprout',
'fixtures.dev_branch',
'fixtures.events',
'fixtures.appliance_update',
'fixtures.blockers',
'fixtures.browser',
'fixtures.cfme_data',
'fixtures.datafile',
'fixtures.db',
'fixtures.fixtureconf',
'fixtures.log',
'fixtures.maximized',
'fixtures.merkyl',
'fixtures.mgmt_system',
'fixtures.nelson',
'fixtures.node_annotate',
'fixtures.page_screenshots',
'fixtures.perf',
'fixtures.provider',
'fixtures.qa_contact',
'fixtures.randomness',
'fixtures.rbac',
'fixtures.screenshots',
'fixtures.soft_assert',
'fixtures.ssh_client',
'fixtures.templateloader',
'fixtures.terminalreporter',
'fixtures.ui_coverage',
'fixtures.version_file',
'fixtures.video',
'fixtures.virtual_machine',
'fixtures.widgets',
'markers',
'cfme.fixtures.pytest_selenium',
'cfme.fixtures.configure_auth_mode',
'cfme.fixtures.rdb',
'cfme.fixtures.rest_api',
'cfme.fixtures.service_fixtures',
'cfme.fixtures.smtp',
'cfme.fixtures.tag',
'cfme.fixtures.vm_name',
'metaplugins',
)
collect_ignore = ["tests/scenarios"]