2 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
8 DEPRECATED: Should be migrated to chromite.lib.locking_unittest.
11 from __future__ import print_function
14 import multiprocessing
20 fixup_path.FixupPath()
22 from chromite.lib import cros_test_lib
23 from chromite.lib import osutils
24 from chromite.lib.paygen import flock
31 class FLockTest(mox.MoxTestBase):
32 """Test FLock lock class."""
34 def __init__(self, testCaseNames):
36 mox.MoxTestBase.__init__(self, testCaseNames)
39 """Prepare for each test."""
42 # To make certain we don't self update while running tests.
43 os.environ['CROSTOOLS_NO_SOURCE_UPDATE'] = '1'
46 """Cleanup after each test."""
49 @osutils.TempDirDecorator
50 def _HelperSingleLockTest(self, blocking, shared):
51 """Helper method that runs a basic test with/without blocking/sharing."""
52 lock = flock.Lock('SingleLock',
53 lock_dir=self.tempdir,
57 expected_lock_file = os.path.join(self.tempdir, 'SingleLock')
59 self.assertFalse(os.path.exists(expected_lock_file))
60 self.assertFalse(lock.IsLocked())
62 self.assertTrue(os.path.exists(expected_lock_file))
63 self.assertTrue(lock.IsLocked())
65 # Acquiring the lock again should be safe.
67 self.assertTrue(lock.IsLocked())
69 # Ensure the lock file contains our pid, and nothing else.
70 fd = open(expected_lock_file, 'r')
71 self.assertEquals(['%d\n' % os.getpid()], fd.readlines())
75 self.assertFalse(lock.IsLocked())
77 @osutils.TempDirDecorator
78 def _HelperDoubleLockTest(self, blocking1, shared1, blocking2, shared2):
79 """Helper method that runs a two-lock test with/without blocking/sharing."""
80 lock1 = flock.Lock('DoubleLock',
81 lock_dir=self.tempdir,
84 lock2 = flock.Lock('DoubleLock',
85 lock_dir=self.tempdir,
90 self.assertTrue(lock1.IsLocked())
91 self.assertFalse(lock2.IsLocked())
93 # The second lock should fail to acquire.
94 self.assertRaises(flock.LockNotAcquired, lock2.Acquire)
95 self.assertTrue(lock1.IsLocked())
96 self.assertFalse(lock2.IsLocked())
99 self.assertFalse(lock1.IsLocked())
100 self.assertFalse(lock2.IsLocked())
102 # Releasing second lock should be harmless.
104 self.assertFalse(lock1.IsLocked())
105 self.assertFalse(lock2.IsLocked())
107 def _HelperInsideProcess(self, name, lock_dir, blocking, shared):
108 """Helper method that runs a basic test with/without blocking."""
111 with flock.Lock(name,
116 sys.exit(LOCK_ACQUIRED)
117 except flock.LockNotAcquired:
118 sys.exit(LOCK_NOT_ACQUIRED)
120 def _HelperStartProcess(self, name, blocking=False, shared=False):
121 """Create a process and invoke _HelperInsideProcess in it."""
122 p = multiprocessing.Process(target=self._HelperInsideProcess,
123 args=(name, self.tempdir, blocking, shared))
126 # It's highly probably that p will have tried to grab the lock before the
127 # timer expired, but not certain.
132 def _HelperWithProcess(self, name, expected, blocking=False, shared=False):
133 """Create a process and invoke _HelperInsideProcess in it."""
134 p = multiprocessing.Process(target=self._HelperInsideProcess,
135 args=(name, self.tempdir, blocking, shared))
138 self.assertEquals(p.exitcode, expected)
140 def testLockName(self):
141 """Make sure that we get the expected lock file name."""
142 lock = flock.Lock(lock_name='/tmp/foo')
143 self.assertEqual(lock.lock_file, '/tmp/foo')
145 lock = flock.Lock(lock_name='foo')
146 self.assertEqual(lock.lock_file, '/tmp/run_once/foo')
148 lock = flock.Lock(lock_name='foo', lock_dir='/bar')
149 self.assertEqual(lock.lock_file, '/bar/foo')
151 def testSingleLock(self):
152 """Just test getting releasing a lock with options."""
153 self._HelperSingleLockTest(blocking=False, shared=False)
154 self._HelperSingleLockTest(blocking=True, shared=False)
155 self._HelperSingleLockTest(blocking=False, shared=True)
156 self._HelperSingleLockTest(blocking=True, shared=True)
158 def testDoubleLock(self):
159 """Test two lock objects for the same lock file."""
160 self._HelperDoubleLockTest(blocking1=False, shared1=False,
161 blocking2=False, shared2=False)
163 def testContextMgr(self):
164 """Make sure we behave properly with 'with'."""
168 # Create an instance, and use it in a with
169 prelock = flock.Lock(name, lock_dir=self.tempdir)
170 self._HelperWithProcess(name, expected=LOCK_ACQUIRED)
172 with prelock as lock:
173 # Assert the instance didn't change.
174 self.assertIs(prelock, lock)
175 self._HelperWithProcess(name, expected=LOCK_NOT_ACQUIRED)
177 self._HelperWithProcess(name, expected=LOCK_ACQUIRED)
179 # Construct the instance in the with expression.
180 with flock.Lock(name, lock_dir=self.tempdir) as lock:
181 self.assertIsInstance(lock, flock.Lock)
182 self._HelperWithProcess(name, expected=LOCK_NOT_ACQUIRED)
184 self._HelperWithProcess(name, expected=LOCK_ACQUIRED)
186 def testAcquireBeforeWith(self):
187 """Sometimes you want to Acquire a lock and then return it into 'with'."""
190 lock = flock.Lock(name, lock_dir=self.tempdir)
193 self._HelperWithProcess(name, expected=LOCK_NOT_ACQUIRED)
196 self._HelperWithProcess(name, expected=LOCK_NOT_ACQUIRED)
198 self._HelperWithProcess(name, expected=LOCK_ACQUIRED)
200 @osutils.TempDirDecorator
201 def testSingleProcessLock(self):
202 """Test grabbing the same lock in processes with no conflicts."""
203 self._HelperWithProcess('ProcessLock', expected=LOCK_ACQUIRED)
204 self._HelperWithProcess('ProcessLock', expected=LOCK_ACQUIRED)
205 self._HelperWithProcess('ProcessLock', expected=LOCK_ACQUIRED,
207 self._HelperWithProcess('ProcessLock', expected=LOCK_ACQUIRED,
209 self._HelperWithProcess('ProcessLock', expected=LOCK_ACQUIRED,
210 blocking=True, shared=True)
212 @osutils.TempDirDecorator
213 def testNonBlockingConflicts(self):
214 """Test that we get a lock conflict for non-blocking locks."""
216 with flock.Lock(name, lock_dir=self.tempdir):
217 self._HelperWithProcess(name,
218 expected=LOCK_NOT_ACQUIRED)
220 self._HelperWithProcess(name,
221 expected=LOCK_NOT_ACQUIRED,
224 # Can grab it after it's released
225 self._HelperWithProcess(name, expected=LOCK_ACQUIRED)
227 @osutils.TempDirDecorator
228 def testSharedLocks(self):
229 """Test lock conflict for blocking locks."""
232 # Intial lock is NOT shared
233 with flock.Lock(name, lock_dir=self.tempdir, shared=False):
234 self._HelperWithProcess(name, expected=LOCK_NOT_ACQUIRED, shared=True)
236 # Intial lock IS shared
237 with flock.Lock(name, lock_dir=self.tempdir, shared=True):
238 self._HelperWithProcess(name, expected=LOCK_ACQUIRED, shared=True)
239 self._HelperWithProcess(name, expected=LOCK_NOT_ACQUIRED, shared=False)
241 @osutils.TempDirDecorator
242 def testBlockingConflicts(self):
243 """Test lock conflict for blocking locks."""
246 # Intial lock is blocking, exclusive
247 with flock.Lock(name, lock_dir=self.tempdir, blocking=True):
248 self._HelperWithProcess(name,
249 expected=LOCK_NOT_ACQUIRED,
252 p = self._HelperStartProcess(name, blocking=True, shared=False)
254 # when the with clause exits, p should unblock and get the lock, setting
255 # its exit code to sucess now.
257 self.assertEquals(p.exitcode, LOCK_ACQUIRED)
259 # Intial lock is NON blocking
260 with flock.Lock(name, lock_dir=self.tempdir):
261 self._HelperWithProcess(name, expected=LOCK_NOT_ACQUIRED)
263 p = self._HelperStartProcess(name, blocking=True, shared=False)
265 # when the with clause exits, p should unblock and get the lock, setting
266 # it's exit code to sucess now.
268 self.assertEquals(p.exitcode, LOCK_ACQUIRED)
270 # Intial lock is shared, blocking lock is exclusive
271 with flock.Lock(name, lock_dir=self.tempdir, shared=True):
272 self._HelperWithProcess(name, expected=LOCK_NOT_ACQUIRED)
273 self._HelperWithProcess(name, expected=LOCK_ACQUIRED, shared=True)
275 p = self._HelperStartProcess(name, blocking=True, shared=False)
276 q = self._HelperStartProcess(name, blocking=True, shared=False)
278 # when the with clause exits, p should unblock and get the lock, setting
279 # it's exit code to sucess now.
281 self.assertEquals(p.exitcode, LOCK_ACQUIRED)
283 self.assertEquals(p.exitcode, LOCK_ACQUIRED)
286 if __name__ == '__main__':