From b0726c697b62ca396381296fce27a9c0270a2eb7 Mon Sep 17 00:00:00 2001 From: nadeemb53 Date: Fri, 4 Oct 2024 12:55:50 +0530 Subject: [PATCH 1/2] test: add edge case coverage for TracesFilesManager --- contracts/test/LineaRollup.ts | 2 +- .../blockcreation/TracesFilesManagerTest.kt | 96 ++++++++++++++----- 2 files changed, 74 insertions(+), 24 deletions(-) diff --git a/contracts/test/LineaRollup.ts b/contracts/test/LineaRollup.ts index 6464d4c30..5fcb43a93 100644 --- a/contracts/test/LineaRollup.ts +++ b/contracts/test/LineaRollup.ts @@ -2118,7 +2118,7 @@ describe("Linea Rollup contract", () => { }); describe("fallback operator Role", () => { - const expectedLastFinalizedState = calculateLastFinalizedState(0, HASH_ZERO, DEFAULT_LAST_FINALIZED_TIMESTAMP); + const expectedLastFinalizedState = calculateLastFinalizedState(0n, HASH_ZERO, DEFAULT_LAST_FINALIZED_TIMESTAMP); it("Should revert if trying to set fallback operator role before six months have passed", async () => { const initialBlock = await ethers.provider.getBlock("latest"); diff --git a/coordinator/app/src/test/kotlin/net/consensys/zkevm/coordinator/blockcreation/TracesFilesManagerTest.kt b/coordinator/app/src/test/kotlin/net/consensys/zkevm/coordinator/blockcreation/TracesFilesManagerTest.kt index c6163c147..f49c4c78c 100644 --- a/coordinator/app/src/test/kotlin/net/consensys/zkevm/coordinator/blockcreation/TracesFilesManagerTest.kt +++ b/coordinator/app/src/test/kotlin/net/consensys/zkevm/coordinator/blockcreation/TracesFilesManagerTest.kt @@ -4,6 +4,7 @@ import io.vertx.core.Vertx import net.consensys.linea.traces.TracesFiles import org.apache.tuweni.bytes.Bytes32 import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.RepeatedTest import org.junit.jupiter.api.Test @@ -93,14 +94,14 @@ class TracesFilesManagerTest { } @Test - fun `waitRawTracesGenerationOf - waits until traces file is found`() { - // write file with wrong extension - val inprogressFile = - tracesDir.resolve(Path.of("1-${block1Hash.toHexString()}.inprogress")).createFile() + fun `waitRawTracesGenerationOf waits until traces file is found`() { + val inprogressFile = tracesDir + .resolve(Path.of("1-${block1Hash.toHexString()}.inprogress")) + .createFile() assertThat(inprogressFile).exists() val future = tracesFilesManager.waitRawTracesGenerationOf(1uL, block1Hash) - vertx.setTimer((config.tracesGenerationTimeout.inWholeMilliseconds / 2)) { + vertx.setTimer(config.tracesGenerationTimeout.inWholeMilliseconds / 2) { Files.createFile(block1TracesFile) } @@ -108,22 +109,22 @@ class TracesFilesManagerTest { } @RepeatedTest(10) - fun `waitRawTracesGenerationOf - returns error after timeout`() { + fun `waitRawTracesGenerationOf returns error after timeout`() { val future = tracesFilesManager.waitRawTracesGenerationOf(2uL, block2Hash1) val exception = assertThrows { future.get() } assertThat(exception.cause).isInstanceOf(FileNotFoundException::class.java) - assertThat(exception.message).matches(".* File matching '2-$block2Hash1.* not found .*") + assertThat(exception.message) + .matches(".* File matching '2-$block2Hash1.* not found .*") } @Test - fun `cleanNonCanonicalSiblingsByHeight - returns error when file to keep is not found`() { + fun `cleanNonCanonicalSiblingsByHeight returns error when file to keep is not found`() { val future = tracesFilesManager.cleanNonCanonicalSiblingsByHeight(1uL, block1Hash) - assertThat(future.get()).isEmpty() } @Test - fun `cleanNonCanonicalSiblingsByHeight - removes found siblings`() { + fun `cleanNonCanonicalSiblingsByHeight removes found siblings`() { Files.createFile(block2TracesFile1) Files.createFile(block2TracesFile2) Files.createFile(block20TracesFile) @@ -138,17 +139,66 @@ class TracesFilesManagerTest { assertThat(block20TracesFile).exists() } - // @Test - // @Disabled("This feature is not necessary anymore. Just keeping the test in case we need to revert") - // fun `waitRawTracesGenerationOf - cleans non canonical siblings`() { - // Files.createFile(block2TracesFile1) - // Files.createFile(block2TracesFile2) - // assertThat(block2TracesFile1).exists() - // assertThat(block2TracesFile2).exists() - // - // tracesFilesManager.waitRawTracesGenerationOf(UInt64.valueOf(2), block2Hash1).get() - // - // assertThat(block2TracesFile1).exists() - // assertThat(block2TracesFile2).doesNotExist() - // } + @Test + fun `initialization fails when nonCanonicalTracesDir doesn't exist and creation is disabled`() { + val configWithoutDirCreation = config.copy( + createNonCanonicalTracesDirIfDoesNotExist = false + ) + Files.delete(nonCanonicalBlocksTracesDir) + + assertThrows { + TracesFilesManager(vertx, configWithoutDirCreation) + } + } + + @Test + fun `initialization creates nonCanonicalTracesDir when it doesn't exist and creation is enabled`() { + Files.delete(nonCanonicalBlocksTracesDir) + + TracesFilesManager(vertx, config) + + assertThat(nonCanonicalBlocksTracesDir).exists() + } + + @Test + fun `cleanNonCanonicalSiblingsByHeight moves files to nonCanonicalTracesDir`() { + Files.createFile(block2TracesFile1) + Files.createFile(block2TracesFile2) + + tracesFilesManager.cleanNonCanonicalSiblingsByHeight(2uL, block2Hash1).get() + + val movedFile = nonCanonicalBlocksTracesDir.resolve(block2TracesFile2.fileName) + assertThat(movedFile).exists() + assertThat(block2TracesFile2).doesNotExist() + } + + @Test + fun `cleanNonCanonicalSiblingsByHeight handles case sensitivity correctly`() { + val mixedCaseHash = block2Hash1.toHexString().uppercase() + val tracesFileName = TracesFiles.rawTracesFileNameSupplierV1( + 2uL, + Bytes32.fromHexString(mixedCaseHash), + tracesVersion, + tracesFileExtension + ) + val mixedCaseFile = tracesDir.resolve(Path.of(tracesFileName)) + Files.createFile(mixedCaseFile) + Files.createFile(block2TracesFile2) + + tracesFilesManager.cleanNonCanonicalSiblingsByHeight(2uL, block2Hash1).get() + + assertThat(mixedCaseFile).exists() + assertThat(block2TracesFile2).doesNotExist() + } + + @Test + fun `waitRawTracesGenerationOf handles extremely short polling interval`() { + val configWithShortPolling = config.copy(pollingInterval = 1.milliseconds) + val manager = TracesFilesManager(vertx, configWithShortPolling) + + val future = manager.waitRawTracesGenerationOf(1uL, block1Hash) + vertx.setTimer(50) { Files.createFile(block1TracesFile) } + + assertThat(future.get()).endsWith(block1TracesFile.toString()) + } } From 8335b19533e19edebce771b945b0464adad39a9d Mon Sep 17 00:00:00 2001 From: nadeemb53 Date: Fri, 4 Oct 2024 13:14:56 +0530 Subject: [PATCH 2/2] remove unused aftereach import --- .../zkevm/coordinator/blockcreation/TracesFilesManagerTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/coordinator/app/src/test/kotlin/net/consensys/zkevm/coordinator/blockcreation/TracesFilesManagerTest.kt b/coordinator/app/src/test/kotlin/net/consensys/zkevm/coordinator/blockcreation/TracesFilesManagerTest.kt index f49c4c78c..e3ea8aa11 100644 --- a/coordinator/app/src/test/kotlin/net/consensys/zkevm/coordinator/blockcreation/TracesFilesManagerTest.kt +++ b/coordinator/app/src/test/kotlin/net/consensys/zkevm/coordinator/blockcreation/TracesFilesManagerTest.kt @@ -4,7 +4,6 @@ import io.vertx.core.Vertx import net.consensys.linea.traces.TracesFiles import org.apache.tuweni.bytes.Bytes32 import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.RepeatedTest import org.junit.jupiter.api.Test