diff --git a/vol_attribute_test.c b/vol_attribute_test.c index 4d46f6d..4a0bc9d 100644 --- a/vol_attribute_test.c +++ b/vol_attribute_test.c @@ -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_string_encodings(void); static int test_delete_attribute(void); static int test_delete_attribute_invalid_params(void); static int test_attribute_exists(void); @@ -99,6 +100,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_string_encodings, test_delete_attribute, test_delete_attribute_invalid_params, test_attribute_exists, @@ -8346,6 +8348,273 @@ test_attribute_iterate_0_attributes(void) return 1; } +/* + * A test to check that attributes preserve data + * correctness for strings with ASCII or UTF-8 char sets + */ +static int +test_attribute_string_encodings(void) +{ + hid_t file_id = H5I_INVALID_HID; + hid_t container_group = H5I_INVALID_HID; + hid_t dset_id1 = H5I_INVALID_HID; + hid_t dset_id2 = H5I_INVALID_HID; + hid_t type_id1 = H5I_INVALID_HID; + hid_t type_id2 = H5I_INVALID_HID; + hid_t space_id = H5I_INVALID_HID; + hid_t attr_id1 = H5I_INVALID_HID; + hid_t attr_id2 = H5I_INVALID_HID; + hsize_t dims[ATTRIBUTE_STRING_ENCODINGS_RANK] = {ATTRIBUTE_STRING_ENCODINGS_EXTENT}; + size_t ascii_str_size = 0; + size_t utf8_str_size = 0; + char *write_buf = NULL; + char *read_buf = NULL; + + TESTING_MULTIPART("string encoding read/write correctness on attributes"); + + /* 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_DATASET_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_ATTR_BASIC)) { + SKIPPED(); + HDprintf(" API functions for basic file, group, basic or more dataset aren't supported with this " + "connector\n"); + return 0; + } + + TESTING_2("test setup"); + + ascii_str_size = strlen(ATTRIBUTE_STRING_ENCODINGS_ASCII_STRING); + utf8_str_size = strlen(ATTRIBUTE_STRING_ENCODINGS_UTF8_STRING); + + if ((file_id = H5Fopen(vol_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open file '%s'\n", vol_test_filename); + goto error; + } + + if ((container_group = H5Gopen2(file_id, ATTRIBUTE_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open container group '%s'\n", ATTRIBUTE_TEST_GROUP_NAME); + goto error; + } + + if ((space_id = H5Screate_simple(ATTRIBUTE_STRING_ENCODINGS_RANK, dims, NULL)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create dataspace\n"); + goto error; + } + + if ((type_id1 = H5Tcopy(H5T_C_S1)) < 0) { + H5_FAILED(); + HDprintf(" couldn't copy builtin string datatype\n"); + goto error; + } + + if ((H5Tset_size(type_id1, ascii_str_size)) < 0) { + H5_FAILED(); + HDprintf(" couldn't set size of string datatype\n"); + goto error; + } + + if ((H5Tset_cset(type_id1, H5T_CSET_ASCII)) < 0) { + H5_FAILED(); + HDprintf(" couldn't set character set of string to ASCII\n"); + goto error; + } + + if ((dset_id1 = H5Dcreate(container_group, ATTRIBUTE_STRING_ENCODINGS_DSET_NAME1, type_id1, space_id, + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create dataset with ascii string\n"); + goto error; + } + + if ((attr_id1 = H5Acreate(dset_id1, ATTRIBUTE_STRING_ENCODINGS_ATTR_NAME1, type_id1, space_id, + H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create attribute with ascii string\n"); + goto error; + } + + if ((type_id2 = H5Tcopy(H5T_C_S1)) < 0) { + H5_FAILED(); + HDprintf(" couldn't copy builtin string datatype\n"); + goto error; + } + + if ((H5Tset_size(type_id2, utf8_str_size)) < 0) { + H5_FAILED(); + HDprintf(" couldn't set size of string datatype\n"); + goto error; + } + + if ((H5Tset_cset(type_id2, H5T_CSET_UTF8)) < 0) { + H5_FAILED(); + HDprintf(" couldn't set character set of string to UTF-8\n"); + goto error; + } + + if ((dset_id2 = H5Dcreate(container_group, ATTRIBUTE_STRING_ENCODINGS_DSET_NAME2, type_id2, space_id, + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create dataset with UTF-8 string\n"); + goto error; + } + + if ((attr_id2 = H5Acreate(dset_id2, ATTRIBUTE_STRING_ENCODINGS_ATTR_NAME2, type_id2, space_id, + H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create attribute with ascii string\n"); + goto error; + } + + PASSED(); + + BEGIN_MULTIPART + { + PART_BEGIN(ASCII_cset) + { + TESTING_2("ASCII character set"); + if ((write_buf = calloc(1, ascii_str_size + 1)) == NULL) { + H5_FAILED(); + HDprintf(" couldn't allocate memory for write buffer\n"); + goto error; + } + + memcpy(write_buf, ATTRIBUTE_STRING_ENCODINGS_ASCII_STRING, ascii_str_size); + + if ((read_buf = calloc(1, ascii_str_size + 1)) == NULL) { + H5_FAILED(); + HDprintf(" couldn't allocate memory for read buffer\n"); + goto error; + } + + if (H5Awrite(attr_id1, type_id1, write_buf) < 0) { + H5_FAILED(); + HDprintf(" couldn't write to attribute with ASCII string\n"); + goto error; + } + + if (H5Aread(attr_id1, type_id1, read_buf) < 0) { + H5_FAILED(); + HDprintf(" couldn't read from attribute with ASCII string\n"); + goto error; + } + + if (strncmp(write_buf, read_buf, ascii_str_size)) { + H5_FAILED(); + HDprintf(" incorrect data read from attribute with ASCII string\n"); + goto error; + } + + free(write_buf); + write_buf = NULL; + + free(read_buf); + read_buf = NULL; + + PASSED(); + } + PART_END(ASCII_cset); + + PART_BEGIN(UTF8_cset) + { + TESTING_2("UTF-8 character set"); + + if ((write_buf = calloc(1, utf8_str_size + 1)) == NULL) { + H5_FAILED(); + HDprintf(" couldn't allocate memory for write buffer\n"); + goto error; + } + + memcpy(write_buf, ATTRIBUTE_STRING_ENCODINGS_UTF8_STRING, utf8_str_size); + + if ((read_buf = calloc(1, utf8_str_size + 1)) == NULL) { + H5_FAILED(); + HDprintf(" couldn't allocate memory for read buffer\n"); + goto error; + } + + if (H5Awrite(attr_id2, type_id2, write_buf) < 0) { + H5_FAILED(); + HDprintf(" couldn't write to attribute with UTF-8 string\n"); + goto error; + } + + if (H5Aread(attr_id2, type_id2, read_buf) < 0) { + H5_FAILED(); + HDprintf(" couldn't read from attribute with UTF-8 string\n"); + goto error; + } + + if (strncmp(write_buf, read_buf, utf8_str_size)) { + H5_FAILED(); + HDprintf(" incorrect data read from attribute with UTF-8 string\n"); + goto error; + } + + free(write_buf); + write_buf = NULL; + + free(read_buf); + read_buf = NULL; + + PASSED(); + } + PART_END(UTF8_cset); + + PASSED(); + } + END_MULTIPART; + +done: + TESTING_2("test cleanup"); + + if (H5Fclose(file_id) < 0) + TEST_ERROR; + if (H5Gclose(container_group) < 0) + TEST_ERROR; + if (H5Dclose(dset_id1) < 0) + TEST_ERROR; + if (H5Dclose(dset_id2) < 0) + TEST_ERROR; + if (H5Tclose(type_id1) < 0) + TEST_ERROR; + if (H5Tclose(type_id2) < 0) + TEST_ERROR; + if (H5Aclose(attr_id1) < 0) + TEST_ERROR; + if (H5Aclose(attr_id2) < 0) + TEST_ERROR; + if (write_buf) + free(write_buf); + if (read_buf) + free(read_buf); + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY + { + H5Fclose(file_id); + H5Gclose(container_group); + H5Dclose(dset_id1); + H5Dclose(dset_id2); + H5Tclose(type_id1); + H5Tclose(type_id2); + H5Aclose(attr_id1); + H5Aclose(attr_id2); + if (write_buf) + free(write_buf); + if (read_buf) + free(read_buf); + } + H5E_END_TRY; + + return 1; +} + /* * A test to check that an attribute can be deleted * using H5Adelete(_by_idx). diff --git a/vol_attribute_test.h b/vol_attribute_test.h index 592bca4..087a13e 100644 --- a/vol_attribute_test.h +++ b/vol_attribute_test.h @@ -156,6 +156,15 @@ int vol_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_STRING_ENCODINGS_RANK 1 +#define ATTRIBUTE_STRING_ENCODINGS_EXTENT 1 +#define ATTRIBUTE_STRING_ENCODINGS_DSET_NAME1 "encoding_dset1" +#define ATTRIBUTE_STRING_ENCODINGS_DSET_NAME2 "encoding_dset2" +#define ATTRIBUTE_STRING_ENCODINGS_ASCII_STRING "asciistr" +#define ATTRIBUTE_STRING_ENCODINGS_UTF8_STRING "αaααaaaα" +#define ATTRIBUTE_STRING_ENCODINGS_ATTR_NAME1 "encoding_attr1" +#define ATTRIBUTE_STRING_ENCODINGS_ATTR_NAME2 "encoding_attr2" + #define ATTRIBUTE_ITERATE_INVALID_PARAMS_TEST_ATTR_SPACE_RANK 1 #define ATTRIBUTE_ITERATE_INVALID_PARAMS_TEST_SUBGROUP_NAME "attribute_iterate_invalid_params_test" #define ATTRIBUTE_ITERATE_INVALID_PARAMS_TEST_ATTR_NAME "invalid_params_iter_attr1" diff --git a/vol_dataset_test.c b/vol_dataset_test.c index 508154b..4b5bb15 100644 --- a/vol_dataset_test.c +++ b/vol_dataset_test.c @@ -56,6 +56,7 @@ static int test_write_dataset_small_hyperslab(void); static int test_write_dataset_small_point_selection(void); static int test_write_dataset_data_verification(void); static int test_write_dataset_invalid_params(void); +static int test_dataset_string_encodings(void); static int test_dataset_builtin_type_conversion(void); static int test_dataset_compound_partial_io(void); static int test_dataset_set_extent_chunked_unlimited(void); @@ -128,6 +129,7 @@ static int (*dataset_tests[])(void) = { test_write_dataset_small_point_selection, test_write_dataset_data_verification, test_write_dataset_invalid_params, + test_dataset_string_encodings, test_dataset_builtin_type_conversion, test_dataset_compound_partial_io, test_dataset_set_extent_chunked_unlimited, @@ -1262,10 +1264,10 @@ test_create_dataset_predefined_types(void) hid_t fspace_id = H5I_INVALID_HID; hid_t dset_id = H5I_INVALID_HID; hid_t predefined_type_test_table[] = {H5T_STD_U8LE, H5T_STD_U8BE, H5T_STD_I8LE, H5T_STD_I8BE, - H5T_STD_U16LE, H5T_STD_U16BE, H5T_STD_I16LE, H5T_STD_I16BE, - H5T_STD_U32LE, H5T_STD_U32BE, H5T_STD_I32LE, H5T_STD_I32BE, - H5T_STD_U64LE, H5T_STD_U64BE, H5T_STD_I64LE, H5T_STD_I64BE, - H5T_IEEE_F32LE, H5T_IEEE_F32BE, H5T_IEEE_F64LE, H5T_IEEE_F64BE}; + H5T_STD_U16LE, H5T_STD_U16BE, H5T_STD_I16LE, H5T_STD_I16BE, + H5T_STD_U32LE, H5T_STD_U32BE, H5T_STD_I32LE, H5T_STD_I32BE, + H5T_STD_U64LE, H5T_STD_U64BE, H5T_STD_I64LE, H5T_STD_I64BE, + H5T_IEEE_F32LE, H5T_IEEE_F32BE, H5T_IEEE_F64LE, H5T_IEEE_F64BE}; TESTING("dataset creation with predefined datatypes"); @@ -6764,6 +6766,251 @@ test_write_dataset_invalid_params(void) return 1; } +/* + * A test to ensure that strings of any encoding + * can be written to and read from a dataset + */ +static int +test_dataset_string_encodings(void) +{ + hid_t file_id = H5I_INVALID_HID; + hid_t container_group = H5I_INVALID_HID; + hid_t dset_id1 = H5I_INVALID_HID; + hid_t dset_id2 = H5I_INVALID_HID; + hid_t type_id1 = H5I_INVALID_HID; + hid_t type_id2 = H5I_INVALID_HID; + hid_t space_id = H5I_INVALID_HID; + hsize_t dims[DATASET_STRING_ENCODINGS_RANK] = {DATASET_STRING_ENCODINGS_EXTENT}; + size_t ascii_str_size = 0; + size_t utf8_str_size = 0; + char *write_buf = NULL; + char *read_buf = NULL; + + TESTING_MULTIPART("string encoding read/write correctness on datasets"); + + /* 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_DATASET_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_ATTR_BASIC)) { + SKIPPED(); + HDprintf(" API functions for basic file, group, basic or more dataset aren't supported with this " + "connector\n"); + return 0; + } + + TESTING_2("test setup"); + + ascii_str_size = strlen(DATASET_STRING_ENCODINGS_ASCII_STRING); + utf8_str_size = strlen(DATASET_STRING_ENCODINGS_UTF8_STRING); + + if ((file_id = H5Fopen(vol_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open file '%s'\n", vol_test_filename); + goto error; + } + + if ((container_group = H5Gopen2(file_id, DATASET_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open container group '%s'\n", DATASET_TEST_GROUP_NAME); + goto error; + } + + if ((space_id = H5Screate_simple(DATASET_STRING_ENCODINGS_RANK, dims, NULL)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create dataspace\n"); + goto error; + } + + if ((type_id1 = H5Tcopy(H5T_C_S1)) < 0) { + H5_FAILED(); + HDprintf(" couldn't copy builtin string datatype\n"); + goto error; + } + + if ((H5Tset_size(type_id1, ascii_str_size)) < 0) { + H5_FAILED(); + HDprintf(" couldn't set size of string datatype\n"); + goto error; + } + + if ((H5Tset_cset(type_id1, H5T_CSET_ASCII)) < 0) { + H5_FAILED(); + HDprintf(" couldn't set character set of string to ASCII\n"); + goto error; + } + + if ((dset_id1 = H5Dcreate(container_group, DATASET_STRING_ENCODINGS_DSET_NAME1, type_id1, space_id, + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create dataset with ascii string\n"); + goto error; + } + + if ((type_id2 = H5Tcopy(H5T_C_S1)) < 0) { + H5_FAILED(); + HDprintf(" couldn't copy builtin string datatype\n"); + goto error; + } + + if ((H5Tset_size(type_id2, utf8_str_size)) < 0) { + H5_FAILED(); + HDprintf(" couldn't set size of string datatype\n"); + goto error; + } + + if ((H5Tset_cset(type_id2, H5T_CSET_UTF8)) < 0) { + H5_FAILED(); + HDprintf(" couldn't set character set of string to UTF-8\n"); + goto error; + } + + if ((dset_id2 = H5Dcreate(container_group, DATASET_STRING_ENCODINGS_DSET_NAME2, type_id2, space_id, + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create dataset with UTF-8 string\n"); + goto error; + } + + PASSED(); + + BEGIN_MULTIPART + { + PART_BEGIN(ASCII_cset) + { + TESTING_2("ASCII character set"); + /* Dataset with ASCII string datatype */ + if ((write_buf = calloc(1, ascii_str_size + 1)) == NULL) { + H5_FAILED(); + HDprintf(" couldn't allocate memory for write buffer\n"); + goto error; + } + + memcpy(write_buf, DATASET_STRING_ENCODINGS_ASCII_STRING, ascii_str_size); + + if ((H5Dwrite(dset_id1, type_id1, H5S_ALL, H5S_ALL, H5P_DEFAULT, write_buf)) < 0) { + H5_FAILED(); + HDprintf(" couldn't write to dataset with ASCII string\n"); + goto error; + } + + if ((read_buf = calloc(1, ascii_str_size + 1)) == NULL) { + H5_FAILED(); + HDprintf(" couldn't allocate memory for read buffer\n"); + goto error; + } + + if ((H5Dread(dset_id1, type_id1, H5S_ALL, H5S_ALL, H5P_DEFAULT, read_buf)) < 0) { + H5_FAILED(); + HDprintf(" couldn't read from dataset with ASCII string\n"); + goto error; + } + + if (strncmp(write_buf, read_buf, ascii_str_size)) { + H5_FAILED(); + HDprintf(" incorrect data read from dataset with ASCII string\n"); + goto error; + } + + free(write_buf); + write_buf = NULL; + + free(read_buf); + read_buf = NULL; + + PASSED(); + } + PART_END(ASCII_cset); + + PART_BEGIN(UTF8_cset) + { + TESTING_2("UTF-8 character set"); + /* Dataset with UTF-8 string datatype */ + if ((write_buf = calloc(1, utf8_str_size + 1)) == NULL) { + H5_FAILED(); + HDprintf(" couldn't allocate memory for write buffer\n"); + goto error; + } + + memcpy(write_buf, DATASET_STRING_ENCODINGS_UTF8_STRING, utf8_str_size); + + if ((H5Dwrite(dset_id2, type_id2, H5S_ALL, H5S_ALL, H5P_DEFAULT, write_buf)) < 0) { + H5_FAILED(); + HDprintf(" couldn't write to dataset with ASCII string\n"); + goto error; + } + + if ((read_buf = calloc(1, utf8_str_size + 1)) == NULL) { + H5_FAILED(); + HDprintf(" couldn't allocate memory for read buffer\n"); + goto error; + } + + if ((H5Dread(dset_id2, type_id2, H5S_ALL, H5S_ALL, H5P_DEFAULT, read_buf)) < 0) { + H5_FAILED(); + HDprintf(" couldn't read from dataset with ASCII string\n"); + goto error; + } + + if (strncmp(write_buf, read_buf, utf8_str_size)) { + H5_FAILED(); + HDprintf(" incorrect data read from dataset with ASCII string\n"); + goto error; + } + + free(write_buf); + write_buf = NULL; + + free(read_buf); + read_buf = NULL; + + PASSED(); + } + PART_END(UTF8_cset); + + PASSED(); + } + END_MULTIPART; + +done: + TESTING_2("test cleanup"); + + if (H5Fclose(file_id) < 0) + TEST_ERROR; + if (H5Gclose(container_group) < 0) + TEST_ERROR; + if (H5Dclose(dset_id1) < 0) + TEST_ERROR; + if (H5Dclose(dset_id2) < 0) + TEST_ERROR; + if (H5Tclose(type_id1) < 0) + TEST_ERROR; + if (H5Tclose(type_id2) < 0) + TEST_ERROR; + if (write_buf) + free(write_buf); + if (read_buf) + free(read_buf); + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY + { + H5Fclose(file_id); + H5Gclose(container_group); + H5Dclose(dset_id1); + H5Dclose(dset_id2); + H5Tclose(type_id1); + H5Tclose(type_id2); + if (write_buf) + free(write_buf); + if (read_buf) + free(read_buf); + } + H5E_END_TRY; + + return 1; +} /* * A test to ensure that data is read back correctly from a dataset after it has * been written, using type conversion with builtin types. diff --git a/vol_dataset_test.h b/vol_dataset_test.h index 8211492..ae2a590 100644 --- a/vol_dataset_test.h +++ b/vol_dataset_test.h @@ -49,6 +49,13 @@ int vol_dataset_test(void); #define DATASET_CREATE_ANONYMOUS_INVALID_PARAMS_GROUP_NAME "anon_dset_creation_invalid_params_test" #define DATASET_CREATE_ANONYMOUS_INVALID_PARAMS_SPACE_RANK 2 +#define DATASET_STRING_ENCODINGS_RANK 1 +#define DATASET_STRING_ENCODINGS_EXTENT 1 +#define DATASET_STRING_ENCODINGS_DSET_NAME1 "encoding_dset1" +#define DATASET_STRING_ENCODINGS_DSET_NAME2 "encoding_dset2" +#define DATASET_STRING_ENCODINGS_ASCII_STRING "asciistr" +#define DATASET_STRING_ENCODINGS_UTF8_STRING "αaααaaaα" + #define DATASET_CREATE_NULL_DATASPACE_TEST_SUBGROUP_NAME "dataset_with_null_space_test" #define DATASET_CREATE_NULL_DATASPACE_TEST_DSET_NAME "dataset_with_null_space"