Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: ✅ Fix race conditions in integration tests #299

Merged
merged 20 commits into from
Dec 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
98807c9
test: :white_check_mark: Fix race condition in `skipTo` waiting for p…
ffarall Dec 23, 2024
2f4e296
test: :technologist: Improve error log in `waitForTxInPool`
ffarall Dec 23, 2024
8475a71
fix: :bug: Remove `break` from `for` loop counting pending proof subm…
ffarall Dec 23, 2024
21d58d3
test: :white_check_mark: Fix race condition of many payment streams c…
ffarall Dec 23, 2024
954a5d4
fix: :white_check_mark: Use correct event variable in test for expect…
ffarall Dec 23, 2024
83855e6
fix: :white_check_mark: Change `sleep`s for waiting and polling funct…
ffarall Dec 23, 2024
46099bb
fix: :white_check_mark: Fix `waitForTxInPool`
ffarall Dec 24, 2024
1c12d8a
style: :art: Apply TS formatting
ffarall Dec 24, 2024
fe53bfb
fix: :white_check_mark: Increase timeout to 10s in `waitForBspStoredW…
ffarall Dec 24, 2024
cdf20ab
fix: :white_check_mark: Increase default timeout in `waitForTxInPool`
ffarall Dec 24, 2024
8b8803b
fix: :white_check_mark: Clarity logic for waiting for proofs in `skipTo`
ffarall Dec 24, 2024
774b252
fix: :adhesive_bandage: Remove `only: true` from test
ffarall Dec 24, 2024
6dfc81a
test: :white_check_mark: Simplify `bsp-thresholds` test to avoid race…
ffarall Dec 24, 2024
8b26006
revert: :rewind: Rollback runtime change to speed up CI
ffarall Dec 24, 2024
54b3823
fix: :white_check_mark: Change name of parameter `watchForBspProofs` …
ffarall Dec 24, 2024
ea414e3
fix: :white_check_mark: Fix submit-proofs tests race conditions
ffarall Dec 24, 2024
5960c95
revert: :rewind: Rollback `only: true` flag
ffarall Dec 24, 2024
be5a4a6
fix: :white_check_mark: Fix race condition of sending transaction wit…
ffarall Dec 26, 2024
6e4ce16
fix: :white_check_mark: Replace `sleep` for `mspApi.wait.fileStorageC…
ffarall Dec 26, 2024
7c27ccf
fix: :white_check_mark: Wait for new signed up BSP to catch up to cha…
ffarall Dec 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion test/scripts/generateBenchmarkProofs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ async function generateBenchmarkProofs() {
fileKeys.push(fileMetadata.fileKey);

await userApi.wait.bspVolunteer(1);
await bspApi.wait.bspFileStorageComplete(fileMetadata.fileKey);
await bspApi.wait.fileStorageComplete(fileMetadata.fileKey);
await userApi.wait.bspStored(1);
}

Expand Down
99 changes: 42 additions & 57 deletions test/suites/integration/bsp/bsp-thresholds.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ describeBspNet(
);

await userApi.sealBlock(
userApi.tx.sudo.sudo(userApi.tx.fileSystem.setGlobalParameters(null, 10))
userApi.tx.sudo.sudo(userApi.tx.fileSystem.setGlobalParameters(null, 500))
);

// Create a new BSP and onboard with no reputation
Expand All @@ -131,8 +131,8 @@ describeBspNet(
await userApi.wait.bspCatchUpToChainTip(bspDownApi);

const { fileKey } = await userApi.file.createBucketAndSendNewStorageRequest(
"res/smile.jpg",
"test/smile.jpg",
"res/whatsup.jpg",
"test/whatsup.jpg",
"bucket-1"
);

Expand All @@ -150,17 +150,27 @@ describeBspNet(
)
).asOk.toNumber();

if ((await userApi.rpc.chain.getHeader()).number.toNumber() < lowReputationVolunteerTick) {
await userApi.block.skipTo(lowReputationVolunteerTick);
}
const currentBlockNumber = (await userApi.rpc.chain.getHeader()).number.toNumber();
assert(
currentBlockNumber === normalReputationVolunteerTick,
"The BSP with high reputation should be able to volunteer immediately"
);
assert(
currentBlockNumber < lowReputationVolunteerTick,
"The volunteer tick for the low reputation BSP should be in the future"
);

