Merge lp:~cjohnston/uci-engine/amulet-int-test-fix into lp:uci-engine
- amulet-int-test-fix
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Celso Providelo |
Approved revision: | 473 |
Merged at revision: | 469 |
Proposed branch: | lp:~cjohnston/uci-engine/amulet-int-test-fix |
Merge into: | lp:uci-engine |
Diff against target: |
570 lines (+117/-97) 10 files modified
ci-utils/ci_utils/testing/__init__.py (+4/-3) ci-utils/ci_utils/testing/features.py (+0/-1) ci-utils/ci_utils/tests/test_file_handler.py (+40/-39) cli/tests/test_cli.py (+14/-13) cli/tests/test_ticket.py (+8/-8) juju-deployer/deploy.py (+19/-9) juju-deployer/test_deploy.py (+13/-5) tests/deployers.py (+4/-6) tests/run.py (+2/-1) tests/test_integration.py (+13/-12) |
To merge this branch: | bzr merge lp:~cjohnston/uci-engine/amulet-int-test-fix |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Approve | |
Vincent Ladeuil (community) | Approve | ||
Chris Johnston (community) | Needs Resubmitting | ||
Review via email:
|
Commit message
Fixes integration amulet tests
Description of the change
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:465
http://
Executed test runs:
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:466
http://
Executed test runs:
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Celso Providelo (cprov) wrote : | # |
Nice move exposing TestCaseWithGnupg() to other test suites! I needed it in GK and had to do an ugly importing dancing.
I think it would be even better if instead of importing ci_utils.tests in callsites (and possibly dealing with name conflicts as you did) we create a ci_utils.testing domain for storing common auxiliary testing tools for UCI-E.
Just a suggestion, though. It's not a big deal to handle namespace clashing here and there, but it might get annoying when we start grouping common testing tools more aggressively.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:467
http://
Executed test runs:
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Vincent Ladeuil (vila) wrote : | # |
> Nice move exposing TestCaseWithGnupg() to other test suites! I needed it in GK
> and had to do an ugly importing dancing.
>
> I think it would be even better if instead of importing ci_utils.tests in
> callsites (and possibly dealing with name conflicts as you did) we create a
> ci_utils.testing domain for storing common auxiliary testing tools for UCI-E.
Objection your honor !
You're kicking the can, the next time we'll have two 'testing' modules and we'll have to deal with the namespace clashing anyway.
This class is part of the test infrastructure and as such, perfectly fine under (or in) the 'tests' module/hierarchy.
> Just a suggestion, though. It's not a big deal to handle namespace clashing
> here and there, but it might get annoying when we start grouping common
> testing tools more aggressively.
This will happen naturally as needed and we'll deal with the conflicts as needed. It's common to define a test class in a lower module and move it up as it's reused. Here we crossing the component boundary but it's still a test class.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Celso Providelo (cprov) wrote : | # |
On Tue, May 6, 2014 at 3:50 AM, Vincent Ladeuil <email address hidden> wrote:
>> Nice move exposing TestCaseWithGnupg() to other test suites! I needed it in GK
>> and had to do an ugly importing dancing.
>>
>> I think it would be even better if instead of importing ci_utils.tests in
>> callsites (and possibly dealing with name conflicts as you did) we create a
>> ci_utils.testing domain for storing common auxiliary testing tools for UCI-E.
>
> Objection your honor !
>
> You're kicking the can, the next time we'll have two 'testing' modules and we'll have to deal with the namespace clashing anyway.
>
> This class is part of the test infrastructure and as such, perfectly fine under (or in) the 'tests' module/hierarchy.
Vincent,
You are obviously misunderstanding the purpose of a ci_utils.testing
submodule. It will hold tests helpers that are common to be project in
the module domain, ci_utils.tests is meant to contain context-relevant
tests not code.
>> Just a suggestion, though. It's not a big deal to handle namespace clashing
>> here and there, but it might get annoying when we start grouping common
>> testing tools more aggressively.
>
> This will happen naturally as needed and we'll deal with the conflicts as needed. It's common to define a test class in a lower module and move it up as it's reused. Here we crossing the component boundary but it's still a test class.
That's the point, testing helpers are not tests, they are helpers and
when they become needed/useful in other context they need to go up to
a shared-place which is the module domain, not the tests folder.
Let's sort this on IRC.
[]
--
Celso Providelo
<email address hidden>
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Chris Johnston (cjohnston) : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:469
http://
Executed test runs:
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Vincent Ladeuil (vila) wrote : | # |
13 +def get_test_
Thanks ! I think it indeed makes more sense to have that as a module
function rather than a test class method.
I've made further cleanups in lp:~vila/uci-engine/amulet-int-test-fix as
revno 470.
141 + old_path = sys.path
142 + sys.path = []
143 + with self.assertRais
144 + deploy.
145 + sys.path = old_path
If the test fails, sys.path won't be restored, bad things will happen ;)
Fixed in revno 471.
73 +def check_dependenc
Good addition, thanks for the added test !
None is a better default value, [] can't be used and adding if needed_imports
is None: needed_imports = [] seems like overkill here.
Fixed in revno 472.
191 + if and_ip:
192 + return units, ip
193 + else:
194 + return ip
Variable signature depending on input args, urgh, I don't think we need it here, if you want to ignore the port, just take the ip.
Fixed in revno 473.
Back to:
138 + def test_check_
144 + deploy.
If gnupg is already imported, this test will (and has in my case ;) fail, so
better check for a non existing module instead.
Fixed in revno 474.
Overall, this MP was about s/ts-django/
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:471
http://
Executed test runs:
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Ubuntu CI Bot (uci-bot) wrote : | # |
Attempt to merge into lp:uci-engine failed due to conflicts:
text conflict in juju-deployer/
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:472
http://
Executed test runs:
Click here to trigger a rebuild:
http://
- 473. By Chris Johnston
-
Fix conflicts - from cprov
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:473
http://
Executed test runs:
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'ci-utils/ci_utils/testing/__init__.py' |
2 | --- ci-utils/ci_utils/testing/__init__.py 2014-05-06 14:52:19 +0000 |
3 | +++ ci-utils/ci_utils/testing/__init__.py 2014-05-07 16:48:40 +0000 |
4 | @@ -70,6 +70,7 @@ |
5 | def _destroy_gnupg_env(self): |
6 | shutil.rmtree(self.gnupg_home) |
7 | |
8 | - def get_test_file_path(self, filename): |
9 | - """Return the absolute path of a given testing file.""" |
10 | - return os.path.join(TEST_DATA_ROOT, filename) |
11 | + |
12 | +def get_test_file_path(filename): |
13 | + """Return the absolute path of a given testing file.""" |
14 | + return os.path.join(TEST_DATA_ROOT, filename) |
15 | |
16 | === modified file 'ci-utils/ci_utils/testing/features.py' |
17 | --- ci-utils/ci_utils/testing/features.py 2014-05-06 14:16:05 +0000 |
18 | +++ ci-utils/ci_utils/testing/features.py 2014-05-07 16:48:40 +0000 |
19 | @@ -21,7 +21,6 @@ |
20 | from ucitests import features |
21 | import yaml |
22 | |
23 | - |
24 | # Provide a shorcut so users don't have to import from ucitests |
25 | requires = features.requires |
26 | |
27 | |
28 | === modified file 'ci-utils/ci_utils/tests/test_file_handler.py' |
29 | --- ci-utils/ci_utils/tests/test_file_handler.py 2014-05-06 16:53:31 +0000 |
30 | +++ ci-utils/ci_utils/tests/test_file_handler.py 2014-05-07 16:48:40 +0000 |
31 | @@ -27,13 +27,11 @@ |
32 | FileToUploadNotFound, |
33 | UploadDirNotFound |
34 | ) |
35 | -from ci_utils.testing import ( |
36 | - TestCaseWithGnupg, |
37 | - TEST_DATA_ROOT, |
38 | -) |
39 | - |
40 | - |
41 | -class ChangesProcessorTestCase(TestCaseWithGnupg): |
42 | +from ci_utils import testing |
43 | + |
44 | + |
45 | +class ChangesProcessorTestCase(testing.TestCaseWithGnupg): |
46 | + |
47 | def setUp(self): |
48 | super(ChangesProcessorTestCase, self).setUp() |
49 | self.create_test_info() |
50 | @@ -58,8 +56,8 @@ |
51 | self.source_version) |
52 | |
53 | def test_parse(self): |
54 | - processor = ChangesProcessor(self.get_test_file_path( |
55 | - self.changes_file)) |
56 | + tf_path = testing.get_test_file_path |
57 | + processor = ChangesProcessor(tf_path(self.changes_file)) |
58 | processor.parse() |
59 | self.assertIsInstance(processor.changes, Changes) |
60 | self.assertEqual(processor.changes.get_package_name(), |
61 | @@ -68,87 +66,90 @@ |
62 | self.assertEqual(processor.source_package_name, self.source_name) |
63 | self.assertEqual(processor.source_version, self.full_version) |
64 | |
65 | - self.assertEqual(self.get_test_file_path(self.dsc_file), |
66 | - processor.changes.get_dsc()) |
67 | - self.assertEqual(self.get_test_file_path(self.debian_tar_gz_file), |
68 | + self.assertEqual(tf_path(self.dsc_file), processor.changes.get_dsc()) |
69 | + self.assertEqual(tf_path(self.debian_tar_gz_file), |
70 | processor.changes.get_diff()) |
71 | - self.assertTrue(self.get_test_file_path(self.orig_file) in |
72 | - processor.changes.get_files()) |
73 | + self.assertTrue(tf_path(self.orig_file) |
74 | + in processor.changes.get_files()) |
75 | |
76 | def test_parse_changes_file_not_found(self): |
77 | - self.assertRaises(ChangesFileNotFound, ChangesProcessor, |
78 | - "barbaz_source.changes") |
79 | + with self.assertRaises(ChangesFileNotFound): |
80 | + ChangesProcessor("barbaz_source.changes") |
81 | |
82 | def test_parse_changes_file_is_a_dsc(self): |
83 | # We're only able to tell a file is a real .changes during parsing. |
84 | processor = ChangesProcessor( |
85 | - self.get_test_file_path("foobar_0.1-1_dsc.changes")) |
86 | - self.assertRaises(ChangesParseError, processor.parse) |
87 | + testing.get_test_file_path("foobar_0.1-1_dsc.changes")) |
88 | + with self.assertRaises(ChangesParseError): |
89 | + processor.parse() |
90 | |
91 | def test_parse_changes_file_is_something_else(self): |
92 | # We're only able to tell a file is a real .changes during parsing. |
93 | processor = ChangesProcessor( |
94 | - self.get_test_file_path("foobar_0.1-1_random.changes")) |
95 | - self.assertRaises(ChangesFileException, processor.parse) |
96 | + testing.get_test_file_path("foobar_0.1-1_random.changes")) |
97 | + with self.assertRaises(ChangesFileException): |
98 | + processor.parse() |
99 | |
100 | def test_upload_dir_not_found(self): |
101 | - self.assertRaises(UploadDirNotFound, ChangesProcessor, |
102 | - self.get_test_file_path(self.changes_file), |
103 | - "foo/bar/baz") |
104 | + with self.assertRaises(UploadDirNotFound): |
105 | + ChangesProcessor(testing.get_test_file_path(self.changes_file), |
106 | + "foo/bar/baz") |
107 | |
108 | def test_files_to_upload_dir_found(self): |
109 | processor = ChangesProcessor( |
110 | - self.get_test_file_path(self.changes_file), |
111 | - files_to_upload_dir=TEST_DATA_ROOT) |
112 | - self.assertEquals(processor.files_to_upload_dir, TEST_DATA_ROOT) |
113 | + testing.get_test_file_path(self.changes_file), |
114 | + files_to_upload_dir=testing.TEST_DATA_ROOT) |
115 | + self.assertEquals(testing.TEST_DATA_ROOT, |
116 | + processor.files_to_upload_dir) |
117 | |
118 | def test_file_to_upload_not_found(self): |
119 | processor = ChangesProcessor( |
120 | - self.get_test_file_path(self.changes_file), |
121 | - files_to_upload_dir=".") |
122 | + testing.get_test_file_path(self.changes_file), |
123 | + files_to_upload_dir="/tmp") |
124 | self.assertRaises(FileToUploadNotFound, processor.parse) |
125 | |
126 | def test_all_files_found(self): |
127 | processor = ChangesProcessor( |
128 | - self.get_test_file_path(self.changes_file)) |
129 | - self.assertEqual(len(processor.files_to_upload), 0) |
130 | + testing.get_test_file_path(self.changes_file)) |
131 | + self.assertEqual(0, len(processor.files_to_upload)) |
132 | processor.parse() |
133 | # The three files (dsc, debian.tar.gz and orig) plus changes file |
134 | - self.assertEqual(len(processor.files_to_upload), 4) |
135 | + self.assertEqual(4, len(processor.files_to_upload)) |
136 | processor.validate() |
137 | self.assertTrue( |
138 | processor.changes.get_dsc() in processor.files_to_upload) |
139 | self.assertTrue( |
140 | processor.changes.get_diff() in processor.files_to_upload) |
141 | self.assertTrue( |
142 | - self.get_test_file_path(self.orig_file) in |
143 | + testing.get_test_file_path(self.orig_file) in |
144 | processor.files_to_upload) |
145 | |
146 | def test_files_to_upload_dir_not_provided(self): |
147 | processor = ChangesProcessor( |
148 | - self.get_test_file_path(self.changes_file)) |
149 | - self.assertEqual(processor.files_to_upload_dir, TEST_DATA_ROOT) |
150 | + testing.get_test_file_path(self.changes_file)) |
151 | + self.assertEqual(testing.TEST_DATA_ROOT, processor.files_to_upload_dir) |
152 | |
153 | def test_signature_check_fails(self): |
154 | processor = ChangesProcessor( |
155 | - self.get_test_file_path("foobar_0.1-1_unsigned.changes")) |
156 | + testing.get_test_file_path("foobar_0.1-1_unsigned.changes")) |
157 | processor.parse() |
158 | self.assertRaises(ChangesValidationError, processor.validate) |
159 | |
160 | def test_validate_distribution_unreleased(self): |
161 | processor = ChangesProcessor( |
162 | - self.get_test_file_path("foobar_0.1-1_unreleased.changes")) |
163 | + testing.get_test_file_path("foobar_0.1-1_unreleased.changes")) |
164 | processor.parse() |
165 | - self.assertRaises(ChangesValidationError, processor.validate) |
166 | + with self.assertRaises(ChangesValidationError): |
167 | + processor.validate() |
168 | |
169 | def test_process(self): |
170 | # Simple test to guarantee minimum integrity of this method, as the |
171 | # parts are being tested elsewhere. |
172 | processor = ChangesProcessor( |
173 | - self.get_test_file_path(self.changes_file)) |
174 | + testing.get_test_file_path(self.changes_file)) |
175 | processor.process() |
176 | self.assertIsInstance(processor.changes, Changes) |
177 | self.assertEqual(processor.changes.get_package_name(), |
178 | self.source_name) |
179 | |
180 | - self.assertEqual(len(processor.files_to_upload), 4) |
181 | + self.assertEqual(4, len(processor.files_to_upload)) |
182 | |
183 | === modified file 'cli/tests/test_cli.py' |
184 | --- cli/tests/test_cli.py 2014-05-06 16:53:31 +0000 |
185 | +++ cli/tests/test_cli.py 2014-05-07 16:48:40 +0000 |
186 | @@ -32,18 +32,18 @@ |
187 | capture_stdout, |
188 | mock_load_config, |
189 | ) |
190 | -from ci_utils.testing import TestCaseWithGnupg |
191 | +from ci_utils import testing |
192 | from ci_utils.ticket_states import ( |
193 | TicketWorkflowStep, |
194 | TicketWorkflowStepStatus, |
195 | ) |
196 | |
197 | |
198 | -class MainScriptTestCase(TestCaseWithGnupg): |
199 | +class MainScriptTestCase(testing.TestCaseWithGnupg): |
200 | |
201 | def setUp(self): |
202 | super(MainScriptTestCase, self).setUp() |
203 | - curdir = os.path.dirname(__file__) |
204 | + curdir = os.path.abspath(os.path.dirname(__file__)) |
205 | self.main_script = os.path.join(curdir, "../ubuntu-ci") |
206 | self.cli = imp.load_source( |
207 | "ubuntu-ci", |
208 | @@ -128,7 +128,7 @@ |
209 | @mock.patch('ci_libs.utils.patch') |
210 | def test_add_new_ticket(self, mock_patch, mock_post, mock_process): |
211 | """Verify cli create_ticket command for one .changes.""" |
212 | - changes = self.get_test_file_path('foobar_0.1-1_source.changes') |
213 | + changes = testing.get_test_file_path('foobar_0.1-1_source.changes') |
214 | args = ['create_ticket', '-t', 'New feature', '-b', '1234', '-o', |
215 | 'someone@example.com', '-d', 'This is a cool new feature', |
216 | '-a', 'foo', '-r', 'bar,baz', '-s', changes] |
217 | @@ -148,8 +148,8 @@ |
218 | def test_add_new_ticket_multiple_subtickets(self, mock_patch, mock_post, |
219 | mock_process): |
220 | """Verify cli create_ticket command for multiple .changes.""" |
221 | - changes_1 = self.get_test_file_path('foobar_0.1-1_source.changes') |
222 | - changes_2 = self.get_test_file_path('barfoo_0.1-1_source.changes') |
223 | + changes_1 = testing.get_test_file_path('foobar_0.1-1_source.changes') |
224 | + changes_2 = testing.get_test_file_path('barfoo_0.1-1_source.changes') |
225 | |
226 | args = ['create_ticket', '-t', '"New feature"', '-b', '4321', '-o', |
227 | 'someone@example.com', '-d', '"This is a cool new feature"', |
228 | @@ -289,7 +289,7 @@ |
229 | |
230 | def test_cli_only_source_files_pass(self): |
231 | """Verify cli fails in case file isn't prefixed .changes.""" |
232 | - wrong_changes = self.get_test_file_path('foobar_0.1-1.dsc') |
233 | + wrong_changes = testing.get_test_file_path('foobar_0.1-1.dsc') |
234 | args = ['create_ticket', '-t', '"New feature"', '-d', |
235 | '"This is a cool new feature"', '-o', 'someone@example.com', |
236 | '-a', 'foo', '-s', wrong_changes] |
237 | @@ -306,7 +306,7 @@ |
238 | return_value='http://www.example.com/api/v1/ticket/39/') |
239 | def test_is_valid_package_list_add_space(self, mock_patch): |
240 | """Test a ticket adding test binaries and not removing any fails.""" |
241 | - changes = self.get_test_file_path('foobar_0.1-1_source.changes') |
242 | + changes = testing.get_test_file_path('foobar_0.1-1_source.changes') |
243 | args = ['create_ticket', '-t', '"New feature"', '-d', |
244 | '"This is a cool new feature"', '-o', 'someone@example.com', |
245 | '-a', 'foo, bar', '-s', changes] |
246 | @@ -323,7 +323,7 @@ |
247 | return_value='http://www.example.com/api/v1/ticket/39/') |
248 | def test_is_valid_package_list_remove_space(self, mock_patch): |
249 | """Test a ticket removing two test binaries fails.""" |
250 | - changes = self.get_test_file_path('foobar_0.1-1_source.changes') |
251 | + changes = testing.get_test_file_path('foobar_0.1-1_source.changes') |
252 | args = ['create_ticket', '-t', '"New feature"', '-d', |
253 | '"This is a cool new feature"', '-o', 'someone@example.com', |
254 | '-a', 'foo', '-r', 'bar, baz', '-s', changes] |
255 | @@ -345,7 +345,7 @@ |
256 | return_value='http://www.example.com/api/v1/ticket/39/') |
257 | def test_cli_dsc_file_in_disguise(self, mock_patch, mock_load_config): |
258 | """Verify cli behavior when .changes file is a .dsc.""" |
259 | - wrong_changes = self.get_test_file_path('foobar_0.1-1_dsc.changes') |
260 | + wrong_changes = testing.get_test_file_path('foobar_0.1-1_dsc.changes') |
261 | args = ['create_ticket', '-t', '"New feature"', '-d', |
262 | '"This is a cool new feature"', '-o', 'someone@example.com', |
263 | '-a', 'foo', '-s', wrong_changes] |
264 | @@ -364,7 +364,8 @@ |
265 | def test_cli_changes_file_is_something_else(self, mock_patch, |
266 | mock_load_config): |
267 | """Verify cli behavior when provided .changes file isn't a .changes.""" |
268 | - wrong_changes = self.get_test_file_path('foobar_0.1-1_random.changes') |
269 | + wrong_changes = testing.get_test_file_path( |
270 | + 'foobar_0.1-1_random.changes') |
271 | args = ['create_ticket', '-t', '"New feature"', '-d', |
272 | '"This is a cool new feature"', '-o', 'someone@example.com', |
273 | '-a', 'foo', '-s', wrong_changes] |
274 | @@ -383,7 +384,7 @@ |
275 | def test_cli_changes_file_unsigned_fails(self, mock_patch, |
276 | mock_load_config): |
277 | """Verify cli behavior when provided .changes isn't signed.""" |
278 | - unsigned_changes = self.get_test_file_path( |
279 | + unsigned_changes = testing.get_test_file_path( |
280 | 'foobar_0.1-1_unsigned.changes') |
281 | args = ['create_ticket', '-t', '"New feature"', '-d', |
282 | '"This is a cool new feature"', '-o', 'someone@example.com', |
283 | @@ -403,7 +404,7 @@ |
284 | def test_cli_changes_file_is_unreleased(self, mock_patch, |
285 | mock_load_config): |
286 | """Verify cli behavior when provided .changes file is UNRELEASED.""" |
287 | - wrong_changes = self.get_test_file_path( |
288 | + wrong_changes = testing.get_test_file_path( |
289 | 'foobar_0.1-1_unreleased.changes') |
290 | args = ['create_ticket', '-t', '"New feature"', '-d', |
291 | '"This is a cool new feature"', '-o', 'someone@example.com', |
292 | |
293 | === modified file 'cli/tests/test_ticket.py' |
294 | --- cli/tests/test_ticket.py 2014-05-06 16:53:31 +0000 |
295 | +++ cli/tests/test_ticket.py 2014-05-07 16:48:40 +0000 |
296 | @@ -19,18 +19,18 @@ |
297 | import mock |
298 | import imp |
299 | |
300 | +from ci_utils import testing |
301 | from ci_libs.ticket import ( |
302 | SubTicket, |
303 | Ticket, |
304 | ) |
305 | -from ci_utils.testing import TestCaseWithGnupg |
306 | - |
307 | - |
308 | -class SubTicketTestCase(TestCaseWithGnupg): |
309 | - |
310 | + |
311 | + |
312 | +class SubTicketTestCase(testing.TestCaseWithGnupg): |
313 | def setUp(self): |
314 | super(SubTicketTestCase, self).setUp() |
315 | - self.changes = self.get_test_file_path('foobar_0.1-1_source.changes') |
316 | + self.changes = testing.get_test_file_path( |
317 | + 'foobar_0.1-1_source.changes') |
318 | |
319 | @mock.patch('ci_libs.utils.post', |
320 | return_value='http://www.example.com/api/v1/sourcepackage/4/') |
321 | @@ -79,7 +79,7 @@ |
322 | new_subticket._create_subticket() |
323 | |
324 | |
325 | -class TicketTestCase(TestCaseWithGnupg): |
326 | +class TicketTestCase(testing.TestCaseWithGnupg): |
327 | |
328 | def setUp(self): |
329 | super(TicketTestCase, self).setUp() |
330 | @@ -91,7 +91,7 @@ |
331 | @mock.patch('ci_libs.utils.post', |
332 | return_value='http://www.example.com/api/v1/ticket/38/') |
333 | def test_create_ticket(self, mock_post): |
334 | - changes = self.get_test_file_path('foobar_0.1-1_source.changes') |
335 | + changes = testing.get_test_file_path('foobar_0.1-1_source.changes') |
336 | args = ['create_ticket', '-t', 'New feature', '-b', '1234', '-o', |
337 | 'someone@example.com', '-d', 'This is a cool new feature', |
338 | '-a', 'foo', '-r', 'baz', '-s', changes] |
339 | |
340 | === modified file 'juju-deployer/deploy.py' |
341 | --- juju-deployer/deploy.py 2014-05-07 00:44:08 +0000 |
342 | +++ juju-deployer/deploy.py 2014-05-07 16:48:40 +0000 |
343 | @@ -17,8 +17,9 @@ |
344 | import argparse |
345 | import atexit |
346 | import base64 |
347 | -from distutils import spawn |
348 | +from distutils import spawn |
349 | import hashlib |
350 | +import importlib |
351 | import itertools |
352 | import logging |
353 | import os |
354 | @@ -375,15 +376,24 @@ |
355 | sys.exit(1) |
356 | |
357 | |
358 | -def check_dependencies(): |
359 | +def check_dependencies(needed_commands=None, needed_imports=None): |
360 | '''Exit the application if we are missing any dependency programs''' |
361 | |
362 | - needed_commands = ['cheetah'] |
363 | - for cmd in needed_commands: |
364 | - if not spawn.find_executable(cmd): |
365 | - err = "%s is missing. Please install it before continuing." % cmd |
366 | - print >>sys.stderr, err |
367 | - sys.exit(1) |
368 | + err = "%s is missing. Please install it before continuing." |
369 | + if needed_commands: |
370 | + for cmd in needed_commands: |
371 | + if not spawn.find_executable(cmd): |
372 | + err = err % cmd |
373 | + print >>sys.stderr, err |
374 | + sys.exit(1) |
375 | + if needed_imports: |
376 | + for impt in needed_imports: |
377 | + try: |
378 | + importlib.import_module(impt) |
379 | + except: |
380 | + err = err % impt |
381 | + print >>sys.stderr, err |
382 | + sys.exit(1) |
383 | |
384 | |
385 | def populate_all_templates(): |
386 | @@ -771,7 +781,7 @@ |
387 | if args.private_ppas_only: |
388 | os.environ['CI_PRIVATE_PPAS_ONLY'] = '1' |
389 | |
390 | - check_dependencies() |
391 | + check_dependencies(needed_commands=['cheetah']) |
392 | |
393 | if not args.build_only: |
394 | check_bootstrapped() |
395 | |
396 | === modified file 'juju-deployer/test_deploy.py' |
397 | --- juju-deployer/test_deploy.py 2014-05-06 21:33:18 +0000 |
398 | +++ juju-deployer/test_deploy.py 2014-05-07 16:48:40 +0000 |
399 | @@ -14,8 +14,9 @@ |
400 | # You should have received a copy of the GNU Affero General Public License |
401 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
402 | |
403 | +import os |
404 | +import sys |
405 | import mock |
406 | -import os |
407 | import tempfile |
408 | import shutil |
409 | import subprocess |
410 | @@ -108,13 +109,20 @@ |
411 | super(TestCheckDependencies, self).setUp() |
412 | fixtures.set_uniq_cwd(self) |
413 | |
414 | - def test_check_dependencies_fails(self): |
415 | - # check_dependencies bails out if it can't find the (executables) |
416 | - # project dependencies. |
417 | + def test_check_dependencies_needed_commands(self): |
418 | + # If we cannot find any of our dependencies, this program should bail |
419 | + # out. |
420 | fixtures.isolate_from_env(self, dict(PATH='')) |
421 | with mock.patch('sys.stderr'): |
422 | with self.assertRaises(SystemExit): |
423 | - deploy.check_dependencies() |
424 | + deploy.check_dependencies(needed_commands=['cheetah']) |
425 | + |
426 | + def test_check_dependencies_needed_imports(self): |
427 | + # If we cannot find any of our import dependencies, this program should |
428 | + # bail out. |
429 | + with mock.patch('sys.stderr'): |
430 | + with self.assertRaises(SystemExit): |
431 | + deploy.check_dependencies(needed_imports=['IDONTEXIST']) |
432 | |
433 | |
434 | class TestBootStrap(unittest.TestCase): |
435 | |
436 | === modified file 'tests/deployers.py' |
437 | --- tests/deployers.py 2014-04-29 16:03:15 +0000 |
438 | +++ tests/deployers.py 2014-05-07 16:48:40 +0000 |
439 | @@ -17,17 +17,15 @@ |
440 | import os |
441 | import subprocess |
442 | import sys |
443 | -import unittest |
444 | |
445 | +import yaml |
446 | +import amulet |
447 | |
448 | HERE = os.path.abspath(os.path.dirname(__file__)) |
449 | # We need access to ci_utils |
450 | sys.path.append(os.path.join(HERE, '..', 'ci-utils')) |
451 | |
452 | -import amulet |
453 | -from ci_utils.tests import features |
454 | -import yaml |
455 | - |
456 | +from ci_utils.testing import features, TestCaseWithGnupg |
457 | |
458 | |
459 | class AmuletDeployment(object): |
460 | @@ -65,7 +63,7 @@ |
461 | |
462 | |
463 | @features.requires(features.bootstrapped_juju) |
464 | -class DeployerTest(unittest.TestCase): |
465 | +class DeployerTest(TestCaseWithGnupg): |
466 | '''Base class for building juju deployer based tests.''' |
467 | |
468 | deployer_cfg = None |
469 | |
470 | === modified file 'tests/run.py' |
471 | --- tests/run.py 2014-04-28 14:45:39 +0000 |
472 | +++ tests/run.py 2014-05-07 16:48:40 +0000 |
473 | @@ -139,7 +139,7 @@ |
474 | # named like the component, we keep matching on that. |
475 | for one in only: |
476 | file_name = 'test_{}.py'.format(one) |
477 | - if file_name in tests: |
478 | + if file_name in tests: |
479 | selected.append(file_name) |
480 | else: |
481 | msg = "Skipping {} as {} does not exist in {}" |
482 | @@ -219,6 +219,7 @@ |
483 | |
484 | def main(): |
485 | check_nova_env() |
486 | + deploy.check_dependencies(needed_imports=['gnupg']) |
487 | |
488 | test_dir = os.path.dirname(sys.argv[0]) |
489 | tests = get_tests(test_dir) |
490 | |
491 | === modified file 'tests/test_integration.py' |
492 | --- tests/test_integration.py 2014-04-16 18:36:03 +0000 |
493 | +++ tests/test_integration.py 2014-05-07 16:48:40 +0000 |
494 | @@ -15,6 +15,7 @@ |
495 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
496 | |
497 | import os |
498 | +import sys |
499 | import json |
500 | import tempfile |
501 | import subprocess |
502 | @@ -25,8 +26,10 @@ |
503 | |
504 | import deployers |
505 | |
506 | - |
507 | HERE = os.path.abspath(os.path.dirname(__file__)) |
508 | +sys.path.append(os.path.join(HERE, '..', 'ci-utils')) |
509 | + |
510 | +from ci_utils import testing |
511 | |
512 | |
513 | def create_virtual_env(): |
514 | @@ -42,8 +45,7 @@ |
515 | def run_virtual_env(temp_dir, args, cwd=None): |
516 | if args is 'create': |
517 | cwd = os.path.join(HERE, '../cli') |
518 | - changes = os.path.abspath(os.path.join(HERE, |
519 | - '../cli/tests/data/foobar_0.1-1_source.changes')) |
520 | + changes = testing.get_test_file_path('foobar_0.1-1_source.changes') |
521 | args = ('python ubuntu-ci create_ticket -t "New feature" -b 1234 -o ' |
522 | 'someone@example.com -d "This is a cool new feature" -a foo ' |
523 | '-s %s' % changes) |
524 | @@ -69,8 +71,8 @@ |
525 | p = os.path.join(HERE, '../cli/setup.py') |
526 | args = '%s develop' % p |
527 | run_virtual_env(self.temp_dir, args) |
528 | - config_url = 'http://{}:{}' |
529 | - config_url = config_url.format(*self.get_ip_and_port('ts-django')) |
530 | + config_url = 'http://{}'.format( |
531 | + self.get_ip_and_port('webui-apache')[0]) |
532 | config = os.path.join(os.environ["HOME"], '.ubuntu-ci') |
533 | with open(config, 'a') as fp: |
534 | fp.write('ci_url: "{}"\n'.format(config_url)) |
535 | @@ -78,8 +80,8 @@ |
536 | run_virtual_env(self.temp_dir, args='create') |
537 | self.addCleanup(delete_virtual_env, self.temp_dir) |
538 | |
539 | - def get_server_status_and_content(self, url, service='ts-django'): |
540 | - final_url = url.format(*self.get_ip_and_port(service)) |
541 | + def get_server_status_and_content(self, url, service='webui-apache'): |
542 | + final_url = url.format(self.get_ip_and_port(service)[0]) |
543 | |
544 | client = httplib2.Http() |
545 | resp, content = client.request(final_url, 'GET') |
546 | @@ -91,7 +93,7 @@ |
547 | up with the proper status when viewed via the API. |
548 | """ |
549 | |
550 | - url = 'http://{}:{}/api/v1/ticket/1/' |
551 | + url = 'http://{}/api/v1/ticket/1/' |
552 | resp, content = self.get_server_status_and_content(url) |
553 | content = json.loads(content) |
554 | self.assertEqual(resp['status'], '200') |
555 | @@ -103,12 +105,11 @@ |
556 | This tests that the WebUI main page shows the ticket that we created |
557 | via the CLI |
558 | """ |
559 | - url = 'http://{}:{}/' |
560 | - resp, content = self.get_server_status_and_content( |
561 | - url, service='webui-apache') |
562 | + url = 'http://{}/' |
563 | + resp, content = self.get_server_status_and_content(url) |
564 | |
565 | self.assertEqual(resp['status'], '200') |
566 | - self.assertIn('<a href="/" class="first ">Ticket List</a>', content) |
567 | + self.assertIn('<a href="/" class="first active">Tickets</a>', content) |
568 | |
569 | |
570 | if __name__ == "__main__": |
FAILED: Continuous integration, rev:461 s-jenkins. ubuntu- ci:8080/ job/uci- engine- ci/580/
http://
Executed test runs:
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/uci- engine- ci/580/ rebuild
http://