teuthology 1.1.0__py3-none-any.whl → 1.2.1__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.
Files changed (170) hide show
  1. scripts/describe.py +1 -0
  2. scripts/dispatcher.py +55 -26
  3. scripts/exporter.py +18 -0
  4. scripts/lock.py +1 -1
  5. scripts/node_cleanup.py +58 -0
  6. scripts/openstack.py +9 -9
  7. scripts/results.py +12 -11
  8. scripts/schedule.py +4 -0
  9. scripts/suite.py +57 -16
  10. scripts/supervisor.py +44 -0
  11. scripts/update_inventory.py +10 -4
  12. teuthology/__init__.py +24 -26
  13. teuthology/beanstalk.py +4 -3
  14. teuthology/config.py +16 -6
  15. teuthology/contextutil.py +18 -14
  16. teuthology/describe_tests.py +25 -18
  17. teuthology/dispatcher/__init__.py +210 -35
  18. teuthology/dispatcher/supervisor.py +140 -58
  19. teuthology/exceptions.py +43 -0
  20. teuthology/exporter.py +347 -0
  21. teuthology/kill.py +76 -81
  22. teuthology/lock/cli.py +3 -3
  23. teuthology/lock/ops.py +135 -61
  24. teuthology/lock/query.py +61 -44
  25. teuthology/ls.py +1 -1
  26. teuthology/misc.py +61 -75
  27. teuthology/nuke/__init__.py +12 -353
  28. teuthology/openstack/__init__.py +4 -3
  29. teuthology/openstack/openstack-centos-7.0-user-data.txt +1 -1
  30. teuthology/openstack/openstack-centos-7.1-user-data.txt +1 -1
  31. teuthology/openstack/openstack-centos-7.2-user-data.txt +1 -1
  32. teuthology/openstack/openstack-debian-8.0-user-data.txt +1 -1
  33. teuthology/openstack/openstack-opensuse-42.1-user-data.txt +1 -1
  34. teuthology/openstack/openstack-teuthology.cron +0 -1
  35. teuthology/orchestra/cluster.py +49 -7
  36. teuthology/orchestra/connection.py +17 -4
  37. teuthology/orchestra/console.py +111 -50
  38. teuthology/orchestra/daemon/cephadmunit.py +15 -2
  39. teuthology/orchestra/daemon/state.py +8 -1
  40. teuthology/orchestra/daemon/systemd.py +4 -4
  41. teuthology/orchestra/opsys.py +30 -11
  42. teuthology/orchestra/remote.py +405 -338
  43. teuthology/orchestra/run.py +3 -3
  44. teuthology/packaging.py +19 -16
  45. teuthology/provision/__init__.py +30 -10
  46. teuthology/provision/cloud/openstack.py +12 -6
  47. teuthology/provision/cloud/util.py +1 -2
  48. teuthology/provision/downburst.py +4 -3
  49. teuthology/provision/fog.py +68 -20
  50. teuthology/provision/openstack.py +5 -4
  51. teuthology/provision/pelagos.py +1 -1
  52. teuthology/repo_utils.py +43 -13
  53. teuthology/report.py +57 -35
  54. teuthology/results.py +5 -3
  55. teuthology/run.py +13 -14
  56. teuthology/run_tasks.py +27 -43
  57. teuthology/schedule.py +4 -3
  58. teuthology/scrape.py +28 -22
  59. teuthology/suite/__init__.py +74 -45
  60. teuthology/suite/build_matrix.py +34 -24
  61. teuthology/suite/fragment-merge.lua +105 -0
  62. teuthology/suite/matrix.py +31 -2
  63. teuthology/suite/merge.py +175 -0
  64. teuthology/suite/placeholder.py +6 -9
  65. teuthology/suite/run.py +175 -100
  66. teuthology/suite/util.py +64 -218
  67. teuthology/task/__init__.py +1 -1
  68. teuthology/task/ansible.py +101 -32
  69. teuthology/task/buildpackages.py +2 -2
  70. teuthology/task/ceph_ansible.py +13 -6
  71. teuthology/task/cephmetrics.py +2 -1
  72. teuthology/task/clock.py +33 -14
  73. teuthology/task/exec.py +18 -0
  74. teuthology/task/hadoop.py +2 -2
  75. teuthology/task/install/__init__.py +29 -7
  76. teuthology/task/install/bin/adjust-ulimits +16 -0
  77. teuthology/task/install/bin/daemon-helper +114 -0
  78. teuthology/task/install/bin/stdin-killer +263 -0
  79. teuthology/task/install/deb.py +1 -1
  80. teuthology/task/install/rpm.py +17 -5
  81. teuthology/task/install/util.py +3 -3
  82. teuthology/task/internal/__init__.py +41 -10
  83. teuthology/task/internal/edit_sudoers.sh +10 -0
  84. teuthology/task/internal/lock_machines.py +2 -9
  85. teuthology/task/internal/redhat.py +31 -1
  86. teuthology/task/internal/syslog.py +31 -8
  87. teuthology/task/kernel.py +152 -145
  88. teuthology/task/lockfile.py +1 -1
  89. teuthology/task/mpi.py +10 -10
  90. teuthology/task/pcp.py +1 -1
  91. teuthology/task/selinux.py +16 -8
  92. teuthology/task/ssh_keys.py +4 -4
  93. teuthology/timer.py +3 -3
  94. teuthology/util/loggerfile.py +19 -0
  95. teuthology/util/scanner.py +159 -0
  96. teuthology/util/sentry.py +52 -0
  97. teuthology/util/time.py +52 -0
  98. teuthology-1.2.1.data/scripts/adjust-ulimits +16 -0
  99. teuthology-1.2.1.data/scripts/daemon-helper +114 -0
  100. teuthology-1.2.1.data/scripts/stdin-killer +263 -0
  101. teuthology-1.2.1.dist-info/METADATA +88 -0
  102. teuthology-1.2.1.dist-info/RECORD +168 -0
  103. {teuthology-1.1.0.dist-info → teuthology-1.2.1.dist-info}/WHEEL +1 -1
  104. {teuthology-1.1.0.dist-info → teuthology-1.2.1.dist-info}/entry_points.txt +3 -2
  105. scripts/nuke.py +0 -47
  106. scripts/worker.py +0 -37
  107. teuthology/lock/test/__init__.py +0 -0
  108. teuthology/lock/test/test_lock.py +0 -7
  109. teuthology/nuke/actions.py +0 -456
  110. teuthology/openstack/test/__init__.py +0 -0
  111. teuthology/openstack/test/openstack-integration.py +0 -286
  112. teuthology/openstack/test/test_config.py +0 -35
  113. teuthology/openstack/test/test_openstack.py +0 -1695
  114. teuthology/orchestra/test/__init__.py +0 -0
  115. teuthology/orchestra/test/integration/__init__.py +0 -0
  116. teuthology/orchestra/test/integration/test_integration.py +0 -94
  117. teuthology/orchestra/test/test_cluster.py +0 -240
  118. teuthology/orchestra/test/test_connection.py +0 -106
  119. teuthology/orchestra/test/test_console.py +0 -217
  120. teuthology/orchestra/test/test_opsys.py +0 -404
  121. teuthology/orchestra/test/test_remote.py +0 -185
  122. teuthology/orchestra/test/test_run.py +0 -286
  123. teuthology/orchestra/test/test_systemd.py +0 -54
  124. teuthology/orchestra/test/util.py +0 -12
  125. teuthology/task/tests/__init__.py +0 -110
  126. teuthology/task/tests/test_locking.py +0 -25
  127. teuthology/task/tests/test_run.py +0 -40
  128. teuthology/test/__init__.py +0 -0
  129. teuthology/test/fake_archive.py +0 -107
  130. teuthology/test/fake_fs.py +0 -92
  131. teuthology/test/integration/__init__.py +0 -0
  132. teuthology/test/integration/test_suite.py +0 -86
  133. teuthology/test/task/__init__.py +0 -205
  134. teuthology/test/task/test_ansible.py +0 -624
  135. teuthology/test/task/test_ceph_ansible.py +0 -176
  136. teuthology/test/task/test_console_log.py +0 -88
  137. teuthology/test/task/test_install.py +0 -337
  138. teuthology/test/task/test_internal.py +0 -57
  139. teuthology/test/task/test_kernel.py +0 -243
  140. teuthology/test/task/test_pcp.py +0 -379
  141. teuthology/test/task/test_selinux.py +0 -35
  142. teuthology/test/test_config.py +0 -189
  143. teuthology/test/test_contextutil.py +0 -68
  144. teuthology/test/test_describe_tests.py +0 -316
  145. teuthology/test/test_email_sleep_before_teardown.py +0 -81
  146. teuthology/test/test_exit.py +0 -97
  147. teuthology/test/test_get_distro.py +0 -47
  148. teuthology/test/test_get_distro_version.py +0 -47
  149. teuthology/test/test_get_multi_machine_types.py +0 -27
  150. teuthology/test/test_job_status.py +0 -60
  151. teuthology/test/test_ls.py +0 -48
  152. teuthology/test/test_misc.py +0 -391
  153. teuthology/test/test_nuke.py +0 -290
  154. teuthology/test/test_packaging.py +0 -763
  155. teuthology/test/test_parallel.py +0 -28
  156. teuthology/test/test_repo_utils.py +0 -225
  157. teuthology/test/test_report.py +0 -77
  158. teuthology/test/test_results.py +0 -155
  159. teuthology/test/test_run.py +0 -239
  160. teuthology/test/test_safepath.py +0 -55
  161. teuthology/test/test_schedule.py +0 -45
  162. teuthology/test/test_scrape.py +0 -167
  163. teuthology/test/test_timer.py +0 -80
  164. teuthology/test/test_vps_os_vers_parameter_checking.py +0 -84
  165. teuthology/test/test_worker.py +0 -303
  166. teuthology/worker.py +0 -354
  167. teuthology-1.1.0.dist-info/METADATA +0 -76
  168. teuthology-1.1.0.dist-info/RECORD +0 -213
  169. {teuthology-1.1.0.dist-info → teuthology-1.2.1.dist-info}/LICENSE +0 -0
  170. {teuthology-1.1.0.dist-info → teuthology-1.2.1.dist-info}/top_level.txt +0 -0
@@ -1,189 +0,0 @@
1
- import pytest
2
-
3
- from teuthology import config
4
-
5
-
6
- class TestYamlConfig(object):
7
- def setup(self):
8
- self.test_class = config.YamlConfig
9
-
10
- def test_set_multiple(self):
11
- conf_obj = self.test_class()
12
- conf_obj.foo = 'foo'
13
- conf_obj.bar = 'bar'
14
- assert conf_obj.foo == 'foo'
15
- assert conf_obj.bar == 'bar'
16
- assert conf_obj.to_dict()['foo'] == 'foo'
17
-
18
- def test_from_dict(self):
19
- in_dict = dict(foo='bar')
20
- conf_obj = self.test_class.from_dict(in_dict)
21
- assert conf_obj.foo == 'bar'
22
-
23
- def test_contains(self):
24
- in_dict = dict(foo='bar')
25
- conf_obj = self.test_class.from_dict(in_dict)
26
- conf_obj.bar = "foo"
27
- assert "bar" in conf_obj
28
- assert "foo" in conf_obj
29
- assert "baz" not in conf_obj
30
-
31
- def test_to_dict(self):
32
- in_dict = dict(foo='bar')
33
- conf_obj = self.test_class.from_dict(in_dict)
34
- assert conf_obj.to_dict() == in_dict
35
-
36
- def test_from_str(self):
37
- in_str = "foo: bar"
38
- conf_obj = self.test_class.from_str(in_str)
39
- assert conf_obj.foo == 'bar'
40
-
41
- def test_to_str(self):
42
- in_str = "foo: bar"
43
- conf_obj = self.test_class.from_str(in_str)
44
- assert conf_obj.to_str() == in_str
45
-
46
- def test_update(self):
47
- conf_obj = self.test_class(dict())
48
- conf_obj.foo = 'foo'
49
- conf_obj.bar = 'bar'
50
- conf_obj.update(dict(bar='baz'))
51
- assert conf_obj.foo == 'foo'
52
- assert conf_obj.bar == 'baz'
53
-
54
- def test_delattr(self):
55
- conf_obj = self.test_class()
56
- conf_obj.foo = 'bar'
57
- assert conf_obj.foo == 'bar'
58
- del conf_obj.foo
59
- assert conf_obj.foo is None
60
-
61
- def test_assignment(self):
62
- conf_obj = self.test_class()
63
- conf_obj["foo"] = "bar"
64
- assert conf_obj["foo"] == "bar"
65
- assert conf_obj.foo == "bar"
66
-
67
- def test_used_with_update(self):
68
- d = dict()
69
- conf_obj = self.test_class.from_dict({"foo": "bar"})
70
- d.update(conf_obj)
71
- assert d["foo"] == "bar"
72
-
73
- def test_get(self):
74
- conf_obj = self.test_class()
75
- assert conf_obj.get('foo') is None
76
- assert conf_obj.get('foo', 'bar') == 'bar'
77
- conf_obj.foo = 'baz'
78
- assert conf_obj.get('foo') == 'baz'
79
-
80
-
81
- class TestTeuthologyConfig(TestYamlConfig):
82
- def setup(self):
83
- self.test_class = config.TeuthologyConfig
84
-
85
- def test_get_ceph_git_base_default(self):
86
- conf_obj = self.test_class()
87
- conf_obj.yaml_path = ''
88
- conf_obj.load()
89
- assert conf_obj.ceph_git_base_url == "https://github.com/ceph/"
90
-
91
- def test_set_ceph_git_base_via_private(self):
92
- conf_obj = self.test_class()
93
- conf_obj._conf['ceph_git_base_url'] = \
94
- "git://git.ceph.com/"
95
- assert conf_obj.ceph_git_base_url == "git://git.ceph.com/"
96
-
97
- def test_get_reserve_machines_default(self):
98
- conf_obj = self.test_class()
99
- conf_obj.yaml_path = ''
100
- conf_obj.load()
101
- assert conf_obj.reserve_machines == 5
102
-
103
- def test_set_reserve_machines_via_private(self):
104
- conf_obj = self.test_class()
105
- conf_obj._conf['reserve_machines'] = 2
106
- assert conf_obj.reserve_machines == 2
107
-
108
- def test_set_nonstandard(self):
109
- conf_obj = self.test_class()
110
- conf_obj.something = 'something else'
111
- assert conf_obj.something == 'something else'
112
-
113
-
114
- class TestJobConfig(TestYamlConfig):
115
- def setup(self):
116
- self.test_class = config.JobConfig
117
-
118
-
119
- class TestFakeNamespace(TestYamlConfig):
120
- def setup(self):
121
- self.test_class = config.FakeNamespace
122
-
123
- def test_docopt_dict(self):
124
- """
125
- Tests if a dict in the format that docopt returns can
126
- be parsed correctly.
127
- """
128
- d = {
129
- "--verbose": True,
130
- "--an-option": "some_option",
131
- "<an_arg>": "the_arg",
132
- "something": "some_thing",
133
- }
134
- conf_obj = self.test_class(d)
135
- assert conf_obj.verbose
136
- assert conf_obj.an_option == "some_option"
137
- assert conf_obj.an_arg == "the_arg"
138
- assert conf_obj.something == "some_thing"
139
-
140
- def test_config(self):
141
- """
142
- Tests that a teuthology_config property is automatically added
143
- to the conf_obj
144
- """
145
- conf_obj = self.test_class(dict(foo="bar"))
146
- assert conf_obj["foo"] == "bar"
147
- assert conf_obj.foo == "bar"
148
- assert conf_obj.teuthology_config.get("fake key") is None
149
-
150
- def test_getattr(self):
151
- conf_obj = self.test_class.from_dict({"foo": "bar"})
152
- result = getattr(conf_obj, "not_there", "default")
153
- assert result == "default"
154
- result = getattr(conf_obj, "foo")
155
- assert result == "bar"
156
-
157
- def test_none(self):
158
- conf_obj = self.test_class.from_dict(dict(null=None))
159
- assert conf_obj.null is None
160
-
161
- def test_delattr(self):
162
- conf_obj = self.test_class()
163
- conf_obj.foo = 'bar'
164
- assert conf_obj.foo == 'bar'
165
- del conf_obj.foo
166
- with pytest.raises(AttributeError):
167
- conf_obj.foo
168
-
169
- def test_to_str(self):
170
- in_str = "foo: bar"
171
- conf_obj = self.test_class.from_str(in_str)
172
- assert conf_obj.to_str() == "{'foo': 'bar'}"
173
-
174
- def test_multiple_access(self):
175
- """
176
- Test that config.config and FakeNamespace.teuthology_config reflect
177
- each others' modifications
178
- """
179
- in_str = "foo: bar"
180
- conf_obj = self.test_class.from_str(in_str)
181
- assert config.config.get('test_key_1') is None
182
- assert conf_obj.teuthology_config.get('test_key_1') is None
183
- config.config.test_key_1 = 'test value'
184
- assert conf_obj.teuthology_config['test_key_1'] == 'test value'
185
-
186
- assert config.config.get('test_key_2') is None
187
- assert conf_obj.teuthology_config.get('test_key_2') is None
188
- conf_obj.teuthology_config['test_key_2'] = 'test value'
189
- assert config.config['test_key_2'] == 'test value'
@@ -1,68 +0,0 @@
1
- from pytest import raises
2
- from teuthology import contextutil
3
- from logging import ERROR
4
-
5
-
6
- class TestSafeWhile(object):
7
-
8
- def setup(self):
9
- contextutil.log.setLevel(ERROR)
10
- self.fake_sleep = lambda s: True
11
- self.s_while = contextutil.safe_while
12
-
13
- def test_6_5_10_deal(self):
14
- with raises(contextutil.MaxWhileTries):
15
- with self.s_while(_sleeper=self.fake_sleep) as proceed:
16
- while proceed():
17
- pass
18
-
19
- def test_6_0_1_deal(self):
20
- with raises(contextutil.MaxWhileTries) as error:
21
- with self.s_while(
22
- tries=1,
23
- _sleeper=self.fake_sleep
24
- ) as proceed:
25
- while proceed():
26
- pass
27
-
28
- assert 'waiting for 6 seconds' in str(error)
29
-
30
- def test_1_0_10_deal(self):
31
- with raises(contextutil.MaxWhileTries) as error:
32
- with self.s_while(
33
- sleep=1,
34
- _sleeper=self.fake_sleep
35
- ) as proceed:
36
- while proceed():
37
- pass
38
-
39
- assert 'waiting for 10 seconds' in str(error)
40
-
41
- def test_6_1_10_deal(self):
42
- with raises(contextutil.MaxWhileTries) as error:
43
- with self.s_while(
44
- increment=1,
45
- _sleeper=self.fake_sleep
46
- ) as proceed:
47
- while proceed():
48
- pass
49
-
50
- assert 'waiting for 105 seconds' in str(error)
51
-
52
- def test_action(self):
53
- with raises(contextutil.MaxWhileTries) as error:
54
- with self.s_while(
55
- action='doing the thing',
56
- _sleeper=self.fake_sleep
57
- ) as proceed:
58
- while proceed():
59
- pass
60
-
61
- assert "'doing the thing' reached maximum tries" in str(error)
62
-
63
- def test_no_raise(self):
64
- with self.s_while(_raise=False, _sleeper=self.fake_sleep) as proceed:
65
- while proceed():
66
- pass
67
-
68
- assert True
@@ -1,316 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- import pytest
3
-
4
- from teuthology.test.fake_fs import make_fake_fstools
5
- from teuthology.describe_tests import (tree_with_info, extract_info,
6
- get_combinations)
7
- from teuthology.exceptions import ParseError
8
- from mock import MagicMock, patch
9
-
10
- realistic_fs = {
11
- 'basic': {
12
- '%': None,
13
- 'base': {
14
- 'install.yaml':
15
- """meta:
16
- - desc: install ceph
17
- install:
18
- """
19
- },
20
- 'clusters': {
21
- 'fixed-1.yaml':
22
- """meta:
23
- - desc: single node cluster
24
- roles:
25
- - [osd.0, osd.1, osd.2, mon.a, mon.b, mon.c, client.0]
26
- """,
27
- 'fixed-2.yaml':
28
- """meta:
29
- - desc: couple node cluster
30
- roles:
31
- - [osd.0, osd.1, osd.2, mon.a, mon.b, mon.c]
32
- - [client.0]
33
- """,
34
- 'fixed-3.yaml':
35
- """meta:
36
- - desc: triple node cluster
37
- roles:
38
- - [osd.0, osd.1, osd.2, mon.a, mon.b, mon.c]
39
- - [client.0]
40
- - [client.1]
41
- """
42
- },
43
- 'workloads': {
44
- 'rbd_api_tests_old_format.yaml':
45
- """meta:
46
- - desc: c/c++ librbd api tests with format 1 images
47
- rbd_features: none
48
- overrides:
49
- ceph:
50
- conf:
51
- client:
52
- rbd default format: 1
53
- tasks:
54
- - workunit:
55
- env:
56
- RBD_FEATURES: 0
57
- clients:
58
- client.0:
59
- - rbd/test_librbd.sh
60
- """,
61
- 'rbd_api_tests.yaml':
62
- """meta:
63
- - desc: c/c++ librbd api tests with default settings
64
- rbd_features: default
65
- tasks:
66
- - workunit:
67
- clients:
68
- client.0:
69
- - rbd/test_librbd.sh
70
- """,
71
- },
72
- },
73
- }
74
-
75
-
76
- expected_tree = """├── %
77
- ├── base
78
- │ └── install.yaml
79
- ├── clusters
80
- │ ├── fixed-1.yaml
81
- │ ├── fixed-2.yaml
82
- │ └── fixed-3.yaml
83
- └── workloads
84
- ├── rbd_api_tests.yaml
85
- └── rbd_api_tests_old_format.yaml""".split('\n')
86
-
87
-
88
- expected_facets = [
89
- '',
90
- '',
91
- 'base',
92
- '',
93
- 'clusters',
94
- 'clusters',
95
- 'clusters',
96
- '',
97
- 'workloads',
98
- 'workloads',
99
- ]
100
-
101
-
102
- expected_desc = [
103
- '',
104
- '',
105
- 'install ceph',
106
- '',
107
- 'single node cluster',
108
- 'couple node cluster',
109
- 'triple node cluster',
110
- '',
111
- 'c/c++ librbd api tests with default settings',
112
- 'c/c++ librbd api tests with format 1 images',
113
- ]
114
-
115
-
116
- expected_rbd_features = [
117
- '',
118
- '',
119
- '',
120
- '',
121
- '',
122
- '',
123
- '',
124
- '',
125
- 'default',
126
- 'none',
127
- ]
128
-
129
-
130
- class TestDescribeTests(object):
131
-
132
- def setup(self):
133
- self.mocks = dict()
134
- self.patchers = dict()
135
- exists, listdir, isfile, isdir, open = make_fake_fstools(realistic_fs)
136
- for ppoint, fn in {
137
- 'os.listdir': listdir,
138
- 'os.path.isdir': isdir,
139
- 'teuthology.describe_tests.open': open,
140
- 'os.path.exists': exists,
141
- 'os.listdir': listdir,
142
- 'os.path.isfile': isfile,
143
- }.items():
144
- mockobj = MagicMock()
145
- patcher = patch(ppoint, mockobj)
146
- mockobj.side_effect = fn
147
- patcher.start()
148
- self.mocks[ppoint] = mockobj
149
- self.patchers[ppoint] = patcher
150
-
151
- def stop_patchers(self):
152
- for patcher in self.patchers.values():
153
- patcher.stop()
154
-
155
- def teardown(self):
156
- self.stop_patchers()
157
-
158
- @staticmethod
159
- def assert_expected_combo_headers(headers):
160
- assert headers == (['subsuite depth 0'] +
161
- sorted(set(filter(bool, expected_facets))))
162
-
163
- def test_no_filters(self):
164
- rows = tree_with_info('basic', [], False, '', [])
165
- assert rows == [[x] for x in expected_tree]
166
-
167
- def test_single_filter(self):
168
- rows = tree_with_info('basic', ['desc'], False, '', [])
169
- assert rows == [list(_) for _ in zip(expected_tree, expected_desc)]
170
-
171
- rows = tree_with_info('basic', ['rbd_features'], False, '', [])
172
- assert rows == [list(_) for _ in zip(expected_tree, expected_rbd_features)]
173
-
174
- def test_single_filter_with_facets(self):
175
- rows = tree_with_info('basic', ['desc'], True, '', [])
176
- assert rows == [list(_) for _ in zip(expected_tree, expected_facets,
177
- expected_desc)]
178
-
179
- rows = tree_with_info('basic', ['rbd_features'], True, '', [])
180
- assert rows == [list(_) for _ in zip(expected_tree, expected_facets,
181
- expected_rbd_features)]
182
-
183
- def test_no_matching(self):
184
- rows = tree_with_info('basic', ['extra'], False, '', [])
185
- assert rows == [list(_) for _ in zip(expected_tree, [''] * len(expected_tree))]
186
-
187
- rows = tree_with_info('basic', ['extra'], True, '', [])
188
- assert rows == [list(_) for _ in zip(expected_tree, expected_facets,
189
- [''] * len(expected_tree))]
190
-
191
- def test_multiple_filters(self):
192
- rows = tree_with_info('basic', ['desc', 'rbd_features'], False, '', [])
193
- assert rows == [list(_) for _ in zip(expected_tree,
194
- expected_desc,
195
- expected_rbd_features)]
196
-
197
- rows = tree_with_info('basic', ['rbd_features', 'desc'], False, '', [])
198
- assert rows == [list(_) for _ in zip(expected_tree,
199
- expected_rbd_features,
200
- expected_desc)]
201
-
202
- def test_multiple_filters_with_facets(self):
203
- rows = tree_with_info('basic', ['desc', 'rbd_features'], True, '', [])
204
- assert rows == [list(_) for _ in zip(expected_tree,
205
- expected_facets,
206
- expected_desc,
207
- expected_rbd_features)]
208
-
209
- rows = tree_with_info('basic', ['rbd_features', 'desc'], True, '', [])
210
- assert rows == [list(_) for _ in zip(expected_tree,
211
- expected_facets,
212
- expected_rbd_features,
213
- expected_desc)]
214
-
215
- def test_combinations_only_facets(self):
216
- headers, rows = get_combinations('basic',
217
- fields=[], subset=None, limit=1,
218
- filter_in=None, filter_out=None, filter_all=None,
219
- include_facet=True)
220
- self.assert_expected_combo_headers(headers)
221
- assert rows == [['basic', 'install', 'fixed-1', 'rbd_api_tests']]
222
-
223
- def test_combinations_desc_features(self):
224
- headers, rows = get_combinations('basic',
225
- fields=['desc', 'rbd_features'], subset=None, limit=1,
226
- filter_in=None, filter_out=None, filter_all=None,
227
- include_facet=False)
228
- assert headers == ['desc', 'rbd_features']
229
- descriptions = '\n'.join([
230
- 'install ceph',
231
- 'single node cluster',
232
- 'c/c++ librbd api tests with default settings',
233
- ])
234
- assert rows == [[descriptions, 'default']]
235
-
236
- def test_combinations_filter_in(self):
237
- headers, rows = get_combinations('basic',
238
- fields=[], subset=None, limit=0,
239
- filter_in=['old_format'], filter_out=None, filter_all=None,
240
- include_facet=True)
241
- self.assert_expected_combo_headers(headers)
242
- assert rows == [
243
- ['basic', 'install', 'fixed-1', 'rbd_api_tests_old_format'],
244
- ['basic', 'install', 'fixed-2', 'rbd_api_tests_old_format'],
245
- ['basic', 'install', 'fixed-3', 'rbd_api_tests_old_format'],
246
- ]
247
-
248
- def test_combinations_filter_out(self):
249
- headers, rows = get_combinations('basic',
250
- fields=[], subset=None, limit=0,
251
- filter_in=None, filter_out=['old_format'], filter_all=None,
252
- include_facet=True)
253
- self.assert_expected_combo_headers(headers)
254
- assert rows == [
255
- ['basic', 'install', 'fixed-1', 'rbd_api_tests'],
256
- ['basic', 'install', 'fixed-2', 'rbd_api_tests'],
257
- ['basic', 'install', 'fixed-3', 'rbd_api_tests'],
258
- ]
259
-
260
- def test_combinations_filter_all(self):
261
- headers, rows = get_combinations('basic',
262
- fields=[], subset=None, limit=0,
263
- filter_in=None, filter_out=None,
264
- filter_all=['fixed-2', 'old_format'],
265
- include_facet=True)
266
- self.assert_expected_combo_headers(headers)
267
- assert rows == [
268
- ['basic', 'install', 'fixed-2', 'rbd_api_tests_old_format']
269
- ]
270
-
271
-
272
- @patch('teuthology.describe_tests.open')
273
- @patch('os.path.isdir')
274
- def test_extract_info_dir(m_isdir, m_open):
275
- simple_fs = {'a': {'b.yaml': 'meta: [{foo: c}]'}}
276
- _, _, _, m_isdir.side_effect, m_open.side_effect = \
277
- make_fake_fstools(simple_fs)
278
- info = extract_info('a', [])
279
- assert info == {}
280
-
281
- info = extract_info('a', ['foo', 'bar'])
282
- assert info == {'foo': '', 'bar': ''}
283
-
284
- info = extract_info('a/b.yaml', ['foo', 'bar'])
285
- assert info == {'foo': 'c', 'bar': ''}
286
-
287
-
288
- @patch('teuthology.describe_tests.open')
289
- @patch('os.path.isdir')
290
- def check_parse_error(fs, m_isdir, m_open):
291
- _, _, _, m_isdir.side_effect, m_open.side_effect = make_fake_fstools(fs)
292
- with pytest.raises(ParseError):
293
- a = extract_info('a.yaml', ['a'])
294
- raise Exception(str(a))
295
-
296
-
297
- def test_extract_info_too_many_elements():
298
- check_parse_error({'a.yaml': 'meta: [{a: b}, {b: c}]'})
299
-
300
-
301
- def test_extract_info_not_a_list():
302
- check_parse_error({'a.yaml': 'meta: {a: b}'})
303
-
304
-
305
- def test_extract_info_not_a_dict():
306
- check_parse_error({'a.yaml': 'meta: [[a, b]]'})
307
-
308
-
309
- @patch('teuthology.describe_tests.open')
310
- @patch('os.path.isdir')
311
- def test_extract_info_empty_file(m_isdir, m_open):
312
- simple_fs = {'a.yaml': ''}
313
- _, _, _, m_isdir.side_effect, m_open.side_effect = \
314
- make_fake_fstools(simple_fs)
315
- info = extract_info('a.yaml', [])
316
- assert info == {}
@@ -1,81 +0,0 @@
1
- from humanfriendly import format_timespan
2
- from mock import Mock, patch
3
- from pytest import mark
4
- from teuthology.config import config
5
- from teuthology.run_tasks import build_email_body as email_body
6
- from textwrap import dedent
7
-
8
- class TestSleepBeforeTeardownEmail(object):
9
- def setup(self):
10
- config.results_ui_server = "http://example.com/"
11
- config.archive_server = "http://qa-proxy.ceph.com/teuthology/"
12
-
13
- @mark.parametrize(
14
- ['status', 'owner', 'suite_name', 'run_name', 'job_id', 'dura'],
15
- [
16
- [
17
- 'pass',
18
- 'noreply@host',
19
- 'dummy',
20
- 'run-name',
21
- 123,
22
- 3600,
23
- ],
24
- [
25
- 'fail',
26
- 'noname',
27
- 'yummy',
28
- 'next-run',
29
- 1000,
30
- 99999,
31
- ],
32
- ]
33
- )
34
- @patch("teuthology.run_tasks.time.time")
35
- def test_sleep_before_teardown_email_body(self, m_time, status, owner,
36
- suite_name, run_name, job_id, dura):
37
- ctx = Mock()
38
- archive_path='archive/path'
39
- archive_dir='/archive/dir'
40
- date_sec=3661
41
- date_str='1970-01-01 01:01:01'
42
- m_time.return_value=float(date_sec)
43
- duration_sec=dura
44
- duration_str=format_timespan(duration_sec)
45
- ref_body=dedent("""
46
- Teuthology job {run}/{job} has fallen asleep at {date} for {duration_str}
47
-
48
- Owner: {owner}
49
- Suite Name: {suite}
50
- Sleep Date: {date}
51
- Sleep Time: {duration_sec} seconds ({duration_str})
52
- Job Info: http://example.com/{run}/
53
- Job Logs: http://qa-proxy.ceph.com/teuthology/path/{job}/
54
- Task Stack: a/b/c
55
- Current Status: {status}"""
56
- .format(duration_sec=duration_sec, duration_str=duration_str,
57
- owner=owner, suite=suite_name, run=run_name,
58
- job=job_id, status=status, date=date_str))
59
- print(ref_body)
60
- ctx.config = dict(
61
- archive_path=archive_path,
62
- job_id=job_id,
63
- suite=suite_name,
64
- )
65
- if status == 'pass':
66
- ctx.summary = dict(
67
- success=True,
68
- )
69
- elif status == 'fail':
70
- ctx.summary = dict(
71
- success=False,
72
- )
73
- else:
74
- ctx.summary = dict()
75
-
76
- ctx.owner = owner
77
- ctx.name = run_name
78
- ctx.archive_dir = archive_dir
79
- tasks = [('a', None), ('b', None), ('c', None)]
80
- (subj, body) = email_body(ctx, tasks, dura)
81
- assert body == ref_body.lstrip('\n')