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.
Files changed (168) 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 +16 -5
  37. teuthology/orchestra/console.py +111 -50
  38. teuthology/orchestra/daemon/cephadmunit.py +17 -4
  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/task/tests/__init__.py +137 -77
  94. teuthology/task/tests/test_fetch_coredumps.py +116 -0
  95. teuthology/task/tests/test_run.py +4 -4
  96. teuthology/timer.py +3 -3
  97. teuthology/util/loggerfile.py +19 -0
  98. teuthology/util/scanner.py +159 -0
  99. teuthology/util/sentry.py +52 -0
  100. teuthology/util/time.py +52 -0
  101. teuthology-1.2.0.data/scripts/adjust-ulimits +16 -0
  102. teuthology-1.2.0.data/scripts/daemon-helper +114 -0
  103. teuthology-1.2.0.data/scripts/stdin-killer +263 -0
  104. teuthology-1.2.0.dist-info/METADATA +89 -0
  105. teuthology-1.2.0.dist-info/RECORD +174 -0
  106. {teuthology-1.1.0.dist-info → teuthology-1.2.0.dist-info}/WHEEL +1 -1
  107. {teuthology-1.1.0.dist-info → teuthology-1.2.0.dist-info}/entry_points.txt +3 -2
  108. scripts/nuke.py +0 -47
  109. scripts/worker.py +0 -37
  110. teuthology/nuke/actions.py +0 -456
  111. teuthology/openstack/test/__init__.py +0 -0
  112. teuthology/openstack/test/openstack-integration.py +0 -286
  113. teuthology/openstack/test/test_config.py +0 -35
  114. teuthology/openstack/test/test_openstack.py +0 -1695
  115. teuthology/orchestra/test/__init__.py +0 -0
  116. teuthology/orchestra/test/integration/__init__.py +0 -0
  117. teuthology/orchestra/test/integration/test_integration.py +0 -94
  118. teuthology/orchestra/test/test_cluster.py +0 -240
  119. teuthology/orchestra/test/test_connection.py +0 -106
  120. teuthology/orchestra/test/test_console.py +0 -217
  121. teuthology/orchestra/test/test_opsys.py +0 -404
  122. teuthology/orchestra/test/test_remote.py +0 -185
  123. teuthology/orchestra/test/test_run.py +0 -286
  124. teuthology/orchestra/test/test_systemd.py +0 -54
  125. teuthology/orchestra/test/util.py +0 -12
  126. teuthology/test/__init__.py +0 -0
  127. teuthology/test/fake_archive.py +0 -107
  128. teuthology/test/fake_fs.py +0 -92
  129. teuthology/test/integration/__init__.py +0 -0
  130. teuthology/test/integration/test_suite.py +0 -86
  131. teuthology/test/task/__init__.py +0 -205
  132. teuthology/test/task/test_ansible.py +0 -624
  133. teuthology/test/task/test_ceph_ansible.py +0 -176
  134. teuthology/test/task/test_console_log.py +0 -88
  135. teuthology/test/task/test_install.py +0 -337
  136. teuthology/test/task/test_internal.py +0 -57
  137. teuthology/test/task/test_kernel.py +0 -243
  138. teuthology/test/task/test_pcp.py +0 -379
  139. teuthology/test/task/test_selinux.py +0 -35
  140. teuthology/test/test_config.py +0 -189
  141. teuthology/test/test_contextutil.py +0 -68
  142. teuthology/test/test_describe_tests.py +0 -316
  143. teuthology/test/test_email_sleep_before_teardown.py +0 -81
  144. teuthology/test/test_exit.py +0 -97
  145. teuthology/test/test_get_distro.py +0 -47
  146. teuthology/test/test_get_distro_version.py +0 -47
  147. teuthology/test/test_get_multi_machine_types.py +0 -27
  148. teuthology/test/test_job_status.py +0 -60
  149. teuthology/test/test_ls.py +0 -48
  150. teuthology/test/test_misc.py +0 -391
  151. teuthology/test/test_nuke.py +0 -290
  152. teuthology/test/test_packaging.py +0 -763
  153. teuthology/test/test_parallel.py +0 -28
  154. teuthology/test/test_repo_utils.py +0 -225
  155. teuthology/test/test_report.py +0 -77
  156. teuthology/test/test_results.py +0 -155
  157. teuthology/test/test_run.py +0 -239
  158. teuthology/test/test_safepath.py +0 -55
  159. teuthology/test/test_schedule.py +0 -45
  160. teuthology/test/test_scrape.py +0 -167
  161. teuthology/test/test_timer.py +0 -80
  162. teuthology/test/test_vps_os_vers_parameter_checking.py +0 -84
  163. teuthology/test/test_worker.py +0 -303
  164. teuthology/worker.py +0 -354
  165. teuthology-1.1.0.dist-info/METADATA +0 -76
  166. teuthology-1.1.0.dist-info/RECORD +0 -213
  167. {teuthology-1.1.0.dist-info → teuthology-1.2.0.dist-info}/LICENSE +0 -0
  168. {teuthology-1.1.0.dist-info → teuthology-1.2.0.dist-info}/top_level.txt +0 -0
