mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-02-11 16:01:00 +08:00
1841 lines
56 KiB
C
1841 lines
56 KiB
C
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||
* 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 */
|
||
|
||
|