Compare commits
12 Commits
hdf5_1_12-
...
inactive/j
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3469bbf4a | ||
|
|
9b2bc59567 | ||
|
|
6e0d81dc8b | ||
|
|
799a732650 | ||
|
|
70c21ab3be | ||
|
|
fdbbe61bcf | ||
|
|
10495f34f8 | ||
|
|
c1f1c89f5a | ||
|
|
1b90939dab | ||
|
|
db9668da65 | ||
|
|
1a95b844f2 | ||
|
|
25a8e2e680 |
30
BRANCH.md
Normal file
30
BRANCH.md
Normal file
@@ -0,0 +1,30 @@
|
||||
This branch is for the development of a test VOL connector to better
|
||||
test the VOL API. In particular, this will expose any issues where
|
||||
we've baked 'native file'-ness into the API.
|
||||
|
||||
The intent is to implement 100% of the HDF5 library's functionality
|
||||
so it can be transparently subbed in for the native VOL connector.
|
||||
|
||||
The JSON parser I've chosen is Jannsen, which is used in other THG
|
||||
products and projects and has an MIT license.
|
||||
|
||||
It currently only supports the Autotools, but it will not be difficult
|
||||
to add CMake support.
|
||||
|
||||
Plan:
|
||||
* Implement configuration and building via the autotools. (DONE)
|
||||
* Add a test program that loads the connector. (DONE)
|
||||
* Implement basic file operations.
|
||||
* Implement group operations.
|
||||
* Implement basic dataset operations.
|
||||
* Implement basic attribute operations.
|
||||
|
||||
NOTES:
|
||||
* The internets says to use libuuid to generate UUIDs as it's pretty
|
||||
lightweight.
|
||||
* Due to dependencies on libuuid and jansson, we're going to need to
|
||||
protect the code and only build when everything is present. I think
|
||||
this is okay since this is more of a test for ensuring the VOL doesn't
|
||||
suck than it is a test that someone's build is working normally.
|
||||
* Partial I/O is going to be crazy slow unless I want to add in some
|
||||
sort of optimized data container behind the scenes.
|
||||
5
MANIFEST
5
MANIFEST
@@ -23,6 +23,7 @@
|
||||
./.autom4te.cfg _DO_NOT_DISTRIBUTE_
|
||||
./.h5chkright.ini _DO_NOT_DISTRIBUTE_
|
||||
./ACKNOWLEDGMENTS
|
||||
./BRANCH.md _DO_NOT_DISTRIBUTE_
|
||||
./COPYING
|
||||
./COPYING_LBNL_HDF5
|
||||
./MANIFEST
|
||||
@@ -1061,6 +1062,9 @@
|
||||
./test/h5test.h
|
||||
./test/hyperslab.c
|
||||
./test/istore.c
|
||||
./test/json_vol.c
|
||||
./test/json_vol_connector.c
|
||||
./test/json_vol_connector.h
|
||||
./test/le_data.h5
|
||||
./test/le_extlink1.h5
|
||||
./test/le_extlink2.h5
|
||||
@@ -1124,6 +1128,7 @@
|
||||
./test/testframe.c
|
||||
./test/testhdf5.c
|
||||
./test/testhdf5.h
|
||||
./test/test_json_vol.sh.in
|
||||
./test/testlibinfo.sh.in
|
||||
./test/test_usecases.sh.in
|
||||
./test/test_vol_plugin.sh.in
|
||||
|
||||
84
configure.ac
84
configure.ac
@@ -1027,6 +1027,7 @@ esac
|
||||
##
|
||||
AC_CHECK_LIB([m], [ceil])
|
||||
AC_CHECK_LIB([dl], [dlopen])
|
||||
AC_CHECK_LIB([uuid], [uuid_generate])
|
||||
|
||||
## ----------------------------------------------------------------------
|
||||
## Check for system header files.
|
||||
@@ -1041,6 +1042,7 @@ AC_CHECK_HEADERS([stddef.h setjmp.h features.h])
|
||||
AC_CHECK_HEADERS([dirent.h])
|
||||
AC_CHECK_HEADERS([stdint.h], [C9x=yes])
|
||||
AC_CHECK_HEADERS([stdbool.h])
|
||||
AC_CHECK_HEADERS([uuid/uuid.h])
|
||||
|
||||
## Darwin
|
||||
AC_CHECK_HEADERS([mach/mach_time.h])
|
||||
@@ -1254,6 +1256,87 @@ AC_ARG_WITH([fnord],
|
||||
include/ and lib/ subdirectories
|
||||
])
|
||||
|
||||
## ----------------------------------------------------------------------
|
||||
## Is Jansson (JSON parser used for VOL testing) available? It has a
|
||||
## header file 'jansson.h' and a library '-ljansson' and their locations
|
||||
## might be specified with the '--with-jansson' command-line switch. The
|
||||
## value is an include path and/or a library path. If the library path is
|
||||
## specified then it must be preceded by a comma.
|
||||
##
|
||||
## NOTE: If this becomes an actual library thing, we'll eventually start
|
||||
## distributing Jansson with the library so builders don't have
|
||||
## have to go dig a copy up and install it. For right now, I
|
||||
## simply avoid building the JSON VOL connector unless it's
|
||||
## available.
|
||||
##
|
||||
AC_SUBST([HAVE_JANSSON])
|
||||
|
||||
## Default is not present
|
||||
HAVE_JANSSON=no
|
||||
|
||||
AC_ARG_WITH([jansson],
|
||||
[AS_HELP_STRING([--with-jansson=DIR],
|
||||
["Location of Jansson JSON parser (used for testing)" [default=no]])],,
|
||||
[withval=no])
|
||||
|
||||
case "X-$withval" in
|
||||
X-yes)
|
||||
HAVE_JANSSON="yes"
|
||||
AC_CHECK_HEADERS([jansson.h],, [unset HAVE_JANSSON])
|
||||
if test "x$HAVE_JANSSON" = "xyes"; then
|
||||
AC_CHECK_LIB([jansson], [json_loads],, [unset HAVE_JANSSON])
|
||||
fi
|
||||
if test -z "$HAVE_JANSSON" -a -n "$HDF5_CONFIG_ABORT"; then
|
||||
AC_MSG_ERROR([couldn't find Jansson library])
|
||||
fi
|
||||
;;
|
||||
X-|X-no|X-none)
|
||||
HAVE_JANSSON="no"
|
||||
AC_MSG_CHECKING([for Jansson library])
|
||||
AC_MSG_RESULT([suppressed])
|
||||
;;
|
||||
*)
|
||||
HAVE_JANSSON="yes"
|
||||
case "$withval" in
|
||||
*,*)
|
||||
jansson_inc="`echo $withval |cut -f1 -d,`"
|
||||
jansson_lib="`echo $withval |cut -f2 -d, -s`"
|
||||
;;
|
||||
*)
|
||||
if test -n "$withval"; then
|
||||
jansson_inc="$withval/include"
|
||||
jansson_lib="$withval/lib"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
saved_CPPFLAGS="$CPPFLAGS"
|
||||
saved_AM_CPPFLAGS="$AM_CPPFLAGS"
|
||||
saved_LDFLAGS="$LDFLAGS"
|
||||
saved_AM_LDFLAGS="$AM_LDFLAGS"
|
||||
|
||||
if test -n "$jansson_inc"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$jansson_inc"
|
||||
AM_CPPFLAGS="$AM_CPPFLAGS -I$jansson_inc"
|
||||
fi
|
||||
|
||||
AC_CHECK_HEADERS([jansson.h],,[CPPFLAGS="$saved_CPPFLAGS"; AM_CPPFLAGS="$saved_AM_CPPFLAGS"] [unset HAVE_JANSSON])
|
||||
|
||||
if test "x$HAVE_JANSSON" = "xyes"; then
|
||||
if test -n "$jansson_lib"; then
|
||||
LDFLAGS="$LDFLAGS -L$jansson_lib"
|
||||
AM_LDFLAGS="$AM_LDFLAGS -L$jansson_lib"
|
||||
fi
|
||||
|
||||
AC_CHECK_LIB([jansson], [json_loads],, [LDFLAGS="$saved_LDFLAGS"; AM_LDFLAGS="$saved_AM_LDFLAGS"; unset HAVE_JANSSON])
|
||||
fi
|
||||
|
||||
if test -z "$HAVE_JANSSON" -a -n "$HDF5_CONFIG_ABORT"; then
|
||||
AC_MSG_ERROR([couldn't find Jansson library])
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
## ----------------------------------------------------------------------
|
||||
## Is dmalloc (debug malloc library) requested? It has a header file
|
||||
## `dmalloc.h' and a library `-ldmalloc' and their locations might be
|
||||
@@ -3478,6 +3561,7 @@ AC_CONFIG_FILES([src/libhdf5.settings
|
||||
test/testcheck_version.sh
|
||||
test/testerror.sh
|
||||
test/testflushrefresh.sh
|
||||
test/test_json_vol.sh
|
||||
test/testlibinfo.sh
|
||||
test/testlinks_env.sh
|
||||
test/testswmr.sh
|
||||
|
||||
@@ -42,8 +42,8 @@ SCRIPT_DEPEND = error_test$(EXEEXT) err_compat$(EXEEXT) links_env$(EXEEXT) \
|
||||
swmr_sparse_reader$(EXEEXT) swmr_sparse_writer$(EXEEXT) swmr_start_write$(EXEEXT) \
|
||||
vds_swmr_gen$(EXEEXT) vds_swmr_reader$(EXEEXT) vds_swmr_writer$(EXEEXT)
|
||||
if HAVE_SHARED_CONDITIONAL
|
||||
TEST_SCRIPT += test_filter_plugin.sh test_vol_plugin.sh
|
||||
SCRIPT_DEPEND += filter_plugin$(EXEEXT) vol_plugin$(EXEEXT)
|
||||
TEST_SCRIPT += test_filter_plugin.sh test_vol_plugin.sh test_json_vol.sh
|
||||
SCRIPT_DEPEND += filter_plugin$(EXEEXT) vol_plugin$(EXEEXT) json_vol$(EXEEXT)
|
||||
endif
|
||||
|
||||
check_SCRIPTS = $(TEST_SCRIPT)
|
||||
@@ -85,7 +85,7 @@ check_PROGRAMS=$(TEST_PROG) error_test err_compat tcheck_version \
|
||||
swmr_remove_writer swmr_addrem_writer swmr_sparse_reader swmr_sparse_writer \
|
||||
swmr_check_compat_vfd vds_swmr_gen vds_swmr_reader vds_swmr_writer
|
||||
if HAVE_SHARED_CONDITIONAL
|
||||
check_PROGRAMS+= filter_plugin vol_plugin
|
||||
check_PROGRAMS+= filter_plugin vol_plugin json_vol
|
||||
endif
|
||||
|
||||
# These programs generate test files for the tests. They don't need to be
|
||||
@@ -108,7 +108,10 @@ if HAVE_SHARED_CONDITIONAL
|
||||
# The libh5test library provides common support code for the tests.
|
||||
# The filter_plugin* libraries are for use in filter_plugin.c.
|
||||
# Build them as shared libraries if that option was enabled in configure.
|
||||
noinst_LTLIBRARIES=libh5test.la libfilter_plugin1_dsets.la libfilter_plugin2_dsets.la libfilter_plugin3_dsets.la libfilter_plugin4_groups.la libnull_vol_connector.la
|
||||
noinst_LTLIBRARIES=libh5test.la \
|
||||
libfilter_plugin1_dsets.la libfilter_plugin2_dsets.la \
|
||||
libfilter_plugin3_dsets.la libfilter_plugin4_groups.la \
|
||||
libnull_vol_connector.la libjson_vol_connector.la
|
||||
libfilter_plugin1_dsets_la_SOURCES=filter_plugin1_dsets.c
|
||||
libfilter_plugin2_dsets_la_SOURCES=filter_plugin2_dsets.c
|
||||
libfilter_plugin3_dsets_la_SOURCES=filter_plugin3_dsets.c
|
||||
@@ -123,8 +126,11 @@ if HAVE_SHARED_CONDITIONAL
|
||||
# VOL plugin test libraries
|
||||
#
|
||||
# null_vol_connector is used for testing basic VOL plugin functionality.
|
||||
# json_vol_connector is used for testing non-native-HDF5 file storage.
|
||||
libnull_vol_connector_la_SOURCES=null_vol_connector.c
|
||||
libnull_vol_connector_la_LDFLAGS=$(AM_LDFLAGS) -avoid-version -module -shared -export-dynamic -rpath /nowhere
|
||||
libjson_vol_connector_la_SOURCES=json_vol_connector.c
|
||||
libjson_vol_connector_la_LDFLAGS=$(AM_LDFLAGS) -avoid-version -module -shared -export-dynamic -rpath /nowhere
|
||||
|
||||
else
|
||||
# The libh5test library provides common support code for the tests.
|
||||
|
||||
349
test/json_vol.c
Normal file
349
test/json_vol.c
Normal file
@@ -0,0 +1,349 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* 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://support.hdfgroup.org/ftp/HDF5/releases. *
|
||||
* If you do not have access to either file, you may request a copy from *
|
||||
* help@hdfgroup.org. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/*
|
||||
* Purpose: Tests basic JSON VOL connector operations.
|
||||
*/
|
||||
|
||||
#include "h5test.h"
|
||||
|
||||
#include "json_vol_connector.h"
|
||||
|
||||
#define JSON_FILE_NAME "json_vol_test.json"
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: test_registration_by_value()
|
||||
*
|
||||
* Purpose: Tests if we can load, register, and close the VOL
|
||||
* connector by value.
|
||||
*
|
||||
* Return: SUCCEED/FAIL
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
test_registration_by_value(void)
|
||||
{
|
||||
htri_t is_registered = FAIL;
|
||||
hid_t vol_id = H5I_INVALID_HID;
|
||||
|
||||
TESTING("VOL registration by value");
|
||||
|
||||
/* The null VOL connector should not be registered at the start of the test */
|
||||
if((is_registered = H5VLis_connector_registered(JSON_VOL_CONNECTOR_NAME)) < 0)
|
||||
TEST_ERROR;
|
||||
if(TRUE == is_registered)
|
||||
FAIL_PUTS_ERROR("JSON VOL connector is inappropriately registered");
|
||||
|
||||
/* Register the connector by value */
|
||||
if((vol_id = H5VLregister_connector_by_value(JSON_VOL_CONNECTOR_VALUE, H5P_DEFAULT)) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
/* The connector should be registered now */
|
||||
if((is_registered = H5VLis_connector_registered(JSON_VOL_CONNECTOR_NAME)) < 0)
|
||||
TEST_ERROR;
|
||||
if(FALSE == is_registered)
|
||||
FAIL_PUTS_ERROR("JSON VOL connector was not registered");
|
||||
|
||||
/* Unregister the connector */
|
||||
if(H5VLunregister_connector(vol_id) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
/* The connector should not be registered now */
|
||||
if((is_registered = H5VLis_connector_registered(JSON_VOL_CONNECTOR_NAME)) < 0)
|
||||
TEST_ERROR;
|
||||
if(TRUE == is_registered)
|
||||
FAIL_PUTS_ERROR("JSON VOL connector is inappropriately registered");
|
||||
|
||||
PASSED();
|
||||
return SUCCEED;
|
||||
|
||||
error:
|
||||
H5E_BEGIN_TRY {
|
||||
H5VLunregister_connector(vol_id);
|
||||
} H5E_END_TRY;
|
||||
return FAIL;
|
||||
|
||||
} /* end test_registration_by_value() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: test_registration_by_name()
|
||||
*
|
||||
* Purpose: Tests if we can load, register, and close a VOL
|
||||
* connector by name.
|
||||
*
|
||||
* Return: SUCCEED/FAIL
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
test_registration_by_name(void)
|
||||
{
|
||||
htri_t is_registered = FAIL;
|
||||
hid_t vol_id = H5I_INVALID_HID;
|
||||
|
||||
TESTING("VOL registration by name");
|
||||
|
||||
/* The null VOL connector should not be registered at the start of the test */
|
||||
if((is_registered = H5VLis_connector_registered(JSON_VOL_CONNECTOR_NAME)) < 0)
|
||||
TEST_ERROR;
|
||||
if(TRUE == is_registered)
|
||||
FAIL_PUTS_ERROR("JSON VOL connector is inappropriately registered");
|
||||
|
||||
/* Register the connector by name */
|
||||
if((vol_id = H5VLregister_connector_by_name(JSON_VOL_CONNECTOR_NAME, H5P_DEFAULT)) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
/* The connector should be registered now */
|
||||
if((is_registered = H5VLis_connector_registered(JSON_VOL_CONNECTOR_NAME)) < 0)
|
||||
TEST_ERROR;
|
||||
if(FALSE == is_registered)
|
||||
FAIL_PUTS_ERROR("JSON VOL connector was not registered");
|
||||
|
||||
/* Unregister the connector */
|
||||
if(H5VLunregister_connector(vol_id) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
/* The connector should not be registered now */
|
||||
if((is_registered = H5VLis_connector_registered(JSON_VOL_CONNECTOR_NAME)) < 0)
|
||||
TEST_ERROR;
|
||||
if(TRUE == is_registered)
|
||||
FAIL_PUTS_ERROR("JSON VOL connector is inappropriately registered");
|
||||
|
||||
PASSED();
|
||||
return SUCCEED;
|
||||
|
||||
error:
|
||||
H5E_BEGIN_TRY {
|
||||
H5VLunregister_connector(vol_id);
|
||||
} H5E_END_TRY;
|
||||
return FAIL;
|
||||
|
||||
} /* end test_registration_by_name() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: test_multiple_registration()
|
||||
*
|
||||
* Purpose: Tests if we can register a VOL connector multiple times.
|
||||
*
|
||||
* Return: SUCCEED/FAIL
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#define N_REGISTRATIONS 10
|
||||
static herr_t
|
||||
test_multiple_registration(void)
|
||||
{
|
||||
htri_t is_registered = FAIL;
|
||||
hid_t vol_ids[N_REGISTRATIONS];
|
||||
int i;
|
||||
|
||||
TESTING("registering a VOL connector multiple times");
|
||||
|
||||
/* The null VOL connector should not be registered at the start of the test */
|
||||
if((is_registered = H5VLis_connector_registered(JSON_VOL_CONNECTOR_NAME)) < 0)
|
||||
TEST_ERROR;
|
||||
if(TRUE == is_registered)
|
||||
FAIL_PUTS_ERROR("JSON VOL connector is inappropriately registered");
|
||||
|
||||
/* Register the connector multiple times */
|
||||
for(i = 0; i < N_REGISTRATIONS; i++) {
|
||||
if((vol_ids[i] = H5VLregister_connector_by_name(JSON_VOL_CONNECTOR_NAME, H5P_DEFAULT)) < 0)
|
||||
TEST_ERROR;
|
||||
}
|
||||
|
||||
/* The connector should be registered now */
|
||||
if((is_registered = H5VLis_connector_registered(JSON_VOL_CONNECTOR_NAME)) < 0)
|
||||
TEST_ERROR;
|
||||
if(FALSE == is_registered)
|
||||
FAIL_PUTS_ERROR("JSON VOL connector was not registered");
|
||||
|
||||
/* Unregister the connector */
|
||||
for(i = 0; i < N_REGISTRATIONS; i++) {
|
||||
if(H5VLunregister_connector(vol_ids[i]) < 0)
|
||||
TEST_ERROR;
|
||||
/* Also test close on some of the IDs. This call currently works
|
||||
* identically to unregister.
|
||||
*/
|
||||
i++;
|
||||
if(H5VLclose(vol_ids[i]) < 0)
|
||||
TEST_ERROR;
|
||||
}
|
||||
|
||||
/* The connector should not be registered now */
|
||||
if((is_registered = H5VLis_connector_registered(JSON_VOL_CONNECTOR_NAME)) < 0)
|
||||
TEST_ERROR;
|
||||
if(TRUE == is_registered)
|
||||
FAIL_PUTS_ERROR("JSON VOL connector is inappropriately registered");
|
||||
|
||||
PASSED();
|
||||
return SUCCEED;
|
||||
|
||||
error:
|
||||
H5E_BEGIN_TRY {
|
||||
for(i = 0; i < N_REGISTRATIONS; i++)
|
||||
H5VLunregister_connector(vol_ids[i]);
|
||||
} H5E_END_TRY;
|
||||
return FAIL;
|
||||
|
||||
} /* end test_multiple_registration() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: test_getters()
|
||||
*
|
||||
* Purpose: Tests H5VL getters
|
||||
*
|
||||
* Return: SUCCEED/FAIL
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
test_getters(void)
|
||||
{
|
||||
htri_t is_registered = FAIL;
|
||||
hid_t vol_id = H5I_INVALID_HID;
|
||||
hid_t vol_id_out = H5I_INVALID_HID;
|
||||
|
||||
TESTING("VOL getters");
|
||||
|
||||
/* The null VOL connector should not be registered at the start of the test */
|
||||
if((is_registered = H5VLis_connector_registered(JSON_VOL_CONNECTOR_NAME)) < 0)
|
||||
TEST_ERROR;
|
||||
if(TRUE == is_registered)
|
||||
FAIL_PUTS_ERROR("JSON VOL connector is inappropriately registered");
|
||||
|
||||
/* Register the connector by name */
|
||||
if((vol_id = H5VLregister_connector_by_name(JSON_VOL_CONNECTOR_NAME, H5P_DEFAULT)) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
/* Get the connector's ID */
|
||||
if((vol_id_out = H5VLget_connector_id(JSON_VOL_CONNECTOR_NAME)) < 0)
|
||||
TEST_ERROR;
|
||||
if(vol_id != vol_id_out)
|
||||
FAIL_PUTS_ERROR("VOL connector IDs don't match");
|
||||
|
||||
/* Unregister the connector */
|
||||
if(H5VLunregister_connector(vol_id) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
PASSED();
|
||||
return SUCCEED;
|
||||
|
||||
error:
|
||||
H5E_BEGIN_TRY {
|
||||
H5VLunregister_connector(vol_id);
|
||||
} H5E_END_TRY;
|
||||
return FAIL;
|
||||
|
||||
} /* end test_getters() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: test_file_operations()
|
||||
*
|
||||
* Purpose: Tests JSON file operations
|
||||
*
|
||||
* Return: SUCCEED/FAIL
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
test_file_operations(void)
|
||||
{
|
||||
hid_t vol_id = H5I_INVALID_HID;
|
||||
hid_t fapl_id = H5I_INVALID_HID;
|
||||
hid_t fid = H5I_INVALID_HID;
|
||||
|
||||
TESTING("File operations");
|
||||
|
||||
/* Register the connector by name */
|
||||
if((vol_id = H5VLregister_connector_by_name(JSON_VOL_CONNECTOR_NAME, H5P_DEFAULT)) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
/* Set the JSON VOL connector */
|
||||
if((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0)
|
||||
TEST_ERROR;
|
||||
if(H5Pset_vol(fapl_id, vol_id, NULL) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
/* Create/open/close the file */
|
||||
if((fid = H5Fcreate(JSON_FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0)
|
||||
TEST_ERROR;
|
||||
if(H5Fclose(fid) < 0)
|
||||
TEST_ERROR;
|
||||
if((fid = H5Fopen(JSON_FILE_NAME, H5F_ACC_RDWR, fapl_id)) < 0)
|
||||
TEST_ERROR;
|
||||
if(H5Fclose(fid) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
/* Close remaining IDs */
|
||||
if(H5Pclose(fapl_id) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
/* Unregister the connector */
|
||||
if(H5VLunregister_connector(vol_id) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
PASSED();
|
||||
return SUCCEED;
|
||||
|
||||
error:
|
||||
H5E_BEGIN_TRY {
|
||||
H5VLunregister_connector(vol_id);
|
||||
H5Fclose(fid);
|
||||
H5Pclose(fapl_id);
|
||||
} H5E_END_TRY;
|
||||
return FAIL;
|
||||
|
||||
} /* end test_getters() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: main
|
||||
*
|
||||
* Purpose: Tests JSON VOL connector operations
|
||||
*
|
||||
* Return: EXIT_SUCCESS/EXIT_FAILURE
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
int nerrors = 0;
|
||||
|
||||
h5_reset();
|
||||
|
||||
HDputs("Testing JSON VOL connector functionality.");
|
||||
|
||||
nerrors += test_registration_by_name() < 0 ? 1 : 0;
|
||||
nerrors += test_registration_by_value() < 0 ? 1 : 0;
|
||||
nerrors += test_multiple_registration() < 0 ? 1 : 0;
|
||||
nerrors += test_getters() < 0 ? 1 : 0;
|
||||
nerrors += test_file_operations() < 0 ? 1 : 0;
|
||||
|
||||
if(nerrors) {
|
||||
HDprintf("***** %d JSON VOL connector TEST%s FAILED! *****\n",
|
||||
nerrors, nerrors > 1 ? "S" : "");
|
||||
HDexit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
HDputs("All JSON VOL connector tests passed.");
|
||||
|
||||
HDexit(EXIT_SUCCESS);
|
||||
|
||||
} /* end main() */
|
||||
|
||||
258
test/json_vol_connector.c
Normal file
258
test/json_vol_connector.c
Normal file
@@ -0,0 +1,258 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* 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://support.hdfgroup.org/ftp/HDF5/releases. *
|
||||
* If you do not have access to either file, you may request a copy from *
|
||||
* help@hdfgroup.org. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/* Purpose: A virtual object layer (VOL) connector that uses JSON to
|
||||
* store HDF5 data and metadata.
|
||||
*
|
||||
* The JSON representation is taken from hdf5-json, though
|
||||
* that code can't be directly used because it's in Python.
|
||||
* (https://github.com/HDFGroup/hdf5-json)
|
||||
*/
|
||||
|
||||
#include "hdf5.h"
|
||||
|
||||
#include "H5PLextern.h"
|
||||
|
||||
#include "json_vol_connector.h"
|
||||
|
||||
/* XXX: Note that we're going to have to guard most of the JSON VOL
|
||||
* connector content with #ifdefs in the final product...
|
||||
*/
|
||||
|
||||
/* The Jansson JSON parser */
|
||||
#include <jansson.h>
|
||||
|
||||
/* libuuid for generating UUIDs */
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
#define SUCCEED 0
|
||||
#define FAIL (-1)
|
||||
|
||||
/* Callbacks */
|
||||
/* File */
|
||||
static void *jvc_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id, void **req);
|
||||
static void *jvc_file_open(const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, void **req);
|
||||
static herr_t jvc_file_close(void *file, hid_t dxpl_id, void **req);
|
||||
|
||||
/* The VOL class struct */
|
||||
static const H5VL_class_t json_vol_g = {
|
||||
JSON_VOL_CONNECTOR_VERSION, /* version */
|
||||
JSON_VOL_CONNECTOR_VALUE, /* value */
|
||||
JSON_VOL_CONNECTOR_NAME, /* name */
|
||||
0, /* capability flags */
|
||||
NULL, /* initialize */
|
||||
NULL, /* terminate */
|
||||
{ /* info_cls */
|
||||
(size_t)0, /* info size */
|
||||
NULL, /* info copy */
|
||||
NULL, /* info compare */
|
||||
NULL, /* info free */
|
||||
NULL, /* info to str */
|
||||
NULL /* str to info */
|
||||
},
|
||||
{ /* wrap_cls */
|
||||
NULL, /* get_object */
|
||||
NULL, /* get_wrap_ctx */
|
||||
NULL, /* wrap_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_size */
|
||||
NULL, /* specific */
|
||||
NULL, /* optional */
|
||||
NULL /* close */
|
||||
},
|
||||
{ /* file_cls */
|
||||
jvc_file_create, /* create */
|
||||
jvc_file_open, /* open */
|
||||
NULL, /* get */
|
||||
NULL, /* specific */
|
||||
NULL, /* optional */
|
||||
jvc_file_close /* 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 */
|
||||
},
|
||||
{ /* request_cls */
|
||||
NULL, /* wait */
|
||||
NULL, /* notify */
|
||||
NULL, /* cancel */
|
||||
NULL, /* specific */
|
||||
NULL, /* optional */
|
||||
NULL /* free */
|
||||
},
|
||||
NULL /* optional */
|
||||
};
|
||||
|
||||
/* These two functions are necessary to load this plugin using
|
||||
* the HDF5 library.
|
||||
*/
|
||||
H5PL_type_t H5PLget_plugin_type(void) {return H5PL_TYPE_VOL;}
|
||||
const void *H5PLget_plugin_info(void) {return &json_vol_g;}
|
||||
|
||||
/******************/
|
||||
/* IMPLEMENTATION */
|
||||
/******************/
|
||||
|
||||
typedef struct json_vol_file_t {
|
||||
FILE *fp; /* File pointer to JSON file */
|
||||
json_t *root; /* Root of the JSON tree */
|
||||
json_t *groups; /* JSON array of groups */
|
||||
} json_vol_file_t;
|
||||
|
||||
#if 0
|
||||
/* Helper functions */
|
||||
static herr_t
|
||||
jvc_helper_create_group(json_vol_file_t *jfile, char *group_name)
|
||||
{
|
||||
return SUCCEED;
|
||||
} /* end jvc_helper_create_group() */
|
||||
#endif
|
||||
|
||||
/* File callback implementation */
|
||||
static void *
|
||||
jvc_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id, void **req)
|
||||
{
|
||||
json_vol_file_t *jfile = NULL;
|
||||
|
||||
/* Set up */
|
||||
if(NULL == (jfile = (json_vol_file_t *)calloc((size_t)1, sizeof(json_vol_file_t))))
|
||||
goto error;
|
||||
|
||||
/* Create the file */
|
||||
if(NULL == (jfile->fp = fopen(name, "w")))
|
||||
goto error;
|
||||
|
||||
/* Create the JSON root */
|
||||
jfile->root = json_object();
|
||||
|
||||
/* Add the groups array */
|
||||
jfile->groups = json_array();
|
||||
json_object_set_new(jfile->root, "groups", jfile->groups);
|
||||
|
||||
return (void *)jfile;
|
||||
|
||||
error:
|
||||
if(jfile->fp)
|
||||
fclose(jfile->fp);
|
||||
if(jfile)
|
||||
free(jfile);
|
||||
return NULL;
|
||||
} /* end jvc_file_create() */
|
||||
|
||||
static void *
|
||||
jvc_file_open(const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, void **req)
|
||||
{
|
||||
json_vol_file_t *jfile = NULL;
|
||||
char *json_in = NULL;
|
||||
long int file_size;
|
||||
json_error_t jerror;
|
||||
|
||||
/* Set up */
|
||||
if(NULL == (jfile = (json_vol_file_t *)calloc((size_t)1, sizeof(json_vol_file_t))))
|
||||
goto error;
|
||||
|
||||
/* Open the file and get the size */
|
||||
if(NULL == (jfile->fp = fopen(name, "r")))
|
||||
goto error;
|
||||
fseek(jfile->fp, 0, SEEK_END);
|
||||
file_size = ftell(jfile->fp);
|
||||
fseek(jfile->fp, 0, SEEK_SET);
|
||||
|
||||
/* Create the JSON root */
|
||||
if(NULL == (json_in = (char *)malloc((size_t)(file_size + 1) * sizeof(char))))
|
||||
goto error;
|
||||
fread(json_in, (size_t)file_size, 1, jfile->fp);
|
||||
jfile->root = json_loads(json_in, 0, &jerror);
|
||||
|
||||
/* Will still need to parse out the groups array */
|
||||
|
||||
free(json_in);
|
||||
|
||||
return (void *)jfile;
|
||||
|
||||
error:
|
||||
if(json_in)
|
||||
free(json_in);
|
||||
if(jfile->fp)
|
||||
fclose(jfile->fp);
|
||||
if(jfile)
|
||||
free(jfile);
|
||||
return NULL;
|
||||
} /* end jvc_file_open() */
|
||||
|
||||
static herr_t
|
||||
jvc_file_close(void *file, hid_t dxpl_id, void **req)
|
||||
{
|
||||
json_vol_file_t *jfile = (json_vol_file_t *)file;
|
||||
|
||||
/* Dump the JSON string to the file */
|
||||
fprintf(jfile->fp, "%s", json_dumps(jfile->root, 0));
|
||||
|
||||
/* Close the file */
|
||||
if(EOF == fclose(jfile->fp))
|
||||
goto error;
|
||||
|
||||
/* Decrement the reference count on the JSON root, closing it */
|
||||
json_decref(jfile->root);
|
||||
|
||||
/* Tear down */
|
||||
free(jfile);
|
||||
|
||||
return SUCCEED;
|
||||
|
||||
error:
|
||||
return FAIL;
|
||||
} /* end jvc_file_close() */
|
||||
|
||||
27
test/json_vol_connector.h
Normal file
27
test/json_vol_connector.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* 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://support.hdfgroup.org/ftp/HDF5/releases. *
|
||||
* If you do not have access to either file, you may request a copy from *
|
||||
* help@hdfgroup.org. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/* Purpose: A virtual object layer (VOL) connector that uses JSON to
|
||||
* store HDF5 data and metadata.
|
||||
*/
|
||||
|
||||
#ifndef _json_vol_connector_H
|
||||
#define _json_vol_connector_H
|
||||
|
||||
#include "hdf5.h"
|
||||
|
||||
#define JSON_VOL_CONNECTOR_VERSION 1
|
||||
#define JSON_VOL_CONNECTOR_VALUE ((H5VL_class_value_t)104)
|
||||
#define JSON_VOL_CONNECTOR_NAME "json_vol_connector"
|
||||
|
||||
#endif /* _json_vol_connector_H */
|
||||
|
||||
84
test/test_json_vol.sh.in
Normal file
84
test/test_json_vol.sh.in
Normal file
@@ -0,0 +1,84 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# 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://support.hdfgroup.org/ftp/HDF5/releases.
|
||||
# If you do not have access to either file, you may request a copy from
|
||||
# help@hdfgroup.org.
|
||||
#
|
||||
# This shell script is for testing basic JSON VOL operations.
|
||||
#
|
||||
srcdir=@srcdir@
|
||||
TOP_BUILDDIR=@top_builddir@
|
||||
|
||||
EXIT_SUCCESS=0
|
||||
EXIT_FAILURE=1
|
||||
|
||||
nerrors=0
|
||||
verbose=yes
|
||||
exit_code=$EXIT_SUCCESS
|
||||
|
||||
TEST_NAME=json_vol
|
||||
TEST_BIN=`pwd`/$TEST_NAME
|
||||
FROM_DIR=`pwd`/.libs
|
||||
case $(uname) in
|
||||
CYGWIN* )
|
||||
JSON_VOL_PLUGIN="$FROM_DIR/cygjson_vol_connector*"
|
||||
;;
|
||||
*)
|
||||
JSON_VOL_PLUGIN="$FROM_DIR/libjson_vol_connector*"
|
||||
;;
|
||||
esac
|
||||
TEMP_PLUGIN_DIR=json_vol_plugin_dir
|
||||
CP="cp -p" # Use -p to preserve mode,ownership, timestamps
|
||||
RM="rm -rf"
|
||||
|
||||
# Print a line-line message left justified in a field of 70 characters
|
||||
# beginning with the word "Testing".
|
||||
#
|
||||
TESTING() {
|
||||
SPACES=" "
|
||||
echo "Testing $* $SPACES" | cut -c1-70 | tr -d '\012'
|
||||
}
|
||||
|
||||
# Main Body
|
||||
# Create test directory if necessary.
|
||||
test -d $TEMP_PLUGIN_DIR || mkdir -p $TEMP_PLUGIN_DIR
|
||||
if [ $? != 0 ]; then
|
||||
echo "Failed to create VOL connector plugin test directory ($TEMP_PLUGIN_DIR)"
|
||||
exit $EXIT_FAILURE
|
||||
fi
|
||||
|
||||
# Copy plugin for the tests.
|
||||
$CP $JSON_VOL_PLUGIN $TEMP_PLUGIN_DIR
|
||||
if [ $? != 0 ]; then
|
||||
echo "Failed to copy JSON VOL plugin ($JSON_VOL_PLUGIN) to test directory."
|
||||
exit $EXIT_FAILURE
|
||||
fi
|
||||
|
||||
# setup plugin path
|
||||
ENVCMD="env HDF5_PLUGIN_PATH=${TEMP_PLUGIN_DIR}"
|
||||
|
||||
# Run the test
|
||||
$ENVCMD $TEST_BIN
|
||||
if [ $? != 0 ]; then
|
||||
nerrors=`expr $nerrors + 1`
|
||||
fi
|
||||
|
||||
# print results
|
||||
if test $nerrors -ne 0 ; then
|
||||
echo "$nerrors errors encountered"
|
||||
exit_code=$EXIT_FAILURE
|
||||
else
|
||||
echo "All JSON VOL plugin tests passed."
|
||||
exit_code=$EXIT_SUCCESS
|
||||
fi
|
||||
|
||||
# Clean up temporary files/directories and leave
|
||||
$RM $TEMP_PLUGIN_DIR
|
||||
|
||||
exit $exit_code
|
||||
Reference in New Issue
Block a user