summaryrefslogtreecommitdiff
path: root/lib/spack/spack/test/llnl/util/lock.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/spack/spack/test/llnl/util/lock.py')
-rw-r--r--lib/spack/spack/test/llnl/util/lock.py181
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)