~hopem/charms/trusty/keystone/reloads

« back to all changes in this revision

Viewing changes to unit_tests/test_keystone_hooks.py

  • Committer: Edward Hope-Morley
  • Date: 2015-01-10 14:56:22 UTC
  • Revision ID: edward.hope-morley@canonical.com-20150110145622-dmss29v1klazhp54
Fixed a few race issues and switched to using decorators

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
from mock import call, patch, MagicMock
2
2
import os
3
3
import json
 
4
import uuid
4
5
 
5
6
from test_utils import CharmTestCase
6
7
 
34
35
    'relation_set',
35
36
    'relation_get',
36
37
    'related_units',
 
38
    'remote_unit',
37
39
    'unit_get',
38
40
    'peer_echo',
39
41
    # charmhelpers.core.host
54
56
    'migrate_database',
55
57
    'ensure_initial_admin',
56
58
    'add_service_to_keystone',
57
 
    'synchronize_ca',
 
59
    'synchronize_ca_if_changed',
58
60
    # other
59
61
    'check_call',
60
62
    'execd_preinstall',
158
160
            'Attempting to associate a postgresql database when there '
159
161
            'is already associated a mysql one')
160
162
 
 
163
    @patch('keystone_utils.log')
 
164
    @patch('keystone_utils.peer_units')
161
165
    @patch.object(hooks, 'CONFIGS')
162
 
    def test_db_changed_missing_relation_data(self, configs):
 
166
    def test_db_changed_missing_relation_data(self, configs, mock_peer_units,
 
167
                                              mock_log):
 
168
        mock_peer_units.return_value = None
163
169
        configs.complete_contexts = MagicMock()
164
170
        configs.complete_contexts.return_value = []
165
171
        hooks.db_changed()
190
196
        configs.write = MagicMock()
191
197
        hooks.pgsql_db_changed()
192
198
 
 
199
    @patch('keystone_utils.log')
 
200
    @patch('keystone_utils.peer_units')
193
201
    @patch.object(hooks, 'CONFIGS')
194
202
    @patch.object(hooks, 'identity_changed')
195
 
    def test_db_changed_allowed(self, identity_changed, configs):
 
203
    def test_db_changed_allowed(self, identity_changed, configs,
 
204
                                mock_peer_units, mock_log):
 
205
        mock_peer_units.return_value = None
196
206
        self.relation_ids.return_value = ['identity-service:0']
197
207
        self.related_units.return_value = ['unit/0']
198
208
 
205
215
            relation_id='identity-service:0',
206
216
            remote_unit='unit/0')
207
217
 
 
218
    @patch('keystone_utils.log')
 
219
    @patch('keystone_utils.peer_units')
208
220
    @patch.object(hooks, 'CONFIGS')
209
221
    @patch.object(hooks, 'identity_changed')
210
 
    def test_db_changed_not_allowed(self, identity_changed, configs):
 
222
    def test_db_changed_not_allowed(self, identity_changed, configs,
 
223
                                    mock_peer_units, mock_log):
 
224
        mock_peer_units.return_value = None
211
225
        self.relation_ids.return_value = ['identity-service:0']
212
226
        self.related_units.return_value = ['unit/0']
213
227
 
218
232
        self.assertFalse(self.ensure_initial_admin.called)
219
233
        self.assertFalse(identity_changed.called)
220
234
 
 
235
    @patch('keystone_utils.log')
 
236
    @patch('keystone_utils.peer_units')
221
237
    @patch.object(hooks, 'CONFIGS')
222
238
    @patch.object(hooks, 'identity_changed')
223
 
    def test_postgresql_db_changed(self, identity_changed, configs):
 
239
    def test_postgresql_db_changed(self, identity_changed, configs,
 
240
                                   mock_peer_units, mock_log):
 
241
        mock_peer_units.return_value = None
224
242
        self.relation_ids.return_value = ['identity-service:0']
225
243
        self.related_units.return_value = ['unit/0']
226
244
 
233
251
            relation_id='identity-service:0',
234
252
            remote_unit='unit/0')
235
253
 
 
254
    @patch('keystone_utils.is_sync_master')
236
255
    @patch.object(hooks, 'ensure_permissions')
237
256
    @patch.object(hooks, 'cluster_joined')
238
257
    @patch.object(unison, 'ensure_user')
243
262
    def test_config_changed_no_openstack_upgrade_leader(
244
263
            self, configure_https, identity_changed,
245
264
            configs, get_homedir, ensure_user, cluster_joined,
246
 
            ensure_permissions):
 
265
            ensure_permissions, is_sync_master):
 
266
        is_sync_master.return_value = False
247
267
        self.openstack_upgrade_available.return_value = False
248
268
        self.is_elected_leader.return_value = True
249
269
        self.relation_ids.return_value = ['identity-service:0']
263
283
            'Firing identity_changed hook for all related services.')
264
284
        identity_changed.assert_called_with(
265
285
            relation_id='identity-service:0',
266
 
            remote_unit='unit/0',
267
 
            sync_certs=False)
 
286
            remote_unit='unit/0')
268
287
 
 
288
    @patch('keystone_utils.is_sync_master')
269
289
    @patch.object(hooks, 'ensure_permissions')
270
290
    @patch.object(hooks, 'cluster_joined')
271
291
    @patch.object(unison, 'ensure_user')
276
296
    def test_config_changed_no_openstack_upgrade_not_leader(
277
297
            self, configure_https, identity_changed,
278
298
            configs, get_homedir, ensure_user, cluster_joined,
279
 
            ensure_permissions):
 
299
            ensure_permissions, is_sync_master):
 
300
        is_sync_master.return_value = False
280
301
        self.openstack_upgrade_available.return_value = False
281
302
        self.is_elected_leader.return_value = False
282
303
 
292
313
        self.assertFalse(self.ensure_initial_admin.called)
293
314
        self.assertFalse(identity_changed.called)
294
315
 
 
316
    @patch('keystone_utils.is_sync_master')
295
317
    @patch.object(hooks, 'ensure_permissions')
296
318
    @patch.object(hooks, 'cluster_joined')
297
319
    @patch.object(unison, 'ensure_user')
302
324
    def test_config_changed_with_openstack_upgrade(
303
325
            self, configure_https, identity_changed,
304
326
            configs, get_homedir, ensure_user, cluster_joined,
305
 
            ensure_permissions):
 
327
            ensure_permissions, is_sync_master):
 
328
        is_sync_master.return_value = False
306
329
        self.openstack_upgrade_available.return_value = True
307
330
        self.is_elected_leader.return_value = True
308
331
        self.relation_ids.return_value = ['identity-service:0']
324
347
            'Firing identity_changed hook for all related services.')
325
348
        identity_changed.assert_called_with(
326
349
            relation_id='identity-service:0',
327
 
            remote_unit='unit/0',
328
 
            sync_certs=False)
 
350
            remote_unit='unit/0')
329
351
 
 
352
    @patch('keystone_utils.log')
 
353
    @patch('keystone_utils.peer_units')
 
354
    @patch('keystone_utils.relation_ids')
 
355
    @patch('keystone_utils.is_elected_leader')
 
356
    @patch('keystone_utils.is_sync_master')
 
357
    @patch('keystone_utils.update_hash_from_path')
 
358
    @patch('keystone_utils.synchronize_ca')
330
359
    @patch.object(hooks, 'hashlib')
331
360
    @patch.object(hooks, 'send_notifications')
332
361
    def test_identity_changed_leader(self, mock_send_notifications,
333
 
                                     mock_hashlib):
 
362
                                     mock_hashlib, mock_synchronize_ca,
 
363
                                     mock_update_hash_from_path,
 
364
                                     mock_is_sync_master,
 
365
                                     mock_is_elected_leader,
 
366
                                     mock_relation_ids, mock_peer_units,
 
367
                                     mock_log):
 
368
        mock_peer_units.return_value = None
 
369
        mock_relation_ids.return_value = []
 
370
        mock_is_sync_master.return_value = True
 
371
        mock_is_elected_leader.return_value = True
 
372
        # Ensure always returns diff
 
373
        mock_update_hash_from_path.side_effect = \
 
374
            lambda hash, *args, **kwargs: hash.update(str(uuid.uuid4()))
 
375
 
334
376
        self.is_elected_leader.return_value = True
