From a24e7d06619370720e4820deedde88c6b0b44e87 Mon Sep 17 00:00:00 2001 From: Davide Angelocola Date: Sun, 28 Jun 2026 00:06:47 +0200 Subject: [PATCH] chore: clear SonarCloud code smells (78 -> 0) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All open issues were CODE_SMELL (0 bugs, 0 vulns; gate already green). Fix the genuine ones and suppress the rules that conflict with mandatory FFM idiom or an enforced project convention: Fixed: - S6213 (28) rename variables matching restricted identifiers - S5838 (6) use AssertJ hasSize/hasSizeLessThan - S5853 (3) chain assertions on the same actual (left the side-effecting InputStream.read() triple alone — chaining would change reads) - S1066 (1) merge nested if in ZstdInputStream.produce() (behavior-identical) - S7467 (1) unnamed pattern for an unused binding Suppressed (with justification): - S7474 (34) pom-level ignore: the rule wants {@link}/HTML javadoc, which the project forbids (mandates `///` Markdown + [Class#method] refs, checkstyle-enforced) - S112 (3) @SuppressWarnings on the invokeExact wrapper interfaces - S1181 (1) catching Throwable is mandatory: MethodHandle.invokeExact throws it - S3776 (1) produce() complexity is inherent to the decode/EOF loop and tested No production behavior change. validate + test green. Co-Authored-By: Claude Opus 4.8 --- .../github/dfa1/zstd/it/GoldenCorpusTest.java | 5 +- .../dfa1/zstd/it/ZstdInteropExtrasTest.java | 11 +- .../dfa1/zstd/it/ZstdJniInteropTest.java | 30 ++-- pom.xml | 9 ++ .../java/io/github/dfa1/zstd/NativeCall.java | 2 + .../io/github/dfa1/zstd/NativeObject.java | 1 + .../dfa1/zstd/ZstdDecompressStream.java | 1 + .../io/github/dfa1/zstd/ZstdInputStream.java | 18 ++- .../io/github/dfa1/zstd/NativeObjectTest.java | 2 +- .../io/github/dfa1/zstd/RefPrefixTest.java | 2 +- .../github/dfa1/zstd/ZstdDictionaryTest.java | 152 +++++++++--------- .../io/github/dfa1/zstd/ZstdFrameTest.java | 5 +- .../github/dfa1/zstd/ZstdParameterTest.java | 4 +- .../dfa1/zstd/ZstdSegmentStreamTest.java | 10 +- .../io/github/dfa1/zstd/ZstdSegmentTest.java | 22 +-- .../io/github/dfa1/zstd/ZstdStreamTest.java | 28 ++-- .../java/io/github/dfa1/zstd/ZstdTest.java | 4 +- 17 files changed, 162 insertions(+), 144 deletions(-) diff --git a/integration-tests/src/test/java/io/github/dfa1/zstd/it/GoldenCorpusTest.java b/integration-tests/src/test/java/io/github/dfa1/zstd/it/GoldenCorpusTest.java index bd62e5f..7e65733 100644 --- a/integration-tests/src/test/java/io/github/dfa1/zstd/it/GoldenCorpusTest.java +++ b/integration-tests/src/test/java/io/github/dfa1/zstd/it/GoldenCorpusTest.java @@ -254,8 +254,9 @@ void dictIdRidesWithFrame(Path file) { ZstdDictionaryId frameDictId = ZstdFrame.dictId(frame); // Then - assertThat(frameDictId).isEqualTo(dict.id()); - assertThat(frameDictId).isNotEqualTo(ZstdDictionaryId.NONE); + assertThat(frameDictId) + .isEqualTo(dict.id()) + .isNotEqualTo(ZstdDictionaryId.NONE); } } } diff --git a/integration-tests/src/test/java/io/github/dfa1/zstd/it/ZstdInteropExtrasTest.java b/integration-tests/src/test/java/io/github/dfa1/zstd/it/ZstdInteropExtrasTest.java index d509652..456c244 100644 --- a/integration-tests/src/test/java/io/github/dfa1/zstd/it/ZstdInteropExtrasTest.java +++ b/integration-tests/src/test/java/io/github/dfa1/zstd/it/ZstdInteropExtrasTest.java @@ -217,25 +217,26 @@ void javaReadsDictIdFromJniDictFrame() { ZstdDictionary dict = trainDict(); var jniDict = new com.github.luben.zstd.ZstdDictCompress( dict.toByteArray(), Zstd.defaultCompressionLevel()); - byte[] frame = com.github.luben.zstd.Zstd.compress(record(7), jniDict); + byte[] frame = com.github.luben.zstd.Zstd.compress(sample(7), jniDict); // When ZstdDictionaryId dictId = ZstdFrame.dictId(frame); // Then - assertThat(dictId).isEqualTo(dict.id()); - assertThat(dictId).isNotEqualTo(ZstdDictionaryId.NONE); + assertThat(dictId) + .isEqualTo(dict.id()) + .isNotEqualTo(ZstdDictionaryId.NONE); } private ZstdDictionary trainDict() { List samples = new ArrayList<>(); for (int i = 0; i < 3000; i++) { - samples.add(record(i)); + samples.add(sample(i)); } return ZstdDictionary.train(samples, 8 * 1024); } - private byte[] record(int i) { + private byte[] sample(int i) { return ("{\"id\":" + i + ",\"user\":\"u" + (i % 30) + "\",\"event\":\"click\"}") .getBytes(StandardCharsets.UTF_8); } diff --git a/integration-tests/src/test/java/io/github/dfa1/zstd/it/ZstdJniInteropTest.java b/integration-tests/src/test/java/io/github/dfa1/zstd/it/ZstdJniInteropTest.java index 9148a59..cc0e5ac 100644 --- a/integration-tests/src/test/java/io/github/dfa1/zstd/it/ZstdJniInteropTest.java +++ b/integration-tests/src/test/java/io/github/dfa1/zstd/it/ZstdJniInteropTest.java @@ -100,29 +100,29 @@ class Dictionary { @Test void javaDictCompressJniDictDecompress() { ZstdDictionary dict = trainDict(); - byte[] record = record(11); + byte[] sample = sample(11); byte[] frame; try (ZstdCompressCtx ctx = new ZstdCompressCtx()) { - frame = ctx.compress(record, dict); + frame = ctx.compress(sample, dict); } ZstdDictDecompress jniDict = new ZstdDictDecompress(dict.toByteArray()); - assertThat(com.github.luben.zstd.Zstd.decompress(frame, jniDict, record.length)).isEqualTo(record); + assertThat(com.github.luben.zstd.Zstd.decompress(frame, jniDict, sample.length)).isEqualTo(sample); } @Test void jniDictCompressJavaDictDecompress() { ZstdDictionary dict = trainDict(); - byte[] record = record(22); + byte[] sample = sample(22); ZstdDictCompress jniDict = new ZstdDictCompress(dict.toByteArray(), Zstd.defaultCompressionLevel()); - byte[] frame = com.github.luben.zstd.Zstd.compress(record, jniDict); + byte[] frame = com.github.luben.zstd.Zstd.compress(sample, jniDict); byte[] restored; try (ZstdDecompressCtx ctx = new ZstdDecompressCtx()) { - restored = ctx.decompress(frame, record.length, dict); + restored = ctx.decompress(frame, sample.length, dict); } - assertThat(restored).isEqualTo(record); + assertThat(restored).isEqualTo(sample); } @Test @@ -131,42 +131,42 @@ void javaLoadedDictWithChecksumJniDictDecompress() { // (checksum) — the COMPRESS2 path — must still produce a frame zstd-jni // decodes against the same dictionary. ZstdDictionary dict = trainDict(); - byte[] record = record(33); + byte[] sample = sample(33); byte[] frame; try (ZstdCompressCtx ctx = new ZstdCompressCtx().checksum(true)) { ctx.loadDictionary(dict); - frame = ctx.compress(record); + frame = ctx.compress(sample); } ZstdDictDecompress jniDict = new ZstdDictDecompress(dict.toByteArray()); - assertThat(com.github.luben.zstd.Zstd.decompress(frame, jniDict, record.length)).isEqualTo(record); + assertThat(com.github.luben.zstd.Zstd.decompress(frame, jniDict, sample.length)).isEqualTo(sample); } @Test void javaReferencedDigestedDictJniDictDecompress() { // A frame from a context referencing a digested CDict must decode in zstd-jni. ZstdDictionary dict = trainDict(); - byte[] record = record(44); + byte[] sample = sample(44); byte[] frame; try (ZstdCompressDict cdict = new ZstdCompressDict(dict, Zstd.defaultCompressionLevel()); ZstdCompressCtx ctx = new ZstdCompressCtx()) { ctx.refDictionary(cdict); - frame = ctx.compress(record); + frame = ctx.compress(sample); } ZstdDictDecompress jniDict = new ZstdDictDecompress(dict.toByteArray()); - assertThat(com.github.luben.zstd.Zstd.decompress(frame, jniDict, record.length)).isEqualTo(record); + assertThat(com.github.luben.zstd.Zstd.decompress(frame, jniDict, sample.length)).isEqualTo(sample); } private ZstdDictionary trainDict() { List samples = new ArrayList<>(); for (int i = 0; i < 3000; i++) { - samples.add(record(i)); + samples.add(sample(i)); } return ZstdDictionary.train(samples, 8 * 1024); } - private byte[] record(int i) { + private byte[] sample(int i) { return ("{\"id\":" + i + ",\"user\":\"u" + (i % 30) + "\",\"event\":\"click\"}") .getBytes(StandardCharsets.UTF_8); } diff --git a/pom.xml b/pom.xml index ec44717..d5026d6 100644 --- a/pom.xml +++ b/pom.xml @@ -72,6 +72,15 @@ **/benchmark/** + + jep467 + java:S7474 + **/*.java **/benchmark/** diff --git a/zstd/src/main/java/io/github/dfa1/zstd/NativeCall.java b/zstd/src/main/java/io/github/dfa1/zstd/NativeCall.java index d7cc61c..8181289 100644 --- a/zstd/src/main/java/io/github/dfa1/zstd/NativeCall.java +++ b/zstd/src/main/java/io/github/dfa1/zstd/NativeCall.java @@ -12,6 +12,7 @@ final class NativeCall { /// A native call returning a zstd `size_t` status that may encode an error. @FunctionalInterface + @SuppressWarnings("java:S112") // wraps MethodHandle.invokeExact, which is declared to throw Throwable interface ZstdCall { long run() throws Throwable; } @@ -33,6 +34,7 @@ static long checkReturnValue(ZstdCall c) { /// A native factory call returning a freshly allocated object pointer. @FunctionalInterface + @SuppressWarnings("java:S112") // wraps MethodHandle.invokeExact, which is declared to throw Throwable interface NativeFactory { MemorySegment create() throws Throwable; } diff --git a/zstd/src/main/java/io/github/dfa1/zstd/NativeObject.java b/zstd/src/main/java/io/github/dfa1/zstd/NativeObject.java index c91ef92..698d0fe 100644 --- a/zstd/src/main/java/io/github/dfa1/zstd/NativeObject.java +++ b/zstd/src/main/java/io/github/dfa1/zstd/NativeObject.java @@ -47,5 +47,6 @@ public final void close() { /// /// @param ptr the non-NULL native pointer to free /// @throws Throwable if the native free call fails; the exception is swallowed by [#close()] + @SuppressWarnings("java:S112") // implementations wrap MethodHandle.invokeExact, declared to throw Throwable protected abstract void tryClose(MemorySegment ptr) throws Throwable; } diff --git a/zstd/src/main/java/io/github/dfa1/zstd/ZstdDecompressStream.java b/zstd/src/main/java/io/github/dfa1/zstd/ZstdDecompressStream.java index a1f59ae..ef3dfc7 100644 --- a/zstd/src/main/java/io/github/dfa1/zstd/ZstdDecompressStream.java +++ b/zstd/src/main/java/io/github/dfa1/zstd/ZstdDecompressStream.java @@ -26,6 +26,7 @@ public ZstdDecompressStream() { /// Creates a streaming decompressor for frames built with `dictionary`. /// /// @param dictionary the dictionary the frames were compressed against, or `null` for none + @SuppressWarnings("java:S1181") // loadDictionary wraps MethodHandle.invokeExact (throws Throwable); must catch Throwable public ZstdDecompressStream(ZstdDictionary dictionary) { // Own the context first, so any failure setting it up is cleaned up by // close() — one release path, no leak on a half-built stream. diff --git a/zstd/src/main/java/io/github/dfa1/zstd/ZstdInputStream.java b/zstd/src/main/java/io/github/dfa1/zstd/ZstdInputStream.java index d4ac8bb..715a33d 100644 --- a/zstd/src/main/java/io/github/dfa1/zstd/ZstdInputStream.java +++ b/zstd/src/main/java/io/github/dfa1/zstd/ZstdInputStream.java @@ -127,6 +127,10 @@ public int read(byte[] b, int off, int len) throws IOException { } /// Decodes the next slice of output into `hold`. Returns false at end of stream. + // The branching here (input refill, truncation detection, no-progress guard) is + // essential to correct EOF/truncation handling and is covered by tests; splitting + // it would obscure the decode loop rather than clarify it. + @SuppressWarnings("java:S3776") // cognitive complexity is inherent to the streaming decode/EOF logic private boolean produce() throws IOException { while (true) { if (inBuf.pos() == inBuf.size()) { @@ -157,15 +161,13 @@ private boolean produce() throws IOException { } // Nothing produced. If the decoder neither advanced its input nor wants // more, it cannot make progress on this input — stop to avoid spinning. - if (inBuf.pos() == inBuf.size()) { - if (inputEof) { - if (lastHint != 0) { - throw new ZstdException("truncated zstd stream: " + lastHint - + " more input byte(s) expected"); - } - return false; + // (Input drained but not at EOF: fall through and loop to refill from `in`.) + if (inBuf.pos() == inBuf.size() && inputEof) { + if (lastHint != 0) { + throw new ZstdException("truncated zstd stream: " + lastHint + + " more input byte(s) expected"); } - // input drained but frame wants more: loop to refill from `in`. + return false; } } } diff --git a/zstd/src/test/java/io/github/dfa1/zstd/NativeObjectTest.java b/zstd/src/test/java/io/github/dfa1/zstd/NativeObjectTest.java index d5316be..81133d8 100644 --- a/zstd/src/test/java/io/github/dfa1/zstd/NativeObjectTest.java +++ b/zstd/src/test/java/io/github/dfa1/zstd/NativeObjectTest.java @@ -15,7 +15,7 @@ import org.assertj.core.api.ThrowableAssert.ThrowingCallable; import org.junit.jupiter.api.Test; -class NativeObjectTest { +class NativeObjectTest { // A non-NULL stand-in pointer; never dereferenced, only compared by identity. private static final MemorySegment POINTER = MemorySegment.ofAddress(0x1234); diff --git a/zstd/src/test/java/io/github/dfa1/zstd/RefPrefixTest.java b/zstd/src/test/java/io/github/dfa1/zstd/RefPrefixTest.java index 9c7f9bc..7310886 100644 --- a/zstd/src/test/java/io/github/dfa1/zstd/RefPrefixTest.java +++ b/zstd/src/test/java/io/github/dfa1/zstd/RefPrefixTest.java @@ -79,7 +79,7 @@ void prefixIsAppliedAndRequiredToDecode() { MemorySegment out = arena.allocate(random.length); long m = dctx.decompress(out, segmentOf(arena, frame)); reproduced = Arrays.equals(bytesOf(out, (int) m), random); - } catch (ZstdException e) { + } catch (ZstdException _) { reproduced = false; } assertThat(reproduced).isFalse(); diff --git a/zstd/src/test/java/io/github/dfa1/zstd/ZstdDictionaryTest.java b/zstd/src/test/java/io/github/dfa1/zstd/ZstdDictionaryTest.java index e993f27..56190cd 100644 --- a/zstd/src/test/java/io/github/dfa1/zstd/ZstdDictionaryTest.java +++ b/zstd/src/test/java/io/github/dfa1/zstd/ZstdDictionaryTest.java @@ -29,7 +29,7 @@ void trainDictionary() { // Given many small, structurally-similar records — the case dictionaries win on samples = new ArrayList<>(); for (int i = 0; i < 4000; i++) { - samples.add(record(i)); + samples.add(sample(i)); } sut = ZstdDictionary.train(samples, 16 * 1024); } @@ -44,18 +44,18 @@ void fastCoverRoundTrips() { assertThat(dict.size()).isGreaterThan(0); // Then records round-trip and compress smaller than dictionaryless - byte[] record = samples.get(321); + byte[] sample = samples.get(321); byte[] plain; byte[] withDict; byte[] restored; try (ZstdCompressCtx cctx = new ZstdCompressCtx(); ZstdDecompressCtx dctx = new ZstdDecompressCtx()) { - plain = cctx.compress(record); - withDict = cctx.compress(record, dict); - restored = dctx.decompress(cctx.compress(record, dict), record.length, dict); + plain = cctx.compress(sample); + withDict = cctx.compress(sample, dict); + restored = dctx.decompress(cctx.compress(sample, dict), sample.length, dict); } - assertThat(withDict.length).isLessThan(plain.length); - assertThat(restored).isEqualTo(record); + assertThat(withDict).hasSizeLessThan(plain.length); + assertThat(restored).isEqualTo(sample); } @Test @@ -64,11 +64,11 @@ void coverRoundTrips() { ZstdDictionary dict = ZstdDictionary.trainCover(samples.subList(0, 1000), 8 * 1024); assertThat(dict.size()).isGreaterThan(0); - byte[] record = samples.get(5); + byte[] sample = samples.get(5); try (ZstdCompressCtx cctx = new ZstdCompressCtx(); ZstdDecompressCtx dctx = new ZstdDecompressCtx()) { - byte[] frame = cctx.compress(record, dict); - assertThat(dctx.decompress(frame, record.length, dict)).isEqualTo(record); + byte[] frame = cctx.compress(sample, dict); + assertThat(dctx.decompress(frame, sample.length, dict)).isEqualTo(sample); } } @@ -106,15 +106,15 @@ void finalizesRawContentIntoUsableDictionary() { ZstdDictionary dict = ZstdDictionary.finalizeFrom(content, samples, 16 * 1024, 0); - // Then it carries a header and round-trips a record + // Then it carries a header and round-trips a sample assertThat(dict.size()).isGreaterThan(0); assertThat(dict.headerSize()).isPositive(); - byte[] record = samples.get(3); + byte[] sample = samples.get(3); try (ZstdCompressCtx cctx = new ZstdCompressCtx(); ZstdDecompressCtx dctx = new ZstdDecompressCtx()) { - byte[] frame = cctx.compress(record, dict); - assertThat(dctx.decompress(frame, record.length, dict)).isEqualTo(record); + byte[] frame = cctx.compress(sample, dict); + assertThat(dctx.decompress(frame, sample.length, dict)).isEqualTo(sample); } } @@ -148,19 +148,19 @@ void producesNonEmptyDictionary() { @Test void beatsDictionarylessOnTinyPayload() { - // Given a single small record - byte[] record = samples.get(123); + // Given a single small sample + byte[] sample = samples.get(123); // When compressed with and without the dictionary byte[] plain; byte[] withDict; try (ZstdCompressCtx ctx = new ZstdCompressCtx()) { - plain = ctx.compress(record); - withDict = ctx.compress(record, sut); + plain = ctx.compress(sample); + withDict = ctx.compress(sample, sut); } - // Then the dictionary compresses the tiny record noticeably better - assertThat(withDict.length).isLessThan(plain.length); + // Then the dictionary compresses the tiny sample noticeably better + assertThat(withDict).hasSizeLessThan(plain.length); } @Test @@ -195,19 +195,19 @@ class RawDictionary { @ParameterizedTest @ValueSource(ints = {0, 7, 123, 2048, 3999}) void roundTripsRecord(int index) { - // Given a record - byte[] record = samples.get(index); + // Given a sample + byte[] sample = samples.get(index); // When compressed and decompressed against the raw dictionary byte[] restored; try (ZstdCompressCtx cctx = new ZstdCompressCtx(); ZstdDecompressCtx dctx = new ZstdDecompressCtx()) { - byte[] frame = cctx.compress(record, sut); - restored = dctx.decompress(frame, record.length, sut); + byte[] frame = cctx.compress(sample, sut); + restored = dctx.decompress(frame, sample.length, sut); } - // Then the record is recovered - assertThat(restored).isEqualTo(record); + // Then the sample is recovered + assertThat(restored).isEqualTo(sample); } } @@ -217,7 +217,7 @@ class DigestedDictionary { @Test void roundTripsViaCDictAndDDict() { // Given digested compress/decompress dictionaries at a fixed level - byte[] record = samples.get(999); + byte[] sample = samples.get(999); byte[] restored; int level; @@ -227,13 +227,13 @@ void roundTripsViaCDictAndDDict() { ZstdDecompressDict ddict = new ZstdDecompressDict(sut)) { // When round-tripped through the digested dictionaries - byte[] frame = cctx.compress(record, cdict); - restored = dctx.decompress(frame, record.length, ddict); + byte[] frame = cctx.compress(sample, cdict); + restored = dctx.decompress(frame, sample.length, ddict); level = cdict.level(); } - // Then the record is recovered at the requested level - assertThat(restored).isEqualTo(record); + // Then the sample is recovered at the requested level + assertThat(restored).isEqualTo(sample); assertThat(level).isEqualTo(19); } @@ -248,21 +248,21 @@ void digestedDictionariesReportTheSameId() { @Test void interoperatesWithRawPath() { - // Given a record compressed with the raw dictionary - byte[] record = samples.get(2048); + // Given a sample compressed with the raw dictionary + byte[] sample = samples.get(2048); byte[] restored; try (ZstdCompressCtx cctx = new ZstdCompressCtx(); ZstdDecompressCtx dctx = new ZstdDecompressCtx(); ZstdDecompressDict ddict = new ZstdDecompressDict(sut)) { - byte[] frame = cctx.compress(record, sut); + byte[] frame = cctx.compress(sample, sut); // When decompressed with the digested dictionary - restored = dctx.decompress(frame, record.length, ddict); + restored = dctx.decompress(frame, sample.length, ddict); } // Then the two dictionary forms interoperate - assertThat(restored).isEqualTo(record); + assertThat(restored).isEqualTo(sample); } } @@ -300,7 +300,7 @@ void decompressDictReportsTheDictionaryId() { @Test void factoryDictionariesRoundTrip() { // Given factory-built digested dictionaries - byte[] record = samples.get(123); + byte[] sample = samples.get(123); byte[] restored; try (ZstdCompressCtx cctx = new ZstdCompressCtx(); @@ -309,12 +309,12 @@ void factoryDictionariesRoundTrip() { ZstdDecompressDict ddict = sut.decompressDict()) { // When round-tripped through them - byte[] frame = cctx.compress(record, cdict); - restored = dctx.decompress(frame, record.length, ddict); + byte[] frame = cctx.compress(sample, cdict); + restored = dctx.decompress(frame, sample.length, ddict); } - // Then the record is recovered - assertThat(restored).isEqualTo(record); + // Then the sample is recovered + assertThat(restored).isEqualTo(sample); } } @@ -330,14 +330,14 @@ void reloadedDictionaryKeepsIdentityAndDecodes() { assertThat(reloaded.id()).isEqualTo(sut.id()); // And a frame from the reload decodes against the original - byte[] record = samples.get(1); + byte[] sample = samples.get(1); byte[] restored; try (ZstdCompressCtx cctx = new ZstdCompressCtx(); ZstdDecompressCtx dctx = new ZstdDecompressCtx()) { - byte[] frame = cctx.compress(record, reloaded); - restored = dctx.decompress(frame, record.length, sut); + byte[] frame = cctx.compress(sample, reloaded); + restored = dctx.decompress(frame, sample.length, sut); } - assertThat(restored).isEqualTo(record); + assertThat(restored).isEqualTo(sample); } } @@ -348,7 +348,7 @@ class SegmentDigestedDictionary { void roundTripsViaSegmentBuiltCDictAndDDict() { // Given digested dictionaries built straight from native dictionary // segments (the zero-copy path — no heap byte[] bounce) - byte[] record = samples.get(999); + byte[] sample = samples.get(999); byte[] raw = sut.toByteArray(); byte[] restored; @@ -360,13 +360,13 @@ void roundTripsViaSegmentBuiltCDictAndDDict() { ZstdDecompressDict ddict = new ZstdDecompressDict(nativeDict(arena, raw))) { // When round-tripped through the segment-built dictionaries - byte[] frame = cctx.compress(record, cdict); - restored = dctx.decompress(frame, record.length, ddict); + byte[] frame = cctx.compress(sample, cdict); + restored = dctx.decompress(frame, sample.length, ddict); level = cdict.level(); } - // Then the record is recovered at the requested level - assertThat(restored).isEqualTo(record); + // Then the sample is recovered at the requested level + assertThat(restored).isEqualTo(sample); assertThat(level).isEqualTo(19); } @@ -387,7 +387,7 @@ void segmentBuiltDictionariesReportSameIdAsHeap() { @Test void interoperatesWithHeapBuiltDictionaries() { // Given a frame compressed with a segment-built CDict - byte[] record = samples.get(2048); + byte[] sample = samples.get(2048); byte[] raw = sut.toByteArray(); byte[] restored; @@ -396,14 +396,14 @@ void interoperatesWithHeapBuiltDictionaries() { ZstdDecompressCtx dctx = new ZstdDecompressCtx(); ZstdCompressDict cdict = new ZstdCompressDict(nativeDict(arena, raw)); ZstdDecompressDict ddict = new ZstdDecompressDict(sut)) { - byte[] frame = cctx.compress(record, cdict); + byte[] frame = cctx.compress(sample, cdict); // When decompressed with a heap-built DDict - restored = dctx.decompress(frame, record.length, ddict); + restored = dctx.decompress(frame, sample.length, ddict); } // Then segment- and heap-built dictionaries interoperate - assertThat(restored).isEqualTo(record); + assertThat(restored).isEqualTo(sample); } @Test @@ -438,25 +438,25 @@ class StickyDictionary { void loadedDictionaryCombinesWithAdvancedParameters() { // Given a context with both a loaded dictionary AND a checksum — the // combination the per-call compress(src, dict) overloads cannot give - byte[] record = samples.get(123); + byte[] sample = samples.get(123); byte[] frame; try (ZstdCompressCtx cctx = new ZstdCompressCtx().checksum(true)) { cctx.loadDictionary(sut); - frame = cctx.compress(record); + frame = cctx.compress(sample); } byte[] plain; try (ZstdCompressCtx ctx = new ZstdCompressCtx()) { - plain = ctx.compress(record); + plain = ctx.compress(sample); } // Then the dictionary is honoured (smaller than dictionaryless) and decodes - assertThat(frame.length).isLessThan(plain.length); + assertThat(frame).hasSizeLessThan(plain.length); byte[] restored; try (ZstdDecompressCtx dctx = new ZstdDecompressCtx()) { dctx.loadDictionary(sut); - restored = dctx.decompress(frame, record.length); + restored = dctx.decompress(frame, sample.length); } - assertThat(restored).isEqualTo(record); + assertThat(restored).isEqualTo(sample); } @Test @@ -489,17 +489,17 @@ void referencedDigestedDictionarySurvivesSessionReset() { @Test void parameterResetClearsTheLoadedDictionary() { // Given a context that loaded a dictionary, then cleared its parameters - byte[] record = samples.get(7); + byte[] sample = samples.get(7); byte[] afterReset; try (ZstdCompressCtx cctx = new ZstdCompressCtx()) { cctx.loadDictionary(sut); - cctx.compress(record); + cctx.compress(sample); cctx.reset(ZstdResetDirective.SESSION_AND_PARAMETERS); - afterReset = cctx.compress(record); + afterReset = cctx.compress(sample); } byte[] noDict; try (ZstdCompressCtx ctx = new ZstdCompressCtx()) { - noDict = ctx.compress(record); + noDict = ctx.compress(sample); } // Then the dictionary is gone: the frame matches a fresh dictionaryless one @@ -509,16 +509,16 @@ void parameterResetClearsTheLoadedDictionary() { @Test void nullClearsTheLoadedDictionary() { // Given a context whose loaded dictionary is then cleared with null - byte[] record = samples.get(7); + byte[] sample = samples.get(7); byte[] cleared; try (ZstdCompressCtx cctx = new ZstdCompressCtx()) { cctx.loadDictionary(sut); cctx.loadDictionary((ZstdDictionary) null); - cleared = cctx.compress(record); + cleared = cctx.compress(sample); } byte[] noDict; try (ZstdCompressCtx ctx = new ZstdCompressCtx()) { - noDict = ctx.compress(record); + noDict = ctx.compress(sample); } // Then it compresses as if no dictionary was ever loaded @@ -528,20 +528,20 @@ void nullClearsTheLoadedDictionary() { @Test void loadsDictionaryFromNativeSegmentWithoutHeapCopy() { // Given a dictionary loaded straight from native segments (zero-copy path) - byte[] record = samples.get(2048); + byte[] sample = samples.get(2048); byte[] raw = sut.toByteArray(); byte[] restored; try (Arena arena = Arena.ofConfined(); ZstdCompressCtx cctx = new ZstdCompressCtx(); ZstdDecompressCtx dctx = new ZstdDecompressCtx()) { cctx.loadDictionary(nativeDict(arena, raw)); - byte[] frame = cctx.compress(record); + byte[] frame = cctx.compress(sample); dctx.loadDictionary(nativeDict(arena, raw)); - restored = dctx.decompress(frame, record.length); + restored = dctx.decompress(frame, sample.length); } - // Then the record round-trips through the segment-loaded dictionary - assertThat(restored).isEqualTo(record); + // Then the sample round-trips through the segment-loaded dictionary + assertThat(restored).isEqualTo(sample); } @Test @@ -561,16 +561,16 @@ void rejectsHeapDictionarySegment() { @Test void nullNativeSegmentClearsTheLoadedDictionary() { // Given a context whose dictionary is cleared through the native overload - byte[] record = samples.get(7); + byte[] sample = samples.get(7); byte[] cleared; try (ZstdCompressCtx cctx = new ZstdCompressCtx()) { cctx.loadDictionary(sut); cctx.loadDictionary((MemorySegment) null); - cleared = cctx.compress(record); + cleared = cctx.compress(sample); } byte[] noDict; try (ZstdCompressCtx ctx = new ZstdCompressCtx()) { - noDict = ctx.compress(record); + noDict = ctx.compress(sample); } // Then it compresses as if no dictionary was ever loaded @@ -610,7 +610,7 @@ void loadAndRefReturnTheSameDecompressContext() { } } - private static byte[] record(int i) { + private static byte[] sample(int i) { return ("{\"id\":" + i + ",\"user\":\"user_" + (i % 50) + "\",\"active\":" + (i % 2 == 0) diff --git a/zstd/src/test/java/io/github/dfa1/zstd/ZstdFrameTest.java b/zstd/src/test/java/io/github/dfa1/zstd/ZstdFrameTest.java index d3aafaa..2f4d75a 100644 --- a/zstd/src/test/java/io/github/dfa1/zstd/ZstdFrameTest.java +++ b/zstd/src/test/java/io/github/dfa1/zstd/ZstdFrameTest.java @@ -365,8 +365,9 @@ void contentHasValueEqualityOverTheBytesNotArrayIdentity() { // Then equality and hashCode follow the content bytes, and toString omits the identity hash assertThat(sameBytesEqual).isTrue(); assertThat(differentVariantEqual).isFalse(); - assertThat(a).hasSameHashCodeAs(b); - assertThat(a).hasToString("ZstdSkippableContent[content=4 bytes, magicVariant=3]"); + assertThat(a) + .hasSameHashCodeAs(b) + .hasToString("ZstdSkippableContent[content=4 bytes, magicVariant=3]"); } } diff --git a/zstd/src/test/java/io/github/dfa1/zstd/ZstdParameterTest.java b/zstd/src/test/java/io/github/dfa1/zstd/ZstdParameterTest.java index c66cdf6..e0088ad 100644 --- a/zstd/src/test/java/io/github/dfa1/zstd/ZstdParameterTest.java +++ b/zstd/src/test/java/io/github/dfa1/zstd/ZstdParameterTest.java @@ -32,7 +32,7 @@ void addsFourByteTrailerAndStillRoundTrips() { } // Then the checksum adds exactly its 4-byte trailer, and the frame still decodes - assertThat(checksummed.length).isEqualTo(plain.length + 4); + assertThat(checksummed).hasSize(plain.length + 4); assertThat(Zstd.decompress(checksummed)).isEqualTo(PAYLOAD); } @@ -330,7 +330,7 @@ void levelActuallyAppliesToTheNativeCompressionPath() { // Then the higher level produces a strictly smaller frame — proving level() // sets the native parameter rather than silently leaving the default - assertThat(atMax.length).isLessThan(atMin.length); + assertThat(atMax).hasSizeLessThan(atMin.length); } private static byte[] levelSensitivePayload() { diff --git a/zstd/src/test/java/io/github/dfa1/zstd/ZstdSegmentStreamTest.java b/zstd/src/test/java/io/github/dfa1/zstd/ZstdSegmentStreamTest.java index 32c4864..efa655d 100644 --- a/zstd/src/test/java/io/github/dfa1/zstd/ZstdSegmentStreamTest.java +++ b/zstd/src/test/java/io/github/dfa1/zstd/ZstdSegmentStreamTest.java @@ -121,19 +121,19 @@ class WithDictionary { @Test void roundTripsAgainstDictionary() { ZstdDictionary dict = trainDict(); - byte[] record = "{\"id\":1,\"user\":\"u\",\"event\":\"x\"}".getBytes(StandardCharsets.UTF_8); + byte[] sample = "{\"id\":1,\"user\":\"u\",\"event\":\"x\"}".getBytes(StandardCharsets.UTF_8); try (Arena arena = Arena.ofConfined(); ZstdCompressStream cs = new ZstdCompressStream(3, dict); ZstdDecompressStream ds = new ZstdDecompressStream(dict)) { - MemorySegment src = segmentOf(arena, record); - MemorySegment dst = arena.allocate(Zstd.compressBound(record.length)); + MemorySegment src = segmentOf(arena, sample); + MemorySegment dst = arena.allocate(Zstd.compressBound(sample.length)); ZstdStreamResult c = cs.compress(dst, src, ZstdEndDirective.END); - MemorySegment out = arena.allocate(record.length); + MemorySegment out = arena.allocate(sample.length); ds.decompress(out, dst.asSlice(0, c.bytesProduced())); - assertThat(bytesOf(out, record.length)).isEqualTo(record); + assertThat(bytesOf(out, sample.length)).isEqualTo(sample); } } diff --git a/zstd/src/test/java/io/github/dfa1/zstd/ZstdSegmentTest.java b/zstd/src/test/java/io/github/dfa1/zstd/ZstdSegmentTest.java index 8ba42c6..186d8e7 100644 --- a/zstd/src/test/java/io/github/dfa1/zstd/ZstdSegmentTest.java +++ b/zstd/src/test/java/io/github/dfa1/zstd/ZstdSegmentTest.java @@ -76,9 +76,9 @@ class WithDictionary { @Test void roundTripsWithDigestedDictionary() { - // Given a digested dictionary and a record in a native segment + // Given a digested dictionary and a sample in a native segment ZstdDictionary dict = trainDictionary(2000); - byte[] record = "{\"id\":42,\"user\":\"u\",\"active\":true}".getBytes(StandardCharsets.UTF_8); + byte[] sample = "{\"id\":42,\"user\":\"u\",\"active\":true}".getBytes(StandardCharsets.UTF_8); try (Arena arena = Arena.ofConfined(); ZstdCompressCtx cctx = new ZstdCompressCtx(); @@ -86,15 +86,15 @@ void roundTripsWithDigestedDictionary() { ZstdCompressDict cdict = new ZstdCompressDict(dict); ZstdDecompressDict ddict = new ZstdDecompressDict(dict)) { - MemorySegment src = segmentOf(arena, record); + MemorySegment src = segmentOf(arena, sample); // When round-tripped segment-to-segment against the dictionary MemorySegment frame = cctx.compress(arena, src, cdict); - MemorySegment out = arena.allocate(record.length); + MemorySegment out = arena.allocate(sample.length); long written = dctx.decompress(out, frame, ddict); - // Then the record is recovered - assertThat(bytesOf(out, written)).isEqualTo(record); + // Then the sample is recovered + assertThat(bytesOf(out, written)).isEqualTo(sample); } } @@ -102,7 +102,7 @@ void roundTripsWithDigestedDictionary() { void arenaAllocatingDecompressSizesOutputFromTheDigestedDictionaryFrame() { // Given a digested-dictionary frame that stores its decompressed size ZstdDictionary dict = trainDictionary(2000); - byte[] record = "{\"id\":99,\"user\":\"u\",\"active\":false}".getBytes(StandardCharsets.UTF_8); + byte[] sample = "{\"id\":99,\"user\":\"u\",\"active\":false}".getBytes(StandardCharsets.UTF_8); try (Arena arena = Arena.ofConfined(); ZstdCompressCtx cctx = new ZstdCompressCtx(); @@ -110,16 +110,16 @@ void arenaAllocatingDecompressSizesOutputFromTheDigestedDictionaryFrame() { ZstdCompressDict cdict = new ZstdCompressDict(dict); ZstdDecompressDict ddict = new ZstdDecompressDict(dict)) { - MemorySegment src = segmentOf(arena, record); + MemorySegment src = segmentOf(arena, sample); MemorySegment frame = cctx.compress(arena, src, cdict); // When decoded through the arena-allocating ddict overload MemorySegment out = dctx.decompress(arena, frame, ddict); - // Then it allocates the exact size and returns the record (a non-null segment) + // Then it allocates the exact size and returns the sample (a non-null segment) assertThat(out).isNotNull(); - assertThat(out.byteSize()).isEqualTo(record.length); - assertThat(bytesOf(out, out.byteSize())).isEqualTo(record); + assertThat(out.byteSize()).isEqualTo(sample.length); + assertThat(bytesOf(out, out.byteSize())).isEqualTo(sample); } } } diff --git a/zstd/src/test/java/io/github/dfa1/zstd/ZstdStreamTest.java b/zstd/src/test/java/io/github/dfa1/zstd/ZstdStreamTest.java index 99e21ca..7e74491 100644 --- a/zstd/src/test/java/io/github/dfa1/zstd/ZstdStreamTest.java +++ b/zstd/src/test/java/io/github/dfa1/zstd/ZstdStreamTest.java @@ -44,7 +44,7 @@ void compressesIncompressibleAndCompressibleAlike() throws IOException { byte[] frame = streamCompress(text, 9); - assertThat(frame.length).isLessThan(text.length); + assertThat(frame).hasSizeLessThan(text.length); assertThat(streamDecompress(frame)).isEqualTo(text); } @@ -93,51 +93,51 @@ class Dictionary { @Test void roundTripsWithDictionary() throws IOException { - // Given a dictionary and a small record + // Given a dictionary and a small sample ZstdDictionary dict = trainDict(); - byte[] record = record(42); + byte[] sample = sample(42); // When streamed through compress and decompress with the same dictionary ByteArrayOutputStream sink = new ByteArrayOutputStream(); try (ZstdOutputStream zout = new ZstdOutputStream(sink, dict)) { - zout.write(record); + zout.write(sample); } byte[] restored; try (ZstdInputStream zin = new ZstdInputStream(new ByteArrayInputStream(sink.toByteArray()), dict)) { restored = zin.readAllBytes(); } - // Then the record is recovered - assertThat(restored).isEqualTo(record); + // Then the sample is recovered + assertThat(restored).isEqualTo(sample); } @Test void dictionaryShrinksStreamedRecord() throws IOException { ZstdDictionary dict = trainDict(); - byte[] record = record(123); + byte[] sample = sample(123); ByteArrayOutputStream withDict = new ByteArrayOutputStream(); try (ZstdOutputStream zout = new ZstdOutputStream(withDict, dict)) { - zout.write(record); + zout.write(sample); } - // a dictionary frame of a tiny record is smaller than a plain stream frame - assertThat(withDict.size()).isLessThan(streamCompress(record, Zstd.defaultCompressionLevel()).length); + // a dictionary frame of a tiny sample is smaller than a plain stream frame + assertThat(withDict.size()).isLessThan(streamCompress(sample, Zstd.defaultCompressionLevel()).length); } @Test void streamWithDictionaryDecodesWithOneShot() throws IOException { // Given a dictionary frame produced by the streaming compressor ZstdDictionary dict = trainDict(); - byte[] record = record(7); + byte[] sample = sample(7); ByteArrayOutputStream sink = new ByteArrayOutputStream(); try (ZstdOutputStream zout = new ZstdOutputStream(sink, dict)) { - zout.write(record); + zout.write(sample); } // Then the one-shot context decodes it with the same dictionary try (ZstdDecompressCtx ctx = new ZstdDecompressCtx()) { - assertThat(ctx.decompress(sink.toByteArray(), record.length, dict)).isEqualTo(record); + assertThat(ctx.decompress(sink.toByteArray(), sample.length, dict)).isEqualTo(sample); } } @@ -145,7 +145,7 @@ private ZstdDictionary trainDict() { return trainDictionary(3000); } - private byte[] record(int i) { + private byte[] sample(int i) { return ("{\"id\":" + i + ",\"user\":\"user_" + (i % 40) + "\",\"event\":\"click\"}") .getBytes(StandardCharsets.UTF_8); } diff --git a/zstd/src/test/java/io/github/dfa1/zstd/ZstdTest.java b/zstd/src/test/java/io/github/dfa1/zstd/ZstdTest.java index 9b3be92..c806572 100644 --- a/zstd/src/test/java/io/github/dfa1/zstd/ZstdTest.java +++ b/zstd/src/test/java/io/github/dfa1/zstd/ZstdTest.java @@ -53,7 +53,7 @@ void shrinksCompressibleInput() { byte[] frame = Zstd.compress(original); // Then the frame is smaller than the input - assertThat(frame.length).isLessThan(original.length); + assertThat(frame).hasSizeLessThan(original.length); } } @@ -264,7 +264,7 @@ class UntrustedInput { void boundedDecompressRefusesADecompressionBomb() { // Given a tiny frame that expands enormously (8 MiB of zeros -> a few bytes) byte[] bomb = Zstd.compress(new byte[8 * 1024 * 1024]); - assertThat(bomb.length).isLessThan(1024); // huge amplification ratio + assertThat(bomb).hasSizeLessThan(1024); // huge amplification ratio // When decompressed with a small bound (the safe path for untrusted input) ThrowingCallable result = () -> Zstd.decompress(bomb, 64 * 1024);