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

Proposed by Blake Rouse
Status: Merged
Approved by: Blake Rouse
Approved revision: no longer in the source branch.
Merged at revision: 2282
Proposed branch: lp:~blake-rouse/maas/fix-bug-1324966-1.5
Merge into: lp:maas/1.5
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-1.5
Reviewer Review Type Date Requested Status
Blake Rouse (community) Approve
Review via email: mp+221755@code.launchpad.net

Commit message

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

To post a comment you must log in.
Revision history for this message
Blake Rouse (blake-rouse) wrote :

Backport, self approve.

review: Approve

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:30:26 +0000
3+++ src/provisioningserver/custom_hardware/tests/test_virsh.py 2014-06-02 15:43:50 +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:30:26 +0000
148+++ src/provisioningserver/custom_hardware/virsh.py 2014-06-02 15:43:50 +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

Subscribers

People subscribed via source and target branches

to all changes: