Merge lp:~blake-rouse/maas/fix-bug-1324966 into lp:~maas-committers/maas/trunk

Proposed by Blake Rouse
Status: Merged
Approved by: Blake Rouse
Approved revision: no longer in the source branch.
Merged at revision: 2394
Proposed branch: lp:~blake-rouse/maas/fix-bug-1324966
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 201 lines (+125/-10)
2 files modified
src/provisioningserver/custom_hardware/tests/test_virsh.py (+114/-3)
src/provisioningserver/custom_hardware/virsh.py (+11/-7)
To merge this branch: bzr merge lp:~blake-rouse/maas/fix-bug-1324966
Reviewer Review Type Date Requested Status
Raphaël Badin (community) Approve
Review via email: mp+221561@code.launchpad.net

Commit message

Fix invalid attribute references in the VirshSSH class. Added more test for the VirshSSH class.

Description of the change

The VirshSSH class is referencing attributes that were renamed during the code review process. The test did not cover that section of the code, so it went by unnoticed.

I have fixed the attributes and added test's to cover those attributes, and other methods in the VirshSSH class.

To post a comment you must log in.
Revision history for this message
Raphaël Badin (rvb) wrote :

Looks good. Couple of comments inline.

review: Approve
Revision history for this message
Blake Rouse (blake-rouse) wrote :

Thanks for the quick review. I made the recommended changes.

Revision history for this message
Julian Edwards (julian-edwards) wrote :

On 03/06/14 01:00, Raphaël Badin wrote:
> It's not always possible but we usually try to make the name of each test a bit more readable than this one it. This might seem a detail but it's really useful when reviewing tons of tests. In this instance I'd rename the test into "test_login_with_sshey". This is true for most of the tests in this branch.

I'd go a bit further with that. The test function names should
generally be of the format:

test_doing_foo_results_in_bar

