diff --git a/packages/beacon-node/test/e2e/api/impl/beacon/state/endpoint.test.ts b/packages/beacon-node/test/e2e/api/impl/beacon/state/endpoint.test.ts index 8cfbbc2c7dea..81932a3d446d 100644 --- a/packages/beacon-node/test/e2e/api/impl/beacon/state/endpoint.test.ts +++ b/packages/beacon-node/test/e2e/api/impl/beacon/state/endpoint.test.ts @@ -49,27 +49,27 @@ describe("beacon state api", function () { ApiError.assert(res); const epochCommittees = res.response.data; - expect(epochCommittees.length).toBe(committeeCount); + expect(epochCommittees).toHaveLength(committeeCount); const slotCount: Record = {}; const indexCount: Record = {}; for (const committee of epochCommittees) { - expect(committee.index).toBeGreaterThanOrEqual(0); - expect(committee.index).toBeLessThanOrEqual(committeeCount - 1); - expect(committee.slot).toBeGreaterThanOrEqual(0); - expect(committee.slot).toBeLessThanOrEqual(SLOTS_PER_EPOCH - 1); - expect(committee.validators.length).toBe(validatorsPerCommittee); + expect(committee).toBeValidEpochCommittee({ + committeeCount, + validatorsPerCommittee, + slotsPerEpoch: SLOTS_PER_EPOCH, + }); slotCount[committee.slot] = (slotCount[committee.slot] || 0) + 1; indexCount[committee.index] = (indexCount[committee.index] || 0) + 1; } for (let i = 0; i < SLOTS_PER_EPOCH; i++) { - expect(slotCount[i]).toBe(committeesPerSlot); + expect(slotCount[i]).toBeWithMessage(committeesPerSlot, `Incorrect number of committees with slot ${i}`); } for (let i = 0; i < committeesPerSlot; i++) { - expect(indexCount[i]).toBe(SLOTS_PER_EPOCH); + expect(indexCount[i]).toBeWithMessage(SLOTS_PER_EPOCH, `Incorrect number of committees with index ${i}`); } }); @@ -78,9 +78,9 @@ describe("beacon state api", function () { const res = await client.getEpochCommittees("head", {index}); ApiError.assert(res); const epochCommittees = res.response.data; - expect(epochCommittees.length).toBe(SLOTS_PER_EPOCH); + expect(epochCommittees).toHaveLength(SLOTS_PER_EPOCH); for (const committee of epochCommittees) { - expect(committee.index).toBe(index); + expect(committee.index).toBeWithMessage(index, "Committee index does not match supplied index"); } }); @@ -89,9 +89,9 @@ describe("beacon state api", function () { const res = await client.getEpochCommittees("head", {slot}); ApiError.assert(res); const epochCommittees = res.response.data; - expect(epochCommittees.length).toBe(committeesPerSlot); + expect(epochCommittees).toHaveLength(committeesPerSlot); for (const committee of epochCommittees) { - expect(committee.slot).toBe(slot); + expect(committee.slot).toBeWithMessage(slot, "Committee slot does not match supplied slot"); } }); }); diff --git a/packages/beacon-node/test/e2e/doppelganger/doppelganger.test.ts b/packages/beacon-node/test/e2e/doppelganger/doppelganger.test.ts index 78c52a36cd88..a747e0132ec4 100644 --- a/packages/beacon-node/test/e2e/doppelganger/doppelganger.test.ts +++ b/packages/beacon-node/test/e2e/doppelganger/doppelganger.test.ts @@ -124,13 +124,25 @@ describe.skip("doppelganger / doppelganger test", function () { await connect(bn2.network, bn.network); - expect(validators[0].isRunning).toBe(true); - expect(validatorsWithDoppelganger[0].isRunning).toBe(true); + expect(validators[0].isRunning).toBeWithMessage( + true, + "validator without doppelganger protection should be running" + ); + expect(validatorsWithDoppelganger[0].isRunning).toBeWithMessage( + true, + "validator with doppelganger protection should be running before first epoch" + ); await waitForEvent(bn2.chain.clock, ClockEvent.epoch, timeout); // After first epoch doppelganger protection should have stopped the validatorsWithDoppelganger - expect(validators[0].isRunning).toBe(true); + expect(validators[0].isRunning).toBeWithMessage( + true, + "validator without doppelganger protection should still be running after first epoch" + ); const pubkeyOfIndex: PubkeyHex = validatorsWithDoppelganger[0].validatorStore.getPubkeyOfIndex(0) as PubkeyHex; - expect(validatorsWithDoppelganger[0].validatorStore.isDoppelgangerSafe(pubkeyOfIndex)).toBe(false); + expect(validatorsWithDoppelganger[0].validatorStore.isDoppelgangerSafe(pubkeyOfIndex)).toBeWithMessage( + false, + "validator with doppelganger protection should be stopped after first epoch" + ); }); it("should shut down validator if same key is active with same BN and started after genesis", async function () { @@ -156,13 +168,25 @@ describe.skip("doppelganger / doppelganger test", function () { }); afterEachCallbacks.push(() => Promise.all(validator0WithoutDoppelganger.map((v) => v.close()))); - expect(validator0WithDoppelganger[0].isRunning).toBe(true); - expect(validator0WithoutDoppelganger[0].isRunning).toBe(true); + expect(validator0WithDoppelganger[0].isRunning).toBeWithMessage( + true, + "validator with doppelganger protection should be running" + ); + expect(validator0WithoutDoppelganger[0].isRunning).toBeWithMessage( + true, + "validator without doppelganger protection should be running before first epoch" + ); await waitForEvent(bn.chain.clock, ClockEvent.epoch, timeout); //After first epoch doppelganger protection should have stopped the validator0WithDoppelganger - expect(validator0WithoutDoppelganger[0].isRunning).toBe(true); + expect(validator0WithoutDoppelganger[0].isRunning).toBeWithMessage( + true, + "validator without doppelganger protection should still be running after first epoch" + ); const pubkeyOfIndex: PubkeyHex = validator0WithDoppelganger[0].validatorStore.getPubkeyOfIndex(0) as PubkeyHex; - expect(validator0WithDoppelganger[0].validatorStore.isDoppelgangerSafe(pubkeyOfIndex)).toBe(false); + expect(validator0WithDoppelganger[0].validatorStore.isDoppelgangerSafe(pubkeyOfIndex)).toBeWithMessage( + false, + "validator with doppelganger protection should be stopped after first epoch" + ); }); it("should not shut down validator if key is different", async function () { @@ -179,11 +203,23 @@ describe.skip("doppelganger / doppelganger test", function () { await connect(bn2.network, bn.network); - expect(validators[0].isRunning).toBe(true); - expect(validatorsWithDoppelganger[0].isRunning).toBe(true); + expect(validators[0].isRunning).toBeWithMessage( + true, + "validator without doppelganger protection should be running" + ); + expect(validatorsWithDoppelganger[0].isRunning).toBeWithMessage( + true, + "validator with doppelganger protection should be running before first epoch" + ); await waitForEvent(bn2.chain.clock, ClockEvent.epoch, timeout); - expect(validators[0].isRunning).toBe(true); - expect(validatorsWithDoppelganger[0].isRunning).toBe(true); + expect(validators[0].isRunning).toBeWithMessage( + true, + "validator without doppelganger protection should still be running after first epoch" + ); + expect(validatorsWithDoppelganger[0].isRunning).toBeWithMessage( + true, + "validator with doppelganger protection should still be active after first epoch" + ); }); it("should not sign block if doppelganger period has not passed and not started at genesis", async function () { diff --git a/packages/beacon-node/test/e2e/eth1/jsonRpcHttpClient.test.ts b/packages/beacon-node/test/e2e/eth1/jsonRpcHttpClient.test.ts index 4508607ab57f..cf6d769ed9a3 100644 --- a/packages/beacon-node/test/e2e/eth1/jsonRpcHttpClient.test.ts +++ b/packages/beacon-node/test/e2e/eth1/jsonRpcHttpClient.test.ts @@ -199,7 +199,7 @@ describe("eth1 / jsonRpcHttpClient - with retries", function () { }, }) ).rejects.toThrow("getaddrinfo ENOTFOUND"); - expect(retryCount).toBe(retryAttempts); + expect(retryCount).toBeWithMessage(retryAttempts, "ENOTFOUND should be retried before failing"); }); it("should retry ECONNREFUSED", async function () { @@ -221,7 +221,7 @@ describe("eth1 / jsonRpcHttpClient - with retries", function () { }, }) ).rejects.toThrow(expect.objectContaining({code: "ECONNREFUSED"})); - expect(retryCount).toBe(retryAttempts); + expect(retryCount).toBeWithMessage(retryAttempts, "code ECONNREFUSED should be retried before failing"); }); it("should retry 404", async function () { @@ -251,7 +251,7 @@ describe("eth1 / jsonRpcHttpClient - with retries", function () { const controller = new AbortController(); const eth1JsonRpcClient = new JsonRpcHttpClient([url], {signal: controller.signal}); await expect(eth1JsonRpcClient.fetchWithRetries(payload, {retryAttempts})).rejects.toThrow("Not Found"); - expect(retryCount).toBe(retryAttempts); + expect(retryCount).toBeWithMessage(retryAttempts, "404 responses should be retried before failing"); }); it("should retry timeout", async function () { @@ -284,7 +284,7 @@ describe("eth1 / jsonRpcHttpClient - with retries", function () { await expect(eth1JsonRpcClient.fetchWithRetries(payload, {retryAttempts, timeout})).rejects.toThrow( "Timeout request" ); - expect(retryCount).toBe(retryAttempts); + expect(retryCount).toBeWithMessage(retryAttempts, "Timeout request should be retried before failing"); }); it("should retry aborted", async function () { @@ -314,7 +314,7 @@ describe("eth1 / jsonRpcHttpClient - with retries", function () { setTimeout(() => controller.abort(), 50); const eth1JsonRpcClient = new JsonRpcHttpClient([url], {signal: controller.signal}); await expect(eth1JsonRpcClient.fetchWithRetries(payload, {retryAttempts, timeout})).rejects.toThrow("Aborted"); - expect(retryCount).toBe(1); + expect(retryCount).toBeWithMessage(1, "Aborted request should be retried before failing"); }); it("should not retry payload error", async function () { @@ -344,6 +344,6 @@ describe("eth1 / jsonRpcHttpClient - with retries", function () { const controller = new AbortController(); const eth1JsonRpcClient = new JsonRpcHttpClient([url], {signal: controller.signal}); await expect(eth1JsonRpcClient.fetchWithRetries(payload, {retryAttempts})).rejects.toThrow("Method not found"); - expect(retryCount).toBe(1); + expect(retryCount).toBeWithMessage(1, "Payload error (non-network error) should not be retried"); }); }, {timeout: 10_000}); diff --git a/packages/beacon-node/vitest.config.ts b/packages/beacon-node/vitest.config.ts index 9bb4e5809a06..1df0de848936 100644 --- a/packages/beacon-node/vitest.config.ts +++ b/packages/beacon-node/vitest.config.ts @@ -1,27 +1,11 @@ -import {defineConfig} from "vitest/config"; +import {defineConfig, mergeConfig} from "vitest/config"; +import vitestConfig from "../../vitest.base.config"; -export default defineConfig({ - test: { - globalSetup: ["./test/globalSetup.ts"], - reporters: ["default", "hanging-process"], - coverage: { - clean: true, - all: false, - extension: [".ts"], - provider: "v8", - reporter: [["lcovonly", {file: "lcov.info"}], ["text"]], - reportsDirectory: "./coverage", - exclude: [ - "**/*.d.ts", - "**/*.js", - "**/lib/**", - "**/coverage/**", - "**/scripts/**", - "**/test/**", - "**/types/**", - "**/bin/**", - "**/node_modules/**", - ], +export default mergeConfig( + vitestConfig, + defineConfig({ + test: { + globalSetup: ["./test/globalSetup.ts"], }, - }, -}); + }) +);