/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright by The HDF Group. * * All rights reserved. * * * * This file is part of HDF5. The full HDF5 copyright notice, including * * terms governing use, modification, and redistribution, is contained in * * the COPYING file, which can be found at the root of the source code * * distribution tree, or in https://www.hdfgroup.org/licenses. * * If you do not have access to either file, you may request a copy from * * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * Purpose: Tests the virtual object layer (H5VL) * * This is a minimal test to ensure VOL usage (setting a VOL, etc.) * works as expected. Actual VOL functionality is tested using * other mechanisms. */ /* Headers needed */ #include "h5test.h" /* Filename */ const char *FILENAME[] = {"native_vol_test", NULL}; #define NATIVE_VOL_TEST_GROUP_NAME "test_group" #define NATIVE_VOL_TEST_DATASET_NAME "test_dataset" #define NATIVE_VOL_TEST_ATTRIBUTE_NAME "test_dataset" #define NATIVE_VOL_TEST_HARD_LINK_NAME "test_hard_link" #define NATIVE_VOL_TEST_SOFT_LINK_NAME "test_soft_link" #define NATIVE_VOL_TEST_MOVE_LINK_NAME "test_move_link" #define NATIVE_VOL_TEST_COPY_LINK_NAME "test_copy_link" #define NATIVE_VOL_TEST_DATATYPE_NAME "test_datatype" #define N_ELEMENTS 10 #define FAKE_VOL_NAME "fake" #define FAKE_VOL_VALUE ((H5VL_class_value_t)501) /* A VOL class struct that describes a VOL class with no * functionality. */ static const H5VL_class_t fake_vol_g = { H5VL_VERSION, /* VOL class struct version */ FAKE_VOL_VALUE, /* value */ FAKE_VOL_NAME, /* name */ 0, /* capability flags */ NULL, /* initialize */ NULL, /* terminate */ { /* info_cls */ (size_t)0, /* size */ NULL, /* copy */ NULL, /* compare */ NULL, /* free */ NULL, /* to_str */ NULL, /* from_str */ }, { /* wrap_cls */ NULL, /* get_object */ NULL, /* get_wrap_ctx */ NULL, /* wrap_object */ NULL, /* unwrap_object */ NULL, /* free_wrap_ctx */ }, { /* attribute_cls */ NULL, /* create */ NULL, /* open */ NULL, /* read */ NULL, /* write */ NULL, /* get */ NULL, /* specific */ NULL, /* optional */ NULL /* close */ }, { /* dataset_cls */ NULL, /* create */ NULL, /* open */ NULL, /* read */ NULL, /* write */ NULL, /* get */ NULL, /* specific */ NULL, /* optional */ NULL /* close */ }, { /* datatype_cls */ NULL, /* commit */ NULL, /* open */ NULL, /* get */ NULL, /* specific */ NULL, /* optional */ NULL /* close */ }, { /* file_cls */ NULL, /* create */ NULL, /* open */ NULL, /* get */ NULL, /* specific */ NULL, /* optional */ NULL /* close */ }, { /* group_cls */ NULL, /* create */ NULL, /* open */ NULL, /* get */ NULL, /* specific */ NULL, /* optional */ NULL /* close */ }, { /* link_cls */ NULL, /* create */ NULL, /* copy */ NULL, /* move */ NULL, /* get */ NULL, /* specific */ NULL /* optional */ }, { /* object_cls */ NULL, /* open */ NULL, /* copy */ NULL, /* get */ NULL, /* specific */ NULL /* optional */ }, { /* introspect_cls */ NULL, /* get_conn_cls */ NULL, /* opt_query */ }, { /* request_cls */ NULL, /* wait */ NULL, /* notify */ NULL, /* cancel */ NULL, /* specific */ NULL, /* optional */ NULL /* free */ }, { /* blob_cls */ NULL, /* put */ NULL, /* get */ NULL, /* specific */ NULL /* optional */ }, { /* token_cls */ NULL, /* cmp */ NULL, /* to_str */ NULL /* from_str */ }, NULL /* optional */ }; /*------------------------------------------------------------------------- * Function: test_vol_registration() * * Purpose: Tests if we can load, register, and close a simple * VOL connector. * * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ static herr_t test_vol_registration(void) { hid_t native_id = H5I_INVALID_HID; hid_t lapl_id = H5I_INVALID_HID; hid_t vipl_id = H5I_INVALID_HID; herr_t ret = SUCCEED; htri_t is_registered = FAIL; hid_t vol_id = H5I_INVALID_HID; hid_t vol_id2 = H5I_INVALID_HID; H5VL_class_t *bad_fake_vol_class = NULL; TESTING("VOL registration"); /* The test/fake VOL connector should not be registered at the start of the test */ if ((is_registered = H5VLis_connector_registered_by_name(FAKE_VOL_NAME)) < 0) TEST_ERROR; if (is_registered > 0) FAIL_PUTS_ERROR("VOL connector is inappropriately registered"); if ((is_registered = H5VLis_connector_registered_by_value(FAKE_VOL_VALUE)) < 0) TEST_ERROR; if (is_registered > 0) FAIL_PUTS_ERROR("VOL connector is inappropriately registered"); /* Test registering a connector with an incorrect property list (SHOULD FAIL) */ if ((lapl_id = H5Pcreate(H5P_LINK_ACCESS)) < 0) TEST_ERROR; H5E_BEGIN_TRY { vol_id = H5VLregister_connector(&fake_vol_g, lapl_id); } H5E_END_TRY; if (H5I_INVALID_HID != vol_id) FAIL_PUTS_ERROR("should not be able to register a connector with an incorrect property list"); if (H5Pclose(lapl_id) < 0) TEST_ERROR; /* Test registering a VOL connector with an incompatible version # */ if (NULL == (bad_fake_vol_class = HDmalloc(sizeof(H5VL_class_t)))) TEST_ERROR; HDmemcpy(bad_fake_vol_class, &fake_vol_g, sizeof(H5VL_class_t)); bad_fake_vol_class->version = H5VL_VERSION + 1; H5E_BEGIN_TRY { vol_id = H5VLregister_connector(bad_fake_vol_class, H5P_DEFAULT); } H5E_END_TRY; if (H5I_INVALID_HID != vol_id) FAIL_PUTS_ERROR("should not be able to register a connector with an incompatible version #"); HDfree(bad_fake_vol_class); bad_fake_vol_class = NULL; /* Load a VOL interface * The vipl_id does nothing without a VOL that needs it, but we do need to * test creating a property list of that class and passing it along as a * smoke check. */ if ((vipl_id = H5Pcreate(H5P_VOL_INITIALIZE)) < 0) TEST_ERROR; if ((vol_id = H5VLregister_connector(&fake_vol_g, vipl_id)) < 0) TEST_ERROR; if (H5Pclose(vipl_id) < 0) TEST_ERROR; /* The test/fake VOL connector should be registered now */ if ((is_registered = H5VLis_connector_registered_by_name(FAKE_VOL_NAME)) < 0) TEST_ERROR; if (0 == is_registered) FAIL_PUTS_ERROR("VOL connector is un-registered"); if ((is_registered = H5VLis_connector_registered_by_value(FAKE_VOL_VALUE)) < 0) TEST_ERROR; if (0 == is_registered) FAIL_PUTS_ERROR("VOL connector is un-registered"); /* Re-register a VOL connector */ if ((vol_id2 = H5VLregister_connector(&fake_vol_g, H5P_DEFAULT)) < 0) TEST_ERROR; /* The test/fake VOL connector should still be registered now */ if ((is_registered = H5VLis_connector_registered_by_name(FAKE_VOL_NAME)) < 0) TEST_ERROR; if (0 == is_registered) FAIL_PUTS_ERROR("VOL connector is un-registered"); if ((is_registered = H5VLis_connector_registered_by_value(FAKE_VOL_VALUE)) < 0) TEST_ERROR; if (0 == is_registered) FAIL_PUTS_ERROR("VOL connector is un-registered"); /* Unregister the second test/fake VOL ID */ if (H5VLunregister_connector(vol_id2) < 0) TEST_ERROR; /* The test/fake VOL connector should still be registered now */ if ((is_registered = H5VLis_connector_registered_by_name(FAKE_VOL_NAME)) < 0) TEST_ERROR; if (0 == is_registered) FAIL_PUTS_ERROR("VOL connector is un-registered"); if ((is_registered = H5VLis_connector_registered_by_value(FAKE_VOL_VALUE)) < 0) TEST_ERROR; if (0 == is_registered) FAIL_PUTS_ERROR("VOL connector is un-registered"); /* Unregister the original test/fake VOL ID */ if (H5VLunregister_connector(vol_id) < 0) TEST_ERROR; /* Try to unregister the native VOL connector (should fail) */ if (H5I_INVALID_HID == (native_id = H5VLget_connector_id_by_name(H5VL_NATIVE_NAME))) TEST_ERROR; H5E_BEGIN_TRY { ret = H5VLunregister_connector(native_id); } H5E_END_TRY; if (FAIL != ret) FAIL_PUTS_ERROR("should not be able to unregister the native VOL connector"); PASSED(); return SUCCEED; error: H5E_BEGIN_TRY { H5VLunregister_connector(vol_id); H5Pclose(lapl_id); H5Pclose(vipl_id); } H5E_END_TRY; if (bad_fake_vol_class) HDfree(bad_fake_vol_class); return FAIL; } /* end test_vol_registration() */ /*------------------------------------------------------------------------- * Function: test_native_vol_init() * * Purpose: Tests if the native VOL connector gets initialized. * * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ static herr_t test_native_vol_init(void) { htri_t is_registered; TESTING("Native VOL connector initialization"); /* The native VOL connector should always be registered */ if ((is_registered = H5VLis_connector_registered_by_name(H5VL_NATIVE_NAME)) < 0) TEST_ERROR; if (0 == is_registered) FAIL_PUTS_ERROR("native VOL connector is un-registered"); if ((is_registered = H5VLis_connector_registered_by_value(H5VL_NATIVE_VALUE)) < 0) TEST_ERROR; if (0 == is_registered) FAIL_PUTS_ERROR("native VOL connector is un-registered"); PASSED(); return SUCCEED; error: return FAIL; } /* end test_native_vol_init() */ /*------------------------------------------------------------------------- * Function: test_basic_file_operation() * * Purpose: Uses the native VOL connector to test basic VOL file operations * * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ static herr_t test_basic_file_operation(const char *env_h5_drvr) { hid_t fid = H5I_INVALID_HID; hid_t fid_reopen = H5I_INVALID_HID; hid_t fapl_id = H5I_INVALID_HID; hid_t fapl_id2 = H5I_INVALID_HID; hid_t fcpl_id = H5I_INVALID_HID; char filename[1024]; ssize_t obj_count; hid_t obj_id_list[1]; hsize_t file_size; unsigned intent; void *os_file_handle = NULL; H5F_info2_t finfo; char name[32]; TESTING("Basic VOL file operations"); /* Retrieve the file access property for testing */ fapl_id = h5_fileaccess(); h5_fixname(FILENAME[0], fapl_id, filename, sizeof filename); /* Set the file close degree to a non-default value, to make the H5Pequal * work out. This is kinda odd, but the library's current behavior with * a default value is to return the value chosen (H5F_CLOSE_SEMI) instead * of the default value (H5F_CLOSE_DEFAULT) from the property and then * the H5Pequal doesn't detect that the property lists are the same. Since * this is the documented behavior for file close degree for many years, * I'm not fighting it, just getting the testing to verify that the VOL * connector property is returned correctly. -QAK, 2018/11/17 */ if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI) < 0) TEST_ERROR; if (H5Pset_metadata_read_attempts(fapl_id, 9) < 0) TEST_ERROR /* H5Fcreate */ if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0) TEST_ERROR; /* H5Fget_obj_count */ if ((obj_count = H5Fget_obj_count(fid, H5F_OBJ_FILE)) < 0) TEST_ERROR; if ((obj_count = H5Fget_obj_count(fid, H5F_OBJ_ALL)) < 0) TEST_ERROR; if ((obj_count = H5Fget_obj_count((hid_t)H5F_OBJ_ALL, H5F_OBJ_DATASET)) < 0) TEST_ERROR; /* H5Fget_obj_ids */ if ((obj_count = H5Fget_obj_ids(fid, H5F_OBJ_ALL, 2, obj_id_list)) < 0) TEST_ERROR; if ((obj_count = H5Fget_obj_ids((hid_t)H5F_OBJ_ALL, H5F_OBJ_DATASET, 2, obj_id_list)) < 0) TEST_ERROR; /* Can't compare VFD properties for split / multi / family VFDs */ if ((hbool_t)(HDstrcmp(env_h5_drvr, "split") != 0 && HDstrcmp(env_h5_drvr, "multi") != 0 && HDstrcmp(env_h5_drvr, "family") != 0)) { /* H5Fget_access_plist */ if ((fapl_id2 = H5Fget_access_plist(fid)) < 0) TEST_ERROR; if (H5Pequal(fapl_id, fapl_id2) != TRUE) TEST_ERROR; if (H5Pclose(fapl_id2) < 0) TEST_ERROR; } /* end if */ /* H5Fget_create_plist */ if ((fcpl_id = H5Fget_create_plist(fid)) < 0) TEST_ERROR; if (H5Pclose(fcpl_id) < 0) TEST_ERROR; /* H5Fget_filesize */ if (H5Fget_filesize(fid, &file_size) < 0) TEST_ERROR; /* Can't retrieve VFD handle for split / multi / family VFDs */ if ((hbool_t)(HDstrcmp(env_h5_drvr, "split") != 0 && HDstrcmp(env_h5_drvr, "multi") != 0 && HDstrcmp(env_h5_drvr, "family") != 0)) { /* H5Fget_vfd_handle */ if (H5Fget_vfd_handle(fid, H5P_DEFAULT, &os_file_handle) < 0) TEST_ERROR; } /* end if */ /* H5Fget_intent */ if (H5Fget_intent(fid, &intent) < 0) TEST_ERROR; /* H5Fget_info2 */ if (H5Fget_info2(fid, &finfo) < 0) TEST_ERROR; /* H5Fget_name */ if (H5Fget_name(fid, name, 32) < 0) TEST_ERROR; /* H5Fclear_elink_file_cache */ if (H5Fclear_elink_file_cache(fid) < 0) TEST_ERROR; /* H5Fflush */ if (H5Fflush(fid, H5F_SCOPE_GLOBAL) < 0) TEST_ERROR; /* H5Fclose */ if (H5Fclose(fid) < 0) TEST_ERROR; /* H5Fis_accessible */ if (H5Fis_accessible(filename, fapl_id) < 0) TEST_ERROR; /* H5Fopen */ if ((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl_id)) < 0) TEST_ERROR; /* Can't compare VFD properties for split / multi / family VFDs */ if ((hbool_t)(HDstrcmp(env_h5_drvr, "split") != 0 && HDstrcmp(env_h5_drvr, "multi") != 0 && HDstrcmp(env_h5_drvr, "family") != 0)) { /* H5Fget_access_plist */ if ((fapl_id2 = H5Fget_access_plist(fid)) < 0) TEST_ERROR; if (H5Pequal(fapl_id, fapl_id2) != TRUE) TEST_ERROR; if (H5Pclose(fapl_id2) < 0) TEST_ERROR; } /* end if */ if ((fid_reopen = H5Freopen(fid)) < 0) TEST_ERROR; /* Can't compare VFD properties for split / multi / family VFDs */ if ((hbool_t)(HDstrcmp(env_h5_drvr, "split") != 0 && HDstrcmp(env_h5_drvr, "multi") != 0 && HDstrcmp(env_h5_drvr, "family") != 0)) { /* H5Fget_access_plist */ if ((fapl_id2 = H5Fget_access_plist(fid_reopen)) < 0) TEST_ERROR; if (H5Pequal(fapl_id, fapl_id2) != TRUE) TEST_ERROR; if (H5Pclose(fapl_id2) < 0) TEST_ERROR; } /* end if */ if (H5Fclose(fid) < 0) TEST_ERROR; if (H5Fclose(fid_reopen) < 0) TEST_ERROR; h5_delete_test_file(FILENAME[0], fapl_id); /* H5Pclose */ if (H5Pclose(fapl_id) < 0) TEST_ERROR; PASSED(); return SUCCEED; error: H5E_BEGIN_TRY { H5Fclose(fid); H5Fclose(fid_reopen); H5Pclose(fapl_id); H5Pclose(fapl_id2); H5Pclose(fcpl_id); } H5E_END_TRY; return FAIL; } /* end test_basic_file_operation() */ /*------------------------------------------------------------------------- * Function: test_basic_group_operation() * * Purpose: Uses the native VOL connector to test basic VOL group operations * * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ static herr_t test_basic_group_operation(void) { hid_t fid = H5I_INVALID_HID; hid_t fapl_id = H5I_INVALID_HID; hid_t gid = H5I_INVALID_HID; hid_t gid_a = H5I_INVALID_HID; hid_t gcpl_id = H5I_INVALID_HID; char filename[1024]; H5G_info_t info; TESTING("Basic VOL group operations"); /* Retrieve the file access property for testing */ fapl_id = h5_fileaccess(); h5_fixname(FILENAME[0], fapl_id, filename, sizeof filename); if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0) TEST_ERROR; /* H5Gcreate */ if ((gid = H5Gcreate2(fid, NATIVE_VOL_TEST_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; /* H5Gget_create_plist */ if ((gcpl_id = H5Gget_create_plist(gid)) < 0) TEST_ERROR; if (H5Pclose(gcpl_id) < 0) TEST_ERROR; /* H5Gget_info */ if (H5Gget_info(gid, &info) < 0) TEST_ERROR; if (H5Gget_info(fid, &info) < 0) TEST_ERROR; /* H5Gget_info_by_name */ if (H5Gget_info_by_name(fid, NATIVE_VOL_TEST_GROUP_NAME, &info, H5P_DEFAULT) < 0) TEST_ERROR; /* H5Gget_info_by_idx */ if (H5Gget_info_by_idx(fid, "/", H5_INDEX_NAME, H5_ITER_NATIVE, 0, &info, H5P_DEFAULT) < 0) TEST_ERROR; /* H5Gflush */ if (H5Gflush(gid) < 0) TEST_ERROR; /* H5Gclose */ if (H5Gclose(gid) < 0) TEST_ERROR; /* H5Gopen */ if ((gid = H5Gopen2(fid, NATIVE_VOL_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) TEST_ERROR; /* H5Gcreate_anon */ if ((gid_a = H5Gcreate_anon(fid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; /* H5Grefresh */ if (H5Grefresh(gid) < 0) TEST_ERROR; if (H5Gclose(gid) < 0) TEST_ERROR; if (H5Gclose(gid_a) < 0) TEST_ERROR; if (H5Fclose(fid) < 0) TEST_ERROR; h5_delete_test_file(FILENAME[0], fapl_id); /* H5Pclose */ if (H5Pclose(fapl_id) < 0) TEST_ERROR; PASSED(); return SUCCEED; error: H5E_BEGIN_TRY { H5Fclose(fid); H5Gclose(gid); H5Pclose(fapl_id); H5Pclose(gcpl_id); } H5E_END_TRY; return FAIL; } /* end test_basic_group_operation() */ /*------------------------------------------------------------------------- * Function: test_basic_dataset_operation() * * Purpose: Uses the native VOL connector to test basic VOL dataset operations * * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ static herr_t test_basic_dataset_operation(void) { hid_t fid = H5I_INVALID_HID; hid_t fapl_id = H5I_INVALID_HID; hid_t dcpl_id = H5I_INVALID_HID; hid_t dapl_id = H5I_INVALID_HID; hid_t did = H5I_INVALID_HID; hid_t did_a = H5I_INVALID_HID; hid_t sid = H5I_INVALID_HID; hid_t tid = H5I_INVALID_HID; char filename[1024]; hsize_t curr_dims = 0; hsize_t max_dims = H5S_UNLIMITED; hsize_t storage_size; haddr_t offset; H5D_space_status_t status; int in_buf[N_ELEMENTS]; int out_buf[N_ELEMENTS]; int i; TESTING("Basic VOL dataset operations"); /* Retrieve the file access property for testing */ fapl_id = h5_fileaccess(); h5_fixname(FILENAME[0], fapl_id, filename, sizeof filename); if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0) TEST_ERROR; for (i = 0; i < N_ELEMENTS; i++) { in_buf[i] = i; out_buf[i] = 0; } /* H5Dcreate */ curr_dims = 0; if ((sid = H5Screate_simple(1, &curr_dims, &max_dims)) < 0) TEST_ERROR; curr_dims = N_ELEMENTS; if ((dcpl_id = H5Pcreate(H5P_DATASET_CREATE)) < 0) TEST_ERROR; if (H5Pset_chunk(dcpl_id, 1, &curr_dims) < 0) TEST_ERROR; if ((did = H5Dcreate2(fid, NATIVE_VOL_TEST_DATASET_NAME, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl_id, H5P_DEFAULT)) < 0) TEST_ERROR; /* H5Dcreate_anon */ if ((did_a = H5Dcreate_anon(fid, H5T_NATIVE_INT, sid, dcpl_id, H5P_DEFAULT)) < 0) TEST_ERROR; if (H5Sclose(sid) < 0) TEST_ERROR; if (H5Pclose(dcpl_id) < 0) TEST_ERROR; /* H5Dset_extent */ curr_dims = N_ELEMENTS; if (H5Dset_extent(did, &curr_dims) < 0) TEST_ERROR; /* H5Dflush */ if (H5Dflush(did) < 0) TEST_ERROR; /* H5Dwrite */ if (H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, in_buf) < 0) TEST_ERROR; /* H5Drefresh */ if (H5Drefresh(did) < 0) TEST_ERROR; /* H5Dclose */ if (H5Dclose(did) < 0) TEST_ERROR; if (H5Dclose(did_a) < 0) TEST_ERROR; /* H5Dopen */ if ((did = H5Dopen2(fid, NATIVE_VOL_TEST_DATASET_NAME, H5P_DEFAULT)) < 0) TEST_ERROR; /* H5Dget_space */ if ((sid = H5Dget_space(did)) < 0) TEST_ERROR; if (H5Sclose(sid) < 0) TEST_ERROR; /* H5Dget_space_status */ if (H5Dget_space_status(did, &status) < 0) TEST_ERROR; /* H5Dget_type */ if ((tid = H5Dget_type(did)) < 0) TEST_ERROR; if (H5Tclose(tid) < 0) TEST_ERROR; /* H5Tcopy (when used w/ a dataset, it gets an H5VL struct */ if ((tid = H5Tcopy(did)) < 0) TEST_ERROR; if (H5Tclose(tid) < 0) TEST_ERROR; /* H5Dget_create_plist */ if ((dcpl_id = H5Dget_create_plist(did)) < 0) TEST_ERROR; if (H5Pclose(dcpl_id) < 0) TEST_ERROR; /* H5Dget_access_plist */ if ((dapl_id = H5Dget_access_plist(did)) < 0) TEST_ERROR; if (H5Pclose(dapl_id) < 0) TEST_ERROR; /* H5Dget_storage_size */ /* XXX: This is a terrible API call that can't truly indicate failure */ if (0 == (storage_size = H5Dget_storage_size(did))) TEST_ERROR; /* H5Dget_offset */ /* XXX: Another bad API call that can't flag error values. Also, this * returns HADDR_UNDEF for chunked datasets, which is bizarre. */ if (HADDR_UNDEF != (offset = H5Dget_offset(did))) TEST_ERROR; /* H5Dread */ if (H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, out_buf) < 0) TEST_ERROR; for (i = 0; i < N_ELEMENTS; i++) if (in_buf[i] != out_buf[i]) TEST_ERROR; if (H5Dclose(did) < 0) TEST_ERROR; if (H5Fclose(fid) < 0) TEST_ERROR; h5_delete_test_file(FILENAME[0], fapl_id); /* H5Pclose */ if (H5Pclose(fapl_id) < 0) TEST_ERROR; PASSED(); return SUCCEED; error: H5E_BEGIN_TRY { H5Fclose(fid); H5Dclose(did); H5Dclose(did_a); H5Sclose(sid); H5Tclose(tid); H5Pclose(fapl_id); H5Pclose(dapl_id); H5Pclose(dcpl_id); } H5E_END_TRY; return FAIL; } /* end test_basic_dataset_operation() */ /*------------------------------------------------------------------------- * Function: test_basic_attribute_operation() * * Purpose: Uses the native VOL connector to test basic VOL attribute operations * * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ static herr_t test_basic_attribute_operation(void) { hid_t fid = H5I_INVALID_HID; hid_t fapl_id = H5I_INVALID_HID; hid_t gid = H5I_INVALID_HID; hid_t aid = H5I_INVALID_HID; hid_t aid_name = H5I_INVALID_HID; hid_t sid = H5I_INVALID_HID; char filename[1024]; hsize_t dims = 1; int data_in = 42; int data_out = 0; TESTING("Basic VOL attribute operations"); /* Retrieve the file access property for testing */ fapl_id = h5_fileaccess(); h5_fixname(FILENAME[0], fapl_id, filename, sizeof filename); if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0) TEST_ERROR; if ((gid = H5Gcreate2(fid, NATIVE_VOL_TEST_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; dims = 1; if ((sid = H5Screate_simple(1, &dims, &dims)) < 0) TEST_ERROR; /* H5Acreate */ if ((aid = H5Acreate2(fid, NATIVE_VOL_TEST_ATTRIBUTE_NAME, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; /* H5Awrite */ if (H5Awrite(aid, H5T_NATIVE_INT, &data_in) < 0) TEST_ERROR; /* H5Aread */ if (H5Aread(aid, H5T_NATIVE_INT, &data_out) < 0) TEST_ERROR; if (data_in != data_out) TEST_ERROR; /* H5Aclose */ if (H5Aclose(aid) < 0) TEST_ERROR; /* H5Aopen */ if ((aid = H5Aopen(fid, NATIVE_VOL_TEST_ATTRIBUTE_NAME, H5P_DEFAULT)) < 0) TEST_ERROR; if (H5Aclose(aid) < 0) TEST_ERROR; /* H5Adelete */ if (H5Adelete(fid, NATIVE_VOL_TEST_ATTRIBUTE_NAME) < 0) TEST_ERROR; /* H5Acreate_by_name */ if ((aid_name = H5Acreate_by_name(fid, NATIVE_VOL_TEST_GROUP_NAME, NATIVE_VOL_TEST_ATTRIBUTE_NAME, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; /* H5Aclose */ if (H5Aclose(aid_name) < 0) TEST_ERROR; /* H5Adelete_by_name */ if (H5Adelete_by_name(fid, NATIVE_VOL_TEST_GROUP_NAME, NATIVE_VOL_TEST_ATTRIBUTE_NAME, H5P_DEFAULT) < 0) TEST_ERROR; if (H5Sclose(sid) < 0) TEST_ERROR; if (H5Gclose(gid) < 0) TEST_ERROR; if (H5Fclose(fid) < 0) TEST_ERROR; h5_delete_test_file(FILENAME[0], fapl_id); /* H5Pclose */ if (H5Pclose(fapl_id) < 0) TEST_ERROR; PASSED(); return SUCCEED; error: H5E_BEGIN_TRY { H5Fclose(fid); H5Pclose(fapl_id); H5Gclose(gid); H5Sclose(sid); H5Aclose(aid); H5Aclose(aid_name); } H5E_END_TRY; return FAIL; } /* end test_basic_attribute_operation() */ /*------------------------------------------------------------------------- * Function: test_basic_object_operation() * * Purpose: Uses the native VOL connector to test basic VOL object operations * * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ static herr_t test_basic_object_operation(void) { hid_t fid = H5I_INVALID_HID; hid_t fapl_id = H5I_INVALID_HID; hid_t gid = H5I_INVALID_HID; hid_t oid = H5I_INVALID_HID; char filename[1024]; H5O_info2_t object_info; TESTING("Basic VOL object operations"); /* Retrieve the file access property for testing */ fapl_id = h5_fileaccess(); h5_fixname(FILENAME[0], fapl_id, filename, sizeof filename); if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0) TEST_ERROR; if ((gid = H5Gcreate2(fid, NATIVE_VOL_TEST_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; /* H5Oget_info */ if (H5Oget_info3(fid, &object_info, H5O_INFO_ALL) < 0) TEST_ERROR; //! [H5Oget_info_by_name3_snip] /* H5Oget_info_by_name */ if (H5Oget_info_by_name3(fid, NATIVE_VOL_TEST_GROUP_NAME, &object_info, H5O_INFO_ALL, H5P_DEFAULT) < 0) TEST_ERROR; //! [H5Oget_info_by_name3_snip] /* H5Oexists_by_name */ if (H5Oexists_by_name(fid, NATIVE_VOL_TEST_GROUP_NAME, H5P_DEFAULT) != TRUE) TEST_ERROR; /* H5Oopen/close */ if ((oid = H5Oopen(fid, NATIVE_VOL_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) TEST_ERROR; if (H5Oclose(oid) < 0) TEST_ERROR; if (H5Fclose(fid) < 0) TEST_ERROR; if (H5Gclose(gid) < 0) TEST_ERROR; h5_delete_test_file(FILENAME[0], fapl_id); /* H5Pclose */ if (H5Pclose(fapl_id) < 0) TEST_ERROR; PASSED(); return SUCCEED; error: H5E_BEGIN_TRY { H5Fclose(fid); H5Pclose(fapl_id); H5Gclose(gid); } H5E_END_TRY; return FAIL; } /* end test_basic_object_operation() */ /*------------------------------------------------------------------------- * Function: test_basic_link_operation() * * Purpose: Uses the native VOL connector to test basic VOL link operations * * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ static herr_t test_basic_link_operation(void) { hid_t fid = H5I_INVALID_HID; hid_t gid = H5I_INVALID_HID; hid_t fapl_id = H5I_INVALID_HID; char filename[1024]; TESTING("Basic VOL link operations"); /* Retrieve the file access property for testing */ fapl_id = h5_fileaccess(); h5_fixname(FILENAME[0], fapl_id, filename, sizeof filename); if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0) TEST_ERROR; if ((gid = H5Gcreate2(fid, NATIVE_VOL_TEST_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; /* H5Lcreate_hard */ if (H5Lcreate_hard(fid, "/", gid, NATIVE_VOL_TEST_HARD_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; /* H5Lcreate_soft (to itself) */ if (H5Lcreate_soft("/", fid, NATIVE_VOL_TEST_SOFT_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; /* H5Lexists */ if (H5Lexists(gid, NATIVE_VOL_TEST_HARD_LINK_NAME, H5P_DEFAULT) < 0) TEST_ERROR; if (H5Lexists(fid, NATIVE_VOL_TEST_SOFT_LINK_NAME, H5P_DEFAULT) < 0) TEST_ERROR; /* H5Lcopy */ if (H5Lcopy(gid, NATIVE_VOL_TEST_HARD_LINK_NAME, fid, NATIVE_VOL_TEST_COPY_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; /* H5Lmove */ if (H5Lmove(fid, NATIVE_VOL_TEST_COPY_LINK_NAME, gid, NATIVE_VOL_TEST_MOVE_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; if (H5Fclose(fid) < 0) TEST_ERROR; if (H5Gclose(gid) < 0) TEST_ERROR; h5_delete_test_file(FILENAME[0], fapl_id); /* H5Pclose */ if (H5Pclose(fapl_id) < 0) TEST_ERROR; PASSED(); return SUCCEED; error: H5E_BEGIN_TRY { H5Fclose(fid); H5Fclose(gid); H5Pclose(fapl_id); } H5E_END_TRY; return FAIL; } /* end test_basic_link_operation() */ /*------------------------------------------------------------------------- * Function: test_basic_datatype_operation() * * Purpose: Uses the native VOL connector to test basic VOL datatype operations * * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ static herr_t test_basic_datatype_operation(void) { hid_t fid = H5I_INVALID_HID; hid_t fapl_id = H5I_INVALID_HID; hid_t tid = H5I_INVALID_HID; hid_t tid_anon = H5I_INVALID_HID; hid_t tcpl_id = H5I_INVALID_HID; char filename[1024]; TESTING("Basic VOL datatype operations"); /* Retrieve the file access property for testing */ fapl_id = h5_fileaccess(); h5_fixname(FILENAME[0], fapl_id, filename, sizeof filename); if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0) TEST_ERROR; if ((tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR; /* H5Tcommit */ if (H5Tcommit2(fid, NATIVE_VOL_TEST_DATATYPE_NAME, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; /* H5Tflush */ if (H5Tflush(tid) < 0) TEST_ERROR; /* H5Trefresh */ if (H5Trefresh(tid) < 0) TEST_ERROR; /* H5Tclose */ if (H5Tclose(tid) < 0) TEST_ERROR; /* H5Topen */ if ((tid = H5Topen2(fid, NATIVE_VOL_TEST_DATATYPE_NAME, H5P_DEFAULT)) < 0) TEST_ERROR; /* H5Tget_create_plist */ if ((tcpl_id = H5Tget_create_plist(tid)) < 0) TEST_ERROR; /* H5Tcommit_anon */ if ((tid_anon = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR; if (H5Tcommit_anon(fid, tid_anon, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; if (H5Pclose(tcpl_id) < 0) TEST_ERROR; if (H5Tclose(tid) < 0) TEST_ERROR; if (H5Tclose(tid_anon) < 0) TEST_ERROR; if (H5Fclose(fid) < 0) TEST_ERROR; h5_delete_test_file(FILENAME[0], fapl_id); /* H5Pclose */ if (H5Pclose(fapl_id) < 0) TEST_ERROR; PASSED(); return SUCCEED; error: H5E_BEGIN_TRY { H5Pclose(tcpl_id); H5Fclose(fid); H5Pclose(fapl_id); H5Tclose(tid); H5Tclose(tid_anon); } H5E_END_TRY; return FAIL; } /* end test_basic_datatype_operation() */ /*------------------------------------------------------------------------- * Function: main * * Purpose: Tests the virtual object layer interface (H5VL) * * Return: EXIT_SUCCESS/EXIT_FAILURE * *------------------------------------------------------------------------- */ int main(void) { const char *env_h5_drvr; /* File driver value from environment */ int nerrors = 0; /* Get the VFD to use */ env_h5_drvr = HDgetenv("HDF5_DRIVER"); if (env_h5_drvr == NULL) env_h5_drvr = "nomatch"; h5_reset(); HDputs("Testing basic Virtual Object Layer (VOL) functionality."); nerrors += test_vol_registration() < 0 ? 1 : 0; nerrors += test_native_vol_init() < 0 ? 1 : 0; nerrors += test_basic_file_operation(env_h5_drvr) < 0 ? 1 : 0; nerrors += test_basic_group_operation() < 0 ? 1 : 0; nerrors += test_basic_dataset_operation() < 0 ? 1 : 0; nerrors += test_basic_attribute_operation() < 0 ? 1 : 0; nerrors += test_basic_object_operation() < 0 ? 1 : 0; nerrors += test_basic_link_operation() < 0 ? 1 : 0; nerrors += test_basic_datatype_operation() < 0 ? 1 : 0; if (nerrors) { HDprintf("***** %d Virtual Object Layer TEST%s FAILED! *****\n", nerrors, nerrors > 1 ? "S" : ""); HDexit(EXIT_FAILURE); } HDputs("All Virtual Object Layer (VOL) tests passed."); HDexit(EXIT_SUCCESS); } /* end main() */