diff options
Diffstat (limited to 'lib/spack/spack/test/llnl/util/lock.py')
-rw-r--r-- | lib/spack/spack/test/llnl/util/lock.py | 181 |
1 files changed, 45 insertions, 136 deletions
diff --git a/lib/spack/spack/test/llnl/util/lock.py b/lib/spack/spack/test/llnl/util/lock.py index 9b32b9fd15..7c38a2547f 100644 --- a/lib/spack/spack/test/llnl/util/lock.py +++ b/lib/spack/spack/test/llnl/util/lock.py @@ -72,11 +72,9 @@ from multiprocessing import Process import pytest +import llnl.util.lock as lk import llnl.util.multiproc as mp -from llnl.util.filesystem import touch, group_ids - -import spack.util.lock -from spack.util.lock import Lock, WriteTransaction, ReadTransaction, LockError +from llnl.util.filesystem import touch # @@ -267,7 +265,7 @@ multiproc_test = mpi_multiproc_test if mpi else local_multiproc_test # def acquire_write(lock_path, start=0, length=0): def fn(barrier): - lock = Lock(lock_path, start, length) + lock = lk.Lock(lock_path, start, length) lock.acquire_write() # grab exclusive lock barrier.wait() barrier.wait() # hold the lock until timeout in other procs. @@ -276,7 +274,7 @@ def acquire_write(lock_path, start=0, length=0): def acquire_read(lock_path, start=0, length=0): def fn(barrier): - lock = Lock(lock_path, start, length) + lock = lk.Lock(lock_path, start, length) lock.acquire_read() # grab shared lock barrier.wait() barrier.wait() # hold the lock until timeout in other procs. @@ -285,9 +283,9 @@ def acquire_read(lock_path, start=0, length=0): def timeout_write(lock_path, start=0, length=0): def fn(barrier): - lock = Lock(lock_path, start, length) + lock = lk.Lock(lock_path, start, length) barrier.wait() # wait for lock acquire in first process - with pytest.raises(LockError): + with pytest.raises(lk.LockError): lock.acquire_write(lock_fail_timeout) barrier.wait() return fn @@ -295,9 +293,9 @@ def timeout_write(lock_path, start=0, length=0): def timeout_read(lock_path, start=0, length=0): def fn(barrier): - lock = Lock(lock_path, start, length) + lock = lk.Lock(lock_path, start, length) barrier.wait() # wait for lock acquire in first process - with pytest.raises(LockError): + with pytest.raises(lk.LockError): lock.acquire_read(lock_fail_timeout) barrier.wait() return fn @@ -552,7 +550,7 @@ def test_upgrade_read_to_write(private_lock_path): # to begin wtih. touch(private_lock_path) - lock = Lock(private_lock_path) + lock = lk.Lock(private_lock_path) assert lock._reads == 0 assert lock._writes == 0 @@ -577,16 +575,14 @@ def test_upgrade_read_to_write(private_lock_path): assert lock._file is None -# -# Test that read-only file can be read-locked but not write-locked. -# def test_upgrade_read_to_write_fails_with_readonly_file(private_lock_path): - # ensure lock file exists the first time, so we open it read-only - # to begin wtih. + """Test that read-only file can be read-locked but not write-locked.""" + # ensure lock file exists the first time touch(private_lock_path) + # open it read-only to begin wtih. with read_only(private_lock_path): - lock = Lock(private_lock_path) + lock = lk.Lock(private_lock_path) assert lock._reads == 0 assert lock._writes == 0 @@ -595,7 +591,8 @@ def test_upgrade_read_to_write_fails_with_readonly_file(private_lock_path): assert lock._writes == 0 assert lock._file.mode == 'r' - with pytest.raises(LockError): + # upgrade to writ here + with pytest.raises(lk.LockError): lock.acquire_write() @@ -605,7 +602,7 @@ def test_upgrade_read_to_write_fails_with_readonly_file(private_lock_path): # def test_complex_acquire_and_release_chain(lock_path): def p1(barrier): - lock = Lock(lock_path) + lock = lk.Lock(lock_path) lock.acquire_write() barrier.wait() # ---------------------------------------- 1 @@ -613,7 +610,7 @@ def test_complex_acquire_and_release_chain(lock_path): barrier.wait() # ---------------------------------------- 2 lock.release_write() # release and others acquire read barrier.wait() # ---------------------------------------- 3 - with pytest.raises(LockError): + with pytest.raises(lk.LockError): lock.acquire_write(lock_fail_timeout) lock.acquire_read() barrier.wait() # ---------------------------------------- 4 @@ -622,9 +619,9 @@ def test_complex_acquire_and_release_chain(lock_path): # p2 upgrades read to write barrier.wait() # ---------------------------------------- 6 - with pytest.raises(LockError): + with pytest.raises(lk.LockError): lock.acquire_write(lock_fail_timeout) - with pytest.raises(LockError): + with pytest.raises(lk.LockError): lock.acquire_read(lock_fail_timeout) barrier.wait() # ---------------------------------------- 7 # p2 releases write and read @@ -634,9 +631,9 @@ def test_complex_acquire_and_release_chain(lock_path): barrier.wait() # ---------------------------------------- 9 # p3 upgrades read to write barrier.wait() # ---------------------------------------- 10 - with pytest.raises(LockError): + with pytest.raises(lk.LockError): lock.acquire_write(lock_fail_timeout) - with pytest.raises(LockError): + with pytest.raises(lk.LockError): lock.acquire_read(lock_fail_timeout) barrier.wait() # ---------------------------------------- 11 # p3 releases locks @@ -646,13 +643,13 @@ def test_complex_acquire_and_release_chain(lock_path): lock.release_read() def p2(barrier): - lock = Lock(lock_path) + lock = lk.Lock(lock_path) # p1 acquires write barrier.wait() # ---------------------------------------- 1 - with pytest.raises(LockError): + with pytest.raises(lk.LockError): lock.acquire_write(lock_fail_timeout) - with pytest.raises(LockError): + with pytest.raises(lk.LockError): lock.acquire_read(lock_fail_timeout) barrier.wait() # ---------------------------------------- 2 lock.acquire_read() @@ -674,9 +671,9 @@ def test_complex_acquire_and_release_chain(lock_path): barrier.wait() # ---------------------------------------- 9 # p3 upgrades read to write barrier.wait() # ---------------------------------------- 10 - with pytest.raises(LockError): + with pytest.raises(lk.LockError): lock.acquire_write(lock_fail_timeout) - with pytest.raises(LockError): + with pytest.raises(lk.LockError): lock.acquire_read(lock_fail_timeout) barrier.wait() # ---------------------------------------- 11 # p3 releases locks @@ -686,13 +683,13 @@ def test_complex_acquire_and_release_chain(lock_path): lock.release_read() def p3(barrier): - lock = Lock(lock_path) + lock = lk.Lock(lock_path) # p1 acquires write barrier.wait() # ---------------------------------------- 1 - with pytest.raises(LockError): + with pytest.raises(lk.LockError): lock.acquire_write(lock_fail_timeout) - with pytest.raises(LockError): + with pytest.raises(lk.LockError): lock.acquire_read(lock_fail_timeout) barrier.wait() # ---------------------------------------- 2 lock.acquire_read() @@ -704,9 +701,9 @@ def test_complex_acquire_and_release_chain(lock_path): # p2 upgrades read to write barrier.wait() # ---------------------------------------- 6 - with pytest.raises(LockError): + with pytest.raises(lk.LockError): lock.acquire_write(lock_fail_timeout) - with pytest.raises(LockError): + with pytest.raises(lk.LockError): lock.acquire_read(lock_fail_timeout) barrier.wait() # ---------------------------------------- 7 # p2 releases write & read @@ -736,9 +733,9 @@ def test_transaction(lock_path): vals['exited'] = True vals['exception'] = (t or v or tb) - lock = Lock(lock_path) + lock = lk.Lock(lock_path) vals = {'entered': False, 'exited': False, 'exception': False} - with ReadTransaction(lock, enter_fn, exit_fn): + with lk.ReadTransaction(lock, enter_fn, exit_fn): pass assert vals['entered'] @@ -746,7 +743,7 @@ def test_transaction(lock_path): assert not vals['exception'] vals = {'entered': False, 'exited': False, 'exception': False} - with WriteTransaction(lock, enter_fn, exit_fn): + with lk.WriteTransaction(lock, enter_fn, exit_fn): pass assert vals['entered'] @@ -762,14 +759,14 @@ def test_transaction_with_exception(lock_path): vals['exited'] = True vals['exception'] = (t or v or tb) - lock = Lock(lock_path) + lock = lk.Lock(lock_path) def do_read_with_exception(): - with ReadTransaction(lock, enter_fn, exit_fn): + with lk.ReadTransaction(lock, enter_fn, exit_fn): raise Exception() def do_write_with_exception(): - with WriteTransaction(lock, enter_fn, exit_fn): + with lk.WriteTransaction(lock, enter_fn, exit_fn): raise Exception() vals = {'entered': False, 'exited': False, 'exception': False} @@ -801,11 +798,11 @@ def test_transaction_with_context_manager(lock_path): vals['exited_fn'] = True vals['exception_fn'] = (t or v or tb) - lock = Lock(lock_path) + lock = lk.Lock(lock_path) vals = {'entered': False, 'exited': False, 'exited_fn': False, 'exception': False, 'exception_fn': False} - with ReadTransaction(lock, TestContextManager, exit_fn): + with lk.ReadTransaction(lock, TestContextManager, exit_fn): pass assert vals['entered'] @@ -816,7 +813,7 @@ def test_transaction_with_context_manager(lock_path): vals = {'entered': False, 'exited': False, 'exited_fn': False, 'exception': False, 'exception_fn': False} - with ReadTransaction(lock, TestContextManager): + with lk.ReadTransaction(lock, TestContextManager): pass assert vals['entered'] @@ -827,7 +824,7 @@ def test_transaction_with_context_manager(lock_path): vals = {'entered': False, 'exited': False, 'exited_fn': False, 'exception': False, 'exception_fn': False} - with WriteTransaction(lock, TestContextManager, exit_fn): + with lk.WriteTransaction(lock, TestContextManager, exit_fn): pass assert vals['entered'] @@ -838,7 +835,7 @@ def test_transaction_with_context_manager(lock_path): vals = {'entered': False, 'exited': False, 'exited_fn': False, 'exception': False, 'exception_fn': False} - with WriteTransaction(lock, TestContextManager): + with lk.WriteTransaction(lock, TestContextManager): pass assert vals['entered'] @@ -861,14 +858,14 @@ def test_transaction_with_context_manager_and_exception(lock_path): vals['exited_fn'] = True vals['exception_fn'] = (t or v or tb) - lock = Lock(lock_path) + lock = lk.Lock(lock_path) def do_read_with_exception(exit_fn): - with ReadTransaction(lock, TestContextManager, exit_fn): + with lk.ReadTransaction(lock, TestContextManager, exit_fn): raise Exception() def do_write_with_exception(exit_fn): - with WriteTransaction(lock, TestContextManager, exit_fn): + with lk.WriteTransaction(lock, TestContextManager, exit_fn): raise Exception() vals = {'entered': False, 'exited': False, 'exited_fn': False, @@ -910,91 +907,3 @@ def test_transaction_with_context_manager_and_exception(lock_path): assert vals['exception'] assert not vals['exited_fn'] assert not vals['exception_fn'] - - -def test_disable_locking(private_lock_path): - """Ensure that locks do no real locking when disabled.""" - old_value = spack.config.get('config:locks') - - with spack.config.override('config:locks', False): - lock = Lock(private_lock_path) - - lock.acquire_read() - assert not os.path.exists(private_lock_path) - - lock.acquire_write() - assert not os.path.exists(private_lock_path) - - lock.release_write() - assert not os.path.exists(private_lock_path) - - lock.release_read() - assert not os.path.exists(private_lock_path) - - assert old_value == spack.config.get('config:locks') - - -def test_lock_checks_user(tmpdir): - """Ensure lock checks work with a self-owned, self-group repo.""" - uid = os.getuid() - if uid not in group_ids(): - pytest.skip("user has no group with gid == uid") - - # self-owned, own group - tmpdir.chown(uid, uid) - - # safe - path = str(tmpdir) - tmpdir.chmod(0o744) - spack.util.lock.check_lock_safety(path) - - # safe - tmpdir.chmod(0o774) - spack.util.lock.check_lock_safety(path) - - # unsafe - tmpdir.chmod(0o777) - with pytest.raises(spack.error.SpackError): - spack.util.lock.check_lock_safety(path) - - # safe - tmpdir.chmod(0o474) - spack.util.lock.check_lock_safety(path) - - # safe - tmpdir.chmod(0o477) - spack.util.lock.check_lock_safety(path) - - -def test_lock_checks_group(tmpdir): - """Ensure lock checks work with a self-owned, non-self-group repo.""" - uid = os.getuid() - gid = next((g for g in group_ids() if g != uid), None) - if not gid: - pytest.skip("user has no group with gid != uid") - - # self-owned, another group - tmpdir.chown(uid, gid) - - # safe - path = str(tmpdir) - tmpdir.chmod(0o744) - spack.util.lock.check_lock_safety(path) - - # unsafe - tmpdir.chmod(0o774) - with pytest.raises(spack.error.SpackError): - spack.util.lock.check_lock_safety(path) - - # unsafe - tmpdir.chmod(0o777) - with pytest.raises(spack.error.SpackError): - spack.util.lock.check_lock_safety(path) - - # safe - tmpdir.chmod(0o474) - spack.util.lock.check_lock_safety(path) - - # safe - tmpdir.chmod(0o477) - spack.util.lock.check_lock_safety(path) |