~andrewjbeach/juju-ci-tools/make-local-patcher

« back to all changes in this revision

Viewing changes to tests/test_run_deployer.py

Handle LoggedException in quickstart_deploy, assess_bootstrap.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
from argparse import Namespace
2
2
import logging
3
3
import os
4
 
import pickle
5
4
import stat
6
5
import subprocess
7
6
from tempfile import NamedTemporaryFile
15
14
 
16
15
from jujupy import (
17
16
    EnvJujuClient,
18
 
    JujuData,
 
17
    SimpleEnvironment,
19
18
    )
20
19
from run_deployer import (
21
20
    apply_condition,
27
26
    parse_args,
28
27
    )
29
28
import tests
30
 
from tests.test_jujupy import fake_juju_client
 
29
from tests.test_jujupy import FakeJujuClient
31
30
 
32
31
 
33
32
class TestParseArgs(tests.TestCase):
40
39
        self.assertEqual(args.juju_bin, 'new/bin/juju')
41
40
        self.assertEqual(args.logs, '/tmp/logs')
42
41
        self.assertEqual(args.temp_env_name, 'test_job')
43
 
        self.assertEqual(args.allow_native_deploy, False)
44
42
        self.assertEqual(args.bundle_name, None)
45
43
        self.assertEqual(args.health_cmd, None)
46
44
        self.assertEqual(args.keep_env, False)
51
49
        self.assertEqual(args.verbose, logging.INFO)
52
50
        self.assertEqual(args.upgrade, False)
53
51
        self.assertEqual(args.upgrade_condition, None)
54
 
        self.assertEqual(args.agent_timeout, 1200)
55
 
        self.assertEqual(args.workload_timeout, 1800)
56
 
 
57
 
    def test_allow_native_bundle(self):
58
 
        args = parse_args(['./bundle/path', 'an_env', './juju', './logs',
59
 
                           'temp_env', '--allow-native-deploy'])
60
 
        self.assertEqual(args.bundle_path, './bundle/path')
61
 
        self.assertEqual(args.env, 'an_env')
62
 
        self.assertEqual(args.juju_bin, './juju')
63
 
        self.assertEqual(args.logs, './logs')
64
 
        self.assertEqual(args.temp_env_name, 'temp_env')
65
 
        self.assertEqual(args.allow_native_deploy, True)
66
 
 
67
 
    def test_native_bundle_no_name(self):
68
 
        with tests.parse_error(self) as stderr:
69
 
            parse_args(['./bundle/path', 'an_env', './juju', './logs',
70
 
                        'temp_env', '--allow-native-deploy',
71
 
                        '--bundle-name', 'specific_bundle'])
72
 
        self.assertRegexpMatches(
73
 
            stderr.getvalue(),
74
 
            'error: cannot supply bundle name with native juju deploying$')
75
52
 
76
53
 
77
54
class TestMain(tests.FakeHomeTestCase):
78
55
 
79
56
    def test_basic_args(self):
80
57
        args = ['bundles', 'an-env', '/bin/juju', 'logs', 'deployer-env']
81
 
        env = JujuData('an-env')
82
 
        client = EnvJujuClient(env, '1.234-76', None)
83
 
        with patch('run_deployer.client_from_config',
84
 
                   return_value=client) as c_mock:
85
 
            with patch('run_deployer.boot_context'):
86
 
                with patch('run_deployer.assess_deployer') as ad_mock:
87
 
                    main(args)
88
 
        c_mock.assert_called_once_with('an-env', '/bin/juju', debug=False,
89
 
                                       soft_deadline=None)
90
 
        ad_mock.assert_called_once_with(parse_args(args), client, 1200, 1800)
91
 
 
92
 
    def test_basic_args_native_deploy(self):
93
 
        args = ['mediawiki-scalable.yaml', 'an-env', '/bin/juju', 'logs',
94
 
                'deployer-env', '--allow-native-deploy',
95
 
                '--bundle-verification-script',
96
 
                'verify_mediawiki_bundle.py']
97
 
        env = JujuData('an-env')
98
 
        client = EnvJujuClient(env, '1.234-76', None)
99
 
        with patch('run_deployer.client_from_config',
100
 
                   return_value=client) as c_mock:
101
 
            with patch('run_deployer.boot_context'):
102
 
                with patch('run_deployer.assess_deployer') as ad_mock:
103
 
                    with patch('run_deployer.run_command') as mb_mock:
 
58
        env = SimpleEnvironment('an-env')
 
59
        client = EnvJujuClient(env, '1.234-76', None)
 
60
        with patch('jujupy.SimpleEnvironment.from_config',
 
61
                   return_value=env) as e_mock:
 
62
            with patch('jujupy.EnvJujuClient.by_version',
 
63
                       return_value=client) as c_mock:
 
64
                with patch('run_deployer.boot_context'):
 
65
                    with patch('run_deployer.assess_deployer') as ad_mock:
104
66
                        main(args)
105
 
        c_mock.assert_called_once_with('an-env', '/bin/juju', debug=False,
106
 
                                       soft_deadline=None)
