Merge lp:~ericsnowcurrently/fake-juju/python-lib-classes into lp:~landscape/fake-juju/trunk-old
- python-lib-classes
- Merge into trunk-old
Proposed by
Eric Snow
Status: | Merged |
---|---|
Approved by: | Eric Snow |
Approved revision: | 53 |
Merged at revision: | 39 |
Proposed branch: | lp:~ericsnowcurrently/fake-juju/python-lib-classes |
Merge into: | lp:~landscape/fake-juju/trunk-old |
Prerequisite: | lp:~ericsnowcurrently/fake-juju/python-lib-helpers |
Diff against target: |
479 lines (+427/-1) 5 files modified
python/fakejuju/__init__.py (+8/-0) python/fakejuju/failures.py (+65/-0) python/fakejuju/fakejuju.py (+100/-0) python/fakejuju/tests/test_failures.py (+101/-0) python/fakejuju/tests/test_fakejuju.py (+153/-1) |
To merge this branch: | bzr merge lp:~ericsnowcurrently/fake-juju/python-lib-classes |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
🤖 Landscape Builder | test results | Approve | |
Free Ekanayaka (community) | Approve | ||
Review via email: mp+307895@code.launchpad.net |
This proposal supersedes a proposal from 2016-10-06.
Commit message
Add the FakeJuju and Failures classes.
Description of the change
Add the FakeJuju and Failures classes.
Testing instructions:
Run the unit tests.
To post a comment you must log in.
Revision history for this message
🤖 Landscape Builder (landscape-builder) : | # |
review:
Abstain
(executing tests)
Revision history for this message
🤖 Landscape Builder (landscape-builder) wrote : | # |
review:
Approve
(test results)
Revision history for this message
Free Ekanayaka (free.ekanayaka) wrote : | # |
Looks mostly good to me, marking as N/I just to see what you think of the comments, but I'll be also happy to approve this MP as it is, in case.
review:
Needs Information
Revision history for this message
Eric Snow (ericsnowcurrently) : | # |
Revision history for this message
Free Ekanayaka (free.ekanayaka) wrote : | # |
+1 with a comment about YAGNI-ing the logsdir parameter.
review:
Approve
Revision history for this message
🤖 Landscape Builder (landscape-builder) : | # |
review:
Abstain
(executing tests)
Revision history for this message
🤖 Landscape Builder (landscape-builder) wrote : | # |
Command: make ci-test
Result: Success
Revno: 49
Branch: lp:~ericsnowcurrently/fake-juju/python-lib-classes
Jenkins: https:/
review:
Approve
(test results)
Revision history for this message
🤖 Landscape Builder (landscape-builder) : | # |
review:
Abstain
(executing tests)
Revision history for this message
🤖 Landscape Builder (landscape-builder) wrote : | # |
Command: make ci-test
Result: Success
Revno: 53
Branch: lp:~ericsnowcurrently/fake-juju/python-lib-classes
Jenkins: https:/
review:
Approve
(test results)
Revision history for this message
Eric Snow (ericsnowcurrently) : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'python/fakejuju/__init__.py' | |||
2 | --- python/fakejuju/__init__.py 2016-10-13 18:20:43 +0000 | |||
3 | +++ python/fakejuju/__init__.py 2016-10-17 15:55:46 +0000 | |||
4 | @@ -45,6 +45,14 @@ | |||
5 | 45 | 45 | ||
6 | 46 | """ | 46 | """ |
7 | 47 | 47 | ||
8 | 48 | from .fakejuju import get_filename, set_envvars, FakeJuju | ||
9 | 49 | |||
10 | 50 | |||
11 | 51 | __all__ = [ | ||
12 | 52 | "__version__", | ||
13 | 53 | "get_bootstrap_spec", "get_filename", "set_envvars", | ||
14 | 54 | "FakeJuju", | ||
15 | 55 | ] | ||
16 | 48 | 56 | ||
17 | 49 | __version__ = "0.9.0b1" | 57 | __version__ = "0.9.0b1" |
18 | 50 | 58 | ||
19 | 51 | 59 | ||
20 | === added file 'python/fakejuju/failures.py' | |||
21 | --- python/fakejuju/failures.py 1970-01-01 00:00:00 +0000 | |||
22 | +++ python/fakejuju/failures.py 2016-10-17 15:55:46 +0000 | |||
23 | @@ -0,0 +1,65 @@ | |||
24 | 1 | # Copyright 2016 Canonical Limited. All rights reserved. | ||
25 | 2 | |||
26 | 3 | import errno | ||
27 | 4 | import os | ||
28 | 5 | import os.path | ||
29 | 6 | |||
30 | 7 | |||
31 | 8 | class Failures(object): | ||
32 | 9 | """The collection of injected failures to use with a fake-juju. | ||
33 | 10 | |||
34 | 11 | The failures are tracked here as well as injected into any | ||
35 | 12 | fake-juju using the initial config dir (aka "juju home"). | ||
36 | 13 | |||
37 | 14 | Note that fake-juju provides only limited capability for | ||
38 | 15 | failure injection. | ||
39 | 16 | """ | ||
40 | 17 | |||
41 | 18 | def __init__(self, cfgdir, entities=None): | ||
42 | 19 | """ | ||
43 | 20 | @param cfgdir: The "juju home" directory into which the | ||
44 | 21 | failures will be registered for injection. | ||
45 | 22 | @param entities: The entity names to start with, if any. | ||
46 | 23 | """ | ||
47 | 24 | filename = os.path.join(cfgdir, "juju-failures") | ||
48 | 25 | entities = set(entities or ()) | ||
49 | 26 | |||
50 | 27 | self._filename = filename | ||
51 | 28 | self._entities = entities | ||
52 | 29 | |||
53 | 30 | @property | ||
54 | 31 | def filename(self): | ||
55 | 32 | """The path to the failures file the fake-juju reads.""" | ||
56 | 33 | return self._filename | ||
57 | 34 | |||
58 | 35 | @property | ||
59 | 36 | def entities(self): | ||
60 | 37 | """The IDs of the failing entities.""" | ||
61 | 38 | return set(self._entities) | ||
62 | 39 | |||
63 | 40 | def _flush(self): | ||
64 | 41 | """Write the failures to disk.""" | ||
65 | 42 | data = "\n".join(self._entities) + "\n" | ||
66 | 43 | try: | ||
67 | 44 | file = open(self._filename, "w") | ||
68 | 45 | except IOError: | ||
69 | 46 | dirname = os.path.dirname(self._filename) | ||
70 | 47 | if not os.path.exists(dirname): | ||
71 | 48 | os.makedirs(dirname) | ||
72 | 49 | file = open(self._filename, "w") | ||
73 | 50 | with file: | ||
74 | 51 | file.write(data) | ||
75 | 52 | |||
76 | 53 | def fail_entity(self, tag): | ||
77 | 54 | """Inject a global failure for the identified Juju entity.""" | ||
78 | 55 | self._entities.add(tag) | ||
79 | 56 | self._flush() | ||
80 | 57 | |||
81 | 58 | def clear(self): | ||
82 | 59 | """Remove all injected failures.""" | ||
83 | 60 | try: | ||
84 | 61 | os.remove(self._filename) | ||
85 | 62 | except OSError as e: | ||
86 | 63 | if e.errno != errno.ENOENT: | ||
87 | 64 | raise | ||
88 | 65 | self._entities.clear() | ||
89 | 0 | 66 | ||
90 | === modified file 'python/fakejuju/fakejuju.py' | |||
91 | --- python/fakejuju/fakejuju.py 2016-10-13 18:20:43 +0000 | |||
92 | +++ python/fakejuju/fakejuju.py 2016-10-17 15:55:46 +0000 | |||
93 | @@ -2,6 +2,10 @@ | |||
94 | 2 | 2 | ||
95 | 3 | import os.path | 3 | import os.path |
96 | 4 | 4 | ||
97 | 5 | import txjuju.cli | ||
98 | 6 | |||
99 | 7 | from .failures import Failures | ||
100 | 8 | |||
101 | 5 | 9 | ||
102 | 6 | def get_filename(version, bindir=None): | 10 | def get_filename(version, bindir=None): |
103 | 7 | """Return the full path to the fake-juju binary for the given version. | 11 | """Return the full path to the fake-juju binary for the given version. |
104 | @@ -30,3 +34,99 @@ | |||
105 | 30 | """ | 34 | """ |
106 | 31 | envvars["FAKE_JUJU_FAILURES"] = failures_filename or "" | 35 | envvars["FAKE_JUJU_FAILURES"] = failures_filename or "" |
107 | 32 | envvars["FAKE_JUJU_LOGS_DIR"] = logsdir or "" | 36 | envvars["FAKE_JUJU_LOGS_DIR"] = logsdir or "" |
108 | 37 | |||
109 | 38 | |||
110 | 39 | class FakeJuju(object): | ||
111 | 40 | """The fundamental details for fake-juju.""" | ||
112 | 41 | |||
113 | 42 | @classmethod | ||
114 | 43 | def from_version(cls, version, cfgdir, | ||
115 | 44 | logsdir=None, failuresdir=None, bindir=None): | ||
116 | 45 | """Return a new instance given the provided information. | ||
117 | 46 | |||
118 | 47 | @param version: The Juju version to fake. | ||
119 | 48 | @param cfgdir: The "juju home" directory to use. | ||
120 | 49 | @param logsdir: The directory where logs will be written. | ||
121 | 50 | This defaults to cfgdir. | ||
122 | 51 | @params failuresdir: The directory where failure injection | ||
123 | 52 | is managed. | ||
124 | 53 | @param bindir: The directory containing the fake-juju binary. | ||
125 | 54 | This defaults to /usr/bin. | ||
126 | 55 | """ | ||
127 | 56 | if logsdir is None: | ||
128 | 57 | logsdir = cfgdir | ||
129 | 58 | if failuresdir is None: | ||
130 | 59 | failuresdir = cfgdir | ||
131 | 60 | filename = get_filename(version, bindir=bindir) | ||
132 | 61 | failures = Failures(failuresdir) | ||
133 | 62 | return cls(filename, version, cfgdir, logsdir, failures) | ||
134 | 63 | |||
135 | 64 | def __init__(self, filename, version, cfgdir, logsdir=None, failures=None): | ||
136 | 65 | """ | ||
137 | 66 | @param filename: The path to the fake-juju binary. | ||
138 | 67 | @param version: The Juju version to fake. | ||
139 | 68 | @param cfgdir: The "juju home" directory to use. | ||
140 | 69 | @param logsdir: The directory where logs will be written. | ||
141 | 70 | This defaults to cfgdir. | ||
142 | 71 | @param failures: The set of fake-juju failures to use. | ||
143 | 72 | """ | ||
144 | 73 | logsdir = logsdir if logsdir is not None else cfgdir | ||
145 | 74 | if failures is None and cfgdir: | ||
146 | 75 | failures = Failures(cfgdir) | ||
147 | 76 | |||
148 | 77 | if not filename: | ||
149 | 78 | raise ValueError("missing filename") | ||
150 | 79 | if not version: | ||
151 | 80 | raise ValueError("missing version") | ||
152 | 81 | if not cfgdir: | ||
153 | 82 | raise ValueError("missing cfgdir") | ||
154 | 83 | if not logsdir: | ||
155 | 84 | raise ValueError("missing logsdir") | ||
156 | 85 | if failures is None: | ||
157 | 86 | raise ValueError("missing failures") | ||
158 | 87 | |||
159 | 88 | self.filename = filename | ||
160 | 89 | self.version = version | ||
161 | 90 | self.cfgdir = cfgdir | ||
162 | 91 | self.logsdir = logsdir | ||
163 | 92 | self.failures = failures | ||
164 | 93 | |||
165 | 94 | @property | ||
166 | 95 | def logfile(self): | ||
167 | 96 | """The path to fake-juju's log file.""" | ||
168 | 97 | return os.path.join(self.logsdir, "fake-juju.log") | ||
169 | 98 | |||
170 | 99 | @property | ||
171 | 100 | def infofile(self): | ||
172 | 101 | """The path to fake-juju's data cache.""" | ||
173 | 102 | return os.path.join(self.cfgdir, "fakejuju") | ||
174 | 103 | |||
175 | 104 | @property | ||
176 | 105 | def fifo(self): | ||
177 | 106 | """The path to the fifo file that triggers shutdown.""" | ||
178 | 107 | return os.path.join(self.cfgdir, "fifo") | ||
179 | 108 | |||
180 | 109 | @property | ||
181 | 110 | def cacertfile(self): | ||
182 | 111 | """The path to the API server's certificate.""" | ||
183 | 112 | return os.path.join(self.cfgdir, "cert.ca") | ||
184 | 113 | |||
185 | 114 | def cli(self, envvars=None): | ||
186 | 115 | """Return the txjuju.cli.CLI for this fake-juju. | ||
187 | 116 | |||
188 | 117 | Currently fake-juju supports only the following juju subcommands: | ||
189 | 118 | |||
190 | 119 | * bootstrap | ||
191 | 120 | Not that this only supports the dummy provider and the local | ||
192 | 121 | system is only minimally impacted. | ||
193 | 122 | * api-info | ||
194 | 123 | Note that passwords are always omited, even if requested. | ||
195 | 124 | * api-endpoints | ||
196 | 125 | * destroy-environment | ||
197 | 126 | """ | ||
198 | 127 | if envvars is None: | ||
199 | 128 | envvars = os.environ | ||
200 | 129 | envvars = dict(envvars) | ||
201 | 130 | set_envvars(envvars, self.failures._filename, self.logsdir) | ||
202 | 131 | return txjuju.cli.CLI.from_version( | ||
203 | 132 | self.filename, self.version, self.cfgdir, envvars) | ||
204 | 33 | 133 | ||
205 | === added file 'python/fakejuju/tests/test_failures.py' | |||
206 | --- python/fakejuju/tests/test_failures.py 1970-01-01 00:00:00 +0000 | |||
207 | +++ python/fakejuju/tests/test_failures.py 2016-10-17 15:55:46 +0000 | |||
208 | @@ -0,0 +1,101 @@ | |||
209 | 1 | # Copyright 2016 Canonical Limited. All rights reserved. | ||
210 | 2 | |||
211 | 3 | import os | ||
212 | 4 | import os.path | ||
213 | 5 | import shutil | ||
214 | 6 | import tempfile | ||
215 | 7 | import unittest | ||
216 | 8 | |||
217 | 9 | from fakejuju.failures import Failures | ||
218 | 10 | |||
219 | 11 | |||
220 | 12 | class FailuresTests(unittest.TestCase): | ||
221 | 13 | |||
222 | 14 | def setUp(self): | ||
223 | 15 | super(FailuresTests, self).setUp() | ||
224 | 16 | self.dirname = tempfile.mkdtemp(prefix="fakejuju-test-") | ||
225 | 17 | |||
226 | 18 | def tearDown(self): | ||
227 | 19 | shutil.rmtree(self.dirname) | ||
228 | 20 | super(FailuresTests, self).tearDown() | ||
229 | 21 | |||
230 | 22 | def test_full(self): | ||
231 | 23 | """Failures() works correctly when given all args.""" | ||
232 | 24 | entities = [u"x", u"y", u"z"] | ||
233 | 25 | failures = Failures(u"/some/dir", entities) | ||
234 | 26 | |||
235 | 27 | self.assertEqual(failures.filename, u"/some/dir/juju-failures") | ||
236 | 28 | self.assertEqual(failures.entities, set(entities)) | ||
237 | 29 | |||
238 | 30 | def test_minimal(self): | ||
239 | 31 | """Failures() works correctly when given minimal args.""" | ||
240 | 32 | failures = Failures(u"/some/dir") | ||
241 | 33 | |||
242 | 34 | self.assertEqual(failures.filename, u"/some/dir/juju-failures") | ||
243 | 35 | self.assertEqual(failures.entities, set()) | ||
244 | 36 | |||
245 | 37 | def test_conversion(self): | ||
246 | 38 | """Failures() doesn't convert any values.""" | ||
247 | 39 | failures_str = Failures("/some/dir", ["x", "y", "z"]) | ||
248 | 40 | failures_unicode = Failures(u"/some/dir", [u"x", u"y", u"z"]) | ||
249 | 41 | |||
250 | 42 | self.assertIsInstance(failures_str.filename, str) | ||
251 | 43 | self.assertIsInstance(failures_unicode.filename, unicode) | ||
252 | 44 | for id in failures_str.entities: | ||
253 | 45 | self.assertIsInstance(id, str) | ||
254 | 46 | for id in failures_unicode.entities: | ||
255 | 47 | self.assertIsInstance(id, unicode) | ||
256 | 48 | |||
257 | 49 | def test_file_not_created_initially(self): | ||
258 | 50 | """Failures() doesn't create a missing cfgdir until necessary.""" | ||
259 | 51 | failures = Failures(self.dirname) | ||
260 | 52 | |||
261 | 53 | self.assertFalse(os.path.exists(failures.filename)) | ||
262 | 54 | |||
263 | 55 | def test_cfgdir_created(self): | ||
264 | 56 | """Failures() creates a missing cfgdir as soon as it's needed.""" | ||
265 | 57 | dirname = os.path.join(self.dirname, "subdir") | ||
266 | 58 | self.assertFalse(os.path.exists(dirname)) | ||
267 | 59 | failures = Failures(dirname) | ||
268 | 60 | failures.fail_entity("unit-xyz") | ||
269 | 61 | |||
270 | 62 | self.assertTrue(os.path.exists(dirname)) | ||
271 | 63 | |||
272 | 64 | def test_fail_entity_one(self): | ||
273 | 65 | """Failures,fail_entity() writes an initial entry to disk.""" | ||
274 | 66 | failures = Failures(self.dirname) | ||
275 | 67 | failures.fail_entity("unit-abc") | ||
276 | 68 | with open(failures.filename) as file: | ||
277 | 69 | data = file.read() | ||
278 | 70 | |||
279 | 71 | self.assertEqual(data, "unit-abc\n") | ||
280 | 72 | |||
281 | 73 | def test_fail_entity_multiple(self): | ||
282 | 74 | """Failures.fail_entity() correctly writes multiple entries to disk.""" | ||
283 | 75 | failures = Failures(self.dirname) | ||
284 | 76 | failures.fail_entity("unit-abc") | ||
285 | 77 | failures.fail_entity("unit-xyz") | ||
286 | 78 | |||
287 | 79 | with open(failures.filename) as file: | ||
288 | 80 | data = file.read() | ||
289 | 81 | entities = set(tag for tag in data.splitlines() if tag) | ||
290 | 82 | self.assertEqual(entities, failures.entities) | ||
291 | 83 | self.assertTrue(data.endswith("\n")) | ||
292 | 84 | |||
293 | 85 | def test_clear_exists(self): | ||
294 | 86 | """Failures.clear() deletes the failures file if it exists.""" | ||
295 | 87 | failures = Failures(self.dirname) | ||
296 | 88 | failures.fail_entity("unit-abc") | ||
297 | 89 | self.assertTrue(os.path.exists(failures.filename)) | ||
298 | 90 | failures.clear() | ||
299 | 91 | |||
300 | 92 | self.assertFalse(os.path.exists(failures.filename)) | ||
301 | 93 | self.assertEqual(failures.entities, set()) | ||
302 | 94 | |||
303 | 95 | def test_clear_not_exists(self): | ||
304 | 96 | """Failures.clear() does nothing if the failures file is missing.""" | ||
305 | 97 | failures = Failures(self.dirname) | ||
306 | 98 | self.assertFalse(os.path.exists(failures.filename)) | ||
307 | 99 | failures.clear() | ||
308 | 100 | |||
309 | 101 | self.assertFalse(os.path.exists(failures.filename)) | ||
310 | 0 | 102 | ||
311 | === modified file 'python/fakejuju/tests/test_fakejuju.py' | |||
312 | --- python/fakejuju/tests/test_fakejuju.py 2016-10-13 18:25:28 +0000 | |||
313 | +++ python/fakejuju/tests/test_fakejuju.py 2016-10-17 15:55:46 +0000 | |||
314 | @@ -1,8 +1,13 @@ | |||
315 | 1 | # Copyright 2016 Canonical Limited. All rights reserved. | 1 | # Copyright 2016 Canonical Limited. All rights reserved. |
316 | 2 | 2 | ||
317 | 3 | import os | ||
318 | 3 | import unittest | 4 | import unittest |
319 | 4 | 5 | ||
321 | 5 | from fakejuju.fakejuju import get_filename, set_envvars | 6 | from txjuju import _juju1, _juju2 |
322 | 7 | from txjuju._utils import Executable | ||
323 | 8 | |||
324 | 9 | from fakejuju.failures import Failures | ||
325 | 10 | from fakejuju.fakejuju import get_filename, set_envvars, FakeJuju | ||
326 | 6 | 11 | ||
327 | 7 | 12 | ||
328 | 8 | class GetFilenameTests(unittest.TestCase): | 13 | class GetFilenameTests(unittest.TestCase): |
329 | @@ -115,3 +120,150 @@ | |||
330 | 115 | "FAKE_JUJU_FAILURES": "", | 120 | "FAKE_JUJU_FAILURES": "", |
331 | 116 | "FAKE_JUJU_LOGS_DIR": "", | 121 | "FAKE_JUJU_LOGS_DIR": "", |
332 | 117 | }) | 122 | }) |
333 | 123 | |||
334 | 124 | |||
335 | 125 | class FakeJujuTests(unittest.TestCase): | ||
336 | 126 | |||
337 | 127 | def test_from_version_full(self): | ||
338 | 128 | """FakeJuju.from_version() works correctly when given all args.""" | ||
339 | 129 | juju = FakeJuju.from_version( | ||
340 | 130 | "1.25.6", "/a/juju/home", "/logs/dir", "/failures/dir", "/bin/dir") | ||
341 | 131 | |||
342 | 132 | self.assertEqual(juju.filename, "/bin/dir/fake-juju-1.25.6") | ||
343 | 133 | self.assertEqual(juju.version, "1.25.6") | ||
344 | 134 | self.assertEqual(juju.cfgdir, "/a/juju/home") | ||
345 | 135 | self.assertEqual(juju.logsdir, "/logs/dir") | ||
346 | 136 | self.assertEqual(juju.failures.filename, "/failures/dir/juju-failures") | ||
347 | 137 | |||
348 | 138 | def test_from_version_minimal(self): | ||
349 | 139 | """FakeJuju.from_version() works correctly when given minimal args.""" | ||
350 | 140 | juju = FakeJuju.from_version("1.25.6", "/my/juju/home") | ||
351 | 141 | |||
352 | 142 | self.assertEqual(juju.filename, "/usr/bin/fake-juju-1.25.6") | ||
353 | 143 | self.assertEqual(juju.version, "1.25.6") | ||
354 | 144 | self.assertEqual(juju.cfgdir, "/my/juju/home") | ||
355 | 145 | self.assertEqual(juju.logsdir, "/my/juju/home") | ||
356 | 146 | self.assertEqual(juju.failures.filename, "/my/juju/home/juju-failures") | ||
357 | 147 | |||
358 | 148 | def test_full(self): | ||
359 | 149 | """FakeJuju() works correctly when given all args.""" | ||
360 | 150 | cfgdir = "/my/juju/home" | ||
361 | 151 | failures = Failures(cfgdir) | ||
362 | 152 | juju = FakeJuju("/fake-juju", "1.25.6", cfgdir, "/some/logs", failures) | ||
363 | 153 | |||
364 | 154 | self.assertEqual(juju.filename, "/fake-juju") | ||
365 | 155 | self.assertEqual(juju.version, "1.25.6") | ||
366 | 156 | self.assertEqual(juju.cfgdir, cfgdir) | ||
367 | 157 | self.assertEqual(juju.logsdir, "/some/logs") | ||
368 | 158 | self.assertIs(juju.failures, failures) | ||
369 | 159 | |||
370 | 160 | def test_minimal(self): | ||
371 | 161 | """FakeJuju() works correctly when given minimal args.""" | ||
372 | 162 | juju = FakeJuju("/fake-juju", "1.25.6", "/my/juju/home") | ||
373 | 163 | |||
374 | 164 | self.assertEqual(juju.filename, "/fake-juju") | ||
375 | 165 | self.assertEqual(juju.version, "1.25.6") | ||
376 | 166 | self.assertEqual(juju.cfgdir, "/my/juju/home") | ||
377 | 167 | self.assertEqual(juju.logsdir, "/my/juju/home") | ||
378 | 168 | self.assertEqual(juju.failures.filename, "/my/juju/home/juju-failures") | ||
379 | 169 | |||
380 | 170 | def test_conversions(self): | ||
381 | 171 | """FakeJuju() doesn't convert the type of any value.""" | ||
382 | 172 | juju_str = FakeJuju( | ||
383 | 173 | "/fake-juju", "1.25.6", "/x", "/y", Failures("/...")) | ||
384 | 174 | juju_unicode = FakeJuju( | ||
385 | 175 | u"/fake-juju", u"1.25.6", u"/x", u"/y", Failures(u"/...")) | ||
386 | 176 | |||
387 | 177 | for name in ('filename version cfgdir logsdir'.split()): | ||
388 | 178 | self.assertIsInstance(getattr(juju_str, name), str) | ||
389 | 179 | self.assertIsInstance(getattr(juju_unicode, name), unicode) | ||
390 | 180 | |||
391 | 181 | def test_missing_filename(self): | ||
392 | 182 | """FakeJuju() fails if filename is None or empty.""" | ||
393 | 183 | with self.assertRaises(ValueError): | ||
394 | 184 | FakeJuju(None, "1.25.6", "/my/juju/home") | ||
395 | 185 | with self.assertRaises(ValueError): | ||
396 | 186 | FakeJuju("", "1.25.6", "/my/juju/home") | ||
397 | 187 | |||
398 | 188 | def test_missing_version(self): | ||
399 | 189 | """FakeJuju() fails if version is None or empty.""" | ||
400 | 190 | with self.assertRaises(ValueError): | ||
401 | 191 | FakeJuju("/fake-juju", None, "/my/juju/home") | ||
402 | 192 | with self.assertRaises(ValueError): | ||
403 | 193 | FakeJuju("/fake-juju", "", "/my/juju/home") | ||
404 | 194 | |||
405 | 195 | def test_missing_cfgdir(self): | ||
406 | 196 | """FakeJuju() fails if cfgdir is None or empty.""" | ||
407 | 197 | with self.assertRaises(ValueError): | ||
408 | 198 | FakeJuju("/fake-juju", "1.25.6", None) | ||
409 | 199 | with self.assertRaises(ValueError): | ||
410 | 200 | FakeJuju("/fake-juju", "1.25.6", "") | ||
411 | 201 | |||
412 | 202 | def test_logfile(self): | ||
413 | 203 | """FakeJuju.logfile returns the path to the fake-juju log file.""" | ||
414 | 204 | juju = FakeJuju("/fake-juju", "1.25.6", "/x", "/some/logs") | ||
415 | 205 | |||
416 | 206 | self.assertEqual(juju.logfile, "/some/logs/fake-juju.log") | ||
417 | 207 | |||
418 | 208 | def test_infofile(self): | ||
419 | 209 | """FakeJuju.logfile returns the path to the fake-juju info file.""" | ||
420 | 210 | juju = FakeJuju("/fake-juju", "1.25.6", "/x") | ||
421 | 211 | |||
422 | 212 | self.assertEqual(juju.infofile, "/x/fakejuju") | ||
423 | 213 | |||
424 | 214 | def test_fifo(self): | ||
425 | 215 | """FakeJuju.logfile returns the path to the fake-juju fifo.""" | ||
426 | 216 | juju = FakeJuju("/fake-juju", "1.25.6", "/x") | ||
427 | 217 | |||
428 | 218 | self.assertEqual(juju.fifo, "/x/fifo") | ||
429 | 219 | |||
430 | 220 | def test_cacertfile(self): | ||
431 | 221 | """FakeJuju.cacertfile returns the path to the Juju API cert.""" | ||
432 | 222 | juju = FakeJuju("/fake-juju", "1.25.6", "/x") | ||
433 | 223 | |||
434 | 224 | self.assertEqual(juju.cacertfile, "/x/cert.ca") | ||
435 | 225 | |||
436 | 226 | def test_cli_full(self): | ||
437 | 227 | """FakeJuju.cli() works correctly when given all args.""" | ||
438 | 228 | juju = FakeJuju("/fake-juju", "1.25.6", "/x") | ||
439 | 229 | cli = juju.cli({"SPAM": "eggs"}) | ||
440 | 230 | |||
441 | 231 | self.assertEqual( | ||
442 | 232 | cli._exe, | ||
443 | 233 | Executable("/fake-juju", { | ||
444 | 234 | "SPAM": "eggs", | ||
445 | 235 | "FAKE_JUJU_FAILURES": "/x/juju-failures", | ||
446 | 236 | "FAKE_JUJU_LOGS_DIR": "/x", | ||
447 | 237 | "JUJU_HOME": "/x", | ||
448 | 238 | }), | ||
449 | 239 | ) | ||
450 | 240 | |||
451 | 241 | def test_cli_minimal(self): | ||
452 | 242 | """FakeJuju.cli() works correctly when given minimal args.""" | ||
453 | 243 | juju = FakeJuju("/fake-juju", "1.25.6", "/x") | ||
454 | 244 | cli = juju.cli() | ||
455 | 245 | |||
456 | 246 | self.assertEqual( | ||
457 | 247 | cli._exe, | ||
458 | 248 | Executable("/fake-juju", dict(os.environ, **{ | ||
459 | 249 | "FAKE_JUJU_FAILURES": "/x/juju-failures", | ||
460 | 250 | "FAKE_JUJU_LOGS_DIR": "/x", | ||
461 | 251 | "JUJU_HOME": "/x", | ||
462 | 252 | })), | ||
463 | 253 | ) | ||
464 | 254 | |||
465 | 255 | def test_cli_juju1(self): | ||
466 | 256 | """FakeJuju.cli() works correctly for Juju 1.x.""" | ||
467 | 257 | juju = FakeJuju.from_version("1.25.6", "/x") | ||
468 | 258 | cli = juju.cli() | ||
469 | 259 | |||
470 | 260 | self.assertEqual(cli._exe.envvars["JUJU_HOME"], "/x") | ||
471 | 261 | self.assertIsInstance(cli._juju, _juju1.CLIHooks) | ||
472 | 262 | |||
473 | 263 | def test_cli_juju2(self): | ||
474 | 264 | """FakeJuju.cli() works correctly for Juju 2.x.""" | ||
475 | 265 | juju = FakeJuju.from_version("2.0.0", "/x") | ||
476 | 266 | cli = juju.cli() | ||
477 | 267 | |||
478 | 268 | self.assertEqual(cli._exe.envvars["JUJU_DATA"], "/x") | ||
479 | 269 | self.assertIsInstance(cli._juju, _juju2.CLIHooks) |
Command: make ci-test /ci.lscape. net/job/ latch-test- xenial/ 17/
Result: Success
Revno: 48
Branch: lp:~ericsnowcurrently/fake-juju/python-lib-classes
Jenkins: https:/