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