hdf5/test/ohdr_mindset.c
2018-09-14 13:55:56 -05:00

1841 lines
56 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Tests to verify behavior of minimized object headers.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "hdf5.h"
#include "h5test.h"
/******************
* TESTING MACROS *
******************/
#define DEBUG_OH_SIZE 0 /* toggle some debug printing (0 off, 1 on)*/
#ifndef JSMITH_TESTING
/*****************************************************************************
*
* FILE-LOCAL TESTING MACROS
*
* Purpose:
*
* 1) Upon test failure, goto-jump to single-location teardown in test
* function. E.g., `error:` (consistency with HDF corpus) or
* `failed:` (reflects purpose).
* >>> using "error", in part because `H5E_BEGIN_TRY` expects it.
* 2) Increase clarity and reduce overhead found with `TEST_ERROR`.
* e.g., "if(somefunction(arg, arg2) < 0) TEST_ERROR:"
* requires reading of entire line to know whether this if/call is
* part of the test setup, test operation, or a test unto itself.
* 3) Provide testing macros with optional user-supplied failure message;
* if not supplied (NULL), generate comparison output in the spirit of
* test-driven development. E.g., "expected 5 but was -3"
* User messages clarify test's purpose in code, encouraging description
* without relying on comments.
* 4) Configurable expected-actual order in generated comparison strings.
* Some prefer `VERIFY(expected, actual)`, others
* `VERIFY(actual, expected)`. Provide preprocessor ifdef switch
* to satifsy both parties, assuming one paradigm per test file.
* (One could #undef and redefine the flag through the file as desired,
* but _why_.)
*
* Provided as courtesy, per consideration for inclusion in the library
* proper.
*
* Macros:
*
* JSVERIFY_EXP_ACT - ifdef flag, configures comparison order
* FAIL_IF() - check condition
* FAIL_UNLESS() - check _not_ condition
* JSVERIFY() - long-int equality check; prints reason/comparison
* JSVERIFY_NOT() - long-int inequality check; prints
* JSVERIFY_STR() - string equality check; prints
*
* Programmer: Jacob Smith
* 2017-10-24
*
*****************************************************************************/
/*----------------------------------------------------------------------------
*
* ifdef flag: JSVERIFY_EXP_ACT
*
* JSVERIFY macros accept arguments as (EXPECTED, ACTUAL[, reason])
* default, if this is undefined, is (ACTUAL, EXPECTED[, reason])
*
*----------------------------------------------------------------------------
*/
#define JSVERIFY_EXP_ACT 1L
/*----------------------------------------------------------------------------
*
* Macro: JSFAILED_AT()
*
* Purpose:
*
* Preface a test failure by printing "*FAILED*" and location to stdout
* Similar to `H5_FAILED(); AT();` from h5test.h
*
* *FAILED* at somefile.c:12 in function_name()...
*
* Programmer: Jacob Smith
* 2017-10-24
*
*----------------------------------------------------------------------------
*/
#define JSFAILED_AT() { \
HDprintf("*FAILED* at %s:%d in %s()...\n", __FILE__, __LINE__, FUNC); \
}
/*----------------------------------------------------------------------------
*
* Macro: FAIL_IF()
*
* Purpose:
*
* Make tests more accessible and less cluttered than
* `if (thing == otherthing()) TEST_ERROR`
* paradigm.
*
* The following lines are roughly equivalent:
*
* `if (myfunc() < 0) TEST_ERROR;` (as seen elsewhere in HDF tests)
* `FAIL_IF(myfunc() < 0)`
*
* Prints a generic "FAILED AT" line to stdout and jumps to `error`,
* similar to `TEST_ERROR` in h5test.h
*
* Programmer: Jacob Smith
* 2017-10-23
*
*----------------------------------------------------------------------------
*/
#define FAIL_IF(condition) \
if (condition) { \
JSFAILED_AT() \
goto error; \
}
/*----------------------------------------------------------------------------
*
* Macro: FAIL_UNLESS()
*
* Purpose:
*
* TEST_ERROR wrapper to reduce cognitive overhead from "negative tests",
* e.g., "a != b".
*
* Opposite of FAIL_IF; fails if the given condition is _not_ true.
*
* `FAIL_IF( 5 != my_op() )`
* is equivalent to
* `FAIL_UNLESS( 5 == my_op() )`
* However, `JSVERIFY(5, my_op(), "bad return")` may be even clearer.
* (see JSVERIFY)
*
* Programmer: Jacob Smith
* 2017-10-24
*
*----------------------------------------------------------------------------
*/
#if 0 /* UNUSED */
#define FAIL_UNLESS(condition) \
if (!(condition)) { \
JSFAILED_AT() \
goto error; \
}
#endif /* UNUSED */
/*----------------------------------------------------------------------------
*
* Macro: JSERR_LONG()
*
* Purpose:
*
* Print an failure message for long-int arguments.
* ERROR-AT printed first.
* If `reason` is given, it is printed on own line and newlined after
* else, prints "expected/actual" aligned on own lines.
*
* *FAILED* at myfile.c:488 in somefunc()...
* forest must be made of trees.
*
* or
*
* *FAILED* at myfile.c:488 in somefunc()...
* ! Expected 425
* ! Actual 3
*
* Programmer: Jacob Smith
* 2017-10-24
*
*----------------------------------------------------------------------------
*/
#define JSERR_LONG(expected, actual, reason) { \
JSFAILED_AT() \
if (reason!= NULL) { \
HDprintf("%s\n", (reason)); \
} else { \
HDprintf(" ! Expected %ld\n ! Actual %ld\n", \
(long)(expected), (long)(actual)); \
} \
}
/*----------------------------------------------------------------------------
*
* Macro: JSERR_STR()
*
* Purpose:
*
* Print an failure message for string arguments.
* ERROR-AT printed first.
* If `reason` is given, it is printed on own line and newlined after
* else, prints "expected/actual" aligned on own lines.
*
* *FAILED* at myfile.c:421 in myfunc()...
* Blue and Red strings don't match!
*
* or
*
* *FAILED* at myfile.c:421 in myfunc()...
* !!! Expected:
* this is my expected
* string
* !!! Actual:
* not what I expected at all
*
* Programmer: Jacob Smith
* 2017-10-24
*
*----------------------------------------------------------------------------
*/
#define JSERR_STR(expected, actual, reason) { \
JSFAILED_AT() \
if ((reason) != NULL) { \
HDprintf("%s\n", (reason)); \
} else { \
HDprintf("!!! Expected:\n%s\n!!!Actual:\n%s\n", \
(expected), (actual)); \
} \
}
#ifdef JSVERIFY_EXP_ACT
/*----------------------------------------------------------------------------
*
* Macro: JSVERIFY()
*
* Purpose:
*
* Verify that two long integers are equal.
* If unequal, print failure message
* (with `reason`, if not NULL; expected/actual if NULL)
* and jump to `error` at end of function
*
* Programmer: Jacob Smith
* 2017-10-24
*
*----------------------------------------------------------------------------
*/
#define JSVERIFY(expected, actual, reason) \
if ((long)(actual) != (long)(expected)) { \
JSERR_LONG((expected), (actual), (reason)) \
goto error; \
} /* JSVERIFY */
/*----------------------------------------------------------------------------
*
* Macro: JSVERIFY_NOT()
*
* Purpose:
*
* Verify that two long integers are _not_ equal.
* If equal, print failure message
* (with `reason`, if not NULL; expected/actual if NULL)
* and jump to `error` at end of function
*
* Programmer: Jacob Smith
* 2017-10-24
*
*----------------------------------------------------------------------------
*/
#define JSVERIFY_NOT(expected, actual, reason) \
if ((long)(actual) == (long)(expected)) { \
JSERR_LONG((expected), (actual), (reason)) \
goto error; \
} /* JSVERIFY_NOT */
/*----------------------------------------------------------------------------
*
* Macro: JSVERIFY_STR()
*
* Purpose:
*
* Verify that two strings are equal.
* If unequal, print failure message
* (with `reason`, if not NULL; expected/actual if NULL)
* and jump to `error` at end of function
*
* Programmer: Jacob Smith
* 2017-10-24
*
*----------------------------------------------------------------------------
*/
#define JSVERIFY_STR(expected, actual, reason) \
if (strcmp((actual), (expected)) != 0) { \
JSERR_STR((expected), (actual), (reason)); \
goto error; \
} /* JSVERIFY_STR */
#else /* JSVERIFY_EXP_ACT */
/* Repeats macros above, but with actual/expected parameters reversed. */
/*----------------------------------------------------------------------------
* Macro: JSVERIFY()
* See: JSVERIFY documentation above.
* Programmer: Jacob Smith
* 2017-10-14
*----------------------------------------------------------------------------
*/
#define JSVERIFY(actual, expected, reason) \
if ((long)(actual) != (long)(expected)) { \
JSERR_LONG((expected), (actual), (reason)); \
goto error; \
} /* JSVERIFY */
/*----------------------------------------------------------------------------
* Macro: JSVERIFY_NOT()
* See: JSVERIFY_NOT documentation above.
* Programmer: Jacob Smith
* 2017-10-14
*----------------------------------------------------------------------------
*/
#define JSVERIFY_NOT(actual, expected, reason) \
if ((long)(actual) == (long)(expected)) { \
JSERR_LONG((expected), (actual), (reason)) \
goto error; \
} /* JSVERIFY_NOT */
/*----------------------------------------------------------------------------
* Macro: JSVERIFY_STR()
* See: JSVERIFY_STR documentation above.
* Programmer: Jacob Smith
* 2017-10-14
*----------------------------------------------------------------------------
*/
#define JSVERIFY_STR(actual, expected, reason) \
if (strcmp((actual), (expected)) != 0) { \
JSERR_STR((expected), (actual), (reason)); \
goto error; \
} /* JSVERIFY_STR */
#endif /* JSVERIFY_EXP_ACT */
#endif /* JSMITH_TESTING */
/* basenames of test files created in this test suite */
#define OHMIN_FILENAME_A "ohdr_min_a"
#define OHMIN_FILENAME_B "ohdr_min_b"
/* used for object header size comparison */
#define EQ 1
#define LT 2
#define GT 3
/* pseudo-enumeration of symbols to select H5*close() function in macro */
#define CLOSE_ATTRIBUTE 1
#define CLOSE_DATASET 2
#define CLOSE_DATASPACE 3
#define CLOSE_DATATYPE 4
#define CLOSE_FILE 5
#define CLOSE_PLIST 6
/* ---------------------------------------------------------------------------
* Macro: MUST_CLOSE(...)
*
* Trigger an error if calling close on the id fails (e.g., H5Fclose(fid).
* Uses #defined values to indicate expected id kind (plist vs file, &c.).
* Prints message on error.
* Please use only at "top level" of test function (because JSVERIFY).
* ---------------------------------------------------------------------------
*/
#define MUST_CLOSE(id, kind) \
{ switch (kind) { \
case CLOSE_ATTRIBUTE : \
JSVERIFY(SUCCEED, H5Aclose((id)), "closing attribute") \
break; \
case CLOSE_DATASET : \
JSVERIFY(SUCCEED, H5Dclose((id)), "closing dataset") \
break; \
case CLOSE_DATASPACE : \
JSVERIFY(SUCCEED, H5Sclose((id)), "closing dataspace") \
break; \
case CLOSE_DATATYPE : \
JSVERIFY(SUCCEED, H5Tclose((id)), "closing datatype") \
break; \
case CLOSE_FILE : \
JSVERIFY(SUCCEED, H5Fclose((id)), "closing file") \
break; \
case CLOSE_PLIST : \
JSVERIFY(SUCCEED, H5Pclose((id)), "closing plist") \
break; \
default: \
JSVERIFY(0, 1, "Unidentified MUST_CLOSE constant") \
break; \
} \
(id) = -1; \
}
/* ---------------------------------------------------------------------------
* Macro: PRINT_DSET_OH_COMPARISON(...)
*
* Pretty-print metadata information about two dataset object headers.
* ---------------------------------------------------------------------------
*/
#define PRINT_DSET_OH_COMPARISON(did1, did2) \
{ H5O_info_t info1; \
H5O_info_t info2; \
\
FAIL_IF( SUCCEED != H5Oget_info2((did1), &info1, H5O_INFO_HDR) ) \
FAIL_IF( SUCCEED != H5Oget_info2((did2), &info2, H5O_INFO_HDR) ) \
\
HDprintf("\n==HEADERS== UNMINIMIZED MINIMIZED\n"); \
HDprintf(" version: %11u %9u\n", \
info1.hdr.version, \
info2.hdr.version); \
HDprintf(" # messages: %11u %9u\n", \
info1.hdr.nmesgs, \
info2.hdr.nmesgs); \
HDprintf(" meta: %11llu %9llu\n", \
info1.hdr.space.meta, \
info2.hdr.space.meta); \
HDprintf(" free: %11llu %9llu\n", \
info1.hdr.space.free, \
info2.hdr.space.free); \
HDprintf(" total: %11llu %9llu\n", \
info1.hdr.space.total, \
info2.hdr.space.total); \
}
/* ---------------------------------------------------------------------------
* Macro: CREATE_FILE(...)
*
* Wrapper to create an hdf5 file, and report an error.
* Call only at test function "top level", because of JSVERIFY.
* ---------------------------------------------------------------------------
*/
#define CREATE_FILE(name, id_out) \
{ char errmsg[128] = ""; \
snprintf(errmsg, 128, "unable to create file '%s'", (name)); \
JSVERIFY( SUCCEED, _create_file((name), id_out), errmsg) \
}
/* ---------------------------------------------------------------------------
* Macro: CREATE_DATASET(...)
* + file id
* + dataset name
* + datatype id
* + dataspace id
* + dcpl id
* + pointer to dataset id (store H5Dcreate result )
*
* Wrapper to create a dataset, and report an error.
* Call only at test function "top level", because of JSVERIFY.
* ---------------------------------------------------------------------------
*/
#define CREATE_DATASET(Fid, name, Tid, Sid, dcpl, Did_out) \
{ char errmsg[32] = ""; \
snprintf(errmsg, 32, "unable to create dataset '%s'", (name)); \
JSVERIFY( SUCCEED, \
_make_dataset((Fid), (name), (Tid), (Sid), (dcpl), (Did_out)), \
errmsg) \
}
/*********************
* UTILITY FUNCTIONS *
*********************/
/* ---------------------------------------------------------------------------
* Function: _create_file()
*
* Purpose: Create a file with the name, and record its hid in out parameter.
*
* Return: 0 (success) or -1 (failure)
*
* ---------------------------------------------------------------------------
*/
static herr_t
_create_file( \
const char *filename, \
hid_t *fid)
{
hid_t id = -1;
id = H5Fcreate(
filename,
H5F_ACC_TRUNC,
H5P_DEFAULT,
H5P_DEFAULT);
if (id < 0)
return FAIL;
*fid = id;
return SUCCEED;
} /* _create_file */
/* ---------------------------------------------------------------------------
* Function: _make_dataset()
*
* Purpose: Create a dataset and record its hid in out parameter `dset_id`.
*
* Return: 0 (success) or -1 (failure)
*
* ---------------------------------------------------------------------------
*/
static herr_t
_make_dataset( \
hid_t loc_id, \
const char *name, \
hid_t datatype_id, \
hid_t dataspace_id, \
hid_t dcpl_id, \
hid_t *dset_id)
{
hid_t id = -1;
id = H5Dcreate(
loc_id,
name,
datatype_id,
dataspace_id,
H5P_DEFAULT, /* LCPL id */
dcpl_id,
H5P_DEFAULT); /* DAPL id */
if (id < 0)
return FAIL;
*dset_id = id;
return SUCCEED;
} /* _make_dataset */
/* ---------------------------------------------------------------------------
* Function: put_attribute()
*
* Purpose: Set an attribute with the given information.
*
* If the out parameter `attr_id` is negative, a new attribute will be
* created with the given information. Else, it will attempt to update the
* attribute with the new value.
*
* Return: 0 (success) or -1 (failure)
*
* ---------------------------------------------------------------------------
*/
static herr_t
put_attribute( \
hid_t loc_id, \
const char *attrname, \
const void *attrvalue, \
hid_t datatype_id, \
hid_t dataspace_id, /* ignored if attribute_id >= 0 */ \
hid_t *attribute_id)
{
if ((*attribute_id) < 0) {
hid_t id = -1;
id = H5Acreate(
loc_id,
attrname,
datatype_id,
dataspace_id,
H5P_DEFAULT, /* acpl */
H5P_DEFAULT); /* aapl */
if (id < 0)
return FAIL;
*attribute_id = id;
}
return H5Awrite(*attribute_id, datatype_id, attrvalue);
} /* put_attribute */
/* ---------------------------------------------------------------------------
* Function: count_attributes()
*
* Purpose: Count the number of attributes attached to an object.
*
* TODO: If the location id is that of a file, tries to count all the
* attributes present in the file.
*
* Return: -1 if an error occurred, else the number of attributes.
*
* ---------------------------------------------------------------------------
*/
static int
count_attributes(hid_t dset_id)
{
H5O_info_t info;
if (0 > H5Oget_info(dset_id, &info, H5O_INFO_ALL))
return -1;
else
return (int)info.num_attrs; /* should never exceed int bounds */
} /* count_attributes */
/* ---------------------------------------------------------------------------
* Function: _oh_getsize()
*
* Purpose: Get the total space used by the object header
*
*
* Return: SUCCEED/FAIL. On success, stores size in `size_out` pointer.
*
* ---------------------------------------------------------------------------
*/
static herr_t
_oh_getsize(hid_t did, hsize_t *size_out)
{
H5O_info_t info;
if (FAIL == H5Oget_info2(did, &info, H5O_INFO_HDR))
return FAIL;
*size_out = info.hdr.space.total;
return SUCCEED;
} /* _oh_getsize */
/* ---------------------------------------------------------------------------
* Function: oh_compare()
*
* Purpose: Compare the TOTAL space used by datasets' object headers.
*
*
* Return: -1 if an error occurred, else positive #defined indicator value.
*
* ---------------------------------------------------------------------------
*/
static int
oh_compare( \
hid_t did1, \
hid_t did2)
{
hsize_t space1 = 0;
hsize_t space2 = 0;
if (FAIL == _oh_getsize(did1, &space1))
return -1;
if (FAIL == _oh_getsize(did2, &space2))
return -2;
if (space1 < space2)
return LT;
else if (space1 > space2)
return GT;
else
return EQ;
}
/******************
* TEST FUNCTIONS *
******************/
/* ---------------------------------------------------------------------------
* Function: test_attribute_addition()
*
* Purpose: Demonstrate attribute addition to datasets.
*
* Return: 0 (pass) or 1 (failure)
*
* ---------------------------------------------------------------------------
*/
static int
test_attribute_addition(void)
{
hsize_t array_10[1] = {10}; /* dataspace extent */
char buffer[10] = ""; /* to inspect string attribute */
int a_out = 0;
char filename[512] = "";
hid_t int_type_id = -1;
hid_t char_type_id = -1;
hid_t dcpl_id = -1;
hid_t dspace_id = -1;
hid_t dspace_scalar_id = -1;
hid_t dset_id = -1;
hid_t mindset_id = -1;
hid_t attr_1_id = -1;
hid_t attr_1a_id = -1;
hid_t attr_2_id = -1;
hid_t attr_2a_id = -1;
hid_t attr_3_id = -1;
hid_t attr_3a_id = -1;
hid_t file_id = -1;
TESTING("attribute additions to [un]minimized dataset")
/*********
* SETUP *
*********/
FAIL_IF( NULL == h5_fixname(
OHMIN_FILENAME_A,
H5P_DEFAULT,
filename,
sizeof(filename)) )
dspace_id = H5Screate_simple(
1, /* rank */
array_10, /* current dimensions */
NULL); /* maximum dimensions */
FAIL_IF( 0 > dspace_id )
dspace_scalar_id = H5Screate(H5S_SCALAR);
FAIL_IF( 0 > dspace_scalar_id )
char_type_id = H5Tcopy(H5T_NATIVE_CHAR);
FAIL_IF( 0 > char_type_id )
int_type_id = H5Tcopy(H5T_NATIVE_INT);
FAIL_IF( 0 > int_type_id )
dcpl_id = H5Pcreate(H5P_DATASET_CREATE);
FAIL_IF( 0 > dcpl_id )
JSVERIFY( SUCCEED, \
H5Pset_dset_no_attrs_hint(dcpl_id, TRUE), \
"can't set DCPL to minimize object header")
CREATE_FILE(filename, &file_id)
H5E_BEGIN_TRY {
JSVERIFY( -1, \
count_attributes(dset_id), \
"shouldn't be able to count missing dataset")
} H5E_END_TRY;
CREATE_DATASET( \
file_id, /* shorthand for root group? */ \
"dataset", \
int_type_id, \
dspace_id, \
H5P_DEFAULT, /* default DCPL */ \
&dset_id)
CREATE_DATASET( \
file_id, \
"mindataset", \
int_type_id, \
dspace_id, \
dcpl_id, \
&mindset_id)
/********************
* TEST/DEMONSTRATE *
********************/
/* -------------------
* no attributes added
*/
JSVERIFY( 0, \
count_attributes(dset_id), \
NULL)
JSVERIFY( 0, \
count_attributes(mindset_id), \
NULL)
if (DEBUG_OH_SIZE)
PRINT_DSET_OH_COMPARISON(dset_id, mindset_id)
/* -----------------
* add one attribute
*/
JSVERIFY( SUCCEED, \
put_attribute( \
dset_id, \
"PURPOSE", \
"DEMO", \
char_type_id, \
dspace_id, \
&attr_1_id), \
"unable to set attribute 'PURPOSE:DEMO'")
JSVERIFY( SUCCEED, \
put_attribute( \
mindset_id, \
"PURPOSE", \
"DEMO", \
char_type_id, \
dspace_id, \
&attr_1a_id), \
"unable to set attribute 'PURPOSE:DEMO'")
JSVERIFY( 1, \
count_attributes(dset_id), \
NULL)
JSVERIFY( 1, \
count_attributes(mindset_id), \
NULL)
JSVERIFY( SUCCEED,
H5Aread(attr_1_id, char_type_id, buffer),
"can't read attribute 'PURPOSE'")
JSVERIFY_STR( "DEMO", buffer, NULL )
JSVERIFY( SUCCEED,
H5Aread(attr_1a_id, char_type_id, buffer),
"can't read attribute 'PURPOSE'")
JSVERIFY_STR( "DEMO", buffer, NULL )
if (DEBUG_OH_SIZE)
PRINT_DSET_OH_COMPARISON(dset_id, mindset_id)
/* -----------------
* modify one attribute
*/
JSVERIFY( SUCCEED, \
put_attribute( \
dset_id, \
"PURPOSE", \
"REWRITE", \
char_type_id, \
-1, \
&attr_1_id), \
"unable to rewrite attribute 'PURPOSE:REWRITE'")
JSVERIFY( SUCCEED, \
put_attribute( \
mindset_id, \
"PURPOSE", \
"REWRITE", \
char_type_id, \
-1, \
&attr_1a_id), \
"unable to rewrite attribute 'PURPOSE:REWRITE'")
JSVERIFY( 1, \
count_attributes(dset_id), \
NULL)
JSVERIFY( 1, \
count_attributes(mindset_id), \
NULL)
JSVERIFY( SUCCEED,
H5Aread(attr_1_id, char_type_id, buffer),
"can't read attribute 'PURPOSE'")
JSVERIFY_STR( "REWRITE", buffer, NULL )
JSVERIFY( SUCCEED,
H5Aread(attr_1a_id, char_type_id, buffer),
"can't read attribute 'PURPOSE'")
JSVERIFY_STR( "REWRITE", buffer, NULL )
if (DEBUG_OH_SIZE)
PRINT_DSET_OH_COMPARISON(dset_id, mindset_id)
/* -----------------
* add second attribute
*/
a_out = 5;
JSVERIFY( SUCCEED, \
put_attribute( \
dset_id, \
"RANK", \
&a_out, \
int_type_id, \
dspace_scalar_id, \
&attr_2_id), \
"unable to set attribute 'RANK:5'")
a_out = 3;
JSVERIFY( SUCCEED, \
put_attribute( \
mindset_id, \
"RANK", \
&a_out, \
int_type_id, \
dspace_scalar_id, \
&attr_2a_id), \
"unable to set attribute (minimized) 'RANK:3'")
JSVERIFY( 2, \
count_attributes(dset_id), \
NULL)
JSVERIFY( 2, \
count_attributes(mindset_id), \
NULL)
JSVERIFY( SUCCEED,
H5Aread(attr_2_id, int_type_id, &a_out),
"can't read attribute 'RANK'")
JSVERIFY( 5, a_out, NULL )
JSVERIFY( SUCCEED,
H5Aread(attr_2a_id, int_type_id, &a_out),
"can't read attribute (minimized) 'RANK'")
JSVERIFY( 3, a_out, NULL )
if (DEBUG_OH_SIZE)
PRINT_DSET_OH_COMPARISON(dset_id, mindset_id)
/* -----------------
* add third attribute
*/
a_out = -86;
JSVERIFY( SUCCEED, \
put_attribute( \
dset_id, \
"FLAVOR", \
&a_out, \
int_type_id, \
dspace_scalar_id, \
&attr_3_id), \
"unable to set attribute 'FLAVOR:-86'")
a_out = 2185;
JSVERIFY( SUCCEED, \
put_attribute( \
mindset_id, \
"FLAVOR", \
&a_out, \
int_type_id, \
dspace_scalar_id, \
&attr_3a_id), \
"unable to set attribute (minimized) 'FLAVOR:2185'")
JSVERIFY( 3, \
count_attributes(dset_id), \
NULL)
JSVERIFY( 3, \
count_attributes(mindset_id), \
NULL)
JSVERIFY( SUCCEED,
H5Aread(attr_3_id, int_type_id, &a_out),
"can't read attribute 'RANK'")
JSVERIFY( -86, a_out, NULL )
JSVERIFY( SUCCEED,
H5Aread(attr_3a_id, int_type_id, &a_out),
"can't read attribute (minimized) 'RANK'")
JSVERIFY( 2185, a_out, NULL )
if (DEBUG_OH_SIZE)
PRINT_DSET_OH_COMPARISON(dset_id, mindset_id)
/************
* TEARDOWN *
************/
MUST_CLOSE(int_type_id, CLOSE_DATATYPE)
MUST_CLOSE(char_type_id, CLOSE_DATATYPE)
MUST_CLOSE(dcpl_id, CLOSE_PLIST)
MUST_CLOSE(dspace_id, CLOSE_DATASPACE)
MUST_CLOSE(dset_id, CLOSE_DATASET)
MUST_CLOSE(mindset_id, CLOSE_DATASET)
MUST_CLOSE(attr_1_id, CLOSE_ATTRIBUTE)
MUST_CLOSE(attr_1a_id, CLOSE_ATTRIBUTE)
MUST_CLOSE(attr_2_id, CLOSE_ATTRIBUTE)
MUST_CLOSE(attr_2a_id, CLOSE_ATTRIBUTE)
MUST_CLOSE(attr_3_id, CLOSE_ATTRIBUTE)
MUST_CLOSE(attr_3a_id, CLOSE_ATTRIBUTE)
MUST_CLOSE(file_id, CLOSE_FILE)
PASSED()
return 0;
error :
H5E_BEGIN_TRY {
(void)H5Tclose(int_type_id);
(void)H5Tclose(char_type_id);
(void)H5Pclose(dcpl_id);
(void)H5Sclose(dspace_id);
(void)H5Dclose(dset_id);
(void)H5Dclose(mindset_id);
(void)H5Aclose(attr_1_id);
(void)H5Aclose(attr_1a_id);
(void)H5Aclose(attr_2_id);
(void)H5Aclose(attr_2a_id);
(void)H5Aclose(attr_3_id);
(void)H5Aclose(attr_3a_id);
(void)H5Fclose(file_id);
} H5E_END_TRY;
return 1;
} /* test_attribute_addition */
/* ---------------------------------------------------------------------------
* Function: test_size_comparisons()
*
* Purpose: Examine when headers have been minimized.
*
* Return: 0 (pass) or 1 (failure)
*
* ---------------------------------------------------------------------------
*/
static int
test_size_comparisons(void)
{
hsize_t array_10[1] = {10}; /* dataspace extents */
/* IDs that are file-agnostic */
hid_t dspace_id = -1;
hid_t int_type_id = -1;
hid_t dcpl_minimize = -1;
hid_t dcpl_dontmin = -1;
/* IDs for non-minimzed file open */
hid_t file_f_id = -1; /* lower 'f' for standard file setting */
hid_t dset_f_x_id = -1; /* 'x' for default */
hid_t dset_f_N_id = -1; /* 'N' for explcit non-minimized dset */
hid_t dset_f_Y_id = -1; /* 'Y' for minimzed dset */
/* IDs for minimzed file open */
hid_t file_F_id = -1; /* upper 'F' for minimzed file setting */
hid_t dset_F_x_id = -1; /* 'x' for default */
hid_t dset_F_N_id = -1; /* 'N' for explcit non-minimized dset */
hid_t dset_F_Y_id = -1; /* 'Y' for minimzed dset */
char filename_a[512] = "";
char filename_b[512] = "";
TESTING("default size comparisons");
/*********
* SETUP *
*********/
FAIL_IF( NULL == h5_fixname(
OHMIN_FILENAME_A,
H5P_DEFAULT,
filename_a,
sizeof(filename_a)) )
FAIL_IF( NULL == h5_fixname(
OHMIN_FILENAME_B,
H5P_DEFAULT,
filename_b,
sizeof(filename_b)) )
dcpl_minimize = H5Pcreate(H5P_DATASET_CREATE);
FAIL_IF( 0 > dcpl_minimize )
JSVERIFY( SUCCEED,
H5Pset_dset_no_attrs_hint(dcpl_minimize, TRUE),
NULL )
dcpl_dontmin = H5Pcreate(H5P_DATASET_CREATE);
FAIL_IF( 0 > dcpl_dontmin )
JSVERIFY( SUCCEED,
H5Pset_dset_no_attrs_hint(dcpl_dontmin, FALSE),
NULL )
dspace_id = H5Screate_simple(
1, /* rank */
array_10, /* current dimensions */
NULL); /* maximum dimensions */
FAIL_IF( 0 > dspace_id )
int_type_id = H5Tcopy(H5T_NATIVE_INT);
FAIL_IF( 0 > int_type_id )
CREATE_FILE(filename_a, &file_f_id)
CREATE_DATASET( \
file_f_id, \
"default", \
int_type_id, \
dspace_id, \
H5P_DEFAULT, \
&dset_f_x_id)
CREATE_DATASET( \
file_f_id, \
"dsetNOT", \
int_type_id, \
dspace_id, \
dcpl_dontmin, \
&dset_f_N_id)
CREATE_DATASET( \
file_f_id, \
"dsetMIN", \
int_type_id, \
dspace_id, \
dcpl_minimize, \
&dset_f_Y_id)
CREATE_FILE(filename_b, &file_F_id)
FAIL_IF( 0 > H5Fset_dset_no_attrs_hint(file_F_id, TRUE) )
CREATE_DATASET( \
file_F_id, \
"default", \
int_type_id, \
dspace_id, \
H5P_DEFAULT, \
&dset_F_x_id)
CREATE_DATASET( \
file_F_id, \
"dsetNOT", \
int_type_id, \
dspace_id, \
dcpl_dontmin, \
&dset_F_N_id)
CREATE_DATASET( \
file_F_id, \
"dsetMIN", \
int_type_id, \
dspace_id, \
dcpl_minimize, \
&dset_F_Y_id)
/*********
* TESTS *
*********/
JSVERIFY( EQ, oh_compare(dset_f_x_id, dset_f_x_id), NULL ) /* identity */
JSVERIFY( EQ, oh_compare(dset_f_x_id, dset_f_N_id), NULL )
JSVERIFY( GT, oh_compare(dset_f_x_id, dset_f_Y_id), NULL )
JSVERIFY( GT, oh_compare(dset_f_N_id, dset_f_Y_id), NULL )
JSVERIFY( EQ, oh_compare(dset_F_x_id, dset_F_N_id), NULL )
JSVERIFY( EQ, oh_compare(dset_F_x_id, dset_F_Y_id), NULL )
JSVERIFY( EQ, oh_compare(dset_F_N_id, dset_F_Y_id), NULL )
JSVERIFY( EQ, oh_compare(dset_F_x_id, dset_f_Y_id), NULL )
JSVERIFY( LT, oh_compare(dset_F_x_id, dset_f_x_id), NULL )
if (DEBUG_OH_SIZE)
PRINT_DSET_OH_COMPARISON(dset_f_x_id, dset_F_x_id)
/************
* TEARDOWN *
************/
MUST_CLOSE(dspace_id, CLOSE_DATASPACE)
MUST_CLOSE(int_type_id, CLOSE_DATATYPE)
MUST_CLOSE(dcpl_minimize, CLOSE_PLIST)
MUST_CLOSE(dcpl_dontmin, CLOSE_PLIST)
MUST_CLOSE(file_f_id, CLOSE_FILE)
MUST_CLOSE(dset_f_x_id, CLOSE_DATASET)
MUST_CLOSE(dset_f_N_id, CLOSE_DATASET)
MUST_CLOSE(dset_f_Y_id, CLOSE_DATASET)
MUST_CLOSE(file_F_id, CLOSE_FILE)
MUST_CLOSE(dset_F_x_id, CLOSE_DATASET)
MUST_CLOSE(dset_F_N_id, CLOSE_DATASET)
MUST_CLOSE(dset_F_Y_id, CLOSE_DATASET)
PASSED()
return 0;
error :
H5E_BEGIN_TRY {
(void)H5Pclose(dcpl_minimize);
(void)H5Pclose(dcpl_dontmin);
(void)H5Sclose(dspace_id);
(void)H5Tclose(int_type_id);
(void)H5Fclose(file_f_id);
(void)H5Dclose(dset_f_x_id);
(void)H5Dclose(dset_f_N_id);
(void)H5Dclose(dset_f_Y_id);
(void)H5Fclose(file_F_id);
(void)H5Dclose(dset_F_x_id);
(void)H5Dclose(dset_F_N_id);
(void)H5Dclose(dset_F_Y_id);
} H5E_END_TRY;
return 1;
} /* test_size_comparisons */
/* ---------------------------------------------------------------------------
* Test minimized dataset header with filter/pipeline message
* ---------------------------------------------------------------------------
*/
static int
test_minimized_with_filter(void)
{
char filename[512] = "";
const hsize_t extents[1] = {1024}; /* extents of dataspace */
const unsigned filter_values[] = {0}; /* TBD */
const hsize_t chunk_dim[] = {32}; /* needed for filter */
const int ndims = 1;
hid_t dspace_id = -1;
hid_t dtype_id = -1;
hid_t dcpl_xZ_id = -1;
hid_t dcpl_mx_id = -1;
hid_t dcpl_mZ_id = -1;
hid_t dset_xx_id = -1;
hid_t dset_xZ_id = -1;
hid_t dset_mx_id = -1;
hid_t dset_mZ_id = -1;
hid_t file_id = -1;
/* | default | minimize
* ----------+---------+---------
* no filter | xx | mx
* ----------+---------+---------
* filter | xZ | mZ
*/
TESTING("with filter message");
/*********
* SETUP *
*********/
FAIL_IF( NULL == h5_fixname(
OHMIN_FILENAME_A,
H5P_DEFAULT,
filename,
sizeof(filename)) )
dcpl_mx_id = H5Pcreate(H5P_DATASET_CREATE);
FAIL_IF( 0 > dcpl_mx_id )
JSVERIFY( SUCCEED,
H5Pset_dset_no_attrs_hint(dcpl_mx_id, TRUE),
NULL )
dcpl_xZ_id = H5Pcreate(H5P_DATASET_CREATE);
FAIL_IF( 0 > dcpl_xZ_id )
JSVERIFY( SUCCEED,
H5Pset_chunk(dcpl_xZ_id, ndims, chunk_dim),
"unable to chunk dataset")
JSVERIFY( SUCCEED,
H5Pset_filter(
dcpl_xZ_id,
H5Z_FILTER_DEFLATE,
H5Z_FLAG_OPTIONAL,
0,
filter_values),
"unable to set compression")
dcpl_mZ_id = H5Pcreate(H5P_DATASET_CREATE);
FAIL_IF( 0 > dcpl_mZ_id )
JSVERIFY( SUCCEED,
H5Pset_dset_no_attrs_hint(dcpl_mZ_id, TRUE),
"unable to minimize to-be-filtered dataset header")
JSVERIFY( SUCCEED,
H5Pset_chunk(dcpl_mZ_id, ndims, chunk_dim),
"unable to chunk minimized dataset")
JSVERIFY( SUCCEED,
H5Pset_filter(
dcpl_mZ_id,
H5Z_FILTER_DEFLATE,
H5Z_FLAG_OPTIONAL,
0,
filter_values),
"unable to set compression (minimized)")
dspace_id = H5Screate_simple(1, extents, extents);
FAIL_IF( 0 > dspace_id )
dtype_id = H5Tcopy(H5T_NATIVE_INT);
FAIL_IF( 0 > dtype_id )
CREATE_FILE(filename, &file_id)
CREATE_DATASET( \
file_id, \
"xx", \
dtype_id, \
dspace_id, \
H5P_DEFAULT, \
&dset_xx_id)
CREATE_DATASET( \
file_id, \
"Mx", \
dtype_id, \
dspace_id, \
dcpl_mx_id, \
&dset_mx_id)
CREATE_DATASET( \
file_id, \
"xZ", \
dtype_id, \
dspace_id, \
dcpl_xZ_id, \
&dset_xZ_id)
CREATE_DATASET( \
file_id, \
"MZ", \
dtype_id, \
dspace_id, \
dcpl_mZ_id, \
&dset_mZ_id)
/*********
* TESTS *
*********/
JSVERIFY( LT, oh_compare(dset_mx_id, dset_xx_id), NULL )
JSVERIFY( LT, oh_compare(dset_mx_id, dset_xZ_id), NULL )
JSVERIFY( GT, oh_compare(dset_mZ_id, dset_mx_id), NULL )
JSVERIFY( LT, oh_compare(dset_mZ_id, dset_xZ_id), NULL )
if (DEBUG_OH_SIZE)
PRINT_DSET_OH_COMPARISON(dset_xZ_id, dset_mZ_id)
/************
* TEARDOWN *
************/
MUST_CLOSE(dspace_id, CLOSE_DATASPACE)
MUST_CLOSE(dtype_id, CLOSE_DATATYPE)
MUST_CLOSE(dcpl_xZ_id, CLOSE_PLIST)
MUST_CLOSE(dcpl_mx_id, CLOSE_PLIST)
MUST_CLOSE(dcpl_mZ_id, CLOSE_PLIST)
MUST_CLOSE(dset_xx_id, CLOSE_DATASET)
MUST_CLOSE(dset_xZ_id, CLOSE_DATASET)
MUST_CLOSE(dset_mx_id, CLOSE_DATASET)
MUST_CLOSE(dset_mZ_id, CLOSE_DATASET)
MUST_CLOSE(file_id, CLOSE_FILE)
PASSED()
return 0;
error:
H5E_BEGIN_TRY {
(void)H5Sclose(dspace_id);
(void)H5Tclose(dtype_id);
(void)H5Pclose(dcpl_xZ_id);
(void)H5Pclose(dcpl_mx_id);
(void)H5Pclose(dcpl_mZ_id);
(void)H5Dclose(dset_xx_id);
(void)H5Dclose(dset_xZ_id);
(void)H5Dclose(dset_mx_id);
(void)H5Dclose(dset_mZ_id);
(void)H5Fclose(file_id);
} H5E_END_TRY;
return 1;
} /* test_minimized_with_filter */
/* ---------------------------------------------------------------------------
* Test minimized and recording modification times.
* ---------------------------------------------------------------------------
*/
static int
test_modification_times(void)
{
char filename[512] = "";
const hsize_t extents[1] = {128}; /* extents of dataspace */
hid_t dspace_id = -1;
hid_t dtype_id = -1;
hid_t dcpl_xM_id = -1; /* Modtime */
hid_t dcpl_mx_id = -1; /* minimized */
hid_t dcpl_mM_id = -1; /* minimized, Modtime */
hid_t dcpl_mN_id = -1; /* minimized, do not track */
hid_t dset_xx_id = -1;
hid_t dset_xM_id = -1;
hid_t dset_mx_id = -1;
hid_t dset_mM_id = -1;
hid_t dset_mN_id = -1;
hid_t file_id = -1;
TESTING("with modification times");
/*********
* SETUP *
*********/
FAIL_IF( NULL == h5_fixname(
OHMIN_FILENAME_A,
H5P_DEFAULT,
filename,
sizeof(filename)) )
dcpl_mx_id = H5Pcreate(H5P_DATASET_CREATE);
FAIL_IF( 0 > dcpl_mx_id )
JSVERIFY( SUCCEED,
H5Pset_dset_no_attrs_hint(dcpl_mx_id, TRUE),
NULL )
dcpl_xM_id = H5Pcreate(H5P_DATASET_CREATE);
FAIL_IF( 0 > dcpl_xM_id )
JSVERIFY( SUCCEED,
H5Pset_obj_track_times(dcpl_xM_id, TRUE),
"unable to set unminimized dcpl to track modtime" )
dcpl_mM_id = H5Pcreate(H5P_DATASET_CREATE);
FAIL_IF( 0 > dcpl_mM_id )
JSVERIFY( SUCCEED,
H5Pset_dset_no_attrs_hint(dcpl_mM_id, TRUE),
"unable to minimize to-be-filtered dataset header")
JSVERIFY( SUCCEED,
H5Pset_obj_track_times(dcpl_mM_id, TRUE),
"unable to set minimized dcpl to track modtime" )
dcpl_mN_id = H5Pcreate(H5P_DATASET_CREATE);
FAIL_IF( 0 > dcpl_mN_id )
JSVERIFY( SUCCEED,
H5Pset_dset_no_attrs_hint(dcpl_mN_id, TRUE),
"unable to minimize to-be-filtered dataset header")
JSVERIFY( SUCCEED,
H5Pset_obj_track_times(dcpl_mN_id, FALSE),
"unable to set minimized dcpl to NOT track modtime" )
dspace_id = H5Screate_simple(1, extents, extents);
FAIL_IF( 0 > dspace_id )
dtype_id = H5Tcopy(H5T_NATIVE_INT);
FAIL_IF( 0 > dtype_id )
CREATE_FILE(filename, &file_id)
CREATE_DATASET( \
file_id, \
"xx", \
dtype_id, \
dspace_id, \
H5P_DEFAULT, \
&dset_xx_id)
CREATE_DATASET( \
file_id, \
"mx", \
dtype_id, \
dspace_id, \
dcpl_mx_id, \
&dset_mx_id)
CREATE_DATASET( \
file_id, \
"xM", \
dtype_id, \
dspace_id, \
dcpl_xM_id, \
&dset_xM_id)
CREATE_DATASET( \
file_id, \
"mM", \
dtype_id, \
dspace_id, \
dcpl_mM_id, \
&dset_mM_id)
CREATE_DATASET( \
file_id, \
"mN", \
dtype_id, \
dspace_id, \
dcpl_mN_id, \
&dset_mN_id)
/*********
* TESTS *
*********/
/* sanity check */
FAIL_IF( LT != oh_compare(dset_mx_id, dset_xx_id) )
FAIL_IF( LT != oh_compare(dset_mx_id, dset_xM_id) )
if (DEBUG_OH_SIZE) {
PRINT_DSET_OH_COMPARISON(dset_xx_id, dset_mx_id)
PRINT_DSET_OH_COMPARISON(dset_xM_id, dset_mM_id)
PRINT_DSET_OH_COMPARISON(dset_mM_id, dset_mN_id)
}
/* TODO: do dataset headers support modification time tracking?
* If not, this equality makes more sense?
*/
JSVERIFY( EQ, oh_compare(dset_xx_id, dset_xM_id), NULL )
JSVERIFY( EQ, oh_compare(dset_mx_id, dset_mM_id), NULL )
JSVERIFY( EQ, oh_compare(dset_mN_id, dset_mM_id), NULL )
JSVERIFY( LT, oh_compare(dset_mM_id, dset_xM_id),
"minimized should still be smaller than unminimized" )
/************
* TEARDOWN *
************/
MUST_CLOSE(dspace_id, CLOSE_DATASPACE)
MUST_CLOSE(dtype_id, CLOSE_DATATYPE)
MUST_CLOSE(dcpl_xM_id, CLOSE_PLIST)
MUST_CLOSE(dcpl_mx_id, CLOSE_PLIST)
MUST_CLOSE(dcpl_mM_id, CLOSE_PLIST)
MUST_CLOSE(dcpl_mN_id, CLOSE_PLIST)
MUST_CLOSE(dset_xx_id, CLOSE_DATASET)
MUST_CLOSE(dset_xM_id, CLOSE_DATASET)
MUST_CLOSE(dset_mx_id, CLOSE_DATASET)
MUST_CLOSE(dset_mM_id, CLOSE_DATASET)
MUST_CLOSE(dset_mN_id, CLOSE_DATASET)
MUST_CLOSE(file_id, CLOSE_FILE)
PASSED()
return 0;
error:
H5E_BEGIN_TRY {
(void)H5Sclose(dspace_id);
(void)H5Tclose(dtype_id);
(void)H5Pclose(dcpl_xM_id);
(void)H5Pclose(dcpl_mx_id);
(void)H5Pclose(dcpl_mM_id);
(void)H5Pclose(dcpl_mN_id);
(void)H5Dclose(dset_xx_id);
(void)H5Dclose(dset_xM_id);
(void)H5Dclose(dset_mx_id);
(void)H5Dclose(dset_mM_id);
(void)H5Dclose(dset_mN_id);
(void)H5Fclose(file_id);
} H5E_END_TRY;
return 1;
} /* test_modification_times */
/* ---------------------------------------------------------------------------
* Test minimized dataset header with a fill value set.
* ---------------------------------------------------------------------------
*/
static int
test_fillvalue_backwards_compatability(void)
{
char filename[512] = "";
const hsize_t extents[1] = {64}; /* extents of dataspace */
const int fill[1] = {343}; /* fill value of dataset */
hid_t file_id = -1;
hid_t dtype_id = -1;
hid_t dspace_id = -1;
hid_t dcpl_id = -1;
hid_t fapl_id = -1;
hid_t dset_0_id = -1;
hid_t dset_1_id = -1;
/*********
* SETUP *
*********/
TESTING("with fill values and different libver support");
FAIL_IF( NULL == h5_fixname(
OHMIN_FILENAME_A,
H5P_DEFAULT,
filename,
sizeof(filename)) )
dspace_id = H5Screate_simple(1, extents, extents);
FAIL_IF( 0 > dspace_id )
dtype_id = H5Tcopy(H5T_NATIVE_INT);
FAIL_IF( 0 > dtype_id )
dcpl_id = H5Pcreate(H5P_DATASET_CREATE);
FAIL_IF( 0 > dcpl_id )
FAIL_IF( FAIL == H5Pset_dset_no_attrs_hint(dcpl_id, TRUE) )
FAIL_IF( FAIL == H5Pset_fill_value(dcpl_id, dtype_id, fill) )
fapl_id = H5Pcreate(H5P_FILE_ACCESS);
FAIL_IF( 0 > fapl_id )
FAIL_IF( FAIL == H5Pset_libver_bounds(
fapl_id,
H5F_LIBVER_EARLIEST,
H5F_LIBVER_LATEST) )
file_id = H5Fcreate(
filename,
H5F_ACC_TRUNC,
H5P_DEFAULT,
fapl_id);
FAIL_IF( 0 > file_id )
CREATE_DATASET( \
file_id, \
"fullrange", \
dtype_id, \
dspace_id, \
dcpl_id, \
&dset_0_id)
/* Close file and re-open with different libver bounds
*/
H5Fclose(file_id);
file_id = -1;
FAIL_IF( FAIL == H5Pset_libver_bounds(
fapl_id,
H5F_LIBVER_V18,
H5F_LIBVER_LATEST) )
file_id = H5Fopen(
filename,
H5F_ACC_RDWR,
fapl_id);
FAIL_IF( 0 > file_id )
CREATE_DATASET( \
file_id, \
"upperrange", \
dtype_id, \
dspace_id, \
dcpl_id, \
&dset_1_id)
/*********
* TESTS *
*********/
if (DEBUG_OH_SIZE)
PRINT_DSET_OH_COMPARISON(dset_1_id, dset_0_id)
JSVERIFY( LT, oh_compare(dset_1_id, dset_0_id),
"dset not supporting pre-1.08 should be smaller?")
/************
* TEARDOWN *
************/
MUST_CLOSE(dspace_id, CLOSE_DATASPACE)
MUST_CLOSE(dtype_id, CLOSE_DATATYPE)
MUST_CLOSE(dcpl_id, CLOSE_PLIST)
MUST_CLOSE(fapl_id, CLOSE_PLIST)
MUST_CLOSE(dset_0_id, CLOSE_DATASET)
MUST_CLOSE(dset_1_id, CLOSE_DATASET)
MUST_CLOSE(file_id, CLOSE_FILE)
PASSED()
return 0;
error:
H5E_BEGIN_TRY {
(void)H5Sclose(dspace_id);
(void)H5Tclose(dtype_id);
(void)H5Pclose(dcpl_id);
(void)H5Pclose(fapl_id);
(void)H5Dclose(dset_0_id);
(void)H5Dclose(dset_1_id);
(void)H5Fclose(file_id);
} H5E_END_TRY;
return 1;
} /* test_fillvalue_backwards_compatability */
/* ---------------------------------------------------------------------------
* Test creation of minimized datset through an external link
* ---------------------------------------------------------------------------
*/
static int
test_external_creation(void)
{
char moochname[512] = "";
char targetname[512] = "";
const hsize_t extents[2] = {5,5};
hid_t mooch_fid = -1;
hid_t target_fid = -1;
hid_t dspace_id = -1;
hid_t dtype_id = -1;
hid_t dcpl_id = -1;
hid_t dset_id = -1;
/*********
* SETUP *
*********/
TESTING("creation through external links")
FAIL_IF( NULL == h5_fixname(
OHMIN_FILENAME_A,
H5P_DEFAULT,
moochname,
sizeof(moochname)) )
FAIL_IF( NULL == h5_fixname(
OHMIN_FILENAME_B,
H5P_DEFAULT,
targetname,
sizeof(targetname)) )
dspace_id = H5Screate_simple(2, extents, extents);
FAIL_IF( 0 > dspace_id )
dtype_id = H5Tcopy(H5T_NATIVE_INT);
FAIL_IF( 0 > dtype_id )
dcpl_id = H5Pcreate(H5P_DATASET_CREATE);
FAIL_IF( 0 > dcpl_id )
FAIL_IF( FAIL == H5Pset_dset_no_attrs_hint(dcpl_id, TRUE) )
CREATE_FILE(moochname, &mooch_fid)
JSVERIFY( SUCCEED,
H5Lcreate_external(
targetname, /* path to target file */
"/", /* absolute path in target file */
mooch_fid, /* loc-id where to create link */
"ext_root", /* name of link, relative to loc above */
H5P_DEFAULT, /* lcpl */
H5P_DEFAULT), /* lapl */
"unable to create external link to target" )
/* delete target file from system, if it exists
*/
H5E_BEGIN_TRY {
target_fid = H5Fopen(
targetname,
H5F_ACC_RDONLY,
H5P_DEFAULT);
if (-1 < target_fid) {
/* file found; close and delete */
MUST_CLOSE(target_fid, CLOSE_FILE)
h5_delete_test_file(OHMIN_FILENAME_B, H5P_DEFAULT);
/* verify that file was deleted */
target_fid = H5Fopen(
targetname,
H5F_ACC_RDONLY,
H5P_DEFAULT);
JSVERIFY( -1, target_fid, "target file still exists" )
}
} H5E_END_TRY;
/*********
* TESTS *
*********/
/*----------------
* demonstrate that we cannot create a dataset through a dangling link
*/
H5E_BEGIN_TRY {
JSVERIFY( -1,
H5Dcreate(
mooch_fid,
"ext_root/dataset",
dtype_id,
dspace_id,
H5P_DEFAULT, /* lcpl id */
dcpl_id,
H5P_DEFAULT), /* dapl id */
"creating dataset in nonexistent file should fail")
} H5E_END_TRY;
/*----------------
* Create dataset through valid external link
*/
CREATE_FILE(targetname, &target_fid)
dset_id = H5Dcreate(
mooch_fid,
"ext_root/dataset",
dtype_id,
dspace_id,
H5P_DEFAULT, /* LAPL */
dcpl_id,
H5P_DEFAULT); /* DAPL */
FAIL_IF( 0 > dset_id )
/* equivalent to above explicit creation
*/
/*
JSVERIFY( SUCCEED,
_make_dataset(
mooch_fid,
"ext_root/dataset",
dtype_id,
dspace_id,
dcpl_id,
&dset_id),
"unable to create dataset through link" )
*/
/* equivalent to above explicit creation
*/
/*
CREATE_DATASET(
mooch_fid,
"ext_root/dataset",
dtype_id,
dspace_id,
dcpl_id,
&dset_id)
*/
/************
* TEARDOWN *
************/
MUST_CLOSE(dspace_id, CLOSE_DATASPACE)
MUST_CLOSE(dtype_id, CLOSE_DATATYPE)
MUST_CLOSE(dcpl_id, CLOSE_PLIST)
MUST_CLOSE(dset_id, CLOSE_DATASET)
MUST_CLOSE(mooch_fid, CLOSE_FILE)
MUST_CLOSE(target_fid, CLOSE_FILE)
PASSED()
return 0;
error:
H5E_BEGIN_TRY {
(void)H5Sclose(dspace_id);
(void)H5Tclose(dtype_id);
(void)H5Pclose(dcpl_id);
(void)H5Dclose(dset_id);
(void)H5Fclose(mooch_fid);
(void)H5Fclose(target_fid);
} H5E_END_TRY;
return 1;
} /* test_external_creation */
/********
* MAIN *
********/
/* ---------------------------------------------------------------------------
* Main function is main. Runs tests.
*
* Returns number of failed tests.
* ---------------------------------------------------------------------------
*/
int
main(void)
{
int nerrors = 0;
HDprintf("Testing minimized dataset object headers.\n");
nerrors += test_attribute_addition();
nerrors += test_size_comparisons();
nerrors += test_minimized_with_filter();
nerrors += test_modification_times(); /* TODO: valid for datasets? */
nerrors += test_fillvalue_backwards_compatability();
nerrors += test_external_creation();
if (nerrors > 0) {
HDprintf("***** %d MINIMIZED DATASET OHDR TEST%s FAILED! *****\n",
nerrors,
nerrors > 1 ? "S" : "");
} else {
HDprintf("All minimized dataset object header tests passed.\n");
}
return nerrors;
} /* main */