44
44
series: win2012hvr2
50
50
public-address: 10.55.60.2
54
log = logging.getLogger()
55
self.addCleanup(setattr, log, "handlers", 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)
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"
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)
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())
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"
69
78
remote = remote_from_unit(client, unit, series="trusty")
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())
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"
79
88
status = Status.from_text(self.win2012hvr2_status_output)
80
89
remote = remote_from_unit(client, unit, status=status)
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())
87
95
def test_remote_from_address(self):
100
108
self.assertIs(True, remote.is_windows())
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"
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",
119
mock_cmd.assert_called_once_with("ssh", unit, "cat /a/file")
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"
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",
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",
134
mock_cmd.assert_called_once_with("ssh", unit, "cat /a/file")
130
135
mock_run.assert_called_once_with([
132
137
"-o", "User ubuntu",
133
138
"-o", "UserKnownHostsFile /dev/null",
134
139
"-o", "StrictHostKeyChecking no",
135
"-o", "PasswordAuthentication no",
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: .*")
143
147
def test_run_with_address(self):
144
148
remote = remote_from_address("10.55.60.1")
165
168
"-o", "User ubuntu",
166
169
"-o", "UserKnownHostsFile /dev/null",
167
170
"-o", "StrictHostKeyChecking no",
168
"-o", "PasswordAuthentication no",
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"
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([
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",
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
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".*')
226
def test_copy_ipv6(self):
227
remote = remote_from_address("2001:db8::34")
228
self.assertEqual(remote.address, "2001:db8::34")
230
with patch.object(remote, "_run_subprocess") as mock_run:
231
remote.copy(dest, ["/var/log/*", "~/.config"])
232
mock_run.assert_called_once_with([
236
"-o", "UserKnownHostsFile /dev/null",
237
"-o", "StrictHostKeyChecking no",
238
"-o", "PasswordAuthentication no",
239
"[2001:db8::34]:/var/log/*",
240
"[2001:db8::34]:~/.config",
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"
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"'])
261
def test_run_subprocess_timeout(self):
262
remote = remote_from_address("10.55.60.1")
264
with patch("subprocess.check_output", autospec=True) as mock_co:
265
remote.cat("/a/file")
266
mock_co.assert_called_once_with((
273
"-o", "UserKnownHostsFile /dev/null",
274
"-o", "StrictHostKeyChecking no",
275
"-o", "PasswordAuthentication no",
279
stdin=subprocess.PIPE,
282
244
def test_encoded_copy_to_dir_one(self):
283
245
output = "testfile|K0ktLuECAA==\r\n"
284
246
with temp_dir() as dest: