I have the following file (written for use with py.test):
# test_fuser.py
import subprocess
def fuser(filename):
return subprocess.check_output(['fuser', filename]).split()
def test_fuser_0(tmpdir):
test_file = tmpdir.join('test.txt')
test_file.write('')
assert len(fuser(test_file.strpath)) == 0
def test_fuser_1(tmpdir):
test_file = tmpdir.join('test.txt')
test_file.write('')
with open(test_file.strpath, 'w'):
assert len(fuser(test_file.strpath)) == 1
Running py.test
from the command-line yields:
$ py.test test_fuser.py
================================= test session starts ==================================
platform darwin -- Python 2.7.8 -- py-1.4.26 -- pytest-2.6.4
collected 2 items
test_fuser.py .F
======================================= FAILURES =======================================
_____________________________________ test_fuser_1 _____________________________________
tmpdir = local('/private/var/folders/mx/h4mybl9x1p52wbj2hnvk1lgh0000gn/T/pytest-131/test_fuser_10')
def test_fuser_1(tmpdir):
test_file = tmpdir.join('test.txt')
test_file.write('')
with open(test_file.strpath, 'w'):
> assert len(fuser(test_file.strpath)) == 1
E assert 2 == 1
E + where 2 = len(['71433', '71437'])
E + where ['71433', '71437'] = fuser('/private/var/folders/mx/h4mybl9x1p52wbj2hnvk1lgh0000gn/T/pytest-131/test_fuser_10/test.txt')
E + where '/private/var/folders/mx/h4mybl9x1p52wbj2hnvk1lgh0000gn/T/pytest-131/test_fuser_10/test.txt' = local('/private/var/folders/mx/h4mybl9x1p52wbj2hnvk1lgh0000gn/T/pytest-131/test_fuser_10/test.txt').strpath
test_fuser.py:18: AssertionError
--------------------------------- Captured stderr call ---------------------------------
/private/var/folders/mx/h4mybl9x1p52wbj2hnvk1lgh0000gn/T/pytest-131/test_fuser_10/test.txt:
========================= 1 failed, 1 passed in 10.32 seconds =========================
This is unusual because one would expect fuser()
to return one PID, not two, since only the call to open()
should have the file open.
To investigate this further, I set a breakpoint in test_fuser_1()
right before the call to fuser()
, within the context of open()
and then reran the test.
def test_fuser_1(tmpdir):
test_file = tmpdir.join('test.txt')
test_file.write('')
with open(test_file.strpath, 'w'):
pytest.set_trace()
assert len(fuser(test_file.strpath)) == 1
At the break point I grabbed the name of the temporary file:
>>>>>>>>>>>>>>>>>>>>>>> PDB set_trace (IO-capturing turned off) >>>>>>>>>>>>>>>>>>>>>>>>
> /Users/caesarbautista/Desktop/test_fuser.py(21)test_fuser_1()
-> assert len(fuser(test_file.strpath)) == 1
(Pdb) test_file.strpath
'/private/var/folders/mx/h4mybl9x1p52wbj2hnvk1lgh0000gn/T/pytest-132/test_fuser_10/test.txt'
Then, calling fuser
from another terminal I see one PID as expected.
$ fuser /private/var/folders/mx/h4mybl9x1p52wbj2hnvk1lgh0000gn/T/pytest-132/test_fuser_10/test.txt
/private/var/folders/mx/h4mybl9x1p52wbj2hnvk1lgh0000gn/T/pytest-132/test_fuser_10/test.txt: 71516
This seems to suggest that subprocess is responsible for the second PID, but I'm not certain why that might be and have run out of ideas for how to investigate this further. Any idea where the second PID is coming from?
I though perhaps py.test might be connected to this, so I rewrote the test for use with nose:
def test_fuser_0():
with open('test.txt', 'w') as fp:
fp.write('')
pids = fuser('test.txt')
assert len(pids) == 0, pids
def test_fuser_1():
with open('test.txt', 'w') as fp:
fp.write('')
pids = fuser('test.txt')
assert len(pids) == 1, pids
But running them with nose resulted in the same failure:
$ nosetests --tests=test_fuser.py
test.txt:
.test.txt:
F
======================================================================
FAIL: test_fuser.test_fuser_1
----------------------------------------------------------------------
Traceback (most recent call last):
File "/opt/boxen/homebrew/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
self.test(*self.arg)
File "/Users/caesarbautista/Desktop/test_fuser.py", line 34, in test_fuser_1
assert len(pids) == 1, pids
AssertionError: ['71865', '71869']
----------------------------------------------------------------------
Ran 2 tests in 11.026s
FAILED (failures=1