Skip to content

Commit d5f0b75

Browse files
lukasaricLuka Saricivpavici
authored
test: Test setup refactor & remove RPC sequencer (#1044)
* test: test setup refactor & remove rpc sequencer * fix: enable sequencer tests to run on goerli * chore: format markdowns * fix: remove unnecessary goerli describeIf comment * chore: remove setup verifier & simplify envs check logic * test: naming improvements * test: update test setup data log for testnet * test: change from goerli to sepolia * test: rename from rpc testnet to testnet * test: remove `TEST_PROVIDER_BASE_URL` --------- Co-authored-by: Luka Saric <luka.saric@scayle.com> Co-authored-by: Ivan Pavičić <ivan.pavicic@live.com>
1 parent d396275 commit d5f0b75

File tree

17 files changed

+230
-614
lines changed

17 files changed

+230
-614
lines changed

__tests__/account.test.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import {
2626
compiledOpenZeppelinAccount,
2727
compiledTestDapp,
2828
describeIfDevnet,
29-
describeIfDevnetSequencer,
3029
erc20ClassHash,
3130
getTestAccount,
3231
getTestProvider,
@@ -113,7 +112,7 @@ describe('deploy and test Wallet', () => {
113112
// this is tested indirectly true declareAndDeploy while declaring
114113
});
115114

116-
describeIfDevnetSequencer('Test on Devnet Sequencer', () => {
115+
describeIfDevnet('Test on Devnet', () => {
117116
test('deployAccount with rawArgs - test on devnet', async () => {
118117
const priKey = stark.randomAddress();
119118
const pubKey = ec.starkCurve.getStarkKey(priKey);
@@ -195,7 +194,6 @@ describe('deploy and test Wallet', () => {
195194

196195
describe('simulate transaction - single transaction S0.11.2', () => {
197196
test('simulate INVOKE Cairo 0', async () => {
198-
// INFO: Sequencer S0.11.2 support only one transaction per simulate request
199197
const res = await account.simulateTransaction([
200198
{
201199
type: TransactionType.INVOKE,
@@ -206,7 +204,6 @@ describe('deploy and test Wallet', () => {
206204
amount: uint256(10),
207205
},
208206
},
209-
// This transaction will be skipped on sequencer
210207
{
211208
type: TransactionType.INVOKE,
212209
contractAddress: erc20Address,
@@ -753,7 +750,7 @@ describe('deploy and test Wallet', () => {
753750
});
754751

755752
describe('unit', () => {
756-
describeIfDevnetSequencer('devnet sequencer', () => {
753+
describeIfDevnet('Devnet', () => {
757754
initializeMatcher(expect);
758755
const provider = getTestProvider();
759756
const account = getTestAccount(provider);

__tests__/cairo1.test.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1+
import type { Abi } from 'abi-wan-kanabi';
12
import {
2-
Abi,
3+
type BigNumberish,
4+
type Calldata,
5+
type CompiledSierra,
6+
type DeclareDeployUDCResponse,
7+
type RawArgsArray,
8+
type RawArgsObject,
39
Account,
4-
BigNumberish,
510
CallData,
6-
Calldata,
7-
CompiledSierra,
811
Contract,
912
ContractFactory,
10-
DeclareDeployUDCResponse,
11-
RawArgsArray,
12-
RawArgsObject,
1313
cairo,
1414
ec,
1515
hash,
@@ -26,7 +26,7 @@ import {
2626
compiledHelloSierra,
2727
compiledHelloSierraCasm,
2828
describeIfDevnet,
29-
describeIfSequencerGoerli,
29+
describeIfTestnet,
3030
getTestAccount,
3131
getTestProvider,
3232
} from './config/fixtures';
@@ -550,8 +550,8 @@ describeIfDevnet('Cairo 1 Devnet', () => {
550550
});
551551
});
552552

553-
describeIfSequencerGoerli('Cairo1 Testnet', () => {
554-
describe('Sequencer API - C1 Testnet C:0x00305e...', () => {
553+
describeIfTestnet('Testnet', () => {
554+
describe('TS validation for testnet', () => {
555555
const provider = getTestProvider();
556556
const account = getTestAccount(provider);
557557
const classHash: any = '0x022332bb9c1e22ae13ae7fd9f3101eced4644533c6bfe51a25cf8dea028e5045';

__tests__/config/constants.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,10 @@
11
/* Default test config based on run `starknet-devnet --seed 0` */
22
export const GS_DEFAULT_TEST_PROVIDER_URL = 'http://127.0.0.1:5050/';
3+
4+
export const LOCAL_DEVNET_NOT_RUNNING_MESSAGE = `
5+
Local devnet is not running. In order to properly run it you need to do the following: \n
6+
- Go to the: https://hub.docker.com/r/shardlabs/starknet-devnet-rs/tags
7+
- Find the latest tag and copy the "docker pull" command
8+
- Run Docker on your machine
9+
- Run the command: "docker pull shardlabs/starknet-devnet-rs:latest"
10+
`;

__tests__/config/fixtures.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export function getTestProvider(isProvider: boolean = true): ProviderInterface |
8080
? new Provider({ nodeUrl: process.env.TEST_RPC_URL })
8181
: new RpcProvider({ nodeUrl: process.env.TEST_RPC_URL });
8282

83-
if (process.env.IS_LOCALHOST_DEVNET === 'true') {
83+
if (process.env.IS_DEVNET === 'true') {
8484
// accelerate the tests when running locally
8585
const originalWaitForTransaction = provider.waitForTransaction.bind(provider);
8686
provider.waitForTransaction = (txHash: string, options: waitForTransactionOptions = {}) => {
@@ -104,18 +104,15 @@ export const getTestAccount = (provider: ProviderInterface) => {
104104
};
105105

106106
export const createBlockForDevnet = async (): Promise<void> => {
107-
if (!(process.env.IS_RPC_DEVNET === 'true')) return;
107+
if (!(process.env.IS_DEVNET === 'true')) return;
108108
await fetch(new URL('/create_block', process.env.TEST_RPC_URL), { method: 'POST' });
109109
};
110110

111111
const describeIf = (condition: boolean) => (condition ? describe : describe.skip);
112-
export const describeIfSequencer = describeIf(process.env.IS_SEQUENCER === 'true');
113112
export const describeIfRpc = describeIf(process.env.IS_RPC === 'true');
114-
export const describeIfNotDevnet = describeIf(process.env.IS_LOCALHOST_DEVNET === 'false');
115-
export const describeIfDevnet = describeIf(process.env.IS_LOCALHOST_DEVNET === 'true');
116-
export const describeIfDevnetRpc = describeIf(process.env.IS_RPC_DEVNET === 'true');
117-
export const describeIfDevnetSequencer = describeIf(process.env.IS_SEQUENCER_DEVNET === 'true');
118-
export const describeIfSequencerGoerli = describeIf(process.env.IS_SEQUENCER_GOERLI === 'true');
113+
export const describeIfNotDevnet = describeIf(process.env.IS_DEVNET === 'false');
114+
export const describeIfDevnet = describeIf(process.env.IS_DEVNET === 'true');
115+
export const describeIfTestnet = describeIf(process.env.IS_TESTNET === 'true');
119116

120117
export const erc20ClassHash = '0x54328a1075b8820eb43caf0caa233923148c983742402dcfc38541dd843d01a';
121118
export const wrongClassHash = '0x000000000000000000000000000000000000000000000000000000000000000';
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/* eslint-disable no-console */
2+
import { GS_DEFAULT_TEST_PROVIDER_URL } from '../constants';
3+
4+
class AccountResolver {
5+
get providedUrl() {
6+
return process.env.TEST_RPC_URL;
7+
}
8+
9+
get hasAllAccountEnvs() {
10+
return process.env.TEST_ACCOUNT_ADDRESS && process.env.TEST_ACCOUNT_PRIVATE_KEY;
11+
}
12+
13+
get hasPartialAccountEnvs() {
14+
return process.env.TEST_ACCOUNT_ADDRESS || process.env.TEST_ACCOUNT_PRIVATE_KEY;
15+
}
16+
17+
private async fetchAccount(url: string) {
18+
const response = await fetch(`${url}predeployed_accounts`);
19+
const [account] = await response.json();
20+
const { address, private_key, initial_balance } = account;
21+
process.env.TEST_ACCOUNT_ADDRESS = address;
22+
process.env.TEST_ACCOUNT_PRIVATE_KEY = private_key;
23+
process.env.INITIAL_BALANCE = initial_balance;
24+
}
25+
26+
private async isAccountSet(isDevnet: boolean): Promise<boolean> {
27+
if (this.hasAllAccountEnvs) {
28+
return true;
29+
}
30+
if (this.hasPartialAccountEnvs) {
31+
throw new Error(
32+
'If you are providing one of you need to provide both: TEST_ACCOUNT_ADDRESS & TEST_ACCOUNT_PRIVATE_KEY'
33+
);
34+
}
35+
if (isDevnet) {
36+
// get account from devnet
37+
try {
38+
await this.fetchAccount(GS_DEFAULT_TEST_PROVIDER_URL);
39+
return true;
40+
} catch (error) {
41+
console.error('Fetching account from devnet failed');
42+
}
43+
} else if (this.providedUrl) {
44+
// try to get it from remote devnet
45+
try {
46+
await this.fetchAccount(this.providedUrl);
47+
return true;
48+
} catch (error) {
49+
console.error(`Fetching account from provided url ${this.providedUrl} failed`);
50+
}
51+
}
52+
53+
throw new Error(
54+
'Setting Account using all known strategies failed, provide basic test parameters'
55+
);
56+
}
57+
58+
async execute(isDevnet: boolean): Promise<void> {
59+
const isAccountSet = await this.isAccountSet(isDevnet);
60+
if (isAccountSet) console.log('Detected Account');
61+
}
62+
}
63+
64+
export default new AccountResolver();

__tests__/config/helpers/localDevnetDetector.ts

Lines changed: 0 additions & 73 deletions
This file was deleted.
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/* eslint-disable no-console */
2+
import accountResolver from './accountResolver';
3+
import { GS_DEFAULT_TEST_PROVIDER_URL, LOCAL_DEVNET_NOT_RUNNING_MESSAGE } from '../constants';
4+
import { setIfNullish } from './env';
5+
import { BaseUrl } from '../../../src/constants';
6+
7+
class StrategyResolver {
8+
private isDevnet = false;
9+
10+
private isRpcNode = false;
11+
12+
get isRpcDevnet() {
13+
return this.isDevnet || !!process.env.TEST_RPC_URL;
14+
}
15+
16+
get isTestnet() {
17+
return process.env.TEST_RPC_URL?.includes(BaseUrl.SN_SEPOLIA);
18+
}
19+
20+
get hasAllAccountEnvs() {
21+
const { TEST_ACCOUNT_ADDRESS, TEST_ACCOUNT_PRIVATE_KEY } = process.env;
22+
return !!(TEST_ACCOUNT_PRIVATE_KEY && TEST_ACCOUNT_ADDRESS);
23+
}
24+
25+
private async isRsDevnet(): Promise<boolean> {
26+
const response = await fetch(GS_DEFAULT_TEST_PROVIDER_URL, {
27+
method: 'POST',
28+
headers: { Accept: 'application/json', 'Content-Type': 'application/json' },
29+
body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'starknet_syncing' }),
30+
});
31+
const { jsonrpc } = await response.json();
32+
return jsonrpc === '2.0';
33+
}
34+
35+
async detectDevnet(): Promise<void> {
36+
// if on base url RPC endpoint work it is devnet-rs else it devnet-py
37+
try {
38+
this.isDevnet = await this.isRsDevnet();
39+
if (this.isDevnet) console.log('Detected Devnet-RS');
40+
} catch (error) {
41+
console.log('\x1b[36m%s\x1b[0m', LOCAL_DEVNET_NOT_RUNNING_MESSAGE);
42+
throw new Error(
43+
'Local RS devnet is not Running. Please follow the devnet setup instructions.'
44+
);
45+
}
46+
47+
setIfNullish('IS_DEVNET', this.isRpcDevnet);
48+
}
49+
50+
resolveRpc(): void {
51+
const hasRpcUrl = !!process.env.TEST_RPC_URL;
52+
53+
this.isRpcNode = hasRpcUrl || this.isDevnet;
54+
55+
if (!hasRpcUrl && this.isDevnet) {
56+
process.env.TEST_RPC_URL = GS_DEFAULT_TEST_PROVIDER_URL;
57+
}
58+
59+
setIfNullish('IS_RPC', this.isRpcNode);
60+
setIfNullish('IS_TESTNET', this.isTestnet);
61+
62+
console.log('Detected RPC');
63+
}
64+
65+
private logConfigInfo(): void {
66+
console.table({
67+
TEST_ACCOUNT_ADDRESS: process.env.TEST_ACCOUNT_ADDRESS,
68+
TEST_ACCOUNT_PRIVATE_KEY: '****',
69+
INITIAL_BALANCE: process.env.INITIAL_BALANCE,
70+
TEST_RPC_URL: process.env.TEST_RPC_URL,
71+
TX_VERSION: process.env.TX_VERSION === 'v3' ? 'v3' : 'v2',
72+
});
73+
74+
console.table({
75+
IS_DEVNET: process.env.IS_DEVNET,
76+
IS_RPC: process.env.IS_RPC,
77+
IS_TESTNET: process.env.IS_TESTNET,
78+
});
79+
80+
console.log('Global Test Environment is Ready');
81+
}
82+
83+
private verifyAccountData(shouldThrow?: boolean): void {
84+
const { TEST_ACCOUNT_ADDRESS, TEST_ACCOUNT_PRIVATE_KEY } = process.env;
85+
if (!TEST_ACCOUNT_ADDRESS) {
86+
if (shouldThrow) throw new Error('TEST_ACCOUNT_ADDRESS env is not provided');
87+
console.log('\x1b[33m', 'TEST_ACCOUNT_ADDRESS env is not provided!');
88+
delete process.env.TEST_ACCOUNT_ADDRESS;
89+
}
90+
if (!TEST_ACCOUNT_PRIVATE_KEY) {
91+
if (shouldThrow) throw new Error('TEST_ACCOUNT_PRIVATE_KEY env is not provided');
92+
console.log('\x1b[33m', 'TEST_ACCOUNT_PRIVATE_KEY env is not provided!', '\x1b[0m');
93+
delete process.env.TEST_ACCOUNT_PRIVATE_KEY;
94+
}
95+
}
96+
97+
private useProvidedSetup(): void {
98+
setIfNullish('IS_DEVNET', false);
99+
setIfNullish('IS_RPC', !!process.env.TEST_RPC_URL);
100+
setIfNullish('IS_TESTNET', this.isTestnet);
101+
102+
this.logConfigInfo();
103+
104+
console.log('Using Provided Test Setup');
105+
}
106+
107+
async execute(): Promise<void> {
108+
// 1. Assume setup is provided and ready;
109+
console.log('Global Test Setup Started');
110+
this.verifyAccountData();
111+
112+
if (this.hasAllAccountEnvs) {
113+
this.useProvidedSetup();
114+
return;
115+
}
116+
117+
// 2. Try to detect devnet setup
118+
console.log('Basic test parameters are missing, Auto Setup Started');
119+
120+
await this.detectDevnet();
121+
this.resolveRpc();
122+
await accountResolver.execute(this.isDevnet);
123+
124+
this.verifyAccountData(true);
125+
if (!this.hasAllAccountEnvs) console.error('Test Setup Environment is NOT Ready');
126+
127+
this.logConfigInfo();
128+
}
129+
}
130+
131+
export default new StrategyResolver();

0 commit comments

Comments
 (0)