Skip to content

Commit f1ca790

Browse files
authored
fix: Close hasher in tests (#24587)
Signed-off-by: Artur Kugal <artur.kugal@swirldslabs.com>
1 parent 57ace03 commit f1ca790

File tree

4 files changed

+46
-38
lines changed

4 files changed

+46
-38
lines changed

platform-sdk/swirlds-virtualmap/src/test/java/com/swirlds/virtualmap/internal/hash/VirtualHasherHugeTest.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// SPDX-License-Identifier: Apache-2.0
22
package com.swirlds.virtualmap.internal.hash;
33

4-
import static com.swirlds.virtualmap.test.fixtures.VirtualMapTestUtils.VIRTUAL_MAP_CONFIG;
54
import static org.junit.jupiter.api.Assertions.assertNotNull;
65

76
import com.swirlds.virtualmap.datasource.VirtualHashChunk;
@@ -44,8 +43,7 @@ void hugeTree() {
4443
// Go ahead and hash. I'm just going to check that the root hash produces *something*. I'm not worried
4544
// in this test as to the validity of this root hash since correctness is validated heavily in other
4645
// tests. In this test, I just want to be sure that we complete, and that we don't run out of memory.
47-
final VirtualHasher hasher = new VirtualHasher(VIRTUAL_MAP_CONFIG);
48-
final Hash rootHash = hasher.hash(
46+
final Hash rootHash = defaultHasher.hash(
4947
CHUNK_HEIGHT,
5048
chunkPath -> new VirtualHashChunk(chunkPath, CHUNK_HEIGHT),
5149
LongStream.range(firstLeafPath, lastLeafPath + 1)

platform-sdk/swirlds-virtualmap/src/test/java/com/swirlds/virtualmap/internal/hash/VirtualHasherTest.java

Lines changed: 27 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// SPDX-License-Identifier: Apache-2.0
22
package com.swirlds.virtualmap.internal.hash;
33

4-
import static com.swirlds.virtualmap.test.fixtures.VirtualMapTestUtils.VIRTUAL_MAP_CONFIG;
54
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
65
import static org.junit.jupiter.api.Assertions.assertEquals;
76
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -55,11 +54,10 @@ class VirtualHasherTest extends VirtualHasherTestBase {
5554
@Tag(TestComponentTags.VMAP)
5655
@DisplayName("Null preloader produces NPE")
5756
void nullPreloaderProducesNPE() {
58-
final VirtualHasher hasher = new VirtualHasher(VIRTUAL_MAP_CONFIG);
5957
final List<VirtualLeafBytes> leaves = new ArrayList<>();
6058
assertThrows(
6159
NullPointerException.class,
62-
() -> hasher.hash(CHUNK_HEIGHT, null, leaves.iterator(), 1, 2, null),
60+
() -> defaultHasher.hash(CHUNK_HEIGHT, null, leaves.iterator(), 1, 2, null),
6361
"Call should have produced an NPE");
6462
}
6563

@@ -71,10 +69,9 @@ void nullPreloaderProducesNPE() {
7169
@DisplayName("Null stream produces NPE")
7270
void nullStreamProducesNPE() {
7371
final TestDataSource ds = new TestDataSource(1, 2, CHUNK_HEIGHT);
74-
final VirtualHasher hasher = new VirtualHasher(VIRTUAL_MAP_CONFIG);
7572
assertThrows(
7673
NullPointerException.class,
77-
() -> hasher.hash(CHUNK_HEIGHT, ds::loadHashChunk, null, 1, 2, null),
74+
() -> defaultHasher.hash(CHUNK_HEIGHT, ds::loadHashChunk, null, 1, 2, null),
7875
"Call should have produced an NPE");
7976
}
8077

@@ -87,10 +84,9 @@ void nullStreamProducesNPE() {
8784
@SuppressWarnings({"MismatchedQueryAndUpdateOfCollection", "RedundantOperationOnEmptyContainer"})
8885
void emptyStreamProducesNull() {
8986
final TestDataSource ds = new TestDataSource(1, 2, CHUNK_HEIGHT);
90-
final VirtualHasher hasher = new VirtualHasher(VIRTUAL_MAP_CONFIG);
9187
final List<VirtualLeafBytes> leaves = new ArrayList<>();
9288
assertNull(
93-
hasher.hash(CHUNK_HEIGHT, ds::loadHashChunk, leaves.iterator(), 1, 2, null),
89+
defaultHasher.hash(CHUNK_HEIGHT, ds::loadHashChunk, leaves.iterator(), 1, 2, null),
9490
"Call should have returned a null hash");
9591
}
9692

@@ -102,11 +98,10 @@ void emptyStreamProducesNull() {
10298
@DisplayName("Invalid leaf paths")
10399
void invalidLeafPaths() {
104100
final TestDataSource ds = new TestDataSource(Path.INVALID_PATH, Path.INVALID_PATH, CHUNK_HEIGHT);
105-
final VirtualHasher hasher = new VirtualHasher(VIRTUAL_MAP_CONFIG);
106101
final List<VirtualLeafBytes> emptyLeaves = new ArrayList<>();
107102
// Empty dirty leaves stream -> null hash
108103
assertNull(
109-
hasher.hash(
104+
defaultHasher.hash(
110105
CHUNK_HEIGHT,
111106
ds::loadHashChunk,
112107
emptyLeaves.iterator(),
@@ -115,23 +110,23 @@ void invalidLeafPaths() {
115110
null),
116111
"Call should have produced null");
117112
assertNull(
118-
hasher.hash(CHUNK_HEIGHT, ds::loadHashChunk, emptyLeaves.iterator(), Path.INVALID_PATH, 2, null),
113+
defaultHasher.hash(CHUNK_HEIGHT, ds::loadHashChunk, emptyLeaves.iterator(), Path.INVALID_PATH, 2, null),
119114
"Call should have produced null");
120115
assertNull(
121-
hasher.hash(CHUNK_HEIGHT, ds::loadHashChunk, emptyLeaves.iterator(), 1, Path.INVALID_PATH, null),
116+
defaultHasher.hash(CHUNK_HEIGHT, ds::loadHashChunk, emptyLeaves.iterator(), 1, Path.INVALID_PATH, null),
122117
"Call should have produced null");
123118
assertNull(
124-
hasher.hash(CHUNK_HEIGHT, ds::loadHashChunk, emptyLeaves.iterator(), 0, 2, null),
119+
defaultHasher.hash(CHUNK_HEIGHT, ds::loadHashChunk, emptyLeaves.iterator(), 0, 2, null),
125120
"Call should have produced null");
126121
assertNull(
127-
hasher.hash(CHUNK_HEIGHT, ds::loadHashChunk, emptyLeaves.iterator(), 1, 0, null),
122+
defaultHasher.hash(CHUNK_HEIGHT, ds::loadHashChunk, emptyLeaves.iterator(), 1, 0, null),
128123
"Call should have produced null");
129124
// Non-empty dirty leaves stream + empty leaf path range -> IllegalStateException
130125
final List<VirtualLeafBytes> nonEmptyLeaves = new ArrayList<>();
131126
nonEmptyLeaves.add(appleLeaf(VirtualTestBase.A_PATH));
132127
assertThrows(
133128
IllegalArgumentException.class,
134-
() -> hasher.hash(
129+
() -> defaultHasher.hash(
135130
CHUNK_HEIGHT,
136131
ds::loadHashChunk,
137132
nonEmptyLeaves.iterator(),
@@ -141,11 +136,11 @@ void invalidLeafPaths() {
141136
"Non-null leaves iterator + invalid paths should throw an exception");
142137
assertThrows(
143138
IllegalArgumentException.class,
144-
() -> hasher.hash(CHUNK_HEIGHT, ds::loadHashChunk, nonEmptyLeaves.iterator(), 0, 2, null),
139+
() -> defaultHasher.hash(CHUNK_HEIGHT, ds::loadHashChunk, nonEmptyLeaves.iterator(), 0, 2, null),
145140
"Non-null leaves iterator + invalid paths should throw an exception");
146141
assertThrows(
147142
IllegalArgumentException.class,
148-
() -> hasher.hash(CHUNK_HEIGHT, ds::loadHashChunk, nonEmptyLeaves.iterator(), 1, 0, null),
143+
() -> defaultHasher.hash(CHUNK_HEIGHT, ds::loadHashChunk, nonEmptyLeaves.iterator(), 1, 0, null),
149144
"Non-null leaves iterator + invalid paths should throw an exception");
150145
}
151146

@@ -168,11 +163,10 @@ void hashingPermutations(final long firstLeafPath, final long lastLeafPath, fina
168163
throws Exception {
169164
final TestDataSource ds = new TestDataSource(firstLeafPath, lastLeafPath, CHUNK_HEIGHT);
170165
final HashingListener listener = new HashingListener();
171-
final VirtualHasher hasher = new VirtualHasher(VIRTUAL_MAP_CONFIG);
172166
final Hash expected = hashTree(ds);
173167
final List<VirtualLeafBytes> leaves = invalidateNodes(ds, dirtyPaths.stream());
174-
final Hash rootHash =
175-
hasher.hash(CHUNK_HEIGHT, ds::loadHashChunk, leaves.iterator(), firstLeafPath, lastLeafPath, listener);
168+
final Hash rootHash = defaultHasher.hash(
169+
CHUNK_HEIGHT, ds::loadHashChunk, leaves.iterator(), firstLeafPath, lastLeafPath, listener);
176170
assertEquals(expected, rootHash, "Hash value does not match expected");
177171

178172
// Make sure the saver saw each dirty node exactly once.
@@ -196,8 +190,8 @@ void hashingPermutations(final long firstLeafPath, final long lastLeafPath, fina
196190
assertEquals(savedChunks.size(), seenChunks.size(), "Expected equals");
197191
assertCallsAreBalanced(listener);
198192

199-
final Hash hashItAgain =
200-
hasher.hash(CHUNK_HEIGHT, ds::loadHashChunk, leaves.iterator(), firstLeafPath, lastLeafPath, listener);
193+
final Hash hashItAgain = defaultHasher.hash(
194+
CHUNK_HEIGHT, ds::loadHashChunk, leaves.iterator(), firstLeafPath, lastLeafPath, listener);
201195
assertEquals(expected, hashItAgain, "Hash value does not match expected");
202196

203197
for (int i = 0; i < leaves.size(); i++) {
@@ -209,8 +203,8 @@ void hashingPermutations(final long firstLeafPath, final long lastLeafPath, fina
209203
}
210204
}
211205
leaves.sort(Comparator.comparing(VirtualLeafBytes::path));
212-
final Hash hashItOnceMore =
213-
hasher.hash(CHUNK_HEIGHT, ds::loadHashChunk, leaves.iterator(), firstLeafPath, lastLeafPath, listener);
206+
final Hash hashItOnceMore = defaultHasher.hash(
207+
CHUNK_HEIGHT, ds::loadHashChunk, leaves.iterator(), firstLeafPath, lastLeafPath, listener);
214208
assertEquals(expected, hashItOnceMore, "Hash value does not match expected");
215209
}
216210

@@ -342,7 +336,6 @@ void repeatedTest(final int chunkHeight) throws Exception {
342336
final long firstLeafPath = 52L;
343337
final long lastLeafPath = firstLeafPath * 2;
344338
final TestDataSource ds = new TestDataSource(firstLeafPath, lastLeafPath, chunkHeight);
345-
final VirtualHasher hasher = new VirtualHasher(VIRTUAL_MAP_CONFIG);
346339
final Hash expected = hashTree(ds);
347340
final List<Long> dirtyLeafPaths = List.of(
348341
53L, 56L, 59L, 63L, 66L, 72L, 76L, 77L, 80L, 81L, 82L, 83L, 85L, 87L, 88L, 94L, 96L, 100L, 104L);
@@ -351,8 +344,8 @@ void repeatedTest(final int chunkHeight) throws Exception {
351344
// this will *likely* find it.
352345
for (int i = 0; i < 500; i++) {
353346
final List<VirtualLeafBytes> leaves = invalidateNodes(ds, dirtyLeafPaths.stream());
354-
final Hash rootHash =
355-
hasher.hash(chunkHeight, ds::loadHashChunk, leaves.iterator(), firstLeafPath, lastLeafPath, null);
347+
final Hash rootHash = defaultHasher.hash(
348+
chunkHeight, ds::loadHashChunk, leaves.iterator(), firstLeafPath, lastLeafPath, null);
356349
assertEquals(expected, rootHash, "Expected equals");
357350
}
358351

@@ -365,7 +358,7 @@ public synchronized void onHashChunkHashed(final VirtualHashChunk chunk) {
365358
};
366359
for (int i = 0; i < 500; i++) {
367360
final List<VirtualLeafBytes> leaves = invalidateNodes(ds, dirtyLeafPaths.stream());
368-
final Hash rootHash = hasher.hash(
361+
final Hash rootHash = defaultHasher.hash(
369362
chunkHeight, ds::loadHashChunk, leaves.iterator(), firstLeafPath, lastLeafPath, listener);
370363
assertEquals(expected, rootHash, "Expected equals");
371364
}
@@ -377,7 +370,6 @@ void testAllDirtyLeaves(final int chunkHeight) throws Exception {
377370
final long firstLeafPath = 801;
378371
final long lastLeafPath = firstLeafPath * 2;
379372
final TestDataSource ds = new TestDataSource(firstLeafPath, lastLeafPath, chunkHeight);
380-
final VirtualHasher hasher = new VirtualHasher(VIRTUAL_MAP_CONFIG);
381373
final Hash expected = hashTree(ds);
382374
final List<Long> dirtyLeafPaths =
383375
LongStream.range(firstLeafPath, lastLeafPath + 1).boxed().toList();
@@ -389,13 +381,13 @@ public synchronized void onHashChunkHashed(final VirtualHashChunk chunk) {
389381
}
390382
};
391383
final List<VirtualLeafBytes> leaves = invalidateNodes(ds, dirtyLeafPaths.stream());
392-
final Hash rootHash =
393-
hasher.hash(chunkHeight, ds::loadHashChunk, leaves.iterator(), firstLeafPath, lastLeafPath, listener);
384+
final Hash rootHash = defaultHasher.hash(
385+
chunkHeight, ds::loadHashChunk, leaves.iterator(), firstLeafPath, lastLeafPath, listener);
394386
assertEquals(expected, rootHash, "Expected equals");
395387

396388
final List<VirtualLeafBytes> oneDirtyLeaf = List.of(ds.getLeaf((firstLeafPath + lastLeafPath) / 2));
397-
final Hash hashItAgain =
398-
hasher.hash(chunkHeight, ds::loadHashChunk, oneDirtyLeaf.iterator(), firstLeafPath, lastLeafPath, null);
389+
final Hash hashItAgain = defaultHasher.hash(
390+
chunkHeight, ds::loadHashChunk, oneDirtyLeaf.iterator(), firstLeafPath, lastLeafPath, null);
399391
assertEquals(expected, hashItAgain, "Expected equals");
400392
}
401393

@@ -438,6 +430,7 @@ void listenerCallCounts() throws Exception {
438430

439431
// Validate the calls were all balanced
440432
assertCallsAreBalanced(listener);
433+
hasher.shutdown();
441434
}
442435

443436
/**
@@ -451,7 +444,6 @@ void listenerCallCounts() throws Exception {
451444
@DisplayName("Verify the hasher does not ask for internal records it will recreate")
452445
void hasherDoesNotAskForInternalsItWillRecreate() {
453446
final HashingListener listener = new HashingListener();
454-
final VirtualHasher hasher = new VirtualHasher(VIRTUAL_MAP_CONFIG);
455447

456448
// We will simulate growing the tree from 53 leaves to 106 leaves (doubling the size) and providing
457449
// all new leaves. This will guarantee that some internal nodes live at the paths that leaves used
@@ -469,7 +461,8 @@ void hasherDoesNotAskForInternalsItWillRecreate() {
469461

470462
assertDoesNotThrow(
471463
() -> {
472-
hasher.hash(CHUNK_HEIGHT, hashChunkReader, dirtyLeaves, firstLeafPath, lastLeafPath, listener);
464+
defaultHasher.hash(
465+
CHUNK_HEIGHT, hashChunkReader, dirtyLeaves, firstLeafPath, lastLeafPath, listener);
473466
},
474467
"Hashing should not throw an exception");
475468
}

platform-sdk/swirlds-virtualmap/src/test/java/com/swirlds/virtualmap/internal/hash/VirtualHasherTestBase.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,28 @@
2424
import java.util.stream.Stream;
2525
import org.hiero.base.crypto.Cryptography;
2626
import org.hiero.base.crypto.Hash;
27+
import org.junit.jupiter.api.AfterEach;
28+
import org.junit.jupiter.api.BeforeEach;
2729
import org.junit.jupiter.params.provider.Arguments;
2830

29-
public class VirtualHasherTestBase extends VirtualTestBase {
31+
class VirtualHasherTestBase extends VirtualTestBase {
3032

3133
protected static final int CHUNK_HEIGHT = VIRTUAL_MAP_CONFIG.hashChunkHeight();
3234

35+
protected VirtualHasher defaultHasher;
36+
37+
@BeforeEach
38+
void setup() {
39+
defaultHasher = new VirtualHasher(VIRTUAL_MAP_CONFIG);
40+
}
41+
42+
@AfterEach
43+
void tearDown() {
44+
if (defaultHasher != null) {
45+
defaultHasher.shutdown();
46+
}
47+
}
48+
3349
/**
3450
* Helper method for computing a list of {@link Arguments} of length {@code num}, each of which contains
3551
* a random list of dirty leave paths between {@code firstLeafPath} and {@code lastLeafPath}.

platform-sdk/swirlds-virtualmap/src/test/java/com/swirlds/virtualmap/internal/reconnect/ReconnectHashListenerTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ void flushOrder(int size) {
128128
assertEquals(expected, path, "Path did not match expectation. path=" + path + ", expected=" + expected);
129129
expected++;
130130
}
131+
hasher.shutdown();
131132
}
132133

133134
private VirtualLeafBytes leaf(long path) {

0 commit comments

Comments
 (0)