-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7 from xsuite/release/v0.1.2
Release 0.1.2
- Loading branch information
Showing
7 changed files
with
214 additions
and
105 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,9 @@ | ||
[tool.poetry] | ||
name = "xaux" | ||
version = "0.1.1" | ||
version = "0.1.2" | ||
description = "Support tools for Xsuite packages" | ||
authors = ["Frederik Van der Veken <[email protected]>"] | ||
authors = ["Frederik Van der Veken <[email protected]>", | ||
"Konstantinos Paraschou <[email protected]"] | ||
license = "Apache 2.0" | ||
readme = "README.md" | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import time | ||
import json | ||
from pathlib import Path | ||
import shutil | ||
from xaux import ProtectFile | ||
|
||
ProtectFile._debug = True | ||
|
||
|
||
def rewrite(pf, with_copy=False): | ||
data = json.load(pf) | ||
time.sleep(0.2) | ||
data["myint"] += 1 | ||
if not with_copy: | ||
pf.seek(0) # revert point to beginning of file | ||
json.dump(data, pf, indent=4, sort_keys=True) | ||
pf.truncate() | ||
else: # write to another file and copy back | ||
cfname = "_copy_" + pf.name | ||
with open(cfname, "w") as cf: | ||
json.dump(data, cf, indent=4, sort_keys=True) | ||
shutil.copyfile(cfname, pf.name) | ||
Path.unlink(Path(cfname)) | ||
|
||
|
||
def change_file_protected(fname, with_copy=False, max_lock_time=None): | ||
with ProtectFile(fname, "r+", backup=False, wait=0.1, max_lock_time=max_lock_time) as pf: | ||
rewrite(pf, with_copy=with_copy) | ||
return | ||
|
||
|
||
def change_file_standard(fname, with_copy=False): | ||
with open(fname, "r+") as pf: # fails with this context | ||
rewrite(pf) | ||
return | ||
|
||
|
||
def init_file(fname): | ||
with ProtectFile(fname, "w", backup=False, wait=1) as pf: | ||
json.dump({"myint": 0}, pf, indent=4) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import json | ||
from pathlib import Path | ||
from _test_helpers import init_file, change_file_protected | ||
from multiprocessing import Process | ||
import os | ||
import time | ||
import signal | ||
|
||
|
||
fname = "test_max_lock_time.json" | ||
|
||
|
||
def test_max_lock_time(): | ||
init_file(fname) | ||
|
||
procA = Process(target=change_file_protected, args=(fname, False, 1)) | ||
procB = Process(target=change_file_protected, args=(fname, False, 1)) | ||
|
||
procA.start() # Will take > 0.2s | ||
time.sleep(0.18) | ||
assert Path(fname+'.lock').exists() | ||
|
||
# B will try to access the file while A is still running, and will try | ||
# again 0.1s later by which time A has finished (and the lock will have | ||
# disappeared). | ||
procB.start() | ||
|
||
procA.join() | ||
procB.join() | ||
|
||
with open(fname, "r+") as pf: | ||
Path(fname).unlink() | ||
data = json.load(pf) | ||
assert data["myint"] == 2 | ||
|
||
|
||
def test_max_lock_time_crashed(): | ||
init_file(fname) | ||
|
||
procA = Process(target=change_file_protected, args=(fname, False, 5)) | ||
procB = Process(target=change_file_protected, args=(fname, False, 5)) | ||
|
||
procA.start() | ||
procB.start() | ||
start = time.time() | ||
|
||
# We kill process A after 0.1s such that we have a hanging lockfile | ||
time.sleep(0.1) | ||
os.kill(procA.pid, signal.SIGKILL) | ||
procA.join() | ||
assert Path(fname+'.lock').exists() | ||
|
||
# After 6s (5s * 1.2) the lockfile is allowed to be force-freed. | ||
# First we check that just before that, B was not able to alter the file: | ||
time.sleep(6.1) # 6s max_lock_time + 0.2s rewrite time - 0.1s already waited | ||
with open(fname, "r") as pf: | ||
data = json.load(pf) | ||
assert data["myint"] == 0 | ||
procB.join() | ||
|
||
# Process B was able to complete its work directly after the max_lock_time | ||
stop = time.time() | ||
elapsed_time = stop - start | ||
assert elapsed_time < 6.5 | ||
|
||
with open(fname, "r+") as pf: | ||
Path(fname).unlink() | ||
data = json.load(pf) | ||
assert data["myint"] == 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
from xaux import __version__ | ||
|
||
def test_version(): | ||
assert __version__ == '0.1.1' | ||
assert __version__ == '0.1.2' | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.