This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-codec.git
The following commit(s) were added to refs/heads/master by this push:
new b20eaaad Add tests for BaseNCodecOutputStream.close()
b20eaaad is described below
commit b20eaaad36b6562ebccd5afbded7199ffc5b040c
Author: Gary Gregory <[email protected]>
AuthorDate: Sat Mar 7 07:59:10 2026 -0500
Add tests for BaseNCodecOutputStream.close()
See [CODEC-334] BaseNCodecOutputStream.close() throws on second call —
violates Closeable idempotency contract
---
.../binary/AbstractBaseNOutputStreamTest.java | 39 ++++++++++++++++++++
.../codec/binary/Base16OutputStreamTest.java | 20 +++++++---
.../codec/binary/Base32OutputStreamTest.java | 7 +++-
.../codec/binary/Base58OutputStreamTest.java | 7 +++-
.../codec/binary/Base64OutputStreamTest.java | 7 +++-
.../codec/binary/BaseNCodecOutputStreamTest.java | 32 ++++++++++++++++
.../commons/codec/binary/BaseNCodecTest.java | 25 -------------
.../commons/codec/binary/NoOpBaseNCodec.java | 43 ++++++++++++++++++++++
8 files changed, 147 insertions(+), 33 deletions(-)
diff --git
a/src/test/java/org/apache/commons/codec/binary/AbstractBaseNOutputStreamTest.java
b/src/test/java/org/apache/commons/codec/binary/AbstractBaseNOutputStreamTest.java
new file mode 100644
index 00000000..57e542c7
--- /dev/null
+++
b/src/test/java/org/apache/commons/codec/binary/AbstractBaseNOutputStreamTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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
+ *
+ * https://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.commons.codec.binary;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * Abstract class for {@link BaseNCodecOutputStream} and its subclasses.
+ */
+abstract class AbstractBaseNOutputStreamTest {
+
+ abstract OutputStream newOutputStream();
+
+ @Test
+ void testClose() throws IOException {
+ try (OutputStream out = newOutputStream()) {
+ out.close();
+ out.close();
+ }
+ }
+}
diff --git
a/src/test/java/org/apache/commons/codec/binary/Base16OutputStreamTest.java
b/src/test/java/org/apache/commons/codec/binary/Base16OutputStreamTest.java
index 1ab234bd..8bbffd5b 100644
--- a/src/test/java/org/apache/commons/codec/binary/Base16OutputStreamTest.java
+++ b/src/test/java/org/apache/commons/codec/binary/Base16OutputStreamTest.java
@@ -30,10 +30,15 @@ import org.junit.jupiter.api.Test;
/**
* Tests {@link Base16OutputStream}.
*/
-class Base16OutputStreamTest {
+class Base16OutputStreamTest extends AbstractBaseNOutputStreamTest {
private static final String STRING_FIXTURE = "Hello World";
+ @Override
+ OutputStream newOutputStream() {
+ return new Base16OutputStream(new ByteArrayOutputStream());
+ }
+
/**
* Test the Base16OutputStream implementation against empty input.
*
@@ -132,7 +137,6 @@ class Base16OutputStreamTest {
* @throws IOException Usually signifies a bug in the Base16 commons-codec
implementation.
*/
private void testByChunk(final byte[] encoded, final byte[] decoded, final
boolean lowerCase) throws IOException {
-
// Start with encode.
try (ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
OutputStream out = new Base16OutputStream(byteOut, true,
lowerCase)) {
@@ -140,7 +144,6 @@ class Base16OutputStreamTest {
final byte[] output = byteOut.toByteArray();
assertArrayEquals(encoded, output, "Streaming chunked base16
encode");
}
-
// Now let's try to decode.
try (ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
OutputStream out = new Base16OutputStream(byteOut, false,
lowerCase)) {
@@ -148,7 +151,6 @@ class Base16OutputStreamTest {
final byte[] output = byteOut.toByteArray();
assertArrayEquals(decoded, output, "Streaming chunked base16
decode");
}
-
// wrap encoder with decoder
try (ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
OutputStream decoderOut = new Base16OutputStream(byteOut, false,
lowerCase);
@@ -156,7 +158,6 @@ class Base16OutputStreamTest {
encoderOut.write(decoded);
final byte[] output = byteOut.toByteArray();
-
assertArrayEquals(decoded, output, "Streaming chunked base16
wrap-wrap!");
}
}
@@ -238,6 +239,15 @@ class Base16OutputStreamTest {
}
}
+ @Override
+ @Test
+ void testClose() throws IOException {
+ try (OutputStream out = newOutputStream()) {
+ out.close();
+ out.close();
+ }
+ }
+
/**
* Tests Base16OutputStream.write for expected IndexOutOfBoundsException
conditions.
*
diff --git
a/src/test/java/org/apache/commons/codec/binary/Base32OutputStreamTest.java
b/src/test/java/org/apache/commons/codec/binary/Base32OutputStreamTest.java
index a5447458..705a4a1b 100644
--- a/src/test/java/org/apache/commons/codec/binary/Base32OutputStreamTest.java
+++ b/src/test/java/org/apache/commons/codec/binary/Base32OutputStreamTest.java
@@ -32,7 +32,7 @@ import org.junit.jupiter.api.Test;
/**
* Tests {@link Base32OutputStream}.
*/
-class Base32OutputStreamTest {
+class Base32OutputStreamTest extends AbstractBaseNOutputStreamTest {
private static final byte[] CR_LF = {(byte) '\r', (byte) '\n'};
@@ -61,6 +61,11 @@ class Base32OutputStreamTest {
// );
// }
+ @Override
+ OutputStream newOutputStream() {
+ return new Base32OutputStream(new ByteArrayOutputStream());
+ }
+
private void testBase32EmptyOutputStream(final int chunkSize) throws
Exception {
final byte[] emptyEncoded = {};
final byte[] emptyDecoded = {};
diff --git
a/src/test/java/org/apache/commons/codec/binary/Base58OutputStreamTest.java
b/src/test/java/org/apache/commons/codec/binary/Base58OutputStreamTest.java
index abcaf3eb..266f036a 100644
--- a/src/test/java/org/apache/commons/codec/binary/Base58OutputStreamTest.java
+++ b/src/test/java/org/apache/commons/codec/binary/Base58OutputStreamTest.java
@@ -29,12 +29,17 @@ import org.junit.jupiter.api.Test;
/**
* Tests {@link Base58OutputStream}.
*/
-class Base58OutputStreamTest {
+class Base58OutputStreamTest extends AbstractBaseNOutputStreamTest {
private static final byte[] CR_LF = { (byte) '\r', (byte) '\n' };
private static final byte[] LF = { (byte) '\n' };
+ @Override
+ OutputStream newOutputStream() {
+ return new Base58OutputStream(new ByteArrayOutputStream());
+ }
+
private void testBase58EmptyOutputStream(final int chunkSize) throws
Exception {
final byte[] emptyEncoded = {};
final byte[] emptyDecoded = {};
diff --git
a/src/test/java/org/apache/commons/codec/binary/Base64OutputStreamTest.java
b/src/test/java/org/apache/commons/codec/binary/Base64OutputStreamTest.java
index 3f11f18b..058e7ac3 100644
--- a/src/test/java/org/apache/commons/codec/binary/Base64OutputStreamTest.java
+++ b/src/test/java/org/apache/commons/codec/binary/Base64OutputStreamTest.java
@@ -33,7 +33,7 @@ import org.junit.jupiter.api.Test;
/**
* Tests {@link Base64OutputStream}.
*/
-class Base64OutputStreamTest {
+class Base64OutputStreamTest extends AbstractBaseNOutputStreamTest {
private static final byte[] CR_LF = {(byte) '\r', (byte) '\n'};
@@ -41,6 +41,11 @@ class Base64OutputStreamTest {
private static final String STRING_FIXTURE = "Hello World";
+ @Override
+ OutputStream newOutputStream() {
+ return new Base64OutputStream(new ByteArrayOutputStream());
+ }
+
private void testBase64EmptyOutputStream(final int chunkSize) throws
Exception {
final byte[] emptyEncoded = {};
final byte[] emptyDecoded = {};
diff --git
a/src/test/java/org/apache/commons/codec/binary/BaseNCodecOutputStreamTest.java
b/src/test/java/org/apache/commons/codec/binary/BaseNCodecOutputStreamTest.java
new file mode 100644
index 00000000..b53e0c1e
--- /dev/null
+++
b/src/test/java/org/apache/commons/codec/binary/BaseNCodecOutputStreamTest.java
@@ -0,0 +1,32 @@
+/*
+ * 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
+ *
+ * https://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.commons.codec.binary;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+
+/**
+ * Tests {@link BaseNCodecOutputStream}.
+ */
+public class BaseNCodecOutputStreamTest extends AbstractBaseNOutputStreamTest {
+
+ @Override
+ OutputStream newOutputStream() {
+ return new BaseNCodecOutputStream(new ByteArrayOutputStream(), new
NoOpBaseNCodec(), true);
+ }
+}
diff --git a/src/test/java/org/apache/commons/codec/binary/BaseNCodecTest.java
b/src/test/java/org/apache/commons/codec/binary/BaseNCodecTest.java
index 871d4092..642abe62 100644
--- a/src/test/java/org/apache/commons/codec/binary/BaseNCodecTest.java
+++ b/src/test/java/org/apache/commons/codec/binary/BaseNCodecTest.java
@@ -31,31 +31,6 @@ import org.junit.jupiter.api.Test;
class BaseNCodecTest {
- /**
- * Extend BaseNCodec without implementation (no operations = NoOp).
- * Used for testing the memory allocation in {@link
BaseNCodec#ensureBufferSize(int, Context)}.
- */
- private static final class NoOpBaseNCodec extends BaseNCodec {
- NoOpBaseNCodec() {
- super(0, 0, 0, 0);
- }
-
- @Override
- void decode(final byte[] array, final int i, final int length, final
Context context) {
- // no-op
- }
-
- @Override
- void encode(final byte[] array, final int i, final int length, final
Context context) {
- // no-op
- }
-
- @Override
- protected boolean isInAlphabet(final byte value) {
- return false;
- }
- }
-
private static void assertEnsureBufferSizeExpandsToMaxBufferSize(final
boolean exceedMaxBufferSize) {
// This test is memory hungry.
// By default expansion will double the buffer size.
diff --git a/src/test/java/org/apache/commons/codec/binary/NoOpBaseNCodec.java
b/src/test/java/org/apache/commons/codec/binary/NoOpBaseNCodec.java
new file mode 100644
index 00000000..f3c6d939
--- /dev/null
+++ b/src/test/java/org/apache/commons/codec/binary/NoOpBaseNCodec.java
@@ -0,0 +1,43 @@
+/*
+ * 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
+ *
+ * https://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.commons.codec.binary;
+
+/**
+ * Extend BaseNCodec without implementation (no operations = NoOp).
+ * Used for testing the memory allocation in {@link
BaseNCodec#ensureBufferSize(int, Context)}.
+ */
+final class NoOpBaseNCodec extends BaseNCodec {
+ NoOpBaseNCodec() {
+ super(0, 0, 0, 0);
+ }
+
+ @Override
+ void decode(final byte[] array, final int i, final int length, final
Context context) {
+ // no-op
+ }
+
+ @Override
+ void encode(final byte[] array, final int i, final int length, final
Context context) {
+ // no-op
+ }
+
+ @Override
+ protected boolean isInAlphabet(final byte value) {
+ return false;
+ }
+}