Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
S
Spack
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
eic_tools
Spack
Commits
080a7866
Commit
080a7866
authored
8 years ago
by
Todd Gamblin
Browse files
Options
Downloads
Patches
Plain Diff
Add tests for locks with byte ranges.
parent
3d8d8d36
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
lib/spack/spack/test/lock.py
+150
-42
150 additions, 42 deletions
lib/spack/spack/test/lock.py
with
150 additions
and
42 deletions
lib/spack/spack/test/lock.py
+
150
−
42
View file @
080a7866
...
@@ -25,6 +25,7 @@
...
@@ -25,6 +25,7 @@
"""
"""
These tests ensure that our lock works correctly.
These tests ensure that our lock works correctly.
"""
"""
import
os
import
shutil
import
shutil
import
tempfile
import
tempfile
import
unittest
import
unittest
...
@@ -63,98 +64,185 @@ def multiproc_test(self, *functions):
...
@@ -63,98 +64,185 @@ def multiproc_test(self, *functions):
#
#
# Process snippets below can be composed into tests.
# Process snippets below can be composed into tests.
#
#
def
acquire_write
(
self
,
barrier
):
def
acquire_write
(
self
,
start
=
0
,
length
=
0
):
lock
=
Lock
(
self
.
lock_path
)
def
fn
(
barrier
):
lock
.
acquire_write
()
# grab exclusive lock
lock
=
Lock
(
self
.
lock_path
,
start
,
length
)
barrier
.
wait
()
lock
.
acquire_write
()
# grab exclusive lock
barrier
.
wait
()
# hold the lock until exception raises in other procs.
barrier
.
wait
()
barrier
.
wait
()
# hold the lock until timeout in other procs.
def
acquire_read
(
self
,
barrier
):
return
fn
lock
=
Lock
(
self
.
lock_path
)
lock
.
acquire_read
()
# grab shared lock
def
acquire_read
(
self
,
start
=
0
,
length
=
0
):
barrier
.
wait
()
def
fn
(
barrier
):
barrier
.
wait
()
# hold the lock until exception raises in other procs.
lock
=
Lock
(
self
.
lock_path
,
start
,
length
)
lock
.
acquire_read
()
# grab shared lock
def
timeout_write
(
self
,
barrier
):
barrier
.
wait
()
lock
=
Lock
(
self
.
lock_path
)
barrier
.
wait
()
# hold the lock until timeout in other procs.
barrier
.
wait
()
# wait for lock acquire in first process
return
fn
self
.
assertRaises
(
LockError
,
lock
.
acquire_write
,
0.1
)
barrier
.
wait
()
def
timeout_write
(
self
,
start
=
0
,
length
=
0
):
def
fn
(
barrier
):
lock
=
Lock
(
self
.
lock_path
,
start
,
length
)
barrier
.
wait
()
# wait for lock acquire in first process
self
.
assertRaises
(
LockError
,
lock
.
acquire_write
,
0.1
)
barrier
.
wait
()
return
fn
def
timeout_read
(
self
,
barrier
):
def
timeout_read
(
self
,
start
=
0
,
length
=
0
):
lock
=
Lock
(
self
.
lock_path
)
def
fn
(
barrier
):
barrier
.
wait
()
# wait for lock acquire in first process
lock
=
Lock
(
self
.
lock_path
,
start
,
length
)
self
.
assertRaises
(
LockError
,
lock
.
acquire_read
,
0.1
)
barrier
.
wait
()
# wait for lock acquire in first process
barrier
.
wait
()
self
.
assertRaises
(
LockError
,
lock
.
acquire_read
,
0.1
)
barrier
.
wait
()
return
fn
#
#
# Test that exclusive locks on other processes time out when an
# Test that exclusive locks on other processes time out when an
# exclusive lock is held.
# exclusive lock is held.
#
#
def
test_write_lock_timeout_on_write
(
self
):
def
test_write_lock_timeout_on_write
(
self
):
self
.
multiproc_test
(
self
.
acquire_write
,
self
.
timeout_write
)
self
.
multiproc_test
(
self
.
acquire_write
()
,
self
.
timeout_write
()
)
def
test_write_lock_timeout_on_write_2
(
self
):
def
test_write_lock_timeout_on_write_2
(
self
):
self
.
multiproc_test
(
self
.
multiproc_test
(
self
.
acquire_write
,
self
.
timeout_write
,
self
.
timeout_write
)
self
.
acquire_write
()
,
self
.
timeout_write
()
,
self
.
timeout_write
()
)
def
test_write_lock_timeout_on_write_3
(
self
):
def
test_write_lock_timeout_on_write_3
(
self
):
self
.
multiproc_test
(
self
.
multiproc_test
(
self
.
acquire_write
,
self
.
timeout_write
,
self
.
timeout_write
,
self
.
acquire_write
(),
self
.
timeout_write
(),
self
.
timeout_write
(),
self
.
timeout_write
)
self
.
timeout_write
())
def
test_write_lock_timeout_on_write_ranges
(
self
):
self
.
multiproc_test
(
self
.
acquire_write
(
0
,
1
),
self
.
timeout_write
(
0
,
1
))
def
test_write_lock_timeout_on_write_ranges_2
(
self
):
self
.
multiproc_test
(
self
.
acquire_write
(
0
,
64
),
self
.
acquire_write
(
65
,
1
),
self
.
timeout_write
(
0
,
1
),
self
.
timeout_write
(
63
,
1
))
def
test_write_lock_timeout_on_write_ranges_3
(
self
):
self
.
multiproc_test
(
self
.
acquire_write
(
0
,
1
),
self
.
acquire_write
(
1
,
1
),
self
.
timeout_write
(),
self
.
timeout_write
(),
self
.
timeout_write
())
def
test_write_lock_timeout_on_write_ranges_4
(
self
):
self
.
multiproc_test
(
self
.
acquire_write
(
0
,
1
),
self
.
acquire_write
(
1
,
1
),
self
.
acquire_write
(
2
,
456
),
self
.
acquire_write
(
500
,
64
),
self
.
timeout_write
(),
self
.
timeout_write
(),
self
.
timeout_write
())
#
#
# Test that shared locks on other processes time out when an
# Test that shared locks on other processes time out when an
# exclusive lock is held.
# exclusive lock is held.
#
#
def
test_read_lock_timeout_on_write
(
self
):
def
test_read_lock_timeout_on_write
(
self
):
self
.
multiproc_test
(
self
.
acquire_write
,
self
.
timeout_read
)
self
.
multiproc_test
(
self
.
acquire_write
()
,
self
.
timeout_read
()
)
def
test_read_lock_timeout_on_write_2
(
self
):
def
test_read_lock_timeout_on_write_2
(
self
):
self
.
multiproc_test
(
self
.
multiproc_test
(
self
.
acquire_write
,
self
.
timeout_read
,
self
.
timeout_read
)
self
.
acquire_write
()
,
self
.
timeout_read
()
,
self
.
timeout_read
()
)
def
test_read_lock_timeout_on_write_3
(
self
):
def
test_read_lock_timeout_on_write_3
(
self
):
self
.
multiproc_test
(
self
.
multiproc_test
(
self
.
acquire_write
,
self
.
timeout_read
,
self
.
timeout_read
,
self
.
acquire_write
(),
self
.
timeout_read
(),
self
.
timeout_read
(),
self
.
timeout_read
)
self
.
timeout_read
())
def
test_read_lock_timeout_on_write_ranges
(
self
):
"""
small write lock, read whole file.
"""
self
.
multiproc_test
(
self
.
acquire_write
(
0
,
1
),
self
.
timeout_read
())
def
test_read_lock_timeout_on_write_ranges_2
(
self
):
"""
small write lock, small read lock
"""
self
.
multiproc_test
(
self
.
acquire_write
(
0
,
1
),
self
.
timeout_read
(
0
,
1
))
def
test_read_lock_timeout_on_write_ranges_3
(
self
):
"""
two write locks, overlapping read locks
"""
self
.
multiproc_test
(
self
.
acquire_write
(
0
,
1
),
self
.
acquire_write
(
64
,
128
),
self
.
timeout_read
(
0
,
1
),
self
.
timeout_read
(
128
,
256
))
#
#
# Test that exclusive locks time out when shared locks are held.
# Test that exclusive locks time out when shared locks are held.
#
#
def
test_write_lock_timeout_on_read
(
self
):
def
test_write_lock_timeout_on_read
(
self
):
self
.
multiproc_test
(
self
.
acquire_read
,
self
.
timeout_write
)
self
.
multiproc_test
(
self
.
acquire_read
()
,
self
.
timeout_write
()
)
def
test_write_lock_timeout_on_read_2
(
self
):
def
test_write_lock_timeout_on_read_2
(
self
):
self
.
multiproc_test
(
self
.
multiproc_test
(
self
.
acquire_read
,
self
.
timeout_write
,
self
.
timeout_write
)
self
.
acquire_read
()
,
self
.
timeout_write
()
,
self
.
timeout_write
()
)
def
test_write_lock_timeout_on_read_3
(
self
):
def
test_write_lock_timeout_on_read_3
(
self
):
self
.
multiproc_test
(
self
.
multiproc_test
(
self
.
acquire_read
,
self
.
timeout_write
,
self
.
timeout_write
,
self
.
acquire_read
(),
self
.
timeout_write
(),
self
.
timeout_write
(),
self
.
timeout_write
)
self
.
timeout_write
())
def
test_write_lock_timeout_on_read_ranges
(
self
):
self
.
multiproc_test
(
self
.
acquire_read
(
0
,
1
),
self
.
timeout_write
())
def
test_write_lock_timeout_on_read_ranges_2
(
self
):
self
.
multiproc_test
(
self
.
acquire_read
(
0
,
1
),
self
.
timeout_write
(
0
,
1
))
def
test_write_lock_timeout_on_read_ranges_3
(
self
):
self
.
multiproc_test
(
self
.
acquire_read
(
0
,
1
),
self
.
acquire_read
(
10
,
1
),
self
.
timeout_write
(
0
,
1
),
self
.
timeout_write
(
10
,
1
))
def
test_write_lock_timeout_on_read_ranges_4
(
self
):
self
.
multiproc_test
(
self
.
acquire_read
(
0
,
64
),
self
.
timeout_write
(
10
,
1
),
self
.
timeout_write
(
32
,
1
))
def
test_write_lock_timeout_on_read_ranges_5
(
self
):
self
.
multiproc_test
(
self
.
acquire_read
(
64
,
128
),
self
.
timeout_write
(
65
,
1
),
self
.
timeout_write
(
127
,
1
),
self
.
timeout_write
(
90
,
10
))
#
#
# Test that exclusive locks time while lots of shared locks are held.
# Test that exclusive locks time while lots of shared locks are held.
#
#
def
test_write_lock_timeout_with_multiple_readers_2_1
(
self
):
def
test_write_lock_timeout_with_multiple_readers_2_1
(
self
):
self
.
multiproc_test
(
self
.
multiproc_test
(
self
.
acquire_read
,
self
.
acquire_read
,
self
.
timeout_write
)
self
.
acquire_read
()
,
self
.
acquire_read
()
,
self
.
timeout_write
()
)
def
test_write_lock_timeout_with_multiple_readers_2_2
(
self
):
def
test_write_lock_timeout_with_multiple_readers_2_2
(
self
):
self
.
multiproc_test
(
self
.
multiproc_test
(
self
.
acquire_read
,
self
.
acquire_read
,
self
.
timeout_write
,
self
.
acquire_read
()
,
self
.
acquire_read
()
,
self
.
timeout_write
()
,
self
.
timeout_write
)
self
.
timeout_write
()
)
def
test_write_lock_timeout_with_multiple_readers_3_1
(
self
):
def
test_write_lock_timeout_with_multiple_readers_3_1
(
self
):
self
.
multiproc_test
(
self
.
multiproc_test
(
self
.
acquire_read
,
self
.
acquire_read
,
self
.
acquire_read
,
self
.
acquire_read
()
,
self
.
acquire_read
()
,
self
.
acquire_read
()
,
self
.
timeout_write
)
self
.
timeout_write
()
)
def
test_write_lock_timeout_with_multiple_readers_3_2
(
self
):
def
test_write_lock_timeout_with_multiple_readers_3_2
(
self
):
self
.
multiproc_test
(
self
.
multiproc_test
(
self
.
acquire_read
,
self
.
acquire_read
,
self
.
acquire_read
,
self
.
acquire_read
(),
self
.
acquire_read
(),
self
.
acquire_read
(),
self
.
timeout_write
,
self
.
timeout_write
)
self
.
timeout_write
(),
self
.
timeout_write
())
def
test_write_lock_timeout_with_multiple_readers_2_1_ranges
(
self
):
self
.
multiproc_test
(
self
.
acquire_read
(
0
,
10
),
self
.
acquire_read
(
5
,
10
),
self
.
timeout_write
(
5
,
5
))
def
test_write_lock_timeout_with_multiple_readers_2_3_ranges
(
self
):
self
.
multiproc_test
(
self
.
acquire_read
(
0
,
10
),
self
.
acquire_read
(
5
,
15
),
self
.
timeout_write
(
0
,
1
),
self
.
timeout_write
(
11
,
3
),
self
.
timeout_write
(
7
,
1
))
def
test_write_lock_timeout_with_multiple_readers_3_1_ranges
(
self
):
self
.
multiproc_test
(
self
.
acquire_read
(
0
,
5
),
self
.
acquire_read
(
5
,
5
),
self
.
acquire_read
(
10
,
5
),
self
.
timeout_write
(
0
,
15
))
def
test_write_lock_timeout_with_multiple_readers_3_2_ranges
(
self
):
self
.
multiproc_test
(
self
.
acquire_read
(
0
,
5
),
self
.
acquire_read
(
5
,
5
),
self
.
acquire_read
(
10
,
5
),
self
.
timeout_write
(
3
,
10
),
self
.
timeout_write
(
5
,
1
))
#
#
# Test that read can be upgraded to write.
# Test that read can be upgraded to write.
...
@@ -171,7 +259,7 @@ def test_upgrade_read_to_write(self):
...
@@ -171,7 +259,7 @@ def test_upgrade_read_to_write(self):
lock
.
acquire_read
()
lock
.
acquire_read
()
self
.
assertTrue
(
lock
.
_reads
==
1
)
self
.
assertTrue
(
lock
.
_reads
==
1
)
self
.
assertTrue
(
lock
.
_writes
==
0
)
self
.
assertTrue
(
lock
.
_writes
==
0
)
self
.
assertTrue
(
lock
.
_file
.
mode
==
'
r
'
)
self
.
assertTrue
(
lock
.
_file
.
mode
==
'
r
+
'
)
lock
.
acquire_write
()
lock
.
acquire_write
()
self
.
assertTrue
(
lock
.
_reads
==
1
)
self
.
assertTrue
(
lock
.
_reads
==
1
)
...
@@ -188,6 +276,26 @@ def test_upgrade_read_to_write(self):
...
@@ -188,6 +276,26 @@ def test_upgrade_read_to_write(self):
self
.
assertTrue
(
lock
.
_writes
==
0
)
self
.
assertTrue
(
lock
.
_writes
==
0
)
self
.
assertTrue
(
lock
.
_file
is
None
)
self
.
assertTrue
(
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
(
self
):
# ensure lock file exists the first time, so we open it read-only
# to begin wtih.
touch
(
self
.
lock_path
)
os
.
chmod
(
self
.
lock_path
,
0444
)
lock
=
Lock
(
self
.
lock_path
)
self
.
assertTrue
(
lock
.
_reads
==
0
)
self
.
assertTrue
(
lock
.
_writes
==
0
)
lock
.
acquire_read
()
self
.
assertTrue
(
lock
.
_reads
==
1
)
self
.
assertTrue
(
lock
.
_writes
==
0
)
self
.
assertTrue
(
lock
.
_file
.
mode
==
'
r
'
)
self
.
assertRaises
(
LockError
,
lock
.
acquire_write
)
#
#
# Longer test case that ensures locks are reusable. Ordering is
# Longer test case that ensures locks are reusable. Ordering is
# enforced by barriers throughout -- steps are shown with numbers.
# enforced by barriers throughout -- steps are shown with numbers.
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment