Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add compound subset ops on attributes to API tests #4005

Merged
merged 2 commits into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
265 changes: 265 additions & 0 deletions test/API/H5_api_attribute_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ static int test_attribute_iterate_datatype(void);
static int test_attribute_iterate_index_saving(void);
static int test_attribute_iterate_invalid_params(void);
static int test_attribute_iterate_0_attributes(void);
static int test_attribute_compound_subset(void);
static int test_attribute_string_encodings(void);
static int test_delete_attribute(void);
static int test_delete_attribute_invalid_params(void);
Expand Down Expand Up @@ -100,6 +101,7 @@ static int (*attribute_tests[])(void) = {test_create_attribute_on_root,
test_attribute_iterate_index_saving,
test_attribute_iterate_invalid_params,
test_attribute_iterate_0_attributes,
test_attribute_compound_subset,
test_attribute_string_encodings,
test_delete_attribute,
test_delete_attribute_invalid_params,
Expand Down Expand Up @@ -8335,6 +8337,269 @@ test_attribute_iterate_0_attributes(void)
return 1;
}

/* A compound type for test_attribute_compound_subset */
typedef struct attribute_compound_io_t {
int a;
int b;
} attribute_compound_io_t;

/*
* A test to ensure that data is read back correctly from a attribute after it has
* been written, using subsets of compound datatypes
*/
static int
test_attribute_compound_subset(void)
{
hsize_t dims[1] = {ATTRIBUTE_COMPOUND_IO_ATTR_DIMS};
size_t i;
hid_t file_id = H5I_INVALID_HID;
hid_t container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
hid_t attr_id = H5I_INVALID_HID;
hid_t space_id = H5I_INVALID_HID;
hid_t full_type_id = H5I_INVALID_HID;
hid_t a_type_id = H5I_INVALID_HID;
hid_t b_type_id = H5I_INVALID_HID;
attribute_compound_io_t wbuf[ATTRIBUTE_COMPOUND_IO_ATTR_DIMS];
attribute_compound_io_t rbuf[ATTRIBUTE_COMPOUND_IO_ATTR_DIMS];
attribute_compound_io_t fbuf[ATTRIBUTE_COMPOUND_IO_ATTR_DIMS];
attribute_compound_io_t erbuf[ATTRIBUTE_COMPOUND_IO_ATTR_DIMS];

TESTING_MULTIPART(
"verification of attribute data using H5Awrite then H5Aread with compound type subsets");

/* Make sure the connector supports the API functions being tested */
if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
!(vol_cap_flags_g & H5VL_CAP_FLAG_ATTR_BASIC)) {
SKIPPED();
printf(
" API functions for basic file, group, or attribute aren't supported with this connector\n");
return 0;
}

TESTING_2("test setup");

if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
H5_FAILED();
printf(" couldn't open file '%s'\n", H5_api_test_filename);
goto error;
}

if ((container_group = H5Gopen2(file_id, ATTRIBUTE_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
H5_FAILED();
printf(" couldn't open container group '%s'\n", ATTRIBUTE_TEST_GROUP_NAME);
goto error;
}

if ((group_id = H5Gcreate2(container_group, ATTRIBUTE_COMPOUND_IO_TEST_GROUP_NAME, H5P_DEFAULT,
H5P_DEFAULT, H5P_DEFAULT)) < 0) {
H5_FAILED();
printf(" couldn't create container sub-group '%s'\n", ATTRIBUTE_COMPOUND_IO_TEST_GROUP_NAME);
goto error;
}

if ((space_id = H5Screate_simple(1, dims, NULL)) < 0)
TEST_ERROR;

if ((full_type_id = H5Tcreate(H5T_COMPOUND, sizeof(attribute_compound_io_t))) < 0)
TEST_ERROR;
if (H5Tinsert(full_type_id, "a", HOFFSET(attribute_compound_io_t, a), H5T_NATIVE_INT) < 0)
TEST_ERROR;
if (H5Tinsert(full_type_id, "b", HOFFSET(attribute_compound_io_t, b), H5T_NATIVE_INT) < 0)
TEST_ERROR;

if ((a_type_id = H5Tcreate(H5T_COMPOUND, sizeof(attribute_compound_io_t))) < 0)
TEST_ERROR;
if (H5Tinsert(a_type_id, "a", HOFFSET(attribute_compound_io_t, a), H5T_NATIVE_INT) < 0)
TEST_ERROR;

if ((b_type_id = H5Tcreate(H5T_COMPOUND, sizeof(attribute_compound_io_t))) < 0)
TEST_ERROR;
if (H5Tinsert(b_type_id, "b", HOFFSET(attribute_compound_io_t, b), H5T_NATIVE_INT) < 0)
TEST_ERROR;

if ((attr_id = H5Acreate2(group_id, ATTRIBUTE_COMPOUND_IO_TEST_ATTR_NAME, full_type_id, space_id,
H5P_DEFAULT, H5P_DEFAULT)) < 0) {
H5_FAILED();
printf(" couldn't create attribute '%s'\n", ATTRIBUTE_COMPOUND_IO_TEST_ATTR_NAME);
goto error;
}

PASSED();

BEGIN_MULTIPART
{
PART_BEGIN(write_full_read_full)
{
TESTING_2("H5Awrite then H5Aread with all compound members");

/* Initialize wbuf */
for (i = 0; i < ATTRIBUTE_COMPOUND_IO_ATTR_DIMS; i++) {
wbuf[i].a = (int)(2 * i);
wbuf[i].b = (int)(2 * i + 1);
}

/* Write data */
if (H5Awrite(attr_id, full_type_id, wbuf) < 0)
PART_TEST_ERROR(write_full_read_full);

/* Update fbuf to match file state */
for (i = 0; i < ATTRIBUTE_COMPOUND_IO_ATTR_DIMS; i++) {
fbuf[i].a = wbuf[i].a;
fbuf[i].b = wbuf[i].b;
}

/* Initialize rbuf to -1 */
for (i = 0; i < ATTRIBUTE_COMPOUND_IO_ATTR_DIMS; i++) {
rbuf[i].a = -1;
rbuf[i].b = -1;
}

/* Set erbuf (simply match file state since we're reading the whole
* thing) */
for (i = 0; i < ATTRIBUTE_COMPOUND_IO_ATTR_DIMS; i++) {
erbuf[i].a = fbuf[i].a;
erbuf[i].b = fbuf[i].b;
}

/* Read data */
if (H5Aread(attr_id, full_type_id, rbuf) < 0)
PART_TEST_ERROR(write_full_read_full);

/* Verify data */
for (i = 0; i < ATTRIBUTE_COMPOUND_IO_ATTR_DIMS; i++) {
if (rbuf[i].a != erbuf[i].a)
PART_TEST_ERROR(write_full_read_full);
if (rbuf[i].b != erbuf[i].b)
PART_TEST_ERROR(write_full_read_full);
}

PASSED();
}
PART_END(write_full_read_full);

PART_BEGIN(read_a)
{
TESTING_2("H5Aread with compound member a");

/* Initialize rbuf to -1 */
for (i = 0; i < ATTRIBUTE_COMPOUND_IO_ATTR_DIMS; i++) {
rbuf[i].a = -1;
rbuf[i].b = -1;
}

/* Set erbuf (element a comes from the file, element b in untouched)
*/
for (i = 0; i < ATTRIBUTE_COMPOUND_IO_ATTR_DIMS; i++) {
erbuf[i].a = fbuf[i].a;
erbuf[i].b = rbuf[i].b;
}

/* Read data */
if (H5Aread(attr_id, a_type_id, rbuf) < 0)
PART_TEST_ERROR(read_a);

/* Verify data */
for (i = 0; i < ATTRIBUTE_COMPOUND_IO_ATTR_DIMS; i++) {
if (rbuf[i].a != erbuf[i].a)
PART_TEST_ERROR(read_a);
if (rbuf[i].b != erbuf[i].b)
PART_TEST_ERROR(read_a);
}

PASSED();
}
PART_END(read_a);

PART_BEGIN(write_b_read_full)
{
TESTING_2("H5Awrite with compound member b then H5Aread with all compound members");

/* Initialize wbuf */
for (i = 0; i < ATTRIBUTE_COMPOUND_IO_ATTR_DIMS; i++) {
wbuf[i].a = (int)(2 * ATTRIBUTE_COMPOUND_IO_ATTR_DIMS + 2 * i);
wbuf[i].b = (int)(2 * ATTRIBUTE_COMPOUND_IO_ATTR_DIMS + 2 * i + 1);
}

/* Write data */
if (H5Awrite(attr_id, b_type_id, wbuf) < 0)
PART_TEST_ERROR(write_b_read_full);

/* Update fbuf to match file state - only element b was updated */
for (i = 0; i < ATTRIBUTE_COMPOUND_IO_ATTR_DIMS; i++) {
fbuf[i].b = wbuf[i].b;
}

/* Initialize rbuf to -1 */
for (i = 0; i < ATTRIBUTE_COMPOUND_IO_ATTR_DIMS; i++) {
rbuf[i].a = -1;
rbuf[i].b = -1;
}

/* Set erbuf (simply match file state since we're reading the whole
* thing) */
for (i = 0; i < ATTRIBUTE_COMPOUND_IO_ATTR_DIMS; i++) {
erbuf[i].a = fbuf[i].a;
erbuf[i].b = fbuf[i].b;
}

/* Read data */
if (H5Aread(attr_id, full_type_id, rbuf) < 0)
PART_TEST_ERROR(write_b_read_full);

/* Verify data */
for (i = 0; i < ATTRIBUTE_COMPOUND_IO_ATTR_DIMS; i++) {
if (rbuf[i].a != erbuf[i].a)
PART_TEST_ERROR(write_b_read_full);
if (rbuf[i].b != erbuf[i].b)
PART_TEST_ERROR(write_b_read_full);
}

PASSED();
}
PART_END(write_b_read_full);
}
END_MULTIPART;

TESTING_2("test cleanup");

if (H5Sclose(space_id) < 0)
TEST_ERROR;
if (H5Aclose(attr_id) < 0)
TEST_ERROR;
if (H5Gclose(group_id) < 0)
TEST_ERROR;
if (H5Gclose(container_group) < 0)
TEST_ERROR;
if (H5Fclose(file_id) < 0)
TEST_ERROR;
if (H5Tclose(full_type_id) < 0)
TEST_ERROR;
if (H5Tclose(a_type_id) < 0)
TEST_ERROR;
if (H5Tclose(b_type_id) < 0)
TEST_ERROR;

PASSED();

return 0;

error:
H5E_BEGIN_TRY
{
H5Sclose(space_id);
H5Aclose(attr_id);
H5Gclose(group_id);
H5Gclose(container_group);
H5Fclose(file_id);
H5Tclose(full_type_id);
H5Tclose(a_type_id);
H5Tclose(b_type_id);
}
H5E_END_TRY;

return 1;
}

/*
* A test to check that attributes preserve data
* correctness for strings with ASCII or UTF-8 char sets
Expand Down
4 changes: 4 additions & 0 deletions test/API/H5_api_attribute_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,10 @@ int H5_api_attribute_test(void);
#define ATTRIBUTE_ITERATE_TEST_0_ATTRIBUTES_SUBGROUP_NAME "attribute_iterate_test_0_attributes"
#define ATTRIBUTE_ITERATE_TEST_0_ATTRIBUTES_DSET_NAME "attribute_iterate_dset"

#define ATTRIBUTE_COMPOUND_IO_ATTR_DIMS 10
#define ATTRIBUTE_COMPOUND_IO_TEST_GROUP_NAME "attribute_compound_io_test_group"
#define ATTRIBUTE_COMPOUND_IO_TEST_ATTR_NAME "attribute_compound_io_test_attr"

#define ATTRIBUTE_STRING_ENCODINGS_RANK 1
#define ATTRIBUTE_STRING_ENCODINGS_EXTENT 1
#define ATTRIBUTE_STRING_ENCODINGS_DSET_NAME1 "encoding_dset1"
Expand Down
Loading