teuthology 1.0.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.
Files changed (172) hide show
  1. scripts/describe.py +1 -0
  2. scripts/dispatcher.py +62 -0
  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/run.py +4 -0
  9. scripts/schedule.py +4 -0
  10. scripts/suite.py +61 -16
  11. scripts/supervisor.py +44 -0
  12. scripts/update_inventory.py +10 -4
  13. scripts/wait.py +31 -0
  14. teuthology/__init__.py +24 -21
  15. teuthology/beanstalk.py +4 -3
  16. teuthology/config.py +17 -6
  17. teuthology/contextutil.py +18 -14
  18. teuthology/describe_tests.py +25 -18
  19. teuthology/dispatcher/__init__.py +365 -0
  20. teuthology/dispatcher/supervisor.py +374 -0
  21. teuthology/exceptions.py +54 -0
  22. teuthology/exporter.py +347 -0
  23. teuthology/kill.py +76 -75
  24. teuthology/lock/cli.py +16 -7
  25. teuthology/lock/ops.py +276 -70
  26. teuthology/lock/query.py +61 -44
  27. teuthology/ls.py +9 -18
  28. teuthology/misc.py +152 -137
  29. teuthology/nuke/__init__.py +12 -351
  30. teuthology/openstack/__init__.py +4 -3
  31. teuthology/openstack/openstack-centos-7.0-user-data.txt +1 -1
  32. teuthology/openstack/openstack-centos-7.1-user-data.txt +1 -1
  33. teuthology/openstack/openstack-centos-7.2-user-data.txt +1 -1
  34. teuthology/openstack/openstack-debian-8.0-user-data.txt +1 -1
  35. teuthology/openstack/openstack-opensuse-42.1-user-data.txt +1 -1
  36. teuthology/openstack/openstack-teuthology.cron +0 -1
  37. teuthology/orchestra/cluster.py +51 -9
  38. teuthology/orchestra/connection.py +23 -16
  39. teuthology/orchestra/console.py +111 -50
  40. teuthology/orchestra/daemon/cephadmunit.py +23 -5
  41. teuthology/orchestra/daemon/state.py +10 -3
  42. teuthology/orchestra/daemon/systemd.py +10 -8
  43. teuthology/orchestra/opsys.py +32 -11
  44. teuthology/orchestra/remote.py +369 -152
  45. teuthology/orchestra/run.py +21 -12
  46. teuthology/packaging.py +54 -15
  47. teuthology/provision/__init__.py +30 -10
  48. teuthology/provision/cloud/openstack.py +12 -6
  49. teuthology/provision/cloud/util.py +1 -2
  50. teuthology/provision/downburst.py +83 -29
  51. teuthology/provision/fog.py +68 -20
  52. teuthology/provision/openstack.py +5 -4
  53. teuthology/provision/pelagos.py +13 -5
  54. teuthology/repo_utils.py +91 -44
  55. teuthology/report.py +57 -35
  56. teuthology/results.py +5 -3
  57. teuthology/run.py +21 -15
  58. teuthology/run_tasks.py +114 -40
  59. teuthology/schedule.py +4 -3
  60. teuthology/scrape.py +28 -22
  61. teuthology/suite/__init__.py +75 -46
  62. teuthology/suite/build_matrix.py +34 -24
  63. teuthology/suite/fragment-merge.lua +105 -0
  64. teuthology/suite/matrix.py +31 -2
  65. teuthology/suite/merge.py +175 -0
  66. teuthology/suite/placeholder.py +8 -8
  67. teuthology/suite/run.py +204 -102
  68. teuthology/suite/util.py +67 -211
  69. teuthology/task/__init__.py +1 -1
  70. teuthology/task/ansible.py +101 -31
  71. teuthology/task/buildpackages.py +2 -2
  72. teuthology/task/ceph_ansible.py +13 -6
  73. teuthology/task/cephmetrics.py +2 -1
  74. teuthology/task/clock.py +33 -14
  75. teuthology/task/exec.py +18 -0
  76. teuthology/task/hadoop.py +2 -2
  77. teuthology/task/install/__init__.py +51 -22
  78. teuthology/task/install/bin/adjust-ulimits +16 -0
  79. teuthology/task/install/bin/daemon-helper +114 -0
  80. teuthology/task/install/bin/stdin-killer +263 -0
  81. teuthology/task/install/deb.py +24 -4
  82. teuthology/task/install/redhat.py +36 -32
  83. teuthology/task/install/rpm.py +41 -14
  84. teuthology/task/install/util.py +48 -22
  85. teuthology/task/internal/__init__.py +69 -11
  86. teuthology/task/internal/edit_sudoers.sh +10 -0
  87. teuthology/task/internal/lock_machines.py +3 -133
  88. teuthology/task/internal/redhat.py +48 -28
  89. teuthology/task/internal/syslog.py +31 -8
  90. teuthology/task/kernel.py +155 -147
  91. teuthology/task/lockfile.py +1 -1
  92. teuthology/task/mpi.py +10 -10
  93. teuthology/task/pcp.py +1 -1
  94. teuthology/task/selinux.py +17 -8
  95. teuthology/task/ssh_keys.py +6 -6
  96. teuthology/task/tests/__init__.py +137 -77
  97. teuthology/task/tests/test_fetch_coredumps.py +116 -0
  98. teuthology/task/tests/test_run.py +4 -4
  99. teuthology/timer.py +3 -3
  100. teuthology/util/loggerfile.py +19 -0
  101. teuthology/util/scanner.py +159 -0
  102. teuthology/util/sentry.py +52 -0
  103. teuthology/util/time.py +52 -0
  104. teuthology-1.2.0.data/scripts/adjust-ulimits +16 -0
  105. teuthology-1.2.0.data/scripts/daemon-helper +114 -0
  106. teuthology-1.2.0.data/scripts/stdin-killer +263 -0
  107. teuthology-1.2.0.dist-info/METADATA +89 -0
  108. teuthology-1.2.0.dist-info/RECORD +174 -0
  109. {teuthology-1.0.0.dist-info → teuthology-1.2.0.dist-info}/WHEEL +1 -1
  110. {teuthology-1.0.0.dist-info → teuthology-1.2.0.dist-info}/entry_points.txt +5 -2
  111. scripts/nuke.py +0 -45
  112. scripts/worker.py +0 -37
  113. teuthology/nuke/actions.py +0 -456
  114. teuthology/openstack/test/__init__.py +0 -0
  115. teuthology/openstack/test/openstack-integration.py +0 -286
  116. teuthology/openstack/test/test_config.py +0 -35
  117. teuthology/openstack/test/test_openstack.py +0 -1695
  118. teuthology/orchestra/test/__init__.py +0 -0
  119. teuthology/orchestra/test/integration/__init__.py +0 -0
  120. teuthology/orchestra/test/integration/test_integration.py +0 -94
  121. teuthology/orchestra/test/test_cluster.py +0 -240
  122. teuthology/orchestra/test/test_connection.py +0 -106
  123. teuthology/orchestra/test/test_console.py +0 -217
  124. teuthology/orchestra/test/test_opsys.py +0 -404
  125. teuthology/orchestra/test/test_remote.py +0 -185
  126. teuthology/orchestra/test/test_run.py +0 -286
  127. teuthology/orchestra/test/test_systemd.py +0 -54
  128. teuthology/orchestra/test/util.py +0 -12
  129. teuthology/sentry.py +0 -18
  130. teuthology/test/__init__.py +0 -0
  131. teuthology/test/fake_archive.py +0 -107
  132. teuthology/test/fake_fs.py +0 -92
  133. teuthology/test/integration/__init__.py +0 -0
  134. teuthology/test/integration/test_suite.py +0 -86
  135. teuthology/test/task/__init__.py +0 -205
  136. teuthology/test/task/test_ansible.py +0 -624
  137. teuthology/test/task/test_ceph_ansible.py +0 -176
  138. teuthology/test/task/test_console_log.py +0 -88
  139. teuthology/test/task/test_install.py +0 -337
  140. teuthology/test/task/test_internal.py +0 -57
  141. teuthology/test/task/test_kernel.py +0 -243
  142. teuthology/test/task/test_pcp.py +0 -379
  143. teuthology/test/task/test_selinux.py +0 -35
  144. teuthology/test/test_config.py +0 -189
  145. teuthology/test/test_contextutil.py +0 -68
  146. teuthology/test/test_describe_tests.py +0 -316
  147. teuthology/test/test_email_sleep_before_teardown.py +0 -81
  148. teuthology/test/test_exit.py +0 -97
  149. teuthology/test/test_get_distro.py +0 -47
  150. teuthology/test/test_get_distro_version.py +0 -47
  151. teuthology/test/test_get_multi_machine_types.py +0 -27
  152. teuthology/test/test_job_status.py +0 -60
  153. teuthology/test/test_ls.py +0 -48
  154. teuthology/test/test_misc.py +0 -368
  155. teuthology/test/test_nuke.py +0 -232
  156. teuthology/test/test_packaging.py +0 -763
  157. teuthology/test/test_parallel.py +0 -28
  158. teuthology/test/test_repo_utils.py +0 -204
  159. teuthology/test/test_report.py +0 -77
  160. teuthology/test/test_results.py +0 -155
  161. teuthology/test/test_run.py +0 -238
  162. teuthology/test/test_safepath.py +0 -55
  163. teuthology/test/test_schedule.py +0 -45
  164. teuthology/test/test_scrape.py +0 -167
  165. teuthology/test/test_timer.py +0 -80
  166. teuthology/test/test_vps_os_vers_parameter_checking.py +0 -84
  167. teuthology/test/test_worker.py +0 -303
  168. teuthology/worker.py +0 -339
  169. teuthology-1.0.0.dist-info/METADATA +0 -76
  170. teuthology-1.0.0.dist-info/RECORD +0 -210
  171. {teuthology-1.0.0.dist-info → teuthology-1.2.0.dist-info}/LICENSE +0 -0
  172. {teuthology-1.0.0.dist-info → teuthology-1.2.0.dist-info}/top_level.txt +0 -0
