1# Copyright 2015 Intel 2# All Rights Reserved. 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); you may 5# not use this file except in compliance with the License. You may obtain 6# a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13# License for the specific language governing permissions and limitations 14# under the License. 15 16import inspect 17 18import mock 19import tooz.coordination 20import tooz.locking 21 22from cinder import coordination 23from cinder import test 24 25if hasattr(inspect, 'getfullargspec'): 26 getargspec = inspect.getfullargspec 27else: 28 getargspec = inspect.getargspec 29 30 31class Locked(Exception): 32 pass 33 34 35class MockToozLock(tooz.locking.Lock): 36 active_locks = set() 37 38 def acquire(self, blocking=True): 39 if self.name not in self.active_locks: 40 self.active_locks.add(self.name) 41 return True 42 elif not blocking: 43 return False 44 else: 45 raise Locked 46 47 def release(self): 48 self.active_locks.remove(self.name) 49 50 51@mock.patch('tooz.coordination.get_coordinator') 52class CoordinatorTestCase(test.TestCase): 53 MOCK_TOOZ = False 54 55 def test_coordinator_start(self, get_coordinator): 56 crd = get_coordinator.return_value 57 58 agent = coordination.Coordinator() 59 agent.start() 60 self.assertTrue(get_coordinator.called) 61 self.assertTrue(crd.start.called) 62 63 def test_coordinator_stop(self, get_coordinator): 64 crd = get_coordinator.return_value 65 66 agent = coordination.Coordinator() 67 agent.start() 68 self.assertIsNotNone(agent.coordinator) 69 agent.stop() 70 self.assertTrue(crd.stop.called) 71 self.assertIsNone(agent.coordinator) 72 73 def test_coordinator_lock(self, get_coordinator): 74 crd = get_coordinator.return_value 75 crd.get_lock.side_effect = lambda n: MockToozLock(n) 76 77 agent1 = coordination.Coordinator() 78 agent1.start() 79 agent2 = coordination.Coordinator() 80 agent2.start() 81 82 lock_name = 'lock' 83 expected_name = lock_name.encode('ascii') 84 85 self.assertNotIn(expected_name, MockToozLock.active_locks) 86 with agent1.get_lock(lock_name): 87 self.assertIn(expected_name, MockToozLock.active_locks) 88 self.assertRaises(Locked, agent1.get_lock(lock_name).acquire) 89 self.assertRaises(Locked, agent2.get_lock(lock_name).acquire) 90 self.assertNotIn(expected_name, MockToozLock.active_locks) 91 92 def test_coordinator_offline(self, get_coordinator): 93 crd = get_coordinator.return_value 94 crd.start.side_effect = tooz.coordination.ToozConnectionError('err') 95 96 agent = coordination.Coordinator() 97 self.assertRaises(tooz.coordination.ToozError, agent.start) 98 self.assertFalse(agent.started) 99 100 101@mock.patch.object(coordination.COORDINATOR, 'get_lock') 102class CoordinationTestCase(test.TestCase): 103 def test_synchronized(self, get_lock): 104 @coordination.synchronized('lock-{f_name}-{foo.val}-{bar[val]}') 105 def func(foo, bar): 106 pass 107 108 foo = mock.Mock() 109 foo.val = 7 110 bar = mock.MagicMock() 111 bar.__getitem__.return_value = 8 112 func(foo, bar) 113 get_lock.assert_called_with('lock-func-7-8') 114 self.assertEqual(['foo', 'bar'], getargspec(func)[0]) 115