forked from conda/conda
-
Notifications
You must be signed in to change notification settings - Fork 0
/
test_lock.py
128 lines (101 loc) · 4.01 KB
/
test_lock.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import pytest
from conda.lock import DirectoryLock, FileLock, LockError
from os.path import basename, exists, isfile, join
def test_filelock_passes(tmpdir):
"""
Normal test on file lock
"""
package_name = "conda_file1"
tmpfile = join(tmpdir.strpath, package_name)
with FileLock(tmpfile) as lock:
path = basename(lock.lock_file_path)
assert tmpdir.join(path).exists() and tmpdir.join(path).isfile()
# lock should clean up after itself
assert not tmpdir.join(path).exists()
def test_filelock_locks(tmpdir):
"""
Test on file lock, multiple lock on same file
Lock error should raised
"""
package_name = "conda_file_2"
tmpfile = join(tmpdir.strpath, package_name)
with FileLock(tmpfile) as lock1:
path = basename(lock1.lock_file_path)
assert tmpdir.join(path).exists()
with pytest.raises(LockError) as execinfo:
with FileLock(tmpfile, retries=1) as lock2:
assert False # this should never happen
assert lock2.path_to_lock == lock1.path_to_lock
assert tmpdir.join(path).exists() and tmpdir.join(path).isfile()
# lock should clean up after itself
assert not tmpdir.join(path).exists()
def test_folder_locks(tmpdir):
"""
Test on Directory lock
"""
package_name = "dir_1"
tmpfile = join(tmpdir.strpath, package_name)
with DirectoryLock(tmpfile) as lock1:
assert exists(lock1.lock_file_path) and isfile(lock1.lock_file_path)
with pytest.raises(LockError) as execinfo:
with DirectoryLock(tmpfile, retries=1) as lock2:
assert False # this should never happen
assert exists(lock1.lock_file_path) and isfile(lock1.lock_file_path)
# lock should clean up after itself
assert not exists(lock1.lock_file_path)
def test_lock_thread(tmpdir):
"""
2 thread want to lock a file
One thread will have LockError Raised
"""
def lock_thread(tmpdir, file_path):
with FileLock(file_path) as lock1:
path = basename(lock1.lock_file_path)
assert tmpdir.join(path).exists() and tmpdir.join(path).isfile()
assert not tmpdir.join(path).exists()
from threading import Thread
package_name = "conda_file_3"
tmpfile = join(tmpdir.strpath, package_name)
t = Thread(target=lock_thread, args=(tmpdir, tmpfile))
with FileLock(tmpfile) as lock1:
t.start()
path = basename(lock1.lock_file_path)
assert tmpdir.join(path).exists() and tmpdir.join(path).isfile()
t.join()
# lock should clean up after itself
assert not tmpdir.join(path).exists()
def test_lock_retries(tmpdir):
"""
2 thread want to lock a same file
Lock has zero retries
One thread will have LockError raised
"""
def lock_thread_retries(tmpdir, file_path):
with pytest.raises(LockError) as execinfo:
with FileLock(file_path, retries=0):
assert False # should never enter here, since max_tries is 0
assert "LOCKERROR" in str(execinfo.value)
from threading import Thread
package_name = "conda_file_3"
tmpfile = join(tmpdir.strpath, package_name)
t = Thread(target=lock_thread_retries, args=(tmpdir, tmpfile))
with FileLock(tmpfile) as lock1:
t.start()
path = basename(lock1.lock_file_path)
assert tmpdir.join(path).exists() and tmpdir.join(path).isfile()
t.join()
# lock should clean up after itself
assert not tmpdir.join(path).exists()
def test_permission_file():
"""
Test when lock cannot be created due to permission
Make sure no exception raised
"""
from conda._vendor.auxlib.compat import Utf8NamedTemporaryFile
from conda.common.compat import text_type
with Utf8NamedTemporaryFile(mode='r') as f:
if not isinstance(f.name, text_type):
return
with FileLock(f.name) as lock:
path = basename(lock.lock_file_path)
assert not exists(join(f.name, path))