Skip to content

Commit 26699f7

Browse files
authored
Merge pull request #441 from input-output-hk/test/e2e-rewards
test(e2e): rewards test
2 parents e53ddf4 + b7285f7 commit 26699f7

File tree

22 files changed

+571
-175
lines changed

22 files changed

+571
-175
lines changed

.github/workflows/continuous-integration-e2e.yaml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,21 @@ jobs:
4242
OGMIOS_PORT: '1340'
4343
OGMIOS_URL: 'ws://cardano-node-ogmios:1340'
4444

45-
- name: 🔬 Test - e2e
45+
- name: Wait for some epochs
4646
run: |
47-
yarn workspace @cardano-sdk/e2e build
4847
yarn workspace @cardano-sdk/e2e wait-for-network
48+
yarn workspace @cardano-sdk/e2e wait-for-faucet
49+
env:
50+
FAUCET_PROVIDER: 'cardano-wallet'
51+
FAUCET_PROVIDER_PARAMS: '{"baseUrl":"http://localhost:8090/v2","mnemonic":"fire method repair aware foot tray accuse brother popular olive find account sick rocket next"}'
52+
DB_SYNC_CONNECTION_STRING: 'postgresql://postgres:doNoUseThisSecret!@localhost:5435/cexplorer'
53+
54+
- name: 🔬 Test - e2e
55+
run: |
4956
yarn workspace @cardano-sdk/e2e test:wallet
5057
env:
58+
FAUCET_PROVIDER: 'cardano-wallet'
59+
FAUCET_PROVIDER_PARAMS: '{"baseUrl":"http://localhost:8090/v2","mnemonic":"fire method repair aware foot tray accuse brother popular olive find account sick rocket next"}'
5160
KEY_MANAGEMENT_PROVIDER: 'inMemory'
5261
KEY_MANAGEMENT_PARAMS: '{"accountIndex": 0, "networkId": 0, "password":"some_password","mnemonic":"vacant violin soft weird deliver render brief always monitor general maid smart jelly core drastic erode echo there clump dizzy card filter option defense"}'
5362
ASSET_PROVIDER: 'http'