@@ -1,243 +0,0 @@
1
- from teuthology.config import FakeNamespace
2
- from teuthology.orchestra.cluster import Cluster
3
- from teuthology.orchestra.remote import Remote
4
- from teuthology.task.kernel import (
5
- normalize_and_apply_overrides,
6
- CONFIG_DEFAULT,
7
- TIMEOUT_DEFAULT,
8
- )
9
-
10
- class TestKernelNormalizeAndApplyOverrides(object):
11
-
12
- def setup(self):
13
- self.ctx = FakeNamespace()
14
- self.ctx.cluster = Cluster()
15
- self.ctx.cluster.add(Remote('remote1'), ['mon.a', 'client.0'])
16
- self.ctx.cluster.add(Remote('remote2'), ['osd.0', 'osd.1', 'osd.2'])
17
- self.ctx.cluster.add(Remote('remote3'), ['client.1'])
18
-
19
- def test_default(self):
20
- config = {}
21
- overrides = {}
22
- config, t = normalize_and_apply_overrides(self.ctx, config, overrides)
23
- assert config == {
24
- 'mon.a': CONFIG_DEFAULT,
25
- 'osd.0': CONFIG_DEFAULT,
26
- 'osd.1': CONFIG_DEFAULT,
27
- 'osd.2': CONFIG_DEFAULT,
28
- 'client.0': CONFIG_DEFAULT,
29
- 'client.1': CONFIG_DEFAULT,
30
- }
31
- assert t == TIMEOUT_DEFAULT
32
-
33
- def test_timeout_default(self):
34
- config = {
35
- 'client.0': {'branch': 'testing'},
36
- }
37
- overrides = {}
38
- config, t = normalize_and_apply_overrides(self.ctx, config, overrides)
39
- assert config == {
40
- 'client.0': {'branch': 'testing'},
41
- }
42
- assert t == TIMEOUT_DEFAULT
43
-
44
- def test_timeout(self):
45
- config = {
46
- 'client.0': {'branch': 'testing'},
47
- 'timeout': 100,
48
- }
49
- overrides = {}
50
- config, t = normalize_and_apply_overrides(self.ctx, config, overrides)
51
- assert config == {
52
- 'client.0': {'branch': 'testing'},
53
- }
54
- assert t == 100
55
-
56
- def test_override_timeout(self):
57
- config = {
58
- 'client.0': {'branch': 'testing'},
59
- 'timeout': 100,
60
- }
61
- overrides = {
62
- 'timeout': 200,
63
- }
64
- config, t = normalize_and_apply_overrides(self.ctx, config, overrides)
65
- assert config == {
66
- 'client.0': {'branch': 'testing'},
67
- }
68
- assert t == 200
69
-
70
- def test_override_same_version_key(self):
71
- config = {
72
- 'client.0': {'branch': 'testing'},
73
- }
74
- overrides = {
75
- 'client.0': {'branch': 'wip-foobar'},
76
- }
77
- config, t = normalize_and_apply_overrides(self.ctx, config, overrides)
78
- assert config == {
79
- 'client.0': {'branch': 'wip-foobar'},
80
- }
81
- assert t == TIMEOUT_DEFAULT
82
-
83
- def test_override_different_version_key(self):
84
- config = {
85
- 'client.0': {'branch': 'testing'},
86
- }
87
- overrides = {
88
- 'client.0': {'tag': 'v4.1'},
89
- }
90
- config, t = normalize_and_apply_overrides(self.ctx, config, overrides)
91
- assert config == {
92
- 'client.0': {'tag': 'v4.1'},
93
- }
94
- assert t == TIMEOUT_DEFAULT
95
-
96
- def test_override_actual(self):
97
- config = {
98
- 'osd.1': {'tag': 'v4.1'},
99
- 'client.0': {'branch': 'testing'},
100
- }
101
- overrides = {
102
- 'osd.1': {'koji': 1234, 'kdb': True},
103
- }
104
- config, t = normalize_and_apply_overrides(self.ctx, config, overrides)
105
- assert config == {
106
- 'osd.1': {'koji': 1234, 'kdb': True},
107
- 'client.0': {'branch': 'testing'},
108
- }
109
- assert t == TIMEOUT_DEFAULT
110
-
111
- def test_override_actual_with_generic(self):
112
- config = {
113
- 'osd.1': {'tag': 'v4.1', 'kdb': False},
114
- 'client.0': {'branch': 'testing'},
115
- }
116
- overrides = {
117
- 'osd': {'koji': 1234},
118
- }
119
- config, t = normalize_and_apply_overrides(self.ctx, config, overrides)
120
- assert config == {
121
- 'osd.0': {'koji': 1234},
122
- 'osd.1': {'koji': 1234, 'kdb': False},
123
- 'osd.2': {'koji': 1234},
124
- 'client.0': {'branch': 'testing'},
125
- }
126
- assert t == TIMEOUT_DEFAULT
127
-
128
- def test_override_actual_with_top_level(self):
129
- config = {
130
- 'osd.1': {'tag': 'v4.1'},
131
- 'client.0': {'branch': 'testing', 'kdb': False},
132
- }
133
- overrides = {'koji': 1234, 'kdb': True}
134
- config, t = normalize_and_apply_overrides(self.ctx, config, overrides)
135
- assert config == {
136
- 'mon.a': {'koji': 1234, 'kdb': True},
137
- 'osd.0': {'koji': 1234, 'kdb': True},
138
- 'osd.1': {'koji': 1234, 'kdb': True},
139
- 'osd.2': {'koji': 1234, 'kdb': True},
140
- 'client.0': {'koji': 1234, 'kdb': True},
141
- 'client.1': {'koji': 1234, 'kdb': True},
142
- }
143
- assert t == TIMEOUT_DEFAULT
144
-
145
- def test_override_generic(self):
146
- config = {
147
- 'osd': {'tag': 'v4.1'},
148
- 'client': {'branch': 'testing'},
149
- }
150
- overrides = {
151
- 'client': {'koji': 1234, 'kdb': True},
152
- }
153
- config, t = normalize_and_apply_overrides(self.ctx, config, overrides)
154
- assert config == {
155
- 'osd.0': {'tag': 'v4.1'},
156
- 'osd.1': {'tag': 'v4.1'},
157
- 'osd.2': {'tag': 'v4.1'},
158
- 'client.0': {'koji': 1234, 'kdb': True},
159
- 'client.1': {'koji': 1234, 'kdb': True},
160
- }
161
- assert t == TIMEOUT_DEFAULT
162
-
163
- def test_override_generic_with_top_level(self):
164
- config = {
165
- 'osd': {'tag': 'v4.1'},
166
- 'client': {'branch': 'testing', 'kdb': False},
167
- }
168
- overrides = {
169
- 'client': {'koji': 1234},
170
- }
171
- config, t = normalize_and_apply_overrides(self.ctx, config, overrides)
172
- assert config == {
173
- 'osd.0': {'tag': 'v4.1'},
174
- 'osd.1': {'tag': 'v4.1'},
175
- 'osd.2': {'tag': 'v4.1'},
176
- 'client.0': {'koji': 1234, 'kdb': False},
177
- 'client.1': {'koji': 1234, 'kdb': False},
178
- }
179
- assert t == TIMEOUT_DEFAULT
180
-
181
- def test_override_generic_with_actual(self):
182
- config = {
183
- 'osd': {'tag': 'v4.1', 'kdb': False},
184
- 'client': {'branch': 'testing'},
185
- }
186
- overrides = {
187
- 'osd.2': {'koji': 1234, 'kdb': True},
188
- }
189
- config, t = normalize_and_apply_overrides(self.ctx, config, overrides)
190
- assert config == {
191
- 'osd.0': {'tag': 'v4.1', 'kdb': False},
192
- 'osd.1': {'tag': 'v4.1', 'kdb': False},
193
- 'osd.2': {'koji': 1234, 'kdb': True},
194
- 'client.0': {'branch': 'testing'},
195
- 'client.1': {'branch': 'testing'},
196
- }
197
- assert t == TIMEOUT_DEFAULT
198
-
199
- def test_override_top_level(self):
200
- config = {'branch': 'testing'}
201
- overrides = {'koji': 1234, 'kdb': True}
202
- config, t = normalize_and_apply_overrides(self.ctx, config, overrides)
203
- assert config == {
204
- 'mon.a': {'koji': 1234, 'kdb': True},
205
- 'osd.0': {'koji': 1234, 'kdb': True},
206
- 'osd.1': {'koji': 1234, 'kdb': True},
207
- 'osd.2': {'koji': 1234, 'kdb': True},
208
- 'client.0': {'koji': 1234, 'kdb': True},
209
- 'client.1': {'koji': 1234, 'kdb': True},
210
- }
211
- assert t == TIMEOUT_DEFAULT
212
-
213
- def test_override_top_level_with_actual(self):
214
- config = {'branch': 'testing', 'kdb': False}
215
- overrides = {
216
- 'mon.a': {'koji': 1234},
217
- }
218
- config, t = normalize_and_apply_overrides(self.ctx, config, overrides)
219
- assert config == {
220
- 'mon.a': {'koji': 1234, 'kdb': False},
221
- 'osd.0': {'branch': 'testing', 'kdb': False},
222
- 'osd.1': {'branch': 'testing', 'kdb': False},
223
- 'osd.2': {'branch': 'testing', 'kdb': False},
224
- 'client.0': {'branch': 'testing', 'kdb': False},
225
- 'client.1': {'branch': 'testing', 'kdb': False},
226
- }
227
- assert t == TIMEOUT_DEFAULT
228
-
229
- def test_override_top_level_with_generic(self):
230
- config = {'branch': 'testing', 'kdb': False}
231
- overrides = {
232
- 'client': {'koji': 1234, 'kdb': True},
233
- }
234
- config, t = normalize_and_apply_overrides(self.ctx, config, overrides)
235
- assert config == {
236
- 'mon.a': {'branch': 'testing', 'kdb': False},
237
- 'osd.0': {'branch': 'testing', 'kdb': False},
238
- 'osd.1': {'branch': 'testing', 'kdb': False},
239
- 'osd.2': {'branch': 'testing', 'kdb': False},
240
- 'client.0': {'koji': 1234, 'kdb': True},
241
- 'client.1': {'koji': 1234, 'kdb': True},
242
- }
243
- assert t == TIMEOUT_DEFAULT
@@ -1,379 +0,0 @@
1
- import os
2
- import requests
3
-
4
- from teuthology.util.compat import parse_qs, urljoin
5
-
6
- from mock import patch, DEFAULT, Mock, mock_open, call
7
- from pytest import raises
8
-
9
- from teuthology.config import config, FakeNamespace
10
- from teuthology.orchestra.cluster import Cluster
11
- from teuthology.orchestra.remote import Remote
12
- from teuthology.orchestra.run import Raw
13
- from teuthology.task.pcp import (PCPDataSource, PCPArchive, PCPGrapher,
14
- GrafanaGrapher, GraphiteGrapher, PCP)
15
-
16
- from teuthology.test.task import TestTask
17
-
18
- pcp_host = 'http://pcp.front.sepia.ceph.com:44323/'
19
-
20
-
21
- class TestPCPDataSource(object):
22
- klass = PCPDataSource
23
-
24
- def setup(self):
25
- config.pcp_host = pcp_host
26
-
27
- def test_init(self):
28
- hosts = ['host1', 'host2']
29
- time_from = 'now-2h'
30
- time_until = 'now'
31
- obj = self.klass(
32
- hosts=hosts,
33
- time_from=time_from,
34
- time_until=time_until,
35
- )
36
- assert obj.hosts == hosts
37
- assert obj.time_from == time_from
38
- assert obj.time_until == time_until
39
-
40
-
41
- class TestPCPArchive(TestPCPDataSource):
42
- klass = PCPArchive
43
-
44
- def test_get_archive_input_dir(self):
45
- hosts = ['host1', 'host2']
46
- time_from = 'now-1d'
47
- obj = self.klass(
48
- hosts=hosts,
49
- time_from=time_from,
50
- )
51
- assert obj.get_archive_input_dir('host1') == \
52
- '/var/log/pcp/pmlogger/host1'
53
-
54
- def test_get_pmlogextract_cmd(self):
55
- obj = self.klass(
56
- hosts=['host1'],
57
- time_from='now-3h',
58
- time_until='now-1h',
59
- )
60
- expected = [
61
- 'pmlogextract',
62
- '-S', 'now-3h',
63
- '-T', 'now-1h',
64
- Raw('/var/log/pcp/pmlogger/host1/*.0'),
65
- ]
66
- assert obj.get_pmlogextract_cmd('host1') == expected
67
-
68
- def test_format_time(self):
69
- assert self.klass._format_time(1462893484) == \
70
- '@ Tue May 10 15:18:04 2016'
71
-
72
- def test_format_time_now(self):
73
- assert self.klass._format_time('now-1h') == 'now-1h'
74
-
75
-
76
- class TestPCPGrapher(TestPCPDataSource):
77
- klass = PCPGrapher
78
-
79
- def test_init(self):
80
- hosts = ['host1', 'host2']
81
- time_from = 'now-2h'
82
- time_until = 'now'
83
- obj = self.klass(
84
- hosts=hosts,
85
- time_from=time_from,
86
- time_until=time_until,
87
- )
88
- assert obj.hosts == hosts
89
- assert obj.time_from == time_from
90
- assert obj.time_until == time_until
91
- expected_url = urljoin(config.pcp_host, self.klass._endpoint)
92
- assert obj.base_url == expected_url
93
-
94
-
95
- class TestGrafanaGrapher(TestPCPGrapher):
96
- klass = GrafanaGrapher
97
-
98
- def test_build_graph_url(self):
99
- hosts = ['host1']
100
- time_from = 'now-3h'
101
- time_until = 'now-1h'
102
- obj = self.klass(
103
- hosts=hosts,
104
- time_from=time_from,
105
- time_until=time_until,
106
- )
107
- base_url = urljoin(
108
- config.pcp_host,
109
- 'grafana/index.html#/dashboard/script/index.js',
110
- )
111
- assert obj.base_url == base_url
112
- got_url = obj.build_graph_url()
113
- parsed_query = parse_qs(got_url.split('?')[1])
114
- assert parsed_query['hosts'] == hosts
115
- assert len(parsed_query['time_from']) == 1
116
- assert parsed_query['time_from'][0] == time_from
117
- assert len(parsed_query['time_to']) == 1
118
- assert parsed_query['time_to'][0] == time_until
119
-
120
- def test_format_time(self):
121
- assert self.klass._format_time(1462893484) == \
122
- '2016-05-10T15:18:04'
123
-
124
- def test_format_time_now(self):
125
- assert self.klass._format_time('now-1h') == 'now-1h'
126
-
127
-
128
- class TestGraphiteGrapher(TestPCPGrapher):
129
- klass = GraphiteGrapher
130
-
131
- def test_build_graph_urls(self):
132
- obj = self.klass(
133
- hosts=['host1', 'host2'],
134
- time_from='now-3h',
135
- time_until='now-1h',
136
- )
137
- expected_urls = [obj.get_graph_url(m) for m in obj.metrics]
138
- obj.build_graph_urls()
139
- built_urls = []
140
- for metric in obj.graphs.keys():
141
- built_urls.append(obj.graphs[metric]['url'])
142
- assert len(built_urls) == len(expected_urls)
143
- assert sorted(built_urls) == sorted(expected_urls)
144
-
145
- def test_check_dest_dir(self):
146
- obj = self.klass(
147
- hosts=['host1'],
148
- time_from='now-3h',
149
- )
150
- assert obj.dest_dir is None
151
- with raises(RuntimeError):
152
- obj._check_dest_dir()
153
-
154
- def test_generate_html_dynamic(self):
155
- obj = self.klass(
156
- hosts=['host1'],
157
- time_from='now-3h',
158
- )
159
- html = obj.generate_html()
160
- assert config.pcp_host in html
161
-
162
- def test_download_graphs(self):
163
- dest_dir = '/fake/path'
164
- obj = self.klass(
165
- hosts=['host1'],
166
- time_from='now-3h',
167
- dest_dir=dest_dir,
168
- )
169
- _format = obj.graph_defaults.get('format')
170
- with patch('teuthology.task.pcp.requests.get', create=True) as m_get:
171
- m_resp = Mock()
172
- m_resp.ok = True
173
- m_get.return_value = m_resp
174
- with patch('teuthology.task.pcp.open', mock_open(), create=True):
175
- obj.download_graphs()
176
- expected_filenames = []
177
- for metric in obj.metrics:
178
- expected_filenames.append(
179
- "{}.{}".format(
180
- os.path.join(
181
- dest_dir,
182
- obj._sanitize_metric_name(metric),
183
- ),
184
- _format,
185
- )
186
- )
187
- graph_filenames = []
188
- for metric in obj.graphs.keys():
189
- graph_filenames.append(obj.graphs[metric]['file'])
190
- assert sorted(graph_filenames) == sorted(expected_filenames)
191
-
192
- def test_generate_html_static(self):
193
- obj = self.klass(
194
- hosts=['host1'],
195
- time_from='now-3h',
196
- dest_dir='/fake/path',
197
- )
198
- with patch('teuthology.task.pcp.requests.get', create=True) as m_get:
199
- m_resp = Mock()
200
- m_resp.ok = True
201
- m_get.return_value = m_resp
202
- with patch('teuthology.task.pcp.open', mock_open(), create=True):
203
- obj.download_graphs()
204
- html = obj.generate_html(mode='static')
205
- assert config.pcp_host not in html
206
-
207
- def test_sanitize_metric_name(self):
208
- sanitized_metrics = {
209
- 'foo.bar': 'foo.bar',
210
- 'foo.*': 'foo._all_',
211
- 'foo.bar baz': 'foo.bar_baz',
212
- 'foo.*.bar baz': 'foo._all_.bar_baz',
213
- }
214
- for in_, out in sanitized_metrics.items():
215
- assert self.klass._sanitize_metric_name(in_) == out
216
-
217
- def test_get_target_globs(self):
218
- obj = self.klass(
219
- hosts=['host1'],
220
- time_from='now-3h',
221
- )
222
- assert obj.get_target_globs() == ['*host1*']
223
- assert obj.get_target_globs('a.metric') == ['*host1*.a.metric']
224
- obj.hosts.append('host2')
225
- assert obj.get_target_globs() == ['*host1*', '*host2*']
226
- assert obj.get_target_globs('a.metric') == \
227
- ['*host1*.a.metric', '*host2*.a.metric']
228
-
229
-
230
- class TestPCPTask(TestTask):
231
- klass = PCP
232
- task_name = 'pcp'
233
-
234
- def setup(self):
235
- self.ctx = FakeNamespace()
236
- self.ctx.cluster = Cluster()
237
- self.ctx.cluster.add(Remote('user@remote1'), ['role1'])
238
- self.ctx.cluster.add(Remote('user@remote2'), ['role2'])
239
- self.ctx.config = dict()
240
- self.task_config = dict()
241
- config.pcp_host = pcp_host
242
-
243
- def test_init(self):
244
- task = self.klass(self.ctx, self.task_config)
245
- assert task.stop_time == 'now'
246
-
247
- def test_disabled(self):
248
- config.pcp_host = None
249
- with self.klass(self.ctx, self.task_config) as task:
250
- assert task.enabled is False
251
- assert not hasattr(task, 'grafana')
252
- assert not hasattr(task, 'graphite')
253
- assert not hasattr(task, 'archiver')
254
-
255
- def test_setup(self):
256
- with patch.multiple(
257
- self.klass,
258
- setup_collectors=DEFAULT,
259
- begin=DEFAULT,
260
- end=DEFAULT,
261
- ):
262
- with self.klass(self.ctx, self.task_config) as task:
263
- task.setup_collectors.assert_called_once_with()
264
- assert isinstance(task.start_time, int)
265
-
266
- def test_setup_collectors(self):
267
- with patch.multiple(
268
- self.klass,
269
- begin=DEFAULT,
270
- end=DEFAULT,
271
- ):
272
- with self.klass(self.ctx, self.task_config) as task:
273
- assert hasattr(task, 'grafana')
274
- assert not hasattr(task, 'graphite')
275
- assert not hasattr(task, 'archiver')
276
- self.task_config['grafana'] = False
277
- with self.klass(self.ctx, self.task_config) as task:
278
- assert not hasattr(task, 'grafana')
279
-
280
- @patch('os.makedirs')
281
- def test_setup_grafana(self, m_makedirs):
282
- with patch.multiple(
283
- self.klass,
284
- begin=DEFAULT,
285
- end=DEFAULT,
286
- ):
287
- self.ctx.archive = '/fake/path'
288
- with self.klass(self.ctx, self.task_config) as task:
289
- assert hasattr(task, 'grafana')
290
- self.task_config['grafana'] = False
291
- with self.klass(self.ctx, self.task_config) as task:
292
- assert not hasattr(task, 'grafana')
293
-
294
- @patch('os.makedirs')
295
- @patch('teuthology.task.pcp.GraphiteGrapher')
296
- def test_setup_graphite(self, m_graphite_grapher, m_makedirs):
297
- with patch.multiple(
298
- self.klass,
299
- begin=DEFAULT,
300
- end=DEFAULT,
301
- ):
302
- with self.klass(self.ctx, self.task_config) as task:
303
- assert not hasattr(task, 'graphite')
304
- self.task_config['graphite'] = False
305
- with self.klass(self.ctx, self.task_config) as task:
306
- assert not hasattr(task, 'graphite')
307
- self.ctx.archive = '/fake/path'
308
- self.task_config['graphite'] = True
309
- with self.klass(self.ctx, self.task_config) as task:
310
- assert hasattr(task, 'graphite')
311
- self.task_config['graphite'] = False
312
- with self.klass(self.ctx, self.task_config) as task:
313
- assert not hasattr(task, 'graphite')
314
-
315
- @patch('os.makedirs')
316
- @patch('teuthology.task.pcp.PCPArchive')
317
- def test_setup_archiver(self, m_archive, m_makedirs):
318
- with patch.multiple(
319
- self.klass,
320
- begin=DEFAULT,
321
- end=DEFAULT,
322
- ):
323
- self.task_config['fetch_archives'] = True
324
- with self.klass(self.ctx, self.task_config) as task:
325
- assert not hasattr(task, 'archiver')
326
- self.task_config['fetch_archives'] = False
327
- with self.klass(self.ctx, self.task_config) as task:
328
- assert not hasattr(task, 'archiver')
329
- self.ctx.archive = '/fake/path'
330
- self.task_config['fetch_archives'] = True
331
- with self.klass(self.ctx, self.task_config) as task:
332
- assert hasattr(task, 'archiver')
333
- self.task_config['fetch_archives'] = False
334
- with self.klass(self.ctx, self.task_config) as task:
335
- assert not hasattr(task, 'archiver')
336
-
337
- @patch('os.makedirs')
338
- @patch('teuthology.task.pcp.GrafanaGrapher')
339
- @patch('teuthology.task.pcp.GraphiteGrapher')
340
- def test_begin(self, m_grafana, m_graphite, m_makedirs):
341
- with patch.multiple(
342
- self.klass,
343
- end=DEFAULT,
344
- ):
345
- with self.klass(self.ctx, self.task_config) as task:
346
- task.grafana.build_graph_url.assert_called_once_with()
347
- self.task_config['graphite'] = True
348
- self.ctx.archive = '/fake/path'
349
- with self.klass(self.ctx, self.task_config) as task:
350
- task.graphite.write_html.assert_called_once_with()
351
-
352
- @patch('os.makedirs')
353
- @patch('teuthology.task.pcp.GrafanaGrapher')
354
- @patch('teuthology.task.pcp.GraphiteGrapher')
355
- def test_end(self, m_grafana, m_graphite, m_makedirs):
356
- self.ctx.archive = '/fake/path'
357
- with self.klass(self.ctx, self.task_config) as task:
358
- # begin() should have called write_html() once by now, with no args
359
- task.graphite.write_html.assert_called_once_with()
360
- # end() should have called write_html() a second time by now, with
361
- # mode=static
362
- second_call = task.graphite.write_html.call_args_list[1]
363
- assert second_call[1]['mode'] == 'static'
364
- assert isinstance(task.stop_time, int)
365
-
366
- @patch('os.makedirs')
367
- @patch('teuthology.task.pcp.GrafanaGrapher')
368
- @patch('teuthology.task.pcp.GraphiteGrapher')
369
- def test_end_16049(self, m_grafana, m_graphite, m_makedirs):
370
- # http://tracker.ceph.com/issues/16049
371
- # Jobs were failing if graph downloading failed. We don't want that.
372
- self.ctx.archive = '/fake/path'
373
- with self.klass(self.ctx, self.task_config) as task:
374
- task.graphite.download_graphs.side_effect = \
375
- requests.ConnectionError
376
- # Even though downloading graphs failed, we should have called
377
- # write_html() a second time, again with no args
378
- assert task.graphite.write_html.call_args_list == [call(), call()]
379
- assert isinstance(task.stop_time, int)
@@ -1,35 +0,0 @@
1
- from mock import patch, Mock, DEFAULT
2
-
3
- from teuthology.config import FakeNamespace
4
- from teuthology.orchestra.cluster import Cluster
5
- from teuthology.orchestra.remote import Remote
6
- from teuthology.task.selinux import SELinux
7
-
8
-
9
- class TestSELinux(object):
10
- def setup(self):
11
- self.ctx = FakeNamespace()
12
- self.ctx.config = dict()
13
-
14
- def test_host_exclusion(self):
15
- with patch.multiple(
16
- Remote,
17
- os=DEFAULT,
18
- run=DEFAULT,
19
- ):
20
- self.ctx.cluster = Cluster()
21
- remote1 = Remote('remote1')
22
- remote1.os = Mock()
23
- remote1.os.package_type = 'rpm'
24
- remote1._is_vm = False
25
- self.ctx.cluster.add(remote1, ['role1'])
26
- remote2 = Remote('remote1')
27
- remote2.os = Mock()
28
- remote2.os.package_type = 'deb'
29
- remote2._is_vm = False
30
- self.ctx.cluster.add(remote2, ['role2'])
31
- task_config = dict()
32
- with SELinux(self.ctx, task_config) as task:
33
- remotes = list(task.cluster.remotes)
34
- assert remotes == [remote1]
35
-