test_filelock.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import os
  2. import time
  3. import logging
  4. import multiprocessing
  5. import tempfile
  6. import threading
  7. import library.python.filelock
  8. def _acquire_lock(lock_path, out_file_path):
  9. with library.python.filelock.FileLock(lock_path):
  10. with open(out_file_path, "a") as out:
  11. out.write("{}:{}\n".format(os.getpid(), time.time()))
  12. time.sleep(2)
  13. def test_filelock():
  14. temp_dir = tempfile.mkdtemp()
  15. lock_path = os.path.join(temp_dir, "file.lock")
  16. out_file_path = os.path.join(temp_dir, "out.txt")
  17. process_count = 5
  18. processes = []
  19. for i in range(process_count):
  20. process = multiprocessing.Process(target=_acquire_lock, args=(lock_path, out_file_path))
  21. process.start()
  22. processes.append(process)
  23. for process in processes:
  24. process.join()
  25. pids = []
  26. times = []
  27. with open(out_file_path) as out:
  28. content = out.read()
  29. logging.info("Times:\n%s", content)
  30. for line in content.strip().split("\n"):
  31. pid, time_val = line.split(":")
  32. pids.append(pid)
  33. times.append(float(time_val))
  34. assert len(set(pids)) == process_count
  35. time1 = times.pop()
  36. while times:
  37. time2 = times.pop()
  38. assert int(time1) - int(time2) >= 2
  39. time1 = time2
  40. def test_filelock_init_acquired():
  41. temp_dir = tempfile.mkdtemp()
  42. lock_path = os.path.join(temp_dir, "file.lock")
  43. with library.python.filelock.FileLock(lock_path):
  44. sublock = library.python.filelock.FileLock(lock_path)
  45. del sublock
  46. def test_concurrent_lock():
  47. filename = 'thread.lock'
  48. def lock():
  49. lock = library.python.filelock.FileLock(filename)
  50. time.sleep(1)
  51. assert lock.acquire()
  52. lock.release()
  53. try:
  54. os.unlink(filename)
  55. except OSError:
  56. pass
  57. threads = []
  58. for i in range(100):
  59. t = threading.Thread(target=lock)
  60. threads.append(t)
  61. for t in threads:
  62. t.start()
  63. for t in threads:
  64. t.join()
  65. def test_pidfilelock():
  66. lock_file = 'pidfile.lock'
  67. # there should be no info
  68. lock = library.python.filelock.PidFileLock(lock_file)
  69. assert lock.info.pid == 0
  70. assert lock.info.time == 0
  71. with library.python.filelock.PidFileLock(lock_file) as lock:
  72. assert lock.info.pid == os.getpid()
  73. assert lock.info.time <= time.time()
  74. assert lock.info.time > time.time() - 2
  75. newlock = library.python.filelock.PidFileLock(lock_file)
  76. # info shouldn't require locking
  77. assert newlock.info.pid == os.getpid()
  78. assert not newlock.acquire(blocking=False)
  79. newlock = library.python.filelock.PidFileLock(lock_file)
  80. # info is still accessible
  81. assert newlock.info.pid == os.getpid()
  82. t = newlock.info.time
  83. # info is updated
  84. time.sleep(1)
  85. with newlock as lock:
  86. assert lock.info.time > t
  87. def _try_acquire_pidlock(lock_file, out_file, lock_pid=None):
  88. lock = library.python.filelock.PidFileLock(lock_file)
  89. with open(out_file, "w") as afile:
  90. afile.write("1" if lock.acquire(blocking=False) else "0")
  91. if lock_pid is not None:
  92. assert lock.info.pid == lock_pid
  93. def test_pidfilelock_multiprocessing():
  94. lock_file = 'mp_pidfile.lock'
  95. out_file = lock_file + ".out"
  96. # subprocess can aquire lock
  97. proc = multiprocessing.Process(target=_try_acquire_pidlock, args=(lock_file, out_file))
  98. proc.start()
  99. proc.join()
  100. with open(out_file) as afile:
  101. assert "1" == afile.read()
  102. # subprocess can't aquire lock
  103. with library.python.filelock.PidFileLock(lock_file) as lock:
  104. proc = multiprocessing.Process(target=_try_acquire_pidlock, args=(lock_file, out_file, lock.info.pid))
  105. proc.start()
  106. proc.join()
  107. with open(out_file) as afile:
  108. assert "0" == afile.read()