packages/cardano-services-client/src/HttpProvider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ export const createHttpProvider = <T extends object>({
102102
const response = (await axiosInstance.request(req)).data;
103103
return !isEmptyResponse(response) ? response : undefined;
104104
} catch (error) {
105-
logger.error(error);
106105
if (axios.isAxiosError(error)) {
107106
if (error.response) {
108107
const typedError = fromSerializableObject(error.response.data, {
@@ -116,6 +115,7 @@ export const createHttpProvider = <T extends object>({
116115
throw new ProviderError(ProviderFailure.ConnectionFailure, error, error.code);
117116
}
118117
}
118+
logger.error(error);
119119
throw new ProviderError(ProviderFailure.Unknown, error);
120120
}
121121
};

packages/cardano-services-client/src/TxSubmitProvider/txSubmitHttpProvider.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,17 @@ const paths: HttpProviderConfigPaths<TxSubmitProvider> = {
1414
const toTxSubmissionError = (error: any): Cardano.TxSubmissionError | null => {
1515
if (typeof error === 'object' && typeof error?.name === 'string' && typeof error?.message === 'string') {
1616
const rawError = error as Cardano.TxSubmissionError;
17+
1718
const txSubmissionErrorName = rawError.name as keyof typeof Cardano.TxSubmissionErrors;
1819
const ErrorClass = Cardano.TxSubmissionErrors[txSubmissionErrorName];
1920
if (ErrorClass) {
2021
Object.setPrototypeOf(error, ErrorClass.prototype);
2122
return error;
2223
}
24+
if (rawError.name === Cardano.UnknownTxSubmissionError.name) {
25+
Object.setPrototypeOf(error, Cardano.UnknownTxSubmissionError.prototype);
26+
return error;
27+
}
2328
return new Cardano.UnknownTxSubmissionError(error);
2429
}
2530
return null;
@@ -45,7 +50,11 @@ export const txSubmitHttpProvider = (config: CreateHttpProviderConfig<TxSubmitPr
4550
if (typeof error === 'object' && typeof error.innerError === 'object') {
4651
const txSubmissionError = toTxSubmissionError(error.innerError);
4752
if (txSubmissionError) {
48-
throw new ProviderError(ProviderFailure.BadRequest, txSubmissionError);
53+
const failure =
54+
txSubmissionError instanceof Cardano.UnknownTxSubmissionError
55+
? ProviderFailure.Unknown
56+
: ProviderFailure.BadRequest;
57+
throw new ProviderError(failure, txSubmissionError);
4958
}
5059
}
5160
}

packages/cardano-services-client/test/TxSubmitProvider/txSubmitHttpProvider.test.ts

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ describe('txSubmitHttpProvider', () => {
1717
await expect(provider.healthCheck()).resolves.toEqual({ ok: false });
1818
});
1919
});
20+
// eslint-disable-next-line sonarjs/cognitive-complexity
2021
describe('mocked', () => {
2122
let axiosMock: MockAdapter;
2223
beforeAll(() => {
@@ -53,37 +54,55 @@ describe('txSubmitHttpProvider', () => {
5354
});
5455

5556
describe('errors', () => {
56-
const testError = (bodyError: Error, providerErrorType: unknown) => async () => {
57-
try {
58-
axiosMock.onPost().replyOnce(() => {
59-
throw axiosError(bodyError);
60-
});
61-
const provider = txSubmitHttpProvider(config);
62-
await provider.submitTx({ signedTransaction: emptyUintArrayAsHexString });
63-
throw new Error('Expected to throw');
64-
} catch (error) {
65-
if (error instanceof ProviderError) {
66-
expect(error.reason).toBe(ProviderFailure.BadRequest);
67-
const innerError = error.innerError as Cardano.TxSubmissionError;
68-
expect(innerError).toBeInstanceOf(providerErrorType);
69-
} else {
70-
throw new TypeError('Expected ProviderError');
57+
const testError =
58+
(bodyError: Error, providerFailure: ProviderFailure, providerErrorType: unknown) => async () => {
59+
try {
60+
axiosMock.onPost().replyOnce(() => {
61+
throw axiosError(bodyError);
62+
});
63+
const provider = txSubmitHttpProvider(config);
64+
await provider.submitTx({ signedTransaction: emptyUintArrayAsHexString });
65+
throw new Error('Expected to throw');
66+
} catch (error) {
67+
if (error instanceof ProviderError) {
68+
expect(error.reason).toBe(providerFailure);
69+
const innerError = error.innerError as Cardano.TxSubmissionError;
70+
expect(innerError).toBeInstanceOf(providerErrorType);
71+
} else {
72+
throw new TypeError('Expected ProviderError');
73+
}
7174
}
72-
}
73-
};
75+
};
7476

7577
it(
7678
'rehydrates errors',
7779
testError(
7880
new Cardano.TxSubmissionErrors.BadInputsError({ badInputs: [] }),
81+
ProviderFailure.BadRequest,
7982
Cardano.TxSubmissionErrors.BadInputsError
8083
)
8184
);
8285

8386
it(
8487
'maps unrecognized errors to UnknownTxSubmissionError',
85-
testError(new Error('Unknown error'), Cardano.UnknownTxSubmissionError)
88+
testError(new Error('Unknown error'), ProviderFailure.Unknown, Cardano.UnknownTxSubmissionError)
8689
);
90+
91+
it('does not re-wrap UnknownTxSubmissionError', async () => {
92+
expect.assertions(3);
93+
axiosMock.onPost().replyOnce(() => {
94+
throw axiosError(new Cardano.UnknownTxSubmissionError('Unknown error'));
95+
});
96+
const provider = txSubmitHttpProvider(config);
97+
try {
98+
await provider.submitTx({ signedTransaction: emptyUintArrayAsHexString });
99+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
100+
} catch (error: any) {
101+
expect(error).toBeInstanceOf(ProviderError);
102+
expect(error.innerError).toBeInstanceOf(Cardano.UnknownTxSubmissionError);
103+
expect(error.innerError.innerError.name).not.toBe(Cardano.UnknownTxSubmissionError.name);
104+
}
105+
});
87106
});
88107
});
89108
});

packages/e2e/jest.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,5 @@ module.exports = {
4747
}
4848
}
4949
],
50-
testTimeout: 120_000_000
50+
testTimeout: 1000 * 60 * 25
5151
};
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
here="$(cd "$(dirname "$0")" >/dev/null 2>&1 && pwd)"
6+
root="$(cd "$here/.." && pwd)"
7+
8+
cd "$root"
9+
10+
export PATH=$PWD/bin:$PATH
11+
12+
WALLET_ID="7991322ed68894d0f1fb645a74576c3780ab312c"
13+
PORT=8090
14+
FAUCET_WALLET='{"name": "Faucet", "mnemonic_sentence": ["fire", "method", "repair", "aware", "foot", "tray", "accuse", "brother", "popular", "olive", "find", "account", "sick", "rocket", "next"], "passphrase": "passphrase", "address_pool_gap": 20 }'
15+
16+
# Add Faucet wallet
17+
curl -s http://localhost:"$PORT"/v2/wallets -H 'Content-Type: application/json' -H 'Accept: application/json' -d "$FAUCET_WALLET" > /dev/null
18+
19+
# Get wallet status
20+
status=$(curl -s http://localhost:"$PORT"/v2/wallets/"$WALLET_ID" -H 'Content-Type: application/json' -H 'Accept: application/json' | jq .state.status)
21+
epoch=$(curl -s http://localhost:"$PORT"/v2/wallets/"$WALLET_ID" -H 'Content-Type: application/json' -H 'Accept: application/json' | jq .tip.epoch_number)
22+
totalBalance=$(curl -s http://localhost:"$PORT"/v2/wallets/"$WALLET_ID" -H 'Content-Type: application/json' -H 'Accept: application/json' | jq .balance.total.quantity)
23+
24+
if [[ "$status" == "\"ready\"" && $epoch -gt 4 && $totalBalance -gt 100000000 ]]; then # Faucet will be marked unhealthy if 100 or less tADA remains in the faucet wallet (initial balance is 13.5 billion tADA)
25+
exit 0
26+
fi
27+
28+
exit 9
29+

packages/e2e/local-network/scripts/make-babbage.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ $SED -i "${ROOT}/genesis/shelley/genesis.json" \
164164
-e 's/"slotLength": 1/"slotLength": 0.2/' \
165165
-e 's/"activeSlotsCoeff": 5.0e-2/"activeSlotsCoeff": 0.1/' \
166166
-e 's/"securityParam": 2160/"securityParam": 10/' \
167-
-e 's/"epochLength": 432000/"epochLength": 200/' \
167+
-e 's/"epochLength": 432000/"epochLength": 1000/' \
168168
-e "s/\"maxLovelaceSupply\": 0/\"maxLovelaceSupply\": ${MAX_SUPPLY}/" \
169169
-e 's/"minFeeA": 1/"minFeeA": 44/' \
170170
-e 's/"minFeeB": 0/"minFeeB": 155381/' \

packages/e2e/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@
1313
"scripts": {
1414
"test": "shx echo 'test' command not implemented yet",
1515
"test:blockfrost": "jest -c jest.config.js --selectProjects blockfrost --runInBand --verbose",
16-
"test:wallet": "jest -c jest.config.js --selectProjects wallet --runInBand --verbose",
17-
"test:local-network": "jest -c jest.config.js --selectProjects local-network --runInBand --verbose",
16+
"test:wallet": "jest -c jest.config.js --forceExit --selectProjects wallet --runInBand --verbose",
1817
"test:load-testing": "jest -c jest.config.js --selectProjects load-testing --runInBand --verbose",
1918
"test:ogmios": "jest -c jest.config.js --selectProjects ogmios --runInBand --verbose",
2019
"test:web-extension:build": "webpack -c test/web-extension/webpack.config.js",
@@ -43,7 +42,8 @@
4342
"test:build:verify": "tsc --build ./test && tsc --build ./test/web-extension",
4443
"test:debug": "DEBUG=true yarn test",
4544
"generate-mnemonics": "ts-node src/util/mnemonic.ts",
46-
"wait-for-network": "ts-node src/util/is-local-network-ready.ts"
45+
"wait-for-network": "ts-node src/util/is-local-network-ready.ts",
46+
"wait-for-faucet": "ts-node src/util/is-faucet-ready.ts"
4747
},
4848
"repository": "https://github.com/input-output-hk/cardano-js-sdk",
4949
"contributors": [

packages/e2e/src/FaucetProvider/providers/cardanoWalletFaucetProvider.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,16 @@ export class CardanoWalletFaucetProvider implements FaucetProvider {
131131
if (axiosResponse) this.#faucetWalletId = axiosResponse.data.id;
132132
}
133133

134+
/**
135+
* Gets the remaining balance on the faucet.
136+
*/
137+
public async getBalance(): Promise<number> {
138+
if (this.#faucetWalletId === undefined) throw new Error('Faucet is not running.');
139+
140+
const axiosResponse = await this.#walletServer.walletsApi.getWallet(this.#faucetWalletId);
141+
return axiosResponse.data.balance.total.quantity;
142+
}
143+
134144
/**
135145
* Closes the provider.
136146
*/
@@ -149,7 +159,8 @@ export class CardanoWalletFaucetProvider implements FaucetProvider {
149159
return {
150160
ok:
151161
networkInfo.sync_progress.status === ApiNetworkInformationSyncProgressStatusEnum.Ready &&
152-
this.#faucetWalletId !== ''
162+
this.#faucetWalletId !== '' &&
163+
(await this.getBalance()) > 100_000_000 // Faucet must have more than 100 tADA to be considered healthy
153164
};
154165
}
155166

packages/e2e/src/FaucetProvider/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ export interface FaucetProvider extends Provider {
8080
*/
8181
close(): Promise<void>;
8282

83+
/**
84+
* Gets the remaining balance on the faucet.
85+
*/
86+
getBalance(): Promise<number>;
87+
8388
/**
8489
* Performs a health check on the provider.
8590
*

0 commit comments

Comments
 (0)