IOW, test_login_with_sshkey should be
test_login_with_sshkey_attempts_connection, for example.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/provisioningserver/custom_hardware/tests/test_virsh.py'
2--- src/provisioningserver/custom_hardware/tests/test_virsh.py 2014-05-21 17:03:00 +0000
3+++ src/provisioningserver/custom_hardware/tests/test_virsh.py 2014-06-02 15:21:14 +0000
4@@ -55,11 +55,122 @@
5 class TestVirshSSH(MAASTestCase):
6 """Tests for `VirshSSH`."""
7
8+ def configure_virshssh_pexpect(self, inputs=None):
9+ """Configures the VirshSSH class to use 'cat' process
10+ for testing instead of the actual virsh."""
11+ conn = virsh.VirshSSH(timeout=1)
12+ self.addCleanup(conn.close)
13+ self.patch(conn, '_execute')
14+ conn._spawn('cat')
15+ if inputs is not None:
16+ for line in inputs:
17+ conn.sendline(line)
18+ return conn
19+
20 def configure_virshssh(self, output):
21 self.patch(virsh.VirshSSH, 'run').return_value = output
22 return virsh.VirshSSH()
23
24- def test_virssh_mac_addresses_returns_list(self):
25+ def test_login_prompt(self):
26+ virsh_outputs = [
27+ 'virsh # '
28+ ]
29+ conn = self.configure_virshssh_pexpect(virsh_outputs)
30+ self.assertTrue(conn.login(poweraddr=None))
31+
32+ def test_login_with_sshkey(self):
33+ virsh_outputs = [
34+ "The authenticity of host '127.0.0.1' can't be established.",
35+ "ECDSA key fingerprint is "
36+ "00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff.",
37+ "Are you sure you want to continue connecting (yes/no)? ",
38+ ]
39+ conn = self.configure_virshssh_pexpect(virsh_outputs)
40+ mock_sendline = self.patch(conn, 'sendline')
41+ conn.login(poweraddr=None)
42+ self.assertThat(mock_sendline, MockCalledOnceWith('yes'))
43+
44+ def test_login_with_password(self):
45+ virsh_outputs = [
46+ "ubuntu@%s's password: " % factory.getRandomIPAddress(),
47+ ]
48+ conn = self.configure_virshssh_pexpect(virsh_outputs)
49+ fake_password = factory.make_name('password')
50+ mock_sendline = self.patch(conn, 'sendline')
51+ conn.login(poweraddr=None, password=fake_password)
52+ self.assertThat(mock_sendline, MockCalledOnceWith(fake_password))
53+
54+ def test_login_missing_password(self):
55+ virsh_outputs = [
56+ "ubuntu@%s's password: " % factory.getRandomIPAddress(),
57+ ]
58+ conn = self.configure_virshssh_pexpect(virsh_outputs)
59+ mock_close = self.patch(conn, 'close')
60+ self.assertFalse(conn.login(poweraddr=None, password=None))
61+ mock_close.assert_called()
62+
63+ def test_login_invalid(self):
64+ virsh_outputs = [
65+ factory.getRandomString(),
66+ ]
67+ conn = self.configure_virshssh_pexpect(virsh_outputs)
68+ mock_close = self.patch(conn, 'close')
69+ self.assertFalse(conn.login(poweraddr=None))
70+ mock_close.assert_called()
71+
72+ def test_logout(self):
73+ conn = self.configure_virshssh_pexpect()
74+ mock_sendline = self.patch(conn, 'sendline')
75+ mock_close = self.patch(conn, 'close')
76+ conn.logout()
77+ self.assertThat(mock_sendline, MockCalledOnceWith('quit'))
78+ mock_close.assert_called()
79+
80+ def test_prompt(self):
81+ virsh_outputs = [
82+ 'virsh # '
83+ ]
84+ conn = self.configure_virshssh_pexpect(virsh_outputs)
85+ self.assertTrue(conn.prompt())
86+
87+ def test_invalid_prompt(self):
88+ virsh_outputs = [
89+ factory.getRandomString()
90+ ]
91+ conn = self.configure_virshssh_pexpect(virsh_outputs)
92+ self.assertFalse(conn.prompt())
93+
94+ def test_run(self):
95+ cmd = ['list', '--all', '--name']
96+ expected = ' '.join(cmd)
97+ names = [factory.make_name('machine') for _ in range(3)]
98+ conn = self.configure_virshssh_pexpect()
99+ conn.before = '\n'.join([expected] + names)
100+ mock_sendline = self.patch(conn, 'sendline')
101+ mock_prompt = self.patch(conn, 'prompt')
102+ output = conn.run(cmd)
103+ self.assertThat(mock_sendline, MockCalledOnceWith(expected))
104+ mock_prompt.assert_called()
105+ self.assertEqual('\n'.join(names), output)
106+
107+ def test_list(self):
108+ names = [factory.make_name('machine') for _ in range(3)]
109+ conn = self.configure_virshssh('\n'.join(names))
110+ expected = conn.list()
111+ self.assertItemsEqual(names, expected)
112+
113+ def test_get_state(self):
114+ state = factory.make_name('state')
115+ conn = self.configure_virshssh(state)
116+ expected = conn.get_state('')
117+ self.assertEqual(state, expected)
118+
119+ def test_get_state_error(self):
120+ conn = self.configure_virshssh('error')
121+ expected = conn.get_state('')
122+ self.assertEqual(None, expected)
123+
124+ def test_mac_addresses_returns_list(self):
125 macs = [factory.getRandomMACAddress() for _ in range(2)]
126 output = SAMPLE_IFLIST % (macs[0], macs[1])
127 conn = self.configure_virshssh(output)
128@@ -67,14 +178,14 @@
129 for i in range(2):
130 self.assertEqual(macs[i], expected[i])
131
132- def test_virssh_get_arch_returns_valid(self):
133+ def test_get_arch_returns_valid(self):
134 arch = factory.make_name('arch')
135 output = SAMPLE_DUMPXML % arch
136 conn = self.configure_virshssh(output)
137 expected = conn.get_arch('')
138 self.assertEqual(arch, expected)
139
140- def test_virssh_get_arch_returns_valid_fixed(self):
141+ def test_get_arch_returns_valid_fixed(self):
142 arch = random.choice(virsh.ARCH_FIX.keys())
143 fixed_arch = virsh.ARCH_FIX[arch]
144 output = SAMPLE_DUMPXML % arch
145
146=== modified file 'src/provisioningserver/custom_hardware/virsh.py'
147--- src/provisioningserver/custom_hardware/virsh.py 2014-05-21 17:03:00 +0000
148+++ src/provisioningserver/custom_hardware/virsh.py 2014-06-02 15:21:14 +0000
149@@ -52,8 +52,9 @@
150 PROMPT_PASSWORD,
151 PROMPT,
152 PROMPT_DENIED,
153+ PROMPT_CLOSED,
154 pexpect.TIMEOUT,
155- PROMPT_CLOSED
156+ pexpect.EOF,
157 ]
158
159 I_PROMPT = PROMPTS.index(PROMPT)
160@@ -65,24 +66,27 @@
161 None, timeout=timeout, maxread=maxread)
162 self.name = '<virssh>'
163
164+ def _execute(self, poweraddr):
165+ """Spawns the pexpect command."""
166+ cmd = 'virsh --connect %s' % poweraddr
167+ self._spawn(cmd)
168+
169 def login(self, poweraddr, password=None):
170 """Starts connection to virsh."""
171- cmd = 'virsh --connect %s' % poweraddr
172- super(VirshSSH, self)._spawn(cmd)
173-
174+ self._execute(poweraddr)
175 i = self.expect(self.PROMPTS, timeout=10)
176 if i == self.I_PROMPT_SSHKEY:
177 # New certificate, lets always accept but if
178 # it changes it will fail to login.
179 self.sendline("yes")
180- i = self.expect(self.EXPECT_PROMPTS)
181+ i = self.expect(self.PROMPTS)
182 elif i == self.I_PROMPT_PASSWORD:
183 # Requesting password, give it if available.
184 if password is None:
185 self.close()
186 return False
187 self.sendline(password)
188- i = self.expect(self.EXPECT_PROMPTS)
189+ i = self.expect(self.PROMPTS)
190
191 if i != self.I_PROMPT:
192 # Something bad happened, either disconnect,
193@@ -100,7 +104,7 @@
194 """Waits for virsh prompt."""
195 if timeout is None:
196 timeout = self.timeout
197- i = self.expect([self.VIRSH_PROMPT, pexpect.TIMEOUT], timeout=timeout)
198+ i = self.expect([self.PROMPT, pexpect.TIMEOUT], timeout=timeout)
199 if i == 1:
200 return False
201 return True