335
377
        hooks.identity_changed(
336
378
            relation_id='identity-service:0',
338
380
        self.add_service_to_keystone.assert_called_with(
339
381
            'identity-service:0',
340
382
            'unit/0')
341
 
        self.assertTrue(self.synchronize_ca.called)
 
383
        self.assertTrue(mock_synchronize_ca.called)
342
384
 
343
 
    def test_identity_changed_no_leader(self):
 
385
    @patch('keystone_utils.log')
 
386
    @patch('keystone_utils.peer_units')
 
387
    def test_identity_changed_no_leader(self, mock_peer_units, mock_log):
 
388
        mock_peer_units.return_value = None
344
389
        self.is_elected_leader.return_value = False
345
390
        hooks.identity_changed(
346
391
            relation_id='identity-service:0',
356
401
            user=self.ssh_user, group='juju_keystone',
357
402
            peer_interface='cluster', ensure_local_user=True)
358
403
 
359
 
    @patch.object(hooks, 'is_pending_clustered')
 
404
    @patch('keystone_utils.log')
 
405
    @patch('keystone_utils.relation_ids')
 
406
    @patch('keystone_utils.is_elected_leader')
 
407
    @patch('keystone_utils.is_sync_master')
 
408
    @patch('keystone_utils.update_hash_from_path')
 
409
    @patch('keystone_utils.synchronize_ca')
360
410
    @patch.object(hooks, 'check_peer_actions')
361
411
    @patch.object(unison, 'ssh_authorized_peers')
362
412
    @patch.object(hooks, 'CONFIGS')
363
413
    def test_cluster_changed(self, configs, ssh_authorized_peers,
364
 
                             check_peer_actions, is_pending_clustered):
365
 
        is_pending_clustered.return_value = False
 
414
                             check_peer_actions,
 
415
                             mock_synchronize_ca, mock_update_hash_from_path,
 
416
                             mock_is_sync_master, mock_is_elected_leader,
 
417
                             mock_relation_ids, mock_log):
 
418
        mock_relation_ids.return_value = []
 
419
        mock_is_sync_master.return_value = True
 
420
        mock_is_elected_leader.return_value = True
 
421
        # Ensure always returns diff
 
422
        mock_update_hash_from_path.side_effect = \
 
423
            lambda hash, *args, **kwargs: hash.update(str(uuid.uuid4()))
 
424
 
366
425
        hooks.cluster_changed()
367
426
        whitelist = ['_passwd', 'identity-service:', 'ssl-cert-master']
368
427
        self.peer_echo.assert_called_with(includes=whitelist)
369
428
        ssh_authorized_peers.assert_called_with(
370
429
            user=self.ssh_user, group='keystone',
371
430
            peer_interface='cluster', ensure_local_user=True)
372
 
        self.assertTrue(self.synchronize_ca.called)
 
431
        self.assertTrue(mock_synchronize_ca.called)
373
432
        self.assertTrue(configs.write_all.called)
374
433
 
375
434
    def test_ha_joined(self):
419
478
        }
420
479
        self.relation_set.assert_called_with(**args)
421
480
 
 
481
    @patch('keystone_utils.log')
 
482
    @patch('keystone_utils.peer_units')
 
483
    @patch('keystone_utils.synchronize_ca')
422
484
    @patch.object(hooks, 'CONFIGS')
423
 
    def test_ha_relation_changed_not_clustered_not_leader(self, configs):
 
485
    def test_ha_relation_changed_not_clustered_not_leader(self, configs,
 
486
                                                          mock_synchronize_ca,
 
487
                                                          mock_peer_units,
 
488
                                                          mock_log):
 
489
        mock_peer_units.return_value = None
424
490
        self.relation_get.return_value = False
425
491
        self.is_elected_leader.return_value = False
426
492
 
427
493
        hooks.ha_changed()
428
494
        self.assertTrue(configs.write_all.called)
 
495
        self.assertTrue(mock_synchronize_ca.called)
429
496
 
 
497
    @patch('keystone_utils.log')
 
498
    @patch('keystone_utils.peer_units')
 
499
    @patch('keystone_utils.synchronize_ca')
430
500
    @patch.object(hooks, 'identity_changed')
431
501
    @patch.object(hooks, 'CONFIGS')
432
 
    def test_ha_relation_changed_clustered_leader(
433
 
            self, configs, identity_changed):
 
502
    def test_ha_relation_changed_clustered_leader(self, configs,
 
503
                                                  identity_changed,
 
504
                                                  mock_synchronize_ca,
 
505
                                                  mock_peer_units, mock_log):
 
506
        mock_peer_units.return_value = None
434
507
        self.relation_get.return_value = True
435
508
        self.is_elected_leader.return_value = True
436
509
        self.relation_ids.return_value = ['identity-service:0']
443
516
            'keystone endpoint configuration')
444
517
        identity_changed.assert_called_with(
445
518
            relation_id='identity-service:0',
446
 
            remote_unit='unit/0',
447
 
            sync_certs=False)
 
519
            remote_unit='unit/0')
 
520
        self.assertTrue(mock_synchronize_ca.called)
448
521
 
 
522
    @patch('keystone_utils.log')
 
523
    @patch('keystone_utils.peer_units')
449
524
    @patch.object(hooks, 'CONFIGS')
450
 
    def test_configure_https_enable(self, configs):
 
525
    def test_configure_https_enable(self, configs, mock_peer_units, mock_log):
 
