Merge lp:~jml/lp-dev-utils/fix-tests into lp:lp-dev-utils

Proposed by Jonathan Lange on 2012-04-13
Status: Merged
Approved by: Aaron Bentley on 2012-04-13
Approved revision: 112
Merged at revision: 107
Proposed branch: lp:~jml/lp-dev-utils/fix-tests
Merge into: lp:lp-dev-utils
Diff against target: 246 lines (+97/-25)
5 files modified
.bzrignore (+1/-0)
.testr.conf (+3/-0)
README (+42/-0)
ec2test/tests/test_ec2instance.py (+48/-24)
ec2test/tests/test_remote.py (+3/-1)
To merge this branch: bzr merge lp:~jml/lp-dev-utils/fix-tests
Reviewer Review Type Date Requested Status
Aaron Bentley (community) 2012-04-13 Approve on 2012-04-13
Review via email: mp+101916@code.launchpad.net

Description of the Change

I wanted to add a --public-ip option so I can run 'ec2 demo' from Millbank. I didn't want to start without a passing test suite though. This gets us there.

Main issues:
 * documenting that PYTHONPATH needs to be set (this lets the subprocesses spawned in the daemonization tests find the code that we're testing)
 * removing the dependency on FakeMethod

To post a comment you must log in.
lp:~jml/lp-dev-utils/fix-tests updated on 2012-04-13
112. By Jonathan Lange on 2012-04-13

Set the PYTHONPATH when spawning the daemon in tests, thus eliminating the need
for an explicit PYTHONPATH when running tests.

Aaron Bentley (abentley) wrote :

This is a clear improvement.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2009-10-16 03:03:54 +0000
3+++ .bzrignore 2012-04-13 15:12:22 +0000
4@@ -1,1 +1,2 @@
5 .launchpadlib
6+_trial_temp
7
8=== added file '.testr.conf'
9--- .testr.conf 1970-01-01 00:00:00 +0000
10+++ .testr.conf 2012-04-13 15:12:22 +0000
11@@ -0,0 +1,3 @@
12+[DEFAULT]
13+test_command=PYTHONPATH=.:$PYTHONPATH python -m subunit.run discover $IDLIST
14+test_id_list_default=ec2test
15
16=== added file 'README'
17--- README 1970-01-01 00:00:00 +0000
18+++ README 2012-04-13 15:12:22 +0000
19@@ -0,0 +1,42 @@
20+==============
21+ lp-dev-utils
22+==============
23+Tools for hacking on Launchpad
24+==============================
25+
26+ec2
27+===
28+
29+``ec2`` is a utility for deploying Launchpad to Amazon's EC2 service and for
30+running tests there. Run ``ec2 --help`` to get some more information.
31+
32+Dependencies
33+------------
34+
35+Note that this list probably over-specifies dependencies. However, this has
36+been known to work on an Ubuntu 10.04 LTS machine.
37+
38+ * launchpad-developer-dependencies
39+ * python-bzrlib.tests
40+ * bzr-pqm
41+
42+Running tests
43+-------------
44+
45+Tests can be run with any standard Python test runner. ``nosetests`` and
46+``trial`` have been known to work, for example::
47+
48+ $ nosetests
49+
50+or::
51+
52+ $ trial ec2test
53+
54+If you have ``python-testrepository`` and ``discover`` installed, you can run
55+the tests using ``testr``::
56+
57+ $ testr init
58+ $ testr run
59+ Ran 84 (+84) tests in 51.723s (+51.651s)
60+ FAILED (id=1)
61+
62
63=== modified file 'ec2test/tests/test_ec2instance.py'
64--- ec2test/tests/test_ec2instance.py 2012-02-24 20:23:36 +0000
65+++ ec2test/tests/test_ec2instance.py 2012-04-13 15:12:22 +0000
66@@ -9,13 +9,15 @@
67 from unittest import TestCase
68
69 from ec2test.instance import EC2Instance
70-from lp.testing.fakemethod import FakeMethod
71
72
73 class FakeAccount:
74 """Helper for setting up an `EC2Instance` without EC2."""
75- acquire_private_key = FakeMethod()
76- acquire_security_group = FakeMethod()
77+ def acquire_private_key(self):
78+ pass
79+
80+ def acquire_security_group(self, demo_networks=None):
81+ pass
82
83
84 class FakeOutput:
85@@ -29,8 +31,12 @@
86 state = 'running'
87 public_dns_name = 'fake-instance'
88
89- update = FakeMethod()
90- stop = FakeMethod()
91+ def update(self):
92+ pass
93+
94+ def stop(self):
95+ pass
96+
97 get_console_output = FakeOutput
98
99
100@@ -42,21 +48,40 @@
101
102 class FakeImage:
103 """Helper for setting up an `EC2Instance` without EC2."""
104- run = FakeMethod(result=FakeReservation())
105+
106+ def run(self, key_name, security_groups, instance_type):
107+ return FakeReservation()
108
109
110 class FakeFailure(Exception):
111 """A pretend failure from the test runner."""
112
113
114+class StubbedEC2Instance(EC2Instance):
115+
116+ def __init__(self, *args, **kwargs):
117+ super(StubbedEC2Instance, self).__init__(*args, **kwargs)
118+ self._shutdown_calls = 0
119+
120+ def shutdown(self):
121+ self._shutdown_calls += 1
122+
123+ def log(self, *args, **kwargs):
124+ pass
125+
126+ def _report_traceback(self, *args, **kwargs):
127+ pass
128+
129+
130 class TestEC2Instance(TestCase):
131 """Test running of an `EC2Instance` without EC2."""
132
133 def _makeInstance(self):
134 """Set up an `EC2Instance`, with stubbing where needed.
135
136- `EC2Instance.shutdown` is replaced with a `FakeMethod`, so check
137- its call_count to see whether it's been invoked.
138+ `EC2Instance.shutdown` is replaced with a fake method that increments
139+ ``_shutdown_calls``. Check its value to see if ``shutdown()`` has
140+ been invoked.
141 """
142 session_name = None
143 image = FakeImage()
144@@ -68,21 +93,17 @@
145 login = None
146 region = None
147
148- instance = EC2Instance(
149+ instance = StubbedEC2Instance(
150 session_name, image, instance_type, demo_networks, account,
151 from_scratch, user_key, login,
152 region)
153
154- instance.shutdown = FakeMethod()
155- instance._report_traceback = FakeMethod()
156- instance.log = FakeMethod()
157-
158 return instance
159
160 def _runInstance(self, instance, runnee=None, headless=False):
161 """Set up and run an `EC2Instance` (but without EC2)."""
162 if runnee is None:
163- runnee = FakeMethod()
164+ runnee = lambda: None
165
166 instance.set_up_and_run(False, not headless, runnee)
167
168@@ -91,15 +112,16 @@
169 # down. After running, they have started.
170 # Not a very useful test, except it establishes the basic
171 # assumptions for the other tests.
172+ log = []
173 instance = self._makeInstance()
174- runnee = FakeMethod()
175+ runnee = lambda: log.append(None)
176
177- self.assertEqual(0, runnee.call_count)
178- self.assertEqual(0, instance.shutdown.call_count)
179+ self.assertEqual(0, len(log))
180+ self.assertEqual(0, instance._shutdown_calls)
181
182 self._runInstance(instance, runnee=runnee)
183
184- self.assertEqual(1, runnee.call_count)
185+ self.assertEqual(1, len(log))
186
187 def test_set_up_and_run_headful(self):
188 # A non-headless run executes all tests in the instance, then
189@@ -108,7 +130,7 @@
190
191 self._runInstance(instance, headless=False)
192
193- self.assertEqual(1, instance.shutdown.call_count)
194+ self.assertEqual(1, instance._shutdown_calls)
195
196 def test_set_up_and_run_headless(self):
197 # An asynchronous, headless run kicks off the tests on the
198@@ -117,24 +139,26 @@
199
200 self._runInstance(instance, headless=True)
201
202- self.assertEqual(0, instance.shutdown.call_count)
203+ self.assertEqual(0, instance._shutdown_calls)
204
205 def test_set_up_and_run_headful_failure(self):
206 # If the test runner barfs, the instance swallows the exception
207 # and shuts down.
208 instance = self._makeInstance()
209- runnee = FakeMethod(failure=FakeFailure("Headful barfage."))
210+ def runnee():
211+ raise FakeFailure("Headful barfage.")
212
213 self._runInstance(instance, runnee=runnee, headless=False)
214
215- self.assertEqual(1, instance.shutdown.call_count)
216+ self.assertEqual(1, instance._shutdown_calls)
217
218 def test_set_up_and_run_headless_failure(self):
219 # If the instance's test runner fails to set up for a headless
220 # run, the instance swallows the exception and shuts down.
221 instance = self._makeInstance()
222- runnee = FakeMethod(failure=FakeFailure("Headless boom."))
223+ def runnee():
224+ raise FakeFailure("Headless boom.")
225
226 self._runInstance(instance, runnee=runnee, headless=True)
227
228- self.assertEqual(1, instance.shutdown.call_count)
229+ self.assertEqual(1, instance._shutdown_calls)
230
231=== modified file 'ec2test/tests/test_remote.py'
232--- ec2test/tests/test_remote.py 2012-02-24 20:23:36 +0000
233+++ ec2test/tests/test_remote.py 2012-04-13 15:12:22 +0000
234@@ -915,9 +915,11 @@
235
236 def run_script(self, script_file, pidfile, directory, logfile):
237 path = os.path.join(os.path.dirname(__file__), script_file)
238+ env = dict(os.environ)
239+ env['PYTHONPATH'] = os.pathsep.join(sys.path)
240 popen = subprocess.Popen(
241 [sys.executable, path, pidfile, directory, logfile],
242- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
243+ stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
244 stdout, stderr = popen.communicate()
245 self.assertEqual((0, '', ''), (popen.returncode, stdout, stderr))
246 # Make sure the daemon is finished doing its thing.

Subscribers

People subscribed via source and target branches