Merge lp:~rharding/charms/precise/juju-gui/remove-pyjuju into lp:~juju-gui/charms/precise/juju-gui/trunk

Proposed by Richard Harding
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
Reviewer Review Type Date Requested Status
charmers Pending
Review via email: mp+201510@code.launchpad.net

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.

https://codereview.appspot.com/52440043/

To post a comment you must log in.
Revision history for this message
Richard Harding (rharding) wrote :

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):
   M Dependencies.md
   M README.md
   A [revision details]
   M config.yaml
   M config/haproxy.cfg.template
   D config/juju-api-improv.conf.template
   M hooks/backend.py
   M hooks/utils.py
   M tests/20-functional.test
   M tests/test_backends.py
   M tests/test_utils.py

150. By Richard Harding

Remove agent and zookeeper related functions

151. By Richard Harding

Fix lint

Revision history for this message
Richard Harding (rharding) wrote :

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/52120043/

Affected files (+92, -695 lines):
   M Dependencies.md
   M Makefile
   M README.md
   A [revision details]
   M config.yaml
   M config/haproxy.cfg.template
   D config/juju-api-agent.conf.template
   D config/juju-api-improv.conf.template
   M hooks/backend.py
   M hooks/utils.py
   M tests/20-functional.test
   M tests/test_backends.py
   M tests/test_utils.py

Revision history for this message
Richard Harding (rharding) wrote :

Reviewers: mp+201510_code.launchpad.net,

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://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/51470044/

Affected files (+92, -695 lines):
   M Dependencies.md
   M Makefile
   M README.md
   A [revision details]
   M config.yaml
   M config/haproxy.cfg.template
   D config/juju-api-agent.conf.template
   D config/juju-api-improv.conf.template
   M hooks/backend.py
   M hooks/utils.py
   M tests/20-functional.test
   M tests/test_backends.py
   M tests/test_utils.py

Revision history for this message
Francesco Banconi (frankban) wrote :
Download full text (4.0 KiB)

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://codereview.appspot.com/51470044/diff/1/README.md
File README.md (right):

https://codereview.appspot.com/51470044/diff/1/README.md#newcode76
README.md:76: core) or "admin" (for pyjuju). The password is the same as
your Juju
We can remove the pyjuju reference here.

https://codereview.appspot.com/51470044/diff/1/README.md#newcode105
README.md:105: For both Juju Core and PyJuju, you must simply do the
following steps. Note
And here too...

https://codereview.appspot.com/51470044/diff/1/README.md#newcode162
README.md:162: #### pyjuju ####
We can get rid of this paragraph and of all the juju-jitsu stuff \o/

https://codereview.appspot.com/51470044/diff/1/config/haproxy.cfg.template
File config/haproxy.cfg.template (right):

https://codereview.appspot.com/51470044/diff/1/config/haproxy.cfg.template#newcode25
config/haproxy.cfg.template:25: # Replace "/ws/" with "/" in any request
path.
Nice.

https://codereview.appspot.com/51470044/diff/1/hooks/backend.py
File hooks/backend.py (left):

https://codereview.appspot.com/51470044/diff/1/hooks/backend.py#oldcode262
hooks/backend.py:262: raise ValueError('Unable to use staging with go
backend')
I am very happy we removed this ValueError for incompatible options.

https://codereview.appspot.com/51470044/diff/1/hooks/utils.py
File hooks/utils.py (right):

https://codereview.appspot.com/51470044/diff/1/hooks/utils.py#newcode87
hooks/utils.py:87: Serializer, su,
Please keep "su" in its own line.

https://codereview.appspot.com/51470044/diff/1/hooks/utils.py#newcode148
hooks/utils.py:148: return api_addresses.split()[0]
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://codereview.appspot.com/51470044/diff/1/hooks/utils.py#newcode320
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://codereview.appspot.com/51470044/diff/1/hooks/utils.py#newcode362
hooks/utils.py:362: # In PyJuju environments, use the same certificate
for both HTTPS and
Please remove this reference to PyJuju.

https://codereview.appspot.com/51470044/diff/1/tests/20-functional.test
File tests/20-functional.test (right):

https://codereview.appspot.com/51470044/diff/1/tests/20-functional.test#newcode45
tests/20-functional.test:45: STAGING_SERVICES = ('haproxy', 'mediawiki',
'memcached', 'mysql', 'wordpress')
STAGING_SERVICES seems to be no longer required.

https://codereview.appspot.com/51470044/diff/1/tests/20-functional.test#newcode46
tests/20-functional.test:46: juju_version().major == 0
Can't we remove this line?
Moreover, can't we remove the juju_version function entirely?

https://codereview.appspot.com/51470044/diff/1/tests/20-functional.test#newcode69
tests/20-functional.test:69: # XXX 2012-11-29 frankban bug=872264:
This XXX comment is no longer required. We can remove all the
cleanup_services machinery.

https://codereview.appspot.com/51470044/diff/1/tests/2...

Read more...

152. By Richard Harding

Updated per review

Revision history for this message
Richard Harding (rharding) wrote :

Reviewers: mp+201510_code.launchpad.net,

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://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/52440043/

Affected files (+107, -847 lines):
   M Dependencies.md
   M Makefile
   M README.md
   A [revision details]
   M config.yaml
   M config/haproxy.cfg.template
   D config/juju-api-agent.conf.template
   D config/juju-api-improv.conf.template
   M hooks/backend.py
   M hooks/utils.py
   M tests/20-functional.test
   M tests/helpers.py
   M tests/test_backends.py
   M tests/test_helpers.py
   M tests/test_utils.py

Revision history for this message
Richard Harding (rharding) wrote :
Download full text (4.4 KiB)

I'm fighing lbox. When I updated this it put it over at a new url.

https://codereview.appspot.com/52440043

https://codereview.appspot.com/51470044/diff/1/README.md
File README.md (right):

https://codereview.appspot.com/51470044/diff/1/README.md#newcode76
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://codereview.appspot.com/51470044/diff/1/README.md#newcode105
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://codereview.appspot.com/51470044/diff/1/README.md#newcode162
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://codereview.appspot.com/51470044/diff/1/hooks/utils.py
File hooks/utils.py (right):

https://codereview.appspot.com/51470044/diff/1/hooks/utils.py#newcode87
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://codereview.appspot.com/51470044/diff/1/hooks/utils.py#newcode148
hooks/utils.py:148: return api_addresses.split()[0]
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://codereview.appspot.com/51470044/diff/1/hooks/utils.py#newcode320
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://codereview.appspot.com/51470044/diff/1/hooks/utils.py#newcode362
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://codereview.appspot.com/51470044/diff/1/tests/20-functional.test
File tests/20-functional.test (right):

https://codereview.appspot.com/51470044/diff/1/tests/20-functional.test#newcode45
tests/20-functional.test:45: STAGING_SERVICES = ('haproxy', 'mediawiki',
'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://codereview.appspot.com/51470044/diff/1/tests/20-functional.test#newcode46
tests/20-functional.test:46: juju_version().major == 0
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://codereview.appspot.com/51470044/diff/1/tests/20-functional.test#newcode78
tests/20-functional.test:78: if options is None:
On 2014/0...

Read more...

Revision history for this message
Francesco Banconi (frankban) wrote :

https://codereview.appspot.com/51470044/diff/1/hooks/utils.py
File hooks/utils.py (right):

https://codereview.appspot.com/51470044/diff/1/hooks/utils.py#newcode148
hooks/utils.py:148: return api_addresses.split()[0]
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.

https://codereview.appspot.com/51470044/

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

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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):

Subscribers

People subscribed via source and target branches