Merge lp:~jason-hobbs/juju-deployer/juju-deployer-populate-first into lp:juju-deployer

Proposed by Jason Hobbs
Status: Rejected
Rejected by: Haw Loeung
Proposed branch: lp:~jason-hobbs/juju-deployer/juju-deployer-populate-first
Merge into: lp:juju-deployer
Diff against target: 545 lines (+255/-41)
12 files modified
Makefile (+5/-1)
deployer/action/importer.py (+137/-15)
deployer/cli.py (+7/-0)
deployer/deployment.py (+40/-8)
deployer/env/go.py (+27/-0)
deployer/env/py.py (+6/-0)
deployer/service.py (+11/-4)
deployer/tests/test_charm.py (+8/-0)
deployer/tests/test_deployment.py (+7/-9)
deployer/tests/test_diff.py (+3/-2)
deployer/tests/test_guiserver.py (+3/-2)
deployer/tests/test_importer.py (+1/-0)
To merge this branch: bzr merge lp:~jason-hobbs/juju-deployer/juju-deployer-populate-first
Reviewer Review Type Date Requested Status
juju-deployers Pending
Review via email: mp+261457@code.launchpad.net

Description of the change

Update of lp:~raharper/juju-deployer/populate-first - this merges a newer trunk. It also rename's rharper's add_machine to 'add_specific_machine' to avoid a conflict with the 'add_machine' from trunk. That needs a closer looking at to see how to use just one of those methods but I don't have time to figure it out right now.

To post a comment you must log in.
152. By Jason Hobbs

Fix syntax error and unit test.

153. By Jason Hobbs

Pull in lutostag's test fixes.

154. By Jason Hobbs

Force service sorting, and log it.

155. By Jason Hobbs

Specify series when adding a specific machine.

156. By Jason Hobbs

Use charm series if one provided by the charm.

This fixes deploying mixed Ubuntu/Windows bundles.

157. By Jason Hobbs

Timeout when acquiring a node takes too long.

Unmerged revisions

157. By Jason Hobbs

Timeout when acquiring a node takes too long.

156. By Jason Hobbs

Use charm series if one provided by the charm.

This fixes deploying mixed Ubuntu/Windows bundles.

155. By Jason Hobbs

Specify series when adding a specific machine.

154. By Jason Hobbs

Force service sorting, and log it.

153. By Jason Hobbs

Pull in lutostag's test fixes.

152. By Jason Hobbs

Fix syntax error and unit test.

151. By Jason Hobbs

Merge trunk.

150. By Ryan Harper

Allow nested placement when target uses maas= placement. Fix up debugging log message during deploy_services.

149. By Ryan Harper

Modify depoyment.deploy_services to bring services with placement and multiple units online to ensure subsequent services which placement can target previously deployed service units. Update get_machine to handle container placement.

148. By Ryan Harper

Fix typo

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Makefile'
--- Makefile 2014-08-26 22:34:07 +0000
+++ Makefile 2015-07-06 20:11:20 +0000
@@ -1,5 +1,9 @@
1ifeq (,$(wildcard $(HOME)/.bazaar/bazaar.conf))
2 PREFIX=HOME=/tmp
3endif
1test:4test:
2 nosetests -s --verbosity=2 deployer/tests5 /bin/bash -c 'if [ -n "$(PREFIX)" ]; then mkdir -p /tmp/.juju; else true; fi'
6 /bin/bash -c "$(PREFIX) nosetests -s --verbosity=2 deployer/tests"
37
4freeze:8freeze:
5 pip install -d tools/dist -r requirements.txt9 pip install -d tools/dist -r requirements.txt
610
=== modified file 'deployer/action/importer.py'
--- deployer/action/importer.py 2015-05-28 13:04:30 +0000
+++ deployer/action/importer.py 2015-07-06 20:11:20 +0000
@@ -1,5 +1,6 @@
1import logging1import logging
2import time2import time
3import math
34
4from .base import BaseAction5from .base import BaseAction
5from ..env import watchers6from ..env import watchers
@@ -58,7 +59,8 @@
58 "Adding %d more units to %s" % (abs(delta), svc.name))59 "Adding %d more units to %s" % (abs(delta), svc.name))
59 if svc.unit_placement:60 if svc.unit_placement:
60 # Reload status once after non placed services units are done.61 # Reload status once after non placed services units are done.
61 if reloaded is False:62
63 if self.options.placement_first is True or reloaded is False:
62 # Improved crappy workaround juju-core api inconsistency64 # Improved crappy workaround juju-core api inconsistency
63 delay = time.time() + 6065 delay = time.time() + 60
64 while delay > time.time():66 while delay > time.time():
@@ -71,7 +73,8 @@
7173
72 placement = self.deployment.get_unit_placement(svc, env_status)74 placement = self.deployment.get_unit_placement(svc, env_status)
73 for mid in range(cur_units, svc.num_units):75 for mid in range(cur_units, svc.num_units):
74 self.env.add_unit(svc.name, placement.get(mid))76 self.env.add_unit(svc.name,
77 self.get_machine(placement.get(mid)))
75 else:78 else:
76 self.env.add_units(svc.name, abs(delta))79 self.env.add_units(svc.name, abs(delta))
7780
@@ -181,13 +184,17 @@
181 charm = self.deployment.get_charm_for(svc.name)184 charm = self.deployment.get_charm_for(svc.name)
182 self.log.info(185 self.log.info(
183 " Deploying service %s using %s", svc.name, charm.charm_url)186 " Deploying service %s using %s", svc.name, charm.charm_url)
187
188 # Use charm series instead of deployment one if charm provides it.
189 # If charm does not provide series, this will be set to None.
190 charm_series = self.deployment.get_charm_series(svc.name)
184191
185 if svc.unit_placement:192 if svc.unit_placement:
186 # We sorted all the non placed services first, so we only193 # We sorted all the non placed services first, so we only
187 # need to update status once after we're done with them, in194 # need to update status once after we're done with them, in
188 # the instance of v3 bundles; in the more complex case of v4195 # the instance of v3 bundles; in the more complex case of v4
189 # bundles, we'll need to refresh each time.196 # bundles, we'll need to refresh each time.
190 if not reloaded:197 if self.options.placement_first or not reloaded:
191 self.log.debug(198 self.log.debug(
192 " Refetching status for placement deploys")199 " Refetching status for placement deploys")
193 time.sleep(5.1)200 time.sleep(5.1)
@@ -210,18 +217,59 @@
210 num_units = None217 num_units = None
211218
212 placement = self.deployment.get_unit_placement(svc, env_status)219 placement = self.deployment.get_unit_placement(svc, env_status)
213220 # allocate all of the machines up front for all units
214 if charm.is_subordinate():221 # to ensure we don't allocate a targeted machine to
215 num_units = None222 # a service without placement
216223 if svc.unit_placement and \
217 self.env.deploy(224 svc.num_units > 1 and \
218 svc.name,225 self.options.placement_first is True:
219 charm.charm_url,226 self.log.debug('Pre-allocating machines for %s' % svc.name)
220 self.deployment.repo_path,227 self.log.debug('Deploy base service: %s' % svc.name)
221 svc.config,228 p = placement.get(0)
222 svc.constraints,229 machine = self.get_machine(p, charm_series)
223 num_units,230 self.log.debug('deploy_services: '
224 placement.get(0))231 'service=%s unit=0 placement=%s machine=%s' %
232 (svc.name, p, machine))
233 num_units = 1
234 # deploy base service
235 self.env.deploy(
236 svc.name,
237 charm.charm_url,
238 self.deployment.repo_path,
239 svc.config,
240 svc.constraints,
241 num_units,
242 machine)
243
244 # add additional units
245 time.sleep(5.1)
246 env_status = self.env.status()
247 cur_units = len(env_status['services'][svc.name].get('units', ()))
248 placement = self.deployment.get_unit_placement(svc, env_status)
249 for uid in range(cur_units, svc.num_units):
250 p = placement.get(uid)
251 machine = self.get_machine(p, charm_series)
252 self.log.debug('add_units: '
253 'service=%s unit=%s placement=%s machine=%s' %
254 (svc.name, uid, p, machine))
255 self.env.add_unit(svc.name, machine)
256
257
258 else:
259 # just let add_units handling bring additional units on-line
260 num_units = 1
261
262 if charm.is_subordinate():
263 num_units = None
264
265 self.env.deploy(
266 svc.name,
267 charm.charm_url,
268 self.deployment.repo_path,
269 svc.config,
270 svc.constraints,
271 num_units,
272 self.get_machine(placement.get(0), charm_series))
225273
226 if svc.annotations:274 if svc.annotations:
227 self.log.debug(" Setting annotations")275 self.log.debug(" Setting annotations")
@@ -294,6 +342,80 @@
294 int(timeout), watch=self.options.watch,342 int(timeout), watch=self.options.watch,
295 services=self.deployment.get_service_names(), on_errors=on_errors)343 services=self.deployment.get_service_names(), on_errors=on_errors)
296344
345 def get_machine(self, u_idx, charm_series=None):
346 # find the machine id that matches the target machine
347 # unlike juju status output, the dns-name is one of the
348 # many values returned from our env.status() in addresses
349 if u_idx is None:
350 return None
351
352 status = self.env.status()
353 # lxc:1 kvm:1, or 1
354 if ':' in u_idx or u_idx.isdigit():
355 mid = [u_idx]
356 else:
357 mid = [x for x in status['machines'].keys()
358 if u_idx in
359 [v.get('Value') for v in
360 status['machines'][x]['addresses']]]
361 self.deployment.log.info('mid=%s' % mid)
362 if mid:
363 m = mid.pop()
364 self.deployment.log.debug(
365 'Found juju machine (%s) matching placement: %s', m, u_idx)
366 return m
367 else:
368 self.deployment.log.info(
369 'No match in juju machines for: %s', u_idx)
370
371 # if we don't find a match, we need to add it
372 series = self.deployment.data['series']
373 if (charm_series is not None) and (charm_series != series):
374 # override series if different from deployment series
375 series = charm_series
376
377 mid = self.env.add_specific_machine(u_idx, series)
378
379 # timeout set to ~17 minutes which is much larger than needed
380 backoff = 2
381 delay = 1
382 timeout = math.pow(2, 10)
383
384 self.deployment.log.debug(
385 'Waiting for machine to show up in status.')
386 while True:
387 m = mid.get('Machine')
388 if m in status['machines'].keys():
389 s = [x for x in status['machines'].keys()
390 if u_idx in
391 [v.get('Value') for v in
392 status['machines'][x]['addresses']]]
393 self.deployment.log.debug('addresses: %s' % s)
394 if m in s:
395 break
396 else:
397 self.deployment.log.debug(
398 'Machine %s not in status yet' % m)
399
400 self.deployment.log.debug("Sleep for %s second(s).",
401 str(delay))
402 time.sleep(delay)
403 delay *= backoff
404
405 # The case of a machine failing to show up is really a
406 # an unrecoverable failure that can't be dealt with as upstream
407 # is not handling this case. So, the deployment must fail here.
408 if timeout-delay <= 0:
409 self.deployment.log.error(
410 "Deployment has failed. Machine %s did not show up.",
411 u_idx)
412 raise ErrorExit()
413
414
415 status = self.env.status()
416 self.deployment.log.debug('Machine %s up!' % m)
417 return mid.get('Machine')
418
297 def run(self):419 def run(self):
298 options = self.options420 options = self.options
299 self.start_time = time.time()421 self.start_time = time.time()
300422
=== modified file 'deployer/cli.py'
--- deployer/cli.py 2014-10-01 10:18:36 +0000
+++ deployer/cli.py 2015-07-06 20:11:20 +0000
@@ -82,6 +82,13 @@
82 "machine removal."),82 "machine removal."),
83 dest="deploy_delay", default=0)83 dest="deploy_delay", default=0)
84 parser.add_argument(84 parser.add_argument(
85 '-P', '--placement-first', action='store_true', default=False,
86 dest='placement_first',
87 help=("Sort services with placement services first to "
88 "ensure that the requirement machines are aquired "
89 "before non-targeted services are deployed. Note "
90 "this reverses the default sorting order."))
91 parser.add_argument(
85 '-e', '--environment', action='store', dest='juju_env',92 '-e', '--environment', action='store', dest='juju_env',
86 help='Deploy to a specific Juju environment.',93 help='Deploy to a specific Juju environment.',
87 default=os.getenv('JUJU_ENV'))94 default=os.getenv('JUJU_ENV'))
8895
=== modified file 'deployer/deployment.py'
--- deployer/deployment.py 2015-05-13 14:16:46 +0000
+++ deployer/deployment.py 2015-07-06 20:11:20 +0000
@@ -46,11 +46,10 @@
46 services = []46 services = []
47 for name, svc_data in self.data.get('services', {}).items():47 for name, svc_data in self.data.get('services', {}).items():
48 services.append(Service(name, svc_data))48 services.append(Service(name, svc_data))
49 if self.version == 3:49
50 # Sort unplaced units first, then sort by name for placed units.50 self.log.debug("Sorting services: %s" % services)
51 services.sort(key=lambda svc: (bool(svc.unit_placement), svc.name))51 services.sort(self._services_sort)
52 else:52 self.log.debug("Sorted services: %s" % services)
53 services.sort(self._machines_placement_sort)
54 return services53 return services
5554
56 def set_machines(self, machines):55 def set_machines(self, machines):
@@ -81,7 +80,7 @@
81 return self.data.get('services', {}).keys()80 return self.data.get('services', {}).keys()
8281
83 @staticmethod82 @staticmethod
84 def _machines_placement_sort(svc_a, svc_b):83 def _services_sort(svc_a, svc_b):
85 """Sort machines with machine placement in mind.84 """Sort machines with machine placement in mind.
8685
87 If svc_a is colocated alongside svc_b, svc_b needs to be deployed86 If svc_a is colocated alongside svc_b, svc_b needs to be deployed
@@ -90,6 +89,35 @@
90 whether or not the service has a unit placement, and then finally89 whether or not the service has a unit placement, and then finally
91 based on the name of the service.90 based on the name of the service.
92 """91 """
92 def _placement_sort(svc_a, svc_b):
93 """ Sorts unit_placement lists,
94 putting maas= units at the front"""
95 def maas_first(a, b):
96 if a.startswith('maas='):
97 if b.startswith('maas='):
98 return cmp(a, b)
99 return -1
100 if b.startswith('maas='):
101 return 1
102
103 if ':' in a:
104 if ':' in b:
105 return cmp(a, b)
106 return 1
107
108 return cmp(a, b)
109
110 # sort both services' unit_placement lists
111 # putting maas units first
112 svc_a.unit_placement.sort(cmp=maas_first)
113 svc_b.unit_placement.sort(cmp=maas_first)
114
115 # now compare the service placement lists,
116 # first list with a maas placement goes first
117 for x, y in zip(svc_a.unit_placement,
118 svc_b.unit_placement):
119 return maas_first(x, y)
120
93 if svc_a.unit_placement:121 if svc_a.unit_placement:
94 if svc_b.unit_placement:122 if svc_b.unit_placement:
95 # Check for colocation. This naively assumes that there is no123 # Check for colocation. This naively assumes that there is no
@@ -98,8 +126,8 @@
98 return -1126 return -1
99 if x_in_y(svc_a, svc_b):127 if x_in_y(svc_a, svc_b):
100 return 1128 return 1
101 # If no colocation exists, simply compare names.129 # If no colocation exists, do a placement sort.
102 return cmp(svc_a.name, svc_b.name)130 return _placement_sort(svc_a, svc_b)
103 return 1131 return 1
104 if svc_b.unit_placement:132 if svc_b.unit_placement:
105 return -1133 return -1
@@ -166,6 +194,10 @@
166 return Charm.from_service(194 return Charm.from_service(
167 svc_name, self.repo_path, self.series, svc_data)195 svc_name, self.repo_path, self.series, svc_data)
168196
197 def get_charm_series(self, svc_name):
198 svc_data = self.data['services'][svc_name]
199 return svc_data.get('series')
200
169 def fetch_charms(self, update=False, no_local_mods=False):201 def fetch_charms(self, update=False, no_local_mods=False):
170 for charm in self.get_charms():202 for charm in self.get_charms():
171 if charm.is_local():203 if charm.is_local():
172204
=== modified file 'deployer/env/go.py'
--- deployer/env/go.py 2015-03-12 18:41:43 +0000
+++ deployer/env/go.py 2015-07-06 20:11:20 +0000
@@ -41,6 +41,30 @@
41 series=series, 41 series=series,
42 constraints=parse_constraints(constraints))['Machine']42 constraints=parse_constraints(constraints))['Machine']
4343
44 def add_specific_machine(self, machine, series=""):
45 if ':' in machine:
46 scope, directive = machine.split(':')
47 else:
48 scope = self.get_env_config()['Config']['uuid']
49 directive = machine
50
51 machines = [{
52 "Placement": {
53 "Scope": scope,
54 "Directive": directive,
55 },
56 "ParentId": "",
57 "ContainerType": "",
58 "Series": series,
59 "Constraints": {},
60 "Jobs": [
61 "JobHostUnits"
62 ]
63 }]
64 self.log.debug('Adding machine: %s:%s' % (scope, directive))
65 # {u'Machines': [{u'Machine': u'7', u'Error': None}]}
66 return self.client.add_machines(machines)['Machines'][0]
67
44 def add_unit(self, service_name, machine_spec):68 def add_unit(self, service_name, machine_spec):
45 return self.client.add_unit(service_name, machine_spec)69 return self.client.add_unit(service_name, machine_spec)
4670
@@ -68,6 +92,9 @@
68 def get_config(self, svc_name):92 def get_config(self, svc_name):
69 return self.client.get_config(svc_name)93 return self.client.get_config(svc_name)
7094
95 def get_env_config(self):
96 return self.client.get_env_config()
97
71 def get_constraints(self, svc_name):98 def get_constraints(self, svc_name):
72 try:99 try:
73 return self.client.get_constraints(svc_name)100 return self.client.get_constraints(svc_name)
74101
=== modified file 'deployer/env/py.py'
--- deployer/env/py.py 2014-02-18 12:16:46 +0000
+++ deployer/env/py.py 2015-07-06 20:11:20 +0000
@@ -12,6 +12,12 @@
12 self.name = name12 self.name = name
13 self.options = options13 self.options = options
1414
15 def add_machine(self, machine):
16 params - self._named_env(["juju", "add-machine"])
17 params.extend([machine])
18 self._check_call(
19 params, self.log, "Error adding machine %s", machine)
20
15 def add_units(self, service_name, num_units):21 def add_units(self, service_name, num_units):
16 params = self._named_env(["juju", "add-unit"])22 params = self._named_env(["juju", "add-unit"])
17 if num_units > 1:23 if num_units > 1:
1824
=== modified file 'deployer/service.py'
--- deployer/service.py 2015-03-18 18:19:43 +0000
+++ deployer/service.py 2015-07-06 20:11:20 +0000
@@ -152,12 +152,19 @@
152 feedback.error(152 feedback.error(
153 ("Service placement to machine"153 ("Service placement to machine"
154 "not supported %s to %s") % (154 "not supported %s to %s") % (
155 self.service.name, unit_placement[idx]))155 self.service.name, unit_placement[idx]))
156 elif p in services:156 elif p in services:
157 if services[p].unit_placement:157 if services[p].unit_placement:
158 feedback.error(158 # nested placement is acceptable if the target
159 "Nested placement not supported %s -> %s -> %s" % (159 # is using maas node placement
160 self.service.name, p, services[p].unit_placement))160 for u in services[p].unit_placement:
161 if not u.startswith('maas='):
162 feedback.error(
163 "Nested placement not supported"
164 " %s -> %s -> %s" % (
165 self.service.name, p,
166 services[p].unit_placement))
167 continue
161 elif self.deployment.get_charm_for(p).is_subordinate():168 elif self.deployment.get_charm_for(p).is_subordinate():
162 feedback.error(169 feedback.error(
163 "Cannot place to a subordinate service: %s -> %s" % (170 "Cannot place to a subordinate service: %s -> %s" % (
164171
=== modified file 'deployer/tests/test_charm.py'
--- deployer/tests/test_charm.py 2014-09-29 14:36:34 +0000
+++ deployer/tests/test_charm.py 2015-07-06 20:11:20 +0000
@@ -161,6 +161,14 @@
161 self._call(161 self._call(
162 ["git", "init", self.path],162 ["git", "init", self.path],
163 "Could not initialize repo at %(path)s")163 "Could not initialize repo at %(path)s")
164 self._call(
165 ["git", "config",
166 "user.email", "test@example.com"],
167 "Could not config user.email at %(path)s")
168 self._call(
169 ["git", "config",
170 "user.name", "test"],
171 "Could not config user.name at %(path)s")
164172
165 def write(self, files):173 def write(self, files):
166 for f in files:174 for f in files:
167175
=== modified file 'deployer/tests/test_deployment.py'
--- deployer/tests/test_deployment.py 2015-03-18 18:19:43 +0000
+++ deployer/tests/test_deployment.py 2015-07-06 20:11:20 +0000
@@ -75,8 +75,6 @@
75 def test_maas_name_and_zone_placement(self):75 def test_maas_name_and_zone_placement(self):
76 d = self.get_named_deployment_v3("stack-placement-maas.yml", "stack")76 d = self.get_named_deployment_v3("stack-placement-maas.yml", "stack")
77 d.validate_placement()77 d.validate_placement()
78 placement = d.get_unit_placement('ceph', {})
79 self.assertEqual(placement.get(0), "arnolt")
80 placement = d.get_unit_placement('heat', {})78 placement = d.get_unit_placement('heat', {})
81 self.assertEqual(placement.get(0), "zone=zebra")79 self.assertEqual(placement.get(0), "zone=zebra")
8280
@@ -90,35 +88,35 @@
90 except ErrorExit:88 except ErrorExit:
91 self.fail("Should not fail")89 self.fail("Should not fail")
9290
93 def test_machines_placement_sort(self):91 def test_services_sort(self):
94 d = Deployment('test', None, None)92 d = Deployment('test', None, None)
95 self.assertEqual(93 self.assertEqual(
96 d._machines_placement_sort(94 d._services_sort(
97 FauxService(unit_placement=1),95 FauxService(unit_placement=1),
98 FauxService()96 FauxService()
99 ), 1)97 ), 1)
100 self.assertEqual(98 self.assertEqual(
101 d._machines_placement_sort(99 d._services_sort(
102 FauxService(),100 FauxService(),
103 FauxService(unit_placement=1)101 FauxService(unit_placement=1)
104 ), -1)102 ), -1)
105 self.assertEqual(103 self.assertEqual(
106 d._machines_placement_sort(104 d._services_sort(
107 FauxService(name="x", unit_placement=['asdf']),105 FauxService(name="x", unit_placement=['asdf']),
108 FauxService(name="y", unit_placement=['lxc:x/1'])106 FauxService(name="y", unit_placement=['lxc:x/1'])
109 ), 1)107 ), 1)
110 self.assertEqual(108 self.assertEqual(
111 d._machines_placement_sort(109 d._services_sort(
112 FauxService(name="y", unit_placement=['lxc:x/1']),110 FauxService(name="y", unit_placement=['lxc:x/1']),
113 FauxService(name="x", unit_placement=['asdf'])111 FauxService(name="x", unit_placement=['asdf'])
114 ), -1)112 ), -1)
115 self.assertEqual(113 self.assertEqual(
116 d._machines_placement_sort(114 d._services_sort(
117 FauxService(name="x", unit_placement=['asdf']),115 FauxService(name="x", unit_placement=['asdf']),
118 FauxService(name="y", unit_placement=['hjkl'])116 FauxService(name="y", unit_placement=['hjkl'])
119 ), -1)117 ), -1)
120 self.assertEqual(118 self.assertEqual(
121 d._machines_placement_sort(119 d._services_sort(
122 FauxService(name="x"),120 FauxService(name="x"),
123 FauxService(name="y")121 FauxService(name="y")
124 ), -1)122 ), -1)
125123
=== modified file 'deployer/tests/test_diff.py'
--- deployer/tests/test_diff.py 2015-03-17 17:34:57 +0000
+++ deployer/tests/test_diff.py 2015-07-06 20:11:20 +0000
@@ -35,8 +35,9 @@
35 cls._dir = tempfile.mkdtemp()35 cls._dir = tempfile.mkdtemp()
36 os.mkdir(os.path.join(cls._dir, "precise"))36 os.mkdir(os.path.join(cls._dir, "precise"))
37 deployment.repo_path = cls._dir37 deployment.repo_path = cls._dir
38 deployment.fetch_charms()38 if not TEST_OFFLINE:
39 deployment.resolve()39 deployment.fetch_charms()
40 deployment.resolve()
40 cls._deployment = deployment41 cls._deployment = deployment
4142
42 @classmethod43 @classmethod
4344
=== modified file 'deployer/tests/test_guiserver.py'
--- deployer/tests/test_guiserver.py 2015-03-17 10:40:34 +0000
+++ deployer/tests/test_guiserver.py 2015-07-06 20:11:20 +0000
@@ -28,7 +28,7 @@
28 'find_service', 'ignore_errors', 'juju_env', 'list_deploys',28 'find_service', 'ignore_errors', 'juju_env', 'list_deploys',
29 'no_local_mods', 'no_relations', 'overrides', 'rel_wait',29 'no_local_mods', 'no_relations', 'overrides', 'rel_wait',
30 'retry_count', 'series', 'skip_unit_wait', 'terminate_machines',30 'retry_count', 'series', 'skip_unit_wait', 'terminate_machines',
31 'timeout', 'update_charms', 'verbose', 'watch'31 'timeout', 'update_charms', 'verbose', 'watch', 'placement_first',
32 ])32 ])
33 self.assertEqual(expected_keys, set(self.options.__dict__.keys()))33 self.assertEqual(expected_keys, set(self.options.__dict__.keys()))
3434
@@ -58,6 +58,7 @@
58 self.assertFalse(options.update_charms)58 self.assertFalse(options.update_charms)
59 self.assertFalse(options.verbose)59 self.assertFalse(options.verbose)
60 self.assertFalse(options.watch)60 self.assertFalse(options.watch)
61 self.assertFalse(options.placement_first)
6162
6263
63class TestDeploymentError(unittest.TestCase):64class TestDeploymentError(unittest.TestCase):
@@ -280,7 +281,7 @@
280 mock.call.status(),281 mock.call.status(),
281 mock.call.deploy(282 mock.call.deploy(
282 'mysql', 'cs:precise/mysql-28', '', None,283 'mysql', 'cs:precise/mysql-28', '', None,
283 {'arch': 'i386', 'cpu-cores': 4, 'mem': '4G'}, 2, None),284 {'arch': 'i386', 'cpu-cores': 4, 'mem': '4G'}, 1, None),
284 mock.call.set_annotation(285 mock.call.set_annotation(
285 'mysql', {'gui-y': '164.547', 'gui-x': '494.347'}),286 'mysql', {'gui-y': '164.547', 'gui-x': '494.347'}),
286 mock.call.deploy(287 mock.call.deploy(
287288
=== modified file 'deployer/tests/test_importer.py'
--- deployer/tests/test_importer.py 2015-05-13 14:06:34 +0000
+++ deployer/tests/test_importer.py 2015-07-06 20:11:20 +0000
@@ -34,6 +34,7 @@
34 'no_local_mods': True,34 'no_local_mods': True,
35 'no_relations': False,35 'no_relations': False,
36 'overrides': None,36 'overrides': None,
37 'placement_first': False,
37 'rel_wait': 60,38 'rel_wait': 60,
38 'retry_count': 0,39 'retry_count': 0,
39 'series': None,40 'series': None,

Subscribers

People subscribed via source and target branches