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.
- 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 +17 -4
- teuthology/orchestra/console.py +111 -50
- teuthology/orchestra/daemon/cephadmunit.py +15 -2
- 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/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.1.data/scripts/adjust-ulimits +16 -0
- teuthology-1.2.1.data/scripts/daemon-helper +114 -0
- teuthology-1.2.1.data/scripts/stdin-killer +263 -0
- teuthology-1.2.1.dist-info/METADATA +88 -0
- teuthology-1.2.1.dist-info/RECORD +168 -0
- {teuthology-1.1.0.dist-info → teuthology-1.2.1.dist-info}/WHEEL +1 -1
- {teuthology-1.1.0.dist-info → teuthology-1.2.1.dist-info}/entry_points.txt +3 -2
- scripts/nuke.py +0 -47
- scripts/worker.py +0 -37
- teuthology/lock/test/__init__.py +0 -0
- teuthology/lock/test/test_lock.py +0 -7
- 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/task/tests/__init__.py +0 -110
- teuthology/task/tests/test_locking.py +0 -25
- teuthology/task/tests/test_run.py +0 -40
- 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.1.dist-info}/LICENSE +0 -0
- {teuthology-1.1.0.dist-info → teuthology-1.2.1.dist-info}/top_level.txt +0 -0
teuthology/test/test_exit.py
DELETED
@@ -1,97 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
import random
|
3
|
-
import signal
|
4
|
-
|
5
|
-
from unittest.mock import patch, Mock
|
6
|
-
|
7
|
-
from teuthology import exit
|
8
|
-
|
9
|
-
|
10
|
-
class TestExiter(object):
|
11
|
-
klass = exit.Exiter
|
12
|
-
|
13
|
-
def setup(self):
|
14
|
-
self.pid = os.getpid()
|
15
|
-
|
16
|
-
# Below, we patch os.kill() in such a way that the first time it is
|
17
|
-
# invoked it does actually send the signal. Any subsequent invocation
|
18
|
-
# won't send any signal - this is so we don't kill the process running
|
19
|
-
# our unit tests!
|
20
|
-
self.patcher_kill = patch(
|
21
|
-
'teuthology.exit.os.kill',
|
22
|
-
wraps=os.kill,
|
23
|
-
)
|
24
|
-
|
25
|
-
#Keep a copy of the unpatched kill and call this in place of os.kill
|
26
|
-
#In the Exiter objects, the os.kill calls are patched.
|
27
|
-
#So the call_count should be 1.
|
28
|
-
self.kill_unpatched = os.kill
|
29
|
-
self.m_kill = self.patcher_kill.start()
|
30
|
-
|
31
|
-
def m_kill_unwrap(pid, sig):
|
32
|
-
# Setting return_value of a mocked object disables the wrapping
|
33
|
-
if self.m_kill.call_count > 1:
|
34
|
-
self.m_kill.return_value = None
|
35
|
-
|
36
|
-
self.m_kill.side_effect = m_kill_unwrap
|
37
|
-
|
38
|
-
def teardown(self):
|
39
|
-
self.patcher_kill.stop()
|
40
|
-
del self.m_kill
|
41
|
-
|
42
|
-
def test_noop(self):
|
43
|
-
sig = 15
|
44
|
-
obj = self.klass()
|
45
|
-
assert len(obj.handlers) == 0
|
46
|
-
assert signal.getsignal(sig) == 0
|
47
|
-
|
48
|
-
def test_basic(self):
|
49
|
-
sig = 15
|
50
|
-
obj = self.klass()
|
51
|
-
m_func = Mock()
|
52
|
-
obj.add_handler(sig, m_func)
|
53
|
-
assert len(obj.handlers) == 1
|
54
|
-
self.kill_unpatched(self.pid, sig)
|
55
|
-
assert m_func.call_count == 1
|
56
|
-
assert self.m_kill.call_count == 1
|
57
|
-
for arg_list in self.m_kill.call_args_list:
|
58
|
-
assert arg_list[0] == (self.pid, sig)
|
59
|
-
|
60
|
-
def test_remove_handlers(self):
|
61
|
-
sig = [1, 15]
|
62
|
-
send_sig = random.choice(sig)
|
63
|
-
n = 3
|
64
|
-
obj = self.klass()
|
65
|
-
handlers = list()
|
66
|
-
for i in range(n):
|
67
|
-
m_func = Mock(name="handler %s" % i)
|
68
|
-
handlers.append(obj.add_handler(sig, m_func))
|
69
|
-
assert obj.handlers == handlers
|
70
|
-
for handler in handlers:
|
71
|
-
handler.remove()
|
72
|
-
assert obj.handlers == list()
|
73
|
-
self.kill_unpatched(self.pid, send_sig)
|
74
|
-
assert self.m_kill.call_count == 1
|
75
|
-
for handler in handlers:
|
76
|
-
assert handler.func.call_count == 0
|
77
|
-
|
78
|
-
def test_n_handlers(self, n=10, sig=11):
|
79
|
-
if isinstance(sig, int):
|
80
|
-
send_sig = sig
|
81
|
-
else:
|
82
|
-
send_sig = random.choice(sig)
|
83
|
-
obj = self.klass()
|
84
|
-
handlers = list()
|
85
|
-
for i in range(n):
|
86
|
-
m_func = Mock(name="handler %s" % i)
|
87
|
-
handlers.append(obj.add_handler(sig, m_func))
|
88
|
-
assert obj.handlers == handlers
|
89
|
-
self.kill_unpatched(self.pid, send_sig)
|
90
|
-
for i in range(n):
|
91
|
-
assert handlers[i].func.call_count == 1
|
92
|
-
assert self.m_kill.call_count == 1
|
93
|
-
for arg_list in self.m_kill.call_args_list:
|
94
|
-
assert arg_list[0] == (self.pid, send_sig)
|
95
|
-
|
96
|
-
def test_multiple_signals(self):
|
97
|
-
self.test_n_handlers(n=3, sig=[1, 6, 11, 15])
|
@@ -1,47 +0,0 @@
|
|
1
|
-
from teuthology.misc import get_distro
|
2
|
-
|
3
|
-
|
4
|
-
class Mock:
|
5
|
-
pass
|
6
|
-
|
7
|
-
|
8
|
-
class TestGetDistro(object):
|
9
|
-
|
10
|
-
def setup(self):
|
11
|
-
self.fake_ctx = Mock()
|
12
|
-
self.fake_ctx.config = {}
|
13
|
-
# os_type in ctx will always default to None
|
14
|
-
self.fake_ctx.os_type = None
|
15
|
-
|
16
|
-
def test_default_distro(self):
|
17
|
-
distro = get_distro(self.fake_ctx)
|
18
|
-
assert distro == 'ubuntu'
|
19
|
-
|
20
|
-
def test_argument(self):
|
21
|
-
# we don't want fake_ctx to have a config
|
22
|
-
self.fake_ctx = Mock()
|
23
|
-
self.fake_ctx.os_type = 'centos'
|
24
|
-
distro = get_distro(self.fake_ctx)
|
25
|
-
assert distro == 'centos'
|
26
|
-
|
27
|
-
def test_teuth_config(self):
|
28
|
-
self.fake_ctx.config = {'os_type': 'fedora'}
|
29
|
-
distro = get_distro(self.fake_ctx)
|
30
|
-
assert distro == 'fedora'
|
31
|
-
|
32
|
-
def test_argument_takes_precedence(self):
|
33
|
-
self.fake_ctx.config = {'os_type': 'fedora'}
|
34
|
-
self.fake_ctx.os_type = "centos"
|
35
|
-
distro = get_distro(self.fake_ctx)
|
36
|
-
assert distro == 'centos'
|
37
|
-
|
38
|
-
def test_no_config_or_os_type(self):
|
39
|
-
self.fake_ctx = Mock()
|
40
|
-
self.fake_ctx.os_type = None
|
41
|
-
distro = get_distro(self.fake_ctx)
|
42
|
-
assert distro == 'ubuntu'
|
43
|
-
|
44
|
-
def test_config_os_type_is_none(self):
|
45
|
-
self.fake_ctx.config["os_type"] = None
|
46
|
-
distro = get_distro(self.fake_ctx)
|
47
|
-
assert distro == 'ubuntu'
|
@@ -1,47 +0,0 @@
|
|
1
|
-
from teuthology.misc import get_distro_version
|
2
|
-
|
3
|
-
|
4
|
-
class Mock:
|
5
|
-
pass
|
6
|
-
|
7
|
-
|
8
|
-
class TestGetDistroVersion(object):
|
9
|
-
|
10
|
-
def setup(self):
|
11
|
-
self.fake_ctx = Mock()
|
12
|
-
self.fake_ctx.config = {}
|
13
|
-
self.fake_ctx_noarg = Mock()
|
14
|
-
self.fake_ctx_noarg.config = {}
|
15
|
-
self.fake_ctx_noarg.os_version = None
|
16
|
-
self.fake_ctx.os_type = None
|
17
|
-
self.fake_ctx_noarg.os_type = None
|
18
|
-
|
19
|
-
def test_default_distro_version(self):
|
20
|
-
# Default distro is ubuntu, default version of ubuntu is 16.04
|
21
|
-
self.fake_ctx.os_version = None
|
22
|
-
distroversion = get_distro_version(self.fake_ctx)
|
23
|
-
assert distroversion == '18.04'
|
24
|
-
|
25
|
-
def test_argument_version(self):
|
26
|
-
self.fake_ctx.os_version = '13.04'
|
27
|
-
distroversion = get_distro_version(self.fake_ctx)
|
28
|
-
assert distroversion == '13.04'
|
29
|
-
|
30
|
-
def test_teuth_config_version(self):
|
31
|
-
#Argument takes precidence.
|
32
|
-
self.fake_ctx.os_version = '13.04'
|
33
|
-
self.fake_ctx.config = {'os_version': '13.10'}
|
34
|
-
distroversion = get_distro_version(self.fake_ctx)
|
35
|
-
assert distroversion == '13.04'
|
36
|
-
|
37
|
-
def test_teuth_config_noarg_version(self):
|
38
|
-
self.fake_ctx_noarg.config = {'os_version': '13.04'}
|
39
|
-
distroversion = get_distro_version(self.fake_ctx_noarg)
|
40
|
-
assert distroversion == '13.04'
|
41
|
-
|
42
|
-
def test_no_teuth_config(self):
|
43
|
-
self.fake_ctx = Mock()
|
44
|
-
self.fake_ctx.os_type = None
|
45
|
-
self.fake_ctx.os_version = '13.04'
|
46
|
-
distroversion = get_distro_version(self.fake_ctx)
|
47
|
-
assert distroversion == '13.04'
|
@@ -1,27 +0,0 @@
|
|
1
|
-
from teuthology import misc as teuthology
|
2
|
-
|
3
|
-
class Mock: pass
|
4
|
-
|
5
|
-
class TestGetMultiMachineTypes(object):
|
6
|
-
|
7
|
-
def test_space(self):
|
8
|
-
give = 'burnupi plana vps'
|
9
|
-
expect = ['burnupi','plana','vps']
|
10
|
-
assert teuthology.get_multi_machine_types(give) == expect
|
11
|
-
|
12
|
-
def test_tab(self):
|
13
|
-
give = 'burnupi plana vps'
|
14
|
-
expect = ['burnupi','plana','vps']
|
15
|
-
assert teuthology.get_multi_machine_types(give) == expect
|
16
|
-
|
17
|
-
def test_comma(self):
|
18
|
-
give = 'burnupi,plana,vps'
|
19
|
-
expect = ['burnupi','plana','vps']
|
20
|
-
assert teuthology.get_multi_machine_types(give) == expect
|
21
|
-
|
22
|
-
def test_single(self):
|
23
|
-
give = 'burnupi'
|
24
|
-
expect = ['burnupi']
|
25
|
-
assert teuthology.get_multi_machine_types(give) == expect
|
26
|
-
|
27
|
-
|
@@ -1,60 +0,0 @@
|
|
1
|
-
from teuthology import job_status
|
2
|
-
|
3
|
-
|
4
|
-
class TestJobStatus(object):
|
5
|
-
def test_get_only_success_true(self):
|
6
|
-
summary = dict(success=True)
|
7
|
-
status = job_status.get_status(summary)
|
8
|
-
assert status == 'pass'
|
9
|
-
|
10
|
-
def test_get_only_success_false(self):
|
11
|
-
summary = dict(success=False)
|
12
|
-
status = job_status.get_status(summary)
|
13
|
-
assert status == 'fail'
|
14
|
-
|
15
|
-
def test_get_status_pass(self):
|
16
|
-
summary = dict(status='pass')
|
17
|
-
status = job_status.get_status(summary)
|
18
|
-
assert status == 'pass'
|
19
|
-
|
20
|
-
def test_get_status_fail(self):
|
21
|
-
summary = dict(status='fail')
|
22
|
-
status = job_status.get_status(summary)
|
23
|
-
assert status == 'fail'
|
24
|
-
|
25
|
-
def test_get_status_dead(self):
|
26
|
-
summary = dict(status='dead')
|
27
|
-
status = job_status.get_status(summary)
|
28
|
-
assert status == 'dead'
|
29
|
-
|
30
|
-
def test_get_status_none(self):
|
31
|
-
summary = dict()
|
32
|
-
status = job_status.get_status(summary)
|
33
|
-
assert status is None
|
34
|
-
|
35
|
-
def test_set_status_pass(self):
|
36
|
-
summary = dict()
|
37
|
-
job_status.set_status(summary, 'pass')
|
38
|
-
assert summary == dict(status='pass', success=True)
|
39
|
-
|
40
|
-
def test_set_status_dead(self):
|
41
|
-
summary = dict()
|
42
|
-
job_status.set_status(summary, 'dead')
|
43
|
-
assert summary == dict(status='dead', success=False)
|
44
|
-
|
45
|
-
def test_set_then_get_status_dead(self):
|
46
|
-
summary = dict()
|
47
|
-
job_status.set_status(summary, 'dead')
|
48
|
-
status = job_status.get_status(summary)
|
49
|
-
assert status == 'dead'
|
50
|
-
|
51
|
-
def test_set_status_none(self):
|
52
|
-
summary = dict()
|
53
|
-
job_status.set_status(summary, None)
|
54
|
-
assert summary == dict()
|
55
|
-
|
56
|
-
def test_legacy_fail(self):
|
57
|
-
summary = dict(success=True)
|
58
|
-
summary['success'] = False
|
59
|
-
status = job_status.get_status(summary)
|
60
|
-
assert status == 'fail'
|
teuthology/test/test_ls.py
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
import pytest
|
2
|
-
|
3
|
-
from unittest.mock import patch, Mock
|
4
|
-
|
5
|
-
from teuthology import ls
|
6
|
-
|
7
|
-
|
8
|
-
class TestLs(object):
|
9
|
-
""" Tests for teuthology.ls """
|
10
|
-
|
11
|
-
@patch('os.path.isdir')
|
12
|
-
@patch('os.listdir')
|
13
|
-
def test_get_jobs(self, m_listdir, m_isdir):
|
14
|
-
m_listdir.return_value = ["1", "a", "3"]
|
15
|
-
m_isdir.return_value = True
|
16
|
-
results = ls.get_jobs("some/archive/dir")
|
17
|
-
assert results == ["1", "3"]
|
18
|
-
|
19
|
-
@patch("yaml.safe_load_all")
|
20
|
-
@patch("teuthology.ls.get_jobs")
|
21
|
-
def test_ls(self, m_get_jobs, m_safe_load_all):
|
22
|
-
m_get_jobs.return_value = ["1", "2"]
|
23
|
-
m_safe_load_all.return_value = [{"failure_reason": "reasons"}]
|
24
|
-
ls.ls("some/archive/div", True)
|
25
|
-
|
26
|
-
@patch("teuthology.ls.open")
|
27
|
-
@patch("teuthology.ls.get_jobs")
|
28
|
-
def test_ls_ioerror(self, m_get_jobs, m_open):
|
29
|
-
m_get_jobs.return_value = ["1", "2"]
|
30
|
-
m_open.side_effect = IOError()
|
31
|
-
with pytest.raises(IOError):
|
32
|
-
ls.ls("some/archive/dir", True)
|
33
|
-
|
34
|
-
@patch("teuthology.ls.open")
|
35
|
-
@patch("os.popen")
|
36
|
-
@patch("os.path.isdir")
|
37
|
-
@patch("os.path.isfile")
|
38
|
-
def test_print_debug_info(self, m_isfile, m_isdir, m_popen, m_open):
|
39
|
-
m_isfile.return_value = True
|
40
|
-
m_isdir.return_value = True
|
41
|
-
m_popen.return_value = Mock()
|
42
|
-
cmdline = Mock()
|
43
|
-
cmdline.find = Mock(return_value=0)
|
44
|
-
m1 = Mock()
|
45
|
-
m2 = Mock()
|
46
|
-
m2.read = Mock(return_value=cmdline)
|
47
|
-
m_open.side_effect = [m1, m2]
|
48
|
-
ls.print_debug_info("the_job", "job/dir", "some/archive/dir")
|