From dec490bb8635d90ca27a56583e58508667916d61 Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Tue, 1 Sep 2026 21:31:17 +0200 Subject: [PATCH] Replace the SDK test JAR with a `flume-ng-sdk-test` module The site build runs `mvnw -Dmaven.test.skip install`, which also skips `jar:test-jar`. Maven still resolves the full test classpath before `compiler:testCompile` and `surefire:test` can read their skip flags, so the cross-module `flume-ng-sdk:tests` dependency was demanded but never produced and `deploy-site` failed to resolve it. Assisted-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01WnSh7gt5XaRzNgDYLuFzZ6 --- flume-bom/pom.xml | 5 ++ flume-ng-core/pom.xml | 3 +- .../flume/sink/TestRollingFileSink.java | 2 +- flume-ng-sdk-test/pom.xml | 66 ++++++++++++++++++ .../apache/flume/sdk/test}/TestKeyStores.java | 2 +- .../org/apache/flume/sdk/test}/Whitebox.java | 2 +- .../flume/sdk/test}/X509Certificates.java | 2 +- .../sdk/test/TestSelfSignedKeyStores.java | 67 +++++++++++++++++++ .../apache/flume/sdk/test/TestWhitebox.java | 44 ++++++++++++ .../flume/sdk/test/TestX509Certificates.java | 57 ++++++++++++++++ flume-ng-sdk/pom.xml | 39 ----------- flume-ng-sources/flume-http-source/pom.xml | 3 +- .../flume/source/http/TestHTTPSource.java | 4 +- flume-ng-sources/flume-syslog-source/pom.xml | 3 +- .../syslog/TestMultiportSyslogTCPSource.java | 4 +- .../source/syslog/TestSyslogTcpSource.java | 2 +- flume-ng-sources/flume-taildir-source/pom.xml | 3 +- .../source/taildir/TestTaildirSource.java | 2 +- flume-parent/pom.xml | 3 +- pom.xml | 1 + 20 files changed, 255 insertions(+), 59 deletions(-) create mode 100644 flume-ng-sdk-test/pom.xml rename {flume-ng-sdk/src/test/java/org/apache/flume/util => flume-ng-sdk-test/src/main/java/org/apache/flume/sdk/test}/TestKeyStores.java (98%) rename {flume-ng-sdk/src/test/java/org/apache/flume/util => flume-ng-sdk-test/src/main/java/org/apache/flume/sdk/test}/Whitebox.java (97%) rename {flume-ng-sdk/src/test/java/org/apache/flume/util => flume-ng-sdk-test/src/main/java/org/apache/flume/sdk/test}/X509Certificates.java (99%) create mode 100644 flume-ng-sdk-test/src/test/java/org/apache/flume/sdk/test/TestSelfSignedKeyStores.java create mode 100644 flume-ng-sdk-test/src/test/java/org/apache/flume/sdk/test/TestWhitebox.java create mode 100644 flume-ng-sdk-test/src/test/java/org/apache/flume/sdk/test/TestX509Certificates.java diff --git a/flume-bom/pom.xml b/flume-bom/pom.xml index 9477ac6d16..f65016bd83 100644 --- a/flume-bom/pom.xml +++ b/flume-bom/pom.xml @@ -103,6 +103,11 @@ flume-ng-sdk ${project.version} + + org.apache.flume + flume-ng-sdk-test + ${project.version} + org.apache.flume flume-ng-node diff --git a/flume-ng-core/pom.xml b/flume-ng-core/pom.xml index 2f8044fe37..42efd81a2c 100644 --- a/flume-ng-core/pom.xml +++ b/flume-ng-core/pom.xml @@ -46,8 +46,7 @@ org.apache.flume - flume-ng-sdk - tests + flume-ng-sdk-test test diff --git a/flume-ng-core/src/test/java/org/apache/flume/sink/TestRollingFileSink.java b/flume-ng-core/src/test/java/org/apache/flume/sink/TestRollingFileSink.java index c419a37b18..2d948b53db 100644 --- a/flume-ng-core/src/test/java/org/apache/flume/sink/TestRollingFileSink.java +++ b/flume-ng-core/src/test/java/org/apache/flume/sink/TestRollingFileSink.java @@ -32,7 +32,7 @@ import org.apache.flume.event.SimpleEvent; import org.apache.flume.exception.ChannelException; import org.apache.flume.instrumentation.SinkCounter; -import org.apache.flume.util.Whitebox; +import org.apache.flume.sdk.test.Whitebox; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.junit.After; diff --git a/flume-ng-sdk-test/pom.xml b/flume-ng-sdk-test/pom.xml new file mode 100644 index 0000000000..6e5083d1fd --- /dev/null +++ b/flume-ng-sdk-test/pom.xml @@ -0,0 +1,66 @@ + + + + 4.0.0 + + + org.apache.flume + flume-parent + ${revision} + ../flume-parent/pom.xml + + + flume-ng-sdk-test + Flume NG SDK Test + Test fixtures shared by the Flume modules. + The fixtures live in `main`, so that they are packaged in a regular JAR instead of a test JAR. + + + + false + + 1 + org.apache.flume.sdk.test + + + + + + org.apache.commons + commons-lang3 + + + + org.bouncycastle + bcpkix-jdk18on + + + + org.bouncycastle + bcprov-jdk18on + + + + junit + junit + test + + + + diff --git a/flume-ng-sdk/src/test/java/org/apache/flume/util/TestKeyStores.java b/flume-ng-sdk-test/src/main/java/org/apache/flume/sdk/test/TestKeyStores.java similarity index 98% rename from flume-ng-sdk/src/test/java/org/apache/flume/util/TestKeyStores.java rename to flume-ng-sdk-test/src/main/java/org/apache/flume/sdk/test/TestKeyStores.java index 7be6500271..5b7415c1b1 100644 --- a/flume-ng-sdk/src/test/java/org/apache/flume/util/TestKeyStores.java +++ b/flume-ng-sdk-test/src/main/java/org/apache/flume/sdk/test/TestKeyStores.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.flume.util; +package org.apache.flume.sdk.test; import java.io.OutputStream; import java.nio.file.Files; diff --git a/flume-ng-sdk/src/test/java/org/apache/flume/util/Whitebox.java b/flume-ng-sdk-test/src/main/java/org/apache/flume/sdk/test/Whitebox.java similarity index 97% rename from flume-ng-sdk/src/test/java/org/apache/flume/util/Whitebox.java rename to flume-ng-sdk-test/src/main/java/org/apache/flume/sdk/test/Whitebox.java index 995e0ae3fb..881c0cc2f1 100644 --- a/flume-ng-sdk/src/test/java/org/apache/flume/util/Whitebox.java +++ b/flume-ng-sdk-test/src/main/java/org/apache/flume/sdk/test/Whitebox.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.flume.util; +package org.apache.flume.sdk.test; import org.apache.commons.lang3.reflect.FieldUtils; diff --git a/flume-ng-sdk/src/test/java/org/apache/flume/util/X509Certificates.java b/flume-ng-sdk-test/src/main/java/org/apache/flume/sdk/test/X509Certificates.java similarity index 99% rename from flume-ng-sdk/src/test/java/org/apache/flume/util/X509Certificates.java rename to flume-ng-sdk-test/src/main/java/org/apache/flume/sdk/test/X509Certificates.java index ac38450025..b1ae2f44cd 100644 --- a/flume-ng-sdk/src/test/java/org/apache/flume/util/X509Certificates.java +++ b/flume-ng-sdk-test/src/main/java/org/apache/flume/sdk/test/X509Certificates.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.flume.util; +package org.apache.flume.sdk.test; import java.math.BigInteger; import java.security.KeyPair; diff --git a/flume-ng-sdk-test/src/test/java/org/apache/flume/sdk/test/TestSelfSignedKeyStores.java b/flume-ng-sdk-test/src/test/java/org/apache/flume/sdk/test/TestSelfSignedKeyStores.java new file mode 100644 index 0000000000..b76fc8a651 --- /dev/null +++ b/flume-ng-sdk-test/src/test/java/org/apache/flume/sdk/test/TestSelfSignedKeyStores.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.flume.sdk.test; + +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.KeyStore; +import java.security.cert.X509Certificate; +import org.junit.Assert; +import org.junit.Test; + +public class TestSelfSignedKeyStores { + + private static final String PASSWORD = "password"; + + @Test + public void testKeyStoreHoldsThePrivateKey() throws Exception { + TestKeyStores credentials = TestKeyStores.selfSigned("CN=localhost"); + KeyStore keyStore = credentials.keyStore("JKS", PASSWORD); + + Assert.assertTrue(keyStore.isKeyEntry("key")); + Assert.assertEquals(credentials.certificate(), keyStore.getCertificateChain("key")[0]); + Assert.assertNotNull(keyStore.getKey("key", PASSWORD.toCharArray())); + } + + @Test + public void testTrustStoreHoldsOnlyTheCertificate() throws Exception { + TestKeyStores credentials = TestKeyStores.selfSigned("CN=localhost"); + KeyStore trustStore = credentials.trustStore("JKS"); + + Assert.assertFalse(trustStore.isKeyEntry("cert")); + Assert.assertEquals(credentials.certificate(), trustStore.getCertificate("cert")); + } + + @Test + public void testWrittenKeyStoreCanBeReloaded() throws Exception { + TestKeyStores credentials = TestKeyStores.selfSigned("CN=localhost"); + Path file = Files.createTempFile("keystore", ".jks"); + try { + credentials.writeKeyStore(file, "JKS", PASSWORD); + + KeyStore reloaded = KeyStore.getInstance("JKS"); + try (InputStream in = Files.newInputStream(file)) { + reloaded.load(in, PASSWORD.toCharArray()); + } + X509Certificate certificate = (X509Certificate) reloaded.getCertificateChain("key")[0]; + Assert.assertEquals(credentials.certificate(), certificate); + } finally { + Files.deleteIfExists(file); + } + } +} diff --git a/flume-ng-sdk-test/src/test/java/org/apache/flume/sdk/test/TestWhitebox.java b/flume-ng-sdk-test/src/test/java/org/apache/flume/sdk/test/TestWhitebox.java new file mode 100644 index 0000000000..16e15d2082 --- /dev/null +++ b/flume-ng-sdk-test/src/test/java/org/apache/flume/sdk/test/TestWhitebox.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.flume.sdk.test; + +import org.junit.Assert; +import org.junit.Test; + +public class TestWhitebox { + + private static final class Target { + private String value = "initial"; + } + + @Test + public void testGetInternalState() { + Assert.assertEquals("initial", Whitebox.getInternalState(new Target(), "value")); + } + + @Test + public void testSetInternalState() { + Target target = new Target(); + Whitebox.setInternalState(target, "value", "replaced"); + Assert.assertEquals("replaced", target.value); + } + + @Test(expected = RuntimeException.class) + public void testUnknownFieldFails() { + Whitebox.getInternalState(new Target(), "missing"); + } +} diff --git a/flume-ng-sdk-test/src/test/java/org/apache/flume/sdk/test/TestX509Certificates.java b/flume-ng-sdk-test/src/test/java/org/apache/flume/sdk/test/TestX509Certificates.java new file mode 100644 index 0000000000..ea31fabe3b --- /dev/null +++ b/flume-ng-sdk-test/src/test/java/org/apache/flume/sdk/test/TestX509Certificates.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.flume.sdk.test; + +import java.security.KeyPair; +import java.security.cert.X509Certificate; +import java.util.Collections; +import java.util.Date; +import org.junit.Assert; +import org.junit.Test; + +public class TestX509Certificates { + + @Test + public void testSelfSignedCertificate() throws Exception { + KeyPair keyPair = X509Certificates.generateKeyPair(); + X509Certificate certificate = X509Certificates.generateSelfSignedCertificate(keyPair, "CN=localhost"); + + Assert.assertEquals( + "CN=localhost", certificate.getSubjectX500Principal().getName()); + Assert.assertEquals(certificate.getSubjectX500Principal(), certificate.getIssuerX500Principal()); + // A self-signed certificate verifies against its own public key. + certificate.verify(keyPair.getPublic()); + certificate.checkValidity(new Date()); + } + + @Test + public void testServerCertificateExtensions() throws Exception { + KeyPair keyPair = X509Certificates.generateKeyPair(); + X509Certificate certificate = X509Certificates.generateSelfSignedCertificate(keyPair, "CN=localhost"); + + // A negative path length constraint marks a certificate that is not a CA. + Assert.assertEquals(-1, certificate.getBasicConstraints()); + Assert.assertEquals(Collections.singletonList("1.3.6.1.5.5.7.3.1"), certificate.getExtendedKeyUsage()); + } + + @Test + public void testKeyPairsAreDistinct() { + Assert.assertNotEquals( + X509Certificates.generateKeyPair().getPrivate(), + X509Certificates.generateKeyPair().getPrivate()); + } +} diff --git a/flume-ng-sdk/pom.xml b/flume-ng-sdk/pom.xml index c5b1d20d69..afc5fc81b9 100644 --- a/flume-ng-sdk/pom.xml +++ b/flume-ng-sdk/pom.xml @@ -44,19 +44,6 @@ test - - - org.bouncycastle - bcpkix-jdk18on - test - - - - org.bouncycastle - bcprov-jdk18on - test - - org.apache.logging.log4j log4j-api @@ -82,32 +69,6 @@ - - org.apache.maven.plugins - maven-jar-plugin - - - - test-jar - - - - - - true - true - - - pkg:maven/${project.groupId}/${project.artifactId}@${project.version}?classifier=tests&type=test-jar - - - - - - - org.apache.maven.plugins maven-surefire-plugin diff --git a/flume-ng-sources/flume-http-source/pom.xml b/flume-ng-sources/flume-http-source/pom.xml index d7f2b58500..d3def5ee43 100644 --- a/flume-ng-sources/flume-http-source/pom.xml +++ b/flume-ng-sources/flume-http-source/pom.xml @@ -45,8 +45,7 @@ org.apache.flume - flume-ng-sdk - tests + flume-ng-sdk-test test diff --git a/flume-ng-sources/flume-http-source/src/test/java/org/apache/flume/source/http/TestHTTPSource.java b/flume-ng-sources/flume-http-source/src/test/java/org/apache/flume/source/http/TestHTTPSource.java index 8aa5ea2e8f..4b182805d8 100644 --- a/flume-ng-sources/flume-http-source/src/test/java/org/apache/flume/source/http/TestHTTPSource.java +++ b/flume-ng-sources/flume-http-source/src/test/java/org/apache/flume/source/http/TestHTTPSource.java @@ -63,8 +63,8 @@ import org.apache.flume.conf.Configurables; import org.apache.flume.event.JSONEvent; import org.apache.flume.instrumentation.SourceCounter; -import org.apache.flume.util.TestKeyStores; -import org.apache.flume.util.Whitebox; +import org.apache.flume.sdk.test.TestKeyStores; +import org.apache.flume.sdk.test.Whitebox; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpOptions; diff --git a/flume-ng-sources/flume-syslog-source/pom.xml b/flume-ng-sources/flume-syslog-source/pom.xml index 1f0beb2f9a..50ef7a2014 100644 --- a/flume-ng-sources/flume-syslog-source/pom.xml +++ b/flume-ng-sources/flume-syslog-source/pom.xml @@ -49,8 +49,7 @@ org.apache.flume - flume-ng-sdk - tests + flume-ng-sdk-test test diff --git a/flume-ng-sources/flume-syslog-source/src/test/java/org/apache/flume/source/syslog/TestMultiportSyslogTCPSource.java b/flume-ng-sources/flume-syslog-source/src/test/java/org/apache/flume/source/syslog/TestMultiportSyslogTCPSource.java index 4976e135e6..af739b5836 100644 --- a/flume-ng-sources/flume-syslog-source/src/test/java/org/apache/flume/source/syslog/TestMultiportSyslogTCPSource.java +++ b/flume-ng-sources/flume-syslog-source/src/test/java/org/apache/flume/source/syslog/TestMultiportSyslogTCPSource.java @@ -62,12 +62,12 @@ import org.apache.flume.conf.Configurables; import org.apache.flume.exception.ChannelException; import org.apache.flume.instrumentation.SourceCounter; +import org.apache.flume.sdk.test.TestKeyStores; +import org.apache.flume.sdk.test.Whitebox; import org.apache.flume.source.syslog.MultiportSyslogTCPSource.LineSplitter; import org.apache.flume.source.syslog.MultiportSyslogTCPSource.MultiportSyslogHandler; import org.apache.flume.source.syslog.MultiportSyslogTCPSource.ParsedBuffer; import org.apache.flume.source.syslog.MultiportSyslogTCPSource.ThreadSafeDecoder; -import org.apache.flume.util.TestKeyStores; -import org.apache.flume.util.Whitebox; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.mina.core.buffer.IoBuffer; diff --git a/flume-ng-sources/flume-syslog-source/src/test/java/org/apache/flume/source/syslog/TestSyslogTcpSource.java b/flume-ng-sources/flume-syslog-source/src/test/java/org/apache/flume/source/syslog/TestSyslogTcpSource.java index d6cf09a49f..a4eb816fdb 100644 --- a/flume-ng-sources/flume-syslog-source/src/test/java/org/apache/flume/source/syslog/TestSyslogTcpSource.java +++ b/flume-ng-sources/flume-syslog-source/src/test/java/org/apache/flume/source/syslog/TestSyslogTcpSource.java @@ -50,7 +50,7 @@ import org.apache.flume.channel.ReplicatingChannelSelector; import org.apache.flume.conf.Configurables; import org.apache.flume.exception.ChannelException; -import org.apache.flume.util.TestKeyStores; +import org.apache.flume.sdk.test.TestKeyStores; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.junit.Assert; diff --git a/flume-ng-sources/flume-taildir-source/pom.xml b/flume-ng-sources/flume-taildir-source/pom.xml index d371c0f3b4..2444b0f84a 100644 --- a/flume-ng-sources/flume-taildir-source/pom.xml +++ b/flume-ng-sources/flume-taildir-source/pom.xml @@ -43,8 +43,7 @@ org.apache.flume - flume-ng-sdk - tests + flume-ng-sdk-test test diff --git a/flume-ng-sources/flume-taildir-source/src/test/java/org/apache/flume/source/taildir/TestTaildirSource.java b/flume-ng-sources/flume-taildir-source/src/test/java/org/apache/flume/source/taildir/TestTaildirSource.java index 4c8ec6a6b4..ff4bb18f44 100644 --- a/flume-ng-sources/flume-taildir-source/src/test/java/org/apache/flume/source/taildir/TestTaildirSource.java +++ b/flume-ng-sources/flume-taildir-source/src/test/java/org/apache/flume/source/taildir/TestTaildirSource.java @@ -57,7 +57,7 @@ import org.apache.flume.exception.ChannelException; import org.apache.flume.lifecycle.LifecycleController; import org.apache.flume.lifecycle.LifecycleState; -import org.apache.flume.util.Whitebox; +import org.apache.flume.sdk.test.Whitebox; import org.junit.After; import org.junit.Assume; import org.junit.Before; diff --git a/flume-parent/pom.xml b/flume-parent/pom.xml index 8036ba0ae2..03005e9cf3 100644 --- a/flume-parent/pom.xml +++ b/flume-parent/pom.xml @@ -213,9 +213,8 @@ org.apache.flume - flume-ng-sdk + flume-ng-sdk-test ${flume-project.version} - tests test diff --git a/pom.xml b/pom.xml index 061bef4214..019f9ad801 100644 --- a/pom.xml +++ b/pom.xml @@ -70,6 +70,7 @@ --> flume-ng-channels flume-ng-sdk + flume-ng-sdk-test