/**************************************************************************** * NCSA HDF * * Software Development Group * * National Center for Supercomputing Applications * * University of Illinois at Urbana-Champaign * * 605 E. Springfield, Champaign IL 61820 * * * * For conditions of distribution and use, see the accompanying * * hdf/COPYING file. * * * ****************************************************************************/ /* $Id$ */ /*********************************************************** * * Test program: tmisc * * Test miscellaneous features not tested elsewhere. Generally * regression tests for bugs that are reported and don't * have an existing test to add them to. * *************************************************************/ #include "hdf5.h" #include "testhdf5.h" /* Definitions for misc. test #1 */ #define MISC1_FILE "tmisc.h5" #define MISC1_VAL (13417386) /* 0xccbbaa */ #define MISC1_VAL2 (15654348) /* 0xeeddcc */ #define MISC1_DSET_NAME "/scalar_set" /* Definitions for misc. test #2 */ #define MISC2_FILE_1 "tmisc2a.h5" #define MISC2_FILE_2 "tmisc2b.h5" #define MISC2_ATT_NAME_1 "scalar_att_1" #define MISC2_ATT_NAME_2 "scalar_att_2" typedef struct { char *string; } misc2_struct; /* Definitions for misc. test #3 */ #define MISC3_FILE "tmisc3.h5" #define MISC3_RANK 2 #define MISC3_DIM1 6 #define MISC3_DIM2 6 #define MISC3_CHUNK_DIM1 2 #define MISC3_CHUNK_DIM2 2 #define MISC3_FILL_VALUE 2 #define MISC3_DSET_NAME "/chunked" /* Definitions for misc. test #4 */ #define MISC4_FILE_1 "tmisc4a.h5" #define MISC4_FILE_2 "tmisc4b.h5" #define MISC4_GROUP_1 "/Group1" #define MISC4_GROUP_2 "/Group2" /* Definitions for misc. test #5 */ #define MISC5_FILE "tmisc5.h5" #define MISC5_DSETNAME "dset1" #define MISC5_DSETRANK 1 #define MISC5_NELMTOPLVL 1 #define MISC5_DBGNELM1 2 #define MISC5_DBGNELM2 1 #define MISC5_DBGNELM3 1 #define MISC5_DBGELVAL1 999999999 #define MISC5_DBGELVAL2 888888888 #define MISC5_DBGELVAL3 777777777 typedef struct { int st1_el1; hvl_t st1_el2; } misc5_struct1; typedef struct { int st2_el1; hvl_t st2_el2; } misc5_struct2; typedef struct { int st3_el1; } misc5_struct3; typedef struct { hid_t st3h_base; hid_t st3h_id; } misc5_struct3_hndl; typedef struct { hid_t st2h_base; hid_t st2h_id; misc5_struct3_hndl *st2h_st3hndl; } misc5_struct2_hndl; typedef struct { hid_t st1h_base; hid_t st1h_id; misc5_struct2_hndl *st1h_st2hndl; } misc5_struct1_hndl; /* Definitions for misc. test #6 */ #define MISC6_FILE "tmisc6.h5" #define MISC6_DSETNAME1 "dset1" #define MISC6_DSETNAME2 "dset2" #define MISC6_NUMATTR 16 /* Definitions for misc. test #7 */ #define MISC7_FILE "tmisc7.h5" #define MISC7_DSETNAME1 "Dataset1" #define MISC7_DSETNAME2 "Dataset2" #define MISC7_TYPENAME1 "Datatype1" #define MISC7_TYPENAME2 "Datatype2" /* Definitions for misc. test #8 */ #define MISC8_FILE "tmisc8.h5" #define MISC8_DSETNAME1 "Dataset1" #define MISC8_DSETNAME2 "Dataset2" #define MISC8_DSETNAME3 "Dataset3" #define MISC8_DSETNAME4 "Dataset4" #define MISC8_DSETNAME5 "Dataset5" #define MISC8_DSETNAME6 "Dataset6" #define MISC8_RANK 2 #define MISC8_DIM0 100 #define MISC8_DIM1 100 #define MISC8_CHUNK_DIM0 10 #define MISC8_CHUNK_DIM1 10 /**************************************************************** ** ** test_misc1(): test unlinking a dataset from a group and immediately ** re-using the dataset name ** ****************************************************************/ static void test_misc1(void) { int i; int i_check; hid_t file, dataspace, dataset; herr_t ret; /* Output message about test being performed */ MESSAGE(5, ("Testing Unlinking Dataset and Re-creating It\n")); file = H5Fcreate(MISC1_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); CHECK(file, FAIL, "H5Fcreate"); dataspace = H5Screate(H5S_SCALAR); CHECK(dataspace, FAIL, "H5Screate"); /* Write the dataset the first time. */ dataset = H5Dcreate(file, MISC1_DSET_NAME, H5T_NATIVE_INT, dataspace, H5P_DEFAULT); CHECK(dataset, FAIL, "H5Dcreate"); i = MISC1_VAL; ret = H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &i); CHECK(ret, FAIL, "H5Dwrite"); ret = H5Dclose(dataset); CHECK(ret, FAIL, "H5Dclose"); /* Remove the dataset. */ ret = H5Gunlink(file, MISC1_DSET_NAME); CHECK(ret, FAIL, "H5Gunlink"); /* Write the dataset for the second time with a different value. */ dataset = H5Dcreate(file, MISC1_DSET_NAME, H5T_NATIVE_INT, dataspace, H5P_DEFAULT); CHECK(dataset, FAIL, "H5Dcreate"); i = MISC1_VAL2; ret = H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &i); CHECK(ret, FAIL, "H5Dwrite"); ret = H5Dclose(dataset); CHECK(ret, FAIL, "H5Dclose"); ret = H5Sclose(dataspace); CHECK(ret, FAIL, "H5Sclose"); ret = H5Fclose(file); CHECK(ret, FAIL, "H5Fclose"); /* Now, check the value written to the dataset, after it was re-created */ file = H5Fopen(MISC1_FILE, H5F_ACC_RDONLY, H5P_DEFAULT); CHECK(file, FAIL, "H5Fopen"); dataspace = H5Screate(H5S_SCALAR); CHECK(dataspace, FAIL, "H5Screate"); dataset = H5Dopen(file, MISC1_DSET_NAME); CHECK(dataset, FAIL, "H5Dopen"); ret = H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &i_check); CHECK(ret, FAIL, "H5Dread"); VERIFY(i_check,MISC1_VAL2,"H5Dread"); ret = H5Sclose(dataspace); CHECK(ret, FAIL, "H5Sclose"); ret = H5Dclose(dataset); CHECK(ret, FAIL, "H5Dclose"); ret = H5Fclose(file); CHECK(ret, FAIL, "H5Fclose"); } /* end test_misc1() */ static hid_t misc2_create_type(void) { hid_t type, type_tmp; herr_t ret; type_tmp = H5Tcopy (H5T_C_S1); CHECK(type_tmp, FAIL, "H5Tcopy"); ret = H5Tset_size (type_tmp, H5T_VARIABLE); CHECK(ret, FAIL, "H5Tset_size"); type = H5Tcreate (H5T_COMPOUND, sizeof(misc2_struct)); CHECK(type, FAIL, "H5Tcreate"); ret = H5Tinsert (type, "string", offsetof(misc2_struct, string), type_tmp); CHECK(ret, FAIL, "H5Tinsert"); ret = H5Tclose(type_tmp); CHECK(ret, FAIL, "H5Tclose"); return type; } static void test_misc2_write_attribute(void) { hid_t file1, file2, root1, root2, dataspace, att1, att2; hid_t type; herr_t ret; misc2_struct data, data_check; char *string_att1 = HDstrdup("string attribute in file one"); char *string_att2 = HDstrdup("string attribute in file two"); type = misc2_create_type(); dataspace = H5Screate(H5S_SCALAR); CHECK(dataspace, FAIL, "H5Screate"); file2 = H5Fcreate(MISC2_FILE_2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); CHECK(file2, FAIL, "H5Fcreate"); file1 = H5Fcreate(MISC2_FILE_1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); CHECK(file1, FAIL, "H5Fcreate"); root1 = H5Gopen(file1, "/"); CHECK(root1, FAIL, "H5Gopen"); att1 = H5Acreate(root1, MISC2_ATT_NAME_1, type, dataspace, H5P_DEFAULT); CHECK(att1, FAIL, "H5Acreate"); data.string = string_att1; ret = H5Awrite(att1, type, &data); CHECK(ret, FAIL, "H5Awrite"); ret = H5Aread(att1, type, &data_check); CHECK(ret, FAIL, "H5Aread"); free(data_check.string); ret = H5Aclose(att1); CHECK(ret, FAIL, "HAclose"); ret = H5Gclose(root1); CHECK(ret, FAIL, "H5Gclose"); ret = H5Fclose(file1); CHECK(ret, FAIL, "H5Fclose"); root2 = H5Gopen(file2, "/"); CHECK(root2, FAIL, "H5Gopen"); att2 = H5Acreate(root2, MISC2_ATT_NAME_2, type, dataspace, H5P_DEFAULT); CHECK(att2, FAIL, "H5Acreate"); data.string = string_att2; ret = H5Awrite(att2, type, &data); CHECK(ret, FAIL, "H5Awrite"); ret = H5Aread(att2, type, &data_check); CHECK(ret, FAIL, "H5Aread"); free(data_check.string); ret = H5Aclose(att2); CHECK(ret, FAIL, "HAclose"); ret = H5Gclose(root2); CHECK(ret, FAIL, "H5Gclose"); ret = H5Tclose(type); CHECK(ret, FAIL, "H5Tclose"); ret = H5Sclose(dataspace); CHECK(ret, FAIL, "H5Sclose"); ret = H5Fclose(file2); CHECK(ret, FAIL, "H5Fclose"); free(string_att1); free(string_att2); return; } static void test_misc2_read_attribute(const char *filename, const char *att_name) { hid_t file, root, att; hid_t type; herr_t ret; misc2_struct data_check; type = misc2_create_type(); file = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT); CHECK(file, FAIL, "H5Fopen"); root = H5Gopen(file, "/"); CHECK(root, FAIL, "H5Gopen"); att = H5Aopen_name(root, att_name); CHECK(att, FAIL, "H5Aopen_name"); ret = H5Aread(att, type, &data_check); CHECK(ret, FAIL, "H5Aread"); free(data_check.string); ret = H5Aclose(att); CHECK(ret, FAIL, "H5Aclose"); ret = H5Tclose(type); CHECK(ret, FAIL, "H5Tclose"); ret = H5Gclose(root); CHECK(ret, FAIL, "H5Gclose"); ret = H5Fclose(file); CHECK(ret, FAIL, "H5Fclose"); return; } /**************************************************************** ** ** test_misc2(): test using the same VL-derived datatype in two ** different files, which was causing problems with the ** datatype conversion functions ** ****************************************************************/ static void test_misc2(void) { /* Output message about test being performed */ MESSAGE(5, ("Testing VL datatype in two different files\n")); test_misc2_write_attribute(); test_misc2_read_attribute(MISC2_FILE_1, MISC2_ATT_NAME_1); test_misc2_read_attribute(MISC2_FILE_2, MISC2_ATT_NAME_2); } /* end test_misc2() */ /**************************************************************** ** ** test_misc3(): Test reading from chunked dataset with non-zero ** fill value ** ****************************************************************/ static void test_misc3(void) { hid_t file, dataspace, dataset, dcpl; int rank=MISC3_RANK; hsize_t dims[MISC3_RANK]={MISC3_DIM1,MISC3_DIM2}; hsize_t chunk_dims[MISC3_RANK]={MISC3_CHUNK_DIM1,MISC3_CHUNK_DIM2}; int fill=MISC3_FILL_VALUE; int read_buf[MISC3_DIM1][MISC3_DIM2]; int i,j; herr_t ret; /* Output message about test being performed */ MESSAGE(5, ("Testing reading from chunked dataset with non-zero fill-value\n")); file = H5Fcreate(MISC3_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); CHECK(file, FAIL, "H5Fcreate"); /* Create a simple dataspace */ dataspace = H5Screate_simple(rank,dims,NULL); CHECK(dataspace, FAIL, "H5Screate_simple"); /* Create a dataset creation property list */ dcpl = H5Pcreate(H5P_DATASET_CREATE); CHECK(dcpl, FAIL, "H5Pcreate"); /* Set the chunk information */ ret = H5Pset_chunk(dcpl,rank,chunk_dims); CHECK(dcpl, FAIL, "H5Pset_chunk"); /* Set the fill-value information */ ret = H5Pset_fill_value(dcpl,H5T_NATIVE_INT,&fill); CHECK(dcpl, FAIL, "H5Pset_fill_value"); /* Create the dataset */ dataset = H5Dcreate(file, MISC3_DSET_NAME, H5T_NATIVE_INT, dataspace, dcpl); CHECK(dataset, FAIL, "H5Dcreate"); /* Read from the dataset (should be fill-values) */ ret = H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &read_buf); CHECK(ret, FAIL, "H5Dread"); for(i=0; ist3h_base=H5Tcreate( H5T_COMPOUND, sizeof(misc5_struct3)); CHECK(str3hndl->st3h_base,FAIL,"H5Tcreate"); ret=H5Tinsert(str3hndl->st3h_base, "st3_el1", HOFFSET( misc5_struct3, st3_el1), H5T_NATIVE_INT); CHECK(ret,FAIL,"H5Tinsert"); str3hndl->st3h_id=H5Tvlen_create(str3hndl->st3h_base); CHECK(str3hndl->st3h_id,FAIL,"H5Tvlen_create"); return(str3hndl); } static void delete_struct3(misc5_struct3_hndl *str3hndl) { herr_t ret; /* For error checking */ ret=H5Tclose(str3hndl->st3h_id); CHECK(ret,FAIL,"H5Tclose"); ret=H5Tclose(str3hndl->st3h_base); CHECK(ret,FAIL,"H5Tclose"); free(str3hndl); } static void set_struct3(misc5_struct3 *buf) { buf->st3_el1=MISC5_DBGELVAL3; } /*********************** struct2 ***********************/ static misc5_struct2_hndl * create_struct2(void) { misc5_struct2_hndl *str2hndl; /* New 'struct2' created */ herr_t ret; /* For error checking */ str2hndl=malloc(sizeof(misc5_struct2_hndl)); CHECK(str2hndl,NULL,"malloc"); str2hndl->st2h_base=H5Tcreate( H5T_COMPOUND, sizeof(misc5_struct2)); CHECK(str2hndl->st2h_base,FAIL,"H5Tcreate"); ret=H5Tinsert(str2hndl->st2h_base, "st2_el1", HOFFSET( misc5_struct2, st2_el1), H5T_NATIVE_INT); CHECK(ret,FAIL,"H5Tinsert"); str2hndl->st2h_st3hndl=create_struct3(); CHECK(str2hndl->st2h_st3hndl,NULL,"create_struct3"); ret=H5Tinsert(str2hndl->st2h_base, "st2_el2", HOFFSET(misc5_struct2, st2_el2), str2hndl->st2h_st3hndl->st3h_id); CHECK(ret,FAIL,"H5Tinsert"); str2hndl->st2h_id= H5Tvlen_create(str2hndl->st2h_base); CHECK(str2hndl->st2h_id,FAIL,"H5Tvlen_create"); return(str2hndl); } static void delete_struct2(misc5_struct2_hndl *str2hndl) { herr_t ret; /* For error checking */ ret=H5Tclose(str2hndl->st2h_id); CHECK(ret,FAIL,"H5Tclose"); delete_struct3(str2hndl->st2h_st3hndl); H5Tclose(str2hndl->st2h_base); CHECK(ret,FAIL,"H5Tclose"); free(str2hndl); } static void set_struct2(misc5_struct2 *buf) { unsigned i; /* Local index variable */ buf->st2_el1=MISC5_DBGELVAL2; buf->st2_el2.len=MISC5_DBGNELM3; buf->st2_el2.p=malloc((buf->st2_el2.len)*sizeof(misc5_struct3)); CHECK(buf->st2_el2.p,NULL,"malloc"); for(i=0; i<(buf->st2_el2.len); i++) set_struct3(&(((misc5_struct3 *)(buf->st2_el2.p))[i])); } static void clear_struct2(misc5_struct2 *buf) { free(buf->st2_el2.p); } /*********************** struct1 ***********************/ static misc5_struct1_hndl * create_struct1(void) { misc5_struct1_hndl *str1hndl; /* New 'struct1' created */ herr_t ret; /* For error checking */ str1hndl=malloc(sizeof(misc5_struct1_hndl)); CHECK(str1hndl,NULL,"malloc"); str1hndl->st1h_base=H5Tcreate(H5T_COMPOUND, sizeof(misc5_struct1)); CHECK(str1hndl->st1h_base,FAIL,"H5Tcreate"); ret=H5Tinsert(str1hndl->st1h_base, "st1_el1", HOFFSET(misc5_struct1, st1_el1), H5T_NATIVE_INT); CHECK(ret,FAIL,"H5Tinsert"); str1hndl->st1h_st2hndl=create_struct2(); CHECK(str1hndl->st1h_st2hndl,NULL,"create_struct2"); ret=H5Tinsert(str1hndl->st1h_base, "st1_el2", HOFFSET(misc5_struct1, st1_el2), str1hndl->st1h_st2hndl->st2h_id); CHECK(ret,FAIL,"H5Tinsert"); str1hndl->st1h_id=H5Tvlen_create(str1hndl->st1h_base); CHECK(str1hndl->st1h_id,FAIL,"H5Tvlen_create"); return(str1hndl); } static void delete_struct1(misc5_struct1_hndl *str1hndl) { herr_t ret; /* For error checking */ ret=H5Tclose(str1hndl->st1h_id); CHECK(ret,FAIL,"H5Tclose"); delete_struct2(str1hndl->st1h_st2hndl); ret=H5Tclose(str1hndl->st1h_base); CHECK(ret,FAIL,"H5Tclose"); free(str1hndl); } static void set_struct1(misc5_struct1 *buf) { unsigned i; /* Local index variable */ buf->st1_el1=MISC5_DBGELVAL1; buf->st1_el2.len=MISC5_DBGNELM2; buf->st1_el2.p=malloc((buf->st1_el2.len)*sizeof(misc5_struct2)); CHECK(buf->st1_el2.p,NULL,"malloc"); for(i=0; i<(buf->st1_el2.len); i++) set_struct2(&(((misc5_struct2 *)(buf->st1_el2.p))[i])); } static void clear_struct1(misc5_struct1 *buf) { unsigned i; for(i=0;ist1_el2.len;i++) clear_struct2(&((( misc5_struct2 *)(buf->st1_el2.p))[i])); free(buf->st1_el2.p); } static void test_misc5(void) { hid_t loc_id, space_id, dataset_id; hid_t mem_type_id; misc5_struct1_hndl *str1hndl; hsize_t dims[MISC5_DSETRANK]; hvl_t buf; unsigned i,j,k; herr_t ret; /* Output message about test being performed */ MESSAGE(5, ("Testing several level deep nested compound & VL datatypes \n")); /* Write the dataset out */ loc_id=H5Fcreate(MISC5_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); CHECK(loc_id,FAIL,"H5Fcreate"); /* Create the memory structure to write */ str1hndl=create_struct1(); CHECK(str1hndl,NULL,"create_struct1"); /* Create the dataspace */ dims[0]=MISC5_NELMTOPLVL; space_id=H5Screate_simple(MISC5_DSETRANK, dims, NULL); CHECK(space_id,FAIL,"H5Screate_simple"); /* Create the dataset */ dataset_id=H5Dcreate(loc_id, MISC5_DSETNAME, str1hndl->st1h_id, space_id, H5P_DEFAULT); CHECK(dataset_id,FAIL,"H5Dcreate"); /* Create the variable-length buffer */ buf.len=MISC5_DBGNELM1; buf.p=malloc((buf.len)*sizeof(misc5_struct1)); CHECK(buf.p,NULL,"malloc"); /* Create the top-level VL information */ for(i=0; ist1h_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, &buf); CHECK(ret,FAIL,"H5Dwrite"); /* Release the top-level VL information */ for(j=0; j=(4*MISC8_CHUNK_DIM0*MISC8_CHUNK_DIM1*H5Tget_size(H5T_NATIVE_INT))) { num_errs++; printf("Error on line %d: data wasn't compressed! storage_size=%u\n",__LINE__,(unsigned)storage_size); } /* Write entire dataset */ ret = H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata); CHECK(ret, FAIL, "H5Dwrite"); #ifdef VERIFY_DATA /* Read data */ ret = H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata); CHECK(ret, FAIL, "H5Dread"); /* Check values written */ tdata=wdata; tdata2=rdata; for(u=0; u=(MISC8_DIM0*MISC8_DIM1*H5Tget_size(H5T_NATIVE_INT))) { num_errs++; printf("Error on line %d: data wasn't compressed! storage_size=%u\n",__LINE__,(unsigned)storage_size); } /* Close dataset ID */ ret = H5Dclose(did); CHECK(ret, FAIL, "H5Dclose"); #endif /* H5_HAVE_PARALLEL */ /* Close dataset creation property list */ ret=H5Pclose(dcpl); CHECK(ret, FAIL, "H5Pclose"); /* Close dataspace */ ret=H5Sclose(sid); CHECK(ret, FAIL, "H5Sclose"); /* Close file */ ret=H5Fclose(fid); CHECK(ret, FAIL, "H5Fclose"); /* Free the read & write buffers */ free(wdata); #ifdef VERIFY_DATA free(rdata); #endif /* VERIFY_DATA */ } /* end test_misc8() */ /**************************************************************** ** ** test_misc(): Main misc. test routine. ** ****************************************************************/ void test_misc(void) { /* Output message about test being performed */ MESSAGE(5, ("Testing Miscellaneous Routines\n")); test_misc1(); /* Test unlinking a dataset & immediately re-using name */ test_misc2(); /* Test storing a VL-derived datatype in two different files */ test_misc3(); /* Test reading from chunked dataset with non-zero fill value */ test_misc4(); /* Test retrieving the fileno for various objects with H5Gget_objinfo() */ test_misc5(); /* Test several level deep nested compound & VL datatypes */ test_misc6(); /* Test object header continuation code */ test_misc7(); /* Test for sensible datatypes stored on disk */ test_misc8(); /* Test storage sizes of various types of dataset storage */ } /* test_misc() */ /*------------------------------------------------------------------------- * Function: cleanup_misc * * Purpose: Cleanup temporary test files * * Return: none * * Programmer: Albert Cheng * July 2, 1998 * * Modifications: * *------------------------------------------------------------------------- */ void cleanup_misc(void) { remove(MISC1_FILE); remove(MISC2_FILE_1); remove(MISC2_FILE_2); remove(MISC3_FILE); remove(MISC4_FILE_1); remove(MISC4_FILE_2); remove(MISC5_FILE); remove(MISC6_FILE); remove(MISC7_FILE); remove(MISC8_FILE); }