mirror of https://github.com/embarklabs/embark.git
feat(@embark/test-runner): make vm default node (#1846)
* feat: make vm default node * feat(@embark/tests): enable switching node between tests
This commit is contained in:
parent
2f9d5e6085
commit
f54fbf0b3d
|
@ -5,7 +5,7 @@ let accounts;
|
||||||
|
|
||||||
// For documentation please see https://embark.status.im/docs/contracts_testing.html
|
// For documentation please see https://embark.status.im/docs/contracts_testing.html
|
||||||
config({
|
config({
|
||||||
//deployment: {
|
//blockchain: {
|
||||||
// accounts: [
|
// accounts: [
|
||||||
// // you can configure custom accounts with a custom balance
|
// // you can configure custom accounts with a custom balance
|
||||||
// // see https://embark.status.im/docs/contracts_testing.html#Configuring-accounts
|
// // see https://embark.status.im/docs/contracts_testing.html#Configuring-accounts
|
||||||
|
@ -31,7 +31,7 @@ contract("SimpleStorage", function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("set storage value", async function () {
|
it("set storage value", async function () {
|
||||||
await SimpleStorage.methods.set(150).send();
|
await SimpleStorage.methods.set(150).send({from: web3.eth.defaultAccount});
|
||||||
let result = await SimpleStorage.methods.get().call();
|
let result = await SimpleStorage.methods.get().call();
|
||||||
assert.strictEqual(parseInt(result, 10), 150);
|
assert.strictEqual(parseInt(result, 10), 150);
|
||||||
});
|
});
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
"webpackDone": "webpackDone"
|
"webpackDone": "webpackDone"
|
||||||
},
|
},
|
||||||
"blockchain": {
|
"blockchain": {
|
||||||
|
"vm": "vm",
|
||||||
"call": "eth_call",
|
"call": "eth_call",
|
||||||
"clients": {
|
"clients": {
|
||||||
"geth": "geth",
|
"geth": "geth",
|
||||||
|
|
|
@ -708,9 +708,7 @@ simulator(_options) {
|
||||||
|
|
||||||
const Engine = require('../lib/core/engine.js');
|
const Engine = require('../lib/core/engine.js');
|
||||||
const engine = new Engine({
|
const engine = new Engine({
|
||||||
// TODO: this should not be necessary
|
env: options.env,
|
||||||
env: "development",
|
|
||||||
//env: options.env,
|
|
||||||
client: options.client,
|
client: options.client,
|
||||||
locale: options.locale,
|
locale: options.locale,
|
||||||
version: this.version,
|
version: this.version,
|
||||||
|
@ -743,23 +741,6 @@ simulator(_options) {
|
||||||
engine.registerModuleGroup("pipeline");
|
engine.registerModuleGroup("pipeline");
|
||||||
engine.registerModuleGroup("tests", options);
|
engine.registerModuleGroup("tests", options);
|
||||||
|
|
||||||
let plugin = engine.plugins.createPlugin('cmdcontrollerplugin', {});
|
|
||||||
plugin.registerActionForEvent("embark:engine:started", async (_params, cb) => {
|
|
||||||
try {
|
|
||||||
await engine.events.request2("blockchain:node:start", engine.config.blockchainConfig);
|
|
||||||
|
|
||||||
await Promise.all([
|
|
||||||
engine.events.request2("storage:node:start", engine.config.storageConfig),
|
|
||||||
engine.events.request2("communication:node:start", engine.config.communicationConfig),
|
|
||||||
engine.events.request2("namesystem:node:start", engine.config.namesystemConfig)
|
|
||||||
]);
|
|
||||||
} catch (e) {
|
|
||||||
return cb(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
cb();
|
|
||||||
});
|
|
||||||
|
|
||||||
engine.startEngine(next);
|
engine.startEngine(next);
|
||||||
},
|
},
|
||||||
function setupTestEnvironment(next) {
|
function setupTestEnvironment(next) {
|
||||||
|
|
|
@ -22,7 +22,7 @@ export function getBlockchainDefaults(env) {
|
||||||
wsHost: "localhost",
|
wsHost: "localhost",
|
||||||
wsPort: 8546,
|
wsPort: 8546,
|
||||||
networkType: "custom",
|
networkType: "custom",
|
||||||
miningMode: 'dev',
|
isDev: true,
|
||||||
nodiscover: true,
|
nodiscover: true,
|
||||||
maxpeers: 0,
|
maxpeers: 0,
|
||||||
targetGasLimit: 8000000,
|
targetGasLimit: 8000000,
|
||||||
|
|
|
@ -211,6 +211,7 @@ class Engine {
|
||||||
|
|
||||||
contractsComponents(_options) {
|
contractsComponents(_options) {
|
||||||
this.registerModule('ethereum-blockchain-client');
|
this.registerModule('ethereum-blockchain-client');
|
||||||
|
this.registerModule('ganache');
|
||||||
this.registerModulePackage('embark-web3');
|
this.registerModulePackage('embark-web3');
|
||||||
this.registerModulePackage('embark-accounts-manager');
|
this.registerModulePackage('embark-accounts-manager');
|
||||||
this.registerModulePackage('embark-specialconfigs', {plugins: this.plugins});
|
this.registerModulePackage('embark-specialconfigs', {plugins: this.plugins});
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import async from 'async';
|
import async from 'async';
|
||||||
const {__} = require('embark-i18n');
|
const {__} = require('embark-i18n');
|
||||||
|
const constants = require('embark-core/constants');
|
||||||
const Web3RequestManager = require('web3-core-requestmanager');
|
const Web3RequestManager = require('web3-core-requestmanager');
|
||||||
|
|
||||||
import BlockchainAPI from "./api";
|
import BlockchainAPI from "./api";
|
||||||
|
@ -12,7 +13,7 @@ class Blockchain {
|
||||||
this.blockchainConfig = embark.config.blockchainConfig;
|
this.blockchainConfig = embark.config.blockchainConfig;
|
||||||
this.contractConfig = embark.config.contractConfig;
|
this.contractConfig = embark.config.contractConfig;
|
||||||
this.blockchainApi = new BlockchainAPI(embark);
|
this.blockchainApi = new BlockchainAPI(embark);
|
||||||
|
this.startedClient = null;
|
||||||
|
|
||||||
embark.registerActionForEvent("pipeline:generateAll:before", this.addArtifactFile.bind(this));
|
embark.registerActionForEvent("pipeline:generateAll:before", this.addArtifactFile.bind(this));
|
||||||
|
|
||||||
|
@ -22,6 +23,16 @@ class Blockchain {
|
||||||
});
|
});
|
||||||
|
|
||||||
this.events.setCommandHandler("blockchain:node:start", async (blockchainConfig, cb) => {
|
this.events.setCommandHandler("blockchain:node:start", async (blockchainConfig, cb) => {
|
||||||
|
const self = this;
|
||||||
|
const clientName = blockchainConfig.client;
|
||||||
|
function started() {
|
||||||
|
self.startedClient = clientName;
|
||||||
|
self.events.emit("blockchain:started", clientName);
|
||||||
|
}
|
||||||
|
if (clientName === constants.blockchain.vm) {
|
||||||
|
started();
|
||||||
|
return cb();
|
||||||
|
}
|
||||||
const requestManager = new Web3RequestManager.Manager(blockchainConfig.endpoint);
|
const requestManager = new Web3RequestManager.Manager(blockchainConfig.endpoint);
|
||||||
|
|
||||||
const ogConsoleError = console.error;
|
const ogConsoleError = console.error;
|
||||||
|
@ -37,21 +48,52 @@ class Blockchain {
|
||||||
console.error = ogConsoleError;
|
console.error = ogConsoleError;
|
||||||
if (!err) {
|
if (!err) {
|
||||||
// Node is already started
|
// Node is already started
|
||||||
this.events.emit("blockchain:started");
|
started();
|
||||||
return cb(null, true);
|
return cb(null, true);
|
||||||
}
|
}
|
||||||
const clientName = blockchainConfig.client;
|
const clientFunctions = this.blockchainNodes[clientName];
|
||||||
const client = this.blockchainNodes[clientName];
|
if (!clientFunctions) {
|
||||||
if (!client) return cb("client " + clientName + " not found");
|
return cb(__("Client %s not found", clientName));
|
||||||
|
}
|
||||||
|
|
||||||
let onStart = () => {
|
let onStart = () => {
|
||||||
this.events.emit("blockchain:started", clientName);
|
started();
|
||||||
cb();
|
cb();
|
||||||
};
|
};
|
||||||
|
|
||||||
client.apply(client, [onStart]);
|
this.startedClient = clientName;
|
||||||
|
clientFunctions.launchFn.apply(clientFunctions, [onStart]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.events.setCommandHandler("blockchain:node:stop", (clientName, cb) => {
|
||||||
|
if (typeof clientName === 'function') {
|
||||||
|
if (!this.startedClient) {
|
||||||
|
return cb(__('No blockchain client is currently started'));
|
||||||
|
}
|
||||||
|
cb = clientName;
|
||||||
|
clientName = this.startedClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clientName === constants.blockchain.vm) {
|
||||||
|
this.startedClient = null;
|
||||||
|
this.events.emit("blockchain:stopped", clientName);
|
||||||
|
return cb();
|
||||||
|
}
|
||||||
|
|
||||||
|
const clientFunctions = this.blockchainNodes[clientName];
|
||||||
|
if (!clientFunctions) {
|
||||||
|
return cb(__("Client %s not found", clientName));
|
||||||
|
}
|
||||||
|
|
||||||
|
clientFunctions.stopFn.apply(clientFunctions, [
|
||||||
|
() => {
|
||||||
|
this.events.emit("blockchain:stopped", clientName);
|
||||||
|
cb();
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
this.startedClient = null;
|
||||||
|
});
|
||||||
this.blockchainApi.registerAPIs("ethereum");
|
this.blockchainApi.registerAPIs("ethereum");
|
||||||
this.blockchainApi.registerRequests("ethereum");
|
this.blockchainApi.registerRequests("ethereum");
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,10 @@ class EthereumBlockchainClient {
|
||||||
this.events.request("blockchain:client:register", "ethereum", this.getClient.bind(this));
|
this.events.request("blockchain:client:register", "ethereum", this.getClient.bind(this));
|
||||||
this.events.request("deployment:deployer:register", "ethereum", this.deployer.bind(this));
|
this.events.request("deployment:deployer:register", "ethereum", this.deployer.bind(this));
|
||||||
|
|
||||||
|
this.events.on("blockchain:started", () => {
|
||||||
|
this._web3 = null;
|
||||||
|
});
|
||||||
|
|
||||||
this.registerAPIRequests();
|
this.registerAPIRequests();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,23 +58,18 @@ class EthereumBlockchainClient {
|
||||||
|
|
||||||
async deployer(contract, done) {
|
async deployer(contract, done) {
|
||||||
const web3 = await this.web3;
|
const web3 = await this.web3;
|
||||||
// var web3 = new Web3("ws://localhost:8556")
|
const [account] = await web3.eth.getAccounts();
|
||||||
// web3.eth.getAccounts().then((accounts) => {
|
const contractObj = new web3.eth.Contract(contract.abiDefinition, contract.address);
|
||||||
let accounts = await web3.eth.getAccounts();
|
const contractObject = contractObj.deploy({arguments: (contract.args || []), data: ("0x" + contract.code)});
|
||||||
let account = accounts[0];
|
|
||||||
// let contractObject = this.blockchain.ContractObject({abi: contract.abiDefinition});
|
|
||||||
let contractObj = new web3.eth.Contract(contract.abiDefinition, contract.address);
|
|
||||||
// let deployObject = this.blockchain.deployContractObject(contractObject, {arguments: contractParams, data: dataCode});
|
|
||||||
let contractObject = contractObj.deploy({arguments: (contract.args || []), data: ("0x" + contract.code)});
|
|
||||||
|
|
||||||
if (contract.gas === 'auto' || !contract.gas) {
|
if (contract.gas === 'auto' || !contract.gas) {
|
||||||
let gasValue = await contractObject.estimateGas();
|
const gasValue = await contractObject.estimateGas();
|
||||||
let increase_per = 1 + (Math.random() / 10.0);
|
const increase_per = 1 + (Math.random() / 10.0);
|
||||||
contract.gas = Math.floor(gasValue * increase_per);
|
contract.gas = Math.floor(gasValue * increase_per);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!contract.gasPrice) {
|
if (!contract.gasPrice) {
|
||||||
let gasPrice = await web3.eth.getGasPrice();
|
const gasPrice = await web3.eth.getGasPrice();
|
||||||
contract.gasPrice = contract.gasPrice || gasPrice;
|
contract.gasPrice = contract.gasPrice || gasPrice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,8 +197,7 @@ class EthereumBlockchainClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
async determineAccounts(params, callback) {
|
async determineAccounts(params, callback) {
|
||||||
let provider = await this.events.request2("blockchain:client:provider", "ethereum");
|
const web3 = await this.web3;
|
||||||
let web3 = new Web3(provider);
|
|
||||||
let accounts = await web3.eth.getAccounts();
|
let accounts = await web3.eth.getAccounts();
|
||||||
let deploymentAccount = accounts[0];
|
let deploymentAccount = accounts[0];
|
||||||
let contract = params.contract;
|
let contract = params.contract;
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
class Ganache {
|
||||||
|
constructor(embark) {
|
||||||
|
embark.events.request('proxy:vm:register', () => {
|
||||||
|
const ganache = require('ganache-cli');
|
||||||
|
return ganache.provider();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Ganache;
|
|
@ -6,7 +6,6 @@ import {ws, rpc} from './check.js';
|
||||||
const constants = require('embark-core/constants');
|
const constants = require('embark-core/constants');
|
||||||
|
|
||||||
class Geth {
|
class Geth {
|
||||||
|
|
||||||
constructor(embark, options) {
|
constructor(embark, options) {
|
||||||
this.embark = embark;
|
this.embark = embark;
|
||||||
this.embarkConfig = embark.config.embarkConfig;
|
this.embarkConfig = embark.config.embarkConfig;
|
||||||
|
@ -23,22 +22,28 @@ class Geth {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.events.request("blockchain:node:register", constants.blockchain.clients.geth, (readyCb) => {
|
this.events.request("blockchain:node:register", constants.blockchain.clients.geth, {
|
||||||
this.events.request('processes:register', 'blockchain', {
|
launchFn: (readyCb) => {
|
||||||
launchFn: (cb) => {
|
this.events.request('processes:register', 'blockchain', {
|
||||||
this.startBlockchainNode(cb);
|
launchFn: (cb) => {
|
||||||
},
|
this.startBlockchainNode(cb);
|
||||||
stopFn: (cb) => {
|
},
|
||||||
this.stopBlockchainNode(cb);
|
stopFn: (cb) => {
|
||||||
}
|
this.stopBlockchainNode(cb);
|
||||||
});
|
}
|
||||||
this.events.request("processes:launch", "blockchain", (err) => {
|
});
|
||||||
if (err) {
|
this.events.request("processes:launch", "blockchain", (err) => {
|
||||||
this.logger.error(`Error launching blockchain process: ${err.message || err}`);
|
if (err) {
|
||||||
}
|
this.logger.error(`Error launching blockchain process: ${err.message || err}`);
|
||||||
readyCb();
|
}
|
||||||
});
|
readyCb();
|
||||||
this.registerServiceCheck();
|
});
|
||||||
|
this.registerServiceCheck();
|
||||||
|
},
|
||||||
|
stopFn: async (cb) => {
|
||||||
|
await this.events.request("processes:stop", "blockchain");
|
||||||
|
cb();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.events.request("whisper:node:register", constants.blockchain.clients.geth, readyCb => {
|
this.events.request("whisper:node:register", constants.blockchain.clients.geth, readyCb => {
|
||||||
|
|
|
@ -34,6 +34,10 @@ export default class AccountsManager {
|
||||||
this.embark.registerActionForEvent("blockchain:proxy:request", this.checkBlockchainRequest.bind(this));
|
this.embark.registerActionForEvent("blockchain:proxy:request", this.checkBlockchainRequest.bind(this));
|
||||||
this.embark.registerActionForEvent("blockchain:proxy:response", this.checkBlockchainResponse.bind(this));
|
this.embark.registerActionForEvent("blockchain:proxy:response", this.checkBlockchainResponse.bind(this));
|
||||||
|
|
||||||
|
this.events.on("blockchain:started", () => {
|
||||||
|
this._web3 = null;
|
||||||
|
});
|
||||||
|
|
||||||
// Allow to run transaction in parallel by resolving the nonce manually.
|
// Allow to run transaction in parallel by resolving the nonce manually.
|
||||||
// For each transaction, resolve the nonce by taking the max of current transaction count and the cache we keep locally.
|
// For each transaction, resolve the nonce by taking the max of current transaction count and the cache we keep locally.
|
||||||
// Update the nonce and sign it
|
// Update the nonce and sign it
|
||||||
|
|
|
@ -9,6 +9,10 @@ export default class DeploymentChecks {
|
||||||
this.events = events;
|
this.events = events;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this._web3 = null;
|
this._web3 = null;
|
||||||
|
|
||||||
|
this.events.on("blockchain:started", () => {
|
||||||
|
this._web3 = null;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get web3() {
|
get web3() {
|
||||||
|
|
|
@ -17,6 +17,10 @@ export default class TrackingFunctions {
|
||||||
this._block = null;
|
this._block = null;
|
||||||
|
|
||||||
this.ensureChainTrackerFile();
|
this.ensureChainTrackerFile();
|
||||||
|
|
||||||
|
this.events.on("blockchain:started", () => {
|
||||||
|
this._web3 = null;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get web3() {
|
get web3() {
|
||||||
|
|
|
@ -84,6 +84,10 @@ class ENS {
|
||||||
setImmediate(cb, this.isENSName(name));
|
setImmediate(cb, this.isENSName(name));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.events.on("blockchain:started", () => {
|
||||||
|
this._web3 = null;
|
||||||
|
});
|
||||||
|
|
||||||
this.init(() => {});
|
this.init(() => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,14 @@
|
||||||
},
|
},
|
||||||
"extends": "../../../.eslintrc.json"
|
"extends": "../../../.eslintrc.json"
|
||||||
},
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime-corejs2": "7.3.1",
|
||||||
|
"async": "3.1.0",
|
||||||
|
"embark-i18n": "^4.1.1",
|
||||||
|
"embark-utils": "^4.1.1",
|
||||||
|
"mocha": "6.2.0",
|
||||||
|
"web3": "1.2.1"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/cli": "7.2.3",
|
"@babel/cli": "7.2.3",
|
||||||
"@babel/core": "7.2.2",
|
"@babel/core": "7.2.2",
|
||||||
|
@ -60,12 +68,7 @@
|
||||||
"tslint": "5.16.0",
|
"tslint": "5.16.0",
|
||||||
"typescript": "3.4.5"
|
"typescript": "3.4.5"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
|
||||||
"async": "2.6.1",
|
|
||||||
"embarkjs": "^4.1.1",
|
"embarkjs": "^4.1.1",
|
||||||
"mocha": "6.2.0",
|
|
||||||
"web3": "1.2.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8.12.0 <12.0.0",
|
"node": ">=8.12.0 <12.0.0",
|
||||||
"npm": ">=6.4.1",
|
"npm": ">=6.4.1",
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import {__} from 'embark-i18n';
|
||||||
|
|
||||||
const assert = require('assert').strict;
|
const assert = require('assert').strict;
|
||||||
const async = require('async');
|
const async = require('async');
|
||||||
const EmbarkJS = require('embarkjs');
|
const EmbarkJS = require('embarkjs');
|
||||||
|
@ -14,8 +16,12 @@ class MochaTestRunner {
|
||||||
this.embark = embark;
|
this.embark = embark;
|
||||||
this.events = embark.events;
|
this.events = embark.events;
|
||||||
this.plugins = options.plugins;
|
this.plugins = options.plugins;
|
||||||
|
this.logger = embark.logger;
|
||||||
|
this.fs = embark.fs;
|
||||||
|
|
||||||
this.files = [];
|
this.files = [];
|
||||||
|
this.options = {};
|
||||||
|
this.web3 = null;
|
||||||
|
|
||||||
this.events.request('tests:runner:register',
|
this.events.request('tests:runner:register',
|
||||||
'JavaScript (Mocha)',
|
'JavaScript (Mocha)',
|
||||||
|
@ -37,20 +43,31 @@ class MochaTestRunner {
|
||||||
return JAVASCRIPT_TEST_MATCH.test(path);
|
return JAVASCRIPT_TEST_MATCH.test(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
run(options, cb) {
|
async run(options, cb) {
|
||||||
const {events, plugins} = this;
|
const {events} = this.embark;
|
||||||
const {reporter} = options;
|
const {reporter} = options;
|
||||||
|
this.options = options;
|
||||||
|
|
||||||
const Module = require("module");
|
const Module = require("module");
|
||||||
const originalRequire = require("module").prototype.require;
|
const originalRequire = require("module").prototype.require;
|
||||||
|
|
||||||
let accounts = [];
|
let accounts = [];
|
||||||
let compiledContracts = {};
|
let compiledContracts = {};
|
||||||
let web3;
|
|
||||||
|
|
||||||
const config = (cfg, acctCb) => {
|
const config = (cfg, acctCb) => {
|
||||||
global.before((done) => {
|
global.before((done) => {
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
|
(next) => {
|
||||||
|
events.request("tests:deployment:check", cfg, this.options, (err, provider) => {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
if (provider) {
|
||||||
|
this.web3.setProvider(provider);
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
},
|
||||||
(next) => {
|
(next) => {
|
||||||
events.request("contracts:build", cfg, compiledContracts, next);
|
events.request("contracts:build", cfg, compiledContracts, next);
|
||||||
},
|
},
|
||||||
|
@ -86,6 +103,12 @@ class MochaTestRunner {
|
||||||
}
|
}
|
||||||
|
|
||||||
next();
|
next();
|
||||||
|
},
|
||||||
|
(next) => {
|
||||||
|
this.web3.eth.getAccounts((err, accts) => {
|
||||||
|
accounts = accts;
|
||||||
|
next(err);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
], (err) => {
|
], (err) => {
|
||||||
// Reset the gas accumulator so that we don't show deployment gas on the
|
// Reset the gas accumulator so that we don't show deployment gas on the
|
||||||
|
@ -102,73 +125,79 @@ class MochaTestRunner {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const provider = await this.events.request2("tests:blockchain:start", this.options);
|
||||||
|
this.web3 = new Web3(provider);
|
||||||
|
accounts = await this.web3.eth.getAccounts();
|
||||||
|
await events.request2("contracts:reset");
|
||||||
|
let contractFiles = await events.request2("config:contractsFiles");
|
||||||
|
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
(next) => { // request provider
|
(next) => {
|
||||||
events.request("blockchain:client:provider", "ethereum", next);
|
this.plugins.emitAndRunActionsForEvent('tests:contracts:compile:before', contractFiles, next);
|
||||||
},
|
},
|
||||||
(provider, next) => { // set provider and fetch account list
|
(_contractFiles, next) => {
|
||||||
web3 = new Web3(provider);
|
contractFiles = _contractFiles;
|
||||||
web3.eth.getAccounts(next);
|
events.request("compiler:contracts:compile", _contractFiles, next);
|
||||||
},
|
},
|
||||||
(accts, next) => { // reset contracts as we might have state leakage from other plugins
|
(_compiledContracts, next) => {
|
||||||
accounts = accts;
|
this.plugins.emitAndRunActionsForEvent('tests:contracts:compile:after', _compiledContracts, next);
|
||||||
events.request("contracts:reset", next);
|
|
||||||
},
|
},
|
||||||
(next) => { // get contract files
|
(_compiledContracts, next) => {
|
||||||
events.request("config:contractsFiles", next);
|
compiledContracts = _compiledContracts;
|
||||||
},
|
const fns = this.files.map((file) => {
|
||||||
(cf, next) => {
|
return (seriesCb) => {
|
||||||
plugins.emitAndRunActionsForEvent('tests:contracts:compile:before', cf, next);
|
|
||||||
},
|
|
||||||
(cf, next) => { // compile contracts
|
|
||||||
events.request("compiler:contracts:compile", cf, next);
|
|
||||||
},
|
|
||||||
(cc, next) => {
|
|
||||||
plugins.emitAndRunActionsForEvent('tests:contracts:compile:after', cc, next);
|
|
||||||
},
|
|
||||||
(cc, next) => { // override require
|
|
||||||
compiledContracts = cc;
|
|
||||||
|
|
||||||
Module.prototype.require = function(req) {
|
this.fs.readFile(file, (err, data) => {
|
||||||
const prefix = "Embark/contracts/";
|
if (err) {
|
||||||
if (!req.startsWith(prefix)) {
|
self.logger.error(__('Error reading file %s', file));
|
||||||
return originalRequire.apply(this, arguments);
|
self.logger.error(err);
|
||||||
}
|
seriesCb(null, 1);
|
||||||
|
}
|
||||||
|
if (data.toString().search(/contract\(|describe\(/) === -1) {
|
||||||
|
return seriesCb(null, 0);
|
||||||
|
}
|
||||||
|
|
||||||
const contractClass = req.replace(prefix, "");
|
Module.prototype.require = function(req) {
|
||||||
const instance = compiledContracts[contractClass];
|
const prefix = "Embark/contracts/";
|
||||||
|
if (!req.startsWith(prefix)) {
|
||||||
|
return originalRequire.apply(this, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
if (!instance) {
|
const contractClass = req.replace(prefix, "");
|
||||||
throw new Error(`Cannot find module '${req}'`);
|
const instance = compiledContracts[contractClass];
|
||||||
}
|
|
||||||
|
|
||||||
return instance;
|
if (!instance) {
|
||||||
};
|
throw new Error(`Cannot find module '${req}'`);
|
||||||
next();
|
}
|
||||||
},
|
return instance;
|
||||||
(next) => { // initialize Mocha
|
};
|
||||||
const mocha = new Mocha();
|
|
||||||
|
|
||||||
mocha.reporter(Reporter, { reporter: reporter });
|
const mocha = new Mocha();
|
||||||
const describeWithAccounts = (scenario, cb) => {
|
mocha.reporter(Reporter, {reporter: options.reporter});
|
||||||
Mocha.describe(scenario, cb.bind(mocha, accounts));
|
const describeWithAccounts = (scenario, cb) => {
|
||||||
};
|
Mocha.describe(scenario, cb.bind(mocha, accounts));
|
||||||
|
};
|
||||||
|
|
||||||
mocha.suite.on('pre-require', () => {
|
mocha.suite.on('pre-require', () => {
|
||||||
global.describe = describeWithAccounts;
|
global.describe = describeWithAccounts;
|
||||||
global.contract = describeWithAccounts;
|
global.contract = describeWithAccounts;
|
||||||
global.assert = assert;
|
global.assert = assert;
|
||||||
global.config = config;
|
global.config = config;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
mocha.suite.timeout(TEST_TIMEOUT);
|
||||||
|
mocha.addFile(file);
|
||||||
|
|
||||||
|
mocha.run((failures) => {
|
||||||
|
Module.prototype.require = originalRequire;
|
||||||
|
seriesCb(null, failures);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
mocha.suite.timeout(TEST_TIMEOUT);
|
async.series(fns, next);
|
||||||
for(const file of this.files) {
|
|
||||||
mocha.addFile(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
mocha.run((_failures) => {
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
], (err) => {
|
], (err) => {
|
||||||
events.emit('tests:finished');
|
events.emit('tests:finished');
|
||||||
|
|
|
@ -10,6 +10,9 @@ class TransactionTracker {
|
||||||
this._web3 = null;
|
this._web3 = null;
|
||||||
|
|
||||||
embark.events.on("block:header", this.onBlockHeader.bind(this));
|
embark.events.on("block:header", this.onBlockHeader.bind(this));
|
||||||
|
this.events.on("blockchain:started", () => {
|
||||||
|
this._web3 = null;
|
||||||
|
});
|
||||||
this.registerAPICalls();
|
this.registerAPICalls();
|
||||||
this.subscribeToPendingTransactions();
|
this.subscribeToPendingTransactions();
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,11 +40,6 @@ class EmbarkWeb3 {
|
||||||
}
|
}
|
||||||
|
|
||||||
async registerWeb3Object() {
|
async registerWeb3Object() {
|
||||||
const checkWeb3 = `return (typeof web3 === 'undefined');`;
|
|
||||||
const web3NotDefined = await this.events.request2('runcode:eval', checkWeb3);
|
|
||||||
|
|
||||||
if (!web3NotDefined) return;
|
|
||||||
|
|
||||||
const provider = await this.events.request2("blockchain:client:provider", "ethereum");
|
const provider = await this.events.request2("blockchain:client:provider", "ethereum");
|
||||||
const web3 = new Web3(provider);
|
const web3 = new Web3(provider);
|
||||||
await this.events.request2("runcode:register", 'web3', web3);
|
await this.events.request2("runcode:register", 'web3', web3);
|
||||||
|
|
|
@ -44,6 +44,10 @@ class ContractsManager {
|
||||||
cb(null, this.contracts[contract.className]);
|
cb(null, this.contracts[contract.className]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.events.on("blockchain:started", () => {
|
||||||
|
this._web3 = null;
|
||||||
|
});
|
||||||
|
|
||||||
this.registerCommands();
|
this.registerCommands();
|
||||||
this.registerAPIs();
|
this.registerAPIs();
|
||||||
}
|
}
|
||||||
|
@ -262,6 +266,9 @@ class ContractsManager {
|
||||||
function prepareContractsFromConfig(callback) {
|
function prepareContractsFromConfig(callback) {
|
||||||
self.events.emit("status", __("Building..."));
|
self.events.emit("status", __("Building..."));
|
||||||
|
|
||||||
|
if (contractsConfig.contracts.deploy) {
|
||||||
|
contractsConfig.contracts = contractsConfig.contracts.deploy;
|
||||||
|
}
|
||||||
async.eachOf(contractsConfig.contracts, (contract, className, eachCb) => {
|
async.eachOf(contractsConfig.contracts, (contract, className, eachCb) => {
|
||||||
contract = new Contract(self.logger, contract);
|
contract = new Contract(self.logger, contract);
|
||||||
if (!contract.artifact) {
|
if (!contract.artifact) {
|
||||||
|
|
|
@ -13,7 +13,6 @@ class ContractDeployer {
|
||||||
}
|
}
|
||||||
|
|
||||||
deployContract(contract, callback) {
|
deployContract(contract, callback) {
|
||||||
|
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
(next) => {
|
(next) => {
|
||||||
this.plugins.emitAndRunActionsForEvent('deployment:contract:beforeDeploy', {contract: contract}, (err, _params) => {
|
this.plugins.emitAndRunActionsForEvent('deployment:contract:beforeDeploy', {contract: contract}, (err, _params) => {
|
||||||
|
@ -22,7 +21,6 @@ class ContractDeployer {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
(next) => {
|
(next) => {
|
||||||
// self.plugins.emitAndRunActionsForEvent('deployment:contract:arguments', {contract: contract}, (_params) => {
|
|
||||||
this.plugins.emitAndRunActionsForEvent('deployment:contract:shouldDeploy', {contract: contract, shouldDeploy: true}, (err, params) => {
|
this.plugins.emitAndRunActionsForEvent('deployment:contract:shouldDeploy', {contract: contract, shouldDeploy: true}, (err, params) => {
|
||||||
next(err, params);
|
next(err, params);
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,26 +11,29 @@ export default class ProxyManager {
|
||||||
private proxy: any;
|
private proxy: any;
|
||||||
private plugins: any;
|
private plugins: any;
|
||||||
private readonly host: string;
|
private readonly host: string;
|
||||||
private rpcPort: number;
|
private rpcPort = 0;
|
||||||
private wsPort: number;
|
private wsPort = 0;
|
||||||
private ready: boolean;
|
private ready = false;
|
||||||
private isWs = false;
|
private isWs = false;
|
||||||
|
private vms: any[];
|
||||||
|
|
||||||
constructor(private embark: Embark, options: any) {
|
constructor(private embark: Embark, options: any) {
|
||||||
this.logger = embark.logger;
|
this.logger = embark.logger;
|
||||||
this.events = embark.events;
|
this.events = embark.events;
|
||||||
this.plugins = options.plugins;
|
this.plugins = options.plugins;
|
||||||
this.ready = false;
|
this.vms = [];
|
||||||
this.rpcPort = 0;
|
|
||||||
this.wsPort = 0;
|
|
||||||
|
|
||||||
this.host = "localhost";
|
this.host = "localhost";
|
||||||
|
|
||||||
this.events.once("blockchain:started", async () => {
|
this.events.on("blockchain:started", async (clientName: string) => {
|
||||||
await this.setupProxy();
|
await this.setupProxy(clientName);
|
||||||
this.ready = true;
|
this.ready = true;
|
||||||
this.events.emit("proxy:ready");
|
this.events.emit("proxy:ready");
|
||||||
});
|
});
|
||||||
|
this.events.on("blockchain:stopped", async (clientName: string, node?: string) => {
|
||||||
|
this.ready = false;
|
||||||
|
await this.stopProxy();
|
||||||
|
});
|
||||||
|
|
||||||
if (!this.embark.config.blockchainConfig.proxy) {
|
if (!this.embark.config.blockchainConfig.proxy) {
|
||||||
this.logger.warn(__("The proxy has been disabled -- some Embark features will not work."));
|
this.logger.warn(__("The proxy has been disabled -- some Embark features will not work."));
|
||||||
|
@ -48,6 +51,10 @@ export default class ProxyManager {
|
||||||
}
|
}
|
||||||
cb(null, buildUrl("http", this.host, this.rpcPort, "rpc"));
|
cb(null, buildUrl("http", this.host, this.rpcPort, "rpc"));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.events.setCommandHandler("proxy:vm:register", (handler: any) => {
|
||||||
|
this.vms.push(handler);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public onReady() {
|
public onReady() {
|
||||||
|
@ -61,23 +68,31 @@ export default class ProxyManager {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async setupProxy() {
|
private async setupProxy(clientName: string) {
|
||||||
if (!this.embark.config.blockchainConfig.proxy) {
|
if (!this.embark.config.blockchainConfig.proxy) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (this.proxy) {
|
||||||
|
throw new Error("Proxy is already started");
|
||||||
|
}
|
||||||
const port = await findNextPort(this.embark.config.blockchainConfig.rpcPort + constants.blockchain.servicePortOnProxy);
|
const port = await findNextPort(this.embark.config.blockchainConfig.rpcPort + constants.blockchain.servicePortOnProxy);
|
||||||
|
|
||||||
this.rpcPort = port;
|
this.rpcPort = port;
|
||||||
this.wsPort = port + 1;
|
this.wsPort = port + 1;
|
||||||
this.isWs = (/wss?/).test(this.embark.config.blockchainConfig.endpoint);
|
this.isWs = clientName === constants.blockchain.vm || (/wss?/).test(this.embark.config.blockchainConfig.endpoint);
|
||||||
|
|
||||||
this.proxy = await new Proxy({events: this.events, plugins: this.plugins, logger: this.logger})
|
this.proxy = await new Proxy({events: this.events, plugins: this.plugins, logger: this.logger, vms: this.vms});
|
||||||
.serve(
|
|
||||||
this.embark.config.blockchainConfig.endpoint,
|
await this.proxy.serve(
|
||||||
this.host,
|
clientName === constants.blockchain.vm ? constants.blockchain.vm : this.embark.config.blockchainConfig.endpoint,
|
||||||
this.isWs ? this.wsPort : this.rpcPort,
|
this.host,
|
||||||
this.isWs,
|
this.isWs ? this.wsPort : this.rpcPort,
|
||||||
);
|
this.isWs,
|
||||||
return;
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private stopProxy() {
|
||||||
|
this.proxy.stop();
|
||||||
|
this.proxy = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import express from 'express';
|
||||||
import expressWs from 'express-ws';
|
import expressWs from 'express-ws';
|
||||||
import cors from 'cors';
|
import cors from 'cors';
|
||||||
const Web3RequestManager = require('web3-core-requestmanager');
|
const Web3RequestManager = require('web3-core-requestmanager');
|
||||||
|
const constants = require("embark-core/constants");
|
||||||
|
|
||||||
const ACTION_TIMEOUT = 5000;
|
const ACTION_TIMEOUT = 5000;
|
||||||
|
|
||||||
|
@ -15,9 +16,15 @@ export class Proxy {
|
||||||
this.timeouts = {};
|
this.timeouts = {};
|
||||||
this.plugins = options.plugins;
|
this.plugins = options.plugins;
|
||||||
this.logger = options.logger;
|
this.logger = options.logger;
|
||||||
|
this.vms = options.vms;
|
||||||
|
this.app = null;
|
||||||
|
this.server = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async serve(endpoint, localHost, localPort, ws) {
|
async serve(endpoint, localHost, localPort, ws) {
|
||||||
|
if (endpoint === constants.blockchain.vm) {
|
||||||
|
endpoint = this.vms[this.vms.length - 1]();
|
||||||
|
}
|
||||||
const requestManager = new Web3RequestManager.Manager(endpoint);
|
const requestManager = new Web3RequestManager.Manager(endpoint);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -26,17 +33,17 @@ export class Proxy {
|
||||||
throw new Error(__('Unable to connect to the blockchain endpoint'));
|
throw new Error(__('Unable to connect to the blockchain endpoint'));
|
||||||
}
|
}
|
||||||
|
|
||||||
const app = express();
|
this.app = express();
|
||||||
if (ws) {
|
if (ws) {
|
||||||
expressWs(app);
|
expressWs(this.app);
|
||||||
}
|
}
|
||||||
|
|
||||||
app.use(cors());
|
this.app.use(cors());
|
||||||
app.use(express.json());
|
this.app.use(express.json());
|
||||||
app.use(express.urlencoded({extended: true}));
|
this.app.use(express.urlencoded({extended: true}));
|
||||||
|
|
||||||
if (ws) {
|
if (ws) {
|
||||||
app.ws('/', (ws, _wsReq) => {
|
this.app.ws('/', (ws, _wsReq) => {
|
||||||
ws.on('message', (msg) => {
|
ws.on('message', (msg) => {
|
||||||
let jsonMsg;
|
let jsonMsg;
|
||||||
try {
|
try {
|
||||||
|
@ -50,7 +57,7 @@ export class Proxy {
|
||||||
// Send the possibly modified request to the Node
|
// Send the possibly modified request to the Node
|
||||||
requestManager.send(resp.reqData, (err, result) => {
|
requestManager.send(resp.reqData, (err, result) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return this.logger.error(__('Error executing the request on the Node'), JSON.stringify(err));
|
return this.logger.error(__('Error executing the request on the Node'), err.message || err);
|
||||||
}
|
}
|
||||||
this.emitActionsForResponse(resp.reqData, {jsonrpc: "2.0", id: resp.reqData.id, result}, (_err, resp) => {
|
this.emitActionsForResponse(resp.reqData, {jsonrpc: "2.0", id: resp.reqData.id, result}, (_err, resp) => {
|
||||||
// Send back to the caller (web3)
|
// Send back to the caller (web3)
|
||||||
|
@ -62,7 +69,7 @@ export class Proxy {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// HTTP
|
// HTTP
|
||||||
app.use((req, res) => {
|
this.app.use((req, res) => {
|
||||||
// Modify request
|
// Modify request
|
||||||
this.emitActionsForRequest(req.body, (_err, resp) => {
|
this.emitActionsForRequest(req.body, (_err, resp) => {
|
||||||
// Send the possibly modified request to the Node
|
// Send the possibly modified request to the Node
|
||||||
|
@ -80,9 +87,9 @@ export class Proxy {
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
app.listen(localPort, localHost, null,
|
this.server = this.app.listen(localPort, localHost, null,
|
||||||
() => {
|
() => {
|
||||||
resolve(app);
|
resolve(this.app);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -147,4 +154,17 @@ export class Proxy {
|
||||||
calledBack = true;
|
calledBack = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
if (!this.server) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.server.close();
|
||||||
|
this.server = null;
|
||||||
|
this.app = null;
|
||||||
|
this.commList = {};
|
||||||
|
this.receipts = {};
|
||||||
|
this.transactions = {};
|
||||||
|
this.timeouts = {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
import { __ } from 'embark-i18n';
|
import { __ } from 'embark-i18n';
|
||||||
|
import {buildUrl, deconstructUrl, recursiveMerge} from "embark-utils";
|
||||||
const async = require('async');
|
const async = require('async');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const { dappPath } = require('embark-utils');
|
const { dappPath } = require('embark-utils');
|
||||||
|
import cloneDeep from "lodash.clonedeep";
|
||||||
import { COVERAGE_GAS_LIMIT, GAS_LIMIT } from './constants';
|
import { COVERAGE_GAS_LIMIT, GAS_LIMIT } from './constants';
|
||||||
|
const constants = require('embark-core/constants');
|
||||||
|
|
||||||
const coverage = require('istanbul-lib-coverage');
|
const coverage = require('istanbul-lib-coverage');
|
||||||
const reporter = require('istanbul-lib-report');
|
const reporter = require('istanbul-lib-report');
|
||||||
|
@ -22,6 +25,10 @@ class TestRunner {
|
||||||
this.gasLimit = options.coverage ? COVERAGE_GAS_LIMIT : GAS_LIMIT;
|
this.gasLimit = options.coverage ? COVERAGE_GAS_LIMIT : GAS_LIMIT;
|
||||||
this.files = [];
|
this.files = [];
|
||||||
|
|
||||||
|
this.configObj = embark.config;
|
||||||
|
this.originalConfigObj = cloneDeep(embark.config);
|
||||||
|
this.simOptions = {};
|
||||||
|
|
||||||
this.events.setCommandHandler('tests:run', (options, callback) => {
|
this.events.setCommandHandler('tests:run', (options, callback) => {
|
||||||
this.run(options, callback);
|
this.run(options, callback);
|
||||||
});
|
});
|
||||||
|
@ -32,6 +39,9 @@ class TestRunner {
|
||||||
// like Jest tests and such.
|
// like Jest tests and such.
|
||||||
this.runners.unshift({pluginName, matchFn, addFn, runFn});
|
this.runners.unshift({pluginName, matchFn, addFn, runFn});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.events.setCommandHandler('tests:deployment:check', this.checkDeploymentOptions.bind(this));
|
||||||
|
this.events.setCommandHandler('tests:blockchain:start', this.startBlockchainNode.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
run(options, cb) {
|
run(options, cb) {
|
||||||
|
@ -65,7 +75,7 @@ class TestRunner {
|
||||||
});
|
});
|
||||||
|
|
||||||
async.series(runnerFns, next);
|
async.series(runnerFns, next);
|
||||||
},
|
}
|
||||||
], (err) => {
|
], (err) => {
|
||||||
reporter.footer();
|
reporter.footer();
|
||||||
|
|
||||||
|
@ -85,16 +95,16 @@ class TestRunner {
|
||||||
open(dappPath('coverage/index.html')).then(() => {
|
open(dappPath('coverage/index.html')).then(() => {
|
||||||
cb(err, reporter.passes, reporter.fails);
|
cb(err, reporter.passes, reporter.fails);
|
||||||
});
|
});
|
||||||
} catch(err) {
|
} catch(e) {
|
||||||
process.stdout.write(chalk`{red Coverage report could not be created:}\n{white ${err.message}}\n`);
|
process.stdout.write(chalk`{red Coverage report could not be created:}\n{white ${e.message}}\n`);
|
||||||
cb(err, reporter.passes, reporter.fails);
|
cb(e, reporter.passes, reporter.fails);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
generateCoverageReport() {
|
generateCoverageReport() {
|
||||||
const coveragePath = dappPath(".embark", "coverage.json");
|
const coveragePath = dappPath(".embark", "coverage.json");
|
||||||
const coverageMap = JSON.parse(fs.readFileSync(coveragePath));
|
const coverageMap = JSON.parse(this.fs.readFileSync(coveragePath));
|
||||||
const map = coverage.createCoverageMap(coverageMap);
|
const map = coverage.createCoverageMap(coverageMap);
|
||||||
const tree = reporter.summarizers.nested(map);
|
const tree = reporter.summarizers.nested(map);
|
||||||
|
|
||||||
|
@ -131,6 +141,77 @@ class TestRunner {
|
||||||
cb(null, [filePath]);
|
cb(null, [filePath]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async checkDeploymentOptions(config, options, cb = () => {}) {
|
||||||
|
let resetServices = false;
|
||||||
|
const blockchainConfig = config.blockchain || {};
|
||||||
|
let {host, port, type, protocol} = blockchainConfig.endpoint ? deconstructUrl(blockchainConfig.endpoint) : {};
|
||||||
|
const accounts = blockchainConfig.accounts;
|
||||||
|
|
||||||
|
if (host && port && !['rpc', 'ws'].includes(type)) {
|
||||||
|
return cb(__("contracts config error: unknown deployment type %s", type));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!type) {
|
||||||
|
type = constants.blockchain.vm;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (accounts || port !== this.simOptions.port || type !== this.simOptions.type || host !== this.simOptions.host) {
|
||||||
|
resetServices = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(this.simOptions, {host, port, type, protocol, accounts, client: config.blockchain && config.blockchain.client});
|
||||||
|
|
||||||
|
if (!resetServices) {
|
||||||
|
return cb();
|
||||||
|
}
|
||||||
|
|
||||||
|
const provider = await this.startBlockchainNode(options);
|
||||||
|
cb(null, provider);
|
||||||
|
return provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
async startBlockchainNode(options, cb = () => {}) {
|
||||||
|
let node = options.node;
|
||||||
|
if (!this.simOptions.host && (node && node === constants.blockchain.vm)) {
|
||||||
|
this.simOptions.type = constants.blockchain.vm;
|
||||||
|
this.simOptions.client = constants.blockchain.vm;
|
||||||
|
} else if (this.simOptions.host || (node && node !== constants.blockchain.vm)) {
|
||||||
|
let options = this.simOptions;
|
||||||
|
if (node && node !== constants.blockchain.vm) {
|
||||||
|
options = deconstructUrl(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!options.protocol) {
|
||||||
|
options.protocol = (options.type === "rpc") ? 'http' : 'ws';
|
||||||
|
}
|
||||||
|
Object.assign(this.simOptions, options);
|
||||||
|
node = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.configObj.blockchainConfig = recursiveMerge({}, this.originalConfigObj.blockchainConfig, {
|
||||||
|
endpoint: this.simOptions.host ? buildUrl(this.simOptions.protocol, this.simOptions.host, this.simOptions.port, this.simOptions.type) : null,
|
||||||
|
type: this.simOptions.type,
|
||||||
|
accounts: this.simOptions.accounts,
|
||||||
|
coverage: options.coverage
|
||||||
|
});
|
||||||
|
if (this.simOptions.client) {
|
||||||
|
this.configObj.blockchainConfig.client = this.simOptions.client;
|
||||||
|
}
|
||||||
|
this.logger.trace('Setting blockchain configs:', this.configObj.blockchainConfig);
|
||||||
|
await this.events.request2('config:blockchainConfig:set', this.configObj.blockchainConfig);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.events.request2("blockchain:node:stop");
|
||||||
|
} catch (e) {
|
||||||
|
// Nothing to do here, the node probably wasn't even started
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.events.request2("blockchain:node:start", this.configObj.blockchainConfig);
|
||||||
|
const provider = await this.events.request2("blockchain:client:provider", "ethereum");
|
||||||
|
cb(null, provider);
|
||||||
|
return provider;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = TestRunner;
|
module.exports = TestRunner;
|
||||||
|
|
Loading…
Reference in New Issue