Skip to content

Commit

Permalink
chore(trustchain): simplify test folders
Browse files Browse the repository at this point in the history
  • Loading branch information
gre committed Jul 9, 2024
1 parent 0e09748 commit b31efb7
Show file tree
Hide file tree
Showing 48 changed files with 142 additions and 187 deletions.
12 changes: 10 additions & 2 deletions libs/trustchain/scripts/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
### Run end 2 end tests and generate missing unit tests
### Run end 2 end tests and generate missing integration tests

the e2e script will run all end 2 end tests and record the APDUs, network calls and crypto randomness in order to replay them deterministically in integration tests.

Just run the tests that miss snapshot mocks.

```
pnpm trustchain e2e
```

This script will both run all end 2 end tests, and when not created yet, will bootstrap unit tests related to them by recording all APDUs, network calls and crypto randomness in order to play them deterministically in unit tests.
Run all the end2end tests regardless if there are snapshot generated.

```
RUN_EVEN_IF_SNAPSHOT_EXISTS=1 pnpm trustchain e2e
```
22 changes: 5 additions & 17 deletions libs/trustchain/scripts/e2e.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
/* eslint-disable no-console */
import fsPromises from "fs/promises";
import { listen } from "@ledgerhq/logs";
import { recordTestTrustchainSdk } from "../src/test-helpers/recordTrustchainSdkTests";
import { recordTestTrustchainSdk } from "../tests/test-helpers/recordTrustchainSdkTests";
import path from "path";
import expect from "expect";

// we force inject expect to allow us to have expect() code in the test-scenarios
(global as any).expect = expect;