@@ -1,624 +0,0 @@
1
- import json
2
- import os
3
- import yaml
4
-
5
- from mock import patch, DEFAULT, Mock
6
- from pytest import raises, mark
7
- from teuthology.util.compat import PY3
8
- if PY3:
9
- from io import StringIO as StringIO
10
- else:
11
- from io import BytesIO as StringIO
12
-
13
- from teuthology.config import config, FakeNamespace
14
- from teuthology.exceptions import CommandFailedError
15
- from teuthology.orchestra.cluster import Cluster
16
- from teuthology.orchestra.remote import Remote
17
- from teuthology.task import ansible
18
- from teuthology.task.ansible import Ansible, CephLab
19
-
20
- from teuthology.test.task import TestTask
21
-
22
- class TestAnsibleTask(TestTask):
23
- klass = Ansible
24
- task_name = 'ansible'
25
-
26
- def setup(self):
27
- pass
28
-
29
- def setup_method(self, method):
30
- self.ctx = FakeNamespace()
31
- self.ctx.cluster = Cluster()
32
- self.ctx.cluster.add(Remote('user@remote1'), ['role1'])
33
- self.ctx.cluster.add(Remote('user@remote2'), ['role2'])
34
- self.ctx.config = dict()
35
- self.ctx.summary = dict()
36
- self.task_config = dict(playbook=[])
37
- self.start_patchers()
38
-
39
- def start_patchers(self):
40
- self.patchers = dict()
41
- self.mocks = dict()
42
- self.patchers['mkdtemp'] = patch(
43
- 'teuthology.task.ansible.mkdtemp', return_value='/tmp/'
44
- )
45
- m_NTF = Mock()
46
- m_file = Mock()
47
- m_file.name = 'file_name'
48
- m_NTF.return_value = m_file
49
- self.patchers['NTF'] = patch(
50
- 'teuthology.task.ansible.NamedTemporaryFile',
51
- m_NTF,
52
- )
53
- self.patchers['file'] = patch(
54
- 'teuthology.task.ansible.open', create=True)
55
- self.patchers['os_mkdir'] = patch(
56
- 'teuthology.task.ansible.os.mkdir',
57
- )
58
- self.patchers['os_remove'] = patch(
59
- 'teuthology.task.ansible.os.remove',
60
- )
61
- self.patchers['shutil_rmtree'] = patch(
62
- 'teuthology.task.ansible.shutil.rmtree',
63
- )
64
- for name in self.patchers.keys():
65
- self.start_patcher(name)
66
-
67
- def start_patcher(self, name):
68
- if name not in self.mocks.keys():
69
- self.mocks[name] = self.patchers[name].start()
70
-
71
- def teardown_method(self, method):
72
- self.stop_patchers()
73
-
74
- def stop_patchers(self):
75
- for name in list(self.mocks):
76
- self.stop_patcher(name)
77
-
78
- def stop_patcher(self, name):
79
- self.patchers[name].stop()
80
- del self.mocks[name]
81
-
82
- def test_setup(self):
83
- self.task_config.update(dict(
84
- playbook=[]
85
- ))
86
-
87
- def fake_get_playbook(self):
88
- self.playbook_file = 'fake'
89
-
90
- with patch.multiple(
91
- self.klass,
92
- find_repo=DEFAULT,
93
- get_playbook=fake_get_playbook,
94
- get_inventory=DEFAULT,
95
- generate_inventory=DEFAULT,
96
- generate_playbook=Mock(side_effect=Exception),
97
- ):
98
- task = self.klass(self.ctx, self.task_config)
99
- task.setup()
100
-
101
- def test_setup_generate_playbook(self):
102
- self.task_config.update(dict(
103
- playbook=[]
104
- ))
105
- with patch.multiple(
106
- self.klass,
107
- find_repo=DEFAULT,
108
- get_playbook=DEFAULT,
109
- get_inventory=DEFAULT,
110
- generate_inventory=DEFAULT,
111
- generate_playbook=DEFAULT,
112
- ):
113
- task = self.klass(self.ctx, self.task_config)
114
- task.setup()
115
- task.generate_playbook.assert_called_once_with()
116
-
117
- def test_find_repo_path(self):
118
- self.task_config.update(dict(
119
- repo='~/my/repo',
120
- ))
121
- task = self.klass(self.ctx, self.task_config)
122
- task.find_repo()
123
- assert task.repo_path == os.path.expanduser(self.task_config['repo'])
124
-
125
- @patch('teuthology.task.ansible.fetch_repo')
126
- def test_find_repo_path_remote(self, m_fetch_repo):
127
- self.task_config.update(dict(
128
- repo='git://fake_host/repo.git',
129
- ))
130
- m_fetch_repo.return_value = '/tmp/repo'
131
- task = self.klass(self.ctx, self.task_config)
132
- task.find_repo()
133
- assert task.repo_path == os.path.expanduser('/tmp/repo')
134
-
135
- @patch('teuthology.task.ansible.fetch_repo')
136
- def test_find_repo_http(self, m_fetch_repo):
137
- self.task_config.update(dict(
138
- repo='http://example.com/my/repo',
139
- ))
140
- task = self.klass(self.ctx, self.task_config)
141
- task.find_repo()
142
- m_fetch_repo.assert_called_once_with(self.task_config['repo'],
143
- 'master')
144
-
145
- @patch('teuthology.task.ansible.fetch_repo')
146
- def test_find_repo_git(self, m_fetch_repo):
147
- self.task_config.update(dict(
148
- repo='git@example.com/my/repo',
149
- ))
150
- task = self.klass(self.ctx, self.task_config)
151
- task.find_repo()
152
- m_fetch_repo.assert_called_once_with(self.task_config['repo'],
153
- 'master')
154
-
155
- def test_playbook_none(self):
156
- del self.task_config['playbook']
157
- task = self.klass(self.ctx, self.task_config)
158
- with raises(KeyError):
159
- task.get_playbook()
160
-
161
- def test_playbook_wrong_type(self):
162
- self.task_config.update(dict(
163
- playbook=dict(),
164
- ))
165
- task = self.klass(self.ctx, self.task_config)
166
- with raises(TypeError):
167
- task.get_playbook()
168
-
169
- def test_playbook_list(self):
170
- playbook = [
171
- dict(
172
- roles=['role1'],
173
- ),
174
- ]
175
- self.task_config.update(dict(
176
- playbook=playbook,
177
- ))
178
- task = self.klass(self.ctx, self.task_config)
179
- task.get_playbook()
180
- assert task.playbook == playbook
181
-
182
- @patch.object(ansible.requests, 'get')
183
- def test_playbook_http(self, m_get):
184
- m_get.return_value = Mock()
185
- m_get.return_value.text = 'fake playbook text'
186
- playbook = "http://example.com/my_playbook.yml"
187
- self.task_config.update(dict(
188
- playbook=playbook,
189
- ))
190
- task = self.klass(self.ctx, self.task_config)
191
- task.get_playbook()
192
- m_get.assert_called_once_with(playbook)
193
-
194
- def test_playbook_file(self):
195
- fake_playbook = [dict(fake_playbook=True)]
196
- fake_playbook_obj = StringIO(yaml.safe_dump(fake_playbook))
197
- self.task_config.update(dict(
198
- playbook='~/fake/playbook',
199
- ))
200
- task = self.klass(self.ctx, self.task_config)
201
- self.mocks['file'].return_value = fake_playbook_obj
202
- task.get_playbook()
203
- assert task.playbook == fake_playbook
204
-
205
- def test_playbook_file_missing(self):
206
- self.task_config.update(dict(
207
- playbook='~/fake/playbook',
208
- ))
209
- task = self.klass(self.ctx, self.task_config)
210
- self.mocks['file'].side_effect = IOError
211
- with raises(IOError):
212
- task.get_playbook()
213
-
214
- def test_inventory_none(self):
215
- self.task_config.update(dict(
216
- playbook=[]
217
- ))
218
- task = self.klass(self.ctx, self.task_config)
219
- with patch.object(ansible.os.path, 'exists') as m_exists:
220
- m_exists.return_value = False
221
- task.get_inventory()
222
- assert task.inventory is None
223
-
224
- def test_inventory_path(self):
225
- inventory = '/my/inventory'
226
- self.task_config.update(dict(
227
- playbook=[],
228
- inventory=inventory,
229
- ))
230
- task = self.klass(self.ctx, self.task_config)
231
- task.get_inventory()
232
- assert task.inventory == inventory
233
- assert task.generated_inventory is False
234
-
235
- def test_inventory_etc(self):
236
- self.task_config.update(dict(
237
- playbook=[]
238
- ))
239
- task = self.klass(self.ctx, self.task_config)
240
- with patch.object(ansible.os.path, 'exists') as m_exists:
241
- m_exists.return_value = True
242
- task.get_inventory()
243
- assert task.inventory == '/etc/ansible/hosts'
244
- assert task.generated_inventory is False
245
-
246
- @mark.parametrize(
247
- 'group_vars',
248
- [
249
- dict(),
250
- dict(all=dict(var0=0, var1=1)),
251
- dict(foo=dict(var0=0), bar=dict(var0=1)),
252
- ]
253
- )
254
- def test_generate_inventory(self, group_vars):
255
- self.task_config.update(dict(
256
- playbook=[]
257
- ))
258
- if group_vars:
259
- self.task_config.update(dict(group_vars=group_vars))
260
- task = self.klass(self.ctx, self.task_config)
261
- hosts_file_path = '/my/hosts/inventory'
262
- hosts_file_obj = StringIO()
263
- hosts_file_obj.name = hosts_file_path
264
- inventory_dir = os.path.dirname(hosts_file_path)
265
- gv_dir = os.path.join(inventory_dir, 'group_vars')
266
- self.mocks['mkdtemp'].return_value = inventory_dir
267
- m_file = self.mocks['file']
268
- fake_files = [hosts_file_obj]
269
- # Create StringIO object for each group_vars file
270
- if group_vars:
271
- fake_files += [StringIO() for i in sorted(group_vars)]
272
- m_file.side_effect = fake_files
273
- task.generate_inventory()
274
- file_calls = m_file.call_args_list
275
- # Verify the inventory file was created
276
- assert file_calls[0][0][0] == hosts_file_path
277
- # Verify each group_vars file was created
278
- for gv_name, call_obj in zip(sorted(group_vars), file_calls[1:]):
279
- gv_path = call_obj[0][0]
280
- assert gv_path == os.path.join(gv_dir, '%s.yml' % gv_name)
281
- # Verify the group_vars dir was created
282
- if group_vars:
283
- mkdir_call = self.mocks['os_mkdir'].call_args_list
284
- assert mkdir_call[0][0][0] == gv_dir
285
- assert task.generated_inventory is True
286
- assert task.inventory == inventory_dir
287
- # Verify the content of the inventory *file*
288
- hosts_file_obj.seek(0)
289
- assert hosts_file_obj.readlines() == [
290
- 'remote1\n',
291
- 'remote2\n',
292
- ]
293
- # Verify the contents of each group_vars file
294
- gv_names = sorted(group_vars)
295
- for i in range(len(gv_names)):
296
- gv_name = gv_names[i]
297
- in_val = group_vars[gv_name]
298
- gv_stringio = fake_files[1 + i]
299
- gv_stringio.seek(0)
300
- out_val = yaml.safe_load(gv_stringio)
301
- assert in_val == out_val
302
-
303
- def test_generate_playbook(self):
304
- playbook = [
305
- dict(
306
- roles=['role1', 'role2'],
307
- ),
308
- ]
309
- self.task_config.update(dict(
310
- playbook=playbook
311
- ))
312
- task = self.klass(self.ctx, self.task_config)
313
- playbook_file_path = '/my/playbook/file'
314
- playbook_file_obj = StringIO()
315
- playbook_file_obj.name = playbook_file_path
316
- with patch.object(ansible, 'NamedTemporaryFile') as m_NTF:
317
- m_NTF.return_value = playbook_file_obj
318
- task.find_repo()
319
- task.get_playbook()
320
- task.generate_playbook()
321
- m_NTF.assert_called_once_with(
322
- prefix="teuth_ansible_playbook_",
323
- dir=task.repo_path,
324
- delete=False,
325
- )
326
- assert task.generated_playbook is True
327
- assert task.playbook_file == playbook_file_obj
328
- playbook_file_obj.seek(0)
329
- playbook_result = yaml.safe_load(playbook_file_obj)
330
- assert playbook_result == playbook
331
-
332
- def test_execute_playbook(self):
333
- playbook = '/my/playbook'
334
- self.task_config.update(dict(
335
- playbook=playbook
336
- ))
337
- fake_playbook = [dict(fake_playbook=True)]
338
- fake_playbook_obj = StringIO(yaml.safe_dump(fake_playbook))
339
- fake_playbook_obj.name = playbook
340
- self.mocks['mkdtemp'].return_value = '/inventory/dir'
341
-
342
- task = self.klass(self.ctx, self.task_config)
343
- self.mocks['file'].return_value = fake_playbook_obj
344
- task.setup()
345
- args = task._build_args()
346
- logger = StringIO()
347
- with patch.object(ansible.pexpect, 'run') as m_run:
348
- m_run.return_value = ('', 0)
349
- with patch.object(Remote, 'reconnect') as m_reconnect:
350
- m_reconnect.return_value = True
351
- task.execute_playbook(_logfile=logger)
352
- m_run.assert_called_once_with(
353
- ' '.join(args),
354
- cwd=task.repo_path,
355
- logfile=logger,
356
- withexitstatus=True,
357
- timeout=None,
358
- )
359
-
360
- def test_execute_playbook_fail(self):
361
- self.task_config.update(dict(
362
- playbook=[],
363
- ))
364
- self.mocks['mkdtemp'].return_value = '/inventory/dir'
365
- task = self.klass(self.ctx, self.task_config)
366
- task.setup()
367
- with patch.object(ansible.pexpect, 'run') as m_run:
368
- with patch('teuthology.task.ansible.open') as m_open:
369
- fake_failure_log = Mock()
370
- fake_failure_log.__enter__ = Mock()
371
- fake_failure_log.__exit__ = Mock()
372
- m_open.return_value = fake_failure_log
373
- m_run.return_value = ('', 1)
374
- with raises(CommandFailedError):
375
- task.execute_playbook()
376
- assert task.ctx.summary.get('status') is None
377
-
378
- def test_build_args_no_tags(self):
379
- self.task_config.update(dict(
380
- playbook=[],
381
- ))
382
- task = self.klass(self.ctx, self.task_config)
383
- task.setup()
384
- args = task._build_args()
385
- assert '--tags' not in args
386
-
387
- def test_build_args_tags(self):
388
- self.task_config.update(dict(
389
- playbook=[],
390
- tags="user,pubkeys"
391
- ))
392
- task = self.klass(self.ctx, self.task_config)
393
- task.setup()
394
- args = task._build_args()
395
- assert args.count('--tags') == 1
396
- assert args[args.index('--tags') + 1] == 'user,pubkeys'
397
-
398
- def test_build_args_skip_tags(self):
399
- self.task_config.update(dict(
400
- playbook=[],
401
- skip_tags="user,pubkeys"
402
- ))
403
- task = self.klass(self.ctx, self.task_config)
404
- task.setup()
405
- args = task._build_args()
406
- assert args.count('--skip-tags') == 1
407
- assert args[args.index('--skip-tags') + 1] == 'user,pubkeys'
408
-
409
- def test_build_args_no_vars(self):
410
- self.task_config.update(dict(
411
- playbook=[],
412
- ))
413
- task = self.klass(self.ctx, self.task_config)
414
- task.setup()
415
- args = task._build_args()
416
- assert args.count('--extra-vars') == 1
417
- vars_str = args[args.index('--extra-vars') + 1].strip("'")
418
- extra_vars = json.loads(vars_str)
419
- assert list(extra_vars) == ['ansible_ssh_user']
420
-
421
- def test_build_args_vars(self):
422
- extra_vars = dict(
423
- string1='value1',
424
- list1=['item1'],
425
- dict1=dict(key='value'),
426
- )
427
-
428
- self.task_config.update(dict(
429
- playbook=[],
430
- vars=extra_vars,
431
- ))
432
- task = self.klass(self.ctx, self.task_config)
433
- task.setup()
434
- args = task._build_args()
435
- assert args.count('--extra-vars') == 1
436
- vars_str = args[args.index('--extra-vars') + 1].strip("'")
437
- got_extra_vars = json.loads(vars_str)
438
- assert 'ansible_ssh_user' in got_extra_vars
439
- assert got_extra_vars['string1'] == extra_vars['string1']
440
- assert got_extra_vars['list1'] == extra_vars['list1']
441
- assert got_extra_vars['dict1'] == extra_vars['dict1']
442
-
443
- def test_teardown_inventory(self):
444
- self.task_config.update(dict(
445
- playbook=[],
446
- ))
447
- task = self.klass(self.ctx, self.task_config)
448
- task.generated_inventory = True
449
- task.inventory = 'fake'
450
- with patch.object(ansible.shutil, 'rmtree') as m_rmtree:
451
- task.teardown()
452
- assert m_rmtree.called_once_with('fake')
453
-
454
- def test_teardown_playbook(self):
455
- self.task_config.update(dict(
456
- playbook=[],
457
- ))
458
- task = self.klass(self.ctx, self.task_config)
459
- task.generated_playbook = True
460
- task.playbook_file = Mock()
461
- task.playbook_file.name = 'fake'
462
- with patch.object(ansible.os, 'remove') as m_remove:
463
- task.teardown()
464
- assert m_remove.called_once_with('fake')
465
-
466
- def test_teardown_cleanup_with_vars(self):
467
- self.task_config.update(dict(
468
- playbook=[],
469
- cleanup=True,
470
- vars=dict(yum_repos="testing"),
471
- ))
472
- task = self.klass(self.ctx, self.task_config)
473
- task.inventory = "fake"
474
- task.generated_playbook = True
475
- task.playbook_file = Mock()
476
- task.playbook_file.name = 'fake'
477
- with patch.object(self.klass, 'execute_playbook') as m_execute:
478
- with patch.object(ansible.os, 'remove'):
479
- task.teardown()
480
- task._build_args()
481
- assert m_execute.called
482
- assert 'cleanup' in task.config['vars']
483
- assert 'yum_repos' in task.config['vars']
484
-
485
- def test_teardown_cleanup_with_no_vars(self):
486
- self.task_config.update(dict(
487
- playbook=[],
488
- cleanup=True,
489
- ))
490
- task = self.klass(self.ctx, self.task_config)
491
- task.inventory = "fake"
492
- task.generated_playbook = True
493
- task.playbook_file = Mock()
494
- task.playbook_file.name = 'fake'
495
- with patch.object(self.klass, 'execute_playbook') as m_execute:
496
- with patch.object(ansible.os, 'remove'):
497
- task.teardown()
498
- task._build_args()
499
- assert m_execute.called
500
- assert 'cleanup' in task.config['vars']
501
-
502
-
503
- class TestCephLabTask(TestAnsibleTask):
504
- klass = CephLab
505
- task_name = 'ansible.cephlab'
506
-
507
- def setup(self):
508
- super(TestCephLabTask, self).setup()
509
- self.task_config = dict()
510
-
511
- def start_patchers(self):
512
- super(TestCephLabTask, self).start_patchers()
513
- self.patchers['fetch_repo'] = patch(
514
- 'teuthology.task.ansible.fetch_repo',
515
- )
516
- self.patchers['fetch_repo'].return_value = 'PATH'
517
-
518
- def fake_get_playbook(self):
519
- self.playbook_file = Mock()
520
- self.playbook_file.name = 'cephlab.yml'
521
-
522
- self.patchers['get_playbook'] = patch(
523
- 'teuthology.task.ansible.CephLab.get_playbook',
524
- new=fake_get_playbook,
525
- )
526
- for name in self.patchers.keys():
527
- self.start_patcher(name)
528
-
529
- @patch('teuthology.task.ansible.fetch_repo')
530
- def test_find_repo_http(self, m_fetch_repo):
531
- repo = os.path.join(config.ceph_git_base_url,
532
- 'ceph-cm-ansible.git')
533
- task = self.klass(self.ctx, dict())
534
- task.find_repo()
535
- m_fetch_repo.assert_called_once_with(repo, 'master')
536
-
537
- def test_playbook_file(self):
538
- fake_playbook = [dict(fake_playbook=True)]
539
- fake_playbook_obj = StringIO(yaml.safe_dump(fake_playbook))
540
- playbook = 'cephlab.yml'
541
- fake_playbook_obj.name = playbook
542
- task = self.klass(self.ctx, dict())
543
- task.repo_path = '/tmp/fake/repo'
544
- self.mocks['file'].return_value = fake_playbook_obj
545
- task.get_playbook()
546
- assert task.playbook_file.name == playbook
547
-
548
- def test_generate_inventory(self):
549
- self.task_config.update(dict(
550
- playbook=[]
551
- ))
552
- task = self.klass(self.ctx, self.task_config)
553
- hosts_file_path = '/my/hosts/file'
554
- hosts_file_obj = StringIO()
555
- hosts_file_obj.name = hosts_file_path
556
- self.mocks['mkdtemp'].return_value = os.path.dirname(hosts_file_path)
557
- self.mocks['file'].return_value = hosts_file_obj
558
- task.generate_inventory()
559
- assert task.generated_inventory is True
560
- assert task.inventory == os.path.dirname(hosts_file_path)
561
- hosts_file_obj.seek(0)
562
- assert hosts_file_obj.readlines() == [
563
- '[testnodes]\n',
564
- 'remote1\n',
565
- 'remote2\n',
566
- ]
567
-
568
- def test_fail_status_dead(self):
569
- self.task_config.update(dict(
570
- playbook=[],
571
- ))
572
- self.mocks['mkdtemp'].return_value = '/inventory/dir'
573
- task = self.klass(self.ctx, self.task_config)
574
- task.ctx.summary = dict()
575
- task.setup()
576
- with patch.object(ansible.pexpect, 'run') as m_run:
577
- with patch('teuthology.task.ansible.open') as m_open:
578
- fake_failure_log = Mock()
579
- fake_failure_log.__enter__ = Mock()
580
- fake_failure_log.__exit__ = Mock()
581
- m_open.return_value = fake_failure_log
582
- m_run.return_value = ('', 1)
583
- with raises(CommandFailedError):
584
- task.execute_playbook()
585
- assert task.ctx.summary.get('status') == 'dead'
586
-
587
- def test_execute_playbook_fail(self):
588
- self.mocks['mkdtemp'].return_value = '/inventory/dir'
589
- task = self.klass(self.ctx, self.task_config)
590
- task.setup()
591
- with patch.object(ansible.pexpect, 'run') as m_run:
592
- with patch('teuthology.task.ansible.open') as m_open:
593
- fake_failure_log = Mock()
594
- fake_failure_log.__enter__ = Mock()
595
- fake_failure_log.__exit__ = Mock()
596
- m_open.return_value = fake_failure_log
597
- m_run.return_value = ('', 1)
598
- with raises(CommandFailedError):
599
- task.execute_playbook()
600
- assert task.ctx.summary.get('status') == 'dead'
601
-
602
- @mark.skip("Unsupported")
603
- def test_generate_playbook(self):
604
- pass
605
-
606
- @mark.skip("Unsupported")
607
- def test_playbook_http(self):
608
- pass
609
-
610
- @mark.skip("Unsupported")
611
- def test_playbook_none(self):
612
- pass
613
-
614
- @mark.skip("Unsupported")
615
- def test_playbook_wrong_type(self):
616
- pass
617
-
618
- @mark.skip("Unsupported")
619
- def test_playbook_list(self):
620
- pass
621
-
622
- @mark.skip("Test needs to be reimplemented for this class")
623
- def test_playbook_file_missing(self):
624
- pass