Refactored provider test cases to more reliable CI.
This commit is contained in:
parent
86e0269a86
commit
de8a717b4c
@ -8,8 +8,6 @@ import { ethers } from "ethers";
|
||||
|
||||
const bnify = ethers.BigNumber.from;
|
||||
|
||||
type Dictionary = { [ key: string ]: any };
|
||||
|
||||
type TestCases = {
|
||||
addresses: Array<any>;
|
||||
blocks: Array<any>;
|
||||
@ -70,7 +68,7 @@ const blockchainData: { [ network: string ]: TestCases } = {
|
||||
s: "0x269c3e5b3558267ad91b0a887d51f9f10098771c67b82ea6cb74f29638754f54",
|
||||
v: 38,
|
||||
creates: null,
|
||||
raw: "0xf8d2808504a817c8008303d090946fc21092da55b392b045ed78f4732bff3c580e2c880186cc6acd4b0000b864f2c298be000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000067269636d6f6f000000000000000000000000000000000000000000000000000026a01e5605197a03e3f0a168f14749168dfeefc44c9228312dacbffdcbbb13263265a0269c3e5b3558267ad91b0a887d51f9f10098771c67b82ea6cb74f29638754f54",
|
||||
//raw: "0xf8d2808504a817c8008303d090946fc21092da55b392b045ed78f4732bff3c580e2c880186cc6acd4b0000b864f2c298be000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000067269636d6f6f000000000000000000000000000000000000000000000000000026a01e5605197a03e3f0a168f14749168dfeefc44c9228312dacbffdcbbb13263265a0269c3e5b3558267ad91b0a887d51f9f10098771c67b82ea6cb74f29638754f54",
|
||||
chainId: 1
|
||||
}
|
||||
],
|
||||
@ -375,6 +373,8 @@ blockchainData["default"] = blockchainData.homestead;
|
||||
function equals(name: string, actual: any, expected: any): void {
|
||||
if (expected && expected.eq) {
|
||||
if (actual == null) { assert.ok(false, name + " - actual big number null"); }
|
||||
expected = ethers.BigNumber.from(expected);
|
||||
actual = ethers.BigNumber.from(actual);
|
||||
assert.ok(expected.eq(actual), name + " matches");
|
||||
|
||||
} else if (Array.isArray(expected)) {
|
||||
@ -383,6 +383,7 @@ function equals(name: string, actual: any, expected: any): void {
|
||||
for (let i = 0; i < expected.length; i++) {
|
||||
equals("(" + name + " - item " + i + ")", actual[i], expected[i]);
|
||||
}
|
||||
|
||||
} else if (typeof(expected) === "object") {
|
||||
if (actual == null) {
|
||||
if (expected === actual) { return; }
|
||||
@ -405,35 +406,131 @@ function equals(name: string, actual: any, expected: any): void {
|
||||
|
||||
function waiter(duration: number): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(resolve, duration);
|
||||
const timer = setTimeout(resolve, duration);
|
||||
if (timer.unref) { timer.unref(); }
|
||||
});
|
||||
}
|
||||
|
||||
function testProvider(providerName: string, networkName: string) {
|
||||
|
||||
// Delay (ms) after each test case to prevent the backends from throttling
|
||||
const delay = 1000;
|
||||
type ProviderDescription = {
|
||||
name: string;
|
||||
networks: Array<string>;
|
||||
create: (network: string) => ethers.providers.Provider;
|
||||
};
|
||||
|
||||
describe(("Read-Only " + providerName + " (" + networkName + ")"), function() {
|
||||
this.retries(3);
|
||||
type CheckSkipFunc = (provider: string, network: string, test: TestDescription) => boolean;
|
||||
|
||||
// Get the Provider based on the name of the provider we are testing and the network
|
||||
let provider: ethers.providers.Provider = null;
|
||||
if (networkName === "default") {
|
||||
if (providerName === "getDefaultProvider") {
|
||||
provider = ethers.getDefaultProvider();
|
||||
} else {
|
||||
provider = new (<any>(ethers.providers))[providerName]();
|
||||
type TestDescription = {
|
||||
name: string;
|
||||
networks: Array<string>;
|
||||
execute: (provider: ethers.providers.Provider) => Promise<void>;
|
||||
|
||||
attempts?: number;
|
||||
timeout?: number;
|
||||
extras?: Array<"nowait" | "funding">;
|
||||
checkSkip?: CheckSkipFunc;
|
||||
};
|
||||
|
||||
|
||||
const allNetworks = [ "default", "homestead", "ropsten", "rinkeby", "kovan", "goerli" ];
|
||||
|
||||
const providerFunctions: Array<ProviderDescription> = [
|
||||
{
|
||||
name: "getDefaultProvider",
|
||||
networks: allNetworks,
|
||||
create: (network: string) => {
|
||||
if (network == "default") {
|
||||
return ethers.getDefaultProvider();
|
||||
}
|
||||
} else {
|
||||
if (providerName === "getDefaultProvider") {
|
||||
provider = ethers.getDefaultProvider(networkName);
|
||||
} else {
|
||||
provider = new (<any>(ethers.providers))[providerName](networkName);
|
||||
return ethers.getDefaultProvider(network);
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "AlchemyProvider",
|
||||
networks: allNetworks,
|
||||
create: (network: string) => {
|
||||
if (network == "default") {
|
||||
return new ethers.providers.AlchemyProvider();
|
||||
}
|
||||
return new ethers.providers.AlchemyProvider(network);
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "CloudflareProvider",
|
||||
networks: [ "homestead" ],
|
||||
create: (network: string) => {
|
||||
return new ethers.providers.AlchemyProvider(network);
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "InfuraProvider",
|
||||
networks: allNetworks,
|
||||
create: (network: string) => {
|
||||
if (network == "default") {
|
||||
return new ethers.providers.InfuraProvider();
|
||||
}
|
||||
return new ethers.providers.InfuraProvider(network);
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "EtherscanProvider",
|
||||
networks: allNetworks,
|
||||
create: (network: string) => {
|
||||
if (network == "default") {
|
||||
return new ethers.providers.EtherscanProvider();
|
||||
}
|
||||
return new ethers.providers.EtherscanProvider(network);
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "NodesmithProvider",
|
||||
networks: [ ],
|
||||
create: (network: string) => {
|
||||
throw new Error("not tested");
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Web3Provider",
|
||||
networks: [ ],
|
||||
create: (network: string) => {
|
||||
throw new Error("not tested");
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
const tests: TestCases = blockchainData[networkName];
|
||||
// This wallet can be funded and used for various test cases
|
||||
const fundWallet = ethers.Wallet.createRandom();
|
||||
|
||||
|
||||
const testFunctions: Array<TestDescription> = [ ];
|
||||
|
||||
Object.keys(blockchainData).forEach((network) => {
|
||||
function addSimpleTest(name: string, func: (provider: ethers.providers.Provider) => Promise<any>, expected: any) {
|
||||
testFunctions.push({
|
||||
name: name,
|
||||
networks: [ network ],
|
||||
execute: async (provider: ethers.providers.Provider) => {
|
||||
const value = await func(provider);
|
||||
equals(name, expected, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addObjectTest(name: string, func: (provider: ethers.providers.Provider) => Promise<any>, expected: any, checkSkip?: CheckSkipFunc) {
|
||||
testFunctions.push({
|
||||
name,
|
||||
networks: [ network ],
|
||||
checkSkip,
|
||||
execute: async (provider: ethers.providers.Provider) => {
|
||||
const value = await func(provider);
|
||||
Object.keys(expected).forEach((key) => {
|
||||
equals(`${ name }.${ key }`, value[key], expected[key]);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const tests: TestCases = blockchainData[network];
|
||||
|
||||
// And address test case can have any of the following:
|
||||
// - balance
|
||||
@ -442,82 +539,49 @@ function testProvider(providerName: string, networkName: string) {
|
||||
// - ENS name
|
||||
tests.addresses.forEach((test) => {
|
||||
if (test.balance) {
|
||||
it(`fetches address balance: ${ test.address }`, function() {
|
||||
// Note: These tests could be fiddled with if someone sends ether
|
||||
// to our address; we just have to live with jerks sending us
|
||||
// money. *smile emoji*
|
||||
|
||||
this.timeout(60000);
|
||||
return provider.getBalance(test.address).then((balance) => {
|
||||
equals("Balance", test.balance, balance);
|
||||
return waiter(delay);
|
||||
});
|
||||
});
|
||||
addSimpleTest(`fetches account balance: ${ test.address }`, (provider: ethers.providers.Provider) => {
|
||||
return provider.getBalance(test.address);
|
||||
}, test.balance);
|
||||
}
|
||||
|
||||
if (test.code) {
|
||||
it(`fetches address code: ${ test.address }`, function() {
|
||||
this.timeout(60000);
|
||||
return provider.getCode(test.address).then((code) => {
|
||||
equals("Code", test.code, code);
|
||||
return waiter(delay);
|
||||
});
|
||||
});
|
||||
addSimpleTest(`fetches account code: ${ test.address }`, (provider: ethers.providers.Provider) => {
|
||||
return provider.getCode(test.address);
|
||||
}, test.code);
|
||||
}
|
||||
|
||||
if (test.storage) {
|
||||
Object.keys(test.storage).forEach((position) => {
|
||||
it(`fetches storage: ${ test.address }:${ position }`, function() {
|
||||
this.timeout(60000);
|
||||
return provider.getStorageAt(test.address, bnify(position)).then((value) => {
|
||||
equals("Storage", test.storage[position], value);
|
||||
return waiter(delay);
|
||||
});
|
||||
});
|
||||
addSimpleTest(`fetches storage: ${ test.address }:${ position }`, (provider: ethers.providers.Provider) => {
|
||||
return provider.getStorageAt(test.address, bnify(position));
|
||||
}, test.storage[position]);
|
||||
});
|
||||
}
|
||||
|
||||
if (test.name) {
|
||||
it(`fetches the ENS name: ${ test.name }`, function() {
|
||||
this.timeout(60000);
|
||||
return provider.resolveName(test.name).then((address) => {
|
||||
equals("ENS Name", test.address, address);
|
||||
return waiter(delay);
|
||||
});
|
||||
});
|
||||
addSimpleTest(`fetches ENS name: ${ test.address }`, (provider: ethers.providers.Provider) => {
|
||||
return provider.resolveName(test.name);
|
||||
}, test.address);
|
||||
}
|
||||
});
|
||||
|
||||
tests.blocks.forEach((test) => {
|
||||
function checkBlock(promise: Promise<any>): Promise<any> {
|
||||
return promise.then((block) => {
|
||||
for (let key in test) {
|
||||
equals("Block " + key, block[key], test[key]);
|
||||
}
|
||||
return waiter(delay);
|
||||
});
|
||||
}
|
||||
|
||||
it(`fetches block (by number) #${ test.number }`, function() {
|
||||
this.timeout(60000);
|
||||
return checkBlock(provider.getBlock(test.number));
|
||||
addObjectTest(`fetches block (by number) #${ test.number }`, (provider: ethers.providers.Provider) => {
|
||||
return provider.getBlock(test.number);
|
||||
}, test);
|
||||
});
|
||||
|
||||
// Etherscan does not support getBlockByBlockhash... *sad emoji*
|
||||
if (providerName === "EtherscanProvider") {
|
||||
return;
|
||||
}
|
||||
|
||||
it(`fetches block (by hash) ${ test.hash }`, function() {
|
||||
this.timeout(60000);
|
||||
return checkBlock(provider.getBlock(test.hash));
|
||||
tests.blocks.forEach((test) => {
|
||||
addObjectTest(`fetches block (by hash) ${ test.hash }`, (provider: ethers.providers.Provider) => {
|
||||
return provider.getBlock(test.hash);
|
||||
}, test, (provider: string, network: string, test: TestDescription) => {
|
||||
return (provider === "EtherscanProvider");
|
||||
});
|
||||
});
|
||||
|
||||
tests.transactions.forEach((test) => {
|
||||
function testTransaction(expected: Dictionary): Promise<void> {
|
||||
const title = ("Transaction " + expected.hash.substring(0, 10) + " - ");
|
||||
return provider.getTransaction(expected.hash).then((tx) => {
|
||||
addObjectTest(`fetches transaction ${ test.hash }`, async (provider: ethers.providers.Provider) => {
|
||||
const tx = await provider.getTransaction(test.hash);
|
||||
|
||||
// This changes with every block
|
||||
assert.equal(typeof(tx.confirmations), "number", "confirmations is a number");
|
||||
@ -526,62 +590,52 @@ function testProvider(providerName: string, networkName: string) {
|
||||
assert.equal(typeof(tx.wait), "function", "wait is a function");
|
||||
delete tx.wait
|
||||
|
||||
for (const key in tx) {
|
||||
equals((title + key), (<any>tx)[key], expected[key]);
|
||||
}
|
||||
|
||||
return waiter(delay);
|
||||
});
|
||||
}
|
||||
|
||||
it(`fetches transaction: ${ test.hash }`, function() {
|
||||
this.timeout(60000);
|
||||
return testTransaction(test);
|
||||
return tx;
|
||||
}, test, (provider: string, network: string, test: TestDescription) => {
|
||||
return (provider === "EtherscanProvider");
|
||||
});
|
||||
});
|
||||
|
||||
tests.transactionReceipts.forEach((test) => {
|
||||
function testTransactionReceipt(expected: Dictionary): Promise<void> {
|
||||
const title = ("Receipt " + expected.transactionHash.substring(0, 10) + " - ");
|
||||
return provider.getTransactionReceipt(expected.transactionHash).then(function(receipt) {
|
||||
addObjectTest(`fetches transaction receipt ${ test.transactionHash }`, async (provider: ethers.providers.Provider) => {
|
||||
const receipt = await provider.getTransactionReceipt(test.transactionHash);
|
||||
|
||||
if (test.status === null) {
|
||||
assert.ok(receipt.status === undefined, "no status");
|
||||
receipt.status = null;
|
||||
}
|
||||
|
||||
// This changes with every block; so just make sure it is a number
|
||||
assert.equal(typeof(receipt.confirmations), "number", "confirmations is a number");
|
||||
delete receipt.confirmations;
|
||||
|
||||
for (const key in receipt) {
|
||||
equals((title + key), (<any>receipt)[key], expected[key]);
|
||||
}
|
||||
//equals(("Receipt " + expected.transactionHash.substring(0, 10)), receipt, expected);
|
||||
|
||||
return waiter(delay);
|
||||
return receipt;
|
||||
}, test);
|
||||
});
|
||||
}
|
||||
|
||||
it(`fetches transaction receipt: ${ test.transactionHash }`, function() {
|
||||
this.timeout(60000);
|
||||
return testTransactionReceipt(test);
|
||||
});
|
||||
});
|
||||
|
||||
if (networkName === "ropsten") {
|
||||
|
||||
it("throws correct NONCE_EXPIRED errors", async function() {
|
||||
this.timeout(60000);
|
||||
});
|
||||
|
||||
(function() {
|
||||
function addErrorTest(code: string, func: (provider: ethers.providers.Provider) => Promise<any>) {
|
||||
testFunctions.push({
|
||||
name: `throws correct ${ code } error`,
|
||||
networks: [ "ropsten" ],
|
||||
execute: async (provider: ethers.providers.Provider) => {
|
||||
try {
|
||||
const tx = await provider.sendTransaction("0xf86480850218711a0082520894000000000000000000000000000000000000000002801ba038aaddcaaae7d3fa066dfd6f196c8348e1bb210f2c121d36cb2c24ef20cea1fba008ae378075d3cd75aae99ab75a70da82161dffb2c8263dabc5d8adecfa9447fa");
|
||||
console.log(tx);
|
||||
assert.ok(false);
|
||||
const value = await func(provider);
|
||||
console.log(value);
|
||||
assert.ok(false, "did not throw");
|
||||
} catch (error) {
|
||||
assert.equal(error.code, ethers.utils.Logger.errors.NONCE_EXPIRED);
|
||||
assert.equal(error.code, code, "incorrect error thrown");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
await waiter(delay);
|
||||
addErrorTest(ethers.utils.Logger.errors.NONCE_EXPIRED, async (provider: ethers.providers.Provider) => {
|
||||
return provider.sendTransaction("0xf86480850218711a0082520894000000000000000000000000000000000000000002801ba038aaddcaaae7d3fa066dfd6f196c8348e1bb210f2c121d36cb2c24ef20cea1fba008ae378075d3cd75aae99ab75a70da82161dffb2c8263dabc5d8adecfa9447fa");
|
||||
});
|
||||
|
||||
it("throws correct INSUFFICIENT_FUNDS errors", async function() {
|
||||
this.timeout(60000);
|
||||
addErrorTest(ethers.utils.Logger.errors.INSUFFICIENT_FUNDS, async (provider: ethers.providers.Provider) => {
|
||||
|
||||
const txProps = {
|
||||
to: "0x8ba1f109551bD432803012645Ac136ddd64DBA72",
|
||||
@ -592,20 +646,10 @@ function testProvider(providerName: string, networkName: string) {
|
||||
|
||||
const wallet = ethers.Wallet.createRandom();
|
||||
const tx = await wallet.signTransaction(txProps);
|
||||
|
||||
try {
|
||||
await provider.sendTransaction(tx);
|
||||
assert.ok(false);
|
||||
} catch (error) {
|
||||
assert.equal(error.code, ethers.utils.Logger.errors.INSUFFICIENT_FUNDS);
|
||||
}
|
||||
|
||||
await waiter(delay);
|
||||
return provider.sendTransaction(tx);
|
||||
});
|
||||
|
||||
it("throws correct INSUFFICIENT_FUNDS errors (signer)", async function() {
|
||||
this.timeout(60000);
|
||||
|
||||
addErrorTest(ethers.utils.Logger.errors.INSUFFICIENT_FUNDS, async (provider: ethers.providers.Provider) => {
|
||||
const txProps = {
|
||||
to: "0x8ba1f109551bD432803012645Ac136ddd64DBA72",
|
||||
gasPrice: 9000000000,
|
||||
@ -614,89 +658,119 @@ function testProvider(providerName: string, networkName: string) {
|
||||
};
|
||||
|
||||
const wallet = ethers.Wallet.createRandom().connect(provider);
|
||||
|
||||
try {
|
||||
await wallet.sendTransaction(txProps);
|
||||
assert.ok(false);
|
||||
} catch (error) {
|
||||
assert.equal(error.code, ethers.utils.Logger.errors.INSUFFICIENT_FUNDS);
|
||||
}
|
||||
|
||||
await waiter(delay);
|
||||
return wallet.sendTransaction(txProps);
|
||||
});
|
||||
|
||||
it("throws correct UNPREDICTABLE_GAS_LIMIT errors", async function() {
|
||||
this.timeout(60000);
|
||||
|
||||
try {
|
||||
await provider.estimateGas({
|
||||
to: "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e" // ENS; no payable fallback
|
||||
addErrorTest(ethers.utils.Logger.errors.UNPREDICTABLE_GAS_LIMIT, async (provider: ethers.providers.Provider) => {
|
||||
return provider.estimateGas({
|
||||
to: "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e" // ENS contract
|
||||
});
|
||||
assert.ok(false);
|
||||
} catch (error) {
|
||||
assert.equal(error.code, ethers.utils.Logger.errors.UNPREDICTABLE_GAS_LIMIT);
|
||||
}
|
||||
|
||||
await waiter(delay);
|
||||
});
|
||||
})();
|
||||
|
||||
it("sends a transaction", async function() {
|
||||
this.timeout(360000);
|
||||
|
||||
const wallet = ethers.Wallet.createRandom().connect(provider);
|
||||
const funder = await ethers.utils.fetchJson(`https:/\/api.ethers.io/api/v1/?action=fundAccount&address=${ wallet.address.toLowerCase() }`);
|
||||
await provider.waitForTransaction(funder.hash);
|
||||
testFunctions.push({
|
||||
name: "sends a transaction",
|
||||
extras: [ "funding" ], // We need funding to the funWallet
|
||||
timeout: 300, // 5 minutes
|
||||
networks: [ "ropsten" ], // Only test on Ropsten
|
||||
execute: async (provider: ethers.providers.Provider) => {
|
||||
const wallet = fundWallet.connect(provider);
|
||||
|
||||
const addr = "0x8210357f377E901f18E45294e86a2A32215Cc3C9";
|
||||
const gasPrice = 9000000000;
|
||||
|
||||
let balance = await provider.getBalance(wallet.address);
|
||||
assert.ok(balance.eq(ethers.utils.parseEther("3.141592653589793238")), "balance is pi after funding");
|
||||
const b0 = await provider.getBalance(wallet.address);
|
||||
assert.ok(b0.gt(ethers.constants.Zero), "balance is non-zero");
|
||||
|
||||
const tx = await wallet.sendTransaction({
|
||||
to: addr,
|
||||
gasPrice: gasPrice,
|
||||
value: balance.sub(21000 * gasPrice)
|
||||
value: 123
|
||||
});
|
||||
|
||||
await tx.wait();
|
||||
|
||||
balance = await provider.getBalance(wallet.address);
|
||||
assert.ok(balance.eq(ethers.constants.Zero), "balance is zero after after sweeping");
|
||||
|
||||
await waiter(delay);
|
||||
});
|
||||
const b1 = await provider.getBalance(wallet.address);
|
||||
assert.ok(b0.gt(b1), "balance is decreased");
|
||||
}
|
||||
});
|
||||
|
||||
describe("Test Provider Methods", function() {
|
||||
let fundReceipt: Promise<ethers.providers.TransactionReceipt> = null;
|
||||
const faucet = "0x8210357f377E901f18E45294e86a2A32215Cc3C9";
|
||||
|
||||
// Obviously many more cases to add here
|
||||
// - getTransactionCount
|
||||
// - getBlockNumber
|
||||
// - getGasPrice
|
||||
// - estimateGas
|
||||
// - sendTransaction
|
||||
// - call
|
||||
// - getLogs
|
||||
//
|
||||
// Many of these are tLegacyParametersested in run-providers, which uses nodeunit, but
|
||||
// also creates a local private key which must then be funded to
|
||||
// execute the tests. I am working on a better test contract to deploy
|
||||
// to all the networks to help test these.
|
||||
before(async function() {
|
||||
// Get some ether from the faucet
|
||||
const provider = ethers.getDefaultProvider("ropsten");
|
||||
const funder = await ethers.utils.fetchJson(`https:/\/api.ethers.io/api/v1/?action=fundAccount&address=${ fundWallet.address.toLowerCase() }`);
|
||||
fundReceipt = provider.waitForTransaction(funder.hash);
|
||||
fundReceipt.then((receipt) => {
|
||||
console.log(`*** Funded: ${ fundWallet.address }`);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
["default", "homestead", "ropsten", "rinkeby", "kovan", "goerli"].forEach(function(networkName) {
|
||||
["getDefaultProvider", "AlchemyProvider", "CloudflareProvider", "InfuraProvider", "EtherscanProvider", "NodesmithProvider", "Web3Provider"].forEach(function(providerName) {
|
||||
if (providerName === "NodesmithProvider") { return; }
|
||||
if (providerName === "CloudflareProvider") { return; }
|
||||
if (providerName === "Web3Provider") { return; }
|
||||
after(async function() {
|
||||
// Wait until the funding is complete
|
||||
await fundReceipt;
|
||||
|
||||
if ((networkName !== "homestead" && networkName !== "default") && providerName === "CloudflareProvider") {
|
||||
// Refund all unused ether to the faucet
|
||||
const provider = ethers.getDefaultProvider("ropsten");
|
||||
const gasPrice = await provider.getGasPrice();
|
||||
const balance = await provider.getBalance(fundWallet.address);
|
||||
fundWallet.connect(provider).sendTransaction({
|
||||
to: faucet,
|
||||
gasLimit: 21000,
|
||||
gasPrice: gasPrice,
|
||||
value: balance.sub(gasPrice.mul(21000))
|
||||
});
|
||||
});
|
||||
|
||||
providerFunctions.forEach(({ name, networks, create}) => {
|
||||
|
||||
networks.forEach((network) => {
|
||||
const provider = create(network);
|
||||
|
||||
testFunctions.forEach((test) => {
|
||||
|
||||
// Skip tests not supported on this network
|
||||
if (test.networks.indexOf(network) === -1) { return; }
|
||||
if (test.checkSkip && test.checkSkip(name, network, test)) {
|
||||
return;
|
||||
}
|
||||
|
||||
testProvider(providerName, networkName);
|
||||
// How many attempts to try?
|
||||
const attempts = (test.attempts != null) ? test.attempts: 3;
|
||||
const timeout = (test.timeout != null) ? test.timeout: 60;
|
||||
const extras = (test.extras || []).reduce((accum, key) => {
|
||||
accum[key] = true;
|
||||
return accum;
|
||||
}, <{ [ key: string ]: boolean }>{ });
|
||||
|
||||
it(`${ name }.${ network ? network: "default" } ${ test.name}`, async function() {
|
||||
this.timeout(timeout * 1000 * attempts);
|
||||
|
||||
// Wait for the funding transaction to be mined
|
||||
if (extras.funding) { await fundReceipt; }
|
||||
|
||||
// We wait at least 1 seconds between tests
|
||||
if (!extras.nowait) { await waiter(1000); }
|
||||
|
||||
let error: Error = null;
|
||||
for (let attempt = 0; attempt < attempts; attempt++) {
|
||||
try {
|
||||
return await Promise.race([
|
||||
test.execute(provider),
|
||||
waiter(timeout * 1000).then((resolve) => { throw new Error("timeout"); })
|
||||
]);
|
||||
} catch (attemptError) {
|
||||
console.log(`*** Failed attempt ${ attempt + 1 }: ${ attemptError.message }`);
|
||||
error = attemptError;
|
||||
}
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
/*
|
||||
@ -720,7 +794,7 @@ describe("Test extra Etherscan operations", function() {
|
||||
*/
|
||||
|
||||
describe("Test Basic Authentication", function() {
|
||||
this.retries(3);
|
||||
//this.retries(3);
|
||||
|
||||
// https://stackoverflow.com/questions/6509278/authentication-test-servers#16756383
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user