from datetime import datetime import unittest from osclib.obslock import OBSLock from . import OBSLocal class TestOBSLock(unittest.TestCase): def obs_lock(self, wf, reason='list'): return OBSLock(wf.apiurl, wf.project, reason=reason) def assertLockFail(self, lock): with self.assertRaises(SystemExit): with lock: self.assertFalse(lock.locked) def test_lock(self): wf = self.setup_vcr() lock = self.obs_lock(wf) self.assertFalse(lock.locked) with lock: self.assertTrue(lock.locked) user, reason, reason_sub, ts = lock._parse(lock._read()) self.assertIsNotNone(user) self.assertEqual(reason, 'list') self.assertIsNone(reason_sub) self.assertIsInstance(ts, datetime) self.assertFalse(lock.locked) def test_locked_self(self): wf = self.setup_vcr() self.locked_self(wf, hold=False) def locked_self(self, wf, hold=False): lock1 = self.obs_lock(wf) lock2 = self.obs_lock(wf) self.assertFalse(lock1.locked) self.assertFalse(lock2.locked) with lock1: self.assertTrue(lock1.locked) self.assertLockFail(lock2) if not hold: # A hold will remain locked. self.assertFalse(lock1.locked) self.assertFalse(lock2.locked) def test_hold(self): wf = self.setup_vcr() lock = self.obs_lock(wf, 'lock') self.assertFalse(lock.locked) with lock: self.assertTrue(lock.locked) lock.hold('test') self.assertTrue(lock.locked) # Same constraints should apply since same user against hold. self.locked_self(wf, hold=True) # Hold should remain after subcommands are executed. user, reason, reason_sub, ts = lock._parse(lock._read()) self.assertIsNotNone(user) self.assertEqual(reason, 'hold: test') self.assertIsNone(reason_sub) self.assertIsInstance(ts, datetime) # Other users should not bypass hold. lock_user2 = self.obs_lock(wf) lock_user2.user = 'other' self.assertLockFail(lock_user2) lock.release(force=True) self.assertFalse(lock.locked) def test_expire(self): wf = self.setup_vcr() lock1 = self.obs_lock(wf) lock2 = self.obs_lock(wf) lock2.ttl = 0 lock2.user = 'user2' self.assertFalse(lock1.locked) self.assertFalse(lock2.locked) with lock1: self.assertTrue(lock1.locked) with lock2: self.assertTrue(lock2.locked) user, _, _, _ = lock2._parse(lock2._read()) self.assertEqual(user, lock2.user) def test_expire_hold(self): wf = self.setup_vcr() lock1 = self.obs_lock(wf, 'lock') lock2 = self.obs_lock(wf, 'override') lock2.ttl = 0 lock2.user = 'user2' self.assertFalse(lock1.locked) self.assertFalse(lock2.locked) with lock1: self.assertTrue(lock1.locked) lock1.hold('test') with lock2: self.assertTrue(lock2.locked) user, reason, reason_sub, _ = lock2._parse(lock2._read()) self.assertEqual(user, lock2.user) self.assertEqual(reason, 'override') self.assertEqual(reason_sub, None, 'does not inherit hold') def setup_vcr(self): wf = OBSLocal.FactoryWorkflow() wf.create_target() # we should most likely create this as part of create_target, but # it just slows down all other tests wf.create_attribute_type('openSUSE', 'LockedBy') wf.create_project(wf.project + ':Staging') return wf def test_reserved_characters(self): wf = self.setup_vcr() lock = self.obs_lock(wf, 'some reason @ #night') with lock: _, reason, _, _ = lock._parse(lock._read()) self.assertEqual(reason, 'some reason at hashnight') def test_needed(self): wf = self.setup_vcr() lock1 = self.obs_lock(wf) lock2 = self.obs_lock(wf, 'unlock') lock2.user = 'user2' lock2.needed = False self.assertFalse(lock1.locked) self.assertFalse(lock2.locked) with lock1: self.assertTrue(lock1.locked) with lock2: self.assertFalse(lock2.locked) user, _, _, _ = lock2._parse(lock2._read()) self.assertEqual(user, lock1.user, 'lock1 remains') lock2.release(force=True) user, _, _, _ = lock2._parse(lock2._read()) self.assertEqual(user, None, 'unlocked')