async function main() {
const scenarioFolder = path.join(__dirname, "../src/test-scenarios");
const unitFolder = path.join(__dirname, "../src/__tests__/sdk");
const scenarioFolder = path.join(__dirname, "../tests/scenarios");
const mockFolder = path.join(__dirname, "../mocks/scenarios");
const files = await fsPromises.readdir(scenarioFolder);

for (const file of files) {
if (file.endsWith(".ts") && !file.endsWith(".test.ts") && !file.startsWith("_")) {
if (file.endsWith(".ts") && !file.startsWith("_")) {
const slug = file.slice(0, -3);
const e2eFile = path.join(scenarioFolder, file);
const mod = await import(e2eFile);
const scenario = mod.scenario;
const snapshotFile = path.join(unitFolder, slug + ".json");
const unitTestFile = path.join(unitFolder, slug + ".ts");
const snapshotFile = path.join(mockFolder, slug + ".json");
const snapshotFileExists = await exists(snapshotFile);
if (snapshotFileExists && !process.env.RUN_EVEN_IF_SNAPSHOT_EXISTS) {
continue;
Expand All @@ -32,17 +31,6 @@ async function main() {
overridesAppPath: "app.elf",
...mod.recorderConfig,
});
// we also rebootrap missing test files
if (!(await exists(unitTestFile))) {
await fsPromises.writeFile(
unitTestFile,
`import json from "./${slug}.json";
import { replayTrustchainSdkTests } from "../../test-helpers/replayTrustchainSdkTests";
import { scenario } from "../../test-scenarios/${slug}";
replayTrustchainSdkTests(json, scenario);
`,
);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import path from "path";
import fs from "fs";
import { TransportReplayer } from "@ledgerhq/hw-transport-mocker/lib/openTransportReplayer";
import { RecordStore } from "@ledgerhq/hw-transport-mocker";
import { setEnv } from "@ledgerhq/live-env";
import { getEnv, setEnv } from "@ledgerhq/live-env";
import { ScenarioOptions } from "../../../tests/test-helpers/types";
import { getSdk } from "../..";

setEnv("MOCK", "true");

Expand All @@ -13,7 +15,7 @@ const nonMockableScenarios = [
"userRefusesAuth", // can't simulate device interaction at the moment
];

const scenarioFolder = path.join(__dirname, "./test-scenarios");
const scenarioFolder = path.join(__dirname, "../../../tests/scenarios");
fs.readdirSync(scenarioFolder).forEach(file => {
if (file.endsWith(".ts") && !file.startsWith("_")) {
const slug = file.slice(0, -3);
Expand All @@ -23,7 +25,13 @@ fs.readdirSync(scenarioFolder).forEach(file => {
const mod = require(e2eFile);
test(slug, async () => {
const scenario = mod.scenario;
await scenario(new TransportReplayer(new RecordStore()));
const transport = new TransportReplayer(new RecordStore());
const options: ScenarioOptions = {
sdkForName: name => getSdk(!!getEnv("MOCK"), { applicationId: 16, name }),
pauseRecorder: () => Promise.resolve(), // replayer don't need to pause
switchDeviceSeed: async () => transport, // nothing to actually do, we will continue replaying
};
await scenario(transport, options);
});
}
});
20 changes: 20 additions & 0 deletions libs/trustchain/src/__tests__/integration/sdk.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/* eslint-disable @typescript-eslint/no-var-requires */
import path from "path";
import fs from "fs";
import { replayTrustchainSdkTests } from "../../../tests/test-helpers/replayTrustchainSdkTests";

const mockFolder = path.join(__dirname, "../../../mocks/scenarios");
const scenarioFolder = path.join(__dirname, "../../../tests/scenarios");

fs.readdirSync(mockFolder).forEach(file => {
if (!file.endsWith(".json")) return;

const slug = file.slice(0, -5);
const json = require(path.join(mockFolder, file));
const mod = require(path.join(scenarioFolder, slug + ".ts"));

test(slug, async () => {
const scenario = mod.scenario;
await replayTrustchainSdkTests(json, scenario);
});
});
4 changes: 0 additions & 4 deletions libs/trustchain/src/__tests__/sdk/create2trustchainInARow.ts

This file was deleted.

This file was deleted.

4 changes: 0 additions & 4 deletions libs/trustchain/src/__tests__/sdk/member3implicitlyAdded.ts

This file was deleted.

4 changes: 0 additions & 4 deletions libs/trustchain/src/__tests__/sdk/membersManySelfAdd.ts

This file was deleted.

4 changes: 0 additions & 4 deletions libs/trustchain/src/__tests__/sdk/randomMemberTryToDestroy.ts

This file was deleted.

This file was deleted.

4 changes: 0 additions & 4 deletions libs/trustchain/src/__tests__/sdk/removedMemberEjected.ts

This file was deleted.

This file was deleted.

This file was deleted.

4 changes: 0 additions & 4 deletions libs/trustchain/src/__tests__/sdk/success.ts

This file was deleted.

4 changes: 0 additions & 4 deletions libs/trustchain/src/__tests__/sdk/tokenExpires.ts

This file was deleted.

4 changes: 0 additions & 4 deletions libs/trustchain/src/__tests__/sdk/userRefusesAuth.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import Transport from "@ledgerhq/hw-transport";
import { getSdk } from "..";
import { ScenarioOptions } from "../test-helpers/types";

export async function scenario(transport: Transport) {
export async function scenario(transport: Transport, { sdkForName }: ScenarioOptions) {
/**
* Edit this code to the test you want.
* This script will be used both as a end-to-end tests and unit tests.
* The end-to-end tests are used to generate mock for the same unit tests.
*/
const applicationId = 16;
const name1 = "cli-member1";
const sdk1 = getSdk(false, { applicationId, name: name1 });
const sdk1 = sdkForName(name1);
const memberCredentials = await sdk1.initMemberCredentials();
const { trustchain } = await sdk1.getOrCreateTrustchain(transport, memberCredentials);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import Transport from "@ledgerhq/hw-transport";
import { getSdk } from "..";
import { getEnv } from "@ledgerhq/live-env";
import { ScenarioOptions } from "../test-helpers/types";

export async function scenario(transport: Transport) {
const applicationId = 16;
const sdk = getSdk(!!getEnv("MOCK"), { applicationId, name: "Foo" });
export async function scenario(transport: Transport, { sdkForName }: ScenarioOptions) {
const sdk = sdkForName("Foo");
const creds = await sdk.initMemberCredentials();

const t1 = await sdk.getOrCreateTrustchain(transport, creds);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import Transport from "@ledgerhq/hw-transport";
import { getSdk } from "..";
import { getEnv } from "@ledgerhq/live-env";
import { ScenarioOptions } from "../test-helpers/types";

export async function scenario(transport: Transport) {
const applicationId = 16;
export async function scenario(transport: Transport, { sdkForName }: ScenarioOptions) {
const name1 = "Member 1";
const sdk1 = getSdk(!!getEnv("MOCK"), { applicationId, name: name1 });
const sdk1 = sdkForName(name1);
const member1creds = await sdk1.initMemberCredentials();

let interactionCounter = 0;
Expand Down Expand Up @@ -39,7 +37,7 @@ export async function scenario(transport: Transport) {

// verify that a second member can join the trustchain and get the same trustchain
const name2 = "Member 2";
const sdk2 = getSdk(!!getEnv("MOCK"), { applicationId, name: name2 });
const sdk2 = sdkForName(name2);
const member2creds = await sdk2.initMemberCredentials();
const { trustchain: t3, type: type3 } = await sdk2.getOrCreateTrustchain(
transport,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
import { getEnv } from "@ledgerhq/live-env";
import Transport from "@ledgerhq/hw-transport";
import { getSdk } from "..";
import { ScenarioOptions } from "../test-helpers/types";

/**
* a complete scenario with 3 members and various sdk successful interactions.
*/
export async function scenario(transport: Transport) {
const applicationId = 16;

export async function scenario(transport: Transport, { sdkForName }: ScenarioOptions) {
// members
const name1 = "Member 1";
const sdk1 = getSdk(!!getEnv("MOCK"), { applicationId, name: name1 });
const sdk1 = sdkForName(name1);
const member1creds = await sdk1.initMemberCredentials();

const name2 = "Member 2";
const sdk2 = getSdk(!!getEnv("MOCK"), { applicationId, name: name2 });
const sdk2 = sdkForName(name2);
const member2creds = await sdk2.initMemberCredentials();

const name3 = "Member 3";
const sdk3 = getSdk(!!getEnv("MOCK"), { applicationId, name: name3 });
const sdk3 = sdkForName(name3);
const member3creds = await sdk3.initMemberCredentials();

// auth with the device and init the first trustchain
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import { getEnv } from "@ledgerhq/live-env";
import Transport from "@ledgerhq/hw-transport";
import { getSdk } from "..";

export async function scenario(transport: Transport) {
const applicationId = 16;
import { ScenarioOptions } from "../test-helpers/types";

export async function scenario(transport: Transport, { sdkForName }: ScenarioOptions) {
let trustchainId;
const n = 10;
for (let i = 1; i < n; i++) {
const name = "Member " + i;
const sdk = getSdk(!!getEnv("MOCK"), { applicationId, name });
const sdk = sdkForName(name);
const creds = await sdk.initMemberCredentials();
const { trustchain } = await sdk.getOrCreateTrustchain(transport, creds);
if (!trustchainId) trustchainId = trustchain.rootId;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
import { getEnv } from "@ledgerhq/live-env";
import Transport from "@ledgerhq/hw-transport";
import { getSdk } from "..";
import { TrustchainEjected } from "../errors";

export async function scenario(transport: Transport) {
const applicationId = 16;
import { TrustchainEjected } from "../../src/errors";
import { ScenarioOptions } from "../test-helpers/types";

export async function scenario(transport: Transport, { sdkForName }: ScenarioOptions) {
// first member initializes itself
const name1 = "Member 1";
const sdk1 = getSdk(!!getEnv("MOCK"), { applicationId, name: name1 });
const sdk1 = sdkForName(name1);
const member1creds = await sdk1.initMemberCredentials();

// second member initializes itself
const name2 = "Member 2";
const sdk2 = getSdk(!!getEnv("MOCK"), { applicationId, name: name2 });
const sdk2 = sdkForName(name2);
const member2creds = await sdk2.initMemberCredentials();

// auth with the device and init the first trustchain
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import Transport from "@ledgerhq/hw-transport";
import { getSdk } from "..";
import { ScenarioOptions } from "../test-helpers/types";
import { getEnv } from "@ledgerhq/live-env";

export async function scenario(transport: Transport, { switchDeviceSeed }: ScenarioOptions) {
const applicationId = 16;
export async function scenario(
transport: Transport,
{ sdkForName, switchDeviceSeed }: ScenarioOptions,
) {
const name1 = "Member 1";
const sdk1 = getSdk(!!getEnv("MOCK"), { applicationId, name: name1 });
const sdk1 = sdkForName(name1);
const member1creds = await sdk1.initMemberCredentials();
const member1 = { name: name1, id: member1creds.pubkey, permissions: 0xffffffff };

const name2 = "Member 2";
const sdk2 = getSdk(!!getEnv("MOCK"), { applicationId, name: name2 });
const sdk2 = sdkForName(name2);
const member2creds = await sdk2.initMemberCredentials();
const member2 = { name: name2, id: member2creds.pubkey, permissions: 0xffffffff };

Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
import { getEnv } from "@ledgerhq/live-env";
import Transport from "@ledgerhq/hw-transport";
import { getSdk } from "..";
import { TrustchainEjected } from "../errors";

export async function scenario(transport: Transport) {
const applicationId = 16;
import { TrustchainEjected } from "../../src/errors";
import { ScenarioOptions } from "../test-helpers/types";

export async function scenario(transport: Transport, { sdkForName }: ScenarioOptions) {
// first member initializes itself
const name1 = "Member 1";
const sdk1 = getSdk(!!getEnv("MOCK"), { applicationId, name: name1 });
const sdk1 = sdkForName(name1);
const member1creds = await sdk1.initMemberCredentials();

// auth with the device and init the first trustchain
const { trustchain } = await sdk1.getOrCreateTrustchain(transport, member1creds);

// second member initializes itself
const name2 = "Member 2";
const sdk2 = getSdk(!!getEnv("MOCK"), { applicationId, name: name2 });
const sdk2 = sdkForName(name2);
const member2creds = await sdk2.initMemberCredentials();

// member 1 adds member 2 (= qr code flow)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
import Transport from "@ledgerhq/hw-transport";
import { getSdk } from "..";
import { getEnv } from "@ledgerhq/live-env";

export async function scenario(transport: Transport) {
const applicationId = 16;
import { ScenarioOptions } from "../test-helpers/types";

export async function scenario(transport: Transport, { sdkForName }: ScenarioOptions) {
const name1 = "Member 1";
const sdk1 = getSdk(!!getEnv("MOCK"), { applicationId, name: name1 });
const sdk1 = sdkForName(name1);
const member1creds = await sdk1.initMemberCredentials();

const name2 = "Member 2";
const sdk2 = getSdk(!!getEnv("MOCK"), { applicationId, name: name2 });
const sdk2 = sdkForName(name2);
const member2creds = await sdk2.initMemberCredentials();
const member2 = { name: name2, id: member2creds.pubkey, permissions: 0xffffffff };

Expand Down
Loading

0 comments on commit b31efb7

Please sign in to comment.