diff options
author | jhendersonHDF <jhenderson@hdfgroup.org> | 2021-09-29 18:28:12 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-29 18:28:12 (GMT) |
commit | 3da0802c40d58759995916bf9d0880e19f0af44d (patch) | |
tree | 809ada78cec1cbaaf6ec2ace5b4429a56d0f6574 /test/vfd_plugin.c | |
parent | 0fa5836cc5f037dd9f2cdd7f9a1051ddcc1c9ad0 (diff) | |
download | hdf5-3da0802c40d58759995916bf9d0880e19f0af44d.zip hdf5-3da0802c40d58759995916bf9d0880e19f0af44d.tar.gz hdf5-3da0802c40d58759995916bf9d0880e19f0af44d.tar.bz2 |
VFD plugins (#602)
* Implement support for loading of Virtual File Drivers as plugins
Fix plugin caching for VOL connector and VFD plugins
Fix plugin iteration to skip paths that can't be opened
* Enable dynamic loading of VFDs with HDF5_DRIVER environment variable
* Temporarily disable error reporting during H5F_open double file open
* Default to using HDstat in h5_get_file_size for unknown VFDs
* Use macros for some environment variables that HDF5 interprets
* Update "null" and "ctl testing" VFDs
Diffstat (limited to 'test/vfd_plugin.c')
-rw-r--r-- | test/vfd_plugin.c | 388 |
1 files changed, 388 insertions, 0 deletions
diff --git a/test/vfd_plugin.c b/test/vfd_plugin.c new file mode 100644 index 0000000..df211cc --- /dev/null +++ b/test/vfd_plugin.c @@ -0,0 +1,388 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 basic VFD plugin operations. Uses a basic testing VFD + * which is loaded as a dynamic plugin. + */ + +#include "h5test.h" + +#include "null_vfd_plugin.h" + +#define DEFAULT_DRIVER_NAME "sec2" + +/*------------------------------------------------------------------------- + * Function: test_set_by_name() + * + * Purpose: Tests if we can load and register a VFD plugin by name. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +test_set_by_name(void) +{ + htri_t is_registered = FAIL; + hid_t driver_id = H5I_INVALID_HID; + hid_t fapl_id = H5I_INVALID_HID; + + TESTING("VFD plugin registration by name"); + + /* The null VFD should not be registered at the start of the test */ + if ((is_registered = H5FDis_driver_registered_by_name(NULL_VFD_NAME)) < 0) + TEST_ERROR; + if (TRUE == is_registered) + FAIL_PUTS_ERROR("NULL VFD is inappropriately registered"); + + /* Register the null VFD by name */ + if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) + TEST_ERROR; + if (H5Pset_driver_by_name(fapl_id, NULL_VFD_NAME, NULL) < 0) + TEST_ERROR; + + /* The null VFD should be registered now */ + if ((is_registered = H5FDis_driver_registered_by_name(NULL_VFD_NAME)) < 0) + TEST_ERROR; + if (FALSE == is_registered) + FAIL_PUTS_ERROR("NULL VFD was not registered"); + + /* Unregister the null VFD */ + if ((driver_id = H5Pget_driver(fapl_id)) < 0) + TEST_ERROR; + if (H5FDunregister(driver_id) < 0) + TEST_ERROR; + + /* Close FAPL, which holds last reference to null VFD */ + if (H5Pclose(fapl_id) < 0) + TEST_ERROR; + + /* The null VFD should not be registered now */ + if ((is_registered = H5FDis_driver_registered_by_name(NULL_VFD_NAME)) < 0) + TEST_ERROR; + if (TRUE == is_registered) + FAIL_PUTS_ERROR("NULL VFD is inappropriately registered"); + + PASSED(); + + return SUCCEED; + +error: + H5E_BEGIN_TRY + { + H5Pclose(fapl_id); + } + H5E_END_TRY; + + return FAIL; +} + +/*------------------------------------------------------------------------- + * Function: test_set_by_value() + * + * Purpose: Tests if we can load and register a VFD plugin by value + * (ID). + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +test_set_by_value(void) +{ + htri_t is_registered = FAIL; + hid_t driver_id = H5I_INVALID_HID; + hid_t fapl_id = H5I_INVALID_HID; + + TESTING("VFD plugin registration by value (ID)"); + + /* The null VFD should not be registered at the start of the test */ + if ((is_registered = H5FDis_driver_registered_by_value(NULL_VFD_VALUE)) < 0) + TEST_ERROR; + if (TRUE == is_registered) + FAIL_PUTS_ERROR("NULL VFD is inappropriately registered"); + + /* Register the null VFD by value */ + if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) + TEST_ERROR; + if (H5Pset_driver_by_value(fapl_id, NULL_VFD_VALUE, NULL) < 0) + TEST_ERROR; + + /* The null VFD should be registered now */ + if ((is_registered = H5FDis_driver_registered_by_value(NULL_VFD_VALUE)) < 0) + TEST_ERROR; + if (FALSE == is_registered) + FAIL_PUTS_ERROR("NULL VFD was not registered"); + + /* Unregister the null VFD */ + if ((driver_id = H5Pget_driver(fapl_id)) < 0) + TEST_ERROR; + if (H5FDunregister(driver_id) < 0) + TEST_ERROR; + + /* Close FAPL, which holds last reference to null VFD */ + if (H5Pclose(fapl_id) < 0) + TEST_ERROR; + + /* The null VFD should not be registered now */ + if ((is_registered = H5FDis_driver_registered_by_value(NULL_VFD_VALUE)) < 0) + TEST_ERROR; + if (TRUE == is_registered) + FAIL_PUTS_ERROR("NULL VFD is inappropriately registered"); + + PASSED(); + + return SUCCEED; + +error: + H5E_BEGIN_TRY + { + H5Pclose(fapl_id); + } + H5E_END_TRY; + + return FAIL; +} + +/*------------------------------------------------------------------------- + * Function: test_set_multi() + * + * Purpose: Tests if we can register a VFD plugin multiple times. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +#define N_REGISTRATIONS 10 +static herr_t +test_set_multi(void) +{ + htri_t is_registered = FAIL; + hid_t driver_id = H5I_INVALID_HID; + hid_t fapl_id = H5I_INVALID_HID; + int i; + + TESTING("registering a VFD plugin multiple times"); + + /* The null VFD should not be registered at the start of the test */ + if ((is_registered = H5FDis_driver_registered_by_name(NULL_VFD_NAME)) < 0) + TEST_ERROR; + if (TRUE == is_registered) + FAIL_PUTS_ERROR("NULL VFD is inappropriately registered"); + + /* Register the VFD multiple times */ + if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) + TEST_ERROR; + for (i = 0; i < N_REGISTRATIONS; i++) { + if (H5Pset_driver_by_name(fapl_id, NULL_VFD_NAME, NULL) < 0) + TEST_ERROR; + } + + /* The null VFD should be registered now */ + if ((is_registered = H5FDis_driver_registered_by_name(NULL_VFD_NAME)) < 0) + TEST_ERROR; + if (FALSE == is_registered) + FAIL_PUTS_ERROR("NULL VFD was not registered"); + + /* Unregister the null VFD */ + if ((driver_id = H5Pget_driver(fapl_id)) < 0) + TEST_ERROR; + for (i = 0; i < N_REGISTRATIONS; i++) { + if (H5FDunregister(driver_id) < 0) + TEST_ERROR; + } + + /* Close FAPL, which holds last reference to null VFD */ + if (H5Pclose(fapl_id) < 0) + TEST_ERROR; + + /* The null VFD should not be registered now */ + if ((is_registered = H5FDis_driver_registered_by_name(NULL_VFD_NAME)) < 0) + TEST_ERROR; + if (TRUE == is_registered) + FAIL_PUTS_ERROR("NULL VFD is inappropriately registered"); + + /* Repeat testing with the _by_value routines */ + + /* The null VFD should not be registered at the start of the test */ + if ((is_registered = H5FDis_driver_registered_by_value(NULL_VFD_VALUE)) < 0) + TEST_ERROR; + if (TRUE == is_registered) + FAIL_PUTS_ERROR("NULL VFD is inappropriately registered"); + + /* Register the VFD multiple times */ + if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) + TEST_ERROR; + for (i = 0; i < N_REGISTRATIONS; i++) { + if (H5Pset_driver_by_value(fapl_id, NULL_VFD_VALUE, NULL) < 0) + TEST_ERROR; + } + + /* The null VFD should be registered now */ + if ((is_registered = H5FDis_driver_registered_by_value(NULL_VFD_VALUE)) < 0) + TEST_ERROR; + if (FALSE == is_registered) + FAIL_PUTS_ERROR("NULL VFD was not registered"); + + /* Unregister the null VFD */ + if ((driver_id = H5Pget_driver(fapl_id)) < 0) + TEST_ERROR; + for (i = 0; i < N_REGISTRATIONS; i++) { + if (H5FDunregister(driver_id) < 0) + TEST_ERROR; + } + + /* Close FAPL, which holds last reference to null VFD */ + if (H5Pclose(fapl_id) < 0) + TEST_ERROR; + + /* The null VFD should not be registered now */ + if ((is_registered = H5FDis_driver_registered_by_value(NULL_VFD_VALUE)) < 0) + TEST_ERROR; + if (TRUE == is_registered) + FAIL_PUTS_ERROR("NULL VFD is inappropriately registered"); + + PASSED(); + + return SUCCEED; + +error: + H5E_BEGIN_TRY + { + H5Pclose(fapl_id); + } + H5E_END_TRY; + + return FAIL; +} +#undef N_REGISTRATIONS + +/*------------------------------------------------------------------------- + * Function: test_get_config_str() + * + * Purpose: Tests if we can retrieve a configuration string set for a + * VFL driver. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +test_get_config_str(void) +{ + const char *const config_str = "{name: sec2}"; + ssize_t config_str_len = 0; + hid_t fapl_id = H5I_INVALID_HID; + char config_str_buf[128]; + + TESTING("Retrieval of VFD configuration string"); + + if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) + TEST_ERROR; + + /* Try to retrieve length of default configuration string - should be 0 */ + HDmemset(config_str_buf, 0, 128); + + if ((config_str_len = H5Pget_driver_config_str(fapl_id, config_str_buf, 128)) < 0) + TEST_ERROR; + if (0 != config_str_len) + TEST_ERROR; + if (HDstrlen(config_str_buf) > 0) + TEST_ERROR; + + /* Set a new configuration string on the FAPL and retrieve it */ + if (H5Pset_driver_by_name(fapl_id, DEFAULT_DRIVER_NAME, config_str) < 0) + TEST_ERROR; + if ((config_str_len = H5Pget_driver_config_str(fapl_id, config_str_buf, 128)) < 0) + TEST_ERROR; + if (HDstrlen(config_str) != config_str_len) + TEST_ERROR; + if (HDstrncmp(config_str_buf, config_str, 128)) + TEST_ERROR; + + if (H5Pclose(fapl_id) < 0) + TEST_ERROR; + + /* Set default driver and driver configuration using environment variables */ + if (HDsetenv(HDF5_DRIVER, "sec2", 1) < 0) + TEST_ERROR; + if (HDsetenv(HDF5_DRIVER_CONFIG, config_str, 1) < 0) + TEST_ERROR; + + /* Close and re-open HDF5 to have it parse the environment variables */ + if (H5close() < 0) + TEST_ERROR; + if (H5open() < 0) + TEST_ERROR; + + /* Retrieve configuration string from default FAPL */ + HDmemset(config_str_buf, 0, 128); + if ((config_str_len = H5Pget_driver_config_str(H5P_FILE_ACCESS_DEFAULT, config_str_buf, 128)) < 0) + TEST_ERROR; + if (HDstrlen(config_str) != config_str_len) + TEST_ERROR; + if (HDstrncmp(config_str_buf, config_str, 128)) + TEST_ERROR; + + /* Unset environment variables */ + if (HDsetenv(HDF5_DRIVER, "", 1) < 0) + TEST_ERROR; + if (HDsetenv(HDF5_DRIVER_CONFIG, "", 1) < 0) + TEST_ERROR; + + PASSED(); + + return SUCCEED; + +error: + H5E_BEGIN_TRY + { + H5Pclose(fapl_id); + } + H5E_END_TRY; + + return FAIL; +} + +/*------------------------------------------------------------------------- + * Function: main + * + * Purpose: Tests VFD plugin operations + * + * Return: EXIT_SUCCESS/EXIT_FAILURE + * + *------------------------------------------------------------------------- + */ +int +main(void) +{ + int nerrors = 0; + + h5_reset(); + + HDputs("Testing VFD plugin functionality."); + + nerrors += (test_set_by_name() < 0) ? 1 : 0; + nerrors += (test_set_by_value() < 0) ? 1 : 0; + nerrors += (test_set_multi() < 0) ? 1 : 0; + nerrors += (test_get_config_str() < 0) ? 1 : 0; + + if (nerrors) { + HDprintf("***** %d VFD plugin TEST%s FAILED! *****\n", nerrors, nerrors > 1 ? "S" : ""); + HDexit(EXIT_FAILURE); + } + + HDputs("All VFD plugin tests passed."); + + HDexit(EXIT_SUCCESS); +} |