Merge lp:~james-page/charms/trusty/nova-cloud-controller/service-guard-stable into lp:~openstack-charmers-archive/charms/trusty/nova-cloud-controller/trunk
- Trusty Tahr (14.04)
- service-guard-stable
- Merge into trunk
Proposed by
James Page
Status: | Merged |
---|---|
Merged at revision: | 79 |
Proposed branch: | lp:~james-page/charms/trusty/nova-cloud-controller/service-guard-stable |
Merge into: | lp:~openstack-charmers-archive/charms/trusty/nova-cloud-controller/trunk |
Diff against target: |
390 lines (+228/-7) 6 files modified
config.yaml (+19/-0) hooks/nova_cc_hooks.py (+25/-1) hooks/nova_cc_utils.py (+60/-1) unit_tests/test_nova_cc_hooks.py (+5/-1) unit_tests/test_nova_cc_utils.py (+116/-1) unit_tests/test_utils.py (+3/-3) |
To merge this branch: | bzr merge lp:~james-page/charms/trusty/nova-cloud-controller/service-guard-stable |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Adam Collard (community) | Approve | ||
OpenStack Charmers | Pending | ||
Review via email: mp+228699@code.launchpad.net |
Commit message
Description of the change
Backport support for service-guard option to ensure that services are not
started until all required interfaces have been related and fully configured.
To post a comment you must log in.
Revision history for this message
Adam Collard (adam-collard) wrote : | # |
Revision history for this message
Adam Collard (adam-collard) wrote : | # |
Tested successfully fixes the bugs in Landscape that were caused by having services run prematurely ( #1344413 and #1347986).
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'config.yaml' | |||
2 | --- config.yaml 2014-06-17 10:01:21 +0000 | |||
3 | +++ config.yaml 2014-07-29 15:06:19 +0000 | |||
4 | @@ -165,3 +165,22 @@ | |||
5 | 165 | description: | | 165 | description: | |
6 | 166 | This is uuid of the default NVP/NSX L3 Gateway Service. | 166 | This is uuid of the default NVP/NSX L3 Gateway Service. |
7 | 167 | # end of NVP/NSX configuration | 167 | # end of NVP/NSX configuration |
8 | 168 | service-guard: | ||
9 | 169 | type: boolean | ||
10 | 170 | default: false | ||
11 | 171 | description: | | ||
12 | 172 | Ensure required relations are made and complete before allowing services | ||
13 | 173 | to be started | ||
14 | 174 | . | ||
15 | 175 | By default, services may be up and accepting API request from install | ||
16 | 176 | onwards. | ||
17 | 177 | . | ||
18 | 178 | Enabling this flag ensures that services will not be started until the | ||
19 | 179 | minimum 'core relations' have been made between this charm and other | ||
20 | 180 | charms. | ||
21 | 181 | . | ||
22 | 182 | For this charm the following relations must be made: | ||
23 | 183 | . | ||
24 | 184 | * shared-db or (pgsql-nova-db, pgsql-neutron-db) | ||
25 | 185 | * amqp | ||
26 | 186 | * identity-service | ||
27 | 168 | 187 | ||
28 | === modified file 'hooks/nova_cc_hooks.py' | |||
29 | --- hooks/nova_cc_hooks.py 2014-04-11 16:41:42 +0000 | |||
30 | +++ hooks/nova_cc_hooks.py 2014-07-29 15:06:19 +0000 | |||
31 | @@ -63,7 +63,9 @@ | |||
32 | 63 | NOVA_CONF, | 63 | NOVA_CONF, |
33 | 64 | QUANTUM_CONF, | 64 | QUANTUM_CONF, |
34 | 65 | NEUTRON_CONF, | 65 | NEUTRON_CONF, |
36 | 66 | QUANTUM_API_PASTE | 66 | QUANTUM_API_PASTE, |
37 | 67 | service_guard, | ||
38 | 68 | guard_map, | ||
39 | 67 | ) | 69 | ) |
40 | 68 | 70 | ||
41 | 69 | from charmhelpers.contrib.hahelpers.cluster import ( | 71 | from charmhelpers.contrib.hahelpers.cluster import ( |
42 | @@ -96,6 +98,8 @@ | |||
43 | 96 | 98 | ||
44 | 97 | 99 | ||
45 | 98 | @hooks.hook('config-changed') | 100 | @hooks.hook('config-changed') |
46 | 101 | @service_guard(guard_map(), CONFIGS, | ||
47 | 102 | active=config('service-guard')) | ||
48 | 99 | @restart_on_change(restart_map(), stopstart=True) | 103 | @restart_on_change(restart_map(), stopstart=True) |
49 | 100 | def config_changed(): | 104 | def config_changed(): |
50 | 101 | global CONFIGS | 105 | global CONFIGS |
51 | @@ -114,6 +118,8 @@ | |||
52 | 114 | 118 | ||
53 | 115 | @hooks.hook('amqp-relation-changed') | 119 | @hooks.hook('amqp-relation-changed') |
54 | 116 | @hooks.hook('amqp-relation-departed') | 120 | @hooks.hook('amqp-relation-departed') |
55 | 121 | @service_guard(guard_map(), CONFIGS, | ||
56 | 122 | active=config('service-guard')) | ||
57 | 117 | @restart_on_change(restart_map()) | 123 | @restart_on_change(restart_map()) |
58 | 118 | def amqp_changed(): | 124 | def amqp_changed(): |
59 | 119 | if 'amqp' not in CONFIGS.complete_contexts(): | 125 | if 'amqp' not in CONFIGS.complete_contexts(): |
60 | @@ -171,6 +177,8 @@ | |||
61 | 171 | 177 | ||
62 | 172 | 178 | ||
63 | 173 | @hooks.hook('shared-db-relation-changed') | 179 | @hooks.hook('shared-db-relation-changed') |
64 | 180 | @service_guard(guard_map(), CONFIGS, | ||
65 | 181 | active=config('service-guard')) | ||
66 | 174 | @restart_on_change(restart_map()) | 182 | @restart_on_change(restart_map()) |
67 | 175 | def db_changed(): | 183 | def db_changed(): |
68 | 176 | if 'shared-db' not in CONFIGS.complete_contexts(): | 184 | if 'shared-db' not in CONFIGS.complete_contexts(): |
69 | @@ -186,6 +194,8 @@ | |||
70 | 186 | 194 | ||
71 | 187 | 195 | ||
72 | 188 | @hooks.hook('pgsql-nova-db-relation-changed') | 196 | @hooks.hook('pgsql-nova-db-relation-changed') |
73 | 197 | @service_guard(guard_map(), CONFIGS, | ||
74 | 198 | active=config('service-guard')) | ||
75 | 189 | @restart_on_change(restart_map()) | 199 | @restart_on_change(restart_map()) |
76 | 190 | def postgresql_nova_db_changed(): | 200 | def postgresql_nova_db_changed(): |
77 | 191 | if 'pgsql-nova-db' not in CONFIGS.complete_contexts(): | 201 | if 'pgsql-nova-db' not in CONFIGS.complete_contexts(): |
78 | @@ -201,6 +211,8 @@ | |||
79 | 201 | 211 | ||
80 | 202 | 212 | ||
81 | 203 | @hooks.hook('pgsql-neutron-db-relation-changed') | 213 | @hooks.hook('pgsql-neutron-db-relation-changed') |
82 | 214 | @service_guard(guard_map(), CONFIGS, | ||
83 | 215 | active=config('service-guard')) | ||
84 | 204 | @restart_on_change(restart_map()) | 216 | @restart_on_change(restart_map()) |
85 | 205 | def postgresql_neutron_db_changed(): | 217 | def postgresql_neutron_db_changed(): |
86 | 206 | if network_manager() in ['neutron', 'quantum']: | 218 | if network_manager() in ['neutron', 'quantum']: |
87 | @@ -210,6 +222,8 @@ | |||
88 | 210 | 222 | ||
89 | 211 | 223 | ||
90 | 212 | @hooks.hook('image-service-relation-changed') | 224 | @hooks.hook('image-service-relation-changed') |
91 | 225 | @service_guard(guard_map(), CONFIGS, | ||
92 | 226 | active=config('service-guard')) | ||
93 | 213 | @restart_on_change(restart_map()) | 227 | @restart_on_change(restart_map()) |
94 | 214 | def image_service_changed(): | 228 | def image_service_changed(): |
95 | 215 | if 'image-service' not in CONFIGS.complete_contexts(): | 229 | if 'image-service' not in CONFIGS.complete_contexts(): |
96 | @@ -228,6 +242,8 @@ | |||
97 | 228 | 242 | ||
98 | 229 | 243 | ||
99 | 230 | @hooks.hook('identity-service-relation-changed') | 244 | @hooks.hook('identity-service-relation-changed') |
100 | 245 | @service_guard(guard_map(), CONFIGS, | ||
101 | 246 | active=config('service-guard')) | ||
102 | 231 | @restart_on_change(restart_map()) | 247 | @restart_on_change(restart_map()) |
103 | 232 | def identity_changed(): | 248 | def identity_changed(): |
104 | 233 | if 'identity-service' not in CONFIGS.complete_contexts(): | 249 | if 'identity-service' not in CONFIGS.complete_contexts(): |
105 | @@ -249,6 +265,8 @@ | |||
106 | 249 | 265 | ||
107 | 250 | @hooks.hook('nova-volume-service-relation-joined', | 266 | @hooks.hook('nova-volume-service-relation-joined', |
108 | 251 | 'cinder-volume-service-relation-joined') | 267 | 'cinder-volume-service-relation-joined') |
109 | 268 | @service_guard(guard_map(), CONFIGS, | ||
110 | 269 | active=config('service-guard')) | ||
111 | 252 | @restart_on_change(restart_map()) | 270 | @restart_on_change(restart_map()) |
112 | 253 | def volume_joined(): | 271 | def volume_joined(): |
113 | 254 | CONFIGS.write(NOVA_CONF) | 272 | CONFIGS.write(NOVA_CONF) |
114 | @@ -391,6 +409,8 @@ | |||
115 | 391 | 409 | ||
116 | 392 | @hooks.hook('cluster-relation-changed', | 410 | @hooks.hook('cluster-relation-changed', |
117 | 393 | 'cluster-relation-departed') | 411 | 'cluster-relation-departed') |
118 | 412 | @service_guard(guard_map(), CONFIGS, | ||
119 | 413 | active=config('service-guard')) | ||
120 | 394 | @restart_on_change(restart_map(), stopstart=True) | 414 | @restart_on_change(restart_map(), stopstart=True) |
121 | 395 | def cluster_changed(): | 415 | def cluster_changed(): |
122 | 396 | CONFIGS.write_all() | 416 | CONFIGS.write_all() |
123 | @@ -447,6 +467,8 @@ | |||
124 | 447 | 'pgsql-nova-db-relation-broken', | 467 | 'pgsql-nova-db-relation-broken', |
125 | 448 | 'pgsql-neutron-db-relation-broken', | 468 | 'pgsql-neutron-db-relation-broken', |
126 | 449 | 'quantum-network-service-relation-broken') | 469 | 'quantum-network-service-relation-broken') |
127 | 470 | @service_guard(guard_map(), CONFIGS, | ||
128 | 471 | active=config('service-guard')) | ||
129 | 450 | def relation_broken(): | 472 | def relation_broken(): |
130 | 451 | CONFIGS.write_all() | 473 | CONFIGS.write_all() |
131 | 452 | 474 | ||
132 | @@ -487,6 +509,8 @@ | |||
133 | 487 | 509 | ||
134 | 488 | 510 | ||
135 | 489 | @hooks.hook('nova-vmware-relation-changed') | 511 | @hooks.hook('nova-vmware-relation-changed') |
136 | 512 | @service_guard(guard_map(), CONFIGS, | ||
137 | 513 | active=config('service-guard')) | ||
138 | 490 | @restart_on_change(restart_map()) | 514 | @restart_on_change(restart_map()) |
139 | 491 | def nova_vmware_relation_changed(): | 515 | def nova_vmware_relation_changed(): |
140 | 492 | CONFIGS.write('/etc/nova/nova.conf') | 516 | CONFIGS.write('/etc/nova/nova.conf') |
141 | 493 | 517 | ||
142 | === modified file 'hooks/nova_cc_utils.py' | |||
143 | --- hooks/nova_cc_utils.py 2014-05-21 10:03:01 +0000 | |||
144 | +++ hooks/nova_cc_utils.py 2014-07-29 15:06:19 +0000 | |||
145 | @@ -33,12 +33,15 @@ | |||
146 | 33 | relation_get, | 33 | relation_get, |
147 | 34 | relation_ids, | 34 | relation_ids, |
148 | 35 | remote_unit, | 35 | remote_unit, |
149 | 36 | is_relation_made, | ||
150 | 36 | INFO, | 37 | INFO, |
151 | 37 | ERROR, | 38 | ERROR, |
152 | 38 | ) | 39 | ) |
153 | 39 | 40 | ||
154 | 40 | from charmhelpers.core.host import ( | 41 | from charmhelpers.core.host import ( |
156 | 41 | service_start | 42 | service_start, |
157 | 43 | service_stop, | ||
158 | 44 | service_running | ||
159 | 42 | ) | 45 | ) |
160 | 43 | 46 | ||
161 | 44 | 47 | ||
162 | @@ -695,3 +698,59 @@ | |||
163 | 695 | # quantum-plugin config setting can be safely overriden | 698 | # quantum-plugin config setting can be safely overriden |
164 | 696 | # as we only supported OVS in G/neutron | 699 | # as we only supported OVS in G/neutron |
165 | 697 | return config('neutron-plugin') or config('quantum-plugin') | 700 | return config('neutron-plugin') or config('quantum-plugin') |
166 | 701 | |||
167 | 702 | |||
168 | 703 | def guard_map(): | ||
169 | 704 | '''Map of services and required interfaces that must be present before | ||
170 | 705 | the service should be allowed to start''' | ||
171 | 706 | gmap = {} | ||
172 | 707 | nova_services = deepcopy(BASE_SERVICES) | ||
173 | 708 | if os_release('nova-common') not in ['essex', 'folsom']: | ||
174 | 709 | nova_services.append('nova-conductor') | ||
175 | 710 | |||
176 | 711 | nova_interfaces = ['identity-service', 'amqp'] | ||
177 | 712 | if relation_ids('pgsql-nova-db'): | ||
178 | 713 | nova_interfaces.append('pgsql-nova-db') | ||
179 | 714 | else: | ||
180 | 715 | nova_interfaces.append('shared-db') | ||
181 | 716 | |||
182 | 717 | for svc in nova_services: | ||
183 | 718 | gmap[svc] = nova_interfaces | ||
184 | 719 | |||
185 | 720 | net_manager = network_manager() | ||
186 | 721 | if net_manager in ['neutron', 'quantum'] and \ | ||
187 | 722 | not is_relation_made('neutron-api'): | ||
188 | 723 | neutron_interfaces = ['identity-service', 'amqp'] | ||
189 | 724 | if relation_ids('pgsql-neutron-db'): | ||
190 | 725 | neutron_interfaces.append('pgsql-neutron-db') | ||
191 | 726 | else: | ||
192 | 727 | neutron_interfaces.append('shared-db') | ||
193 | 728 | if network_manager() == 'quantum': | ||
194 | 729 | gmap['quantum-server'] = neutron_interfaces | ||
195 | 730 | else: | ||
196 | 731 | gmap['neutron-server'] = neutron_interfaces | ||
197 | 732 | |||
198 | 733 | return gmap | ||
199 | 734 | |||
200 | 735 | |||
201 | 736 | def service_guard(guard_map, contexts, active=False): | ||
202 | 737 | '''Inhibit services in guard_map from running unless | ||
203 | 738 | required interfaces are found complete in contexts.''' | ||
204 | 739 | def wrap(f): | ||
205 | 740 | def wrapped_f(*args): | ||
206 | 741 | if active is True: | ||
207 | 742 | incomplete_services = [] | ||
208 | 743 | for svc in guard_map: | ||
209 | 744 | for interface in guard_map[svc]: | ||
210 | 745 | if interface not in contexts.complete_contexts(): | ||
211 | 746 | incomplete_services.append(svc) | ||
212 | 747 | f(*args) | ||
213 | 748 | for svc in incomplete_services: | ||
214 | 749 | if service_running(svc): | ||
215 | 750 | log('Service {} has unfulfilled ' | ||
216 | 751 | 'interface requirements, stopping.'.format(svc)) | ||
217 | 752 | service_stop(svc) | ||
218 | 753 | else: | ||
219 | 754 | f(*args) | ||
220 | 755 | return wrapped_f | ||
221 | 756 | return wrap | ||
222 | 698 | 757 | ||
223 | === modified file 'unit_tests/test_nova_cc_hooks.py' | |||
224 | --- unit_tests/test_nova_cc_hooks.py 2014-05-21 10:03:01 +0000 | |||
225 | +++ unit_tests/test_nova_cc_hooks.py 2014-07-29 15:06:19 +0000 | |||
226 | @@ -11,7 +11,11 @@ | |||
227 | 11 | utils.register_configs = MagicMock() | 11 | utils.register_configs = MagicMock() |
228 | 12 | utils.restart_map = MagicMock() | 12 | utils.restart_map = MagicMock() |
229 | 13 | 13 | ||
231 | 14 | import nova_cc_hooks as hooks | 14 | with patch('nova_cc_utils.guard_map') as gmap: |
232 | 15 | with patch('charmhelpers.core.hookenv.config') as config: | ||
233 | 16 | config.return_value = False | ||
234 | 17 | gmap.return_value = {} | ||
235 | 18 | import nova_cc_hooks as hooks | ||
236 | 15 | 19 | ||
237 | 16 | utils.register_configs = _reg | 20 | utils.register_configs = _reg |
238 | 17 | utils.restart_map = _map | 21 | utils.restart_map = _map |
239 | 18 | 22 | ||
240 | === modified file 'unit_tests/test_nova_cc_utils.py' | |||
241 | --- unit_tests/test_nova_cc_utils.py 2014-05-02 10:06:23 +0000 | |||
242 | +++ unit_tests/test_nova_cc_utils.py 2014-07-29 15:06:19 +0000 | |||
243 | @@ -31,10 +31,13 @@ | |||
244 | 31 | 'os_release', | 31 | 'os_release', |
245 | 32 | 'register_configs', | 32 | 'register_configs', |
246 | 33 | 'relation_ids', | 33 | 'relation_ids', |
247 | 34 | 'is_relation_made', | ||
248 | 34 | 'remote_unit', | 35 | 'remote_unit', |
249 | 35 | '_save_script_rc', | 36 | '_save_script_rc', |
250 | 36 | 'service_start', | 37 | 'service_start', |
252 | 37 | 'services' | 38 | 'services', |
253 | 39 | 'service_running', | ||
254 | 40 | 'service_stop' | ||
255 | 38 | ] | 41 | ] |
256 | 39 | 42 | ||
257 | 40 | SCRIPTRC_ENV_VARS = { | 43 | SCRIPTRC_ENV_VARS = { |
258 | @@ -555,3 +558,115 @@ | |||
259 | 555 | utils.do_openstack_upgrade() | 558 | utils.do_openstack_upgrade() |
260 | 556 | expected = [call('cloud:precise-icehouse')] | 559 | expected = [call('cloud:precise-icehouse')] |
261 | 557 | self.assertEquals(_do_openstack_upgrade.call_args_list, expected) | 560 | self.assertEquals(_do_openstack_upgrade.call_args_list, expected) |
262 | 561 | |||
263 | 562 | def test_guard_map_nova(self): | ||
264 | 563 | self.relation_ids.return_value = [] | ||
265 | 564 | self.os_release.return_value = 'havana' | ||
266 | 565 | self.assertEqual( | ||
267 | 566 | {'nova-api-ec2': ['identity-service', 'amqp', 'shared-db'], | ||
268 | 567 | 'nova-api-os-compute': ['identity-service', 'amqp', 'shared-db'], | ||
269 | 568 | 'nova-cert': ['identity-service', 'amqp', 'shared-db'], | ||
270 | 569 | 'nova-conductor': ['identity-service', 'amqp', 'shared-db'], | ||
271 | 570 | 'nova-objectstore': ['identity-service', 'amqp', 'shared-db'], | ||
272 | 571 | 'nova-scheduler': ['identity-service', 'amqp', 'shared-db']}, | ||
273 | 572 | utils.guard_map() | ||
274 | 573 | ) | ||
275 | 574 | self.os_release.return_value = 'essex' | ||
276 | 575 | self.assertEqual( | ||
277 | 576 | {'nova-api-ec2': ['identity-service', 'amqp', 'shared-db'], | ||
278 | 577 | 'nova-api-os-compute': ['identity-service', 'amqp', 'shared-db'], | ||
279 | 578 | 'nova-cert': ['identity-service', 'amqp', 'shared-db'], | ||
280 | 579 | 'nova-objectstore': ['identity-service', 'amqp', 'shared-db'], | ||
281 | 580 | 'nova-scheduler': ['identity-service', 'amqp', 'shared-db']}, | ||
282 | 581 | utils.guard_map() | ||
283 | 582 | ) | ||
284 | 583 | |||
285 | 584 | def test_guard_map_neutron(self): | ||
286 | 585 | self.relation_ids.return_value = [] | ||
287 | 586 | self.network_manager.return_value = 'neutron' | ||
288 | 587 | self.os_release.return_value = 'icehouse' | ||
289 | 588 | self.is_relation_made.return_value = False | ||
290 | 589 | self.assertEqual( | ||
291 | 590 | {'neutron-server': ['identity-service', 'amqp', 'shared-db'], | ||
292 | 591 | 'nova-api-ec2': ['identity-service', 'amqp', 'shared-db'], | ||
293 | 592 | 'nova-api-os-compute': ['identity-service', 'amqp', 'shared-db'], | ||
294 | 593 | 'nova-cert': ['identity-service', 'amqp', 'shared-db'], | ||
295 | 594 | 'nova-conductor': ['identity-service', 'amqp', 'shared-db'], | ||
296 | 595 | 'nova-objectstore': ['identity-service', 'amqp', 'shared-db'], | ||
297 | 596 | 'nova-scheduler': ['identity-service', 'amqp', 'shared-db'], }, | ||
298 | 597 | utils.guard_map() | ||
299 | 598 | ) | ||
300 | 599 | self.network_manager.return_value = 'quantum' | ||
301 | 600 | self.os_release.return_value = 'grizzly' | ||
302 | 601 | self.assertEqual( | ||
303 | 602 | {'quantum-server': ['identity-service', 'amqp', 'shared-db'], | ||
304 | 603 | 'nova-api-ec2': ['identity-service', 'amqp', 'shared-db'], | ||
305 | 604 | 'nova-api-os-compute': ['identity-service', 'amqp', 'shared-db'], | ||
306 | 605 | 'nova-cert': ['identity-service', 'amqp', 'shared-db'], | ||
307 | 606 | 'nova-conductor': ['identity-service', 'amqp', 'shared-db'], | ||
308 | 607 | 'nova-objectstore': ['identity-service', 'amqp', 'shared-db'], | ||
309 | 608 | 'nova-scheduler': ['identity-service', 'amqp', 'shared-db'], }, | ||
310 | 609 | utils.guard_map() | ||
311 | 610 | ) | ||
312 | 611 | |||
313 | 612 | def test_guard_map_pgsql(self): | ||
314 | 613 | self.relation_ids.return_value = ['pgsql:1'] | ||
315 | 614 | self.network_manager.return_value = 'neutron' | ||
316 | 615 | self.is_relation_made.return_value = False | ||
317 | 616 | self.os_release.return_value = 'icehouse' | ||
318 | 617 | self.assertEqual( | ||
319 | 618 | {'neutron-server': ['identity-service', 'amqp', | ||
320 | 619 | 'pgsql-neutron-db'], | ||
321 | 620 | 'nova-api-ec2': ['identity-service', 'amqp', 'pgsql-nova-db'], | ||
322 | 621 | 'nova-api-os-compute': ['identity-service', 'amqp', | ||
323 | 622 | 'pgsql-nova-db'], | ||
324 | 623 | 'nova-cert': ['identity-service', 'amqp', 'pgsql-nova-db'], | ||
325 | 624 | 'nova-conductor': ['identity-service', 'amqp', 'pgsql-nova-db'], | ||
326 | 625 | 'nova-objectstore': ['identity-service', 'amqp', | ||
327 | 626 | 'pgsql-nova-db'], | ||
328 | 627 | 'nova-scheduler': ['identity-service', 'amqp', | ||
329 | 628 | 'pgsql-nova-db'], }, | ||
330 | 629 | utils.guard_map() | ||
331 | 630 | ) | ||
332 | 631 | |||
333 | 632 | def test_service_guard_inactive(self): | ||
334 | 633 | '''Ensure that if disabled, service guards nothing''' | ||
335 | 634 | contexts = MagicMock() | ||
336 | 635 | |||
337 | 636 | @utils.service_guard({'test': ['interfacea', 'interfaceb']}, | ||
338 | 637 | contexts, False) | ||
339 | 638 | def dummy_func(): | ||
340 | 639 | pass | ||
341 | 640 | dummy_func() | ||
342 | 641 | self.assertFalse(self.service_running.called) | ||
343 | 642 | self.assertFalse(contexts.complete_contexts.called) | ||
344 | 643 | |||
345 | 644 | def test_service_guard_active_guard(self): | ||
346 | 645 | '''Ensure services with incomplete interfaces are stopped''' | ||
347 | 646 | contexts = MagicMock() | ||
348 | 647 | contexts.complete_contexts.return_value = ['interfacea'] | ||
349 | 648 | self.service_running.return_value = True | ||
350 | 649 | |||
351 | 650 | @utils.service_guard({'test': ['interfacea', 'interfaceb']}, | ||
352 | 651 | contexts, True) | ||
353 | 652 | def dummy_func(): | ||
354 | 653 | pass | ||
355 | 654 | dummy_func() | ||
356 | 655 | self.service_running.assert_called_with('test') | ||
357 | 656 | self.service_stop.assert_called_with('test') | ||
358 | 657 | self.assertTrue(contexts.complete_contexts.called) | ||
359 | 658 | |||
360 | 659 | def test_service_guard_active_release(self): | ||
361 | 660 | '''Ensure services with complete interfaces are not stopped''' | ||
362 | 661 | contexts = MagicMock() | ||
363 | 662 | contexts.complete_contexts.return_value = ['interfacea', | ||
364 | 663 | 'interfaceb'] | ||
365 | 664 | |||
366 | 665 | @utils.service_guard({'test': ['interfacea', 'interfaceb']}, | ||
367 | 666 | contexts, True) | ||
368 | 667 | def dummy_func(): | ||
369 | 668 | pass | ||
370 | 669 | dummy_func() | ||
371 | 670 | self.assertFalse(self.service_running.called) | ||
372 | 671 | self.assertFalse(self.service_stop.called) | ||
373 | 672 | self.assertTrue(contexts.complete_contexts.called) | ||
374 | 558 | 673 | ||
375 | === modified file 'unit_tests/test_utils.py' | |||
376 | --- unit_tests/test_utils.py 2013-11-08 05:41:39 +0000 | |||
377 | +++ unit_tests/test_utils.py 2014-07-29 15:06:19 +0000 | |||
378 | @@ -82,9 +82,9 @@ | |||
379 | 82 | return self.config | 82 | return self.config |
380 | 83 | 83 | ||
381 | 84 | def set(self, attr, value): | 84 | def set(self, attr, value): |
385 | 85 | if attr not in self.config: | 85 | if attr not in self.config: |
386 | 86 | raise KeyError | 86 | raise KeyError |
387 | 87 | self.config[attr] = value | 87 | self.config[attr] = value |
388 | 88 | 88 | ||
389 | 89 | 89 | ||
390 | 90 | class TestRelation(object): | 90 | class TestRelation(object): |
A few style comments inline below, nothing blocking :)