diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 012edf7aad..51ff16f9dd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -289,7 +289,7 @@ jobs: ETHEREUM_URL: ${{ secrets.ETHEREUM_URL }} AZLE_IDENTITY_STORAGE_MODE: 'plaintext' AZLE_END_TO_END_TEST_LINK_AZLE: ${{ matrix.azle_source == 'repo' }} - AZLE_QUICK_TEST: ${{ matrix.azle_source == 'repo'}} + AZLE_TEST_RUN_ON_RELEASE: ${{ contains(github.head_ref, 'release--') }} strategy: fail-fast: false # We want to see which example tests succeed and which ones fail, we don't want one example test to cancel the rest matrix: diff --git a/examples/basic_bitcoin/src/index.ts b/examples/basic_bitcoin/src/index.ts index bfe32817df..4513aefbbd 100644 --- a/examples/basic_bitcoin/src/index.ts +++ b/examples/basic_bitcoin/src/index.ts @@ -68,17 +68,28 @@ app.get('/get-p2pkh-address', async (req, res) => { /// Sends the given amount of bitcoin from this canister to the given address. /// Returns the transaction ID. app.post('/send', async (req, res) => { - const { destinationAddress, amountInSatoshi } = req.body; - - const txId = await bitcoinWallet.send( - NETWORK, - DERIVATION_PATH, - KEY_NAME, - destinationAddress, - BigInt(jsonParse(JSON.stringify(amountInSatoshi))) - ); - - res.send(txId); + try { + const { destinationAddress, amountInSatoshi } = req.body; + + const txId = await bitcoinWallet.send( + NETWORK, + DERIVATION_PATH, + KEY_NAME, + destinationAddress, + BigInt(jsonParse(JSON.stringify(amountInSatoshi))) + ); + + res.send(txId); + } catch (error: any) { + res.status(500).json({ + success: false, + error: { + code: error.code || 'UNKNOWN_ERROR', + message: error.message, + details: error.info || null + } + }); + } }); app.listen(); diff --git a/examples/bitcoin_psbt/src/index.ts b/examples/bitcoin_psbt/src/index.ts index 0bb512a623..f4467f4b95 100644 --- a/examples/bitcoin_psbt/src/index.ts +++ b/examples/bitcoin_psbt/src/index.ts @@ -69,17 +69,28 @@ app.get('/get-p2wpkh-address', async (req, res) => { /// Sends the given amount of bitcoin from this canister to the given address. /// Returns the transaction ID. app.post('/send', async (req, res) => { - const { destinationAddress, amountInSatoshi } = req.body; - - const txId = await bitcoinWallet.send( - NETWORK, - DERIVATION_PATH, - KEY_NAME, - destinationAddress, - BigInt(jsonParse(JSON.stringify(amountInSatoshi))) - ); - - res.send(txId); + try { + const { destinationAddress, amountInSatoshi } = req.body; + + const txId = await bitcoinWallet.send( + NETWORK, + DERIVATION_PATH, + KEY_NAME, + destinationAddress, + BigInt(jsonParse(JSON.stringify(amountInSatoshi))) + ); + + res.send(txId); + } catch (error: any) { + res.status(500).json({ + success: false, + error: { + code: error.code || 'UNKNOWN_ERROR', + message: error.message, + details: error.info || null + } + }); + } }); app.listen(); diff --git a/property_tests/tests/stable_b_tree_map/test/contains_key.ts b/property_tests/tests/stable_b_tree_map/test/contains_key.ts index 07f0c8d297..c0a8280c14 100644 --- a/property_tests/tests/stable_b_tree_map/test/contains_key.ts +++ b/property_tests/tests/stable_b_tree_map/test/contains_key.ts @@ -40,7 +40,7 @@ export function ContainsKeyTestArb( } function generateBody(stableBTreeMapName: string): string { - return ` + return /*TS*/ ` return ${stableBTreeMapName}.containsKey(param0); `; } diff --git a/property_tests/tests/stable_b_tree_map/test/get.ts b/property_tests/tests/stable_b_tree_map/test/get.ts index 7ee9b60622..958bcb1c2a 100644 --- a/property_tests/tests/stable_b_tree_map/test/get.ts +++ b/property_tests/tests/stable_b_tree_map/test/get.ts @@ -24,7 +24,9 @@ export function GetTestArb( ].join(', '); const returnCandidTypeObject = `Opt(${stableBTreeMap.valueSample.src.candidTypeObject})`; - const body = generateBody(stableBTreeMap.name); + const valueTypeIsNull = + stableBTreeMap.valueSample.src.candidTypeAnnotation === 'Null'; + const body = generateBody(stableBTreeMap.name, valueTypeIsNull); const tests = generateTests( functionName, @@ -43,10 +45,14 @@ export function GetTestArb( }); } -function generateBody(stableBTreeMapName: string): string { +function generateBody( + stableBTreeMapName: string, + valueTypeIsNull: boolean +): string { return /*TS*/ ` const result = ${stableBTreeMapName}.get(param0); - if (result === null) { + const containsKey = ${stableBTreeMapName}.containsKey(param0); // For situations where the stored value is literally null + if (result === null ${valueTypeIsNull ? '&& !containsKey' : ''}) { return None } else { return Some(result) diff --git a/property_tests/tests/stable_b_tree_map/test/remove.ts b/property_tests/tests/stable_b_tree_map/test/remove.ts index b8c1d0390a..ddf2bb86fa 100644 --- a/property_tests/tests/stable_b_tree_map/test/remove.ts +++ b/property_tests/tests/stable_b_tree_map/test/remove.ts @@ -24,7 +24,9 @@ export function RemoveTestArb( ].join(', '); const returnCandidTypeObject = `Opt(${stableBTreeMap.valueSample.src.candidTypeObject})`; - const body = generateBody(stableBTreeMap.name); + const valueTypeIsNull = + stableBTreeMap.valueSample.src.candidTypeAnnotation === 'Null'; + const body = generateBody(stableBTreeMap.name, valueTypeIsNull); const tests = generateTests( functionName, @@ -43,10 +45,14 @@ export function RemoveTestArb( }); } -function generateBody(stableBTreeMapName: string): string { +function generateBody( + stableBTreeMapName: string, + valueTypeIsNull: boolean +): string { return /*TS*/ ` + const containsKey = ${stableBTreeMapName}.containsKey(param0); // For situations where the stored value is literally null const result = ${stableBTreeMapName}.remove(param0); - if (result === null) { + if (result === null ${valueTypeIsNull ? '&& !containsKey' : ''}) { return None } else { return Some(result) diff --git a/tests/end_to_end/candid_rpc/class_syntax/ethereum_json_rpc/jest.config.js b/tests/end_to_end/candid_rpc/class_syntax/ethereum_json_rpc/jest.config.js index 3ab7e2d25e..43cb5d4f5d 100644 --- a/tests/end_to_end/candid_rpc/class_syntax/ethereum_json_rpc/jest.config.js +++ b/tests/end_to_end/candid_rpc/class_syntax/ethereum_json_rpc/jest.config.js @@ -2,6 +2,7 @@ module.exports = { preset: 'ts-jest', testEnvironment: 'node', + testTimeout: 100_000_000, transform: { '^.+\\.ts$': ['ts-jest', { isolatedModules: true }], '^.+\\.js$': 'ts-jest' diff --git a/tests/end_to_end/candid_rpc/class_syntax/new/package.json b/tests/end_to_end/candid_rpc/class_syntax/new/package.json index 600353dd98..6141803118 100644 --- a/tests/end_to_end/candid_rpc/class_syntax/new/package.json +++ b/tests/end_to_end/candid_rpc/class_syntax/new/package.json @@ -1,7 +1,7 @@ { "name": "new_end_to_end_test_functional_syntax", "scripts": { - "test": "if [ \"$AZLE_QUICK_TEST\" != \"true\" ]; then tsx test/test.ts; else echo 'Skipping pretests'; fi" + "test": "if [ \"$AZLE_TEST_RUN_ON_RELEASE\" == \"true\" ]; then tsx test/test.ts; else echo 'Skipping pretests'; fi" }, "devDependencies": { "@dfinity/agent": "^0.19.2", diff --git a/tests/end_to_end/candid_rpc/class_syntax/new_candid_rpc/package.json b/tests/end_to_end/candid_rpc/class_syntax/new_candid_rpc/package.json index 600353dd98..6141803118 100644 --- a/tests/end_to_end/candid_rpc/class_syntax/new_candid_rpc/package.json +++ b/tests/end_to_end/candid_rpc/class_syntax/new_candid_rpc/package.json @@ -1,7 +1,7 @@ { "name": "new_end_to_end_test_functional_syntax", "scripts": { - "test": "if [ \"$AZLE_QUICK_TEST\" != \"true\" ]; then tsx test/test.ts; else echo 'Skipping pretests'; fi" + "test": "if [ \"$AZLE_TEST_RUN_ON_RELEASE\" == \"true\" ]; then tsx test/test.ts; else echo 'Skipping pretests'; fi" }, "devDependencies": { "@dfinity/agent": "^0.19.2", diff --git a/tests/end_to_end/candid_rpc/functional_syntax/ethereum_json_rpc/jest.config.js b/tests/end_to_end/candid_rpc/functional_syntax/ethereum_json_rpc/jest.config.js index 3ab7e2d25e..43cb5d4f5d 100644 --- a/tests/end_to_end/candid_rpc/functional_syntax/ethereum_json_rpc/jest.config.js +++ b/tests/end_to_end/candid_rpc/functional_syntax/ethereum_json_rpc/jest.config.js @@ -2,6 +2,7 @@ module.exports = { preset: 'ts-jest', testEnvironment: 'node', + testTimeout: 100_000_000, transform: { '^.+\\.ts$': ['ts-jest', { isolatedModules: true }], '^.+\\.js$': 'ts-jest' diff --git a/tests/end_to_end/http_server/ethers_base/src/server.ts b/tests/end_to_end/http_server/ethers_base/src/server.ts index e7fedb9992..7c4ceeb671 100644 --- a/tests/end_to_end/http_server/ethers_base/src/server.ts +++ b/tests/end_to_end/http_server/ethers_base/src/server.ts @@ -65,24 +65,35 @@ app.post( app.post( '/transfer-from-canister', async (req: Request, res) => { - const wallet = new ThresholdWallet( - { - derivationPath: [ic.id().toUint8Array()] - }, - ethers.getDefaultProvider('https://sepolia.base.org') - ); - - const to = req.body.to; - const value = ethers.parseEther(req.body.value); - const gasLimit = 21_000n; - - const tx = await wallet.sendTransaction({ - to, - value, - gasLimit - }); - - res.send(`transaction sent with hash: ${tx.hash}`); + try { + const wallet = new ThresholdWallet( + { + derivationPath: [ic.id().toUint8Array()] + }, + ethers.getDefaultProvider('https://sepolia.base.org') + ); + + const to = req.body.to; + const value = ethers.parseEther(req.body.value); + const gasLimit = 21_000n; + + const tx = await wallet.sendTransaction({ + to, + value, + gasLimit + }); + + res.send(`transaction sent with hash: ${tx.hash}`); + } catch (error: any) { + res.status(500).json({ + success: false, + error: { + code: error.code || 'UNKNOWN_ERROR', + message: error.message, + details: error.info || null + } + }); + } } ); diff --git a/tests/end_to_end/http_server/fetch_ic/test/tests.ts b/tests/end_to_end/http_server/fetch_ic/test/tests.ts index ca7d834863..4ce2cc6f82 100644 --- a/tests/end_to_end/http_server/fetch_ic/test/tests.ts +++ b/tests/end_to_end/http_server/fetch_ic/test/tests.ts @@ -37,7 +37,7 @@ export function getTests(canisterName: string): Test { mainPage = pages[1]; }, - 10_000 + 15_000 ); wait('for identity to be set', 5_000); diff --git a/tests/end_to_end/http_server/ic_evm_rpc/src/server.ts b/tests/end_to_end/http_server/ic_evm_rpc/src/server.ts index f7363cda51..44ad56ab3f 100644 --- a/tests/end_to_end/http_server/ic_evm_rpc/src/server.ts +++ b/tests/end_to_end/http_server/ic_evm_rpc/src/server.ts @@ -83,60 +83,74 @@ app.post( app.post( '/transfer-from-canister', async (req: Request, res) => { - if (canisterAddress.value === null) { - canisterAddress.value = ethers.computeAddress( - ethers.hexlify(await ecdsaPublicKey([ic.id().toUint8Array()])) + try { + if (canisterAddress.value === null) { + canisterAddress.value = ethers.computeAddress( + ethers.hexlify( + await ecdsaPublicKey([ic.id().toUint8Array()]) + ) + ); + } + + const to = req.body.to; + const value = ethers.parseEther(req.body.value); + const maxPriorityFeePerGas = await ethMaxPriorityFeePerGas(); + const baseFeePerGas = BigInt( + (await ethFeeHistory()).Consistent?.Ok[0].baseFeePerGas[0] + ); + const maxFeePerGas = baseFeePerGas * 2n + maxPriorityFeePerGas; + const gasLimit = 21_000n; + const nonce = await ethGetTransactionCount(canisterAddress.value); + + let tx = ethers.Transaction.from({ + to, + value, + maxPriorityFeePerGas, + maxFeePerGas, + gasLimit, + nonce, + chainId + }); + + const unsignedSerializedTx = tx.unsignedSerialized; + const unsignedSerializedTxHash = + ethers.keccak256(unsignedSerializedTx); + + const signedSerializedTxHash = await signWithEcdsa( + [ic.id().toUint8Array()], + ethers.getBytes(unsignedSerializedTxHash) ); - } - - const to = req.body.to; - const value = ethers.parseEther(req.body.value); - const maxPriorityFeePerGas = await ethMaxPriorityFeePerGas(); - const baseFeePerGas = BigInt( - (await ethFeeHistory()).Consistent?.Ok[0].baseFeePerGas[0] - ); - const maxFeePerGas = baseFeePerGas * 2n + maxPriorityFeePerGas; - const gasLimit = 21_000n; - const nonce = await ethGetTransactionCount(canisterAddress.value); - - let tx = ethers.Transaction.from({ - to, - value, - maxPriorityFeePerGas, - maxFeePerGas, - gasLimit, - nonce, - chainId - }); - - const unsignedSerializedTx = tx.unsignedSerialized; - const unsignedSerializedTxHash = ethers.keccak256(unsignedSerializedTx); - - const signedSerializedTxHash = await signWithEcdsa( - [ic.id().toUint8Array()], - ethers.getBytes(unsignedSerializedTxHash) - ); - - const { r, s, v } = calculateRsvForTEcdsa( - canisterAddress.value, - unsignedSerializedTxHash, - signedSerializedTxHash - ); - - tx.signature = { - r, - s, - v - }; - - const rawTransaction = tx.serialized; - const result = await ethSendRawTransaction(rawTransaction); + const { r, s, v } = calculateRsvForTEcdsa( + canisterAddress.value, + unsignedSerializedTxHash, + signedSerializedTxHash + ); - if (result.Consistent?.Ok?.Ok.length === 1) { - res.send('transaction sent'); - } else { - res.status(500).send('transaction failed'); + tx.signature = { + r, + s, + v + }; + + const rawTransaction = tx.serialized; + + const result = await ethSendRawTransaction(rawTransaction); + + if (result.Consistent?.Ok?.Ok.length === 1) { + res.send('transaction sent'); + } else { + res.status(500).send('transaction failed'); + } + } catch (error: any) { + res.status(500).json({ + success: false, + error: { + code: error.code || 'UNKNOWN_ERROR', + message: error.message, + details: error.info || null + } + }); } } ); diff --git a/tests/end_to_end/http_server/large_files/test/auto_tests.ts b/tests/end_to_end/http_server/large_files/test/auto_tests.ts index 6cbb01e646..2fc0251b79 100644 --- a/tests/end_to_end/http_server/large_files/test/auto_tests.ts +++ b/tests/end_to_end/http_server/large_files/test/auto_tests.ts @@ -23,9 +23,10 @@ const autoGenAutoUploadSmallFileInfos: [number, Unit][] = [ ]; const autoGenAutoUploadFileInfos: [number, Unit][] = - process.env.AZLE_QUICK_TEST === 'true' - ? autoGenAutoUploadSmallFileInfos - : [...autoGenAutoUploadSmallFileInfos, [250, 'MiB'], [1, 'GiB']]; + process.env.AZLE_TEST_RUN_ON_RELEASE === 'true' || + process.env.AZLE_TEST_RUN_ON_LOCAL === 'true' + ? [...autoGenAutoUploadSmallFileInfos, [250, 'MiB'], [1, 'GiB']] + : autoGenAutoUploadSmallFileInfos; const permanentFiles: string[] = [ 'photos/people/george-washington.tif', diff --git a/tests/end_to_end/http_server/large_files/test/huge_file_tests.ts b/tests/end_to_end/http_server/large_files/test/huge_file_tests.ts index 47be7ecfa1..97708bed4c 100644 --- a/tests/end_to_end/http_server/large_files/test/huge_file_tests.ts +++ b/tests/end_to_end/http_server/large_files/test/huge_file_tests.ts @@ -7,12 +7,13 @@ import { Unit } from '../../../../../scripts/file_generator'; import { generateTestFileOfSize } from './generate_test_files'; import { getAutoGeneratedFileName, verifyUpload } from './tests'; -const hugeAutoGenAutoUploadSmallFileInfos: [number, Unit][] = [[0, 'GiB']]; // The tests will fail if this array is empty, so for AZLE_QUICK_TEST we will have a dummy entry +const hugeAutoGenAutoUploadSmallFileInfos: [number, Unit][] = [[0, 'GiB']]; // The tests will fail if this array is empty, so for !AZLE_TEST_RUN_ON_RELEASE && !AZLE_TEST_RUN_ON_LOCAL we will have a dummy entry const hugeAutoGenAutoUploadFileInfos: [number, Unit][] = - process.env.AZLE_QUICK_TEST === 'true' - ? hugeAutoGenAutoUploadSmallFileInfos - : [...hugeAutoGenAutoUploadSmallFileInfos, [2, 'GiB'], [5, 'GiB']]; + process.env.AZLE_TEST_RUN_ON_RELEASE === 'true' || + process.env.AZLE_TEST_RUN_ON_LOCAL === 'true' + ? [...hugeAutoGenAutoUploadSmallFileInfos, [2, 'GiB'], [5, 'GiB']] + : hugeAutoGenAutoUploadSmallFileInfos; export function hugeFilesTests(origin: string): Test { return () => {