if (normalReputationVolunteerTick < lowReputationVolunteerTick) {
await userApi.wait.bspVolunteer();
} else {
await userApi.wait.bspVolunteer(2);
}
// Checking volunteering and confirming for the high reputation BSP
await userApi.wait.bspVolunteer(1);
await bspApi.wait.fileStorageComplete(fileKey);
await userApi.wait.bspStored(1);

// Checking volunteering and confirming for the low reputation BSP
await userApi.block.skipTo(lowReputationVolunteerTick);
await userApi.wait.bspVolunteer(1);
const matchedEvents = await userApi.assert.eventMany("fileSystem", "AcceptedBspVolunteer"); // T1

// Check that it is in fact the BSP with low reputation that just volunteered
const filtered = matchedEvents.filter(
({ event }) =>
(userApi.events.fileSystem.AcceptedBspVolunteer.is(event) &&
Expand Down Expand Up @@ -224,49 +234,23 @@ describeBspNet(
)
).asOk.toNumber();

if (bsp1VolunteerTick < bsp2VolunteerTick) {
// If the first BSP can volunteer first, wait for it to volunteer and confirm storing the file
if ((await userApi.rpc.chain.getHeader()).number.toNumber() < bsp1VolunteerTick) {
await userApi.block.skipTo(bsp1VolunteerTick);
}
await userApi.wait.bspVolunteer(1);
await bspApi.wait.bspFileStorageComplete(fileKey);
await userApi.wait.bspStored(1);
assert(bsp1VolunteerTick < bsp2VolunteerTick, "BSP one should be able to volunteer first");
const currentBlockNumber = (await userApi.rpc.chain.getHeader()).number.toNumber();
assert(
currentBlockNumber === bsp1VolunteerTick,
"BSP one should be able to volunteer immediately"
);

// Then wait for the second BSP to volunteer and confirm storing the file
if ((await userApi.rpc.chain.getHeader()).number.toNumber() < bsp2VolunteerTick) {
await userApi.block.skipTo(bsp2VolunteerTick);
}
await userApi.wait.bspVolunteer(1);
await bspTwoApi.wait.bspFileStorageComplete(fileKey);
await userApi.wait.bspStored(1);
} else if (bsp1VolunteerTick > bsp2VolunteerTick) {
// If the second BSP can volunteer first, wait for it to volunteer and confirm storing the file
if ((await userApi.rpc.chain.getHeader()).number.toNumber() < bsp2VolunteerTick) {
await userApi.block.skipTo(bsp2VolunteerTick);
}
await userApi.wait.bspVolunteer(1);
await bspTwoApi.wait.bspFileStorageComplete(fileKey);
await userApi.wait.bspStored(1);
await userApi.wait.bspVolunteer(1);
await bspApi.wait.fileStorageComplete(fileKey);
await userApi.wait.bspStored(1);

// Then wait for the first BSP to volunteer and confirm storing the file
if ((await userApi.rpc.chain.getHeader()).number.toNumber() < bsp1VolunteerTick) {
await userApi.block.skipTo(bsp1VolunteerTick);
}
await userApi.wait.bspVolunteer(1);
await bspApi.wait.bspFileStorageComplete(fileKey);
await userApi.wait.bspStored(1);
} else {
// If both BSPs can volunteer at the same time, advance to the tick where both can volunteer
if ((await userApi.rpc.chain.getHeader()).number.toNumber() < bsp1VolunteerTick) {
await userApi.block.skipTo(bsp1VolunteerTick);
}
// And wait for them to volunteer and confirm storing the file
await userApi.wait.bspVolunteer(2);
await bspApi.wait.bspFileStorageComplete(fileKey);
await bspTwoApi.wait.bspFileStorageComplete(fileKey);
await userApi.wait.bspStored(2);
}
// Then wait for the second BSP to volunteer and confirm storing the file
await userApi.block.skipTo(bsp2VolunteerTick);

await userApi.wait.bspVolunteer(1);
await bspTwoApi.wait.fileStorageComplete(fileKey);
await userApi.wait.bspStored(1);

await bspTwoApi.disconnect();
await userApi.docker.stopBspContainer("sh-bsp-two");
Expand All @@ -282,6 +266,7 @@ describeBspNet(
bspStartingWeight: 800_000_000n
});
const bspThreeApi = await BspNetTestApi.create(`ws://127.0.0.1:${rpcPort}`);
await userApi.wait.bspCatchUpToChainTip(bspThreeApi);

// Wait for it to catch up to the top of the chain
await userApi.wait.bspCatchUpToChainTip(bspThreeApi);
Expand Down Expand Up @@ -319,11 +304,11 @@ describeBspNet(
);

// Advance to the tick where the new BSP can volunteer
if (
(await userApi.rpc.chain.getHeader()).number.toNumber() < highReputationBspVolunteerTick
) {
await userApi.block.skipTo(highReputationBspVolunteerTick);
}
const currentBlockNumber = (await userApi.rpc.chain.getHeader()).number.toNumber();
assert(
currentBlockNumber === highReputationBspVolunteerTick,
"BSP with high reputation should be able to volunteer immediately"
);

// Wait until the new BSP volunteers
await userApi.wait.bspVolunteer(1);
Expand Down
22 changes: 7 additions & 15 deletions test/suites/integration/bsp/debt-collection.test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
import assert, { strictEqual } from "node:assert";
import { after } from "node:test";
import {
bob,
describeBspNet,
fetchEvent,
ShConsts,
sleep,
type EnrichedBspApi
} from "../../../util";
import { bob, describeBspNet, fetchEvent, ShConsts, type EnrichedBspApi } from "../../../util";
import { BN } from "@polkadot/util";

describeBspNet(
Expand Down Expand Up @@ -262,9 +255,9 @@ describeBspNet(
3 // There are 3 running BSPs to fulfil the storage request
);
await userApi.wait.bspVolunteer(3);
await bspApi.wait.bspFileStorageComplete(cloudFileMetadata.fileKey);
await bspTwoApi.wait.bspFileStorageComplete(cloudFileMetadata.fileKey);
await bspThreeApi.wait.bspFileStorageComplete(cloudFileMetadata.fileKey);
await bspApi.wait.fileStorageComplete(cloudFileMetadata.fileKey);
await bspTwoApi.wait.fileStorageComplete(cloudFileMetadata.fileKey);
await bspThreeApi.wait.fileStorageComplete(cloudFileMetadata.fileKey);
await userApi.wait.bspStored(3);

const adolphusFileMetadata = await userApi.file.createBucketAndSendNewStorageRequest(
Expand All @@ -277,9 +270,9 @@ describeBspNet(
3 // There are 3 running BSPs to fulfil the storage request
);
await userApi.wait.bspVolunteer(3);
await bspApi.wait.bspFileStorageComplete(adolphusFileMetadata.fileKey);
await bspTwoApi.wait.bspFileStorageComplete(adolphusFileMetadata.fileKey);
await bspThreeApi.wait.bspFileStorageComplete(adolphusFileMetadata.fileKey);
await bspApi.wait.fileStorageComplete(adolphusFileMetadata.fileKey);
await bspTwoApi.wait.fileStorageComplete(adolphusFileMetadata.fileKey);
await bspThreeApi.wait.fileStorageComplete(adolphusFileMetadata.fileKey);
await userApi.wait.bspStored(3);

// Check the payment stream info after adding the new files
Expand Down Expand Up @@ -493,7 +486,6 @@ describeBspNet(

// Seal a block to allow BSPs to charge the payment stream
await userApi.sealBlock();
await sleep(500);

// Assert that event for the BSP charging its payment stream was emitted
await userApi.assert.eventPresent("paymentStreams", "PaymentStreamCharged");
Expand Down
4 changes: 2 additions & 2 deletions test/suites/integration/bsp/multiple-delete.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ describeBspNet("Single BSP Volunteering", ({ before, createBspApi, it, createUse
// Wait for the BSP to volunteer
await userApi.wait.bspVolunteer(source.length);
for (const fileKey of fileKeys) {
await bspApi.wait.bspFileStorageComplete(fileKey);
await bspApi.wait.fileStorageComplete(fileKey);
}

// Waiting for a confirmation of the first file to be stored
Expand Down Expand Up @@ -214,7 +214,7 @@ describeBspNet("Single BSP Volunteering", ({ before, createBspApi, it, createUse
// Wait for the BSP to volunteer
await userApi.wait.bspVolunteer(source.length);
for (const fileKey of fileKeys) {
await bspApi.wait.bspFileStorageComplete(fileKey);
await bspApi.wait.fileStorageComplete(fileKey);
}

// Waiting for a confirmation of the first file to be stored
Expand Down
2 changes: 1 addition & 1 deletion test/suites/integration/bsp/reorg-proof.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ describeBspNet(
await userApi.block.seal(); // To make sure we have a finalised head
const nextChallengeTick = await getNextChallengeHeight(userApi);
await userApi.block.skipTo(nextChallengeTick, {
waitForBspProofs: [ShConsts.DUMMY_BSP_ID, ShConsts.BSP_TWO_ID, ShConsts.BSP_THREE_ID],
watchForBspProofs: [ShConsts.DUMMY_BSP_ID, ShConsts.BSP_TWO_ID, ShConsts.BSP_THREE_ID],
finalised: true
});

Expand Down
2 changes: 1 addition & 1 deletion test/suites/integration/bsp/single-volunteer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ describeBspNet("Single BSP multi-volunteers", ({ before, createBspApi, createUse
// Wait for the BSP to receive and store all files
for (let i = 0; i < source.length; i++) {
const fileKey = fileKeys[i];
await bspApi.wait.bspFileStorageComplete(fileKey);
await bspApi.wait.fileStorageComplete(fileKey);
}

// The first file to be completed will immediately acquire the forest write lock
Expand Down
30 changes: 16 additions & 14 deletions test/suites/integration/bsp/storage-capacity.test.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
import assert from "node:assert";
import { bspKey, describeBspNet, type EnrichedBspApi, ferdie, sleep } from "../../../util";

describeBspNet("BSPNet: Validating max storage", ({ before, it, createUserApi, createBspApi }) => {
describeBspNet("BSPNet: Validating max storage", ({ before, it, createUserApi }) => {
let userApi: EnrichedBspApi;
let bspApi: EnrichedBspApi;

before(async () => {
userApi = await createUserApi();
bspApi = await createBspApi();
});

it("Unregistered accounts fail when changing capacities", async () => {
const totalCapacityBefore = await userApi.query.providers.totalBspsCapacity();
const bspCapacityBefore = await userApi.query.providers.backupStorageProviders(
bspApi.shConsts.DUMMY_BSP_ID
userApi.shConsts.DUMMY_BSP_ID
);
assert.ok(bspCapacityBefore.unwrap().capacity.eq(totalCapacityBefore));

const { events, extSuccess } = await userApi.sealBlock(
userApi.tx.providers.changeCapacity(bspApi.shConsts.CAPACITY[1024]),
userApi.tx.providers.changeCapacity(userApi.shConsts.CAPACITY[1024]),
ferdie
);
assert.strictEqual(extSuccess, false);
Expand All @@ -37,7 +35,7 @@ describeBspNet("BSPNet: Validating max storage", ({ before, it, createUserApi, c

const totalCapacityAfter = await userApi.query.providers.totalBspsCapacity();
const bspCapacityAfter = await userApi.query.providers.backupStorageProviders(
bspApi.shConsts.DUMMY_BSP_ID
userApi.shConsts.DUMMY_BSP_ID
);
assert.ok(bspCapacityAfter.unwrap().capacity.eq(totalCapacityBefore));
assert.ok(totalCapacityAfter.eq(totalCapacityBefore));
Expand All @@ -50,7 +48,7 @@ describeBspNet("BSPNet: Validating max storage", ({ before, it, createUserApi, c
);

const capacityUsed = (
await userApi.query.providers.backupStorageProviders(bspApi.shConsts.DUMMY_BSP_ID)
await userApi.query.providers.backupStorageProviders(userApi.shConsts.DUMMY_BSP_ID)
)
.unwrap()
.capacityUsed.toNumber();
Expand All @@ -59,6 +57,7 @@ describeBspNet("BSPNet: Validating max storage", ({ before, it, createUserApi, c
const newCapacity = Math.max(minCapacity, capacityUsed + 1);

// Set BSP's available capacity to 0 to force the BSP to increase its capacity before volunteering for the storage request.
await userApi.wait.waitForAvailabilityToSendTx(bspKey.address.toString());
const { extSuccess } = await userApi.sealBlock(
userApi.tx.providers.changeCapacity(newCapacity),
bspKey
Expand Down Expand Up @@ -101,9 +100,9 @@ describeBspNet("BSPNet: Validating max storage", ({ before, it, createUserApi, c

await userApi.sealBlock();

const updatedCapacity = BigInt(bspApi.shConsts.JUMP_CAPACITY_BSP + newCapacity);
const updatedCapacity = BigInt(userApi.shConsts.JUMP_CAPACITY_BSP + newCapacity);
const bspCapacityAfter = await userApi.query.providers.backupStorageProviders(
bspApi.shConsts.DUMMY_BSP_ID
userApi.shConsts.DUMMY_BSP_ID
);
assert.strictEqual(bspCapacityAfter.unwrap().capacity.toBigInt(), updatedCapacity);

Expand All @@ -113,16 +112,17 @@ describeBspNet("BSPNet: Validating max storage", ({ before, it, createUserApi, c

it("Total capacity updated when single BSP capacity updated", async () => {
const newCapacity =
BigInt(Math.floor(Math.random() * 1000 * 1024 * 1024)) + bspApi.shConsts.CAPACITY_512;
BigInt(Math.floor(Math.random() * 1000 * 1024 * 1024)) + userApi.shConsts.CAPACITY_512;

// Skip block height past threshold
await userApi.block.skipToMinChangeTime();

await userApi.wait.waitForAvailabilityToSendTx(bspKey.address.toString());
await userApi.sealBlock(userApi.tx.providers.changeCapacity(newCapacity), bspKey);

const totalCapacityAfter = await userApi.query.providers.totalBspsCapacity();
const bspCapacityAfter = await userApi.query.providers.backupStorageProviders(
bspApi.shConsts.DUMMY_BSP_ID
userApi.shConsts.DUMMY_BSP_ID
);
assert.strictEqual(bspCapacityAfter.unwrap().capacity.toBigInt(), newCapacity);
assert.strictEqual(totalCapacityAfter.toBigInt(), newCapacity);
Expand All @@ -140,6 +140,7 @@ describeBspNet("BSPNet: Validating max storage", ({ before, it, createUserApi, c
// Skip block height past threshold
await userApi.block.skipToMinChangeTime();

await userApi.wait.waitForAvailabilityToSendTx(bspKey.address.toString());
const { events, extSuccess } = await userApi.sealBlock(
userApi.tx.providers.changeCapacity(2n),
bspKey
Expand All @@ -160,7 +161,7 @@ describeBspNet("BSPNet: Validating max storage", ({ before, it, createUserApi, c

it("Test BSP storage size increased twice in the same increasing period (check for race condition)", async () => {
const capacityUsed = (
await userApi.query.providers.backupStorageProviders(bspApi.shConsts.DUMMY_BSP_ID)
await userApi.query.providers.backupStorageProviders(userApi.shConsts.DUMMY_BSP_ID)
)
.unwrap()
.capacityUsed.toNumber();
Expand All @@ -169,6 +170,7 @@ describeBspNet("BSPNet: Validating max storage", ({ before, it, createUserApi, c
const newCapacity = Math.max(minCapacity, capacityUsed + 1);

// Set BSP's available capacity to 0 to force the BSP to increase its capacity before volunteering for the storage request.
await userApi.wait.waitForAvailabilityToSendTx(bspKey.address.toString());
const { extSuccess } = await userApi.sealBlock(
userApi.tx.providers.changeCapacity(newCapacity),
bspKey
Expand Down Expand Up @@ -196,7 +198,7 @@ describeBspNet("BSPNet: Validating max storage", ({ before, it, createUserApi, c
await sleep(500);

// Assert BSP has sent a call to increase its capacity.
await bspApi.assert.extrinsicPresent({
await userApi.assert.extrinsicPresent({
module: "providers",
method: "changeCapacity",
checkTxPool: true
Expand All @@ -209,7 +211,7 @@ describeBspNet("BSPNet: Validating max storage", ({ before, it, createUserApi, c

const updatedCapacity = BigInt(userApi.shConsts.JUMP_CAPACITY_BSP + newCapacity);
const bspCapacityAfter = await userApi.query.providers.backupStorageProviders(
bspApi.shConsts.DUMMY_BSP_ID
userApi.shConsts.DUMMY_BSP_ID
);
assert.strictEqual(bspCapacityAfter.unwrap().capacity.toBigInt(), updatedCapacity);
});
Expand Down
Loading
Loading