Merge lp:~rharding/charms/precise/juju-gui/remove-pyjuju into lp:~juju-gui/charms/precise/juju-gui/trunk
- Precise Pangolin (12.04)
- remove-pyjuju
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 148 |
Proposed branch: | lp:~rharding/charms/precise/juju-gui/remove-pyjuju |
Merge into: | lp:~juju-gui/charms/precise/juju-gui/trunk |
Diff against target: |
1620 lines (+105/-777) 13 files modified
Dependencies.md (+1/-2) README.md (+4/-26) config.yaml (+4/-30) config/haproxy.cfg.template (+3/-7) config/juju-api-agent.conf.template (+0/-18) config/juju-api-improv.conf.template (+0/-12) hooks/backend.py (+3/-42) hooks/utils.py (+16/-122) tests/20-functional.test (+19/-73) tests/helpers.py (+0/-31) tests/test_backends.py (+41/-227) tests/test_helpers.py (+0/-71) tests/test_utils.py (+14/-116) |
To merge this branch: | bzr merge lp:~rharding/charms/precise/juju-gui/remove-pyjuju |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
charmers | Pending | ||
Review via email: mp+201510@code.launchpad.net |
Commit message
Description of the change
Remove support for PyJuju and rapi from charm.
- Removes the support for running rapi/pyjuju.
- Removes the agent used to communicate with zookeeper.
- Removes anything pertaining to zookeeper.
- Attempts to clean up docs and such to make sense with pure juju-core.
Note:
- The functional test run was taking 62min to complete for me. The timeout is
bumped to 80min to help allow it to complete. This was against ec2.
Richard Harding (rharding) wrote : | # |
- 150. By Richard Harding
-
Remove agent and zookeeper related functions
- 151. By Richard Harding
-
Fix lint
Richard Harding (rharding) wrote : | # |
Reviewers: mp+201510_
Message:
Please take a look.
Description:
Remove support for PyJuju and rapi from charm.
WIP - couple of question points and failing functional legacy test.
https:/
(do not edit description out of merge proposal)
Please review this at https:/
Affected files (+92, -695 lines):
M Dependencies.md
M Makefile
M README.md
A [revision details]
M config.yaml
M config/
D config/
D config/
M hooks/backend.py
M hooks/utils.py
M tests/20-
M tests/test_
M tests/test_utils.py
Richard Harding (rharding) wrote : | # |
Reviewers: mp+201510_
Message:
Please take a look.
Description:
Remove support for PyJuju and rapi from charm.
- Removes the support for running rapi/pyjuju.
- Removes the agent used to communicate with zookeeper.
- Removes anything pertaining to zookeeper.
- Attempts to clean up docs and such to make sense with pure juju-core.
Note:
- The functional test run was taking 62min to complete for me. The
timeout is
bumped to 80min to help allow it to complete. This was against ec2.
https:/
(do not edit description out of merge proposal)
Please review this at https:/
Affected files (+92, -695 lines):
M Dependencies.md
M Makefile
M README.md
A [revision details]
M config.yaml
M config/
D config/
D config/
M hooks/backend.py
M hooks/utils.py
M tests/20-
M tests/test_
M tests/test_utils.py
Francesco Banconi (frankban) wrote : | # |
Thanks a lot for getting rid of all this pyJuju stuff Rick!
This branch is nice: please take a look at my comments below.
LGTM with changes.
https:/
File README.md (right):
https:/
README.md:76: core) or "admin" (for pyjuju). The password is the same as
your Juju
We can remove the pyjuju reference here.
https:/
README.md:105: For both Juju Core and PyJuju, you must simply do the
following steps. Note
And here too...
https:/
README.md:162: #### pyjuju ####
We can get rid of this paragraph and of all the juju-jitsu stuff \o/
https:/
File config/
https:/
config/
path.
Nice.
https:/
File hooks/backend.py (left):
https:/
hooks/backend.
backend')
I am very happy we removed this ValueError for incompatible options.
https:/
File hooks/utils.py (right):
https:/
hooks/utils.py:87: Serializer, su,
Please keep "su" in its own line.
https:/
hooks/utils.py:148: return api_addresses.
So you decided to stop supporting also old releases of juju-core.
I am not sure about this: at least we should document it more
explicitly.
https:/
hooks/utils.py:320: password = password if password else None
Maybe rewrite those three lines like the following?
if not password:
password = 'admin' if sandbox else None
https:/
hooks/utils.py:362: # In PyJuju environments, use the same certificate
for both HTTPS and
Please remove this reference to PyJuju.
https:/
File tests/20-
https:/
tests/20-
'memcached', 'mysql', 'wordpress')
STAGING_SERVICES seems to be no longer required.
https:/
tests/20-
Can't we remove this line?
Moreover, can't we remove the juju_version function entirely?
https:/
tests/20-
This XXX comment is no longer required. We can remove all the
cleanup_services machinery.
- 152. By Richard Harding
-
Updated per review
Richard Harding (rharding) wrote : | # |
Reviewers: mp+201510_
Message:
Please take a look.
Description:
Remove support for PyJuju and rapi from charm.
- Removes the support for running rapi/pyjuju.
- Removes the agent used to communicate with zookeeper.
- Removes anything pertaining to zookeeper.
- Attempts to clean up docs and such to make sense with pure juju-core.
Note:
- The functional test run was taking 62min to complete for me. The
timeout is
bumped to 80min to help allow it to complete. This was against ec2.
https:/
(do not edit description out of merge proposal)
Please review this at https:/
Affected files (+107, -847 lines):
M Dependencies.md
M Makefile
M README.md
A [revision details]
M config.yaml
M config/
D config/
D config/
M hooks/backend.py
M hooks/utils.py
M tests/20-
M tests/helpers.py
M tests/test_
M tests/test_
M tests/test_utils.py
Richard Harding (rharding) wrote : | # |
I'm fighing lbox. When I updated this it put it over at a new url.
https:/
https:/
File README.md (right):
https:/
README.md:76: core) or "admin" (for pyjuju). The password is the same as
your Juju
On 2014/01/14 17:26:36, frankban wrote:
> We can remove the pyjuju reference here.
Thanks, removed.
https:/
README.md:105: For both Juju Core and PyJuju, you must simply do the
following steps. Note
On 2014/01/14 17:26:36, frankban wrote:
> And here too...
Removed
https:/
README.md:162: #### pyjuju ####
On 2014/01/14 17:26:36, frankban wrote:
> We can get rid of this paragraph and of all the juju-jitsu stuff \o/
Removed
https:/
File hooks/utils.py (right):
https:/
hooks/utils.py:87: Serializer, su,
On 2014/01/14 17:26:36, frankban wrote:
> Please keep "su" in its own line.
Mistake, thanks for the catch.
https:/
hooks/utils.py:148: return api_addresses.
On 2014/01/14 17:26:36, frankban wrote:
> So you decided to stop supporting also old releases of juju-core.
> I am not sure about this: at least we should document it more
explicitly.
Can you talk about this more? My understanding is that we got rid of the
agent bit and that was the conf file we've removed as part of that. Is
the machiner agent file something different?
https:/
hooks/utils.py:320: password = password if password else None
On 2014/01/14 17:26:36, frankban wrote:
> Maybe rewrite those three lines like the following?
> if not password:
> password = 'admin' if sandbox else None
Tweaked.
https:/
hooks/utils.py:362: # In PyJuju environments, use the same certificate
for both HTTPS and
On 2014/01/14 17:26:36, frankban wrote:
> Please remove this reference to PyJuju.
Removed
https:/
File tests/20-
https:/
tests/20-
'memcached', 'mysql', 'wordpress')
On 2014/01/14 17:26:36, frankban wrote:
> STAGING_SERVICES seems to be no longer required.
Wow, how did lint not catch that? Thanks.
https:/
tests/20-
On 2014/01/14 17:26:36, frankban wrote:
> Can't we remove this line?
> Moreover, can't we remove the juju_version function entirely?
Oh hmm, I didn't notice it was only used for pyjuju vs juju-core
distinction. Removing.
https:/
tests/20-
On 2014/0...
Francesco Banconi (frankban) wrote : | # |
https:/
File hooks/utils.py (right):
https:/
hooks/utils.py:148: return api_addresses.
On 2014/01/15 00:03:16, rharding wrote:
> On 2014/01/14 17:26:36, frankban wrote:
> > So you decided to stop supporting also old releases of juju-core.
> > I am not sure about this: at least we should document it more
explicitly.
> Can you talk about this more? My understanding is that we got rid of
the agent
> bit and that was the conf file we've removed as part of that. Is the
machiner
> agent file something different?
Those are two different concepts:
- the pyJuju API agent is the one that was started in the GUI node by
running the rapi-delta branch. The GUI used it as WebSocket server, and
the agent itself was connected to the bootstrap node Zookeper instance.
Your branch get rid of this machinery, and that's ok;
- the machiner agent file is a YAML created by juju-core which includes
the information required by the machiner worker. The API addresses are
part of that information. It must be considered an internal juju-core
detail, and for this reason we introduced the JUJU_API_ADDRESSES env
var, included in the hooks' execution context. But old versions of
juju-core don't support this, so the function strategy was:
- try to use the environment variable;
- if it is not present, parse the machiner agent file.
I am comfortable with that strategy, and I'd be inclined to preserve
that behavior. Anyway, as I mentioned, I can be ok in dropping support
for old juju-core releases if we clearly document it.
- 153. By Richard Harding
-
Put back agent ip address sniffing
- 154. By Richard Harding
-
Fix the force_machine time
- 155. By Richard Harding
-
Update force machine and set timeout back to 40m.
Preview Diff
1 | === modified file 'Dependencies.md' |
2 | --- Dependencies.md 2013-07-16 15:30:33 +0000 |
3 | +++ Dependencies.md 2014-01-15 14:49:45 +0000 |
4 | @@ -14,8 +14,7 @@ |
5 | a single PPA that the Juju GUI charm developers maintain. |
6 | |
7 | The packages in our devel PPA provide a superset of all software the charm may |
8 | -need for different deployment strategies, such as using the sandbox |
9 | -vs. improv, or Python Juju vs. Go Juju. |
10 | +need for different deployment strategies, such as using the sandbox or Go Juju. |
11 | |
12 | # Stable and Devel # |
13 | |
14 | |
15 | === modified file 'README.md' |
16 | --- README.md 2013-10-08 15:30:04 +0000 |
17 | +++ README.md 2014-01-15 14:49:45 +0000 |
18 | @@ -72,9 +72,9 @@ |
19 | By default, the deployment uses self-signed certificates. The browser will ask |
20 | you to accept a security exception once. |
21 | |
22 | -You will see a login form with the username fixed to "user-admin" (for juju- |
23 | -core) or "admin" (for pyjuju). The password is the same as your Juju |
24 | -environment's `admin-secret`, found in `~/.juju/environments.yaml`. |
25 | +You will see a login form with the username fixed to "user-admin". The |
26 | +password is the same as your Juju environment's `admin-secret`, found in |
27 | +`~/.juju/environments.yaml`. |
28 | |
29 | ### Deploying behind a firewall ### |
30 | |
31 | @@ -102,9 +102,6 @@ |
32 | deploy behind a firewall configuring the charm to pull the GUI release from a |
33 | location you specify. |
34 | |
35 | -For both Juju Core and PyJuju, you must simply do the following steps. Note |
36 | -that PyJuju must do these steps, plus another set described further below. |
37 | - |
38 | The config variable `juju-gui-source` allows a `url:` prefix which understands |
39 | both `http://` and `file://` protocols. We will use this to load a local copy |
40 | of the GUI source. |
41 | @@ -125,14 +122,7 @@ |
42 | |
43 | `juju resolved --retry juju-gui/0` |
44 | |
45 | -These steps are sufficient for Juju Core. If you are using PyJuju, you need to |
46 | -do another set of steps in addition. |
47 | - |
48 | -1. Use bzr to branch lp:~hazmat/juju/rapi-rollup locally ("bzr branch |
49 | -lp:~hazmat/juju/rapi-rollup") and copy the branch to the gui service machine. |
50 | - |
51 | -2. Use "juju set juju-gui juju-api-branch=PATH_TO_LOCAL_BZR_BRANCH" (where the |
52 | -path is *not* a file:// URI). |
53 | +These steps are sufficient for Juju Core. |
54 | |
55 | 3. Retry as described in the step 3 above (`juju resolved --retry juju-gui/0`). |
56 | |
57 | @@ -166,18 +156,6 @@ |
58 | |
59 | juju deploy --force-machine 0 cs:precise/juju-gui |
60 | |
61 | -#### pyjuju #### |
62 | - |
63 | -Colocation support is not included by default in the pyjuju implementation; to |
64 | -activate it, you will need to install Jitsu: |
65 | - |
66 | - sudo apt-get install juju-jitsu |
67 | - |
68 | -and then replace "juju deploy cs:precise/juju-gui" from the previous |
69 | -instructions with this: |
70 | - |
71 | - jitsu deploy-to 0 cs:precise/juju-gui |
72 | - |
73 | ## Contacting the Developers ## |
74 | |
75 | If you run into problems with the charm, please feel free to contact us on the |
76 | |
77 | === modified file 'config.yaml' |
78 | --- config.yaml 2014-01-09 21:48:27 +0000 |
79 | +++ config.yaml 2014-01-15 14:49:45 +0000 |
80 | @@ -36,7 +36,7 @@ |
81 | deployed from the specified Bazaar branch. "http://"" prefixed branches |
82 | work as well. It is also possible to include the specific branch |
83 | revision, e.g. "lp:juju-gui:42" will checkout revno 42. |
84 | - - a "url:"" prefixed url: The release found at the given URL |
85 | + - a "url:" prefixed url: The release found at the given URL |
86 | (ex: url:http://... or url:file://...) will be deployed. |
87 | type: string |
88 | default: local |
89 | @@ -45,30 +45,6 @@ |
90 | Run Juju GUI in debug mode, serving the uncompressed GUI source files. |
91 | type: boolean |
92 | default: false |
93 | - juju-api-branch: |
94 | - description: | |
95 | - The Juju API Bazaar branch (implementing the WebSocket server). Since |
96 | - juju-core includes the WebSocket API server out of the box, this option |
97 | - is ignored if the charm is deployed using juju-core. |
98 | - type: string |
99 | - default: lp:~hazmat/juju/rapi-rollup |
100 | - staging: |
101 | - description: | |
102 | - Connect the Juju GUI to the staging backend (i.e. a simulated Juju |
103 | - environment). Currently juju-core does not support the staging backend. |
104 | - For this reason, an error is raised if this option is enabled in a |
105 | - juju-core environment. |
106 | - type: boolean |
107 | - default: false |
108 | - staging-environment: |
109 | - description: | |
110 | - The environment JSON export used by the staging server. This option can |
111 | - be used to change the topology of the simulated Juju environment. |
112 | - Possible values are 'sample' and 'large'. Currently juju-core does not |
113 | - support the staging backend. For this reason, this option is ignored if |
114 | - the charm is deployed using juju-core. |
115 | - type: string |
116 | - default: sample |
117 | juju-gui-console-enabled: |
118 | description: | |
119 | Whether or not the console should be enabled for the browser. |
120 | @@ -132,11 +108,9 @@ |
121 | type: string |
122 | sandbox: |
123 | description: | |
124 | - Run using an in-memory sandbox rather than a real (or even improv) Juju |
125 | - backend. Sandbox is a client side construct running entirely in the |
126 | - client. Sandbox does not currently support imported environment |
127 | - simulation and is exclusive to the staging: true configuration. If |
128 | - staging is true it will be used in preference to sandbox at this time. |
129 | + Run using an in-memory sandbox rather than a real Juju backend. Sandbox |
130 | + is a client side construct running entirely in the client. Sandbox does |
131 | + not currently support imported environment simulation. |
132 | type: boolean |
133 | default: false |
134 | charmworld-url: |
135 | |
136 | === modified file 'config/haproxy.cfg.template' |
137 | --- config/haproxy.cfg.template 2013-03-28 09:39:45 +0000 |
138 | +++ config/haproxy.cfg.template 2014-01-15 14:49:45 +0000 |
139 | @@ -22,13 +22,9 @@ |
140 | backend juju |
141 | # The Juju WebSocket backend. |
142 | # Re-encrypt outgoing connections. |
143 | - {{if legacy_juju}} |
144 | - server ws1 {{api_address}} ssl ca-file {{api_pem}} verify required check-ssl inter 500ms |
145 | - {{else}} |
146 | - # Replace "/ws/" with "/" in any request path. |
147 | - reqrep ^([^\ ]*)\ /ws/ \1\ / |
148 | - server ws1 {{api_address}} ssl check-ssl inter 500ms |
149 | - {{endif}} |
150 | + # Replace "/ws/" with "/" in any request path. |
151 | + reqrep ^([^\ ]*)\ /ws/ \1\ / |
152 | + server ws1 {{api_address}} ssl check-ssl inter 500ms |
153 | |
154 | backend web |
155 | # Web traffic. |
156 | |
157 | === removed file 'config/juju-api-agent.conf.template' |
158 | --- config/juju-api-agent.conf.template 2013-05-22 15:22:53 +0000 |
159 | +++ config/juju-api-agent.conf.template 1970-01-01 00:00:00 +0000 |
160 | @@ -1,18 +0,0 @@ |
161 | -description "Juju API agent" |
162 | -author "Canonical" |
163 | - |
164 | -start on runlevel [2345] |
165 | -stop on runlevel [!2345] |
166 | - |
167 | -env JUJU_ZOOKEEPER={{zookeeper}} |
168 | - |
169 | -# Fix for bug 1130681: when the environment sets "juju-origin: lp:juju", |
170 | -# easy_install mucks sys.path and the juju libs are not found, unless we |
171 | -# change to their directory so that it comes first in sys.path. |
172 | -chdir {{juju_dir}} |
173 | - |
174 | -# Use --nodaemon so that upstart can correctly retrieve the process ID. |
175 | -exec /usr/bin/python -m juju.agents.api --nodaemon --port {{port}} \ |
176 | - --logfile /var/log/juju/api-agent.log \ |
177 | - --session-file /var/run/juju/api-agent.zksession \ |
178 | - --secure --keys {{keys}} {{if read_only}} --read-only {{endif}} |
179 | |
180 | === removed file 'config/juju-api-improv.conf.template' |
181 | --- config/juju-api-improv.conf.template 2013-02-04 17:26:32 +0000 |
182 | +++ config/juju-api-improv.conf.template 1970-01-01 00:00:00 +0000 |
183 | @@ -1,12 +0,0 @@ |
184 | -description "Juju API staging" |
185 | -author "Canonical" |
186 | - |
187 | -start on runlevel [2345] |
188 | -stop on runlevel [!2345] |
189 | - |
190 | -setuid ubuntu |
191 | -env PYTHONPATH={{juju_dir}}:$PYTHONPATH |
192 | - |
193 | -exec /usr/bin/python {{juju_dir}}/improv.py --port {{port}} \ |
194 | - -f {{juju_dir}}/{{staging_env}}.json \ |
195 | - --secure --keys {{keys}} |
196 | |
197 | === modified file 'hooks/backend.py' |
198 | --- hooks/backend.py 2014-01-09 21:48:27 +0000 |
199 | +++ hooks/backend.py 2014-01-15 14:49:45 +0000 |
200 | @@ -67,43 +67,10 @@ |
201 | shutil.rmtree(utils.BASE_DIR) |
202 | |
203 | |
204 | -class PythonInstallMixinBase(object): |
205 | - """Provide a common "install" method to ImprovMixin and PythonMixin.""" |
206 | - |
207 | - def install(self, backend): |
208 | - if (not os.path.exists(utils.JUJU_AGENT_DIR) or |
209 | - backend.different('staging', 'juju-api-branch')): |
210 | - utils.fetch_api(backend.config['juju-api-branch']) |
211 | - |
212 | - |
213 | -class ImprovMixin(PythonInstallMixinBase): |
214 | - """Manage the improv backend when on staging.""" |
215 | - |
216 | - debs = ('zookeeper',) |
217 | - |
218 | - def start(self, backend): |
219 | - config = backend.config |
220 | - utils.start_improv( |
221 | - config['staging-environment'], config['ssl-cert-path']) |
222 | - |
223 | - def stop(self, backend): |
224 | - utils.stop_improv() |
225 | - |
226 | - |
227 | class SandboxMixin(object): |
228 | pass |
229 | |
230 | |
231 | -class PythonMixin(PythonInstallMixinBase): |
232 | - """Manage the real PyJuju backend.""" |
233 | - |
234 | - def start(self, backend): |
235 | - utils.start_agent(backend.config['ssl-cert-path']) |
236 | - |
237 | - def stop(self, backend): |
238 | - utils.stop_agent() |
239 | - |
240 | - |
241 | class GoMixin(object): |
242 | """Manage the real Go juju-core backend.""" |
243 | pass |
244 | @@ -149,7 +116,7 @@ |
245 | config['juju-gui-debug'], config['serve-tests']) |
246 | utils.write_gui_config( |
247 | config['juju-gui-console-enabled'], config['login-help'], |
248 | - config['read-only'], config['staging'], config['charmworld-url'], |
249 | + config['read-only'], config['charmworld-url'], |
250 | build_dir, secure=config['secure'], sandbox=config['sandbox'], |
251 | ga_key=config['ga-key'], |
252 | show_get_juju_button=config['show-get-juju-button'], |
253 | @@ -255,16 +222,10 @@ |
254 | self.prev_config = prev_config |
255 | self.mixins = [SetUpMixin()] |
256 | |
257 | - is_legacy_juju = utils.legacy_juju() |
258 | - |
259 | - if config['staging']: |
260 | - if not is_legacy_juju: |
261 | - raise ValueError('Unable to use staging with go backend') |
262 | - self.mixins.append(ImprovMixin()) |
263 | - elif config['sandbox']: |
264 | + if config['sandbox']: |
265 | self.mixins.append(SandboxMixin()) |
266 | else: |
267 | - mixin = PythonMixin() if is_legacy_juju else GoMixin() |
268 | + mixin = GoMixin() |
269 | self.mixins.append(mixin) |
270 | |
271 | # We always install and start the GUI. |
272 | |
273 | === modified file 'hooks/utils.py' |
274 | --- hooks/utils.py 2014-01-13 16:53:45 +0000 |
275 | +++ hooks/utils.py 2014-01-15 14:49:45 +0000 |
276 | @@ -21,14 +21,12 @@ |
277 | 'APACHE_PORTS', |
278 | 'API_PORT', |
279 | 'CURRENT_DIR', |
280 | - 'JUJU_AGENT_DIR', |
281 | 'JUJU_GUI_DIR', |
282 | 'JUJU_PEM', |
283 | 'WEB_PORT', |
284 | 'cmd_log', |
285 | 'compute_build_dir', |
286 | 'download_release', |
287 | - 'fetch_api', |
288 | 'fetch_gui_from_branch', |
289 | 'fetch_gui_release', |
290 | 'find_missing_packages', |
291 | @@ -37,9 +35,7 @@ |
292 | 'get_launchpad_release', |
293 | 'get_npm_cache_archive_url', |
294 | 'get_release_file_path', |
295 | - 'get_zookeeper_address', |
296 | 'install_missing_packages', |
297 | - 'legacy_juju', |
298 | 'log_hook', |
299 | 'parse_source', |
300 | 'prime_npm_cache', |
301 | @@ -50,14 +46,10 @@ |
302 | 'setup_apache_config', |
303 | 'setup_gui', |
304 | 'setup_haproxy_config', |
305 | - 'start_agent', |
306 | 'start_builtin_server', |
307 | 'start_haproxy_apache', |
308 | - 'start_improv', |
309 | - 'stop_agent', |
310 | 'stop_builtin_server', |
311 | 'stop_haproxy_apache', |
312 | - 'stop_improv', |
313 | 'write_gui_config', |
314 | ] |
315 | |
316 | @@ -72,18 +64,17 @@ |
317 | from subprocess import CalledProcessError |
318 | import tempfile |
319 | import urlparse |
320 | +import yaml |
321 | |
322 | import apt |
323 | from launchpadlib.launchpad import Launchpad |
324 | import tempita |
325 | -import yaml |
326 | |
327 | from charmhelpers import ( |
328 | get_config, |
329 | log, |
330 | RESTART, |
331 | service_control, |
332 | - START, |
333 | STOP, |
334 | unit_get, |
335 | ) |
336 | @@ -94,17 +85,14 @@ |
337 | install_extra_repositories, |
338 | run, |
339 | script_name, |
340 | - search_file, |
341 | Serializer, |
342 | su, |
343 | ) |
344 | |
345 | |
346 | -AGENT = 'juju-api-agent' |
347 | APACHE = 'apache2' |
348 | BUILTIN_SERVER = 'guiserver' |
349 | HAPROXY = 'haproxy' |
350 | -IMPROV = 'juju-api-improv' |
351 | |
352 | API_PORT = 8080 |
353 | WEB_PORT = 8000 |
354 | @@ -112,7 +100,6 @@ |
355 | BASE_DIR = '/var/lib/juju-gui' |
356 | CURRENT_DIR = os.getcwd() |
357 | CONFIG_DIR = os.path.join(CURRENT_DIR, 'config') |
358 | -JUJU_AGENT_DIR = os.path.join(BASE_DIR, 'juju') |
359 | JUJU_GUI_DIR = os.path.join(BASE_DIR, 'juju-gui') |
360 | RELEASES_DIR = os.path.join(CURRENT_DIR, 'releases') |
361 | SERVER_DIR = os.path.join(CURRENT_DIR, 'server') |
362 | @@ -123,10 +110,8 @@ |
363 | HAPROXY_CFG_PATH = os.path.join(os.path.sep, 'etc', 'haproxy', 'haproxy.cfg') |
364 | |
365 | SYS_INIT_DIR = os.path.join(os.path.sep, 'etc', 'init') |
366 | -AGENT_INIT_PATH = os.path.join(SYS_INIT_DIR, 'juju-api-agent.conf') |
367 | GUISERVER_INIT_PATH = os.path.join(SYS_INIT_DIR, 'guiserver.conf') |
368 | HAPROXY_INIT_PATH = os.path.join(SYS_INIT_DIR, 'haproxy.conf') |
369 | -IMPROV_INIT_PATH = os.path.join(SYS_INIT_DIR, 'juju-api-improv.conf') |
370 | |
371 | JUJU_PEM = 'juju.includes-private-key.pem' |
372 | DEB_BUILD_DEPENDENCIES = ( |
373 | @@ -138,11 +123,6 @@ |
374 | config_json = Serializer(os.path.join(os.path.sep, 'tmp', 'config.json')) |
375 | # Bazaar checkout command. |
376 | bzr_checkout = command('bzr', 'co', '--lightweight') |
377 | -# Whether or not the charm is deployed using juju-core. |
378 | -# If juju-core has been used to deploy the charm, an agent.conf file must |
379 | -# be present in the charm parent directory. |
380 | -legacy_juju = lambda: not os.path.exists( |
381 | - os.path.join(CURRENT_DIR, '..', 'agent.conf')) |
382 | |
383 | bzr_url_expression = re.compile(r""" |
384 | ^ # Beginning of line. |
385 | @@ -165,8 +145,6 @@ |
386 | def get_api_address(unit_dir=None): |
387 | """Return the Juju API address. |
388 | |
389 | - If not present in the hook context as an environment variable, try to |
390 | - retrieve the address parsing the machiner agent.conf file. |
391 | """ |
392 | api_addresses = os.getenv('JUJU_API_ADDRESSES') |
393 | if api_addresses is not None: |
394 | @@ -187,6 +165,7 @@ |
395 | raise IOError('Juju agent configuration file not found.') |
396 | contents = yaml.load(open(agent_conf)) |
397 | return contents['apiinfo']['addrs'][0] |
398 | + return api_addresses.split()[0] |
399 | |
400 | |
401 | def first_path_in_dir(directory): |
402 | @@ -235,18 +214,6 @@ |
403 | raise ValueError('%r: file not found' % release_version) |
404 | |
405 | |
406 | -def get_zookeeper_address(agent_file_path): |
407 | - """Retrieve the Zookeeper address contained in the given *agent_file_path*. |
408 | - |
409 | - The *agent_file_path* is a path to a file containing a line similar to the |
410 | - following:: |
411 | - |
412 | - env JUJU_ZOOKEEPER="address" |
413 | - """ |
414 | - line = search_file('JUJU_ZOOKEEPER', agent_file_path).strip() |
415 | - return line.split('=')[1].strip('"') |
416 | - |
417 | - |
418 | @contextmanager |
419 | def log_hook(): |
420 | """Log when a hook starts and stops its execution. |
421 | @@ -346,60 +313,6 @@ |
422 | results_log.info('\n' + results) |
423 | |
424 | |
425 | -def start_improv(staging_env, ssl_cert_path): |
426 | - """Start a simulated juju environment using ``improv.py``.""" |
427 | - log('Setting up the staging Upstart script.') |
428 | - context = { |
429 | - 'juju_dir': JUJU_AGENT_DIR, |
430 | - 'keys': ssl_cert_path, |
431 | - 'port': API_PORT, |
432 | - 'staging_env': staging_env, |
433 | - } |
434 | - render_to_file('juju-api-improv.conf.template', context, IMPROV_INIT_PATH) |
435 | - log('Starting the staging backend.') |
436 | - with su('root'): |
437 | - service_control(IMPROV, START) |
438 | - |
439 | - |
440 | -def stop_improv(): |
441 | - """Stop a simulated Juju environment.""" |
442 | - log('Stopping the staging backend.') |
443 | - with su('root'): |
444 | - service_control(IMPROV, STOP) |
445 | - log('Removing the staging Upstart script.') |
446 | - cmd_log(run('rm', '-f', IMPROV_INIT_PATH)) |
447 | - |
448 | - |
449 | -def start_agent(ssl_cert_path, read_only=False): |
450 | - """Start the Juju agent and connect to the current environment.""" |
451 | - # Retrieve the Zookeeper address from the start up script. |
452 | - unit_name = os.path.basename( |
453 | - os.path.realpath(os.path.join(CURRENT_DIR, '..'))) |
454 | - agent_file = os.path.join(SYS_INIT_DIR, 'juju-{}.conf'.format(unit_name)) |
455 | - zookeeper = get_zookeeper_address(agent_file) |
456 | - log('Setting up the API agent Upstart script.') |
457 | - context = { |
458 | - 'juju_dir': JUJU_AGENT_DIR, |
459 | - 'keys': ssl_cert_path, |
460 | - 'port': API_PORT, |
461 | - 'zookeeper': zookeeper, |
462 | - 'read_only': read_only |
463 | - } |
464 | - render_to_file('juju-api-agent.conf.template', context, AGENT_INIT_PATH) |
465 | - log('Starting the API agent.') |
466 | - with su('root'): |
467 | - service_control(AGENT, START) |
468 | - |
469 | - |
470 | -def stop_agent(): |
471 | - """Stop the Juju agent.""" |
472 | - log('Stopping the API agent.') |
473 | - with su('root'): |
474 | - service_control(AGENT, STOP) |
475 | - log('Removing the API agent Upstart script.') |
476 | - cmd_log(run('rm', '-f', AGENT_INIT_PATH)) |
477 | - |
478 | - |
479 | def compute_build_dir(juju_gui_debug, serve_tests): |
480 | """Compute the build directory.""" |
481 | with su('root'): |
482 | @@ -416,19 +329,21 @@ |
483 | |
484 | |
485 | def write_gui_config( |
486 | - console_enabled, login_help, readonly, in_staging, charmworld_url, |
487 | + console_enabled, login_help, readonly, charmworld_url, |
488 | build_dir, secure=True, sandbox=False, |
489 | show_get_juju_button=False, config_js_path=None, ga_key='', |
490 | password=None): |
491 | """Generate the GUI configuration file.""" |
492 | log('Generating the Juju GUI configuration file.') |
493 | - is_legacy_juju = legacy_juju() |
494 | - user = 'admin' if is_legacy_juju else 'user-admin' |
495 | - # Normalize empty string passwords to None. |
496 | - password = password if password else None |
497 | - if password is None and ((is_legacy_juju and in_staging) or sandbox): |
498 | - password = 'admin' |
499 | - api_backend = 'python' if (is_legacy_juju and not sandbox) else 'go' |
500 | + user = 'user-admin' |
501 | + # Normalize empty string passwords to None. If sandbox is enabled then set |
502 | + # the password to admin and it will auto login. |
503 | + if not password: |
504 | + if sandbox: |
505 | + password = 'admin' |
506 | + else: |
507 | + password = None |
508 | + api_backend = 'go' |
509 | if secure: |
510 | protocol = 'wss' |
511 | else: |
512 | @@ -461,21 +376,12 @@ |
513 | config_path = os.path.join(CONFIG_DIR, 'haproxy.conf') |
514 | shutil.copy(config_path, SYS_INIT_DIR) |
515 | log('Generating haproxy configuration file.') |
516 | - is_legacy_juju = legacy_juju() |
517 | - if is_legacy_juju: |
518 | - # The PyJuju API agent is listening on localhost. |
519 | - api_address = '127.0.0.1:{}'.format(API_PORT) |
520 | - else: |
521 | - # Retrieve the juju-core API server address. |
522 | - api_address = get_api_address() |
523 | + # Retrieve the juju-core API server address. |
524 | + api_address = get_api_address() |
525 | context = { |
526 | 'api_address': api_address, |
527 | 'api_pem': JUJU_PEM, |
528 | - 'legacy_juju': is_legacy_juju, |
529 | 'ssl_cert_path': ssl_cert_path, |
530 | - # In PyJuju environments, use the same certificate for both HTTPS and |
531 | - # WebSocket connections. In juju-core the system already has the proper |
532 | - # certificate installed. |
533 | 'web_pem': JUJU_PEM, |
534 | 'web_port': WEB_PORT, |
535 | 'secure': secure |
536 | @@ -577,14 +483,10 @@ |
537 | 'charmworld_url': charmworld_url, |
538 | } |
539 | if not sandbox: |
540 | - is_legacy_juju = legacy_juju() |
541 | - if is_legacy_juju: |
542 | - api_url = 'wss://127.0.0.1:{}/ws'.format(API_PORT) |
543 | - else: |
544 | - api_url = 'wss://{}'.format(get_api_address()) |
545 | + api_url = 'wss://{}'.format(get_api_address()) |
546 | context.update({ |
547 | 'api_url': api_url, |
548 | - 'api_version': 'python' if is_legacy_juju else 'go', |
549 | + 'api_version': 'go', |
550 | }) |
551 | if serve_tests: |
552 | context['tests_root'] = os.path.join(JUJU_GUI_DIR, 'test', '') |
553 | @@ -737,14 +639,6 @@ |
554 | return download_release(url, filename) |
555 | |
556 | |
557 | -def fetch_api(juju_api_branch): |
558 | - """Retrieve the Juju branch, removing it first if already there.""" |
559 | - # Retrieve Juju API source checkout. |
560 | - log('Retrieving Juju API source checkout.') |
561 | - cmd_log(run('rm', '-rf', JUJU_AGENT_DIR)) |
562 | - cmd_log(bzr_checkout(juju_api_branch, JUJU_AGENT_DIR)) |
563 | - |
564 | - |
565 | def setup_gui(release_tarball): |
566 | """Set up Juju GUI.""" |
567 | # Uncompress the release tarball. |
568 | |
569 | === modified file 'tests/20-functional.test' |
570 | --- tests/20-functional.test 2013-11-27 15:20:58 +0000 |
571 | +++ tests/20-functional.test 2014-01-15 14:49:45 +0000 |
572 | @@ -35,16 +35,12 @@ |
573 | from helpers import ( |
574 | get_admin_secret, |
575 | juju_destroy_service, |
576 | - juju_version, |
577 | make_service_name, |
578 | - stop_services, |
579 | WebSocketClient, |
580 | ) |
581 | import example |
582 | |
583 | JUJU_GUI_TEST_BRANCH = 'lp:~juju-gui/juju-gui/charm-tests-branch' |
584 | -STAGING_SERVICES = ('haproxy', 'mediawiki', 'memcached', 'mysql', 'wordpress') |
585 | -is_legacy_juju = juju_version().major == 0 |
586 | try: |
587 | admin_secret = get_admin_secret() |
588 | except ValueError as err: |
589 | @@ -62,33 +58,18 @@ |
590 | of services that are started in the Juju GUI unit and that must be |
591 | manually stopped by tests. In juju-core, the services list is always empty. |
592 | """ |
593 | - force_machine = None if is_legacy_juju else 0 |
594 | service_name = make_service_name(prefix='juju-gui-') |
595 | unit_info = juju_deploy( |
596 | 'juju-gui', service_name=service_name, options=options, |
597 | - force_machine=force_machine) |
598 | - # XXX 2012-11-29 frankban bug=872264: |
599 | - # Just invoking ``juju destroy-service juju-gui`` in tearDown |
600 | - # should execute the ``stop`` hook, stopping all the services |
601 | - # started by the charm in the machine. Right now this does not |
602 | - # work in pyJuju, so the desired effect is achieved by keeping |
603 | - # track of started services and manually stopping them here. |
604 | - # Once pyJuju works correctly or we drop support for it altogether, we |
605 | - # can remove this shim. |
606 | + force_machine=0) |
607 | cleanup_services = [] |
608 | - if is_legacy_juju: |
609 | - if options is None: |
610 | - options = {} |
611 | - # Either stop the builtin server or the old apache2/haproxy setup. |
612 | - if options.get('builtin-server') == 'true': |
613 | - cleanup_services.append('guiserver') |
614 | - else: |
615 | - cleanup_services.extend(['haproxy', 'apache2']) |
616 | - # Staging uses improv, otherwise the API agent is used. |
617 | - if options.get('staging') == 'true': |
618 | - cleanup_services.append('juju-api-improv') |
619 | - else: |
620 | - cleanup_services.append('juju-api-agent') |
621 | + if options is None: |
622 | + options = {} |
623 | + # Either stop the builtin server or the old apache2/haproxy setup. |
624 | + if options.get('builtin-server') == 'true': |
625 | + cleanup_services.append('guiserver') |
626 | + else: |
627 | + cleanup_services.extend(['haproxy', 'apache2']) |
628 | return service_name, unit_info, cleanup_services |
629 | |
630 | |
631 | @@ -177,19 +158,6 @@ |
632 | services = self.wait_for(services_found, 'Services not displayed.') |
633 | return set([element.text for element in services]) |
634 | |
635 | - def deploy_gui(self, options=None): |
636 | - """Shim in our additional cleanup for pyJuju.""" |
637 | - # Once pyJuju works correctly or we drop support for it altogether, we |
638 | - # can remove this shim. |
639 | - self.service_name, unit_info, cleanup_services = juju_deploy_gui( |
640 | - options=options) |
641 | - # XXX 2013-11-27 frankban bug=872264: |
642 | - # See juju_deploy_gui above. |
643 | - if is_legacy_juju: |
644 | - hostname = unit_info['public-address'] |
645 | - self.addCleanup(stop_services, hostname, cleanup_services) |
646 | - return unit_info |
647 | - |
648 | def get_builtin_server_info(self, hostname): |
649 | """Return a dictionary of info as exposed by the builtin server.""" |
650 | url = 'https://{}/gui-server-info'.format(hostname) |
651 | @@ -205,26 +173,17 @@ |
652 | |
653 | def test_stable_release(self): |
654 | # Ensure the stable Juju GUI release is correctly set up. |
655 | - unit_info = self.deploy_gui(options={'juju-gui-source': 'stable'}) |
656 | - hostname = unit_info['public-address'] |
657 | - self.navigate_to(hostname) |
658 | - self.handle_browser_warning() |
659 | - self.assertEnvironmentIsConnected() |
660 | - |
661 | - @unittest.skipUnless(is_legacy_juju, 'staging only works in pyJuju') |
662 | - def test_staging(self): |
663 | - # Ensure the Juju GUI and staging services are correctly set up. |
664 | - unit_info = self.deploy_gui(options={'staging': 'true'}) |
665 | - hostname = unit_info['public-address'] |
666 | - self.navigate_to(hostname) |
667 | - self.handle_browser_warning() |
668 | - self.assertEnvironmentIsConnected() |
669 | - # The staging environment contains five deployed services. |
670 | - self.assertSetEqual(set(STAGING_SERVICES), self.get_service_names()) |
671 | + self.service_name, unit_info, _ = juju_deploy_gui( |
672 | + options={'juju-gui-source': 'stable'}) |
673 | + hostname = unit_info['public-address'] |
674 | + self.navigate_to(hostname) |
675 | + self.handle_browser_warning() |
676 | + self.assertEnvironmentIsConnected() |
677 | |
678 | def test_sandbox(self): |
679 | # The GUI is correctly deployed and set up in sandbox mode. |
680 | - unit_info = self.deploy_gui(options={'sandbox': 'true'}) |
681 | + self.service_name, unit_info, _ = juju_deploy_gui( |
682 | + options={'sandbox': 'true'}) |
683 | hostname = unit_info['public-address'] |
684 | self.navigate_to(hostname) |
685 | self.handle_browser_warning() |
686 | @@ -236,7 +195,7 @@ |
687 | def test_branch_source(self): |
688 | # Ensure the Juju GUI is correctly deployed from a Bazaar branch. |
689 | options = {'juju-gui-source': JUJU_GUI_TEST_BRANCH} |
690 | - unit_info = self.deploy_gui(options=options) |
691 | + self.service_name, unit_info, _ = juju_deploy_gui(options=options) |
692 | hostname = unit_info['public-address'] |
693 | self.navigate_to(hostname) |
694 | self.handle_browser_warning() |
695 | @@ -245,7 +204,8 @@ |
696 | def test_legacy_server(self): |
697 | # The legacy apache + haproxy server configuration works correctly. |
698 | # Also make sure the correct cache headers are sent. |
699 | - unit_info = self.deploy_gui(options={'builtin-server': 'false'}) |
700 | + self.service_name, unit_info, _ = juju_deploy_gui( |
701 | + options={'builtin-server': 'false'}) |
702 | hostname = unit_info['public-address'] |
703 | self.navigate_to(hostname) |
704 | self.handle_browser_warning() |
705 | @@ -279,10 +239,6 @@ |
706 | # Destroy the GUI service, and perform additional clean up in the case |
707 | # we are in a pyJuju environment. |
708 | juju_destroy_service(cls.service_name) |
709 | - # XXX 2013-11-27 frankban bug=872264: |
710 | - # See juju_deploy_gui above. |
711 | - if is_legacy_juju: |
712 | - stop_services(cls.hostname, cls.cleanup_services) |
713 | |
714 | def make_websocket_client(self, authenticated=True): |
715 | """Create and return a WebSocket client connected to the Juju backend. |
716 | @@ -320,8 +276,6 @@ |
717 | server_header = dict(headers)['server'] |
718 | self.assertIn('TornadoServer', server_header) |
719 | |
720 | - @unittest.skipIf( |
721 | - is_legacy_juju, 'bundle deployments are only supported in juju-core') |
722 | def test_deployer_not_authenticated(self): |
723 | # An error is returned trying to start a bundle deployment without |
724 | # being authenticated. |
725 | @@ -337,8 +291,6 @@ |
726 | 'unauthorized access: no user logged in', response['Error']) |
727 | |
728 | @unittest.skipUnless(admin_secret, 'admin secret was not found') |
729 | - @unittest.skipIf( |
730 | - is_legacy_juju, 'bundle deployments are only supported in juju-core') |
731 | def test_deployer_invalid_bundle_name(self): |
732 | # An error is returned trying to deploy a bundle with an invalid name. |
733 | client = self.make_websocket_client() |
734 | @@ -353,8 +305,6 @@ |
735 | 'invalid request: bundle no-such not found', response['Error']) |
736 | |
737 | @unittest.skipUnless(admin_secret, 'admin secret was not found') |
738 | - @unittest.skipIf( |
739 | - is_legacy_juju, 'bundle deployments are only supported in juju-core') |
740 | def test_deployer_invalid_bundle_yaml(self): |
741 | # An error is returned trying to deploy an invalid bundle YAML. |
742 | client = self.make_websocket_client() |
743 | @@ -369,8 +319,6 @@ |
744 | 'invalid request: invalid YAML contents', response['Error']) |
745 | |
746 | @unittest.skipUnless(admin_secret, 'admin secret was not found') |
747 | - @unittest.skipIf( |
748 | - is_legacy_juju, 'bundle deployments are only supported in juju-core') |
749 | def test_deployer_watch_unknown_deployment(self): |
750 | # An error is returned trying to watch an unknown deployment. |
751 | client = self.make_websocket_client() |
752 | @@ -385,8 +333,6 @@ |
753 | 'invalid request: deployment not found', response['Error']) |
754 | |
755 | @unittest.skipUnless(admin_secret, 'admin secret was not found') |
756 | - @unittest.skipIf( |
757 | - is_legacy_juju, 'bundle deployments are only supported in juju-core') |
758 | def test_deployer(self): |
759 | # The builtin server supports deploying bundles using juju-deployer. |
760 | client = self.make_websocket_client() |
761 | |
762 | === modified file 'tests/helpers.py' |
763 | --- tests/helpers.py 2013-11-27 14:37:06 +0000 |
764 | +++ tests/helpers.py 2014-01-15 14:49:45 +0000 |
765 | @@ -21,7 +21,6 @@ |
766 | import json |
767 | import os |
768 | import random |
769 | -import re |
770 | import string |
771 | import subprocess |
772 | import time |
773 | @@ -172,36 +171,6 @@ |
774 | return json.loads(status) |
775 | |
776 | |
777 | -_juju_version_expression = re.compile(r""" |
778 | - ^ # Beginning of line. |
779 | - (?:juju\s+)? # Optional juju prefix. |
780 | - (\d+)\.(\d+) # Major and minor versions. |
781 | - (?:\.(\d+))? # Optional patch version. |
782 | - .* # Optional suffix. |
783 | - $ # End of line. |
784 | -""", re.VERBOSE) |
785 | - |
786 | - |
787 | -def juju_version(): |
788 | - """Return the currently used Juju version. |
789 | - |
790 | - The version is returned as a named tuple (major, minor, patch). |
791 | - If the patch number is missing, it is set to zero. |
792 | - """ |
793 | - try: |
794 | - # In pyJuju, version info is printed to stderr. |
795 | - output = subprocess.check_output( |
796 | - ['juju', '--version'], stderr=subprocess.STDOUT) |
797 | - except subprocess.CalledProcessError: |
798 | - # Current juju-core exposes a version subcommand. |
799 | - output = subprocess.check_output(['juju', 'version']) |
800 | - match = _juju_version_expression.match(output) |
801 | - if match is None: |
802 | - raise ValueError('invalid juju version: {!r}'.format(output)) |
803 | - to_int = lambda num: 0 if num is None else int(num) |
804 | - return Version._make(map(to_int, match.groups())) |
805 | - |
806 | - |
807 | def make_service_name(prefix='service-'): |
808 | """Generate a long, random service name.""" |
809 | characters = string.ascii_lowercase |
810 | |
811 | === modified file 'tests/test_backends.py' |
812 | --- tests/test_backends.py 2014-01-09 21:48:27 +0000 |
813 | +++ tests/test_backends.py 2014-01-15 14:49:45 +0000 |
814 | @@ -38,10 +38,6 @@ |
815 | 'curl', 'openssl', 'python-bzrlib', 'python-pip') |
816 | EXPECTED_GO_BUILTIN_DEBS = ('curl', 'openssl', 'python-bzrlib', 'python-pip') |
817 | |
818 | -simulate_pyjuju = mock.patch('utils.legacy_juju', mock.Mock(return_value=True)) |
819 | -simulate_juju_core = mock.patch( |
820 | - 'utils.legacy_juju', mock.Mock(return_value=False)) |
821 | - |
822 | |
823 | class TestBackendProperties(unittest.TestCase): |
824 | """Ensure the correct mixins and property values are collected.""" |
825 | @@ -66,59 +62,14 @@ |
826 | 'builtin-server': False, |
827 | 'repository-location': 'ppa:my/location', |
828 | 'sandbox': True, |
829 | - 'staging': False, |
830 | } |
831 | test_backend = backend.Backend(config=config) |
832 | self.assert_mixins(expected_mixins, test_backend) |
833 | self.assert_dependencies( |
834 | EXPECTED_PYTHON_LEGACY_DEBS, 'ppa:my/location', test_backend) |
835 | |
836 | - def test_python_staging_backend(self): |
837 | - expected_mixins = ( |
838 | - 'SetUpMixin', 'ImprovMixin', 'GuiMixin', 'HaproxyApacheMixin') |
839 | - config = { |
840 | - 'builtin-server': False, |
841 | - 'repository-location': 'ppa:my/location', |
842 | - 'sandbox': False, |
843 | - 'staging': True, |
844 | - } |
845 | - with simulate_pyjuju: |
846 | - test_backend = backend.Backend(config=config) |
847 | - self.assert_mixins(expected_mixins, test_backend) |
848 | - self.assert_dependencies( |
849 | - EXPECTED_PYTHON_LEGACY_DEBS + ('zookeeper',), |
850 | - 'ppa:my/location', test_backend) |
851 | - |
852 | - def test_go_staging_backend(self): |
853 | - config = {'sandbox': False, 'staging': True, 'builtin-server': False} |
854 | - with simulate_juju_core: |
855 | - with self.assertRaises(ValueError) as context_manager: |
856 | - backend.Backend(config=config) |
857 | - error = str(context_manager.exception) |
858 | - self.assertEqual('Unable to use staging with go backend', error) |
859 | - |
860 | - def test_python_sandbox_backend(self): |
861 | - with simulate_pyjuju: |
862 | - self.check_sandbox_mode() |
863 | - |
864 | def test_go_sandbox_backend(self): |
865 | - with simulate_juju_core: |
866 | - self.check_sandbox_mode() |
867 | - |
868 | - def test_python_backend(self): |
869 | - expected_mixins = ( |
870 | - 'SetUpMixin', 'PythonMixin', 'GuiMixin', 'HaproxyApacheMixin') |
871 | - config = { |
872 | - 'builtin-server': False, |
873 | - 'repository-location': 'ppa:my/location', |
874 | - 'sandbox': False, |
875 | - 'staging': False, |
876 | - } |
877 | - with simulate_pyjuju: |
878 | - test_backend = backend.Backend(config=config) |
879 | - self.assert_mixins(expected_mixins, test_backend) |
880 | - self.assert_dependencies( |
881 | - EXPECTED_PYTHON_LEGACY_DEBS, 'ppa:my/location', test_backend) |
882 | + self.check_sandbox_mode() |
883 | |
884 | def test_go_backend(self): |
885 | expected_mixins = ( |
886 | @@ -127,58 +78,37 @@ |
887 | 'builtin-server': False, |
888 | 'repository-location': 'ppa:my/location', |
889 | 'sandbox': False, |
890 | - 'staging': False, |
891 | } |
892 | - with simulate_juju_core: |
893 | - test_backend = backend.Backend(config=config) |
894 | - self.assert_mixins(expected_mixins, test_backend) |
895 | - self.assert_dependencies( |
896 | - EXPECTED_GO_LEGACY_DEBS, 'ppa:my/location', test_backend) |
897 | + test_backend = backend.Backend(config=config) |
898 | + self.assert_mixins(expected_mixins, test_backend) |
899 | + self.assert_dependencies( |
900 | + EXPECTED_GO_LEGACY_DEBS, 'ppa:my/location', test_backend) |
901 | |
902 | def test_go_builtin_server(self): |
903 | config = { |
904 | 'builtin-server': True, |
905 | 'repository-location': 'ppa:my/location', |
906 | 'sandbox': False, |
907 | - 'staging': False, |
908 | } |
909 | expected_mixins = ( |
910 | 'SetUpMixin', 'GoMixin', 'GuiMixin', 'BuiltinServerMixin') |
911 | - with simulate_juju_core: |
912 | - test_backend = backend.Backend(config) |
913 | - self.assert_mixins(expected_mixins, test_backend) |
914 | - self.assert_dependencies( |
915 | - EXPECTED_GO_BUILTIN_DEBS, None, test_backend) |
916 | - |
917 | - def test_python_builtin_server(self): |
918 | - config = { |
919 | - 'builtin-server': True, |
920 | - 'repository-location': 'ppa:my/location', |
921 | - 'sandbox': False, |
922 | - 'staging': False, |
923 | - } |
924 | - expected_mixins = ( |
925 | - 'SetUpMixin', 'PythonMixin', 'GuiMixin', 'BuiltinServerMixin') |
926 | - with simulate_pyjuju: |
927 | - test_backend = backend.Backend(config) |
928 | - self.assert_mixins(expected_mixins, test_backend) |
929 | - self.assert_dependencies( |
930 | - EXPECTED_PYTHON_BUILTIN_DEBS, None, test_backend) |
931 | + test_backend = backend.Backend(config) |
932 | + self.assert_mixins(expected_mixins, test_backend) |
933 | + self.assert_dependencies( |
934 | + EXPECTED_GO_BUILTIN_DEBS, None, test_backend) |
935 | |
936 | def test_sandbox_builtin_server(self): |
937 | config = { |
938 | 'builtin-server': True, |
939 | 'repository-location': 'ppa:my/location', |
940 | 'sandbox': True, |
941 | - 'staging': False, |
942 | } |
943 | expected_mixins = ( |
944 | 'SetUpMixin', 'SandboxMixin', 'GuiMixin', 'BuiltinServerMixin') |
945 | - with simulate_juju_core: |
946 | - test_backend = backend.Backend(config) |
947 | - self.assert_mixins(expected_mixins, test_backend) |
948 | - self.assert_dependencies( |
949 | - EXPECTED_PYTHON_BUILTIN_DEBS, None, test_backend) |
950 | + test_backend = backend.Backend(config) |
951 | + self.assert_mixins(expected_mixins, test_backend) |
952 | + self.assert_dependencies( |
953 | + EXPECTED_PYTHON_BUILTIN_DEBS, None, test_backend) |
954 | |
955 | |
956 | class TestBackendCommands(unittest.TestCase): |
957 | @@ -189,10 +119,8 @@ |
958 | self.addCleanup(shutil.rmtree, self.playground) |
959 | self.base_dir = os.path.join(self.playground, 'juju-gui') |
960 | self.command_log_file = os.path.join(self.playground, 'logs') |
961 | - self.juju_agent_dir = os.path.join(self.playground, 'juju-agent-dir') |
962 | self.ssl_cert_path = os.path.join(self.playground, 'ssl-cert-path') |
963 | # Set up default values. |
964 | - self.juju_api_branch = 'lp:juju-api' |
965 | self.juju_gui_source = 'stable' |
966 | self.repository_location = 'ppa:my/location' |
967 | self.parse_source_return_value = ('stable', None) |
968 | @@ -205,7 +133,6 @@ |
969 | 'charmworld-url': 'http://charmworld.example.com/', |
970 | 'command-log-file': self.command_log_file, |
971 | 'ga-key': 'my-key', |
972 | - 'juju-api-branch': self.juju_api_branch, |
973 | 'juju-gui-debug': False, |
974 | 'juju-gui-console-enabled': False, |
975 | 'juju-gui-source': self.juju_gui_source, |
976 | @@ -217,7 +144,6 @@ |
977 | 'serve-tests': False, |
978 | 'show-get-juju-button': False, |
979 | 'ssl-cert-path': self.ssl_cert_path, |
980 | - 'staging': False, |
981 | } |
982 | if options is not None: |
983 | config.update(options) |
984 | @@ -231,7 +157,6 @@ |
985 | mocks = { |
986 | 'base_dir': mock.patch('backend.utils.BASE_DIR', self.base_dir), |
987 | 'compute_build_dir': mock.patch('backend.utils.compute_build_dir'), |
988 | - 'fetch_api': mock.patch('backend.utils.fetch_api'), |
989 | 'fetch_gui_from_branch': mock.patch( |
990 | 'backend.utils.fetch_gui_from_branch'), |
991 | 'fetch_gui_release': mock.patch('backend.utils.fetch_gui_release'), |
992 | @@ -239,8 +164,6 @@ |
993 | 'backend.utils.install_builtin_server'), |
994 | 'install_missing_packages': mock.patch( |
995 | 'backend.utils.install_missing_packages'), |
996 | - 'juju_agent_dir': mock.patch( |
997 | - 'backend.utils.JUJU_AGENT_DIR', self.juju_agent_dir), |
998 | 'log': mock.patch('backend.log'), |
999 | 'open_port': mock.patch('backend.open_port'), |
1000 | 'parse_source': mock.patch( |
1001 | @@ -248,12 +171,10 @@ |
1002 | 'save_or_create_certificates': mock.patch( |
1003 | 'backend.utils.save_or_create_certificates'), |
1004 | 'setup_gui': mock.patch('backend.utils.setup_gui'), |
1005 | - 'start_agent': mock.patch('backend.utils.start_agent'), |
1006 | 'start_builtin_server': mock.patch( |
1007 | 'backend.utils.start_builtin_server'), |
1008 | 'start_haproxy_apache': mock.patch( |
1009 | 'backend.utils.start_haproxy_apache'), |
1010 | - 'stop_agent': mock.patch('backend.utils.stop_agent'), |
1011 | 'stop_builtin_server': mock.patch( |
1012 | 'backend.utils.stop_builtin_server'), |
1013 | 'stop_haproxy_apache': mock.patch( |
1014 | @@ -271,7 +192,7 @@ |
1015 | """Ensure the mocked write_gui_config has been properly called.""" |
1016 | mocks.write_gui_config.assert_called_once_with( |
1017 | config['juju-gui-console-enabled'], config['login-help'], |
1018 | - config['read-only'], config['staging'], config['charmworld-url'], |
1019 | + config['read-only'], config['charmworld-url'], |
1020 | mocks.compute_build_dir(), secure=config['secure'], |
1021 | sandbox=config['sandbox'], ga_key=config['ga-key'], |
1022 | show_get_juju_button=config['show-get-juju-button'], password=None) |
1023 | @@ -293,34 +214,14 @@ |
1024 | test_backend.destroy() |
1025 | self.assertFalse(os.path.exists(utils.BASE_DIR), utils.BASE_DIR) |
1026 | |
1027 | - def test_install_python_legacy_stable(self): |
1028 | - # Install a pyJuju backend with legacy server and stable release. |
1029 | - config = self.make_config({'builtin-server': False}) |
1030 | - with simulate_pyjuju: |
1031 | - test_backend = backend.Backend(config=config) |
1032 | - with self.mock_all() as mocks: |
1033 | - test_backend.install() |
1034 | - mocks.install_missing_packages.assert_called_once_with( |
1035 | - set(EXPECTED_PYTHON_LEGACY_DEBS), |
1036 | - repository=self.repository_location) |
1037 | - mocks.fetch_api.assert_called_once_with(self.juju_api_branch) |
1038 | - mocks.parse_source.assert_called_once_with(self.juju_gui_source) |
1039 | - mocks.fetch_gui_release.assert_called_once_with( |
1040 | - *self.parse_source_return_value) |
1041 | - self.assertFalse(mocks.fetch_gui_from_branch.called) |
1042 | - mocks.setup_gui.assert_called_once_with(mocks.fetch_gui_release()) |
1043 | - self.assertFalse(mocks.install_builtin_server.called) |
1044 | - |
1045 | def test_install_go_legacy_stable(self): |
1046 | # Install a juju-core backend with legacy server and stable release. |
1047 | config = self.make_config({'builtin-server': False}) |
1048 | - with simulate_juju_core: |
1049 | - test_backend = backend.Backend(config=config) |
1050 | - with self.mock_all() as mocks: |
1051 | - test_backend.install() |
1052 | + test_backend = backend.Backend(config=config) |
1053 | + with self.mock_all() as mocks: |
1054 | + test_backend.install() |
1055 | mocks.install_missing_packages.assert_called_once_with( |
1056 | set(EXPECTED_GO_LEGACY_DEBS), repository=self.repository_location) |
1057 | - self.assertFalse(mocks.fetch_api.called) |
1058 | mocks.parse_source.assert_called_once_with(self.juju_gui_source) |
1059 | mocks.fetch_gui_release.assert_called_once_with( |
1060 | *self.parse_source_return_value) |
1061 | @@ -328,33 +229,14 @@ |
1062 | mocks.setup_gui.assert_called_once_with(mocks.fetch_gui_release()) |
1063 | self.assertFalse(mocks.install_builtin_server.called) |
1064 | |
1065 | - def test_install_python_builtin_stable(self): |
1066 | - # Install a pyJuju backend with builtin server and stable release. |
1067 | - config = self.make_config({'builtin-server': True}) |
1068 | - with simulate_pyjuju: |
1069 | - test_backend = backend.Backend(config=config) |
1070 | - with self.mock_all() as mocks: |
1071 | - test_backend.install() |
1072 | - mocks.install_missing_packages.assert_called_once_with( |
1073 | - set(EXPECTED_PYTHON_BUILTIN_DEBS), repository=None) |
1074 | - mocks.fetch_api.assert_called_once_with(self.juju_api_branch) |
1075 | - mocks.parse_source.assert_called_once_with(self.juju_gui_source) |
1076 | - mocks.fetch_gui_release.assert_called_once_with( |
1077 | - *self.parse_source_return_value) |
1078 | - self.assertFalse(mocks.fetch_gui_from_branch.called) |
1079 | - mocks.setup_gui.assert_called_once_with(mocks.fetch_gui_release()) |
1080 | - mocks.install_builtin_server.assert_called_once_with() |
1081 | - |
1082 | def test_install_go_builtin_stable(self): |
1083 | # Install a juju-core backend with builtin server and stable release. |
1084 | config = self.make_config({'builtin-server': True}) |
1085 | - with simulate_juju_core: |
1086 | - test_backend = backend.Backend(config=config) |
1087 | - with self.mock_all() as mocks: |
1088 | - test_backend.install() |
1089 | + test_backend = backend.Backend(config=config) |
1090 | + with self.mock_all() as mocks: |
1091 | + test_backend.install() |
1092 | mocks.install_missing_packages.assert_called_once_with( |
1093 | set(EXPECTED_GO_BUILTIN_DEBS), repository=None) |
1094 | - self.assertFalse(mocks.fetch_api.called) |
1095 | mocks.parse_source.assert_called_once_with(self.juju_gui_source) |
1096 | mocks.fetch_gui_release.assert_called_once_with( |
1097 | *self.parse_source_return_value) |
1098 | @@ -373,12 +255,10 @@ |
1099 | ), |
1100 | ] |
1101 | config = self.make_config({'builtin-server': True}) |
1102 | - with simulate_juju_core: |
1103 | - test_backend = backend.Backend(config=config) |
1104 | - with self.mock_all() as mocks: |
1105 | - test_backend.install() |
1106 | + test_backend = backend.Backend(config=config) |
1107 | + with self.mock_all() as mocks: |
1108 | + test_backend.install() |
1109 | mocks.install_missing_packages.assert_has_calls(expected_calls) |
1110 | - self.assertFalse(mocks.fetch_api.called) |
1111 | mocks.parse_source.assert_called_once_with(self.juju_gui_source) |
1112 | mocks.fetch_gui_from_branch.assert_called_once_with( |
1113 | 'lp:juju-gui', 42, self.command_log_file) |
1114 | @@ -386,31 +266,12 @@ |
1115 | mocks.setup_gui.assert_called_once_with(mocks.fetch_gui_from_branch()) |
1116 | mocks.install_builtin_server.assert_called_once_with() |
1117 | |
1118 | - def test_start_python_legacy(self): |
1119 | - # Start a pyJuju backend with legacy server. |
1120 | - config = self.make_config({'builtin-server': False}) |
1121 | - with simulate_pyjuju: |
1122 | - test_backend = backend.Backend(config=config) |
1123 | - with self.mock_all() as mocks: |
1124 | - test_backend.start() |
1125 | - mocks.start_agent.assert_called_once_with(self.ssl_cert_path) |
1126 | - mocks.compute_build_dir.assert_called_with( |
1127 | - config['juju-gui-debug'], config['serve-tests']) |
1128 | - self.assert_write_gui_config_called(mocks, config) |
1129 | - mocks.open_port.assert_has_calls([mock.call(80), mock.call(443)]) |
1130 | - mocks.start_haproxy_apache.assert_called_once_with( |
1131 | - mocks.compute_build_dir(), config['serve-tests'], |
1132 | - self.ssl_cert_path, config['secure']) |
1133 | - self.assertFalse(mocks.start_builtin_server.called) |
1134 | - |
1135 | def test_start_go_legacy(self): |
1136 | # Start a juju-core backend with legacy server. |
1137 | config = self.make_config({'builtin-server': False}) |
1138 | - with simulate_juju_core: |
1139 | - test_backend = backend.Backend(config=config) |
1140 | - with self.mock_all() as mocks: |
1141 | - test_backend.start() |
1142 | - self.assertFalse(mocks.start_agent.called) |
1143 | + test_backend = backend.Backend(config=config) |
1144 | + with self.mock_all() as mocks: |
1145 | + test_backend.start() |
1146 | mocks.compute_build_dir.assert_called_with( |
1147 | config['juju-gui-debug'], config['serve-tests']) |
1148 | self.assert_write_gui_config_called(mocks, config) |
1149 | @@ -420,33 +281,12 @@ |
1150 | self.ssl_cert_path, config['secure']) |
1151 | self.assertFalse(mocks.start_builtin_server.called) |
1152 | |
1153 | - def test_start_python_builtin(self): |
1154 | - # Start a pyJuju backend with builtin server. |
1155 | - config = self.make_config({'builtin-server': True}) |
1156 | - with simulate_pyjuju: |
1157 | - test_backend = backend.Backend(config=config) |
1158 | - with self.mock_all() as mocks: |
1159 | - test_backend.start() |
1160 | - mocks.start_agent.assert_called_once_with(self.ssl_cert_path) |
1161 | - mocks.compute_build_dir.assert_called_with( |
1162 | - config['juju-gui-debug'], config['serve-tests']) |
1163 | - self.assert_write_gui_config_called(mocks, config) |
1164 | - mocks.open_port.assert_has_calls([mock.call(80), mock.call(443)]) |
1165 | - mocks.start_builtin_server.assert_called_once_with( |
1166 | - mocks.compute_build_dir(), self.ssl_cert_path, |
1167 | - config['serve-tests'], config['sandbox'], |
1168 | - config['builtin-server-logging'], not config['secure'], |
1169 | - config['charmworld-url']) |
1170 | - self.assertFalse(mocks.start_haproxy_apache.called) |
1171 | - |
1172 | def test_start_go_builtin(self): |
1173 | # Start a juju-core backend with builtin server. |
1174 | config = self.make_config({'builtin-server': True}) |
1175 | - with simulate_juju_core: |
1176 | - test_backend = backend.Backend(config=config) |
1177 | - with self.mock_all() as mocks: |
1178 | - test_backend.start() |
1179 | - self.assertFalse(mocks.start_agent.called) |
1180 | + test_backend = backend.Backend(config=config) |
1181 | + with self.mock_all() as mocks: |
1182 | + test_backend.start() |
1183 | mocks.compute_build_dir.assert_called_with( |
1184 | config['juju-gui-debug'], config['serve-tests']) |
1185 | self.assert_write_gui_config_called(mocks, config) |
1186 | @@ -458,47 +298,21 @@ |
1187 | config['charmworld-url']) |
1188 | self.assertFalse(mocks.start_haproxy_apache.called) |
1189 | |
1190 | - def test_stop_python_legacy(self): |
1191 | - # Stop a pyJuju backend with legacy server. |
1192 | - config = self.make_config({'builtin-server': False}) |
1193 | - with simulate_pyjuju: |
1194 | - test_backend = backend.Backend(config=config) |
1195 | - with self.mock_all() as mocks: |
1196 | - test_backend.stop() |
1197 | - mocks.stop_agent.assert_called_once_with() |
1198 | - mocks.stop_haproxy_apache.assert_called_once_with() |
1199 | - self.assertFalse(mocks.stop_builtin_server.called) |
1200 | - |
1201 | def test_stop_go_legacy(self): |
1202 | # Stop a juju-core backend with legacy server. |
1203 | config = self.make_config({'builtin-server': False}) |
1204 | - with simulate_juju_core: |
1205 | - test_backend = backend.Backend(config=config) |
1206 | - with self.mock_all() as mocks: |
1207 | - test_backend.stop() |
1208 | - self.assertFalse(mocks.stop_agent.called) |
1209 | + test_backend = backend.Backend(config=config) |
1210 | + with self.mock_all() as mocks: |
1211 | + test_backend.stop() |
1212 | mocks.stop_haproxy_apache.assert_called_once_with() |
1213 | self.assertFalse(mocks.stop_builtin_server.called) |
1214 | |
1215 | - def test_stop_python_builtin(self): |
1216 | - # Stop a pyJuju backend with builtin server. |
1217 | - config = self.make_config({'builtin-server': True}) |
1218 | - with simulate_pyjuju: |
1219 | - test_backend = backend.Backend(config=config) |
1220 | - with self.mock_all() as mocks: |
1221 | - test_backend.stop() |
1222 | - mocks.stop_agent.assert_called_once_with() |
1223 | - mocks.stop_builtin_server.assert_called_once_with() |
1224 | - self.assertFalse(mocks.stop_haproxy_apache.called) |
1225 | - |
1226 | def test_stop_go_builtin(self): |
1227 | # Stop a juju-core backend with builtin server. |
1228 | config = self.make_config({'builtin-server': True}) |
1229 | - with simulate_juju_core: |
1230 | - test_backend = backend.Backend(config=config) |
1231 | - with self.mock_all() as mocks: |
1232 | - test_backend.stop() |
1233 | - self.assertFalse(mocks.stop_agent.called) |
1234 | + test_backend = backend.Backend(config=config) |
1235 | + with self.mock_all() as mocks: |
1236 | + test_backend.stop() |
1237 | mocks.stop_builtin_server.assert_called_once_with() |
1238 | self.assertFalse(mocks.stop_haproxy_apache.called) |
1239 | |
1240 | @@ -508,22 +322,22 @@ |
1241 | def test_same_config(self): |
1242 | test_backend = backend.Backend( |
1243 | config={ |
1244 | - 'sandbox': False, 'staging': False, 'builtin-server': False}, |
1245 | + 'sandbox': False, 'builtin-server': False}, |
1246 | prev_config={ |
1247 | - 'sandbox': False, 'staging': False, 'builtin-server': False}, |
1248 | + 'sandbox': False, 'builtin-server': False}, |
1249 | ) |
1250 | self.assertFalse(test_backend.different('sandbox')) |
1251 | - self.assertFalse(test_backend.different('staging')) |
1252 | + self.assertFalse(test_backend.different('builtin-server')) |
1253 | |
1254 | def test_different_config(self): |
1255 | test_backend = backend.Backend( |
1256 | config={ |
1257 | - 'sandbox': False, 'staging': False, 'builtin-server': False}, |
1258 | + 'sandbox': False, 'builtin-server': False}, |
1259 | prev_config={ |
1260 | - 'sandbox': True, 'staging': False, 'builtin-server': False}, |
1261 | + 'sandbox': True, 'builtin-server': False}, |
1262 | ) |
1263 | self.assertTrue(test_backend.different('sandbox')) |
1264 | - self.assertFalse(test_backend.different('staging')) |
1265 | + self.assertFalse(test_backend.different('builtin-server')) |
1266 | |
1267 | |
1268 | class TestCallMethods(unittest.TestCase): |
1269 | |
1270 | === modified file 'tests/test_helpers.py' |
1271 | --- tests/test_helpers.py 2013-11-26 20:42:52 +0000 |
1272 | +++ tests/test_helpers.py 2014-01-15 14:49:45 +0000 |
1273 | @@ -20,7 +20,6 @@ |
1274 | import json |
1275 | import os |
1276 | import shutil |
1277 | -import subprocess |
1278 | import tempfile |
1279 | import unittest |
1280 | |
1281 | @@ -34,11 +33,9 @@ |
1282 | juju_destroy_service, |
1283 | juju_env, |
1284 | juju_status, |
1285 | - juju_version, |
1286 | ProcessError, |
1287 | retry, |
1288 | stop_services, |
1289 | - Version, |
1290 | wait_for_unit, |
1291 | WebSocketClient, |
1292 | ) |
1293 | @@ -203,74 +200,6 @@ |
1294 | mock_juju.assert_called_once_with('status', '--format', 'json') |
1295 | |
1296 | |
1297 | -@mock.patch('subprocess.check_output') |
1298 | -class TestJujuVersion(unittest.TestCase): |
1299 | - |
1300 | - error = subprocess.CalledProcessError(2, 'invalid flag', 'output') |
1301 | - |
1302 | - def test_pyjuju(self, mock_check_output): |
1303 | - # The pyJuju version is correctly retrieved. |
1304 | - mock_check_output.return_value = '0.7.2' |
1305 | - version = juju_version() |
1306 | - self.assertEqual(Version(0, 7, 2), version) |
1307 | - mock_check_output.assert_called_once_with( |
1308 | - ['juju', '--version'], stderr=subprocess.STDOUT, |
1309 | - ) |
1310 | - |
1311 | - def test_juju_core(self, mock_check_output): |
1312 | - # The juju-core version is correctly retrieved. |
1313 | - mock_check_output.side_effect = (self.error, '1.12.3') |
1314 | - version = juju_version() |
1315 | - self.assertEqual(Version(1, 12, 3), version) |
1316 | - self.assertEqual(2, mock_check_output.call_count) |
1317 | - first_call, second_call = mock_check_output.call_args_list |
1318 | - self.assertEqual( |
1319 | - mock.call(['juju', '--version'], stderr=subprocess.STDOUT), |
1320 | - first_call, |
1321 | - ) |
1322 | - self.assertEqual(mock.call(['juju', 'version']), second_call) |
1323 | - |
1324 | - def test_not_semantic_versioning(self, mock_check_output): |
1325 | - # If the patch number is missing, it is set to zero. |
1326 | - mock_check_output.return_value = '0.7' |
1327 | - version = juju_version() |
1328 | - self.assertEqual(Version(0, 7, 0), version) |
1329 | - |
1330 | - def test_prefix(self, mock_check_output): |
1331 | - # The function handles versions returned as "juju x.y.z". |
1332 | - mock_check_output.return_value = 'juju 0.8.3' |
1333 | - version = juju_version() |
1334 | - self.assertEqual(Version(0, 8, 3), version) |
1335 | - |
1336 | - def test_suffix(self, mock_check_output): |
1337 | - # The function handles versions returned as "x.y.z-series-arch". |
1338 | - mock_check_output.return_value = '1.10.3-raring-amd64' |
1339 | - version = juju_version() |
1340 | - self.assertEqual(Version(1, 10, 3), version) |
1341 | - |
1342 | - def test_all(self, mock_check_output): |
1343 | - # Additional information is correctly handled. |
1344 | - mock_check_output.side_effect = (self.error, 'juju 1.234-precise-i386') |
1345 | - version = juju_version() |
1346 | - self.assertEqual(Version(1, 234, 0), version) |
1347 | - self.assertEqual(2, mock_check_output.call_count) |
1348 | - |
1349 | - def test_invalid_version(self, mock_check_output): |
1350 | - # A ValueError is raised if the returned version is not valid. |
1351 | - mock_check_output.return_value = '42' |
1352 | - with self.assertRaises(ValueError) as info: |
1353 | - juju_version() |
1354 | - self.assertEqual("invalid juju version: '42'", str(info.exception)) |
1355 | - |
1356 | - def test_failure(self, mock_check_output): |
1357 | - # A CalledProcessError is raised if the Juju version cannot be found. |
1358 | - mock_check_output.side_effect = (self.error, self.error) |
1359 | - with self.assertRaises(subprocess.CalledProcessError) as info: |
1360 | - juju_version() |
1361 | - self.assertIs(self.error, info.exception) |
1362 | - self.assertEqual(2, mock_check_output.call_count) |
1363 | - |
1364 | - |
1365 | class TestProcessError(unittest.TestCase): |
1366 | |
1367 | def test_str(self): |
1368 | |
1369 | === modified file 'tests/test_utils.py' |
1370 | --- tests/test_utils.py 2014-01-09 21:48:27 +0000 |
1371 | +++ tests/test_utils.py 2014-01-15 14:49:45 +0000 |
1372 | @@ -23,15 +23,14 @@ |
1373 | from subprocess import CalledProcessError |
1374 | import tempfile |
1375 | import unittest |
1376 | +import yaml |
1377 | |
1378 | import charmhelpers |
1379 | import mock |
1380 | from shelltoolbox import environ |
1381 | import tempita |
1382 | -import yaml |
1383 | |
1384 | from utils import ( |
1385 | - API_PORT, |
1386 | JUJU_GUI_DIR, |
1387 | JUJU_PEM, |
1388 | WEB_PORT, |
1389 | @@ -45,10 +44,8 @@ |
1390 | get_launchpad_release, |
1391 | get_npm_cache_archive_url, |
1392 | get_release_file_path, |
1393 | - get_zookeeper_address, |
1394 | install_builtin_server, |
1395 | install_missing_packages, |
1396 | - legacy_juju, |
1397 | log_hook, |
1398 | parse_source, |
1399 | remove_apache_setup, |
1400 | @@ -57,14 +54,10 @@ |
1401 | save_or_create_certificates, |
1402 | setup_apache_config, |
1403 | setup_haproxy_config, |
1404 | - start_agent, |
1405 | start_builtin_server, |
1406 | start_haproxy_apache, |
1407 | - start_improv, |
1408 | - stop_agent, |
1409 | stop_builtin_server, |
1410 | stop_haproxy_apache, |
1411 | - stop_improv, |
1412 | write_builtin_server_startup, |
1413 | write_gui_config, |
1414 | ) |
1415 | @@ -410,30 +403,6 @@ |
1416 | self.assertIsNone(path) |
1417 | |
1418 | |
1419 | -class TestLegacyJuju(unittest.TestCase): |
1420 | - |
1421 | - def setUp(self): |
1422 | - self.base_dir = tempfile.mkdtemp() |
1423 | - self.addCleanup(shutil.rmtree, self.base_dir) |
1424 | - # Monkey patch utils.CURRENT_DIR. |
1425 | - self.original_current_dir = utils.CURRENT_DIR |
1426 | - utils.CURRENT_DIR = tempfile.mkdtemp(dir=self.base_dir) |
1427 | - |
1428 | - def tearDown(self): |
1429 | - # Restore the original utils.CURRENT_DIR. |
1430 | - utils.CURRENT_DIR = self.original_current_dir |
1431 | - |
1432 | - def test_jujucore(self): |
1433 | - # If the agent file is found this is a juju-core environment. |
1434 | - agent_path = os.path.join(self.base_dir, 'agent.conf') |
1435 | - open(agent_path, 'w').close() |
1436 | - self.assertFalse(legacy_juju()) |
1437 | - |
1438 | - def test_pyjuju(self): |
1439 | - # If the agent file does not exist this is a PyJuju environment. |
1440 | - self.assertTrue(legacy_juju()) |
1441 | - |
1442 | - |
1443 | def make_collection(attr, values): |
1444 | """Create a collection of objects having an attribute named *attr*. |
1445 | |
1446 | @@ -632,22 +601,6 @@ |
1447 | self.assertEqual('0.1.0.xz', name) |
1448 | |
1449 | |
1450 | -class TestGetZookeeperAddress(unittest.TestCase): |
1451 | - |
1452 | - def setUp(self): |
1453 | - self.zookeeper_address = 'example.com:2000' |
1454 | - contents = 'env JUJU_ZOOKEEPER="{}"\n'.format(self.zookeeper_address) |
1455 | - with tempfile.NamedTemporaryFile(delete=False) as agent_file: |
1456 | - agent_file.write(contents) |
1457 | - self.agent_file_path = agent_file.name |
1458 | - self.addCleanup(os.remove, self.agent_file_path) |
1459 | - |
1460 | - def test_get_zookeeper_address(self): |
1461 | - # Ensure the Zookeeper address is correctly retreived. |
1462 | - address = get_zookeeper_address(self.agent_file_path) |
1463 | - self.assertEqual(self.zookeeper_address, address) |
1464 | - |
1465 | - |
1466 | class TestLogHook(unittest.TestCase): |
1467 | |
1468 | def setUp(self): |
1469 | @@ -853,9 +806,6 @@ |
1470 | def su(user): |
1471 | yield None |
1472 | |
1473 | - def get_zookeeper_address_mock(fp): |
1474 | - return self.fake_zk_address |
1475 | - |
1476 | self.files = {} |
1477 | orig_rtf = utils.render_to_file |
1478 | |
1479 | @@ -872,8 +822,6 @@ |
1480 | run=(utils.run, run), |
1481 | unit_get=(utils.unit_get, noop), |
1482 | render_to_file=(utils.render_to_file, render_to_file), |
1483 | - get_zookeeper_address=( |
1484 | - utils.get_zookeeper_address, get_zookeeper_address_mock), |
1485 | get_api_address=(utils.get_api_address, noop), |
1486 | APACHE_PORTS=(utils.APACHE_PORTS, 'PORTS_NOT_THERE'), |
1487 | APACHE_SITE=(utils.APACHE_SITE, 'SITE_NOT_THERE'), |
1488 | @@ -891,39 +839,6 @@ |
1489 | setattr(utils, fn, fcns[0]) |
1490 | shutil.copy = self.shutil_copy |
1491 | |
1492 | - def test_start_improv(self): |
1493 | - staging_env = 'large' |
1494 | - start_improv(staging_env, self.ssl_cert_path,) |
1495 | - conf = self.files['juju-api-improv.conf'] |
1496 | - self.assertTrue('--port %s' % API_PORT in conf) |
1497 | - self.assertTrue(staging_env + '.json' in conf) |
1498 | - self.assertTrue(self.ssl_cert_path in conf) |
1499 | - self.assertEqual(self.svc_ctl_call_count, 1) |
1500 | - self.assertEqual(self.service_names, ['juju-api-improv']) |
1501 | - self.assertEqual(self.actions, [charmhelpers.START]) |
1502 | - |
1503 | - def test_stop_improv(self): |
1504 | - stop_improv() |
1505 | - self.assertEqual(self.svc_ctl_call_count, 1) |
1506 | - self.assertEqual(self.service_names, ['juju-api-improv']) |
1507 | - self.assertEqual(self.actions, [charmhelpers.STOP]) |
1508 | - |
1509 | - def test_start_agent(self): |
1510 | - start_agent(self.ssl_cert_path, 'config') |
1511 | - conf = self.files['juju-api-agent.conf'] |
1512 | - self.assertTrue('--port %s' % API_PORT in conf) |
1513 | - self.assertTrue('JUJU_ZOOKEEPER=%s' % self.fake_zk_address in conf) |
1514 | - self.assertTrue(self.ssl_cert_path in conf) |
1515 | - self.assertEqual(self.svc_ctl_call_count, 1) |
1516 | - self.assertEqual(self.service_names, ['juju-api-agent']) |
1517 | - self.assertEqual(self.actions, [charmhelpers.START]) |
1518 | - |
1519 | - def test_stop_agent(self): |
1520 | - stop_agent() |
1521 | - self.assertEqual(self.svc_ctl_call_count, 1) |
1522 | - self.assertEqual(self.service_names, ['juju-api-agent']) |
1523 | - self.assertEqual(self.actions, [charmhelpers.STOP]) |
1524 | - |
1525 | def test_compute_build_dir(self): |
1526 | for (juju_gui_debug, serve_tests, result) in ( |
1527 | (False, False, 'build-prod'), |
1528 | @@ -941,9 +856,7 @@ |
1529 | haproxy_conf = self.files['haproxy.cfg'] |
1530 | self.assertIn('ca-base {}'.format(self.ssl_cert_path), haproxy_conf) |
1531 | self.assertIn('crt-base {}'.format(self.ssl_cert_path), haproxy_conf) |
1532 | - self.assertIn('ws1 127.0.0.1:{}'.format(API_PORT), haproxy_conf) |
1533 | self.assertIn('web1 127.0.0.1:{}'.format(WEB_PORT), haproxy_conf) |
1534 | - self.assertIn('ca-file {}'.format(JUJU_PEM), haproxy_conf) |
1535 | self.assertIn('crt {}'.format(JUJU_PEM), haproxy_conf) |
1536 | self.assertIn('redirect scheme https', haproxy_conf) |
1537 | |
1538 | @@ -988,8 +901,9 @@ |
1539 | guiserver_conf = self.files['guiserver.conf'] |
1540 | self.assertIn('description "GUIServer"', guiserver_conf) |
1541 | self.assertIn('--logging="info"', guiserver_conf) |
1542 | - self.assertIn('--apiurl="wss://127.0.0.1:8080/ws"', guiserver_conf) |
1543 | - self.assertIn('--apiversion="python"', guiserver_conf) |
1544 | + # The get_api_address is noop'd in these tests so the addr is None. |
1545 | + self.assertIn('--apiurl="wss://None"', guiserver_conf) |
1546 | + self.assertIn('--apiversion="go"', guiserver_conf) |
1547 | self.assertIn( |
1548 | '--testsroot="{}/test/"'.format(JUJU_GUI_DIR), guiserver_conf) |
1549 | self.assertIn('--insecure', guiserver_conf) |
1550 | @@ -1029,13 +943,13 @@ |
1551 | |
1552 | def test_write_gui_config(self): |
1553 | write_gui_config( |
1554 | - False, 'This is login help.', True, True, self.charmworld_url, |
1555 | + False, 'This is login help.', True, self.charmworld_url, |
1556 | self.build_dir, config_js_path='config', |
1557 | ga_key='UA-123456') |
1558 | js_conf = self.files['config'] |
1559 | self.assertIn('consoleEnabled: false', js_conf) |
1560 | - self.assertIn('user: "admin"', js_conf) |
1561 | - self.assertIn('password: "admin"', js_conf) |
1562 | + self.assertIn('user: "user-admin"', js_conf) |
1563 | + self.assertIn('password: null', js_conf) |
1564 | self.assertIn('login_help: "This is login help."', js_conf) |
1565 | self.assertIn('readOnly: true', js_conf) |
1566 | self.assertIn("socket_url: 'wss://", js_conf) |
1567 | @@ -1046,38 +960,22 @@ |
1568 | |
1569 | def test_write_gui_config_insecure(self): |
1570 | write_gui_config( |
1571 | - False, 'This is login help.', True, True, self.charmworld_url, |
1572 | + False, 'This is login help.', True, self.charmworld_url, |
1573 | self.build_dir, secure=False, config_js_path='config') |
1574 | js_conf = self.files['config'] |
1575 | self.assertIn("socket_url: 'ws://", js_conf) |
1576 | self.assertIn('socket_protocol: "ws"', js_conf) |
1577 | |
1578 | - @mock.patch('utils.legacy_juju') |
1579 | - def test_write_gui_config_default_python_password(self, mock_legacy_juju): |
1580 | - mock_legacy_juju.return_value = True |
1581 | - write_gui_config( |
1582 | - False, 'This is login help.', True, True, self.charmworld_url, |
1583 | - self.build_dir, config_js_path='config', |
1584 | - password='kumquat') |
1585 | - js_conf = self.files['config'] |
1586 | - self.assertIn('user: "admin"', js_conf) |
1587 | - self.assertIn('password: "kumquat"', js_conf) |
1588 | - |
1589 | - @mock.patch('utils.legacy_juju') |
1590 | - def test_write_gui_config_default_sandbox_backend(self, mock_legacy_juju): |
1591 | - mock_legacy_juju.return_value = True |
1592 | - write_gui_config( |
1593 | - False, 'This is login help.', True, True, self.charmworld_url, |
1594 | + def test_write_gui_config_default_sandbox_backend(self): |
1595 | + write_gui_config( |
1596 | + False, 'This is login help.', True, self.charmworld_url, |
1597 | self.build_dir, config_js_path='config', |
1598 | password='kumquat', sandbox=True) |
1599 | js_conf = self.files['config'] |
1600 | - # Because this is sandbox, the apiBackend is always go, even though it |
1601 | - # is legacy_juju. |
1602 | + # Because this is sandbox, the apiBackend is always go. |
1603 | self.assertIn('apiBackend: "go"', js_conf) |
1604 | |
1605 | - @mock.patch('utils.legacy_juju') |
1606 | - def test_write_gui_config_default_go_password(self, mock_legacy_juju): |
1607 | - mock_legacy_juju.return_value = False |
1608 | + def test_write_gui_config_default_go_password(self): |
1609 | write_gui_config( |
1610 | False, 'This is login help.', True, True, self.charmworld_url, |
1611 | self.build_dir, config_js_path='config', |
1612 | @@ -1097,7 +995,7 @@ |
1613 | self.build_dir, sandbox=True, config_js_path='config') |
1614 | js_conf = self.files['config'] |
1615 | self.assertIn('sandbox: true', js_conf) |
1616 | - self.assertIn('user: "admin"', js_conf) |
1617 | + self.assertIn('user: "user-admin"', js_conf) |
1618 | self.assertIn('password: "admin"', js_conf) |
1619 | |
1620 | def test_write_gui_config_with_button(self): |
Reviewers: mp+201510_ code.launchpad. net,
Message:
Please take a look.
Description:
Remove support for PyJuju and rapi from charm.
WIP - couple of question points and failing functional legacy test.
https:/ /code.launchpad .net/~rharding/ charms/ precise/ juju-gui/ remove- pyjuju/ +merge/ 201510
(do not edit description out of merge proposal)
Please review this at https:/ /codereview. appspot. com/51620043/
Affected files (+90, -499 lines): haproxy. cfg.template juju-api- improv. conf.template functional. test backends. py
M Dependencies.md
M README.md
A [revision details]
M config.yaml
M config/
D config/
M hooks/backend.py
M hooks/utils.py
M tests/20-
M tests/test_
M tests/test_utils.py