diff --git a/pom.xml b/pom.xml index 714398b..0863fbd 100644 --- a/pom.xml +++ b/pom.xml @@ -31,8 +31,7 @@ ${project.target.release} 3.5.0 - ${project.target.release} - ${project.target.release} + ${project.target.release} 5.1.1 @@ -191,6 +190,17 @@ + + maven-jar-plugin + + + + true + + + + + maven-source-plugin @@ -259,6 +269,11 @@ !java.*,!sun.* * + true + + {maven-resources}, + META-INF/versions/=${project.build.outputDirectory}/META-INF/versions/ + @@ -274,6 +289,34 @@ + + org.apache.maven.plugins + maven-invoker-plugin + 3.9.1 + + ${project.build.directory}/it + ${project.build.directory}/local-repo + src/it/settings.xml + verify + false + true + + clean + test + + + + + integration-test + + install + run + verify + + + + + @@ -309,13 +352,29 @@ jdk9+-profile - [9,21) + [9,) - - ${project.target.release} - + + maven-compiler-plugin + + + compile-java9 + compile + + compile + + + 9 + + ${project.basedir}/src/main/java9 + + true + + + + maven-surefire-plugin diff --git a/src/it/README.adoc b/src/it/README.adoc new file mode 100644 index 0000000..004e7cf --- /dev/null +++ b/src/it/README.adoc @@ -0,0 +1,66 @@ += Integration Tests + +This directory contains integration tests for the Zero-Allocation-Hashing library using the Maven Invoker Plugin and JUnit 4. + +== Test Cases + +=== 1. simple-usage + +Tests basic usage of the hashing library without modules. + +- Tests various hash functions (XxHash, CityHash, MurmurHash3, FarmHash) +- Verifies hash consistency across byte arrays, ByteBuffers, and CharSequences +- Ensures public API is accessible +- Uses JUnit 4 assertions + +=== 2. module-test + +Tests proper module encapsulation on Java 9+. + +- Uses `module-info.java` to require the `net.openhft.hashing` module +- Verifies that only exported packages are accessible +- Tests are compiled and run with module path +- Demonstrates module system working correctly +- Uses JUnit 4 assertions + +== Running Integration Tests + +Integration tests run automatically during the build with: + +[source,bash] +---- +./mvnw clean verify +---- + +Or run them separately with: + +[source,bash] +---- +./mvnw invoker:run +---- + +== Module Encapsulation + +The library exports only the `net.openhft.hashing` package via module-info.java: + +[source,java] +---- +module net.openhft.hashing { + requires jdk.unsupported; + exports net.openhft.hashing; +} +---- + +Internal packages (like sun.nio.ch) are not exported and cannot be accessed by consuming modules. + +== Multi-Release JAR + +The library is built as a multi-release JAR with module-info.class in META-INF/versions/9/: + +- Java 8: Works as a regular JAR without module system +- Java 9+: Works as a named module with proper encapsulation + +== Test Framework + +All integration tests use JUnit 4 (same as the main project tests) and do not print to System.out. +Test results are reported through Maven Surefire plugin output only. diff --git a/src/it/module-test/invoker.properties b/src/it/module-test/invoker.properties new file mode 100644 index 0000000..ac71e23 --- /dev/null +++ b/src/it/module-test/invoker.properties @@ -0,0 +1,2 @@ +invoker.goals=clean test +invoker.buildResult=success diff --git a/src/it/module-test/pom.xml b/src/it/module-test/pom.xml new file mode 100644 index 0000000..3a90660 --- /dev/null +++ b/src/it/module-test/pom.xml @@ -0,0 +1,42 @@ + + + 4.0.0 + + net.openhft.it + module-test + 1.0-SNAPSHOT + + + UTF-8 + 11 + + + + + @project.groupId@ + @project.artifactId@ + @project.version@ + + + junit + junit + 4.13.2 + test + + + + + + + maven-compiler-plugin + 3.14.0 + + + maven-surefire-plugin + 3.5.4 + + + + diff --git a/src/it/module-test/src/test/java/module-info.java b/src/it/module-test/src/test/java/module-info.java new file mode 100644 index 0000000..7cc33d5 --- /dev/null +++ b/src/it/module-test/src/test/java/module-info.java @@ -0,0 +1,9 @@ +/* + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 + */ +module net.openhft.it.module { + requires net.openhft.hashing; + requires junit; + exports net.openhft.it.module; + opens net.openhft.it.module to junit; +} diff --git a/src/it/module-test/src/test/java/net/openhft/it/module/ModuleTest.java b/src/it/module-test/src/test/java/net/openhft/it/module/ModuleTest.java new file mode 100644 index 0000000..45add4e --- /dev/null +++ b/src/it/module-test/src/test/java/net/openhft/it/module/ModuleTest.java @@ -0,0 +1,41 @@ +/* + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 + */ +package net.openhft.it.module; + +import net.openhft.hashing.LongHashFunction; +import org.junit.Test; + +import java.nio.charset.StandardCharsets; + +import static org.junit.Assert.*; + +/** + * Integration test verifying proper module encapsulation. + * This test ensures that only exported packages are accessible. + */ +public class ModuleTest { + + private static final String TEST_DATA = "Module Test Data"; + private static final byte[] TEST_BYTES = TEST_DATA.getBytes(StandardCharsets.UTF_8); + + @Test + public void testPublicAPIAccessible() { + long xxHash = LongHashFunction.xx().hashBytes(TEST_BYTES); + long cityHash = LongHashFunction.city_1_1().hashBytes(TEST_BYTES); + long murmurHash = LongHashFunction.murmur_3().hashBytes(TEST_BYTES); + + assertTrue("XxHash should produce non-zero result", xxHash != 0); + assertTrue("CityHash should produce non-zero result", cityHash != 0); + assertTrue("MurmurHash should produce non-zero result", murmurHash != 0); + } + + @Test + public void testMainAPIClassAccessible() { + try { + Class.forName("net.openhft.hashing.LongHashFunction"); + } catch (ClassNotFoundException e) { + fail("Public API net.openhft.hashing.LongHashFunction should be accessible"); + } + } +} diff --git a/src/it/settings.xml b/src/it/settings.xml new file mode 100644 index 0000000..8bd5dac --- /dev/null +++ b/src/it/settings.xml @@ -0,0 +1,6 @@ + + + @localRepositoryPath@ + diff --git a/src/it/simple-usage/invoker.properties b/src/it/simple-usage/invoker.properties new file mode 100644 index 0000000..ac71e23 --- /dev/null +++ b/src/it/simple-usage/invoker.properties @@ -0,0 +1,2 @@ +invoker.goals=clean test +invoker.buildResult=success diff --git a/src/it/simple-usage/pom.xml b/src/it/simple-usage/pom.xml new file mode 100644 index 0000000..98a41e4 --- /dev/null +++ b/src/it/simple-usage/pom.xml @@ -0,0 +1,42 @@ + + + 4.0.0 + + net.openhft.it + simple-usage + 1.0-SNAPSHOT + + + UTF-8 + 11 + + + + + @project.groupId@ + @project.artifactId@ + @project.version@ + + + junit + junit + 4.13.2 + test + + + + + + + maven-compiler-plugin + 3.14.0 + + + maven-surefire-plugin + 3.5.4 + + + + diff --git a/src/it/simple-usage/src/test/java/net/openhft/it/HashingTest.java b/src/it/simple-usage/src/test/java/net/openhft/it/HashingTest.java new file mode 100644 index 0000000..d2f1f50 --- /dev/null +++ b/src/it/simple-usage/src/test/java/net/openhft/it/HashingTest.java @@ -0,0 +1,90 @@ +/* + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 + */ +package net.openhft.it; + +import net.openhft.hashing.LongHashFunction; +import org.junit.Test; + +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; + +import static org.junit.Assert.*; + +/** + * Integration test demonstrating usage of Zero-Allocation-Hashing library. + */ +public class HashingTest { + + private static final String TEST_STRING = "Hello, World!"; + private static final byte[] TEST_BYTES = TEST_STRING.getBytes(StandardCharsets.UTF_8); + + @Test + public void testXxHash() { + LongHashFunction xxHash = LongHashFunction.xx(); + ByteBuffer buffer = ByteBuffer.wrap(TEST_BYTES); + + long hashFromBytes = xxHash.hashBytes(TEST_BYTES); + long hashFromBuffer = xxHash.hashBytes(buffer); + buffer.rewind(); + long hashFromChars = xxHash.hashChars(TEST_STRING); + + assertEquals("XxHash: byte[] and ByteBuffer hashes should match", hashFromBytes, hashFromBuffer); + assertTrue("XxHash from bytes should be non-zero", hashFromBytes != 0); + assertTrue("XxHash from chars should be non-zero", hashFromChars != 0); + } + + @Test + public void testCityHash() { + LongHashFunction cityHash = LongHashFunction.city_1_1(); + ByteBuffer buffer = ByteBuffer.wrap(TEST_BYTES); + + long hashFromBytes = cityHash.hashBytes(TEST_BYTES); + long hashFromBuffer = cityHash.hashBytes(buffer); + buffer.rewind(); + long hashFromChars = cityHash.hashChars(TEST_STRING); + + assertEquals("CityHash: byte[] and ByteBuffer hashes should match", hashFromBytes, hashFromBuffer); + assertTrue("CityHash from bytes should be non-zero", hashFromBytes != 0); + assertTrue("CityHash from chars should be non-zero", hashFromChars != 0); + } + + @Test + public void testMurmurHash() { + LongHashFunction murmur = LongHashFunction.murmur_3(); + ByteBuffer buffer = ByteBuffer.wrap(TEST_BYTES); + + long hashFromBytes = murmur.hashBytes(TEST_BYTES); + long hashFromBuffer = murmur.hashBytes(buffer); + buffer.rewind(); + long hashFromChars = murmur.hashChars(TEST_STRING); + + assertEquals("MurmurHash3: byte[] and ByteBuffer hashes should match", hashFromBytes, hashFromBuffer); + assertTrue("MurmurHash3 from bytes should be non-zero", hashFromBytes != 0); + assertTrue("MurmurHash3 from chars should be non-zero", hashFromChars != 0); + } + + @Test + public void testFarmHash() { + LongHashFunction farmHash = LongHashFunction.farmUo(); + ByteBuffer buffer = ByteBuffer.wrap(TEST_BYTES); + + long hashFromBytes = farmHash.hashBytes(TEST_BYTES); + long hashFromBuffer = farmHash.hashBytes(buffer); + buffer.rewind(); + long hashFromChars = farmHash.hashChars(TEST_STRING); + + assertEquals("FarmHash: byte[] and ByteBuffer hashes should match", hashFromBytes, hashFromBuffer); + assertTrue("FarmHash from bytes should be non-zero", hashFromBytes != 0); + assertTrue("FarmHash from chars should be non-zero", hashFromChars != 0); + } + + @Test + public void testPublicAPIAccessible() { + try { + Class.forName("net.openhft.hashing.LongHashFunction"); + } catch (ClassNotFoundException e) { + fail("Public API net.openhft.hashing.LongHashFunction should be accessible"); + } + } +} diff --git a/src/main/java9/module-info.java b/src/main/java9/module-info.java new file mode 100644 index 0000000..4d505e3 --- /dev/null +++ b/src/main/java9/module-info.java @@ -0,0 +1,7 @@ +/* + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 + */ +module net.openhft.hashing { + requires jdk.unsupported; + exports net.openhft.hashing; +}