mirror of
https://github.com/HDFGroup/hdf5.git
synced 2026-09-25 04:09:44 +03:00
FFM build requires Java 25, Jextract 25. Generates FFM bindings during configure. JNI is default when the requirements are not met or can be forced. Presets added for maven and FFM - JNI is default selection. Enhanced Maven options will work with either JNI or FFM New Workflows for testing and maven uploads. Extensive documentation changes for java.
304 lines
11 KiB
Java
304 lines
11 KiB
Java
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* 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 LICENSE 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. *
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
package jtest;
|
|
|
|
import static org.junit.Assert.*;
|
|
|
|
import static jtest.FfmTestSupport.*;
|
|
|
|
import java.lang.foreign.Arena;
|
|
import java.lang.foreign.MemorySegment;
|
|
import java.lang.foreign.ValueLayout;
|
|
|
|
import org.hdfgroup.javahdf5.hdf5_h;
|
|
import org.junit.After;
|
|
import org.junit.Before;
|
|
import org.junit.Rule;
|
|
import org.junit.Test;
|
|
import org.junit.rules.TestName;
|
|
|
|
/**
|
|
* FFM-only tests for HDF5 VOL (Virtual Object Layer) operations.
|
|
*
|
|
* NOTE: These tests focus on the native VOL connector only.
|
|
* Custom VOL connectors require external plugins and specialized setup.
|
|
*/
|
|
public class TestH5VLffm {
|
|
@Rule
|
|
public TestName testname = new TestName();
|
|
|
|
private static final String H5_FILE = "test_H5VLffm.h5";
|
|
|
|
long H5fid = hdf5_h.H5I_INVALID_HID();
|
|
|
|
@Before
|
|
public void createH5file()
|
|
{
|
|
System.out.print(testname.getMethodName());
|
|
|
|
try (Arena arena = Arena.ofConfined()) {
|
|
MemorySegment filename = stringToSegment(arena, H5_FILE);
|
|
H5fid = hdf5_h.H5Fcreate(filename, hdf5_h.H5F_ACC_TRUNC(), hdf5_h.H5P_DEFAULT(),
|
|
hdf5_h.H5P_DEFAULT());
|
|
assertTrue("H5Fcreate failed", isValidId(H5fid));
|
|
}
|
|
}
|
|
|
|
@After
|
|
public void deleteH5file()
|
|
{
|
|
if (isValidId(H5fid)) {
|
|
closeQuietly(H5fid, hdf5_h::H5Fclose);
|
|
H5fid = hdf5_h.H5I_INVALID_HID();
|
|
}
|
|
System.out.println();
|
|
}
|
|
|
|
/**
|
|
* Test H5VLis_connector_registered_by_name for native VOL connector
|
|
*/
|
|
@Test
|
|
public void testH5VLis_connector_registered_by_name()
|
|
{
|
|
try (Arena arena = Arena.ofConfined()) {
|
|
// Native VOL connector should be registered
|
|
MemorySegment name = stringToSegment(arena, "native");
|
|
int result = hdf5_h.H5VLis_connector_registered_by_name(name);
|
|
assertTrue("Native VOL connector should be registered", result > 0);
|
|
|
|
// Non-existent connector should not be registered
|
|
MemorySegment fake_name = stringToSegment(arena, "nonexistent_connector");
|
|
result = hdf5_h.H5VLis_connector_registered_by_name(fake_name);
|
|
assertEquals("Non-existent connector should not be registered", 0, result);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test H5VLis_connector_registered_by_value for native VOL connector
|
|
*/
|
|
@Test
|
|
public void testH5VLis_connector_registered_by_value()
|
|
{
|
|
// Native VOL connector (H5_VOL_NATIVE = 0) should be registered
|
|
int result = hdf5_h.H5VLis_connector_registered_by_value(hdf5_h.H5_VOL_NATIVE());
|
|
assertTrue("Native VOL connector should be registered", result > 0);
|
|
|
|
// Invalid connector value should not be registered
|
|
result = hdf5_h.H5VLis_connector_registered_by_value(9999);
|
|
assertEquals("Invalid connector value should not be registered", 0, result);
|
|
}
|
|
|
|
/**
|
|
* Test H5VLget_connector_id for file object
|
|
*/
|
|
@Test
|
|
public void testH5VLget_connector_id()
|
|
{
|
|
long connector_id = hdf5_h.H5VLget_connector_id(H5fid);
|
|
assertTrue("Should get valid connector ID for file", isValidId(connector_id));
|
|
|
|
// Close the connector ID
|
|
closeQuietly(connector_id, hdf5_h::H5VLclose);
|
|
}
|
|
|
|
/**
|
|
* Test H5VLget_connector_id_by_name for native connector
|
|
*/
|
|
@Test
|
|
public void testH5VLget_connector_id_by_name()
|
|
{
|
|
try (Arena arena = Arena.ofConfined()) {
|
|
MemorySegment name = stringToSegment(arena, "native");
|
|
long connector_id = hdf5_h.H5VLget_connector_id_by_name(name);
|
|
assertTrue("Should get valid connector ID by name", isValidId(connector_id));
|
|
|
|
// Close the connector ID
|
|
closeQuietly(connector_id, hdf5_h::H5VLclose);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test H5VLget_connector_id_by_value for native connector
|
|
*/
|
|
@Test
|
|
public void testH5VLget_connector_id_by_value()
|
|
{
|
|
long connector_id = hdf5_h.H5VLget_connector_id_by_value(hdf5_h.H5_VOL_NATIVE());
|
|
assertTrue("Should get valid connector ID by value", isValidId(connector_id));
|
|
|
|
// Close the connector ID
|
|
closeQuietly(connector_id, hdf5_h::H5VLclose);
|
|
}
|
|
|
|
/**
|
|
* Test H5VLget_connector_name for file object
|
|
*/
|
|
@Test
|
|
public void testH5VLget_connector_name()
|
|
{
|
|
try (Arena arena = Arena.ofConfined()) {
|
|
// First call to get the size
|
|
long size = hdf5_h.H5VLget_connector_name(H5fid, MemorySegment.NULL, 0);
|
|
assertTrue("Should get connector name size", size > 0);
|
|
|
|
// Allocate buffer and get the name
|
|
MemorySegment name_buf = arena.allocate(ValueLayout.JAVA_BYTE, (int)size + 1);
|
|
long actual_size = hdf5_h.H5VLget_connector_name(H5fid, name_buf, size + 1);
|
|
assertEquals("Sizes should match", size, actual_size);
|
|
|
|
// Verify it's the native connector
|
|
String connector_name = segmentToString(name_buf);
|
|
assertEquals("Should be native VOL connector", "native", connector_name);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test H5VLobject_is_native for file object
|
|
*/
|
|
@Test
|
|
public void testH5VLobject_is_native()
|
|
{
|
|
try (Arena arena = Arena.ofConfined()) {
|
|
MemorySegment is_native = arena.allocate(ValueLayout.JAVA_BOOLEAN);
|
|
|
|
int result = hdf5_h.H5VLobject_is_native(H5fid, is_native);
|
|
assertEquals("H5VLobject_is_native should succeed", 0, result);
|
|
|
|
// File should be using native VOL
|
|
boolean native_vol = is_native.get(ValueLayout.JAVA_BOOLEAN, 0);
|
|
assertTrue("File should be using native VOL connector", native_vol);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test H5VLregister_connector_by_name and H5VLunregister_connector
|
|
*
|
|
* Note: This tests registration/unregistration of already-registered
|
|
* native connector to verify the API works.
|
|
*/
|
|
@Test
|
|
public void testH5VLregister_and_unregister_connector_by_name()
|
|
{
|
|
try (Arena arena = Arena.ofConfined()) {
|
|
// Register the native connector (it's already registered, but this verifies API)
|
|
MemorySegment name = stringToSegment(arena, "native");
|
|
long connector_id = hdf5_h.H5VLregister_connector_by_name(name, hdf5_h.H5P_DEFAULT());
|
|
assertTrue("Should get valid connector ID", isValidId(connector_id));
|
|
|
|
// Verify it's registered
|
|
int is_registered = hdf5_h.H5VLis_connector_registered_by_name(name);
|
|
assertTrue("Connector should be registered", is_registered > 0);
|
|
|
|
// Note: Cannot unregister the native connector as it's always needed
|
|
// Just close the ID we got
|
|
closeQuietly(connector_id, hdf5_h::H5VLclose);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test H5VLregister_connector_by_value
|
|
*/
|
|
@Test
|
|
public void testH5VLregister_connector_by_value()
|
|
{
|
|
// Register native connector by value
|
|
long connector_id =
|
|
hdf5_h.H5VLregister_connector_by_value(hdf5_h.H5_VOL_NATIVE(), hdf5_h.H5P_DEFAULT());
|
|
assertTrue("Should get valid connector ID", isValidId(connector_id));
|
|
|
|
// Close the connector ID
|
|
closeQuietly(connector_id, hdf5_h::H5VLclose);
|
|
}
|
|
|
|
/**
|
|
* Test getting connector ID multiple times and closing
|
|
*/
|
|
@Test
|
|
public void testH5VLclose()
|
|
{
|
|
// Get connector ID for file
|
|
long connector_id1 = hdf5_h.H5VLget_connector_id(H5fid);
|
|
assertTrue("Should get valid connector ID", isValidId(connector_id1));
|
|
|
|
// Get another reference
|
|
long connector_id2 = hdf5_h.H5VLget_connector_id(H5fid);
|
|
assertTrue("Should get valid connector ID", isValidId(connector_id2));
|
|
|
|
// Close both
|
|
int result = hdf5_h.H5VLclose(connector_id1);
|
|
assertEquals("H5VLclose should succeed", 0, result);
|
|
|
|
result = hdf5_h.H5VLclose(connector_id2);
|
|
assertEquals("H5VLclose should succeed", 0, result);
|
|
}
|
|
|
|
/**
|
|
* Test VOL connector with dataset object
|
|
*/
|
|
@Test
|
|
public void testH5VLget_connector_id_for_dataset()
|
|
{
|
|
long dset_id = hdf5_h.H5I_INVALID_HID();
|
|
try (Arena arena = Arena.ofConfined()) {
|
|
// Create a simple dataset
|
|
MemorySegment dsetname = stringToSegment(arena, "dataset");
|
|
long sid = hdf5_h.H5Screate(hdf5_h.H5S_SCALAR());
|
|
assertTrue("H5Screate failed", isValidId(sid));
|
|
|
|
dset_id = hdf5_h.H5Dcreate2(H5fid, dsetname, hdf5_h.H5T_NATIVE_INT_g(), sid, hdf5_h.H5P_DEFAULT(),
|
|
hdf5_h.H5P_DEFAULT(), hdf5_h.H5P_DEFAULT());
|
|
assertTrue("H5Dcreate2 failed", isValidId(dset_id));
|
|
|
|
closeQuietly(sid, hdf5_h::H5Sclose);
|
|
|
|
// Get connector ID for dataset
|
|
long connector_id = hdf5_h.H5VLget_connector_id(dset_id);
|
|
assertTrue("Should get valid connector ID for dataset", isValidId(connector_id));
|
|
|
|
// Verify it's native
|
|
MemorySegment is_native = arena.allocate(ValueLayout.JAVA_BOOLEAN);
|
|
int result = hdf5_h.H5VLobject_is_native(dset_id, is_native);
|
|
assertEquals("H5VLobject_is_native should succeed", 0, result);
|
|
assertTrue("Dataset should be using native VOL", is_native.get(ValueLayout.JAVA_BOOLEAN, 0));
|
|
|
|
// Close connector ID
|
|
closeQuietly(connector_id, hdf5_h::H5VLclose);
|
|
}
|
|
finally {
|
|
closeQuietly(dset_id, hdf5_h::H5Dclose);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test H5VLquery_optional (basic test with native VOL)
|
|
*
|
|
* Note: This is a simplified test as full optional operation testing
|
|
* requires detailed knowledge of VOL connector capabilities.
|
|
*/
|
|
@Test
|
|
public void testH5VLquery_optional()
|
|
{
|
|
try (Arena arena = Arena.ofConfined()) {
|
|
MemorySegment flags = allocateLong(arena);
|
|
|
|
// Query optional operations for file object
|
|
// Using subcls=0 (H5VL_SUBCLS_FILE) and opt_type=0 as basic test
|
|
int result = hdf5_h.H5VLquery_optional(H5fid, 0, 0, flags);
|
|
|
|
// Result depends on VOL connector support
|
|
// We just verify the API works (returns >= 0 for success or -1 for not supported)
|
|
assertTrue("H5VLquery_optional should return valid result", result >= -1);
|
|
}
|
|
}
|
|
}
|