/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright by The HDF Group. * * Copyright by the Board of Trustees of the University of Illinois. * * All rights reserved. * * * * This file is part of HDF5. The full HDF5 copyright notice, including * * terms governing use, modification, and redistribution, is contained in * * the files COPYING and Copyright.html. COPYING can be found at the root * * of the source code distribution tree; Copyright.html can be found at the * * root level of an installed copy of the electronic HDF5 document set and * * is linked from the top-level documents page. It can also be found at * * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * * access to either file, you may request a copy from help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /*********************************************************** * * Test program: tfile * * Test the low-level file I/O features. * *************************************************************/ #include "hdf5.h" #include "testhdf5.h" #include "H5Bprivate.h" #include "H5Pprivate.h" /* * This file needs to access private information from the H5F package. * This file also needs to access the file testing code. */ #define H5F_PACKAGE #define H5F_TESTING #include "H5Fpkg.h" /* File access */ #define BAD_USERBLOCK_SIZE1 (hsize_t)1 #define BAD_USERBLOCK_SIZE2 (hsize_t)2 #define BAD_USERBLOCK_SIZE3 (hsize_t)3 #define BAD_USERBLOCK_SIZE4 (hsize_t)64 #define BAD_USERBLOCK_SIZE5 (hsize_t)511 #define BAD_USERBLOCK_SIZE6 (hsize_t)513 #define BAD_USERBLOCK_SIZE7 (hsize_t)6144 #define F1_USERBLOCK_SIZE (hsize_t)0 #define F1_OFFSET_SIZE sizeof(haddr_t) #define F1_LENGTH_SIZE sizeof(hsize_t) #define F1_SYM_LEAF_K 4 #define F1_SYM_INTERN_K 16 #define FILE1 "tfile1.h5" #define SFILE1 "sys_file1" #define F2_USERBLOCK_SIZE (hsize_t)512 #define F2_OFFSET_SIZE 8 #define F2_LENGTH_SIZE 8 #define F2_SYM_LEAF_K 8 #define F2_SYM_INTERN_K 32 #define F2_RANK 2 #define F2_DIM0 4 #define F2_DIM1 6 #define F2_DSET "dset" #define FILE2 "tfile2.h5" #define F3_USERBLOCK_SIZE (hsize_t)0 #define F3_OFFSET_SIZE F2_OFFSET_SIZE #define F3_LENGTH_SIZE F2_LENGTH_SIZE #define F3_SYM_LEAF_K F2_SYM_LEAF_K #define F3_SYM_INTERN_K F2_SYM_INTERN_K #define FILE3 "tfile3.h5" #define GRP_NAME "/group" #define DSET_NAME "dataset" #define ATTR_NAME "attr" #define TYPE_NAME "type" #define FILE4 "tfile4.h5" #define OBJ_ID_COUNT_0 0 #define OBJ_ID_COUNT_1 1 #define OBJ_ID_COUNT_2 2 #define OBJ_ID_COUNT_3 3 #define OBJ_ID_COUNT_4 4 #define OBJ_ID_COUNT_6 6 #define OBJ_ID_COUNT_8 8 #define GROUP1 "Group1" #define DSET1 "Dataset1" #define DSET2 "/Group1/Dataset2" #define TESTA_GROUPNAME "group" #define TESTA_DSETNAME "dataset" #define TESTA_ATTRNAME "attribute" #define TESTA_DTYPENAME "compound" #define TESTA_NAME_BUF_SIZE 64 #define TESTA_RANK 2 #define TESTA_NX 4 #define TESTA_NY 5 #define USERBLOCK_SIZE ((hsize_t) 512) /* Declarations for test_filespace_*() */ #define FILENAME_LEN 1024 /* length of file name */ #define CORE_INCREMENT 1024 /* core file */ #define FAMILY_SIZE 1024 /* family file */ #define DSETNAME "dset" /* Name of dataset */ #define NELMTS(X) (sizeof(X)/sizeof(X[0])) /* # of elements */ #define READ_OLD_BUFSIZE 1024 /* Buffer for holding file data */ #define FILE5 "tfile5.h5" /* Test file */ #define TEST_THRESHOLD10 10 /* Free space section threshold */ const char *OLD_FILENAME[] = { /* Files created under 1.6 branch and 1.8 branch */ "filespace_1_6.h5", /* 1.6 HDF5 file */ "filespace_1_8.h5" /* 1.8 HDF5 file */ }; const char *FILESPACE_NAME[] = { "tfilespace", NULL }; const char *FILENAME[] = { "sec2_tfile", "split_tfile", "stdio_tfile", "core_tfile", "family_tfile", NULL }; static void create_objects(hid_t, hid_t, hid_t *, hid_t *, hid_t *, hid_t *); static void test_obj_count_and_id(hid_t, hid_t, hid_t, hid_t, hid_t, hid_t); static void check_file_id(hid_t, hid_t); /**************************************************************** ** ** test_file_create(): Low-level file creation I/O test routine. ** ****************************************************************/ static void test_file_create(void) { hid_t fid1, fid2, fid3; /* HDF5 File IDs */ hid_t tmpl1, tmpl2; /*file creation templates */ hsize_t ublock; /*sizeof userblock */ size_t parm; /*file-creation parameters */ size_t parm2; /*file-creation parameters */ unsigned iparm; unsigned iparm2; herr_t ret; /*generic return value */ /* Output message about test being performed */ MESSAGE(5, ("Testing Low-Level File Creation I/O\n")); /* First ensure the file does not exist */ HDremove(FILE1); /* Try opening a non-existant file */ fid1 = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); VERIFY(fid1, FAIL, "H5Fopen"); /* Test create with various sequences of H5F_ACC_EXCL and */ /* H5F_ACC_TRUNC flags */ /* Create with H5F_ACC_EXCL */ fid1 = H5Fcreate(FILE1, H5F_ACC_EXCL, H5P_DEFAULT, H5P_DEFAULT); CHECK(fid1, FAIL, "H5Fcreate"); /* * try to create the same file with H5F_ACC_TRUNC. This should fail * because fid1 is the same file and is currently open. */ #ifndef H5_HAVE_FILE_VERSIONS fid2 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); VERIFY(fid2, FAIL, "H5Fcreate"); #endif /*H5_DONT_HAVE_FILE_VERSIONS*/ /* Close all files */ ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); #ifndef H5_HAVE_FILE_VERSIONS ret = H5Fclose(fid2); VERIFY(ret, FAIL, "H5Fclose"); /*file should not have been open */ #endif /*H5_HAVE_FILE_VERSIONS*/ /* * Try again with H5F_ACC_EXCL. This should fail because the file already * exists from the previous steps. */ fid1 = H5Fcreate(FILE1, H5F_ACC_EXCL, H5P_DEFAULT, H5P_DEFAULT); VERIFY(fid1, FAIL, "H5Fcreate"); /* Test create with H5F_ACC_TRUNC. This will truncate the existing file. */ fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); CHECK(fid1, FAIL, "H5Fcreate"); #ifndef H5_HAVE_FILE_VERSIONS /* * Try to truncate first file again. This should fail because fid1 is the * same file and is currently open. */ fid2 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); VERIFY(fid2, FAIL, "H5Fcreate"); /* * Try with H5F_ACC_EXCL. This should fail too because the file already * exists. */ fid2 = H5Fcreate(FILE1, H5F_ACC_EXCL, H5P_DEFAULT, H5P_DEFAULT); VERIFY(fid2, FAIL, "H5Fcreate"); #endif /*H5_HAVE_FILE_VERSIONS*/ /* Get the file-creation template */ tmpl1 = H5Fget_create_plist(fid1); CHECK(tmpl1, FAIL, "H5Fget_create_plist"); /* Get the file-creation parameters */ ret = H5Pget_userblock(tmpl1, &ublock); CHECK(ret, FAIL, "H5Pget_userblock"); VERIFY(ublock, F1_USERBLOCK_SIZE, "H5Pget_userblock"); ret = H5Pget_sizes(tmpl1, &parm, &parm2); CHECK(ret, FAIL, "H5Pget_sizes"); VERIFY(parm, F1_OFFSET_SIZE, "H5Pget_sizes"); VERIFY(parm2, F1_LENGTH_SIZE, "H5Pget_sizes"); ret = H5Pget_sym_k(tmpl1, &iparm, &iparm2); CHECK(ret, FAIL, "H5Pget_sym_k"); VERIFY(iparm, F1_SYM_INTERN_K, "H5Pget_sym_k"); VERIFY(iparm2, F1_SYM_LEAF_K, "H5Pget_sym_k"); /* Release file-creation template */ ret = H5Pclose(tmpl1); CHECK(ret, FAIL, "H5Pclose"); #ifdef LATER /* Double-check that the atom has been vaporized */ ret = H5Pclose(tmpl1); VERIFY(ret, FAIL, "H5Pclose"); #endif /* Create a new file with a non-standard file-creation template */ tmpl1 = H5Pcreate(H5P_FILE_CREATE); CHECK(tmpl1, FAIL, "H5Pcreate"); /* Try setting some bad userblock sizes */ H5E_BEGIN_TRY { ret = H5Pset_userblock(tmpl1, BAD_USERBLOCK_SIZE1); } H5E_END_TRY; VERIFY(ret, FAIL, "H5Pset_userblock"); H5E_BEGIN_TRY { ret = H5Pset_userblock(tmpl1, BAD_USERBLOCK_SIZE2); } H5E_END_TRY; VERIFY(ret, FAIL, "H5Pset_userblock"); H5E_BEGIN_TRY { ret = H5Pset_userblock(tmpl1, BAD_USERBLOCK_SIZE3); } H5E_END_TRY; VERIFY(ret, FAIL, "H5Pset_userblock"); H5E_BEGIN_TRY { ret = H5Pset_userblock(tmpl1, BAD_USERBLOCK_SIZE4); } H5E_END_TRY; VERIFY(ret, FAIL, "H5Pset_userblock"); H5E_BEGIN_TRY { ret = H5Pset_userblock(tmpl1, BAD_USERBLOCK_SIZE5); } H5E_END_TRY; VERIFY(ret, FAIL, "H5Pset_userblock"); H5E_BEGIN_TRY { ret = H5Pset_userblock(tmpl1, BAD_USERBLOCK_SIZE6); } H5E_END_TRY; VERIFY(ret, FAIL, "H5Pset_userblock"); H5E_BEGIN_TRY { ret = H5Pset_userblock(tmpl1, BAD_USERBLOCK_SIZE7); } H5E_END_TRY; VERIFY(ret, FAIL, "H5Pset_userblock"); /* Set the new file-creation parameters */ ret = H5Pset_userblock(tmpl1, F2_USERBLOCK_SIZE); CHECK(ret, FAIL, "H5Pset_userblock"); ret = H5Pset_sizes(tmpl1, (size_t)F2_OFFSET_SIZE, (size_t)F2_LENGTH_SIZE); CHECK(ret, FAIL, "H5Pset_sizes"); ret = H5Pset_sym_k(tmpl1, F2_SYM_INTERN_K, F2_SYM_LEAF_K); CHECK(ret, FAIL, "H5Pset_sym_k"); /* * Try to create second file, with non-standard file-creation template * params. */ fid2 = H5Fcreate(FILE2, H5F_ACC_TRUNC, tmpl1, H5P_DEFAULT); CHECK(fid2, FAIL, "H5Fcreate"); /* Release file-creation template */ ret = H5Pclose(tmpl1); CHECK(ret, FAIL, "H5Pclose"); /* Make certain we can create a dataset properly in the file with the userblock */ { hid_t dataset_id, dataspace_id; /* identifiers */ hsize_t dims[F2_RANK]; unsigned data[F2_DIM0][F2_DIM1]; unsigned i,j; /* Create the data space for the dataset. */ dims[0] = F2_DIM0; dims[1] = F2_DIM1; dataspace_id = H5Screate_simple(F2_RANK, dims, NULL); CHECK(dataspace_id, FAIL, "H5Screate_simple"); /* Create the dataset. */ dataset_id = H5Dcreate2(fid2, F2_DSET, H5T_NATIVE_UINT, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(dataset_id, FAIL, "H5Dcreate2"); for(i = 0; i < F2_DIM0; i++) for(j = 0; j < F2_DIM1; j++) data[i][j] = i * 10 + j; /* Write data to the new dataset */ ret = H5Dwrite(dataset_id, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data); CHECK(ret, FAIL, "H5Dwrite"); /* End access to the dataset and release resources used by it. */ ret = H5Dclose(dataset_id); CHECK(ret, FAIL, "H5Dclose"); /* Terminate access to the data space. */ ret = H5Sclose(dataspace_id); CHECK(ret, FAIL, "H5Sclose"); } /* Get the file-creation template */ tmpl1 = H5Fget_create_plist(fid2); CHECK(tmpl1, FAIL, "H5Fget_create_plist"); /* Get the file-creation parameters */ ret = H5Pget_userblock(tmpl1, &ublock); CHECK(ret, FAIL, "H5Pget_userblock"); VERIFY(ublock, F2_USERBLOCK_SIZE, "H5Pget_userblock"); ret = H5Pget_sizes(tmpl1, &parm, &parm2); CHECK(ret, FAIL, "H5Pget_sizes"); VERIFY(parm, F2_OFFSET_SIZE, "H5Pget_sizes"); VERIFY(parm2, F2_LENGTH_SIZE, "H5Pget_sizes"); ret = H5Pget_sym_k(tmpl1, &iparm, &iparm2); CHECK(ret, FAIL, "H5Pget_sym_k"); VERIFY(iparm, F2_SYM_INTERN_K, "H5Pget_sym_k"); VERIFY(iparm2, F2_SYM_LEAF_K, "H5Pget_sym_k"); /* Clone the file-creation template */ tmpl2 = H5Pcopy(tmpl1); CHECK(tmpl2, FAIL, "H5Pcopy"); /* Release file-creation template */ ret = H5Pclose(tmpl1); CHECK(ret, FAIL, "H5Pclose"); /* Set the new file-creation parameter */ ret = H5Pset_userblock(tmpl2, F3_USERBLOCK_SIZE); CHECK(ret, FAIL, "H5Pset_userblock"); /* * Try to create second file, with non-standard file-creation template * params */ fid3 = H5Fcreate(FILE3, H5F_ACC_TRUNC, tmpl2, H5P_DEFAULT); CHECK(fid3, FAIL, "H5Fcreate"); /* Release file-creation template */ ret = H5Pclose(tmpl2); CHECK(ret, FAIL, "H5Pclose"); /* Get the file-creation template */ tmpl1 = H5Fget_create_plist(fid3); CHECK(tmpl1, FAIL, "H5Fget_create_plist"); /* Get the file-creation parameters */ ret = H5Pget_userblock(tmpl1, &ublock); CHECK(ret, FAIL, "H5Pget_userblock"); VERIFY(ublock, F3_USERBLOCK_SIZE, "H5Pget_userblock"); ret = H5Pget_sizes(tmpl1, &parm, &parm2); CHECK(ret, FAIL, "H5Pget_sizes"); VERIFY(parm, F3_OFFSET_SIZE, "H5Pget_sizes"); VERIFY(parm2, F3_LENGTH_SIZE, "H5Pget_sizes"); ret = H5Pget_sym_k(tmpl1, &iparm, &iparm2); CHECK(ret, FAIL, "H5Pget_sym_k"); VERIFY(iparm, F3_SYM_INTERN_K, "H5Pget_sym_k"); VERIFY(iparm2, F3_SYM_LEAF_K, "H5Pget_sym_k"); /* Release file-creation template */ ret = H5Pclose(tmpl1); CHECK(ret, FAIL, "H5Pclose"); /* Close first file */ ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); /* Close second file */ ret = H5Fclose(fid2); CHECK(ret, FAIL, "H5Fclose"); /* Close third file */ ret = H5Fclose(fid3); CHECK(ret, FAIL, "H5Fclose"); } /* test_file_create() */ /**************************************************************** ** ** test_file_open(): Low-level file open I/O test routine. ** ****************************************************************/ static void test_file_open(void) { hid_t fid1, fid2; /*HDF5 File IDs */ hid_t did; /*dataset ID */ hid_t fapl_id; /*file access property list ID */ hid_t tmpl1; /*file creation templates */ hsize_t ublock; /*sizeof user block */ size_t parm; /*file-creation parameters */ size_t parm2; /*file-creation parameters */ unsigned iparm; unsigned iparm2; unsigned intent; herr_t ret; /*generic return value */ /* * Test single file open */ /* Output message about test being performed */ MESSAGE(5, ("Testing Low-Level File Opening I/O\n")); /* Open first file */ fid1 = H5Fopen(FILE2, H5F_ACC_RDWR, H5P_DEFAULT); CHECK(fid1, FAIL, "H5Fopen"); /* Get the intent */ ret = H5Fget_intent(fid1, &intent); CHECK(ret, FAIL, "H5Fget_intent"); VERIFY(intent, H5F_ACC_RDWR, "H5Fget_intent"); /* Get the file-creation template */ tmpl1 = H5Fget_create_plist(fid1); CHECK(tmpl1, FAIL, "H5Fget_create_plist"); /* Get the file-creation parameters */ ret = H5Pget_userblock(tmpl1, &ublock); CHECK(ret, FAIL, "H5Pget_userblock"); VERIFY(ublock, F2_USERBLOCK_SIZE, "H5Pget_userblock"); ret = H5Pget_sizes(tmpl1, &parm, &parm2); CHECK(ret, FAIL, "H5Pget_sizes"); VERIFY(parm, F2_OFFSET_SIZE, "H5Pget_sizes"); VERIFY(parm2, F2_LENGTH_SIZE, "H5Pget_sizes"); ret = H5Pget_sym_k(tmpl1, &iparm, &iparm2); CHECK(ret, FAIL, "H5Pget_sym_k"); VERIFY(iparm, F2_SYM_INTERN_K, "H5Pget_sym_k"); VERIFY(iparm2, F2_SYM_LEAF_K, "H5Pget_sym_k"); /* Release file-creation template */ ret = H5Pclose(tmpl1); CHECK(ret, FAIL, "H5Pclose"); /* Close first file */ ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); /* * Test two file opens: one is opened H5F_ACC_RDONLY and H5F_CLOSE_WEAK. * It's closed with an object left open. Then another is opened * H5F_ACC_RDWR, which should fail. */ /* Output message about test being performed */ MESSAGE(5, ("Testing 2 File Openings\n")); /* Create file access property list */ fapl_id = H5Pcreate(H5P_FILE_ACCESS); CHECK(fapl_id, FAIL, "H5Pcreate"); /* Set file close mode to H5F_CLOSE_WEAK */ ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_WEAK); CHECK(ret, FAIL, "H5Pset_fclose_degree"); /* Open file for first time */ fid1 = H5Fopen(FILE2, H5F_ACC_RDONLY, fapl_id); CHECK(fid1, FAIL, "H5Fopen"); /* Check the intent */ ret = H5Fget_intent(fid1, &intent); CHECK(ret, FAIL, "H5Fget_intent"); VERIFY(intent, H5F_ACC_RDONLY, "H5Fget_intent"); /* Open dataset */ did = H5Dopen2(fid1, F2_DSET, H5P_DEFAULT); CHECK(did, FAIL, "H5Dopen2"); /* Check that the intent works even if NULL is passed in */ ret = H5Fget_intent(fid1, NULL); CHECK(ret, FAIL, "H5Fget_intent"); /* Close first open */ ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); /* Open file for second time, which should fail. */ fid2 = H5Fopen(FILE2, H5F_ACC_RDWR, fapl_id); VERIFY(fid2, FAIL, "H5Fopen"); /* Check that the intent fails for an invalid ID */ ret = H5Fget_intent(fid1, &intent); VERIFY(ret, FAIL, "H5Fget_intent"); /* Close dataset from first open */ ret = H5Dclose(did); CHECK(ret, FAIL, "H5Dclose"); } /* test_file_open() */ /**************************************************************** ** ** test_file_close(): low-level file close test routine. ** It mainly tests behavior with close degree. ** *****************************************************************/ static void test_file_close(void) { hid_t fid1, fid2; hid_t fapl_id, access_id; hid_t dataset_id, group_id1, group_id2, group_id3; H5F_close_degree_t fc_degree; herr_t ret; /* Test behavior while opening file multiple times with different * file close degree value */ fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); CHECK(fid1, FAIL, "H5Fcreate"); fapl_id = H5Pcreate(H5P_FILE_ACCESS); CHECK(fapl_id, FAIL, "H5Pcreate"); ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG); CHECK(ret, FAIL, "H5Pset_fclose_degree"); ret = H5Pget_fclose_degree(fapl_id, &fc_degree); VERIFY(fc_degree, H5F_CLOSE_STRONG, "H5Pget_fclose_degree"); /* should fail */ fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id); VERIFY(fid2, FAIL, "H5Fopen"); ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_DEFAULT); CHECK(ret, FAIL, "H5Pset_fclose_degree"); /* should succeed */ fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id); CHECK(fid2, FAIL, "H5Fopen"); /* Close first open */ ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); /* Close second open */ ret = H5Fclose(fid2); CHECK(ret, FAIL, "H5Fclose"); /* Test behavior while opening file multiple times with different file * close degree */ fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); CHECK(fid1, FAIL, "H5Fcreate"); ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_WEAK); CHECK(ret, FAIL, "H5Pset_fclose_degree"); ret = H5Pget_fclose_degree(fapl_id, &fc_degree); VERIFY(fc_degree, H5F_CLOSE_WEAK, "H5Pget_fclose_degree"); /* should succeed */ fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id); CHECK(fid2, FAIL, "H5Fopen"); /* Close first open */ ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); /* Close second open */ ret = H5Fclose(fid2); CHECK(ret, FAIL, "H5Fclose"); /* Test behavior while opening file multiple times with file close * degree STRONG */ ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG); CHECK(ret, FAIL, "H5Pset_fclose_degree"); fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id); CHECK(fid1, FAIL, "H5Fcreate"); ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_WEAK); CHECK(ret, FAIL, "H5Pset_fclose_degree"); /* should fail */ fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id); VERIFY(fid2, FAIL, "H5Fopen"); ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG); CHECK(ret, FAIL, "H5Pset_fclose_degree"); /* should succeed */ fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id); CHECK(fid2, FAIL, "H5Fopen"); /* Create a dataset and a group in each file open respectively */ create_objects(fid1, fid2, NULL, NULL, NULL, NULL); /* Close first open */ ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); /* Close second open */ ret = H5Fclose(fid2); CHECK(ret, FAIL, "H5Fclose"); /* Test behavior while opening file multiple times with file close * degree SEMI */ ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI); CHECK(ret, FAIL, "H5Pset_fclose_degree"); fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id); CHECK(fid1, FAIL, "H5Fcreate"); ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_DEFAULT); CHECK(ret, FAIL, "H5Pset_fclose_degree"); /* should fail */ fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id); VERIFY(fid2, FAIL, "H5Fopen"); ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI); CHECK(ret, FAIL, "H5Pset_fclose_degree"); /* should succeed */ fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id); CHECK(fid2, FAIL, "H5Fopen"); /* Create a dataset and a group in each file open respectively */ create_objects(fid1, fid2, &dataset_id, &group_id1, &group_id2, &group_id3); /* Close first open, should fail since it is SEMI and objects are * still open. */ ret = H5Fclose(fid1); VERIFY(ret, FAIL, "H5Fclose"); /* Close second open, should fail since it is SEMI and objects are * still open. */ ret = H5Fclose(fid2); VERIFY(ret, FAIL, "H5Fclose"); ret = H5Dclose(dataset_id); CHECK(ret, FAIL, "H5Dclose"); /* Close first open */ ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); ret = H5Gclose(group_id1); CHECK(ret, FAIL, "H5Gclose"); ret = H5Gclose(group_id2); CHECK(ret, FAIL, "H5Gclose"); /* Close second open, should fail since it is SEMI and one group ID is * still open. */ ret = H5Fclose(fid2); VERIFY(ret, FAIL, "H5Fclose"); /* Same check with H5Idec_ref() (should fail also) */ ret = H5Idec_ref(fid2); VERIFY(ret, FAIL, "H5Idec_ref"); ret = H5Gclose(group_id3); CHECK(ret, FAIL, "H5Gclose"); /* Close second open again. Should succeed. */ ret = H5Fclose(fid2); CHECK(ret, FAIL, "H5Fclose"); /* Test behavior while opening file multiple times with file close * degree WEAK */ ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_WEAK); CHECK(ret, FAIL, "H5Pset_fclose_degree"); fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id); CHECK(fid1, FAIL, "H5Fcreate"); ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI); CHECK(ret, FAIL, "H5Pset_fclose_degree"); /* should fail */ fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id); VERIFY(fid2, FAIL, "H5Fopen"); ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_DEFAULT); CHECK(ret, FAIL, "H5Pset_fclose_degree"); /* should succeed */ fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id); CHECK(fid2, FAIL, "H5Fopen"); /* Create a dataset and a group in each file open respectively */ create_objects(fid1, fid2, &dataset_id, &group_id1, &group_id2, &group_id3); /* Create more new files and test object count and ID list functions */ test_obj_count_and_id(fid1, fid2, dataset_id, group_id1, group_id2, group_id3); /* Close first open */ ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); /* Close second open. File will be finally closed after all objects * are closed. */ ret = H5Fclose(fid2); CHECK(ret, FAIL, "H5Fclose"); ret = H5Dclose(dataset_id); CHECK(ret, FAIL, "H5Dclose"); ret = H5Gclose(group_id1); CHECK(ret, FAIL, "H5Gclose"); ret = H5Gclose(group_id2); CHECK(ret, FAIL, "H5Gclose"); ret = H5Gclose(group_id3); CHECK(ret, FAIL, "H5Gclose"); /* Test behavior while opening file multiple times with file close * degree DEFAULT */ ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_DEFAULT); CHECK(ret, FAIL, "H5Pset_fclose_degree"); fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id); CHECK(fid1, FAIL, "H5Fcreate"); ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI); CHECK(ret, FAIL, "H5Pset_fclose_degree"); /* should fail */ fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id); VERIFY(fid2, FAIL, "H5Fopen"); ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_DEFAULT); CHECK(ret, FAIL, "H5Pset_fclose_degree"); /* should succeed */ fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id); CHECK(fid2, FAIL, "H5Fopen"); /* Create a dataset and a group in each file open respectively */ create_objects(fid1, fid2, &dataset_id, &group_id1, &group_id2, &group_id3); access_id = H5Fget_access_plist(fid1); CHECK(access_id, FAIL, "H5Fget_access_plist"); ret= H5Pget_fclose_degree(access_id, &fc_degree); CHECK(ret, FAIL, "H5Pget_fclose_degree"); switch(fc_degree) { case H5F_CLOSE_STRONG: /* Close first open */ ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); /* Close second open */ ret = H5Fclose(fid2); CHECK(ret, FAIL, "H5Fclose"); break; case H5F_CLOSE_SEMI: /* Close first open */ ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); ret = H5Dclose(dataset_id); CHECK(ret, FAIL, "H5Dclose"); ret = H5Gclose(group_id1); CHECK(ret, FAIL, "H5Gclose"); ret = H5Gclose(group_id2); CHECK(ret, FAIL, "H5Gclose"); ret = H5Gclose(group_id3); CHECK(ret, FAIL, "H5Gclose"); /* Close second open */ ret = H5Fclose(fid2); CHECK(ret, FAIL, "H5Fclose"); break; case H5F_CLOSE_WEAK: /* Close first open */ ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); /* Close second open */ ret = H5Fclose(fid2); CHECK(ret, FAIL, "H5Fclose"); ret = H5Dclose(dataset_id); CHECK(ret, FAIL, "H5Dclose"); ret = H5Gclose(group_id1); CHECK(ret, FAIL, "H5Gclose"); ret = H5Gclose(group_id2); CHECK(ret, FAIL, "H5Gclose"); ret = H5Gclose(group_id3); CHECK(ret, FAIL, "H5Gclose"); break; default: CHECK(fc_degree, H5F_CLOSE_DEFAULT, "H5Pget_fclose_degree"); break; } /* Close file access property list */ ret = H5Pclose(fapl_id); CHECK(ret, FAIL, "H5Pclose"); ret = H5Pclose(access_id); CHECK(ret, FAIL, "H5Pclose"); } /**************************************************************** ** ** create_objects(): routine called by test_file_close to create ** a dataset and a group in file. ** ****************************************************************/ static void create_objects(hid_t fid1, hid_t fid2, hid_t *ret_did, hid_t *ret_gid1, hid_t *ret_gid2, hid_t *ret_gid3) { ssize_t oid_count; herr_t ret; /* Check reference counts of file IDs and opened object IDs. * The verification is hard-coded. If in any case, this testing * is changed, remember to check this part and update the macros. */ { oid_count = H5Fget_obj_count(fid1, H5F_OBJ_ALL); CHECK(oid_count, FAIL, "H5Fget_obj_count"); VERIFY(oid_count, OBJ_ID_COUNT_2, "H5Fget_obj_count"); oid_count = H5Fget_obj_count(fid1, H5F_OBJ_DATASET|H5F_OBJ_GROUP|H5F_OBJ_DATATYPE|H5F_OBJ_ATTR); CHECK(oid_count, FAIL, "H5Fget_obj_count"); VERIFY(oid_count, OBJ_ID_COUNT_0, "H5Fget_obj_count"); oid_count = H5Fget_obj_count(fid2, H5F_OBJ_ALL); CHECK(oid_count, FAIL, "H5Fget_obj_count"); VERIFY(oid_count, OBJ_ID_COUNT_2, "H5Fget_obj_count"); oid_count = H5Fget_obj_count(fid2, H5F_OBJ_DATASET|H5F_OBJ_GROUP|H5F_OBJ_DATATYPE|H5F_OBJ_ATTR); CHECK(oid_count, FAIL, "H5Fget_obj_count"); VERIFY(oid_count, OBJ_ID_COUNT_0, "H5Fget_obj_count"); } /* create a dataset in the first file open */ { hid_t dataset_id, dataspace_id; /* identifiers */ hsize_t dims[F2_RANK]; unsigned data[F2_DIM0][F2_DIM1]; unsigned i,j; /* Create the data space for the dataset. */ dims[0] = F2_DIM0; dims[1] = F2_DIM1; dataspace_id = H5Screate_simple(F2_RANK, dims, NULL); CHECK(dataspace_id, FAIL, "H5Screate_simple"); /* Create the dataset. */ dataset_id = H5Dcreate2(fid1, "/dset", H5T_NATIVE_UINT, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(dataset_id, FAIL, "H5Dcreate2"); for(i = 0; i < F2_DIM0; i++) for(j = 0; j < F2_DIM1; j++) data[i][j] = i * 10 + j; /* Write data to the new dataset */ ret = H5Dwrite(dataset_id, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data); CHECK(ret, FAIL, "H5Dwrite"); if(ret_did != NULL) *ret_did = dataset_id; /* Terminate access to the data space. */ ret = H5Sclose(dataspace_id); CHECK(ret, FAIL, "H5Sclose"); } /* Create a group in the second file open */ { hid_t gid1, gid2, gid3; gid1 = H5Gcreate2(fid2, "/group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(gid1, FAIL, "H5Gcreate2"); if(ret_gid1 != NULL) *ret_gid1 = gid1; gid2 = H5Gopen2(fid2, "/group", H5P_DEFAULT); CHECK(gid2, FAIL, "H5Gopen2"); if(ret_gid2 != NULL) *ret_gid2 = gid2; gid3 = H5Gopen2(fid2, "/group", H5P_DEFAULT); CHECK(gid3, FAIL, "H5Gopen2"); if(ret_gid3 != NULL) *ret_gid3 = gid3; } /* Check reference counts of file IDs and opened object IDs. * The verification is hard-coded. If in any case, this testing * is changed, remember to check this part and update the macros. */ { oid_count = H5Fget_obj_count(fid1, H5F_OBJ_ALL); CHECK(oid_count, FAIL, "H5Fget_obj_count"); VERIFY(oid_count, OBJ_ID_COUNT_6, "H5Fget_obj_count"); oid_count = H5Fget_obj_count(fid1, H5F_OBJ_DATASET|H5F_OBJ_GROUP|H5F_OBJ_DATATYPE|H5F_OBJ_ATTR); CHECK(oid_count, FAIL, "H5Fget_obj_count"); VERIFY(oid_count, OBJ_ID_COUNT_4, "H5Fget_obj_count"); oid_count = H5Fget_obj_count(fid2, H5F_OBJ_ALL); CHECK(oid_count, FAIL, "H5Fget_obj_count"); VERIFY(oid_count, OBJ_ID_COUNT_6, "H5Fget_obj_count"); oid_count = H5Fget_obj_count(fid2, H5F_OBJ_DATASET|H5F_OBJ_GROUP|H5F_OBJ_DATATYPE|H5F_OBJ_ATTR); CHECK(oid_count, FAIL, "H5Fget_obj_count"); VERIFY(oid_count, OBJ_ID_COUNT_4, "H5Fget_obj_count"); } } /**************************************************************** ** ** test_get_file_id(): Test H5Iget_file_id() ** *****************************************************************/ static void test_get_file_id(void) { hid_t fid, fid2, fid3; hid_t datatype_id, dataset_id, dataspace_id, group_id, attr_id; hid_t plist; hsize_t dims[F2_RANK]; unsigned intent; herr_t ret; /* Create a file */ fid = H5Fcreate(FILE4, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); CHECK(fid, FAIL, "H5Fcreate"); /* Check the intent */ ret = H5Fget_intent(fid, &intent); CHECK(ret, FAIL, "H5Fget_intent"); VERIFY(intent, H5F_ACC_RDWR, "H5Fget_intent"); /* Test H5Iget_file_id() */ check_file_id(fid, fid); /* Create a group in the file. Make a duplicated file ID from the group. * And close this duplicated ID */ group_id = H5Gcreate2(fid, GRP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(group_id, FAIL, "H5Gcreate2"); /* Test H5Iget_file_id() */ check_file_id(fid, group_id); /* Close the file and get file ID from the group ID */ ret = H5Fclose(fid); CHECK(ret, FAIL, "H5Fclose"); /* Test H5Iget_file_id() */ check_file_id(-1, group_id); ret = H5Gclose(group_id); CHECK(ret, FAIL, "H5Gclose"); /* Open the file again. Test H5Iget_file_id() */ fid = H5Fopen(FILE4, H5F_ACC_RDWR, H5P_DEFAULT); CHECK(fid, FAIL, "H5Fcreate"); group_id = H5Gopen2(fid, GRP_NAME, H5P_DEFAULT); CHECK(group_id, FAIL, "H5Gopen2"); /* Test H5Iget_file_id() */ check_file_id(fid, group_id); /* Open the file for second time. Test H5Iget_file_id() */ fid3 = H5Freopen(fid); CHECK(fid3, FAIL, "H5Freopen"); /* Test H5Iget_file_id() */ check_file_id(fid3, fid3); ret = H5Fclose(fid3); CHECK(ret, FAIL, "H5Fclose"); /* Create a dataset in the group. Make a duplicated file ID from the * dataset. And close this duplicated ID. */ dims[0] = F2_DIM0; dims[1] = F2_DIM1; dataspace_id = H5Screate_simple(F2_RANK, dims, NULL); CHECK(dataspace_id, FAIL, "H5Screate_simple"); dataset_id = H5Dcreate2(group_id, DSET_NAME, H5T_NATIVE_INT, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(dataset_id, FAIL, "H5Dcreate2"); /* Test H5Iget_file_id() */ check_file_id(fid, dataset_id); /* Create an attribute for the dataset. Make a duplicated file ID from * this attribute. And close it. */ attr_id = H5Acreate2(dataset_id, ATTR_NAME, H5T_NATIVE_INT, dataspace_id, H5P_DEFAULT, H5P_DEFAULT); CHECK(ret, FAIL, "H5Acreate2"); /* Test H5Iget_file_id() */ check_file_id(fid, attr_id); /* Create a named datatype. Make a duplicated file ID from * this attribute. And close it. */ datatype_id = H5Tcopy(H5T_NATIVE_INT); CHECK(ret, FAIL, "H5Tcopy"); ret = H5Tcommit2(fid, TYPE_NAME, datatype_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(ret, FAIL, "H5Tcommit2"); /* Test H5Iget_file_id() */ check_file_id(fid, datatype_id); /* Create a property list and try to get file ID from it. * Supposed to fail. */ plist = H5Pcreate(H5P_FILE_ACCESS); CHECK(plist, FAIL, "H5Pcreate"); H5E_BEGIN_TRY { fid2 = H5Iget_file_id(plist); } H5E_END_TRY; VERIFY(fid2, FAIL, "H5Iget_file_id"); /* Close objects */ ret = H5Tclose(datatype_id); CHECK(ret, FAIL, "H5Tclose"); ret = H5Aclose(attr_id); CHECK(ret, FAIL, "H5Aclose"); ret = H5Sclose(dataspace_id); CHECK(ret, FAIL, "H5Sclose"); ret = H5Dclose(dataset_id); CHECK(ret, FAIL, "H5Dclose"); ret = H5Gclose(group_id); CHECK(ret, FAIL, "H5Gclose"); ret = H5Fclose(fid); CHECK(ret, FAIL, "H5Fclose"); } /**************************************************************** ** ** check_file_id(): Internal function of test_get_file_id() ** *****************************************************************/ static void check_file_id(hid_t fid, hid_t object_id) { hid_t new_fid; herr_t ret; /* Return a duplicated file ID even not expecting user to do it. * And close this duplicated ID */ new_fid = H5Iget_file_id(object_id); if(fid >=0) VERIFY(new_fid, fid, "H5Iget_file_id"); else CHECK(new_fid, FAIL, "H5Iget_file_id"); ret = H5Fclose(new_fid); CHECK(ret, FAIL, "H5Fclose"); } /**************************************************************** ** ** test_obj_count_and_id(): test object count and ID list functions. ** ****************************************************************/ static void test_obj_count_and_id(hid_t fid1, hid_t fid2, hid_t did, hid_t gid1, hid_t gid2, hid_t gid3) { hid_t fid3, fid4; ssize_t oid_count, ret_count; herr_t ret; /* Create two new files */ fid3 = H5Fcreate(FILE2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); CHECK(fid3, FAIL, "H5Fcreate"); fid4 = H5Fcreate(FILE3, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); CHECK(fid4, FAIL, "H5Fcreate"); /* test object count of all files IDs open */ oid_count = H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_FILE); CHECK(oid_count, FAIL, "H5Fget_obj_count"); VERIFY(oid_count, OBJ_ID_COUNT_4, "H5Fget_obj_count"); /* test object count of all datasets open */ oid_count = H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_DATASET); CHECK(oid_count, FAIL, "H5Fget_obj_count"); VERIFY(oid_count, OBJ_ID_COUNT_1, "H5Fget_obj_count"); /* test object count of all groups open */ oid_count = H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_GROUP); CHECK(oid_count, FAIL, "H5Fget_obj_count"); VERIFY(oid_count, OBJ_ID_COUNT_3, "H5Fget_obj_count"); /* test object count of all named datatypes open */ oid_count = H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_DATATYPE); CHECK(oid_count, FAIL, "H5Fget_obj_count"); VERIFY(oid_count, OBJ_ID_COUNT_0, "H5Fget_obj_count"); /* test object count of all attributes open */ oid_count = H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_ATTR); CHECK(oid_count, FAIL, "H5Fget_obj_count"); VERIFY(oid_count, OBJ_ID_COUNT_0, "H5Fget_obj_count"); /* test object count of all objects currently open */ oid_count = H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_ALL); CHECK(oid_count, FAIL, "H5Fget_obj_count"); VERIFY(oid_count, OBJ_ID_COUNT_8, "H5Fget_obj_count"); { hid_t *oid_list; int i; H5I_type_t id_type; oid_list = (hid_t*)calloc((size_t)oid_count, sizeof(hid_t)); if(oid_list != NULL) { ret_count = H5Fget_obj_ids(H5F_OBJ_ALL, H5F_OBJ_ALL, (size_t)oid_count, oid_list); CHECK(ret_count, FAIL, "H5Fget_obj_ids"); } for(i=0; i 0.0) { /* Output message about test being performed */ MESSAGE(1, ("Testing to verify that nothing is written if nothing is changed: This test is skipped on this system because the modification time from stat is the same as the last access time (We know OpenVMS behaves in this way).\n")); } /* end if */ else { hid_t file_id; /* HDF5 File ID */ /* Create and Close a HDF5 File */ file_id = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); CHECK(file_id, FAIL, "H5Fcreate"); ret = H5Fclose(file_id); CHECK(ret, FAIL, "H5Fclose"); /* Determine File's Initial Timestamp */ ret = HDstat(FILE1, &sb1); VERIFY(ret, 0, "HDfstat"); /* Wait for 2 seconds */ /* (This ensures a system time difference between the two file accesses) */ HDsleep(2); /* Open and Close File With Read/Write Permission */ file_id = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); CHECK(file_id, FAIL, "H5Fopen"); ret = H5Fclose(file_id); CHECK(ret, FAIL, "H5Fclose"); /* Determine File's New Timestamp */ ret = HDstat(FILE1, &sb2); VERIFY(ret, 0, "HDstat"); /* Ensure That Timestamps Are Equal */ diff = HDdifftime(sb2.st_mtime, sb1.st_mtime); ret = (diff > 0.0); VERIFY(ret, 0, "Timestamp"); } /* end else */ } /* end test_rw_noupdate() */ /**************************************************************** ** ** test_userblock_alignment_helper1(): helper routine for ** test_userblock_alignment() test, to handle common testing ** ** Programmer: Quincey Koziol ** koziol@hdfgroup.org ** Septmber 10, 2009 ** *****************************************************************/ static int test_userblock_alignment_helper1(hid_t fcpl, hid_t fapl) { hid_t fid; /* File ID */ int curr_num_errs = GetTestNumErrs(); /* Retrieve the current # of errors */ herr_t ret; /* Generic return value */ /* Create a file with FAPL & FCPL */ fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, fcpl, fapl); CHECK(fid, FAIL, "H5Fcreate"); /* Only proceed further if file ID is OK */ if(fid > 0) { hid_t gid; /* Group ID */ hid_t sid; /* Dataspace ID */ hid_t did; /* Dataset ID */ int val = 2; /* Dataset value */ /* Create a group */ gid = H5Gcreate2(fid, "group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(gid, FAIL, "H5Gcreate2"); /* Create a dataset */ sid = H5Screate(H5S_SCALAR); CHECK(sid, FAIL, "H5Screate"); did = H5Dcreate2(gid, "dataset", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(did, FAIL, "H5Dcreate2"); /* Close dataspace */ ret = H5Sclose(sid); CHECK(ret, FAIL, "H5Sclose"); /* Write value to dataset */ ret = H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &val); CHECK(ret, FAIL, "H5Dwrite"); /* Close dataset */ ret = H5Dclose(did); CHECK(ret, FAIL, "H5Dclose"); /* Close group */ ret = H5Gclose(gid); CHECK(ret, FAIL, "H5Gclose"); /* Close file */ ret = H5Fclose(fid); CHECK(ret, FAIL, "H5Fclose"); } /* end if */ return((GetTestNumErrs() == curr_num_errs) ? 0 : -1); } /* end test_userblock_alignment_helper1() */ /**************************************************************** ** ** test_userblock_alignment_helper2(): helper routine for ** test_userblock_alignment() test, to handle common testing ** ** Programmer: Quincey Koziol ** koziol@hdfgroup.org ** Septmber 10, 2009 ** *****************************************************************/ static int test_userblock_alignment_helper2(hid_t fapl, hbool_t open_rw) { hid_t fid; /* File ID */ int curr_num_errs = GetTestNumErrs(); /* Retrieve the current # of errors */ herr_t ret; /* Generic return value */ /* Re-open file */ fid = H5Fopen(FILE1, (open_rw ? H5F_ACC_RDWR : H5F_ACC_RDONLY), fapl); CHECK(fid, FAIL, "H5Fopen"); /* Only proceed further if file ID is OK */ if(fid > 0) { hid_t gid; /* Group ID */ hid_t did; /* Dataset ID */ int val = -1; /* Dataset value */ /* Open group */ gid = H5Gopen2(fid, "group1", H5P_DEFAULT); CHECK(gid, FAIL, "H5Gopen2"); /* Open dataset */ did = H5Dopen2(gid, "dataset", H5P_DEFAULT); CHECK(did, FAIL, "H5Dopen2"); /* Read value from dataset */ ret = H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &val); CHECK(ret, FAIL, "H5Dread"); VERIFY(val, 2, "H5Dread"); /* Close dataset */ ret = H5Dclose(did); CHECK(ret, FAIL, "H5Dclose"); /* Only create new objects if file is open R/W */ if(open_rw) { hid_t gid2; /* Group ID */ /* Create a new group */ gid2 = H5Gcreate2(gid, "group2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(gid, FAIL, "H5Gcreate2"); /* Close new group */ ret = H5Gclose(gid2); CHECK(ret, FAIL, "H5Gclose"); } /* end if */ /* Close group */ ret = H5Gclose(gid); CHECK(ret, FAIL, "H5Gclose"); /* Close file */ ret = H5Fclose(fid); CHECK(ret, FAIL, "H5Fclose"); } /* end if */ return((GetTestNumErrs() == curr_num_errs) ? 0 : -1); } /* end test_userblock_alignment_helper2() */ /**************************************************************** ** ** test_userblock_alignment(): low-level file test routine. ** This test checks to ensure that files with both a userblock and a ** object [allocation] alignment size set interact properly. ** ** Programmer: Quincey Koziol ** koziol@hdfgroup.org ** Septmber 8, 2009 ** *****************************************************************/ static void test_userblock_alignment(void) { hid_t fid; /* File ID */ hid_t fcpl; /* File creation property list ID */ hid_t fapl; /* File access property list ID */ herr_t ret; /* Generic return value */ /* Output message about test being performed */ MESSAGE(5, ("Testing that non-zero userblocks and object alignment interact correctly.\n")); /* Case 1: * Userblock size = 0, alignment != 0 * Outcome: * Should succeed */ /* Create file creation property list with user block */ fcpl = H5Pcreate(H5P_FILE_CREATE); CHECK(fcpl, FAIL, "H5Pcreate"); ret = H5Pset_userblock(fcpl, (hsize_t)0); CHECK(ret, FAIL, "H5Pset_userblock"); /* Create file access property list with alignment */ fapl = H5Pcreate(H5P_FILE_ACCESS); CHECK(fapl, FAIL, "H5Pcreate"); ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)3); CHECK(ret, FAIL, "H5Pset_alignment"); /* Call helper routines to perform file manipulations */ ret = test_userblock_alignment_helper1(fcpl, fapl); CHECK(ret, FAIL, "test_userblock_alignment_helper1"); ret = test_userblock_alignment_helper2(fapl, TRUE); CHECK(ret, FAIL, "test_userblock_alignment_helper2"); /* Release property lists */ ret = H5Pclose(fcpl); CHECK(ret, FAIL, "H5Pclose"); ret = H5Pclose(fapl); CHECK(ret, FAIL, "H5Pclose"); /* Case 2: * Userblock size = 512, alignment = 16 * (userblock is integral mult. of alignment) * Outcome: * Should succeed */ /* Create file creation property list with user block */ fcpl = H5Pcreate(H5P_FILE_CREATE); CHECK(fcpl, FAIL, "H5Pcreate"); ret = H5Pset_userblock(fcpl, (hsize_t)512); CHECK(ret, FAIL, "H5Pset_userblock"); /* Create file access property list with alignment */ fapl = H5Pcreate(H5P_FILE_ACCESS); CHECK(fapl, FAIL, "H5Pcreate"); ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)16); CHECK(ret, FAIL, "H5Pset_alignment"); /* Call helper routines to perform file manipulations */ ret = test_userblock_alignment_helper1(fcpl, fapl); CHECK(ret, FAIL, "test_userblock_alignment_helper1"); ret = test_userblock_alignment_helper2(fapl, TRUE); CHECK(ret, FAIL, "test_userblock_alignment_helper2"); /* Release property lists */ ret = H5Pclose(fcpl); CHECK(ret, FAIL, "H5Pclose"); ret = H5Pclose(fapl); CHECK(ret, FAIL, "H5Pclose"); /* Case 3: * Userblock size = 512, alignment = 512 * (userblock is equal to alignment) * Outcome: * Should succeed */ /* Create file creation property list with user block */ fcpl = H5Pcreate(H5P_FILE_CREATE); CHECK(fcpl, FAIL, "H5Pcreate"); ret = H5Pset_userblock(fcpl, (hsize_t)512); CHECK(ret, FAIL, "H5Pset_userblock"); /* Create file access property list with alignment */ fapl = H5Pcreate(H5P_FILE_ACCESS); CHECK(fapl, FAIL, "H5Pcreate"); ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)512); CHECK(ret, FAIL, "H5Pset_alignment"); /* Call helper routines to perform file manipulations */ ret = test_userblock_alignment_helper1(fcpl, fapl); CHECK(ret, FAIL, "test_userblock_alignment_helper1"); ret = test_userblock_alignment_helper2(fapl, TRUE); CHECK(ret, FAIL, "test_userblock_alignment_helper2"); /* Release property lists */ ret = H5Pclose(fcpl); CHECK(ret, FAIL, "H5Pclose"); ret = H5Pclose(fapl); CHECK(ret, FAIL, "H5Pclose"); /* Case 4: * Userblock size = 512, alignment = 3 * (userblock & alignment each individually valid, but userblock is * non-integral multiple of alignment) * Outcome: * Should fail at file creation */ /* Create file creation property list with user block */ fcpl = H5Pcreate(H5P_FILE_CREATE); CHECK(fcpl, FAIL, "H5Pcreate"); ret = H5Pset_userblock(fcpl, (hsize_t)512); CHECK(ret, FAIL, "H5Pset_userblock"); /* Create file access property list with alignment */ fapl = H5Pcreate(H5P_FILE_ACCESS); CHECK(fapl, FAIL, "H5Pcreate"); ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)3); CHECK(ret, FAIL, "H5Pset_alignment"); /* Create a file with FAPL & FCPL */ H5E_BEGIN_TRY { fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, fcpl, fapl); } H5E_END_TRY; VERIFY(fid, FAIL, "H5Fcreate"); /* Release property lists */ ret = H5Pclose(fcpl); CHECK(ret, FAIL, "H5Pclose"); ret = H5Pclose(fapl); CHECK(ret, FAIL, "H5Pclose"); /* Case 5: * Userblock size = 512, alignment = 1024 * (userblock & alignment each individually valid, but userblock is * less than alignment) * Outcome: * Should fail at file creation */ /* Create file creation property list with user block */ fcpl = H5Pcreate(H5P_FILE_CREATE); CHECK(fcpl, FAIL, "H5Pcreate"); ret = H5Pset_userblock(fcpl, (hsize_t)512); CHECK(ret, FAIL, "H5Pset_userblock"); /* Create file access property list with alignment */ fapl = H5Pcreate(H5P_FILE_ACCESS); CHECK(fapl, FAIL, "H5Pcreate"); ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)1024); CHECK(ret, FAIL, "H5Pset_alignment"); /* Create a file with FAPL & FCPL */ H5E_BEGIN_TRY { fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, fcpl, fapl); } H5E_END_TRY; VERIFY(fid, FAIL, "H5Fcreate"); /* Release property lists */ ret = H5Pclose(fcpl); CHECK(ret, FAIL, "H5Pclose"); ret = H5Pclose(fapl); CHECK(ret, FAIL, "H5Pclose"); /* Case 6: * File created with: * Userblock size = 512, alignment = 512 * File re-opened for read-only & read-write access with: * Userblock size = 512, alignment = 1024 * Outcome: * Should succeed */ /* Create file creation property list with user block */ fcpl = H5Pcreate(H5P_FILE_CREATE); CHECK(fcpl, FAIL, "H5Pcreate"); ret = H5Pset_userblock(fcpl, (hsize_t)512); CHECK(ret, FAIL, "H5Pset_userblock"); /* Create file access property list with alignment */ fapl = H5Pcreate(H5P_FILE_ACCESS); CHECK(fapl, FAIL, "H5Pcreate"); ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)512); CHECK(ret, FAIL, "H5Pset_alignment"); /* Call helper routines to perform file manipulations */ ret = test_userblock_alignment_helper1(fcpl, fapl); CHECK(ret, FAIL, "test_userblock_alignment_helper1"); /* Change alignment in FAPL */ ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)1024); CHECK(ret, FAIL, "H5Pset_alignment"); /* Call helper routines to perform file manipulations */ ret = test_userblock_alignment_helper2(fapl, FALSE); CHECK(ret, FAIL, "test_userblock_alignment_helper2"); ret = test_userblock_alignment_helper2(fapl, TRUE); CHECK(ret, FAIL, "test_userblock_alignment_helper2"); /* Release property lists */ ret = H5Pclose(fcpl); CHECK(ret, FAIL, "H5Pclose"); ret = H5Pclose(fapl); CHECK(ret, FAIL, "H5Pclose"); } /* end test_userblock_alignment() */ /**************************************************************** ** ** test_free_sections(): ** This routine does the actual work of checking information for ** free space sections available in a file in various situations. ** *****************************************************************/ static void test_free_sections(hid_t fapl, char *fname) { hid_t file; /* File ID */ hid_t fcpl; /* File creation property list template */ hssize_t free_space; /* Amount of free space in file */ hid_t dspace; /* Dataspace ID */ hid_t dset; /* Dataset ID */ hid_t dcpl; /* Dataset creation property list */ unsigned u; /* Local index variable */ char name[32]; /* Dataset name */ hssize_t nsects; /* # of free-space sections */ hssize_t saved_nsects; /* saved copy for the # of free-space sections */ int i; /* local index variable */ hsize_t total; /* sum of the free-space section sizes */ hsize_t last_size; /* size of last free-space section */ H5F_sect_info_t *sect_info; /* array to hold the free-space information */ H5F_sect_info_t *saved_sect_info; /* array to hold the free-space information */ herr_t ret; /* return value */ /* Create file-creation template */ fcpl = H5Pcreate(H5P_FILE_CREATE); CHECK(fcpl, FAIL, "H5Pcreate"); /* Set file space strategy and free space section threshold */ ret = H5Pset_file_space(fcpl, H5F_FILE_SPACE_ALL_PERSIST, (hsize_t)0); CHECK(ret, FAIL, "H5Pget_file_space"); /* Create the file */ file = H5Fcreate(fname, H5F_ACC_TRUNC, fcpl, fapl); CHECK(file, FAIL, "H5Fcreate"); /* Create dataspace for datasets */ dspace = H5Screate(H5S_SCALAR); CHECK(dspace, FAIL, "H5Screate"); /* Create a dataset creation property list */ dcpl = H5Pcreate(H5P_DATASET_CREATE); CHECK(dcpl, FAIL, "H5Pcreate"); /* Set the space allocation time to early */ ret = H5Pset_alloc_time(dcpl, H5D_ALLOC_TIME_EARLY); CHECK(ret, FAIL, "H5Pset_alloc_time"); /* Create datasets in file */ for(u = 0; u < 10; u++) { sprintf(name, "Dataset %u", u); dset = H5Dcreate2(file, name, H5T_STD_U32LE, dspace, H5P_DEFAULT, dcpl, H5P_DEFAULT); CHECK(dset, FAIL, "H5Dcreate2"); ret = H5Dclose(dset); CHECK(ret, FAIL, "H5Dclose"); } /* end for */ /* Close dataspace */ ret = H5Sclose(dspace); CHECK(ret, FAIL, "H5Sclose"); /* Close dataset creation property list */ ret = H5Pclose(dcpl); CHECK(ret, FAIL, "H5Pclose"); /* Delete odd-numbered datasets in file */ for(u = 0; u < 10; u++) { sprintf(name, "Dataset %u", u); if(u % 2) { ret = H5Ldelete(file, name, H5P_DEFAULT); CHECK(ret, FAIL, "H5Ldelete"); } /* end if */ } /* end for */ /* Close file */ ret = H5Fclose(file); CHECK(ret, FAIL, "H5Fclose"); /* Re-open the file with read-only permission */ file = H5Fopen(fname, H5F_ACC_RDONLY, fapl); CHECK_I(file, "H5Fopen"); /* Get the amount of free space in the file */ free_space = H5Fget_freespace(file); CHECK(free_space, FAIL, "H5Fget_freespace"); /* Get the # of free-space sections in the file */ saved_nsects = H5Fget_free_sections(file, H5FD_MEM_DEFAULT, (size_t)0, NULL); CHECK(saved_nsects, FAIL, "H5Fget_free_sections"); /* Allocate storage for the free space section information */ saved_sect_info = (H5F_sect_info_t *)HDcalloc((size_t)saved_nsects, sizeof(H5F_sect_info_t)); CHECK(saved_sect_info, NULL, "HDcalloc"); /* Should return failure when nsects is 0 with a nonnull sect_info */ nsects = H5Fget_free_sections(file, H5FD_MEM_DEFAULT, (size_t)0, saved_sect_info); VERIFY(nsects, FAIL, "H5Fget_free_sections"); /* Verify the correct # of free-space sections */ nsects = H5Fget_free_sections(file, H5FD_MEM_DEFAULT, (size_t)saved_nsects, saved_sect_info); VERIFY(nsects, saved_nsects, "H5Fget_free_sections"); /* Verify the amount of free-space is correct */ total = 0; for(i = 0; i < nsects; i++) total += saved_sect_info[i].size; VERIFY(free_space, total, "H5Fget_free_sections"); /* save the last section's size */ last_size = saved_sect_info[nsects-1].size; /* Allocate storage for -1 free space section information */ sect_info = (H5F_sect_info_t *)HDcalloc((size_t)(saved_nsects - 1), sizeof(H5F_sect_info_t)); CHECK(sect_info, NULL, "HDcalloc"); /* Retrieve free space info for -1 sections */ nsects = H5Fget_free_sections(file, H5FD_MEM_DEFAULT, (size_t)(saved_nsects - 1), sect_info); VERIFY(nsects, saved_nsects, "H5Fget_free_sections"); /* Verify the amount of free-space is correct */ total = 0; for(i = 0; i < (saved_nsects - 1); i++) { VERIFY(sect_info[i].addr, saved_sect_info[i].addr, "H5Fget_free_sections"); VERIFY(sect_info[i].size, saved_sect_info[i].size, "H5Fget_free_sections"); total += sect_info[i].size; } VERIFY(((hsize_t)free_space - last_size), total, "H5Fget_free_sections"); HDfree(sect_info); /* Allocate storage for +1 free space section information */ sect_info = (H5F_sect_info_t *)HDcalloc((size_t)(saved_nsects + 1), sizeof(H5F_sect_info_t)); CHECK(sect_info, NULL, "HDcalloc"); /* Retrieve free-space info for +1 sections */ nsects = H5Fget_free_sections(file, H5FD_MEM_DEFAULT, (size_t)(saved_nsects + 1), sect_info); VERIFY(nsects, saved_nsects, "H5Fget_free_sections"); /* Verify free-space info is correct */ total = 0; for(i = 0; i < nsects; i++) { VERIFY(sect_info[i].addr, saved_sect_info[i].addr, "H5Fget_free_sections"); VERIFY(sect_info[i].size, saved_sect_info[i].size, "H5Fget_free_sections"); total += sect_info[i].size; } VERIFY(sect_info[nsects].addr, 0, "H5Fget_free_sections"); VERIFY(sect_info[nsects].size, 0, "H5Fget_free_sections"); VERIFY(free_space, total, "H5Fget_free_sections"); HDfree(sect_info); /* Verify that there is no free-space section for this type */ nsects = H5Fget_free_sections(file, H5FD_MEM_BTREE, (size_t)0, NULL); VERIFY(nsects, 0, "H5Fget_free_sections"); /* Close file */ ret = H5Fclose(file); CHECK(ret, FAIL, "H5Fclose"); ret = H5Pclose(fcpl); CHECK(fcpl, FAIL, "H5Pclose"); HDfree(saved_sect_info); } /* end test_free_sections() */ /**************************************************************** ** ** test_filespace_sects(): ** This test checks free space section info for ** files created with sec2 and split drivers. ** *****************************************************************/ static void test_filespace_sects(void) { hid_t fapl_sec2; /* File access property id with sec2 driver */ hid_t fapl_split; /* File access property id with split driver */ hid_t fapl_core; /* File access property id with core driver */ hid_t fapl_stdio; /* File access property id with stdio driver */ hid_t fapl_family; /* File access property id with family driver */ char filename[FILENAME_LEN]; /* Filename to use */ herr_t ret; /* Return value */ /* SEC2 */ MESSAGE(5, ("Testing File free space information for a sec2 file\n")); fapl_sec2 = H5Pcreate(H5P_FILE_ACCESS); ret = H5Pset_fapl_sec2(fapl_sec2); CHECK(ret, FAIL, "H5Pset_fapl_sec2"); /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl_sec2, filename, sizeof(filename)); /* perform free space information test for file with sec2 driver */ test_free_sections(fapl_sec2, filename); /* close fapl_sec2 and remove the file */ h5_cleanup(FILENAME, fapl_sec2); /* SPLIT */ MESSAGE(5, ("Testing File free space information for a split file\n")); fapl_split = H5Pcreate(H5P_FILE_ACCESS); CHECK(fapl_split, FAIL, "h5_fileaccess"); ret = H5Pset_fapl_split(fapl_split, "-m.h5", H5P_DEFAULT, "-r.h5", H5P_DEFAULT); CHECK(ret, FAIL, "H5Pset_fapl_split"); /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[1], fapl_split, filename, sizeof(filename)); /* perform free space information test for file with split driver */ test_free_sections(fapl_split, filename); /* close fapl and remove the file */ h5_cleanup(FILENAME, fapl_split); /* STDIO */ MESSAGE(5, ("Testing File free space information for a stdio file\n")); fapl_stdio = H5Pcreate(H5P_FILE_ACCESS); CHECK(fapl_stdio, FAIL, "h5_fileaccess"); ret = H5Pset_fapl_stdio(fapl_stdio); CHECK(ret, FAIL, "H5Pset_fapl_split"); /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[2], fapl_stdio, filename, sizeof(filename)); /* perform free space information test for file with stdio driver */ test_free_sections(fapl_stdio, filename); /* close fapl and remove the file */ h5_cleanup(FILENAME, fapl_split); /* CORE */ MESSAGE(5, ("Testing File free space information for a core file\n")); fapl_core = H5Pcreate(H5P_FILE_ACCESS); CHECK(fapl_core, FAIL, "h5_fileaccess"); ret = H5Pset_fapl_core(fapl_core, (size_t)CORE_INCREMENT, TRUE); CHECK(ret, FAIL, "H5Pset_fapl_core"); /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[3], fapl_core, filename, sizeof(filename)); /* perform free space information test for file with core driver */ test_free_sections(fapl_core, filename); /* close fapl_ and remove the file */ h5_cleanup(FILENAME, fapl_core); /* FAMILY */ MESSAGE(5, ("Testing File free space information for a family file\n")); fapl_family = H5Pcreate(H5P_FILE_ACCESS); CHECK(fapl_family, FAIL, "h5_fileaccess"); ret = H5Pset_fapl_family(fapl_family, (hsize_t)FAMILY_SIZE, H5P_DEFAULT); CHECK(ret, FAIL, "H5Pset_fapl_family"); /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[4], fapl_family, filename, sizeof(filename)); /* perform free space information test for file with family driver */ test_free_sections(fapl_family, filename); /* close fapl and remove the file */ h5_cleanup(FILENAME, fapl_family); } /* end test_filespace_sects() */ /**************************************************************** ** ** test_filespace_info(): ** Verify that the public routines H5Pget/set_file_space() ** retrieve and set the file space strategy and free space ** section threshold as specified. ** ****************************************************************/ static void test_filespace_info(void) { hid_t fid1, fid2; /* HDF5 File IDs */ hid_t fapl, new_fapl; /* File access property */ hid_t fcpl, fcpl1, fcpl2; /* File creation property */ char filename[FILENAME_LEN]; /* Filename to use */ H5F_file_space_type_t strategy, fs_type, def_type; /* File space handling strategy */ hsize_t threshold, fs_size, def_size; /* Free space section threshold */ hbool_t new_format; /* new format or old format */ herr_t ret; /* return value */ /* Output message about test being performed */ MESSAGE(5, ("Testing File Space Management public routines: H5Pget/set_file_space()\n")); fapl = h5_fileaccess(); h5_fixname(FILESPACE_NAME[0], fapl, filename, sizeof filename); new_fapl = H5Pcopy(fapl); CHECK(new_fapl, FAIL, "H5Pcopy"); /* Set the "use the latest version of the format" bounds */ ret = H5Pset_libver_bounds(new_fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST); CHECK(ret, FAIL, "H5Pset_libver_bounds"); /* Create file-creation template */ fcpl = H5Pcreate(H5P_FILE_CREATE); CHECK(fcpl, FAIL, "H5Pcreate"); /* Get default file space information */ ret = H5Pget_file_space(fcpl, &def_type, &def_size); CHECK(ret, FAIL, "H5Pget_file_space"); /* Test with old & new format groups */ for(new_format = FALSE; new_format <= TRUE; new_format++) { hid_t my_fapl; /* Set the FAPL for the type of format */ if(new_format) { MESSAGE(5, ("Testing with new group format\n")); my_fapl = new_fapl; } /* end if */ else { MESSAGE(5, ("Testing with old group format\n")); my_fapl = fapl; } /* end else */ /* Test with different sized free space section threshold */ for(fs_size = 0; fs_size <= TEST_THRESHOLD10; fs_size++) { /* Test with different file space handling strategies */ for(fs_type = 0; fs_type < H5F_FILE_SPACE_NTYPES; H5_INC_ENUM(H5F_file_space_type_t, fs_type)) { /* Get a copy of the default file creation property */ fcpl1 = H5Pcopy(fcpl); CHECK(fcpl1, FAIL, "H5Pcopy"); /* Set file space strategy and free space section threshold */ ret = H5Pset_file_space(fcpl1, fs_type, fs_size); CHECK(ret, FAIL, "H5Pget_file_space"); /* Get the file space info from the creation property */ ret = H5Pget_file_space(fcpl1, &strategy, &threshold); CHECK(ret, FAIL, "H5Pget_file_space"); /* A 0 value for strategy retains existing strategy in use */ VERIFY(strategy, (H5F_file_space_type_t)(fs_type ? fs_type : def_type), "H5Pget_file_space"); /* A 0 value for threshold retains existing threshold in use */ VERIFY(threshold, (hsize_t)(fs_size ? fs_size : def_size), "H5Pget_file_space"); /* Create the file with the specified file space info */ fid1 = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl1, my_fapl); CHECK(ret, FAIL, "H5Fcreate"); /* Close the file */ ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); /* Re-open the file */ fid2 = H5Fopen(filename, H5F_ACC_RDWR, my_fapl); CHECK(ret, FAIL, "H5Fopen"); /* Get the file's creation property */ fcpl2 = H5Fget_create_plist(fid2); CHECK(fcpl2, FAIL, "H5Fget_create_plist"); strategy = threshold = 0; /* Get the file space info from the creation property list */ ret = H5Pget_file_space(fcpl2, &strategy, &threshold); CHECK(ret, FAIL, "H5Pget_file_space"); VERIFY(strategy, (H5F_file_space_type_t)(fs_type ? fs_type : def_type), "H5Pget_file_space"); VERIFY(threshold, (hsize_t)(fs_size ? fs_size : def_size), "H5Pget_file_space"); /* Close the file */ ret = H5Fclose(fid2); CHECK(ret, FAIL, "H5Fclose"); /* Release file-creation template */ ret = H5Pclose(fcpl1); CHECK(ret, FAIL, "H5Pclose"); ret = H5Pclose(fcpl2); CHECK(ret, FAIL, "H5Pclose"); } /* end for file space strategy type */ } /* end for free space threshold */ h5_cleanup(FILESPACE_NAME, my_fapl); } /* end for new/old format */ /* Close the file creation property list */ ret = H5Pclose(fcpl); CHECK(ret, FAIL, "H5Pclose"); } /* test_filespace_info() */ /**************************************************************** ** ** test_filespace_compatible(): ** Verify that the branch with file space management enhancement ** can open, read and modify 1.6 HDF5 file and 1.8 HDF5 file. ** Also verify the correct file space strategy/threshold in use ** and the amount of free space. ** ****************************************************************/ static void test_filespace_compatible(void) { int fd_old = (-1), fd_new = (-1); /* File descriptors for copying data */ hid_t fid; /* File id */ hid_t fcpl; /* File creation property list template */ hid_t did; /* Dataset id */ int check[100]; /* Temporary buffer for verifying dataset data */ int rdbuf[100]; /* Temporary buffer for reading in dataset data */ uint8_t buf[READ_OLD_BUFSIZE]; /* temporary buffer for reading */ ssize_t nread; /* Number of bytes read in */ char *srcdir = HDgetenv("srcdir"); /* where the src code is located */ unsigned i, j; /* Local index variable */ hssize_t free_space; /* Amount of free space in the file */ hsize_t threshold; /* Free space section threshold */ H5F_file_space_type_t strategy; /* File space handling strategy */ herr_t ret; /* Return value */ /* Output message about test being performed */ MESSAGE(5, ("Testing File space compatibility for 1.6 and 1.8 files\n")); for(j = 0; j < NELMTS(OLD_FILENAME); j++) { char filename[FILENAME_LEN] = ""; /* old test file name */ /* Generate correct name for test file by prepending the source path */ if(srcdir && ((HDstrlen(srcdir) + HDstrlen(OLD_FILENAME[j]) + 1) < sizeof(filename))) { HDstrcpy(filename, srcdir); HDstrcat(filename, "/"); } HDstrcat(filename, OLD_FILENAME[j]); /* Copy old file into test file */ fd_old = HDopen(filename, O_RDONLY, 0666); CHECK(fd_old, FAIL, "HDopen"); fd_new = HDopen(FILE5, O_RDWR|O_CREAT|O_TRUNC, 0666); CHECK(fd_new, FAIL, "HDopen"); /* Copy data */ while((nread = HDread(fd_old, buf, (size_t)READ_OLD_BUFSIZE)) > 0) HDwrite(fd_new, buf, (size_t)nread); /* Close the files */ ret = HDclose(fd_old); CHECK(ret, FAIL, "HDclose"); ret = HDclose(fd_new); CHECK(ret, FAIL, "HDclose"); /* Open the test file */ fid = H5Fopen(FILE5, H5F_ACC_RDWR, H5P_DEFAULT); CHECK(fid, FAIL, "H5Fopen"); /* There should not be any free space in the file */ free_space = H5Fget_freespace(fid); CHECK(free_space, FAIL, "H5Fget_freespace"); VERIFY(free_space, (hssize_t)0, "H5Fget_freespace"); /* Get the file's file creation property list */ /* Retrieve the file space handling stretegy and threshold */ fcpl = H5Fget_create_plist(fid); CHECK(fcpl, FAIL, "H5Fget_create_plist"); ret = H5Pget_file_space(fcpl, &strategy, &threshold); CHECK(ret, FAIL, "H5Pget_file_space"); /* File space handling strategy should be H5F_FILE_SPACE_ALL = 2 */ /* Free space section threshold should be 1 */ VERIFY(strategy, 2, "H5Pget_file_space"); VERIFY(threshold, 1, "H5Pget_file_space"); /* Generate raw data */ for(i = 0; i < 100; i++) check[i] = (int)i; /* Open and read the dataset */ did = H5Dopen2(fid, DSETNAME, H5P_DEFAULT); CHECK(did, FAIL, "H5Dopen"); ret = H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rdbuf); CHECK(ret, FAIL, "H5Dread"); /* Verify the data read is correct */ for(i = 0; i < 100; i++) VERIFY(rdbuf[i], check[i], "test_compatible"); /* Close the dataset */ ret = H5Dclose(did); CHECK(ret, FAIL, "H5Dclose"); /* Remove the dataset */ ret = H5Ldelete(fid, DSETNAME, H5P_DEFAULT); CHECK(ret, FAIL, "H5Ldelete"); /* Close the file */ ret = H5Fclose(fid); CHECK(ret, FAIL, "H5Fclose"); /* Re-Open the file */ fid = H5Fopen(FILE5, H5F_ACC_RDONLY, H5P_DEFAULT); CHECK(fid, FAIL, "H5Fopen"); /* The dataset should not be there */ did = H5Dopen2(fid, DSETNAME, H5P_DEFAULT); VERIFY(did, FAIL, "H5Dopen"); /* There should not be any free space in the file */ free_space = H5Fget_freespace(fid); CHECK(free_space, FAIL, "H5Fget_freespace"); VERIFY(free_space, (hssize_t)0, "H5Fget_freespace"); /* Close the file */ ret = H5Fclose(fid); CHECK(ret, FAIL, "H5Fclose"); } /* end for */ } /* test_filespace_compatible */ /**************************************************************** ** ** test_deprec(): ** Test deprecated functionality. ** ****************************************************************/ #ifndef H5_NO_DEPRECATED_SYMBOLS static void test_deprec(void) { hid_t file; /* File IDs for old & new files */ hid_t fcpl; /* File creation property list */ unsigned super; /* Superblock version # */ unsigned freelist; /* Free list version # */ unsigned stab; /* Symbol table entry version # */ unsigned shhdr; /* Shared object header version # */ H5F_info1_t finfo; /* global information about file */ herr_t ret; /* Generic return value */ /* Output message about test being performed */ MESSAGE(5, ("Testing deprecated routines\n")); /* Creating a file with the default file creation property list should * create a version 0 superblock */ /* Create file with default file creation property list */ file= H5Fcreate(FILE1, H5F_ACC_TRUNC , H5P_DEFAULT, H5P_DEFAULT); CHECK(file, FAIL, "H5Fcreate"); /* Get the file's version information */ ret = H5Fget_info1(file, &finfo); CHECK(ret, FAIL, "H5Fget_info1"); VERIFY(finfo.super_ext_size, 0,"H5Fget_info1"); VERIFY(finfo.sohm.hdr_size, 0,"H5Fget_info1"); VERIFY(finfo.sohm.msgs_info.index_size, 0,"H5Fget_info1"); VERIFY(finfo.sohm.msgs_info.heap_size, 0,"H5Fget_info1"); /* Get the file's dataset creation property list */ fcpl = H5Fget_create_plist(file); CHECK(fcpl, FAIL, "H5Fget_create_plist"); /* Get the file's version information */ ret=H5Pget_version(fcpl, &super, &freelist, &stab, &shhdr); CHECK(ret, FAIL, "H5Pget_version"); VERIFY(super,0,"H5Pget_version"); VERIFY(freelist,0,"H5Pget_version"); VERIFY(stab,0,"H5Pget_version"); VERIFY(shhdr,0,"H5Pget_version"); /* Close FCPL */ ret=H5Pclose(fcpl); CHECK(ret, FAIL, "H5Pclose"); /* Close file */ ret=H5Fclose(file); CHECK(ret, FAIL, "H5Fclose"); /* Create a file creation property list */ fcpl = H5Pcreate(H5P_FILE_CREATE); CHECK(fcpl, FAIL, "H5Pcreate"); /* Set a property in the FCPL that will push the superblock version up */ ret = H5Pset_file_space(fcpl, H5F_FILE_SPACE_VFD, (hsize_t)0); CHECK(ret, FAIL, "H5Pset_file_space"); /* Creating a file with the non-default file creation property list should * create a version 2 superblock */ /* Create file with custom file creation property list */ file= H5Fcreate(FILE1, H5F_ACC_TRUNC , fcpl, H5P_DEFAULT); CHECK(file, FAIL, "H5Fcreate"); /* Close FCPL */ ret=H5Pclose(fcpl); CHECK(ret, FAIL, "H5Pclose"); /* Get the file's version information */ ret = H5Fget_info1(file, &finfo); CHECK(ret, FAIL, "H5Fget_info1"); VERIFY(finfo.super_ext_size, 40,"H5Fget_info1"); VERIFY(finfo.sohm.hdr_size, 0,"H5Fget_info1"); VERIFY(finfo.sohm.msgs_info.index_size, 0,"H5Fget_info1"); VERIFY(finfo.sohm.msgs_info.heap_size, 0,"H5Fget_info1"); /* Get the file's dataset creation property list */ fcpl = H5Fget_create_plist(file); CHECK(fcpl, FAIL, "H5Fget_create_plist"); /* Get the file's version information */ ret=H5Pget_version(fcpl, &super, &freelist, &stab, &shhdr); CHECK(ret, FAIL, "H5Pget_version"); VERIFY(super,2,"H5Pget_version"); VERIFY(freelist,0,"H5Pget_version"); VERIFY(stab,0,"H5Pget_version"); VERIFY(shhdr,0,"H5Pget_version"); /* Close FCPL */ ret=H5Pclose(fcpl); CHECK(ret, FAIL, "H5Pclose"); /* Close file */ ret=H5Fclose(file); CHECK(ret, FAIL, "H5Fclose"); /* Re-open the file */ file = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT); CHECK(file, FAIL, "H5Fcreate"); /* Get the file's version information */ ret = H5Fget_info1(file, &finfo); CHECK(ret, FAIL, "H5Fget_info1"); VERIFY(finfo.super_ext_size, 40,"H5Fget_info1"); VERIFY(finfo.sohm.hdr_size, 0,"H5Fget_info1"); VERIFY(finfo.sohm.msgs_info.index_size, 0,"H5Fget_info1"); VERIFY(finfo.sohm.msgs_info.heap_size, 0,"H5Fget_info1"); /* Get the file's creation property list */ fcpl = H5Fget_create_plist(file); CHECK(fcpl, FAIL, "H5Fget_create_plist"); /* Get the file's version information */ ret=H5Pget_version(fcpl, &super, &freelist, &stab, &shhdr); CHECK(ret, FAIL, "H5Pget_version"); VERIFY(super,2,"H5Pget_version"); VERIFY(freelist,0,"H5Pget_version"); VERIFY(stab,0,"H5Pget_version"); VERIFY(shhdr,0,"H5Pget_version"); /* Close FCPL */ ret=H5Pclose(fcpl); CHECK(ret, FAIL, "H5Pclose"); /* Close file */ ret=H5Fclose(file); CHECK(ret, FAIL, "H5Fclose"); } /* test_deprec */ #endif /* H5_NO_DEPRECATED_SYMBOLS */ /**************************************************************** ** ** test_file(): Main low-level file I/O test routine. ** ****************************************************************/ void test_file(void) { /* Output message about test being performed */ MESSAGE(5, ("Testing Low-Level File I/O\n")); test_file_create(); /* Test file creation(also creation templates)*/ test_file_open(); /* Test file opening */ #ifndef H5_NO_SHARED_WRITING test_file_close(); /* Test file close behavior */ #endif /* H5_NO_SHARED_WRITING */ test_get_file_id(); /* Test H5Iget_file_id */ test_file_perm(); /* Test file access permissions */ test_file_freespace(); /* Test file free space information */ test_file_ishdf5(); /* Test detecting HDF5 files correctly */ test_file_open_dot(); /* Test opening objects with "." for a name */ #ifndef H5_CANNOT_OPEN_TWICE test_file_open_overlap(); /* Test opening files in an overlapping manner */ #endif /*H5_CANNOT_OPEN_TWICE*/ test_file_getname(); /* Test basic H5Fget_name() functionality */ #ifndef H5_CANNOT_OPEN_TWICE test_file_double_root_open(); /* Test opening root group from two files works properly */ test_file_double_group_open(); /* Test opening same group from two files works properly */ test_file_double_dataset_open(); /* Test opening same dataset from two files works properly */ test_file_double_datatype_open(); /* Test opening same named datatype from two files works properly */ #endif /*H5_CANNOT_OPEN_TWICE*/ test_userblock_file_size(); /* Tests that files created with a userblock have the correct size */ test_cached_stab_info(); /* Tests that files are created with cached stab info in the superblock */ test_rw_noupdate(); /* Test to ensure that RW permissions don't write the file unless dirtied */ test_userblock_alignment(); /* Tests that files created with a userblock and alignment interact properly */ test_filespace_sects(); /* Test file free space section information */ test_filespace_info(); /* Test file creation public routines:H5Pget/set_file_space */ test_filespace_compatible();/* Test compatibility for file space management */ #ifndef H5_NO_DEPRECATED_SYMBOLS test_deprec(); /* Test deprecated routines */ #endif /* H5_NO_DEPRECATED_SYMBOLS */ } /* test_file() */ /*------------------------------------------------------------------------- * Function: cleanup_file * * Purpose: Cleanup temporary test files * * Return: none * * Programmer: Albert Cheng * July 2, 1998 * * Modifications: * *------------------------------------------------------------------------- */ void cleanup_file(void) { HDremove(SFILE1); HDremove(FILE1); HDremove(FILE2); HDremove(FILE3); HDremove(FILE4); HDremove(FILE5); }