107
 
        ad_mock.assert_called_once_with(parse_args(args), client, 1200, 1800)
108
 
        client_ser = pickle.dumps(client)
109
 
        mb_mock.assert_called_once_with(['verify_mediawiki_bundle.py',
110
 
                                         client_ser])
111
 
 
112
 
    def test_basic_args_native_deploy_landscape(self):
113
 
        args = ['cs:~landscape/bundle/landscape-scalable', 'an-env',
114
 
                '/bin/juju', 'logs', 'deployer-env',
115
 
                '--allow-native-deploy',
116
 
                '--bundle-verification-script',
117
 
                'verify_landscape_bundle.py']
118
 
        env = JujuData('an-env')
119
 
        client = EnvJujuClient(env, '1.234-76', None)
120
 
        with patch('run_deployer.client_from_config',
121
 
                   return_value=client) as c_mock:
122
 
            with patch('run_deployer.boot_context'):
123
 
                with patch('run_deployer.assess_deployer') as ad_mock:
124
 
                        with patch('run_deployer.run_command') as rc:
125
 
                            main(args)
126
 
        c_mock.assert_called_once_with('an-env', '/bin/juju', debug=False,
127
 
                                       soft_deadline=None)
128
 
        ad_mock.assert_called_once_with(parse_args(args), client, 1200, 1800)
129
 
        client_ser = pickle.dumps(client)
130
 
        rc.assert_called_once_with(['verify_landscape_bundle.py',
131
 
                                   client_ser])
 
67
        e_mock.assert_called_once_with('an-env')
 
68
        c_mock.assert_called_once_with(env, '/bin/juju', debug=False)
 
69
        ad_mock.assert_called_once_with(parse_args(args), client)
132
70
 
133
71
 
134
72
class TestAssessDeployer(tests.TestCase):
135
73
 
136
 
    @staticmethod
137
 
    def make_args(temp_env_name='foo', env='bar', series=None, agent_url=None,
138
 
                  agent_stream=None, juju_bin='', logs=None, keep_env=False,
139
 
                  health_cmd=None, debug=False, bundle_path='bundle.yaml',
140
 
                  bundle_name='bu', verbose=logging.INFO, region=None,
141
 
                  upgrade=False, upgrade_condition=None,
142
 
                  allow_native_deploy=False):
143
 
        return Namespace(
144
 
            temp_env_name=temp_env_name, env=env, series=series,
145
 
            agent_url=agent_url, agent_stream=agent_stream, juju_bin=juju_bin,
146
 
            logs=logs, keep_env=keep_env, health_cmd=health_cmd, debug=debug,
147
 
            bundle_path=bundle_path, bundle_name=bundle_name, verbose=verbose,
148
 
            region=region, upgrade=upgrade,
149
 
            allow_native_deploy=allow_native_deploy,
150
 
            upgrade_condition=upgrade_condition)
151
 
 
152
74
    def test_health(self):
153
 
        args = self.make_args(health_cmd='/tmp/check')
 
75
        args = Namespace(
 
76
            temp_env_name='foo', env='bar', series=None, agent_url=None,
 
77
            agent_stream=None, juju_bin='', logs=None, keep_env=False,
 
78
            health_cmd='/tmp/check', debug=False, bundle_path='bundle.yaml',
 
79
            bundle_name='bu', verbose=logging.INFO, region=None, upgrade=False)
154
80
        client_mock = Mock(spec=EnvJujuClient)
155
81
        with patch('run_deployer.check_health', autospec=True) as ch_mock:
156
 
            assess_deployer(args, client_mock, 600, 1800)
 
82
            assess_deployer(args, client_mock)
157
83
        client_mock.deployer.assert_called_once_with('bundle.yaml', 'bu')
158
 
        client_mock.wait_for_workloads.assert_called_once_with(timeout=1800)
159
 
        environ = client_mock._shell_environ()
160
 
        ch_mock.assert_called_once_with('/tmp/check', 'foo', environ)
 
84
        client_mock.wait_for_workloads.assert_called_once_with()
 
85
        ch_mock.assert_called_once_with('/tmp/check', 'foo')
161
86
 
162
87
    def test_upgrade(self):
163
 
        args = self.make_args(juju_bin='new/juju', upgrade=True)
 
88
        args = Namespace(
 
89
            temp_env_name='foo', env='bar', series=None, agent_url=None,
 
90
            agent_stream=None, juju_bin='new/juju', logs=None, keep_env=False,
 
91
            health_cmd=None, debug=False, bundle_path='bundle.yaml',
 
92
            bundle_name='bu', verbose=logging.INFO, region=None, upgrade=True,
 
93
            upgrade_condition=[])
164
94
        client_mock = Mock(spec=EnvJujuClient)
165
95
        with patch('run_deployer.assess_upgrade', autospec=True) as au_mock:
166
 
            assess_deployer(args, client_mock, 600, 1800)
 
96
            assess_deployer(args, client_mock)
167
97
        client_mock.deployer.assert_called_once_with('bundle.yaml', 'bu')
168
 
        client_mock.show_status.assert_called_once_with()
 
98
        client_mock.juju.assert_called_once_with('status', ())
