Handling named temporary files in tests

Hi, While fixing several windows specific unit test failures, I encountered some problems I am not sure how to solve. In particular, we have a relatively common idiom as follows: Open file securely with a visible name (using NamedTemporaryFile) write some content into it open the file with another open call Of course, this does not work on windows. NamedTemporaryFile is basically useless on this platform (windows refuses to let a process to reopen a file opened from NamedTemporaryFile). I can see two solutions: - using mkstemp + re-opening the file later from the name returned by mkstemp: AFAICT, this basically defeats the whole purpose of mkstemp - have our own layer to bypass mkstemp on windows, where security is not a concern anyway, and use the proper functions on sane platforms. Do people have an opinion on this ? Or maybe a solution to the problem altogether ? cheers, David

A Monday 09 March 2009, David Cournapeau escrigué:
Hi,
While fixing several windows specific unit test failures, I encountered some problems I am not sure how to solve. In particular, we have a relatively common idiom as follows:
Open file securely with a visible name (using NamedTemporaryFile) write some content into it open the file with another open call
Of course, this does not work on windows. NamedTemporaryFile is basically useless on this platform (windows refuses to let a process to reopen a file opened from NamedTemporaryFile). I can see two solutions: - using mkstemp + re-opening the file later from the name returned by mkstemp: AFAICT, this basically defeats the whole purpose of mkstemp - have our own layer to bypass mkstemp on windows, where security is not a concern anyway, and use the proper functions on sane platforms.
Do people have an opinion on this ? Or maybe a solution to the problem altogether ?
We have a similar case of use for the PyTables project, and we ended implementing a class that is meant to be used as a mixin from which the test classes inherits. The class is, more or less: class TempFileMixin: def setUp(self): """Set ``h5file`` and ``h5fname`` instance attributes.""" self.h5fname = tempfile.mktemp(suffix='.h5') self.h5file = tables.openFile( self.h5fname, 'w', title=self._getName()) def tearDown(self): """Close ``h5file`` and remove ``h5fname``.""" self.h5file.close() self.h5file = None os.remove(self.h5fname) def _reopen(self, mode='r'): """Reopen ``h5file`` in the specified ``mode``.""" self.h5file.close() self.h5file = tables.openFile(self.h5fname, mode) return True The advantage is that, by simply inheriting from `TempFileMixin`, the developer have avaliable the ``h5file`` (file handler) and ``h5fname`` (file name). The mixin is responsible to open, close and remove the temporary file. In addition, the `_reopen()` method allows you to manually close and re-open the temporary, if that is what you want. An example of use: # Test for building very large MD columns without defaults class MDLargeColTestCase(common.TempFileMixin, common.PyTablesTestCase): reopen = True def test01_create(self): "Create a Table with a very large MD column. Ticket #211." N = 2**18 cols = {'col1': Int8Col(shape=N, dflt=0)} tbl = self.h5file.createTable('/', 'test', cols) tbl.row.append() # add a single row tbl.flush() if self.reopen: self._reopen() tbl = self.h5file.root.test # Check the value assert allequal(tbl[0]['col1'], zeros(N, 'i1')) This proved to be pretty handy in practice. HTH, -- Francesc Alted
participants (2)
-
David Cournapeau
-
Francesc Alted