526
        mock_peer_units.return_value = None
451
527
        configs.complete_contexts = MagicMock()
452
528
        configs.complete_contexts.return_value = ['https']
453
529
        configs.write = MagicMock()
457
533
        cmd = ['a2ensite', 'openstack_https_frontend']
458
534
        self.check_call.assert_called_with(cmd)
459
535
 
 
536
    @patch('keystone_utils.log')
 
537
    @patch('keystone_utils.peer_units')
460
538
    @patch.object(hooks, 'CONFIGS')
461
 
    def test_configure_https_disable(self, configs):
 
539
    def test_configure_https_disable(self, configs, mock_peer_units, mock_log):
 
540
        mock_peer_units.return_value = None
462
541
        configs.complete_contexts = MagicMock()
463
542
        configs.complete_contexts.return_value = ['']
464
543
        configs.write = MagicMock()
468
547
        cmd = ['a2dissite', 'openstack_https_frontend']
469
548
        self.check_call.assert_called_with(cmd)
470
549
 
 
550
    @patch('keystone_utils.relation_ids')
 
551
    @patch('keystone_utils.is_elected_leader')
 
552
    @patch('keystone_utils.is_sync_master')
 
553
    @patch('keystone_utils.update_hash_from_path')
 
554
    @patch('keystone_utils.synchronize_ca')
471
555
    @patch.object(unison, 'ssh_authorized_peers')
472
 
    def test_upgrade_charm_leader(self, ssh_authorized_peers):
 
556
    def test_upgrade_charm_leader(self, ssh_authorized_peers,
 
557
                                  mock_synchronize_ca,
 
558
                                  mock_update_hash_from_path,
 
559
                                  mock_is_sync_master, mock_is_elected_leader,
 
560
                                  mock_relation_ids):
 
561
        mock_relation_ids.return_value = []
 
562
        mock_is_sync_master.return_value = True
 
563
        mock_is_elected_leader.return_value = True
 
564
        # Ensure always returns diff
 
565
        mock_update_hash_from_path.side_effect = \
 
566
            lambda hash, *args, **kwargs: hash.update(str(uuid.uuid4()))
 
567
 
473
568
        self.is_elected_leader.return_value = True
474
569
        self.filter_installed_packages.return_value = []
475
570
        hooks.upgrade_charm()
477
572
        ssh_authorized_peers.assert_called_with(
478
573
            user=self.ssh_user, group='keystone',
479
574
            peer_interface='cluster', ensure_local_user=True)
480
 
        self.assertTrue(self.synchronize_ca.called)
 
575
        self.assertTrue(mock_synchronize_ca.called)
481
576
        self.log.assert_called_with(
482
577
            'Cluster leader - ensuring endpoint configuration'
483
578
            ' is up to date')
484
579
        self.assertTrue(self.ensure_initial_admin.called)
485
580
 
 
581
    @patch('keystone_utils.relation_ids')
 
582
    @patch('keystone_utils.is_elected_leader')
 
583
    @patch('keystone_utils.is_sync_master')
 
584
    @patch('keystone_utils.update_hash_from_path')
 
585
    @patch('keystone_utils.synchronize_ca')
486
586
    @patch.object(unison, 'ssh_authorized_peers')
487
 
    def test_upgrade_charm_not_leader(self, ssh_authorized_peers):
 
587
    def test_upgrade_charm_not_leader(self, ssh_authorized_peers,
 
588
                                      mock_synchronize_ca,
 
589
                                      mock_update_hash_from_path,
 
590
                                      mock_is_sync_master,
 
591
                                      mock_is_elected_leader,
 
592
                                      mock_relation_ids):
 
593
        mock_relation_ids.return_value = []
 
594
        mock_is_sync_master.return_value = True
 
595
        mock_is_elected_leader.return_value = True
 
596
        # Ensure always returns diff
 
597
        mock_update_hash_from_path.side_effect = \
 
598
            lambda hash, *args, **kwargs: hash.update(str(uuid.uuid4()))
 
599
 
488
600
        self.is_elected_leader.return_value = False
489
601
        self.filter_installed_packages.return_value = []
490
602
        hooks.upgrade_charm()
492
604
        ssh_authorized_peers.assert_called_with(
493
605
            user=self.ssh_user, group='keystone',
494
606
            peer_interface='cluster', ensure_local_user=True)
495
 
        self.assertTrue(self.synchronize_ca.called)
 
607
        self.assertTrue(mock_synchronize_ca.called)
496
608
        self.assertFalse(self.log.called)
497
609
        self.assertFalse(self.ensure_initial_admin.called)