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

« back to all changes in this revision

Viewing changes to test_remote.py

  • Committer: Martin Packman
  • Date: 2015-07-02 00:59:47 UTC
  • mfrom: (994.4.5 winrm_copy)
  • Revision ID: martin.packman@canonical.com-20150702005947-p0nzw2dja0m1m5rb
Enable windows deployment testing and log collection

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
"""Tests for remote access to juju machines."""
2
2
 
 
3
import logging
3
4
from mock import patch
4
5
import os
 
6
from StringIO import StringIO
5
7
import subprocess
6
 
import sys
 
8
import unittest
7
9
 
8
10
import winrm
9
11
 
10
12
from jujupy import (
11
13
    EnvJujuClient,
12
 
    get_timeout_path,
13
 
    JujuData,
 
14
    SimpleEnvironment,
14
15
    Status,
15
16
)
16
17
from remote import (
18
19
    remote_from_unit,
19
20
    WinRmRemote,
20
21
)
21
 
import tests
22
22
from utility import (
23
23
    temp_dir,
24
24
)
25
25
 
26
26
 
27
 
class TestRemote(tests.FakeHomeTestCase):
 
27
class TestRemote(unittest.TestCase):
28
28
 
29
29
    precise_status_output = """\
30
30
    machines:
31
31
        "1":
32
32
            series: precise
33
 
    applications:
34
 
        a-application:
 
33
    services:
 
34
        a-service:
35
35
            units:
36
 
                a-application/0:
 
36
                a-service/0:
37
37
                    machine: "1"
38
38
                    public-address: 10.55.60.1
39
39
    """
42
42
    machines:
43
43
        "2":
44
44
            series: win2012hvr2
45
 
    applications:
46
 
        a-application:
 
45
    services:
 
46
        a-service:
47
47
            units:
48
 
                a-application/0:
 
48
                a-service/0:
49
49
                    machine: "2"
50
50
                    public-address: 10.55.60.2
51
51
    """
52
52
 
 
53
    def setUp(self):
 
54
        log = logging.getLogger()
 
55
        self.addCleanup(setattr, log, "handlers", log.handlers)
 
56
        log.handlers = []
 
57
        self.log_stream = StringIO()
 
58
        handler = logging.StreamHandler(self.log_stream)
 
59
        handler.setFormatter(logging.Formatter("%(levelname)s %(message)s"))
 
60
        log.addHandler(handler)
 
61
 
53
62
    def test_remote_from_unit(self):
54
 
        env = JujuData("an-env", {"type": "nonlocal"})
 
63
        env = SimpleEnvironment("an-env", {"type": "nonlocal"})
55
64
        client = EnvJujuClient(env, None, None)
56
 
        unit = "a-application/0"
 
65
        unit = "a-service/0"
57
66
        with patch.object(client, "get_status", autospec=True) as st:
58
67
            st.return_value = Status.from_text(self.precise_status_output)
59
68
            remote = remote_from_unit(client, unit)
60
69
        self.assertEqual(
61
70
            repr(remote),
62
 
            "<SSHRemote env='an-env' unit='a-application/0'>")
 
71
            "<SSHRemote env='an-env' unit='a-service/0'>")
63
72
        self.assertIs(False, remote.is_windows())
64
73
 
65
74
    def test_remote_from_unit_with_series(self):
66
 
        env = JujuData("an-env", {"type": "nonlocal"})
 
75
        env = SimpleEnvironment("an-env", {"type": "nonlocal"})
67
76
        client = EnvJujuClient(env, None, None)
68
 
        unit = "a-application/0"
 
77
        unit = "a-service/0"
69
78
        remote = remote_from_unit(client, unit, series="trusty")
70
79
        self.assertEqual(
71
80
            repr(remote),
72
 
            "<SSHRemote env='an-env' unit='a-application/0'>")
 
81
            "<SSHRemote env='an-env' unit='a-service/0'>")
73
82
        self.assertIs(False, remote.is_windows())
74
83
 
75
84
    def test_remote_from_unit_with_status(self):
76
 
        env = JujuData("an-env", {"type": "nonlocal"})
 
85
        env = SimpleEnvironment("an-env", {"type": "nonlocal"})
77
86
        client = EnvJujuClient(env, None, None)
78
 
        unit = "a-application/0"
 
87
        unit = "a-service/0"
79
88
        status = Status.from_text(self.win2012hvr2_status_output)
80
89
        remote = remote_from_unit(client, unit, status=status)
81
90
        self.assertEqual(
82
91
            repr(remote),
83
 
            "<WinRmRemote env='an-env' unit='a-application/0'"
84
 
            " addr='10.55.60.2'>")
 
92
            "<WinRmRemote env='an-env' unit='a-service/0' addr='10.55.60.2'>")
85
93
        self.assertIs(True, remote.is_windows())
86
94
 
87
95
    def test_remote_from_address(self):
100
108
        self.assertIs(True, remote.is_windows())
101
109
 
102
110
    def test_run_with_unit(self):
103
 
        env = JujuData("an-env", {"type": "nonlocal"})
 
111
        env = SimpleEnvironment("an-env", {"type": "nonlocal"})
104
112
        client = EnvJujuClient(env, None, None)
105
 
        unit = "a-application/0"
 
113
        unit = "a-service/0"
106
114
        remote = remote_from_unit(client, unit, series="trusty")
107
115
        with patch.object(client, "get_juju_output") as mock_cmd:
108
116
            mock_cmd.return_value = "contents of /a/file"
109
117
            output = remote.run("cat /a/file")
110
118
            self.assertEqual(output, "contents of /a/file")
111
 
        mock_cmd.assert_called_once_with("ssh", unit, "cat /a/file",
112
 
                                         timeout=120)
 
119
        mock_cmd.assert_called_once_with("ssh", unit, "cat /a/file")
113
120
 
114
121
    def test_run_with_unit_fallback(self):
115
 
        env = JujuData("an-env", {"type": "nonlocal"})
 
122
        env = SimpleEnvironment("an-env", {"type": "nonlocal"})
116
123
        client = EnvJujuClient(env, None, None)
117
 
        unit = "a-application/0"
 
124
        unit = "a-service/0"
118
125
        with patch.object(client, "get_status") as st:
119
126
            st.return_value = Status.from_text(self.precise_status_output)
120
127
            remote = remote_from_unit(client, unit)
121
 
            with patch.object(client, "get_juju_output") as mock_gjo:
122
 
                mock_gjo.side_effect = subprocess.CalledProcessError(1, "ssh",
123
 
                                                                     output="")
 
128
            with patch.object(client, "get_juju_output") as mock_cmd:
 
129
                mock_cmd.side_effect = subprocess.CalledProcessError(1, "ssh")
124
130
                with patch.object(remote, "_run_subprocess") as mock_run:
125
131
                    mock_run.return_value = "contents of /a/file"
126
132
                    output = remote.run("cat /a/file")
127
133
                    self.assertEqual(output, "contents of /a/file")
128
 
        mock_gjo.assert_called_once_with("ssh", unit, "cat /a/file",
129
 
                                         timeout=120)
 
134
        mock_cmd.assert_called_once_with("ssh", unit, "cat /a/file")
130
135
        mock_run.assert_called_once_with([
131
136
            "ssh",
132
137
            "-o", "User ubuntu",
133
138
            "-o", "UserKnownHostsFile /dev/null",
134
139
            "-o", "StrictHostKeyChecking no",
135
 
            "-o", "PasswordAuthentication no",
136
140
            "10.55.60.1",
137
141
            "cat /a/file",
138
142
        ])
139
143
        self.assertRegexpMatches(
140
144
            self.log_stream.getvalue(),
141
 
            "(?m)^WARNING juju ssh to 'a-application/0' failed, .*")
 
145
            "(?m)^WARNING juju ssh to 'a-service/0' failed: .*")
142
146
 
143
147
    def test_run_with_address(self):
144
148
        remote = remote_from_address("10.55.60.1")
151
155
            "-o", "User ubuntu",
152
156
            "-o", "UserKnownHostsFile /dev/null",
153
157
            "-o", "StrictHostKeyChecking no",
154
 
            "-o", "PasswordAuthentication no",
155
158
            "10.55.60.1",
156
159
            "cat /a/file",
157
160
        ])
165
168
            "-o", "User ubuntu",
166
169
            "-o", "UserKnownHostsFile /dev/null",
167
170
            "-o", "StrictHostKeyChecking no",
168
 
            "-o", "PasswordAuthentication no",
169
171
            "10.55.60.1",
170
172
            "cat /a/file",
171
173
        ])
172
174
 
173
175
    def test_cat_on_windows(self):
174
 
        env = JujuData("an-env", {"type": "nonlocal"})
 
176
        env = SimpleEnvironment("an-env", {"type": "nonlocal"})
175
177
        client = EnvJujuClient(env, None, None)
176
 
        unit = "a-application/0"
 
178
        unit = "a-service/0"
177
179
        with patch.object(client, "get_status", autospec=True) as st:
178
180
            st.return_value = Status.from_text(self.win2012hvr2_status_output)
179
181
            response = winrm.Response(("contents of /a/file", "",  0))
192
194
            remote.copy(dest, ["/var/log/*", "~/.config"])
193
195
        mock_run.assert_called_once_with([
194
196
            "scp",
195
 
            "-rC",
 
197
            "-C",
196
198
            "-o", "User ubuntu",
197
199
            "-o", "UserKnownHostsFile /dev/null",
198
200
            "-o", "StrictHostKeyChecking no",
199
 
            "-o", "PasswordAuthentication no",
200
201
            "10.55.60.1:/var/log/*",
201
202
            "10.55.60.1:~/.config",
202
203
            "/local/path",
203
204
        ])
204
205
 
205
206
    def test_copy_on_windows(self):
206
 
        env = JujuData("an-env", {"type": "nonlocal"})
 
207
        env = SimpleEnvironment("an-env", {"type": "nonlocal"})
207
208
        client = EnvJujuClient(env, None, None)
208
 
        unit = "a-application/0"
 
209
        unit = "a-service/0"
209
210
        dest = "/local/path"
210
211
        with patch.object(client, "get_status", autospec=True) as st:
211
212
            st.return_value = Status.from_text(self.win2012hvr2_status_output)
223
224
            mock_run.call_args[0][0],
224
225
            r'.*"C:\\logs\\[*]","%APPDATA%\\[*].log".*')
225
226
 
226
 
    def test_copy_ipv6(self):
227
 
        remote = remote_from_address("2001:db8::34")
228
 
        self.assertEqual(remote.address, "2001:db8::34")
229
 
        dest = "/local/path"
230
 
        with patch.object(remote, "_run_subprocess") as mock_run:
231
 
            remote.copy(dest, ["/var/log/*", "~/.config"])
232
 
        mock_run.assert_called_once_with([
233
 
            "scp",
234
 
            "-rC",
235
 
            "-o", "User ubuntu",
236
 
            "-o", "UserKnownHostsFile /dev/null",
237
 
            "-o", "StrictHostKeyChecking no",
238
 
            "-o", "PasswordAuthentication no",
239
 
            "[2001:db8::34]:/var/log/*",
240
 
            "[2001:db8::34]:~/.config",
241
 
            "/local/path",
242
 
        ])
243
 
 
244
227
    def test_run_cmd(self):
245
 
        env = JujuData("an-env", {"type": "nonlocal"})
 
228
        env = SimpleEnvironment("an-env", {"type": "nonlocal"})
246
229
        client = EnvJujuClient(env, None, None)
247
 
        unit = "a-application/0"
 
230
        unit = "a-service/0"
248
231
        with patch.object(client, "get_status", autospec=True) as st:
249
232
            st.return_value = Status.from_text(self.win2012hvr2_status_output)
250
233
            response = winrm.Response(("some out", "some err",  0))
258
241
        mock_run.assert_called_once_with(
259
242
            '"C:\\Program Files\\bin.exe"', ['/IN "Bob\'s Stuff"'])
260
243
 
261
 
    def test_run_subprocess_timeout(self):
262
 
        remote = remote_from_address("10.55.60.1")
263
 
        remote.timeout = 63
264
 
        with patch("subprocess.check_output", autospec=True) as mock_co:
265
 
            remote.cat("/a/file")
266
 
        mock_co.assert_called_once_with((
267
 
            sys.executable,
268
 
            get_timeout_path(),
269
 
            "63.00",
270
 
            "--",
271
 
            "ssh",
272
 
            "-o", "User ubuntu",
273
 
            "-o", "UserKnownHostsFile /dev/null",
274
 
            "-o", "StrictHostKeyChecking no",
275
 
            "-o", "PasswordAuthentication no",
276
 
            "10.55.60.1",
277
 
            "cat /a/file",
278
 
            ),
279
 
            stdin=subprocess.PIPE,
280
 
        )
281
 
 
282
244
    def test_encoded_copy_to_dir_one(self):
283
245
        output = "testfile|K0ktLuECAA==\r\n"
284
246
        with temp_dir() as dest: