Merge lp:~bac/python-jujuclient/tls into lp:~hazmat/python-jujuclient/trunk

Proposed by Brad Crittenden
Status: Merged
Merged at revision: 35
Proposed branch: lp:~bac/python-jujuclient/tls
Merge into: lp:~hazmat/python-jujuclient/trunk
Diff against target: 121 lines (+47/-13)
3 files modified
HACKING.rst (+22/-0)
jujuclient.py (+6/-6)
test_jujuclient.py (+19/-7)
To merge this branch: bzr merge lp:~bac/python-jujuclient/tls
Reviewer Review Type Date Requested Status
Kapil Thangavelu Approve
Review via email: mp+223823@code.launchpad.net

Description of the change

Force websocket to use TLS.

The default SSL library on OS X attempts to use SSLv2 on connections. When
trying to connect to the juju endpoint with SSLv2 the connection is refused
and no negotiation is tried.

Luckily websocket create_connection has an undocumented kwarg sslopt which can
be used to force TLS.

Without the change all tests fail on OS X. With the change they all pass.

The test suite had failures before this branch was started and they have been
fixed.

The use of time.sleep(4) after calling client.destroy_service is required for
the status to be removed from status calls.

Also a minimal HACKING.rst doc was added to show how to run the tests.

To post a comment you must log in.
Revision history for this message
Brad Crittenden (bac) wrote :

Please take a look.

Revision history for this message
Kapil Thangavelu (hazmat) wrote :

Thanks

review: Approve
Revision history for this message
Kapil Thangavelu (hazmat) wrote :

comments re sync client

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'HACKING.rst'
2--- HACKING.rst 1970-01-01 00:00:00 +0000
3+++ HACKING.rst 2014-06-19 20:55:27 +0000
4@@ -0,0 +1,22 @@
5+Juju Client Hacking Tips
6+========================
7+
8+Running tests
9+-------------
10+
11+In order to run the tests a Juju environment must be bootstrapped manually for
12+the tests to interact. Do the following to run against an ec2 environment::
13+
14+ $ juju bootstrap -e ec2
15+
16+After it is booted, set the dns-name of machine 0 to be JUJU_ENDPOINT::
17+
18+ $ export JUJU_ENDPOINT=`juju status | \
19+ grep dns-name | awk -F': ' '{print "wss://"$2":17070"}'`
20+
21+You must also set JUJU_AUTH to be the admin-secret from the file in
22+$JUJU_HOME/environments/ec2
23+
24+Once those two environment variables are set you can run the tests with::
25+
26+ $ python test_jujuclient.py
27
28=== modified file 'jujuclient.py'
29--- jujuclient.py 2014-04-27 01:38:13 +0000
30+++ jujuclient.py 2014-06-19 20:55:27 +0000
31@@ -56,6 +56,7 @@
32 import pprint
33 import signal
34 import socket
35+import ssl
36 import StringIO
37 import time
38 import websocket
39@@ -176,7 +177,8 @@
40 try:
41 self.conn = websocket.create_connection(
42 self._reconnect_params['url'],
43- origin=self._reconnect_params['origin'])
44+ origin=self._reconnect_params['origin'],
45+ sslopt={'ssl_version': ssl.PROTOCOL_TLSv1})
46 break
47 except socket.error as err:
48 if not err.errno in (
49@@ -308,7 +310,8 @@
50 self.conn = conn
51 else:
52 self.conn = websocket.create_connection(
53- endpoint, origin=self.endpoint)
54+ endpoint, origin=self.endpoint,
55+ sslopt={'ssl_version': ssl.PROTOCOL_TLSv1})
56
57 def close(self):
58 for w in self._watches:
59@@ -959,14 +962,11 @@
60 for ep in d['Endpoints']:
61 svc_rels = self.data.setdefault(
62 'services', {}).setdefault(
63- ep['ServiceName'], {}).setdefault(
64- 'relations', {})
65+ ep['ServiceName'], {}).setdefault('relations', {})
66 svc_rels.setdefault(
67 ep['Relation']['Name'], []).append(ep['RemoteService'])
68
69
70-
71-
72 def main():
73 import os
74 juju_url, juju_token = (
75
76=== modified file 'test_jujuclient.py'
77--- test_jujuclient.py 2014-03-18 11:45:26 +0000
78+++ test_jujuclient.py 2014-06-19 20:55:27 +0000
79@@ -18,23 +18,35 @@
80
81 def assert_service(self, svc_name):
82 status = self.client.status()
83- self.assertTrue(svc_name in [
84- svc.get('Name') for svc in status.get('Services', ())])
85+ services = status.get('Services', {})
86+ self.assertTrue(
87+ svc_name in services,
88+ "Service {} does not exist".format(svc_name)
89+ )
90
91 def assert_not_service(self, svc_name):
92 status = self.client.status()
93- self.assertTrue(svc_name not in [
94- svc.get('Name') for svc in status.get('Services', ())])
95+ services = status.get('Services', {})
96+ self.assertFalse(
97+ svc_name in services,
98+ "Service {} exists".format(svc_name)
99+ )
100
101 def test_juju_info(self):
102 self.assertEqual(
103- self.client.info().keys(),
104- ['DefaultSeries', 'Name', 'ProviderType'])
105+ sorted(self.client.info().keys()),
106+ ['DefaultSeries', 'Name', 'ProviderType', 'UUID'])
107
108 def test_deploy_and_destroy(self):
109 self.assert_not_service('db')
110- self.client.deploy('db', 'precise/mysql')
111+ self.client.deploy('db', 'precise/mysql-46')
112 self.assert_service('db')
113+ self.client.destroy_service('db')
114+ # XXX: This library claims to be synchronous but destroying a service
115+ # takes over 3 seconds to be removed from the status listing.
116+ import time
117+ time.sleep(4)
118+ self.assert_not_service('db')
119
120 def test_expose_unexpose(self):
121 pass

Subscribers

People subscribed via source and target branches