""" Test module for compatibility with plain HDF files ================================================== :Author: Ivan Vilata i Balaguer :Contact: ivilata@carabos.com :Created: 2005-09-29 :License: BSD :Revision: $Id: test_hdf5compat.py 3035 2007-06-18 12:03:52Z faltet $ """ import unittest import tempfile import numpy import tables from tables.tests import common from tables.tests.common import allequal class HDF5CompatibilityTestCase(common.PyTablesTestCase): """ Base class for HDF5 compatibility tests. Test cases deriving from this class must define an ``h5fname`` attribute with the name of the file to be opened, and a ``_test()`` method with checks on the opened file. """ def setUp(self): self.h5file = None def tearDown(self): if self.h5file is not None: self.h5file.close() self.h5file = None def test(self): self.h5fname = self._testFilename(self.h5fname) self.h5file = tables.openFile(self.h5fname) self._test() class EnumTestCase(HDF5CompatibilityTestCase): """ Test for enumerated datatype. See ftp://ftp.hdfgroup.org/HDF5/current/src/unpacked/test/enum.c. """ h5fname = 'smpl_enum.h5' def _test(self): self.assert_('/EnumTest' in self.h5file) arr = self.h5file.getNode('/EnumTest') self.assert_(isinstance(arr, tables.Array)) enum = arr.getEnum() expectedEnum = tables.Enum(['RED', 'GREEN', 'BLUE', 'WHITE', 'BLACK']) self.assertEqual(enum, expectedEnum) data = list(arr.read()) expectedData = [ enum[name] for name in ['RED', 'GREEN', 'BLUE', 'WHITE', 'BLACK', 'RED', 'GREEN', 'BLUE', 'WHITE', 'BLACK']] self.assertEqual(data, expectedData) class NumericTestCase(HDF5CompatibilityTestCase): """ Test for several numeric datatypes. See ftp://ftp.ncsa.uiuc.edu/HDF/files/hdf5/samples/[fiu]l?{8,16,32,64}{be,le}.c (they seem to be no longer available). """ def _test(self): self.assert_('/TestArray' in self.h5file) arr = self.h5file.getNode('/TestArray') self.assert_(isinstance(arr, tables.Array)) self.assertEqual(arr.atom.type, self.type) self.assertEqual(arr.byteorder, self.byteorder) self.assertEqual(arr.shape, (6, 5)) data = arr.read() expectedData = numpy.array([ [0, 1, 2, 3, 4], [1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [3, 4, 5, 6, 7], [4, 5, 6, 7, 8], [5, 6, 7, 8, 9]], dtype=self.type) self.assert_(common.areArraysEqual(data, expectedData)) class F64BETestCase(NumericTestCase): h5fname = 'smpl_f64be.h5' type = 'float64' byteorder = 'big' class F64LETestCase(NumericTestCase): h5fname = 'smpl_f64le.h5' type = 'float64' byteorder = 'little' class I64BETestCase(NumericTestCase): h5fname = 'smpl_i64be.h5' type = 'int64' byteorder = 'big' class I64LETestCase(NumericTestCase): h5fname = 'smpl_i64le.h5' type = 'int64' byteorder = 'little' class I32BETestCase(NumericTestCase): h5fname = 'smpl_i32be.h5' type = 'int32' byteorder = 'big' class I32LETestCase(NumericTestCase): h5fname = 'smpl_i32le.h5' type = 'int32' byteorder = 'little' class ChunkedCompoundTestCase(HDF5CompatibilityTestCase): """ Test for a more complex and chunked compound structure. This is generated by a chunked version of the example in ftp://ftp.ncsa.uiuc.edu/HDF/files/hdf5/samples/compound2.c. """ h5fname = 'smpl_compound_chunked.h5' def _test(self): self.assert_('/CompoundChunked' in self.h5file) tbl = self.h5file.getNode('/CompoundChunked') self.assert_(isinstance(tbl, tables.Table)) self.assertEqual( tbl.colnames, ['a_name', 'c_name', 'd_name', 'e_name', 'f_name', 'g_name']) self.assertEqual(tbl.coltypes['a_name'], 'int32') self.assertEqual(tbl.coldtypes['a_name'].shape, ()) self.assertEqual(tbl.coltypes['c_name'], 'string') self.assertEqual(tbl.coldtypes['c_name'].shape, ()) self.assertEqual(tbl.coltypes['d_name'], 'int16') self.assertEqual(tbl.coldtypes['d_name'].shape, (5, 10)) self.assertEqual(tbl.coltypes['e_name'], 'float32') self.assertEqual(tbl.coldtypes['e_name'].shape, ()) self.assertEqual(tbl.coltypes['f_name'], 'float64') self.assertEqual(tbl.coldtypes['f_name'].shape, (10,)) self.assertEqual(tbl.coltypes['g_name'], 'uint8') self.assertEqual(tbl.coldtypes['g_name'].shape, ()) for m in range(len(tbl)): row = tbl[m] # This version of the loop seems to fail because of ``iterrows()``. #for (m, row) in enumerate(tbl): self.assertEqual(row['a_name'], m) self.assertEqual(row['c_name'], "Hello!") dRow = row['d_name'] for n in range(5): for o in range(10): self.assertEqual(dRow[n][o], m + n + o) self.assertAlmostEqual(row['e_name'], m * 0.96, places=6) fRow = row['f_name'] for n in range(10): self.assertAlmostEqual(fRow[n], m * 1024.9637) self.assertEqual(row['g_name'], ord('m')) class ContiguousCompoundTestCase(HDF5CompatibilityTestCase): """ Test for support of native contiguous compound datasets. This example has been provided by Dav Clark. """ h5fname = 'non-chunked-table.h5' def _test(self): self.assert_('/test_var/structure variable' in self.h5file) tbl = self.h5file.getNode('/test_var/structure variable') self.assert_(isinstance(tbl, tables.Table)) self.assertEqual( tbl.colnames, ['a', 'b', 'c', 'd']) self.assertEqual(tbl.coltypes['a'], 'float64') self.assertEqual(tbl.coldtypes['a'].shape, ()) self.assertEqual(tbl.coltypes['b'], 'float64') self.assertEqual(tbl.coldtypes['b'].shape, ()) self.assertEqual(tbl.coltypes['c'], 'float64') self.assertEqual(tbl.coldtypes['c'].shape, (2,)) self.assertEqual(tbl.coltypes['d'], 'string') self.assertEqual(tbl.coldtypes['d'].shape, ()) for row in tbl.iterrows(): self.assertEqual(row['a'], 3.0) self.assertEqual(row['b'], 4.0) self.assert_(allequal(row['c'], numpy.array([2.0, 3.0], dtype="float64"))) self.assertEqual(row['d'], "d") self.h5file.close() class ContiguousCompoundAppendTestCase(HDF5CompatibilityTestCase): """ Test for appending data to native contiguous compound datasets. """ h5fname = 'non-chunked-table.h5' def _test(self): self.assert_('/test_var/structure variable' in self.h5file) self.h5file.close() # Reopen in 'a'ppend mode try: self.h5file = tables.openFile(self.h5fname, 'a') except IOError: # Problems for opening (probably not permisions to write the file) return tbl = self.h5file.getNode('/test_var/structure variable') # Try to add rows to a non-chunked table (this should raise an error) self.assertRaises(tables.HDF5ExtError, tbl.append, [(4.0,5.0,[2.0,3.0],'d')]) # Appending using the Row interface self.assertRaises(tables.HDF5ExtError, tbl.row.append) class ExtendibleTestCase(HDF5CompatibilityTestCase): """ Test for extendible datasets. See the example programs in the Introduction to HDF5. """ h5fname = 'smpl_SDSextendible.h5' def _test(self): self.assert_('/ExtendibleArray' in self.h5file) arr = self.h5file.getNode('/ExtendibleArray') self.assert_(isinstance(arr, tables.EArray)) self.assertEqual(arr.byteorder, 'big') self.assertEqual(arr.atom.type, 'int32') self.assertEqual(arr.shape, (10, 5)) self.assertEqual(arr.extdim, 0) self.assertEqual(len(arr), 10) data = arr.read() expectedData = numpy.array([ [1, 1, 1, 3, 3], [1, 1, 1, 3, 3], [1, 1, 1, 0, 0], [2, 0, 0, 0, 0], [2, 0, 0, 0, 0], [2, 0, 0, 0, 0], [2, 0, 0, 0, 0], [2, 0, 0, 0, 0], [2, 0, 0, 0, 0], [2, 0, 0, 0, 0]], dtype=arr.atom.type) self.assert_(common.areArraysEqual(data, expectedData)) class SzipTestCase(HDF5CompatibilityTestCase): """ Test for native HDF5 files with datasets compressed with szip. """ h5fname = 'test_szip.h5' def _test(self): self.assert_('/dset_szip' in self.h5file) arr = self.h5file.getNode('/dset_szip') filters = "Filters(complib='szip', shuffle=False, fletcher32=False)" self.assertEqual(repr(arr.filters), filters) def suite(): """Return a test suite consisting of all the test cases in the module.""" theSuite = unittest.TestSuite() niter = 1 for i in range(niter): theSuite.addTest(unittest.makeSuite(EnumTestCase)) theSuite.addTest(unittest.makeSuite(F64BETestCase)) theSuite.addTest(unittest.makeSuite(F64LETestCase)) theSuite.addTest(unittest.makeSuite(I64BETestCase)) theSuite.addTest(unittest.makeSuite(I64LETestCase)) theSuite.addTest(unittest.makeSuite(I32BETestCase)) theSuite.addTest(unittest.makeSuite(I32LETestCase)) theSuite.addTest(unittest.makeSuite(ChunkedCompoundTestCase)) theSuite.addTest(unittest.makeSuite(ContiguousCompoundTestCase)) theSuite.addTest(unittest.makeSuite(ContiguousCompoundAppendTestCase)) theSuite.addTest(unittest.makeSuite(ExtendibleTestCase)) theSuite.addTest(unittest.makeSuite(SzipTestCase)) return theSuite if __name__ == '__main__': unittest.main(defaultTest='suite') ## Local Variables: ## mode: python ## py-indent-offset: 4 ## tab-width: 4 ## fill-column: 72 ## End: