test_atomicwrites.py 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import errno
  2. import os
  3. from atomicwrites import atomic_write
  4. import pytest
  5. def test_atomic_write(tmpdir):
  6. fname = tmpdir.join('ha')
  7. for i in range(2):
  8. with atomic_write(str(fname), overwrite=True) as f:
  9. f.write('hoho')
  10. with pytest.raises(OSError) as excinfo:
  11. with atomic_write(str(fname), overwrite=False) as f:
  12. f.write('haha')
  13. assert excinfo.value.errno == errno.EEXIST
  14. assert fname.read() == 'hoho'
  15. assert len(tmpdir.listdir()) == 1
  16. def test_teardown(tmpdir):
  17. fname = tmpdir.join('ha')
  18. with pytest.raises(AssertionError):
  19. with atomic_write(str(fname), overwrite=True):
  20. assert False
  21. assert not tmpdir.listdir()
  22. def test_replace_simultaneously_created_file(tmpdir):
  23. fname = tmpdir.join('ha')
  24. with atomic_write(str(fname), overwrite=True) as f:
  25. f.write('hoho')
  26. fname.write('harhar')
  27. assert fname.read() == 'harhar'
  28. assert fname.read() == 'hoho'
  29. assert len(tmpdir.listdir()) == 1
  30. def test_dont_remove_simultaneously_created_file(tmpdir):
  31. fname = tmpdir.join('ha')
  32. with pytest.raises(OSError) as excinfo:
  33. with atomic_write(str(fname), overwrite=False) as f:
  34. f.write('hoho')
  35. fname.write('harhar')
  36. assert fname.read() == 'harhar'
  37. assert excinfo.value.errno == errno.EEXIST
  38. assert fname.read() == 'harhar'
  39. assert len(tmpdir.listdir()) == 1
  40. # Verify that nested exceptions during rollback do not overwrite the initial
  41. # exception that triggered a rollback.
  42. def test_open_reraise(tmpdir):
  43. fname = tmpdir.join('ha')
  44. with pytest.raises(AssertionError):
  45. aw = atomic_write(str(fname), overwrite=False)
  46. with aw:
  47. # Mess with internals, so commit will trigger a ValueError. We're
  48. # testing that the initial AssertionError triggered below is
  49. # propagated up the stack, not the second exception triggered
  50. # during commit.
  51. aw.rollback = lambda: 1 / 0
  52. # Now trigger our own exception.
  53. assert False, "Intentional failure for testing purposes"
  54. def test_atomic_write_in_pwd(tmpdir):
  55. orig_curdir = os.getcwd()
  56. try:
  57. os.chdir(str(tmpdir))
  58. fname = 'ha'
  59. for i in range(2):
  60. with atomic_write(str(fname), overwrite=True) as f:
  61. f.write('hoho')
  62. with pytest.raises(OSError) as excinfo:
  63. with atomic_write(str(fname), overwrite=False) as f:
  64. f.write('haha')
  65. assert excinfo.value.errno == errno.EEXIST
  66. assert open(fname).read() == 'hoho'
  67. assert len(tmpdir.listdir()) == 1
  68. finally:
  69. os.chdir(orig_curdir)