From e6d8c1483d33551833a64484b239fe30e2ecd1bc Mon Sep 17 00:00:00 2001 From: Oleksii Kosynskyi Date: Tue, 28 Nov 2023 10:01:53 -0500 Subject: [PATCH] Stress Tests 1 - QA Tests (#6595) * add data stress test * fix unit tests * fix * try to fix validator test * fix ipc tests * fix load test * fix * move to tests folder * moved * fix * add send tests * browser tests * move validator test to web3 package * fix * fix naming * add browser test * fix * move to TS. remove time logs * fix start.sh * fix validation test run script * fix name * move to TS * move to jest * add browser tests * fix * fixes * fix * fix tests count --------- Co-authored-by: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> --- README.md | 3 +- package.json | 14 +- packages/web3/.eslintignore | 4 +- packages/web3/cypress | 1 + packages/web3/cypress.config.js | 31 +++ packages/web3/package.json | 4 +- .../index.ts => e2e_manual/data.test.ts} | 50 ++--- packages/web3/test/e2e_manual/jest.config.js | 32 +++ .../web3/test/e2e_manual/requests.test.ts | 147 ++++++++++++++ packages/web3/test/e2e_manual/setup.js | 24 +++ .../web3/test/e2e_manual/validation.test.ts | 183 ++++++++++++++++++ packages/web3/test/stress/data.test.ts | 72 +++++++ packages/web3/test/stress/jest.config.js | 33 ++++ .../browser_test/connection.html | 0 .../nodejs_test/long_connection_ws.js | 0 packages/web3/test/stress/requests.test.ts | 147 ++++++++++++++ packages/web3/test/stress/setup.js | 24 +++ packages/web3/test/stress/start.sh | 17 -- packages/web3/test/stress/validation.test.ts | 183 ++++++++++++++++++ packages/web3/test/stress/validator.ts | 126 ------------ scripts/gen_accounts.js | 4 +- scripts/geth_binary.sh | 7 +- scripts/test-runner.sh | 22 ++- 23 files changed, 942 insertions(+), 186 deletions(-) create mode 120000 packages/web3/cypress create mode 100644 packages/web3/cypress.config.js rename packages/web3/test/{stress/index.ts => e2e_manual/data.test.ts} (62%) create mode 100644 packages/web3/test/e2e_manual/jest.config.js create mode 100644 packages/web3/test/e2e_manual/requests.test.ts create mode 100644 packages/web3/test/e2e_manual/setup.js create mode 100644 packages/web3/test/e2e_manual/validation.test.ts create mode 100644 packages/web3/test/stress/data.test.ts create mode 100644 packages/web3/test/stress/jest.config.js rename packages/web3/test/{manual => stress}/long_ws_tests/browser_test/connection.html (100%) rename packages/web3/test/{manual => stress}/long_ws_tests/nodejs_test/long_connection_ws.js (100%) create mode 100644 packages/web3/test/stress/requests.test.ts create mode 100644 packages/web3/test/stress/setup.js delete mode 100755 packages/web3/test/stress/start.sh create mode 100644 packages/web3/test/stress/validation.test.ts delete mode 100644 packages/web3/test/stress/validator.ts diff --git a/README.md b/README.md index 4baf220afb3..c1f5bcb2398 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ yarn add web3 ## Package.json Scripts | Script | Description | -| ---------------- | ------------------------------------------------------------------ | +| ---------------- |--------------------------------------------------------------------| | clean | Uses `rimraf` to remove `dist/` | | build | Uses `tsc` to build all packages | | lint | Uses `eslint` to lint all packages | @@ -86,6 +86,7 @@ yarn add web3 | test | Uses `jest` to run unit tests in each package | | test:integration | Uses `jest` to run tests under `/test/integration` in each package | | test:unit | Uses `jest` to run tests under `/test/unit` in each package | +| test:manual:long-connection-ws | Runs manual tests for keeping a long WebSocket connection | | test:manual | Runs manual tests under `test/manual` in the web3 package | [npm-url]: https://npmjs.org/package/web3 diff --git a/package.json b/package.json index d8122891087..2a767bf4d23 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,8 @@ "geth-binary:start": "WEB3_SYSTEM_TEST_BACKEND=geth && ./scripts/geth_binary.sh start", "geth-binary:start:background": "WEB3_SYSTEM_TEST_BACKEND=geth && ./scripts/geth_binary.sh start 1", "geth-binary:stop": "WEB3_SYSTEM_TEST_BACKEND=geth && ./scripts/geth_binary.sh stop", + "geth-manual:start:background": "WEB3_SYSTEM_TEST_BACKEND=geth && ./scripts/geth_binary.sh manualStart 1", + "geth-manual:stop": "WEB3_SYSTEM_TEST_BACKEND=geth && ./scripts/geth_binary.sh stop", "lint": "lerna run lint --stream --parallel", "lint:fix": "lerna run lint:fix --stream --parallel", "format": "lerna run format --stream --parallel && prettier --write ./scripts/**/*.ts", @@ -61,6 +63,7 @@ "test:coverage:integration": "lerna run test:coverage:integration --stream --parallel", "test:unit": "lerna run test:unit --stream --parallel && jest --config=./scripts/jest.config.js", "test:integration": "lerna run test:integration --stream", + "test:integration:stress": "lerna run test:integration:stress --stream", "test:e2e:ganache:http": "./scripts/test-runner.sh ganache http", "test:e2e:ganache:ws": "./scripts/test-runner.sh ganache ws", "test:e2e:geth:http": "./scripts/test-runner.sh geth http", @@ -74,6 +77,10 @@ "test:e2e:mainnet:ws": "./scripts/test-runner.sh mainnet ws", "test:e2e:sepolia:http": "./scripts/test-runner.sh sepolia http", "test:e2e:sepolia:ws": "./scripts/test-runner.sh sepolia ws", + "test:stress:geth:ws": "./scripts/test-runner.sh geth-manual ws node manual", + "test:stress:geth:ipc": "./scripts/test-runner.sh geth-manual ipc node manual", + "test:stress:geth:http": "./scripts/test-runner.sh geth-manual http node manual", + "test:e2e:stress:geth:ws:chrome": "./scripts/test-runner.sh geth-manual ws chrome manual", "generate:accounts": "node ./scripts/gen_accounts.js", "pre-blackbox": "yarn config set registry http://localhost:4873 && git init && git config --global user.email \"ci@github.com\" && git config --global user.name \"CI\"", "post-blackbox": "./scripts/verdaccio.sh stop", @@ -85,11 +92,8 @@ "test:blackbox:geth:ws": "yarn pre-blackbox && yarn geth:start:background && ./scripts/verdaccio.sh startBackgroundAndPublish && lerna run test:blackbox:geth:ws --stream && yarn post-blackbox:geth", "test:blackbox:infura:http": "yarn pre-blackbox && ./scripts/verdaccio.sh startBackgroundAndPublish && lerna run test:blackbox:infura:http --stream && yarn post-blackbox", "test:blackbox:infura:ws": "yarn pre-blackbox && ./scripts/verdaccio.sh startBackgroundAndPublish && lerna run test:blackbox:infura:ws --stream && yarn post-blackbox", - "test:manual:stress:data": "packages/web3/test/stress/start.sh", - "test:manual:stress:validation": "npx ts-node packages/web3/test/stress/validator.ts", - "test:manual:stress": "yarn test:manual:stress:data && yarn test:manual:stress:validation", - "test:manual:long-connection-ws":"node ./packages/web3/test/manual/long_ws_tests/nodejs_test/long_connection_ws.js", - "test:manual":"yarn test:manual:stress && yarn test:manual:long-connection-ws", + "test:manual:long-connection-ws": "node packages/web3/test/stress/long_ws_tests/nodejs_test/long_connection_ws.js", + "test:stress":"yarn test:stress:geth:ws && yarn test:stress:geth:http && yarn test:stress:geth:ipc && yarn test:e2e:stress:geth:ws:chrome", "husky:install": "husky install", "husky:uninstall": "husky uninstall", "postinstall": "yarn build", diff --git a/packages/web3/.eslintignore b/packages/web3/.eslintignore index 81748e9e93c..22d50895f3c 100644 --- a/packages/web3/.eslintignore +++ b/packages/web3/.eslintignore @@ -3,5 +3,7 @@ lib hardhat.config.js jest.config.js webpack.config.js +cypress +cypress.config.js .eslintrc.js -webpack.analyze.js \ No newline at end of file +webpack.analyze.js diff --git a/packages/web3/cypress b/packages/web3/cypress new file mode 120000 index 00000000000..4a671a7beac --- /dev/null +++ b/packages/web3/cypress @@ -0,0 +1 @@ +../../templates/cypress \ No newline at end of file diff --git a/packages/web3/cypress.config.js b/packages/web3/cypress.config.js new file mode 100644 index 00000000000..d9c99839969 --- /dev/null +++ b/packages/web3/cypress.config.js @@ -0,0 +1,31 @@ +/* +This file is part of web3.js. + +web3.js is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +web3.js is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with web3.js. If not, see . +*/ +const config = { + screenshotOnRunFailure: false, + video: false, + e2e: { + // We've imported your old cypress plugins here. + // You may want to clean this up later by importing these. + setupNodeEvents(on, config) { + return require('./cypress/plugins/index.js')(on, config); + }, + specPattern: 'test/e2e_manual/**/**/*.test.ts', + excludeSpecPattern: [], + }, +}; + +module.exports = config; diff --git a/packages/web3/package.json b/packages/web3/package.json index b9f54e5a950..675264fdbfd 100644 --- a/packages/web3/package.json +++ b/packages/web3/package.json @@ -53,12 +53,14 @@ "test:watch": "npm test -- --watch", "test:unit": "jest --config=./test/unit/jest.config.js", "test:integration": "jest --config=./test/integration/jest.config.js --forceExit", + "test:integration:stress": "jest --config=./test/stress/jest.config.js --forceExit", "test:blackbox:ganache:http": "./scripts/black_box_test.sh ganache http", "test:blackbox:ganache:ws": "./scripts/black_box_test.sh ganache ws", "test:blackbox:geth:http": "./scripts/black_box_test.sh geth http", "test:blackbox:geth:ws": "./scripts/black_box_test.sh geth ws", "test:blackbox:infura:http": "./scripts/black_box_test.sh infura http", - "test:blackbox:infura:ws": "./scripts/black_box_test.sh infura ws" + "test:blackbox:infura:ws": "./scripts/black_box_test.sh infura ws", + "test:e2e:chrome:stress": "npx cypress run --headless --browser chrome" }, "devDependencies": { "@truffle/hdwallet-provider": "^2.0.12", diff --git a/packages/web3/test/stress/index.ts b/packages/web3/test/e2e_manual/data.test.ts similarity index 62% rename from packages/web3/test/stress/index.ts rename to packages/web3/test/e2e_manual/data.test.ts index 67471e136fb..eb57a6ebab8 100644 --- a/packages/web3/test/stress/index.ts +++ b/packages/web3/test/e2e_manual/data.test.ts @@ -17,10 +17,11 @@ along with web3.js. If not, see . /* eslint-disable */ import { Web3 } from 'web3'; -import { IpcProvider } from 'web3-providers-ipc'; -import accounts from '../shared_fixtures/accounts.json'; -import { BasicAbi, BasicBytecode } from '../shared_fixtures/build/Basic'; import WebSocketProvider from 'web3-providers-ws'; +import accounts from '../../../../scripts/accounts.json'; +import { isWs, isIpc, getSystemTestProvider } from '../../../../scripts/system_tests_utils'; +import { BasicAbi, BasicBytecode } from '../../../../fixtures/build/Basic'; + const DATA_AMOUNT = 50 * 1024; // 50 kB const sendAndGetData = async (web3: Web3, i: number) => { @@ -37,32 +38,33 @@ const sendAndGetData = async (web3: Web3, i: number) => { const contract = await c.deploy(deployOptions).send(sendOptions); await contract.methods - // @ts-ignore .setValues(1, 'A'.repeat(DATA_AMOUNT), true) .send({ from: accounts[i].address }); await contract.methods.getStringValue().call(); }; -const test = async () => { - const providerString = String(process.env.WEB3_SYSTEM_TEST_PROVIDER); - console.log(`Start test with provider: ${providerString}`); - const provider = providerString.includes('ipc') - ? new IpcProvider(providerString) - : providerString; - const web3 = new Web3(provider); - - for (const a of accounts) { - const acc = web3.eth.accounts.privateKeyToAccount(a.privateKey); - web3.eth.accounts.wallet.add(acc); - } +describe('huge data', () => { + let web3: Web3; + beforeAll(() => { + web3 = new Web3(getSystemTestProvider()); + }); + afterAll(() => { + if (isWs || isIpc) { + (web3.provider as unknown as WebSocketProvider).disconnect(); + } + }); - const prs = []; - for (let i = 0; i < 15; i++) { - prs.push(sendAndGetData(web3, i)); - } - await Promise.all(prs); - (web3.provider as unknown as WebSocketProvider).disconnect(); -}; + it('send and get', async () => { + for (const a of accounts) { + const acc = web3.eth.accounts.privateKeyToAccount(a.privateKey); + web3.eth.accounts.wallet.add(acc); + } -test().catch(console.error); + const prs = []; + for (let i = 0; i < 15; i++) { + prs.push(sendAndGetData(web3, i)); + } + await Promise.all(prs); + }); +}); diff --git a/packages/web3/test/e2e_manual/jest.config.js b/packages/web3/test/e2e_manual/jest.config.js new file mode 100644 index 00000000000..7ce09e43a4b --- /dev/null +++ b/packages/web3/test/e2e_manual/jest.config.js @@ -0,0 +1,32 @@ +'use strict'; + +const base = require('../config/jest.config'); + +module.exports = { + ...base, + setupFilesAfterEnv: ['/test/e2e/setup.js'], + testMatch: [`/test/e2e_manual/**/*.(spec|test).(js|ts)`], + /** + * restoreMocks [boolean] + * + * Default: false + * + * Automatically restore mock state between every test. + * Equivalent to calling jest.restoreAllMocks() between each test. + * This will lead to any mocks having their fake implementations removed + * and restores their initial implementation. + */ + restoreMocks: true, + + /** + * resetModules [boolean] + * + * Default: false + * + * By default, each test file gets its own independent module registry. + * Enabling resetModules goes a step further and resets the module registry before running each individual test. + * This is useful to isolate modules for every test so that local module state doesn't conflict between tests. + * This can be done programmatically using jest.resetModules(). + */ + resetModules: true, +}; diff --git a/packages/web3/test/e2e_manual/requests.test.ts b/packages/web3/test/e2e_manual/requests.test.ts new file mode 100644 index 00000000000..b79e09fd573 --- /dev/null +++ b/packages/web3/test/e2e_manual/requests.test.ts @@ -0,0 +1,147 @@ +/* +This file is part of web3.js. + +web3.js is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +web3.js is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with web3.js. If not, see . +*/ + +/* eslint-disable */ +import WebSocketProvider from 'web3-providers-ws'; +import { Web3Account } from 'web3-eth-accounts'; +import { Web3, Contract, Numbers, EventLog } from 'web3'; +import { BasicBytecode, BasicAbi } from '../../../../fixtures/build/Basic'; +import { isWs, isIpc, getSystemTestProvider } from '../../../../scripts/system_tests_utils'; + +const contracts: { [key: string]: Contract } = {}; + +const deployContracts = async (web3: Web3, accounts: Web3Account[]) => { + const prs = []; + for (let i = 0; i < accounts.length; i++) { + const account = accounts[i]; + const sendOptions = { from: account.address }; + const deployOptions = { + data: BasicBytecode, + arguments: [123, ''] as [number, string], + gas: BigInt(9000000000000), + gasLimit: BigInt(9000000000000), + type: BigInt(0), + }; + const c = new web3.eth.Contract(BasicAbi); + prs.push( + c + .deploy(deployOptions) + .send(sendOptions) + .then((contract: typeof c) => { + contracts[account.address] = contract; + }), + ); + } + await Promise.all(prs); +}; + +const addAccount = async ( + web3: Web3, + mainAcc: string, + address: string, + privateKey: string, + nonce: Numbers, +) => { + web3.eth.accounts.wallet.add(privateKey); + return web3.eth.sendTransaction({ + from: mainAcc, + to: address, + nonce, + gas: 1500000, + value: '1000000000000000000', + }); +}; + +const prepareAccounts = async (web3: Web3, n = 1000) => { + const prs = []; + const list = await web3.eth.personal.getAccounts(); + const mainAcc = list[0]; + const accountList: Web3Account[] = []; + const nonce = await web3.eth.getTransactionCount(mainAcc); + for (let i = 0; i < n; i++) { + const acc = web3.eth.accounts.create(); + prs.push(addAccount(web3, mainAcc, acc.address, acc.privateKey, Number(nonce) + i)); + accountList.push(acc); + } + await Promise.all(prs); + return accountList; +}; + +const sendData = async (account: Web3Account) => { + const contract = contracts[account.address]; + return contract.methods + .firesStringEvent(`String event: ${account.address}`) + .send({ from: account.address }); +}; + +const getData = async (account: Web3Account) => { + const contract = contracts[account.address]; + await contract.methods.getStringValue().call(); +}; + +const receivedEvents: { [key: string]: EventLog } = {}; +const subscribeContract = (acc: Web3Account) => { + const contract = contracts[acc.address]; + const event = contract.events.StringEvent(); + + event.on('data', res => { + if (res.returnValues.str !== `String event: ${acc.address}`) { + throw new Error('Event is not correct'); + } + receivedEvents[acc.address] = res; + }); +}; +const contractSubscriptions = (accounts: Web3Account[]) => { + for (const acc of accounts) { + subscribeContract(acc); + } +}; + +describe('huge data', () => { + let web3: Web3; + let parallelCount = 100; + let accounts: Web3Account[] = []; + beforeAll(async () => { + parallelCount = isIpc ? 5 : parallelCount; + web3 = new Web3(getSystemTestProvider()); + accounts = await prepareAccounts(web3, parallelCount); + await deployContracts(web3, accounts); + }); + afterAll(() => { + if (isWs || isIpc) { + (web3.provider as unknown as WebSocketProvider).disconnect(); + } + }); + it('send requests', async () => { + const sendPrs = []; + for (let i = 0; i < parallelCount; i++) { + sendPrs.push(sendData(accounts[i])); + } + await Promise.all(sendPrs); + // if socket subscribe to events + if (isIpc || isWs) { + contractSubscriptions(accounts); + } + }); + it('get requests', async () => { + const getPrs = []; + for (let i = 0; i < parallelCount; i++) { + getPrs.push(getData(accounts[i])); + } + await Promise.all(getPrs); + }); +}); diff --git a/packages/web3/test/e2e_manual/setup.js b/packages/web3/test/e2e_manual/setup.js new file mode 100644 index 00000000000..e9757a61e1c --- /dev/null +++ b/packages/web3/test/e2e_manual/setup.js @@ -0,0 +1,24 @@ +/* +This file is part of web3.js. + +web3.js is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +web3.js is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with web3.js. If not, see . +*/ + +// Have to use `require` because of Jest issue https://jestjs.io/docs/ecmascript-modules +// eslint-disable-next-line @typescript-eslint/no-require-imports +require('../config/setup'); + +const jestTimeout = 300000; + +jest.setTimeout(jestTimeout); diff --git a/packages/web3/test/e2e_manual/validation.test.ts b/packages/web3/test/e2e_manual/validation.test.ts new file mode 100644 index 00000000000..7ef7e44ef4c --- /dev/null +++ b/packages/web3/test/e2e_manual/validation.test.ts @@ -0,0 +1,183 @@ +/* +This file is part of web3.js. + +web3.js is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +web3.js is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with web3.js. If not, see . +*/ + +import { Web3Validator, Json, JsonSchema, ValidationSchemaInput } from 'web3-validator'; + +const abi = [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { indexed: false, internalType: 'uint256', name: 'value', type: 'uint256' }, +]; + +const abiJsonSchema = { + type: 'array', + items: [ + { name: 'from', format: 'address' }, + { name: 'to', format: 'address' }, + { name: 'value', format: 'uint256' }, + ], +}; + +const abiData = [ + '0xCB00CDE33a7a0Fba30C63745534F1f7Ae607076b', + '0xCB00CDE33a7a0Fba30C63745534F1f7Ae607076b', + '0xCB00CDE33a7a0Fba30C63745534F1f7Ae607076b', +]; + +const simpleSchema = { + type: 'object', + required: ['blockHash', 'blockNumber', 'from', 'to', 'data'], + properties: { + blockHash: { + format: 'bytes32', + }, + blockNumber: { + format: 'uint', + }, + from: { + format: 'address', + }, + to: { + oneOf: [{ format: 'address' }, { type: 'null' }], + }, + data: { + format: 'bytes', + }, + }, +}; + +const simpleData = { + blockHash: '0x0dec0518fa672a70027b04c286582e543ab17319fbdd384fa7bc8f3d5a542c0b', + blockNumber: BigInt(2), + from: '0xCB00CDE33a7a0Fba30C63745534F1f7Ae607076b', + to: '0xCB00CDE33a7a0Fba30C63745534F1f7Ae607076b', + data: '0xafea', +} as unknown as ValidationSchemaInput; + +const createHugeSchema = ( + schema: JsonSchema, + data: Json, + n = 3, +): { schema: JsonSchema; data: Json } => { + if (n > 0) { + const { data: resultData, schema: resultSchema } = createHugeSchema( + { ...simpleSchema } as JsonSchema, + { ...simpleData } as Json, + n - 1, + ); + return { + data: { ...(data as unknown as object), simple: resultData }, + schema: { ...schema, properties: { ...schema.properties, simple: resultSchema } }, + }; + } + return { + schema, + data, + }; +}; + +const { schema: hugeSchema, data: hugeData } = createHugeSchema( + { ...simpleSchema } as JsonSchema, + { ...simpleData } as Json, + 500, +); + +const { schema: hugeSchema1000, data: hugeData1000 } = createHugeSchema( + { ...simpleSchema } as JsonSchema, + { ...simpleData } as Json, + 1000, +); +describe('validator', () => { + let validator: Web3Validator; + beforeAll(() => { + validator = new Web3Validator(); + }); + + it('huge schema', () => { + let t = 0; + expect(() => { + const t1 = Number(new Date()); + validator.validateJSONSchema(hugeSchema, hugeData as object); + t = Number(new Date()) - t1; + }).not.toThrow(); + expect(t).toBeLessThan(6000); + expect(t).toBeGreaterThan(0); + }); + + it('huge schema 1000', () => { + let t = 0; + expect(() => { + const t1 = Number(new Date()); + validator.validateJSONSchema(hugeSchema1000, hugeData1000 as object); + t = Number(new Date()) - t1; + }).not.toThrow(); + expect(t).toBeLessThan(6000); + expect(t).toBeGreaterThan(0); + }); + + it('simple schema multiple times', () => { + let t = 0; + expect(() => { + const t1 = Number(new Date()); + for (let i = 0; i < 500; i += 1) { + validator.validateJSONSchema(simpleSchema, simpleData as object); + } + t = Number(new Date()) - t1; + }).not.toThrow(); + expect(t).toBeLessThan(3000); + expect(t).toBeGreaterThan(0); + }); + + it('simple schema 1000 times', () => { + let t = 0; + expect(() => { + const t1 = Number(new Date()); + for (let i = 0; i < 1000; i += 1) { + validator.validateJSONSchema(simpleSchema, simpleData as object); + } + t = Number(new Date()) - t1; + }).not.toThrow(); + expect(t).toBeLessThan(4000); + expect(t).toBeGreaterThan(0); + }); + + it('simple JSON schema 1000 times', () => { + let t = 0; + expect(() => { + const t1 = Number(new Date()); + for (let i = 0; i < 1000; i += 1) { + validator.validateJSONSchema(abiJsonSchema, abiData as object); + } + t = Number(new Date()) - t1; + }).not.toThrow(); + expect(t).toBeLessThan(4000); + expect(t).toBeGreaterThan(0); + }); + + it('simple ABI 1000 times', () => { + let t = 0; + expect(() => { + const t1 = Number(new Date()); + for (let i = 0; i < 1000; i += 1) { + validator.validate(abi, abiData); + } + t = Number(new Date()) - t1; + }).not.toThrow(); + expect(t).toBeLessThan(4000); + expect(t).toBeGreaterThan(0); + }); +}); diff --git a/packages/web3/test/stress/data.test.ts b/packages/web3/test/stress/data.test.ts new file mode 100644 index 00000000000..e7bc4915369 --- /dev/null +++ b/packages/web3/test/stress/data.test.ts @@ -0,0 +1,72 @@ +/* +This file is part of web3.js. + +web3.js is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +web3.js is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with web3.js. If not, see . +*/ + +/* eslint-disable */ +import { Web3 } from 'web3'; +import WebSocketProvider from 'web3-providers-ws'; +import accounts from '../../../../scripts/accounts.json'; +import { BasicAbi, BasicBytecode } from '../../../../fixtures/build/Basic'; +import { getSystemTestProvider, isWs, isIpc } from '../shared_fixtures/system_tests_utils'; + +const DATA_AMOUNT = 50 * 1024; // 50 kB + +const sendAndGetData = async (web3: Web3, i: number) => { + const sendOptions = { from: accounts[i].address }; + const deployOptions = { + data: BasicBytecode, + arguments: [0, ''] as [number, string], + gasPrice: await web3.eth.getGasPrice(), + gas: BigInt(9000000000000), + gasLimit: BigInt(9000000000000), + type: BigInt(0), + }; + const c = new web3.eth.Contract(BasicAbi); + const contract = await c.deploy(deployOptions).send(sendOptions); + + await expect( + contract.methods + .setValues(1, 'A'.repeat(DATA_AMOUNT), true) + .send({ from: accounts[i].address }), + ).resolves.toBeDefined(); + + await expect(contract.methods.getStringValue().call()).resolves.toBe('A'.repeat(DATA_AMOUNT)); +}; + +describe('huge data', () => { + let web3: Web3; + beforeAll(() => { + web3 = new Web3(getSystemTestProvider()); + }); + afterAll(() => { + if (isWs || isIpc) { + (web3.provider as unknown as WebSocketProvider).disconnect(); + } + }); + + it('send and get large data', async () => { + for (const a of accounts) { + const acc = web3.eth.accounts.privateKeyToAccount(a.privateKey); + web3.eth.accounts.wallet.add(acc); + } + + const prs = []; + for (let i = 0; i < 15; i++) { + prs.push(sendAndGetData(web3, i)); + } + await expect(Promise.all(prs)).resolves.toBeDefined(); + }); +}); diff --git a/packages/web3/test/stress/jest.config.js b/packages/web3/test/stress/jest.config.js new file mode 100644 index 00000000000..de1e19d4ace --- /dev/null +++ b/packages/web3/test/stress/jest.config.js @@ -0,0 +1,33 @@ +'use strict'; + +const base = require('../config/jest.config'); + +module.exports = { + ...base, + setupFilesAfterEnv: ['/test/stress/setup.js'], + testMatch: ['/test/stress/**/*.(spec|test).(js|ts)'], + /** + * restoreMocks [boolean] + * + * Default: false + * + * Automatically restore mock state between every test. + * Equivalent to calling jest.restoreAllMocks() between each test. + * This will lead to any mocks having their fake implementations removed + * and restores their initial implementation. + */ + restoreMocks: true, + + /** + * resetModules [boolean] + * + * Default: false + * + * By default, each test file gets its own independent module registry. + * Enabling resetModules goes a step further and resets the module registry before running each individual test. + * This is useful to isolate modules for every test so that local module state doesn't conflict between tests. + * This can be done programmatically using jest.resetModules(). + */ + resetModules: true, + coverageDirectory: '.coverage/integration', +}; diff --git a/packages/web3/test/manual/long_ws_tests/browser_test/connection.html b/packages/web3/test/stress/long_ws_tests/browser_test/connection.html similarity index 100% rename from packages/web3/test/manual/long_ws_tests/browser_test/connection.html rename to packages/web3/test/stress/long_ws_tests/browser_test/connection.html diff --git a/packages/web3/test/manual/long_ws_tests/nodejs_test/long_connection_ws.js b/packages/web3/test/stress/long_ws_tests/nodejs_test/long_connection_ws.js similarity index 100% rename from packages/web3/test/manual/long_ws_tests/nodejs_test/long_connection_ws.js rename to packages/web3/test/stress/long_ws_tests/nodejs_test/long_connection_ws.js diff --git a/packages/web3/test/stress/requests.test.ts b/packages/web3/test/stress/requests.test.ts new file mode 100644 index 00000000000..6b082265674 --- /dev/null +++ b/packages/web3/test/stress/requests.test.ts @@ -0,0 +1,147 @@ +/* +This file is part of web3.js. + +web3.js is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +web3.js is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with web3.js. If not, see . +*/ + +/* eslint-disable */ +import WebSocketProvider from 'web3-providers-ws'; +import { Web3Account } from 'web3-eth-accounts'; +import { Web3, Contract, Numbers, EventLog } from 'web3'; +import { BasicBytecode, BasicAbi } from '../../../../fixtures/build/Basic'; +import { isWs, isIpc, getSystemTestProvider } from '../../../../scripts/system_tests_utils'; + +const contracts: { [key: string]: Contract } = {}; + +const deployContracts = async (web3: Web3, accounts: Web3Account[]) => { + const prs = []; + for (let i = 0; i < accounts.length; i++) { + const account = accounts[i]; + const sendOptions = { from: account.address }; + const deployOptions = { + data: BasicBytecode, + arguments: [123, ''] as [number, string], + gas: BigInt(9000000000000), + gasLimit: BigInt(9000000000000), + type: BigInt(0), + }; + const c = new web3.eth.Contract(BasicAbi); + prs.push( + c + .deploy(deployOptions) + .send(sendOptions) + .then((contract: typeof c) => { + contracts[account.address] = contract; + }), + ); + } + await Promise.all(prs); +}; + +const addAccount = async ( + web3: Web3, + mainAcc: string, + address: string, + privateKey: string, + nonce: Numbers, +) => { + web3.eth.accounts.wallet.add(privateKey); + return web3.eth.sendTransaction({ + from: mainAcc, + to: address, + nonce, + gas: 1500000, + value: '1000000000000000000', + }); +}; + +const prepareAccounts = async (web3: Web3, n = 1000) => { + const prs = []; + const list = await web3.eth.personal.getAccounts(); + const mainAcc = list[0]; + const accountList: Web3Account[] = []; + const nonce = await web3.eth.getTransactionCount(mainAcc); + for (let i = 0; i < n; i++) { + const acc = web3.eth.accounts.create(); + prs.push(addAccount(web3, mainAcc, acc.address, acc.privateKey, Number(nonce) + i)); + accountList.push(acc); + } + await Promise.all(prs); + return accountList; +}; + +const sendData = async (account: Web3Account) => { + const contract = contracts[account.address]; + return contract.methods + .firesStringEvent(`String event: ${account.address}`) + .send({ from: account.address }); +}; + +const getData = async (account: Web3Account) => { + const contract = contracts[account.address]; + await contract.methods.getStringValue().call(); +}; + +const receivedEvents: { [key: string]: EventLog } = {}; +const subscribeContract = (acc: Web3Account) => { + const contract = contracts[acc.address]; + const event = contract.events.StringEvent(); + + event.on('data', res => { + if (res.returnValues.str !== `String event: ${acc.address}`) { + throw new Error('Event is not correct'); + } + receivedEvents[acc.address] = res; + }); +}; +const contractSubscriptions = (accounts: Web3Account[]) => { + for (const acc of accounts) { + subscribeContract(acc); + } +}; + +describe('huge data', () => { + let web3: Web3; + let parallelCount = 100; + let accounts: Web3Account[] = []; + beforeAll(async () => { + parallelCount = parallelCount; + web3 = new Web3(getSystemTestProvider()); + accounts = await prepareAccounts(web3, parallelCount); + await deployContracts(web3, accounts); + }); + afterAll(() => { + if (isWs || isIpc) { + (web3.provider as unknown as WebSocketProvider).disconnect(); + } + }); + it('send requests large number of requests', async () => { + const sendPrs = []; + for (let i = 0; i < parallelCount; i++) { + sendPrs.push(sendData(accounts[i])); + } + await expect(Promise.all(sendPrs)).resolves.toBeDefined(); + // if socket subscribe to events + if (isIpc || isWs) { + contractSubscriptions(accounts); + } + }); + it('get requests', async () => { + const getPrs = []; + for (let i = 0; i < parallelCount; i++) { + getPrs.push(getData(accounts[i])); + } + await expect(Promise.all(getPrs)).resolves.toBeDefined(); + }); +}); diff --git a/packages/web3/test/stress/setup.js b/packages/web3/test/stress/setup.js new file mode 100644 index 00000000000..e9757a61e1c --- /dev/null +++ b/packages/web3/test/stress/setup.js @@ -0,0 +1,24 @@ +/* +This file is part of web3.js. + +web3.js is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +web3.js is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with web3.js. If not, see . +*/ + +// Have to use `require` because of Jest issue https://jestjs.io/docs/ecmascript-modules +// eslint-disable-next-line @typescript-eslint/no-require-imports +require('../config/setup'); + +const jestTimeout = 300000; + +jest.setTimeout(jestTimeout); diff --git a/packages/web3/test/stress/start.sh b/packages/web3/test/stress/start.sh deleted file mode 100755 index 9de30d524d9..00000000000 --- a/packages/web3/test/stress/start.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash -. scripts/env.sh - -export WEB3_SYSTEM_TEST_BACKEND="geth" -export TS_NODE_PREFER_TS_EXTS=true - -./scripts/geth_binary.sh stressStart - -yarn generate:accounts - -export WEB3_SYSTEM_TEST_PROVIDER=$IPC_PATH -npx ts-node ./packages/web3/test/stress/index.ts - -export WEB3_SYSTEM_TEST_PROVIDER=ws://127.0.0.1:8545 -npx ts-node ./packages/web3/test/stress/index.ts - -./scripts/geth_binary.sh stop diff --git a/packages/web3/test/stress/validation.test.ts b/packages/web3/test/stress/validation.test.ts new file mode 100644 index 00000000000..7ef7e44ef4c --- /dev/null +++ b/packages/web3/test/stress/validation.test.ts @@ -0,0 +1,183 @@ +/* +This file is part of web3.js. + +web3.js is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +web3.js is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with web3.js. If not, see . +*/ + +import { Web3Validator, Json, JsonSchema, ValidationSchemaInput } from 'web3-validator'; + +const abi = [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { indexed: false, internalType: 'uint256', name: 'value', type: 'uint256' }, +]; + +const abiJsonSchema = { + type: 'array', + items: [ + { name: 'from', format: 'address' }, + { name: 'to', format: 'address' }, + { name: 'value', format: 'uint256' }, + ], +}; + +const abiData = [ + '0xCB00CDE33a7a0Fba30C63745534F1f7Ae607076b', + '0xCB00CDE33a7a0Fba30C63745534F1f7Ae607076b', + '0xCB00CDE33a7a0Fba30C63745534F1f7Ae607076b', +]; + +const simpleSchema = { + type: 'object', + required: ['blockHash', 'blockNumber', 'from', 'to', 'data'], + properties: { + blockHash: { + format: 'bytes32', + }, + blockNumber: { + format: 'uint', + }, + from: { + format: 'address', + }, + to: { + oneOf: [{ format: 'address' }, { type: 'null' }], + }, + data: { + format: 'bytes', + }, + }, +}; + +const simpleData = { + blockHash: '0x0dec0518fa672a70027b04c286582e543ab17319fbdd384fa7bc8f3d5a542c0b', + blockNumber: BigInt(2), + from: '0xCB00CDE33a7a0Fba30C63745534F1f7Ae607076b', + to: '0xCB00CDE33a7a0Fba30C63745534F1f7Ae607076b', + data: '0xafea', +} as unknown as ValidationSchemaInput; + +const createHugeSchema = ( + schema: JsonSchema, + data: Json, + n = 3, +): { schema: JsonSchema; data: Json } => { + if (n > 0) { + const { data: resultData, schema: resultSchema } = createHugeSchema( + { ...simpleSchema } as JsonSchema, + { ...simpleData } as Json, + n - 1, + ); + return { + data: { ...(data as unknown as object), simple: resultData }, + schema: { ...schema, properties: { ...schema.properties, simple: resultSchema } }, + }; + } + return { + schema, + data, + }; +}; + +const { schema: hugeSchema, data: hugeData } = createHugeSchema( + { ...simpleSchema } as JsonSchema, + { ...simpleData } as Json, + 500, +); + +const { schema: hugeSchema1000, data: hugeData1000 } = createHugeSchema( + { ...simpleSchema } as JsonSchema, + { ...simpleData } as Json, + 1000, +); +describe('validator', () => { + let validator: Web3Validator; + beforeAll(() => { + validator = new Web3Validator(); + }); + + it('huge schema', () => { + let t = 0; + expect(() => { + const t1 = Number(new Date()); + validator.validateJSONSchema(hugeSchema, hugeData as object); + t = Number(new Date()) - t1; + }).not.toThrow(); + expect(t).toBeLessThan(6000); + expect(t).toBeGreaterThan(0); + }); + + it('huge schema 1000', () => { + let t = 0; + expect(() => { + const t1 = Number(new Date()); + validator.validateJSONSchema(hugeSchema1000, hugeData1000 as object); + t = Number(new Date()) - t1; + }).not.toThrow(); + expect(t).toBeLessThan(6000); + expect(t).toBeGreaterThan(0); + }); + + it('simple schema multiple times', () => { + let t = 0; + expect(() => { + const t1 = Number(new Date()); + for (let i = 0; i < 500; i += 1) { + validator.validateJSONSchema(simpleSchema, simpleData as object); + } + t = Number(new Date()) - t1; + }).not.toThrow(); + expect(t).toBeLessThan(3000); + expect(t).toBeGreaterThan(0); + }); + + it('simple schema 1000 times', () => { + let t = 0; + expect(() => { + const t1 = Number(new Date()); + for (let i = 0; i < 1000; i += 1) { + validator.validateJSONSchema(simpleSchema, simpleData as object); + } + t = Number(new Date()) - t1; + }).not.toThrow(); + expect(t).toBeLessThan(4000); + expect(t).toBeGreaterThan(0); + }); + + it('simple JSON schema 1000 times', () => { + let t = 0; + expect(() => { + const t1 = Number(new Date()); + for (let i = 0; i < 1000; i += 1) { + validator.validateJSONSchema(abiJsonSchema, abiData as object); + } + t = Number(new Date()) - t1; + }).not.toThrow(); + expect(t).toBeLessThan(4000); + expect(t).toBeGreaterThan(0); + }); + + it('simple ABI 1000 times', () => { + let t = 0; + expect(() => { + const t1 = Number(new Date()); + for (let i = 0; i < 1000; i += 1) { + validator.validate(abi, abiData); + } + t = Number(new Date()) - t1; + }).not.toThrow(); + expect(t).toBeLessThan(4000); + expect(t).toBeGreaterThan(0); + }); +}); diff --git a/packages/web3/test/stress/validator.ts b/packages/web3/test/stress/validator.ts deleted file mode 100644 index 076351820c0..00000000000 --- a/packages/web3/test/stress/validator.ts +++ /dev/null @@ -1,126 +0,0 @@ -/* -This file is part of web3.js. - -web3.js is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -web3.js is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with web3.js. If not, see . -*/ - -/* eslint-disable */ -import { Web3Validator, JsonSchema, Json } from 'web3-validator'; - -const abi = [ - { indexed: true, internalType: 'address', name: 'from', type: 'address' }, - { indexed: true, internalType: 'address', name: 'to', type: 'address' }, - { indexed: false, internalType: 'uint256', name: 'value', type: 'uint256' }, -]; - -const abiJsonSchema = { - type: 'array', - items: [ - { name: 'from', format: 'address' }, - { name: 'to', format: 'address' }, - { name: 'value', format: 'uint256' }, - ], -}; - -const abiData = [ - '0xCB00CDE33a7a0Fba30C63745534F1f7Ae607076b', - '0xCB00CDE33a7a0Fba30C63745534F1f7Ae607076b', - '0xCB00CDE33a7a0Fba30C63745534F1f7Ae607076b', -]; - -const simpleSchema = { - type: 'object', - required: ['blockHash', 'blockNumber', 'from', 'to', 'data'], - properties: { - blockHash: { - format: 'bytes32', - }, - blockNumber: { - format: 'uint', - }, - from: { - format: 'address', - }, - to: { - oneOf: [{ format: 'address' }, { type: 'null' }], - }, - data: { - format: 'bytes', - }, - }, -}; - -const simpleData = { - blockHash: '0x0dec0518fa672a70027b04c286582e543ab17319fbdd384fa7bc8f3d5a542c0b', - blockNumber: BigInt(2), - from: '0xCB00CDE33a7a0Fba30C63745534F1f7Ae607076b', - to: '0xCB00CDE33a7a0Fba30C63745534F1f7Ae607076b', - data: '0xafea', -}; - -const createHugeSchema = ( - schema: JsonSchema, - data: Json, - n = 3, -): { schema: JsonSchema; data: Json } => { - if (n > 0) { - const { data: resultData, schema: resultSchema } = createHugeSchema( - { ...simpleSchema }, - { ...simpleData } as unknown as Json, - n - 1, - ); - return { - data: { ...(typeof data === 'object' ? data : { data }), simple: resultData }, - schema: { ...schema, properties: { ...schema.properties, simple: resultSchema } }, - }; - } - return { - schema, - data, - }; -}; - -const { schema: hugeSchema, data: hugeData } = createHugeSchema( - { ...simpleSchema }, - { ...simpleData } as unknown as Json, - 500, -); - -const { schema: hugeSchema1000, data: hugeData1000 } = createHugeSchema( - { ...simpleSchema }, - { ...simpleData } as unknown as Json, - 1000, -); - -const validator = new Web3Validator(); - -validator.validateJSONSchema(hugeSchema, hugeData as object); - -validator.validateJSONSchema(hugeSchema1000, hugeData1000 as object); - -for (let i = 0; i < 500; i += 1) { - validator.validateJSONSchema(simpleSchema, simpleData); -} - -for (let i = 0; i < 1000; i += 1) { - validator.validateJSONSchema(simpleSchema, simpleData); -} - -for (let i = 0; i < 1000; i += 1) { - validator.validateJSONSchema(abiJsonSchema, abiData); -} - -for (let i = 0; i < 1000; i += 1) { - validator.validate(abi, abiData); -} diff --git a/scripts/gen_accounts.js b/scripts/gen_accounts.js index b67519a702e..75d29bbe610 100644 --- a/scripts/gen_accounts.js +++ b/scripts/gen_accounts.js @@ -24,7 +24,9 @@ const addAccount = async (address, privateKey) => { if (!accountList.find(acc => acc.address === address)) { await web3Personal.importRawKey( - getSystemTestBackend() === 'geth' ? privateKey.slice(2) : privateKey, + ['geth', 'geth-manual'].includes(getSystemTestBackend()) + ? privateKey.slice(2) + : privateKey, '123456', ); } diff --git a/scripts/geth_binary.sh b/scripts/geth_binary.sh index 82f48622ec6..c4e1511e22e 100755 --- a/scripts/geth_binary.sh +++ b/scripts/geth_binary.sh @@ -70,10 +70,10 @@ start() { fi } -startStress() { +startManual() { download - echo "Starting geth..." + echo "Starting manual geth..." echo "geth --ipcpath $IPC_PATH --nodiscover --nousb --ws --ws.addr 0.0.0.0 --ws.port $WEB3_SYSTEM_TEST_PORT --http --http.addr 0.0.0.0 --http.port $WEB3_SYSTEM_TEST_PORT --allow-insecure-unlock --http.api personal,web3,eth,admin,debug,txpool,net --ws.api personal,web3,eth,admin,debug,miner,txpool,net --dev --mine --dev.period=0 --dev.gaslimit 9000000000000000 --rpc.txfeecap=1000000 &>/dev/null &" ${TMP_FOLDER}/geth --ipcpath $IPC_PATH --nodiscover --nousb --ws --ws.addr 0.0.0.0 --ws.port $WEB3_SYSTEM_TEST_PORT --http --http.addr 0.0.0.0 --http.port $WEB3_SYSTEM_TEST_PORT --allow-insecure-unlock --http.api personal,web3,eth,admin,debug,txpool,net --ws.api personal,web3,eth,admin,debug,miner,txpool,net --dev --mine --dev.period=0 --rpc.enabledeprecatedpersonal --dev.gaslimit 9000000000000000 --rpc.txfeecap=1000000 &>/dev/null & echo "Waiting for geth..." @@ -81,7 +81,6 @@ startStress() { } - startSync() { download @@ -107,7 +106,7 @@ stop() { } case $1 in -stressStart) startStress ;; +manualStart) startManual ;; syncStart) startSync ;; syncStop) syncStop ;; start) start ;; diff --git a/scripts/test-runner.sh b/scripts/test-runner.sh index cdb3798e461..cbe35641285 100755 --- a/scripts/test-runner.sh +++ b/scripts/test-runner.sh @@ -13,11 +13,11 @@ MODE=${ORIGARGS[1]} ENGINE=${ORIGARGS[2]} TEST_OPTION=${ORIGARGS[3]} -SUPPORTED_BACKENDS=("geth" "ganache" "sepolia" "mainnet") +SUPPORTED_BACKENDS=("geth" "ganache" "sepolia" "mainnet" "geth-manual") SUPPORTED_MODE=("http" "ws" "ipc") # if you will add a new browser please also add it in the system_test_utils.ts => isBrowser SUPPORTED_ENGINES=("node" "electron" "firefox" "chrome" "") -SUPPORTED_TEST_OPTIONS=("coverage" "sync" "") +SUPPORTED_TEST_OPTIONS=("coverage" "sync" "manual" "") if [[ ! " ${SUPPORTED_BACKENDS[*]} " =~ " ${BACKEND} " ]]; then helpFunction @@ -47,11 +47,17 @@ TEST_COMMAND="" if [[ $MODE == "ipc" ]]; then export WEB3_SYSTEM_TEST_PROVIDER=$IPC_PATH - BACKEND=geth-binary + if [[ $BACKEND != "geth-manual" ]]; then + BACKEND=geth-binary + fi fi + + if [[ $ENGINE == "node" ]] || [[ $ENGINE == "" ]]; then - if [[ $TEST_OPTION == "coverage" ]]; then + if [[ $TEST_OPTION == "manual" ]]; then + TEST_COMMAND="test:integration:stress" + elif [[ $TEST_OPTION == "coverage" ]]; then TEST_COMMAND="test:coverage:integration" elif [[ $BACKEND == "sepolia" || $BACKEND == "mainnet" ]]; then TEST_COMMAND="lerna run test:e2e:$BACKEND" @@ -59,11 +65,15 @@ if [[ $ENGINE == "node" ]] || [[ $ENGINE == "" ]]; then TEST_COMMAND="test:integration" fi else - TEST_COMMAND="lerna run test:e2e:$ENGINE --stream" + if [[ $TEST_OPTION == "manual" ]]; then + TEST_COMMAND="lerna run test:e2e:$ENGINE:stress --stream" + else + TEST_COMMAND="lerna run test:e2e:$ENGINE --stream" + fi fi -if [[ $BACKEND == "geth" || $BACKEND == "ganache" || $BACKEND == "geth-binary" ]]; then +if [[ $BACKEND == "geth" || $BACKEND == "ganache" || $BACKEND == "geth-binary" || $BACKEND == "geth-manual" ]]; then yarn "$BACKEND:start:background" && yarn generate:accounts && yarn $TEST_COMMAND && yarn "$BACKEND:stop" else yarn $TEST_COMMAND