169
99
        au_mock.assert_called_once_with(client_mock, 'new/juju')
170
100
        self.assertEqual(
171
 
            client_mock.wait_for_workloads.call_args_list,
172
 
            [call(timeout=1800), call()])
 
101
            client_mock.wait_for_workloads.call_args_list, [call()] * 2)
173
102
 
174
103
    def test_upgrade_and_health(self):
175
 
        args = self.make_args(health_cmd='/tmp/check', juju_bin='new/juju',
176
 
                              upgrade=True)
 
104
        args = Namespace(
 
105
            temp_env_name='foo', env='bar', series=None, agent_url=None,
 
106
            agent_stream=None, juju_bin='new/juju', logs=None, keep_env=False,
 
107
            health_cmd='/tmp/check', debug=False, bundle_path='bundle.yaml',
 
108
            bundle_name='bu', verbose=logging.INFO, region=None, upgrade=True,
 
109
            upgrade_condition=[])
177
110
        client_mock = Mock(spec=EnvJujuClient)
178
111
        with patch('run_deployer.assess_upgrade', autospec=True) as au_mock:
179
112
            with patch('run_deployer.check_health', autospec=True) as ch_mock:
180
 
                assess_deployer(args, client_mock, 600, 1800)
 
113
                assess_deployer(args, client_mock)
181
114
        client_mock.deployer.assert_called_once_with('bundle.yaml', 'bu')
182
 
        client_mock.show_status.assert_called_once_with()
 
115
        client_mock.juju.assert_called_once_with('status', ())
183
116
        au_mock.assert_called_once_with(client_mock, 'new/juju')
184
117
        self.assertEqual(
185
 
            client_mock.wait_for_workloads.call_args_list,
186
 
            [call(timeout=1800), call()])
187
 
        environ = client_mock._shell_environ()
 
118
            client_mock.wait_for_workloads.call_args_list, [call()] * 2)
188
119
        self.assertEqual(
189
 
            ch_mock.call_args_list, [call('/tmp/check', 'foo', environ)] * 2)
 
120
            ch_mock.call_args_list, [call('/tmp/check', 'foo')] * 2)
190
121
 
 
122
    @patch('run_deployer.SimpleEnvironment.from_config')
191
123
    @patch('run_deployer.boot_context', autospec=True)
192
124
    def test_run_deployer_upgrade(self, *args):
193
 
        args = self.make_args(
194
 
            juju_bin='baz/juju', upgrade=True,
 
125
        args = Namespace(
 
126
            env='foo', juju_bin='baz/juju', logs=None, temp_env_name='foo_t',
 
127
            bundle_path='bundle.yaml', bundle_name='bundle',
 
128
            health_cmd=None, debug=False, upgrade=True,
195
129
            upgrade_condition=['bla/0:clock_skew', 'foo/1:fill_disk'])
196
 
        client = fake_juju_client()
197
 
        client.bootstrap()
198
 
        with patch('run_deployer.client_from_config', return_value=client):
 
130
        client = FakeJujuClient()
 
131
        with patch('run_deployer.EnvJujuClient.by_version',
 
132
                   return_value=client):
199
133
            with patch('run_deployer.apply_condition') as ac_mock:
200
134
                with patch('run_deployer.assess_upgrade') as au_mock:
201
 
                    assess_deployer(args, client, 600, 1800)
 
135
                    assess_deployer(args, client)
202
136
        self.assertEqual(2, ac_mock.call_count)
203
137
        self.assertEqual(
204
138
            ac_mock.call_args_list,
206
140
             call(client, 'foo/1:fill_disk')])
207
141
        au_mock.assert_called_once_with(client, 'baz/juju')
208
142
 
209
 
    def test_allow_native_deploy(self):
210
 
        args = self.make_args(allow_native_deploy=True)
211
 
        client_mock = Mock(spec=EnvJujuClient)
212
 
        assess_deployer(args, client_mock, 600, 1800)
213
 
        client_mock.deploy_bundle.assert_called_once_with('bundle.yaml')
214
 
        client_mock.wait_for_started.assert_called_once_with(timeout=600)
215
 
        client_mock.wait_for_workloads.assert_called_once_with(timeout=1800)
216
 
 
217
143
 
218
144
class FakeRemote():
219
145
    """Fake remote class for testing."""
231
157
class TestApplyCondition(tests.TestCase):
232
158
 
233
159
    def test_apply_condition_clock_skew(self):
234
 
        client = fake_juju_client()
 
160
        client = FakeJujuClient()
235
161
        remote = FakeRemote()
236
162
        with patch('run_deployer.remote_from_unit',
237
163
                   return_value=remote, autospec=True) as ru_mock:
240
166
        self.assertEqual(CLOCK_SKEW_SCRIPT, remote.command)
241
167
 
242
168
    def test_apply_condition_raises_ErrUnitCondition(self):
243
 
        client = fake_juju_client()
 
169
        client = FakeJujuClient()
244
170
        remote = FakeRemote()
245
171
        with patch('run_deployer.remote_from_unit',
246
172
                   return_value=remote) as rfu_mock: