teuthology 1.1.0__py3-none-any.whl → 1.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- scripts/describe.py +1 -0
- scripts/dispatcher.py +55 -26
- scripts/exporter.py +18 -0
- scripts/lock.py +1 -1
- scripts/node_cleanup.py +58 -0
- scripts/openstack.py +9 -9
- scripts/results.py +12 -11
- scripts/schedule.py +4 -0
- scripts/suite.py +57 -16
- scripts/supervisor.py +44 -0
- scripts/update_inventory.py +10 -4
- teuthology/__init__.py +24 -26
- teuthology/beanstalk.py +4 -3
- teuthology/config.py +16 -6
- teuthology/contextutil.py +18 -14
- teuthology/describe_tests.py +25 -18
- teuthology/dispatcher/__init__.py +210 -35
- teuthology/dispatcher/supervisor.py +140 -58
- teuthology/exceptions.py +43 -0
- teuthology/exporter.py +347 -0
- teuthology/kill.py +76 -81
- teuthology/lock/cli.py +3 -3
- teuthology/lock/ops.py +135 -61
- teuthology/lock/query.py +61 -44
- teuthology/ls.py +1 -1
- teuthology/misc.py +61 -75
- teuthology/nuke/__init__.py +12 -353
- teuthology/openstack/__init__.py +4 -3
- teuthology/openstack/openstack-centos-7.0-user-data.txt +1 -1
- teuthology/openstack/openstack-centos-7.1-user-data.txt +1 -1
- teuthology/openstack/openstack-centos-7.2-user-data.txt +1 -1
- teuthology/openstack/openstack-debian-8.0-user-data.txt +1 -1
- teuthology/openstack/openstack-opensuse-42.1-user-data.txt +1 -1
- teuthology/openstack/openstack-teuthology.cron +0 -1
- teuthology/orchestra/cluster.py +49 -7
- teuthology/orchestra/connection.py +16 -5
- teuthology/orchestra/console.py +111 -50
- teuthology/orchestra/daemon/cephadmunit.py +17 -4
- teuthology/orchestra/daemon/state.py +8 -1
- teuthology/orchestra/daemon/systemd.py +4 -4
- teuthology/orchestra/opsys.py +30 -11
- teuthology/orchestra/remote.py +405 -338
- teuthology/orchestra/run.py +3 -3
- teuthology/packaging.py +19 -16
- teuthology/provision/__init__.py +30 -10
- teuthology/provision/cloud/openstack.py +12 -6
- teuthology/provision/cloud/util.py +1 -2
- teuthology/provision/downburst.py +4 -3
- teuthology/provision/fog.py +68 -20
- teuthology/provision/openstack.py +5 -4
- teuthology/provision/pelagos.py +1 -1
- teuthology/repo_utils.py +43 -13
- teuthology/report.py +57 -35
- teuthology/results.py +5 -3
- teuthology/run.py +13 -14
- teuthology/run_tasks.py +27 -43
- teuthology/schedule.py +4 -3
- teuthology/scrape.py +28 -22
- teuthology/suite/__init__.py +74 -45
- teuthology/suite/build_matrix.py +34 -24
- teuthology/suite/fragment-merge.lua +105 -0
- teuthology/suite/matrix.py +31 -2
- teuthology/suite/merge.py +175 -0
- teuthology/suite/placeholder.py +6 -9
- teuthology/suite/run.py +175 -100
- teuthology/suite/util.py +64 -218
- teuthology/task/__init__.py +1 -1
- teuthology/task/ansible.py +101 -32
- teuthology/task/buildpackages.py +2 -2
- teuthology/task/ceph_ansible.py +13 -6
- teuthology/task/cephmetrics.py +2 -1
- teuthology/task/clock.py +33 -14
- teuthology/task/exec.py +18 -0
- teuthology/task/hadoop.py +2 -2
- teuthology/task/install/__init__.py +29 -7
- teuthology/task/install/bin/adjust-ulimits +16 -0
- teuthology/task/install/bin/daemon-helper +114 -0
- teuthology/task/install/bin/stdin-killer +263 -0
- teuthology/task/install/deb.py +1 -1
- teuthology/task/install/rpm.py +17 -5
- teuthology/task/install/util.py +3 -3
- teuthology/task/internal/__init__.py +41 -10
- teuthology/task/internal/edit_sudoers.sh +10 -0
- teuthology/task/internal/lock_machines.py +2 -9
- teuthology/task/internal/redhat.py +31 -1
- teuthology/task/internal/syslog.py +31 -8
- teuthology/task/kernel.py +152 -145
- teuthology/task/lockfile.py +1 -1
- teuthology/task/mpi.py +10 -10
- teuthology/task/pcp.py +1 -1
- teuthology/task/selinux.py +16 -8
- teuthology/task/ssh_keys.py +4 -4
- teuthology/task/tests/__init__.py +137 -77
- teuthology/task/tests/test_fetch_coredumps.py +116 -0
- teuthology/task/tests/test_run.py +4 -4
- teuthology/timer.py +3 -3
- teuthology/util/loggerfile.py +19 -0
- teuthology/util/scanner.py +159 -0
- teuthology/util/sentry.py +52 -0
- teuthology/util/time.py +52 -0
- teuthology-1.2.0.data/scripts/adjust-ulimits +16 -0
- teuthology-1.2.0.data/scripts/daemon-helper +114 -0
- teuthology-1.2.0.data/scripts/stdin-killer +263 -0
- teuthology-1.2.0.dist-info/METADATA +89 -0
- teuthology-1.2.0.dist-info/RECORD +174 -0
- {teuthology-1.1.0.dist-info → teuthology-1.2.0.dist-info}/WHEEL +1 -1
- {teuthology-1.1.0.dist-info → teuthology-1.2.0.dist-info}/entry_points.txt +3 -2
- scripts/nuke.py +0 -47
- scripts/worker.py +0 -37
- teuthology/nuke/actions.py +0 -456
- teuthology/openstack/test/__init__.py +0 -0
- teuthology/openstack/test/openstack-integration.py +0 -286
- teuthology/openstack/test/test_config.py +0 -35
- teuthology/openstack/test/test_openstack.py +0 -1695
- teuthology/orchestra/test/__init__.py +0 -0
- teuthology/orchestra/test/integration/__init__.py +0 -0
- teuthology/orchestra/test/integration/test_integration.py +0 -94
- teuthology/orchestra/test/test_cluster.py +0 -240
- teuthology/orchestra/test/test_connection.py +0 -106
- teuthology/orchestra/test/test_console.py +0 -217
- teuthology/orchestra/test/test_opsys.py +0 -404
- teuthology/orchestra/test/test_remote.py +0 -185
- teuthology/orchestra/test/test_run.py +0 -286
- teuthology/orchestra/test/test_systemd.py +0 -54
- teuthology/orchestra/test/util.py +0 -12
- teuthology/test/__init__.py +0 -0
- teuthology/test/fake_archive.py +0 -107
- teuthology/test/fake_fs.py +0 -92
- teuthology/test/integration/__init__.py +0 -0
- teuthology/test/integration/test_suite.py +0 -86
- teuthology/test/task/__init__.py +0 -205
- teuthology/test/task/test_ansible.py +0 -624
- teuthology/test/task/test_ceph_ansible.py +0 -176
- teuthology/test/task/test_console_log.py +0 -88
- teuthology/test/task/test_install.py +0 -337
- teuthology/test/task/test_internal.py +0 -57
- teuthology/test/task/test_kernel.py +0 -243
- teuthology/test/task/test_pcp.py +0 -379
- teuthology/test/task/test_selinux.py +0 -35
- teuthology/test/test_config.py +0 -189
- teuthology/test/test_contextutil.py +0 -68
- teuthology/test/test_describe_tests.py +0 -316
- teuthology/test/test_email_sleep_before_teardown.py +0 -81
- teuthology/test/test_exit.py +0 -97
- teuthology/test/test_get_distro.py +0 -47
- teuthology/test/test_get_distro_version.py +0 -47
- teuthology/test/test_get_multi_machine_types.py +0 -27
- teuthology/test/test_job_status.py +0 -60
- teuthology/test/test_ls.py +0 -48
- teuthology/test/test_misc.py +0 -391
- teuthology/test/test_nuke.py +0 -290
- teuthology/test/test_packaging.py +0 -763
- teuthology/test/test_parallel.py +0 -28
- teuthology/test/test_repo_utils.py +0 -225
- teuthology/test/test_report.py +0 -77
- teuthology/test/test_results.py +0 -155
- teuthology/test/test_run.py +0 -239
- teuthology/test/test_safepath.py +0 -55
- teuthology/test/test_schedule.py +0 -45
- teuthology/test/test_scrape.py +0 -167
- teuthology/test/test_timer.py +0 -80
- teuthology/test/test_vps_os_vers_parameter_checking.py +0 -84
- teuthology/test/test_worker.py +0 -303
- teuthology/worker.py +0 -354
- teuthology-1.1.0.dist-info/METADATA +0 -76
- teuthology-1.1.0.dist-info/RECORD +0 -213
- {teuthology-1.1.0.dist-info → teuthology-1.2.0.dist-info}/LICENSE +0 -0
- {teuthology-1.1.0.dist-info → teuthology-1.2.0.dist-info}/top_level.txt +0 -0
teuthology/test/test_parallel.py
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
from teuthology.parallel import parallel
|
2
|
-
|
3
|
-
|
4
|
-
def identity(item, input_set=None, remove=False):
|
5
|
-
if input_set is not None:
|
6
|
-
assert item in input_set
|
7
|
-
if remove:
|
8
|
-
input_set.remove(item)
|
9
|
-
return item
|
10
|
-
|
11
|
-
|
12
|
-
class TestParallel(object):
|
13
|
-
def test_basic(self):
|
14
|
-
in_set = set(range(10))
|
15
|
-
with parallel() as para:
|
16
|
-
for i in in_set:
|
17
|
-
para.spawn(identity, i, in_set, remove=True)
|
18
|
-
assert para.any_spawned is True
|
19
|
-
assert para.count == len(in_set)
|
20
|
-
|
21
|
-
def test_result(self):
|
22
|
-
in_set = set(range(10))
|
23
|
-
with parallel() as para:
|
24
|
-
for i in in_set:
|
25
|
-
para.spawn(identity, i, in_set)
|
26
|
-
for result in para:
|
27
|
-
in_set.remove(result)
|
28
|
-
|
@@ -1,225 +0,0 @@
|
|
1
|
-
import logging
|
2
|
-
import unittest.mock as mock
|
3
|
-
import os
|
4
|
-
import os.path
|
5
|
-
from pytest import raises, mark
|
6
|
-
import shutil
|
7
|
-
import subprocess
|
8
|
-
import tempfile
|
9
|
-
|
10
|
-
from teuthology.exceptions import BranchNotFoundError, CommitNotFoundError
|
11
|
-
from teuthology import repo_utils
|
12
|
-
from teuthology import parallel
|
13
|
-
repo_utils.log.setLevel(logging.WARNING)
|
14
|
-
|
15
|
-
|
16
|
-
class TestRepoUtils(object):
|
17
|
-
|
18
|
-
@classmethod
|
19
|
-
def setup_class(cls):
|
20
|
-
cls.temp_path = tempfile.mkdtemp(prefix='test_repo-')
|
21
|
-
cls.dest_path = cls.temp_path + '/empty_dest'
|
22
|
-
cls.src_path = cls.temp_path + '/empty_src'
|
23
|
-
|
24
|
-
if 'TEST_ONLINE' in os.environ:
|
25
|
-
cls.repo_url = 'https://github.com/ceph/empty.git'
|
26
|
-
cls.commit = '71245d8e454a06a38a00bff09d8f19607c72e8bf'
|
27
|
-
else:
|
28
|
-
cls.repo_url = 'file://' + cls.src_path
|
29
|
-
cls.commit = None
|
30
|
-
|
31
|
-
@classmethod
|
32
|
-
def teardown_class(cls):
|
33
|
-
shutil.rmtree(cls.temp_path)
|
34
|
-
|
35
|
-
def setup_method(self, method):
|
36
|
-
assert not os.path.exists(self.dest_path)
|
37
|
-
proc = subprocess.Popen(
|
38
|
-
('git', 'init', self.src_path),
|
39
|
-
stdout=subprocess.PIPE,
|
40
|
-
)
|
41
|
-
assert proc.wait() == 0
|
42
|
-
proc = subprocess.Popen(
|
43
|
-
('git', 'config', 'user.email', 'test@ceph.com'),
|
44
|
-
cwd=self.src_path,
|
45
|
-
stdout=subprocess.PIPE,
|
46
|
-
)
|
47
|
-
assert proc.wait() == 0
|
48
|
-
proc = subprocess.Popen(
|
49
|
-
('git', 'config', 'user.name', 'Test User'),
|
50
|
-
cwd=self.src_path,
|
51
|
-
stdout=subprocess.PIPE,
|
52
|
-
)
|
53
|
-
assert proc.wait() == 0
|
54
|
-
proc = subprocess.Popen(
|
55
|
-
('git', 'commit', '--allow-empty', '--allow-empty-message',
|
56
|
-
'--no-edit'),
|
57
|
-
cwd=self.src_path,
|
58
|
-
stdout=subprocess.PIPE,
|
59
|
-
)
|
60
|
-
assert proc.wait() == 0
|
61
|
-
if not self.commit:
|
62
|
-
result = subprocess.check_output(
|
63
|
-
'git rev-parse HEAD',
|
64
|
-
shell=True,
|
65
|
-
cwd=self.src_path,
|
66
|
-
).split()
|
67
|
-
assert result
|
68
|
-
self.commit = result[0].decode()
|
69
|
-
|
70
|
-
def teardown_method(self, method):
|
71
|
-
shutil.rmtree(self.dest_path, ignore_errors=True)
|
72
|
-
|
73
|
-
def test_clone_repo_existing_branch(self):
|
74
|
-
repo_utils.clone_repo(self.repo_url, self.dest_path, 'master', self.commit)
|
75
|
-
assert os.path.exists(self.dest_path)
|
76
|
-
|
77
|
-
def test_clone_repo_non_existing_branch(self):
|
78
|
-
with raises(BranchNotFoundError):
|
79
|
-
repo_utils.clone_repo(self.repo_url, self.dest_path, 'nobranch', self.commit)
|
80
|
-
assert not os.path.exists(self.dest_path)
|
81
|
-
|
82
|
-
def test_fetch_no_repo(self):
|
83
|
-
fake_dest_path = self.temp_path + '/not_a_repo'
|
84
|
-
assert not os.path.exists(fake_dest_path)
|
85
|
-
with raises(OSError):
|
86
|
-
repo_utils.fetch(fake_dest_path)
|
87
|
-
assert not os.path.exists(fake_dest_path)
|
88
|
-
|
89
|
-
def test_fetch_noop(self):
|
90
|
-
repo_utils.clone_repo(self.repo_url, self.dest_path, 'master', self.commit)
|
91
|
-
repo_utils.fetch(self.dest_path)
|
92
|
-
assert os.path.exists(self.dest_path)
|
93
|
-
|
94
|
-
def test_fetch_branch_no_repo(self):
|
95
|
-
fake_dest_path = self.temp_path + '/not_a_repo'
|
96
|
-
assert not os.path.exists(fake_dest_path)
|
97
|
-
with raises(OSError):
|
98
|
-
repo_utils.fetch_branch(fake_dest_path, 'master')
|
99
|
-
assert not os.path.exists(fake_dest_path)
|
100
|
-
|
101
|
-
def test_fetch_branch_fake_branch(self):
|
102
|
-
repo_utils.clone_repo(self.repo_url, self.dest_path, 'master', self.commit)
|
103
|
-
with raises(BranchNotFoundError):
|
104
|
-
repo_utils.fetch_branch(self.dest_path, 'nobranch')
|
105
|
-
|
106
|
-
@mark.parametrize('git_str',
|
107
|
-
["fatal: couldn't find remote ref",
|
108
|
-
"fatal: Couldn't find remote ref"])
|
109
|
-
@mock.patch('subprocess.Popen')
|
110
|
-
def test_fetch_branch_different_git_versions(self, mock_popen, git_str):
|
111
|
-
"""
|
112
|
-
Newer git versions return a lower case string
|
113
|
-
See: https://github.com/git/git/commit/0b9c3afdbfb629363
|
114
|
-
"""
|
115
|
-
branch_name = 'nobranch'
|
116
|
-
process_mock = mock.Mock()
|
117
|
-
attrs = {
|
118
|
-
'wait.return_value': 1,
|
119
|
-
'stdout.read.return_value': f"{git_str} {branch_name}".encode(),
|
120
|
-
}
|
121
|
-
process_mock.configure_mock(**attrs)
|
122
|
-
mock_popen.return_value = process_mock
|
123
|
-
with raises(BranchNotFoundError):
|
124
|
-
repo_utils.fetch_branch('', branch_name)
|
125
|
-
|
126
|
-
def test_enforce_existing_branch(self):
|
127
|
-
repo_utils.enforce_repo_state(self.repo_url, self.dest_path,
|
128
|
-
'master')
|
129
|
-
assert os.path.exists(self.dest_path)
|
130
|
-
|
131
|
-
def test_enforce_existing_commit(self):
|
132
|
-
repo_utils.enforce_repo_state(self.repo_url, self.dest_path,
|
133
|
-
'master', self.commit)
|
134
|
-
assert os.path.exists(self.dest_path)
|
135
|
-
|
136
|
-
def test_enforce_non_existing_branch(self):
|
137
|
-
with raises(BranchNotFoundError):
|
138
|
-
repo_utils.enforce_repo_state(self.repo_url, self.dest_path,
|
139
|
-
'blah', self.commit)
|
140
|
-
assert not os.path.exists(self.dest_path)
|
141
|
-
|
142
|
-
def test_enforce_non_existing_commit(self):
|
143
|
-
with raises(CommitNotFoundError):
|
144
|
-
repo_utils.enforce_repo_state(self.repo_url, self.dest_path,
|
145
|
-
'master', 'c69e90807d222c1719c45c8c758bf6fac3d985f1')
|
146
|
-
assert not os.path.exists(self.dest_path)
|
147
|
-
|
148
|
-
def test_enforce_multiple_calls_same_branch(self):
|
149
|
-
repo_utils.enforce_repo_state(self.repo_url, self.dest_path,
|
150
|
-
'master', self.commit)
|
151
|
-
assert os.path.exists(self.dest_path)
|
152
|
-
repo_utils.enforce_repo_state(self.repo_url, self.dest_path,
|
153
|
-
'master', self.commit)
|
154
|
-
assert os.path.exists(self.dest_path)
|
155
|
-
repo_utils.enforce_repo_state(self.repo_url, self.dest_path,
|
156
|
-
'master', self.commit)
|
157
|
-
assert os.path.exists(self.dest_path)
|
158
|
-
|
159
|
-
def test_enforce_multiple_calls_different_branches(self):
|
160
|
-
with raises(BranchNotFoundError):
|
161
|
-
repo_utils.enforce_repo_state(self.repo_url, self.dest_path,
|
162
|
-
'blah1')
|
163
|
-
assert not os.path.exists(self.dest_path)
|
164
|
-
repo_utils.enforce_repo_state(self.repo_url, self.dest_path,
|
165
|
-
'master', self.commit)
|
166
|
-
assert os.path.exists(self.dest_path)
|
167
|
-
repo_utils.enforce_repo_state(self.repo_url, self.dest_path,
|
168
|
-
'master', self.commit)
|
169
|
-
assert os.path.exists(self.dest_path)
|
170
|
-
with raises(BranchNotFoundError):
|
171
|
-
repo_utils.enforce_repo_state(self.repo_url, self.dest_path,
|
172
|
-
'blah2')
|
173
|
-
assert not os.path.exists(self.dest_path)
|
174
|
-
repo_utils.enforce_repo_state(self.repo_url, self.dest_path,
|
175
|
-
'master', self.commit)
|
176
|
-
assert os.path.exists(self.dest_path)
|
177
|
-
|
178
|
-
def test_enforce_invalid_branch(self):
|
179
|
-
with raises(ValueError):
|
180
|
-
repo_utils.enforce_repo_state(self.repo_url, self.dest_path, 'a b', self.commit)
|
181
|
-
|
182
|
-
def test_simultaneous_access(self):
|
183
|
-
count = 5
|
184
|
-
with parallel.parallel() as p:
|
185
|
-
for i in range(count):
|
186
|
-
p.spawn(repo_utils.enforce_repo_state, self.repo_url,
|
187
|
-
self.dest_path, 'master', self.commit)
|
188
|
-
for result in p:
|
189
|
-
assert result is None
|
190
|
-
|
191
|
-
def test_simultaneous_access_different_branches(self):
|
192
|
-
branches = [('master', self.commit), ('master', self.commit), ('nobranch', 'nocommit'),
|
193
|
-
('nobranch', 'nocommit'), ('master', self.commit), ('nobranch', 'nocommit')]
|
194
|
-
|
195
|
-
with parallel.parallel() as p:
|
196
|
-
for branch, commit in branches:
|
197
|
-
if branch == 'master':
|
198
|
-
p.spawn(repo_utils.enforce_repo_state, self.repo_url,
|
199
|
-
self.dest_path, branch, commit)
|
200
|
-
else:
|
201
|
-
dest_path = self.dest_path + '_' + branch
|
202
|
-
|
203
|
-
def func():
|
204
|
-
repo_utils.enforce_repo_state(
|
205
|
-
self.repo_url, dest_path,
|
206
|
-
branch, commit)
|
207
|
-
p.spawn(
|
208
|
-
raises,
|
209
|
-
BranchNotFoundError,
|
210
|
-
func,
|
211
|
-
)
|
212
|
-
for result in p:
|
213
|
-
pass
|
214
|
-
|
215
|
-
URLS_AND_DIRNAMES = [
|
216
|
-
('git@git.ceph.com/ceph-qa-suite.git', 'git.ceph.com_ceph-qa-suite'),
|
217
|
-
('git://git.ceph.com/ceph-qa-suite.git', 'git.ceph.com_ceph-qa-suite'),
|
218
|
-
('https://github.com/ceph/ceph', 'github.com_ceph_ceph'),
|
219
|
-
('https://github.com/liewegas/ceph.git', 'github.com_liewegas_ceph'),
|
220
|
-
('file:///my/dir/has/ceph.git', 'my_dir_has_ceph'),
|
221
|
-
]
|
222
|
-
|
223
|
-
@mark.parametrize("input_, expected", URLS_AND_DIRNAMES)
|
224
|
-
def test_url_to_dirname(self, input_, expected):
|
225
|
-
assert repo_utils.url_to_dirname(input_) == expected
|
teuthology/test/test_report.py
DELETED
@@ -1,77 +0,0 @@
|
|
1
|
-
import yaml
|
2
|
-
import json
|
3
|
-
from teuthology.test import fake_archive
|
4
|
-
from teuthology import report
|
5
|
-
|
6
|
-
|
7
|
-
class TestSerializer(object):
|
8
|
-
def setup(self):
|
9
|
-
self.archive = fake_archive.FakeArchive()
|
10
|
-
self.archive.setup()
|
11
|
-
self.archive_base = self.archive.archive_base
|
12
|
-
self.reporter = report.ResultsReporter(archive_base=self.archive_base)
|
13
|
-
|
14
|
-
def teardown(self):
|
15
|
-
self.archive.teardown()
|
16
|
-
|
17
|
-
def test_all_runs_one_run(self):
|
18
|
-
run_name = "test_all_runs"
|
19
|
-
yaml_path = "examples/3node_ceph.yaml"
|
20
|
-
job_count = 3
|
21
|
-
self.archive.create_fake_run(run_name, job_count, yaml_path)
|
22
|
-
assert [run_name] == self.reporter.serializer.all_runs
|
23
|
-
|
24
|
-
def test_all_runs_three_runs(self):
|
25
|
-
run_count = 3
|
26
|
-
runs = {}
|
27
|
-
for i in range(run_count):
|
28
|
-
run_name = "run #%s" % i
|
29
|
-
yaml_path = "examples/3node_ceph.yaml"
|
30
|
-
job_count = 3
|
31
|
-
job_ids = self.archive.create_fake_run(
|
32
|
-
run_name,
|
33
|
-
job_count,
|
34
|
-
yaml_path)
|
35
|
-
runs[run_name] = job_ids
|
36
|
-
assert sorted(runs.keys()) == sorted(self.reporter.serializer.all_runs)
|
37
|
-
|
38
|
-
def test_jobs_for_run(self):
|
39
|
-
run_name = "test_jobs_for_run"
|
40
|
-
yaml_path = "examples/3node_ceph.yaml"
|
41
|
-
job_count = 3
|
42
|
-
jobs = self.archive.create_fake_run(run_name, job_count, yaml_path)
|
43
|
-
job_ids = [str(job['job_id']) for job in jobs]
|
44
|
-
|
45
|
-
got_jobs = self.reporter.serializer.jobs_for_run(run_name)
|
46
|
-
assert sorted(job_ids) == sorted(got_jobs.keys())
|
47
|
-
|
48
|
-
def test_running_jobs_for_run(self):
|
49
|
-
run_name = "test_jobs_for_run"
|
50
|
-
yaml_path = "examples/3node_ceph.yaml"
|
51
|
-
job_count = 10
|
52
|
-
num_hung = 3
|
53
|
-
self.archive.create_fake_run(run_name, job_count, yaml_path,
|
54
|
-
num_hung=num_hung)
|
55
|
-
|
56
|
-
got_jobs = self.reporter.serializer.running_jobs_for_run(run_name)
|
57
|
-
assert len(got_jobs) == num_hung
|
58
|
-
|
59
|
-
def test_json_for_job(self):
|
60
|
-
run_name = "test_json_for_job"
|
61
|
-
yaml_path = "examples/3node_ceph.yaml"
|
62
|
-
job_count = 1
|
63
|
-
jobs = self.archive.create_fake_run(run_name, job_count, yaml_path)
|
64
|
-
job = jobs[0]
|
65
|
-
|
66
|
-
with open(yaml_path) as yaml_file:
|
67
|
-
obj_from_yaml = yaml.safe_load(yaml_file)
|
68
|
-
full_obj = obj_from_yaml.copy()
|
69
|
-
full_obj.update(job['info'])
|
70
|
-
full_obj.update(job['summary'])
|
71
|
-
|
72
|
-
out_json = self.reporter.serializer.json_for_job(
|
73
|
-
run_name, str(job['job_id']))
|
74
|
-
out_obj = json.loads(out_json)
|
75
|
-
assert full_obj == out_obj
|
76
|
-
|
77
|
-
|
teuthology/test/test_results.py
DELETED
@@ -1,155 +0,0 @@
|
|
1
|
-
import textwrap
|
2
|
-
from teuthology.config import config
|
3
|
-
from teuthology import results
|
4
|
-
from teuthology import report
|
5
|
-
|
6
|
-
from unittest.mock import patch, DEFAULT
|
7
|
-
|
8
|
-
|
9
|
-
class TestResultsEmail(object):
|
10
|
-
reference = {
|
11
|
-
'run_name': 'test_name',
|
12
|
-
'jobs': [
|
13
|
-
# Running
|
14
|
-
{'description': 'description for job with name test_name',
|
15
|
-
'job_id': 30481,
|
16
|
-
'name': 'test_name',
|
17
|
-
'log_href': 'http://qa-proxy.ceph.com/teuthology/test_name/30481/teuthology.log', # noqa
|
18
|
-
'owner': 'job@owner',
|
19
|
-
'duration': None,
|
20
|
-
'status': 'running',
|
21
|
-
},
|
22
|
-
# Waiting
|
23
|
-
{'description': 'description for job with name test_name',
|
24
|
-
'job_id': 62965,
|
25
|
-
'name': 'test_name',
|
26
|
-
'log_href': 'http://qa-proxy.ceph.com/teuthology/test_name/30481/teuthology.log', # noqa
|
27
|
-
'owner': 'job@owner',
|
28
|
-
'duration': None,
|
29
|
-
'status': 'waiting',
|
30
|
-
},
|
31
|
-
# Queued
|
32
|
-
{'description': 'description for job with name test_name',
|
33
|
-
'job_id': 79063,
|
34
|
-
'name': 'test_name',
|
35
|
-
'log_href': 'http://qa-proxy.ceph.com/teuthology/test_name/30481/teuthology.log', # noqa
|
36
|
-
'owner': 'job@owner',
|
37
|
-
'duration': None,
|
38
|
-
'status': 'queued',
|
39
|
-
},
|
40
|
-
# Failed
|
41
|
-
{'description': 'description for job with name test_name',
|
42
|
-
'job_id': 88979,
|
43
|
-
'name': 'test_name',
|
44
|
-
'log_href': 'http://qa-proxy.ceph.com/teuthology/test_name/88979/teuthology.log', # noqa
|
45
|
-
'owner': 'job@owner',
|
46
|
-
'duration': 35190,
|
47
|
-
'success': False,
|
48
|
-
'status': 'fail',
|
49
|
-
'failure_reason': 'Failure reason!',
|
50
|
-
},
|
51
|
-
# Dead
|
52
|
-
{'description': 'description for job with name test_name',
|
53
|
-
'job_id': 69152,
|
54
|
-
'name': 'test_name',
|
55
|
-
'log_href': 'http://qa-proxy.ceph.com/teuthology/test_name/69152/teuthology.log', # noqa
|
56
|
-
'owner': 'job@owner',
|
57
|
-
'duration': 5225,
|
58
|
-
'success': False,
|
59
|
-
'status': 'dead',
|
60
|
-
'failure_reason': 'Dead reason!',
|
61
|
-
},
|
62
|
-
# Passed
|
63
|
-
{'description': 'description for job with name test_name',
|
64
|
-
'job_id': 68369,
|
65
|
-
'name': 'test_name',
|
66
|
-
'log_href': 'http://qa-proxy.ceph.com/teuthology/test_name/68369/teuthology.log', # noqa
|
67
|
-
'owner': 'job@owner',
|
68
|
-
'duration': 33771,
|
69
|
-
'success': True,
|
70
|
-
'status': 'pass',
|
71
|
-
},
|
72
|
-
],
|
73
|
-
'subject': '1 fail, 1 dead, 1 running, 1 waiting, 1 queued, 1 pass in test_name', # noqa
|
74
|
-
'body': textwrap.dedent("""
|
75
|
-
Test Run: test_name
|
76
|
-
=================================================================
|
77
|
-
info: http://example.com/test_name/
|
78
|
-
logs: http://qa-proxy.ceph.com/teuthology/test_name/
|
79
|
-
failed: 1
|
80
|
-
dead: 1
|
81
|
-
running: 1
|
82
|
-
waiting: 1
|
83
|
-
queued: 1
|
84
|
-
passed: 1
|
85
|
-
|
86
|
-
|
87
|
-
Fail
|
88
|
-
=================================================================
|
89
|
-
[88979] description for job with name test_name
|
90
|
-
-----------------------------------------------------------------
|
91
|
-
time: 09:46:30
|
92
|
-
info: http://example.com/test_name/88979/
|
93
|
-
log: http://qa-proxy.ceph.com/teuthology/test_name/88979/
|
94
|
-
|
95
|
-
Failure reason!
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
Dead
|
100
|
-
=================================================================
|
101
|
-
[69152] description for job with name test_name
|
102
|
-
-----------------------------------------------------------------
|
103
|
-
time: 01:27:05
|
104
|
-
info: http://example.com/test_name/69152/
|
105
|
-
log: http://qa-proxy.ceph.com/teuthology/test_name/69152/
|
106
|
-
|
107
|
-
Dead reason!
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
Running
|
112
|
-
=================================================================
|
113
|
-
[30481] description for job with name test_name
|
114
|
-
info: http://example.com/test_name/30481/
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
Waiting
|
119
|
-
=================================================================
|
120
|
-
[62965] description for job with name test_name
|
121
|
-
info: http://example.com/test_name/62965/
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
Queued
|
126
|
-
=================================================================
|
127
|
-
[79063] description for job with name test_name
|
128
|
-
info: http://example.com/test_name/79063/
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
Pass
|
133
|
-
=================================================================
|
134
|
-
[68369] description for job with name test_name
|
135
|
-
time: 09:22:51
|
136
|
-
info: http://example.com/test_name/68369/
|
137
|
-
""").strip(),
|
138
|
-
}
|
139
|
-
|
140
|
-
def setup(self):
|
141
|
-
config.results_ui_server = "http://example.com/"
|
142
|
-
config.archive_server = "http://qa-proxy.ceph.com/teuthology/"
|
143
|
-
|
144
|
-
def test_build_email_body(self):
|
145
|
-
run_name = self.reference['run_name']
|
146
|
-
with patch.multiple(
|
147
|
-
report,
|
148
|
-
ResultsReporter=DEFAULT,
|
149
|
-
):
|
150
|
-
reporter = report.ResultsReporter()
|
151
|
-
reporter.get_jobs.return_value = self.reference['jobs']
|
152
|
-
(subject, body) = results.build_email_body(
|
153
|
-
run_name, _reporter=reporter)
|
154
|
-
assert subject == self.reference['subject']
|
155
|
-
assert body == self.reference['body']
|