feat: enable starting and switching storage configs in tests

This commit is contained in:
Jonathan Rainville 2019-07-12 12:51:56 -04:00
parent ba86c25b1e
commit ef5d451679
16 changed files with 285 additions and 166 deletions

View File

@ -50,7 +50,7 @@ module.exports = {
}, },
testnet: { testnet: {
networkType: "testnet", // Can be: testnet, rinkeby, livenet or custom, in which case, it will use the specified networkId networkType: "testnet", // Can be: testnet(ropsten), rinkeby, livenet or custom, in which case, it will use the specified networkId
syncMode: "light", syncMode: "light",
accounts: [ accounts: [
{ {

View File

@ -50,7 +50,7 @@ module.exports = {
}, },
testnet: { testnet: {
networkType: "testnet", // Can be: testnet, rinkeby, livenet or custom, in which case, it will use the specified networkId networkType: "testnet", // Can be: testnet(ropsten), rinkeby, livenet or custom, in which case, it will use the specified networkId
syncMode: "light", syncMode: "light",
accounts: [ accounts: [
{ {

View File

@ -39,9 +39,11 @@ module.exports = {
privateparitynet: { privateparitynet: {
client: "parity", client: "parity",
genesisBlock: "config/privatenet/genesis-parity.json", clientConfig: {
datadir: ".embark/privatenet/datadir", genesisBlock: "config/privatenet/genesis-parity.json",
miningMode: 'off' datadir: ".embark/privatenet/datadir",
miningMode: 'off'
}
}, },
externalnode: { externalnode: {
@ -56,7 +58,7 @@ module.exports = {
}, },
testnet: { testnet: {
networkType: "testnet", // Can be: testnet, rinkeby, livenet or custom, in which case, it will use the specified networkId networkType: "testnet", // Can be: testnet(ropsten), rinkeby, livenet or custom, in which case, it will use the specified networkId
syncMode: "light", syncMode: "light",
accounts: [ accounts: [
{ {

View File

@ -28,10 +28,7 @@ class CodeGenerator {
this.rpcHost = this.blockchainConfig.rpcHost || ''; this.rpcHost = this.blockchainConfig.rpcHost || '';
this.rpcPort = this.blockchainConfig.rpcPort || ''; this.rpcPort = this.blockchainConfig.rpcPort || '';
this.contractsConfig = embark.config.contractsConfig || {}; this.contractsConfig = embark.config.contractsConfig || {};
this.storageConfig = embark.config.storageConfig || {}; this.config = embark.config;
this.communicationConfig = embark.config.communicationConfig || {};
this.namesystemConfig = embark.config.namesystemConfig || {};
this.webServerConfig = embark.config.webServerConfig || {};
this.env = options.env || 'development'; this.env = options.env || 'development';
this.plugins = options.plugins; this.plugins = options.plugins;
this.events = embark.events; this.events = embark.events;
@ -240,31 +237,31 @@ class CodeGenerator {
} }
generateNamesInitialization(useEmbarkJS) { generateNamesInitialization(useEmbarkJS) {
if (!useEmbarkJS || this.namesystemConfig === {}) return ""; if (!useEmbarkJS || this.config.namesystemConfig === {}) return "";
let result = "\n"; let result = "\n";
result += Templates.define_when_env_loaded(); result += Templates.define_when_env_loaded();
result += this._getInitCode('names', this.namesystemConfig); result += this._getInitCode('names', this.config.namesystemConfig);
return result; return result;
} }
generateStorageInitialization(useEmbarkJS) { generateStorageInitialization(useEmbarkJS) {
if (!useEmbarkJS || this.storageConfig === {}) return ""; if (!useEmbarkJS || this.config.storageConfig === {}) return "";
let result = "\n"; let result = "\n";
result += Templates.define_when_env_loaded(); result += Templates.define_when_env_loaded();
result += this._getInitCode('storage', this.storageConfig); result += this._getInitCode('storage', this.config.storageConfig);
return result; return result;
} }
generateCommunicationInitialization(useEmbarkJS) { generateCommunicationInitialization(useEmbarkJS) {
if (!useEmbarkJS || this.communicationConfig === {}) return ""; if (!useEmbarkJS || this.config.communicationConfig === {}) return "";
let result = "\n"; let result = "\n";
result += Templates.define_when_env_loaded(); result += Templates.define_when_env_loaded();
result += this._getInitCode('communication', this.communicationConfig); result += this._getInitCode('communication', this.config.communicationConfig);
return result; return result;
} }
@ -438,10 +435,10 @@ class CodeGenerator {
getInitProviderCode() { getInitProviderCode() {
const codeTypes = { const codeTypes = {
blockchain: this.blockchainConfig || {}, blockchain: this.config.blockchainConfig || {},
communication: this.communicationConfig || {}, communication: this.config.communicationConfig || {},
names: this.namesystemConfig || {}, names: this.config.namesystemConfig || {},
storage: this.storageConfig || {} storage: this.config.storageConfig || {}
}; };
return this.plugins.getPluginsFor("initConsoleCode").reduce((acc, plugin) => { return this.plugins.getPluginsFor("initConsoleCode").reduce((acc, plugin) => {

View File

@ -150,6 +150,10 @@ export class ProcessManager {
self.events.setCommandHandler('processes:stop', (name, cb) => { self.events.setCommandHandler('processes:stop', (name, cb) => {
let process = self.processes[name]; let process = self.processes[name];
if (!process) {
// Process was never started
return cb();
}
cb = cb || function noop() {}; cb = cb || function noop() {};
if (![ProcessState.Running, ProcessState.Errored].includes(process.state)) { if (![ProcessState.Running, ProcessState.Errored].includes(process.state)) {
return cb(__(`The ${name} process is already ${process.state.toLowerCase()}.`)); return cb(__(`The ${name} process is already ${process.state.toLowerCase()}.`));

View File

@ -73,8 +73,7 @@ class ENS {
this.ensConfig = ensConfig; this.ensConfig = ensConfig;
this.configured = false; this.configured = false;
this.modulesPath = dappPath(embark.config.embarkConfig.generationDir, dappArtifacts.symlinkDir); this.modulesPath = dappPath(embark.config.embarkConfig.generationDir, dappArtifacts.symlinkDir);
this.consoleCmdsRegistered = false; this.initated = false;
this.eventsRegistered = false;
this.events.setCommandHandler("ens:resolve", this.ensResolve.bind(this)); this.events.setCommandHandler("ens:resolve", this.ensResolve.bind(this));
this.events.setCommandHandler("ens:isENSName", this.isENSName.bind(this)); this.events.setCommandHandler("ens:isENSName", this.isENSName.bind(this));
@ -88,7 +87,7 @@ class ENS {
} }
init(cb = () => {}) { init(cb = () => {}) {
if (this.config.namesystemConfig === {} || if (this.initated || this.config.namesystemConfig === {} ||
this.config.namesystemConfig.enabled !== true || this.config.namesystemConfig.enabled !== true ||
!this.config.namesystemConfig.available_providers || !this.config.namesystemConfig.available_providers ||
this.config.namesystemConfig.available_providers.indexOf('ens') < 0) { this.config.namesystemConfig.available_providers.indexOf('ens') < 0) {
@ -100,6 +99,7 @@ class ENS {
this.registerEvents(); this.registerEvents();
this.registerConsoleCommands(); this.registerConsoleCommands();
this.addENSToEmbarkJS(cb); this.addENSToEmbarkJS(cb);
this.initated = true;
} }
reset() { reset() {
@ -107,10 +107,6 @@ class ENS {
} }
registerConsoleCommands() { registerConsoleCommands() {
if (this.consoleCmdsRegistered) {
return;
}
this.consoleCmdsRegistered = true;
this.embark.registerConsoleCommand({ this.embark.registerConsoleCommand({
usage: 'resolve [name]', usage: 'resolve [name]',
description: __('Resolves an ENS name'), description: __('Resolves an ENS name'),
@ -153,10 +149,6 @@ class ENS {
} }
registerEvents() { registerEvents() {
if (this.eventsRegistered) {
return;
}
this.eventsRegistered = true;
this.embark.registerActionForEvent("deploy:beforeAll", this.configureContractsAndRegister.bind(this)); this.embark.registerActionForEvent("deploy:beforeAll", this.configureContractsAndRegister.bind(this));
this.events.on('blockchain:reseted', this.reset.bind(this)); this.events.on('blockchain:reseted', this.reset.bind(this));
this.events.setCommandHandler("storage:ens:associate", this.associateStorageToEns.bind(this)); this.events.setCommandHandler("storage:ens:associate", this.associateStorageToEns.bind(this));

View File

@ -13,7 +13,7 @@ class IPFS {
this.events = embark.events; this.events = embark.events;
this.buildDir = options.buildDir; this.buildDir = options.buildDir;
this.embarkConfig = embark.config.embarkConfig; this.embarkConfig = embark.config.embarkConfig;
this.storageConfig = embark.config.storageConfig; this.config = embark.config;
this.namesystemConfig = embark.config.namesystemConfig; this.namesystemConfig = embark.config.namesystemConfig;
this.embark = embark; this.embark = embark;
this.fs = embark.fs; this.fs = embark.fs;
@ -22,43 +22,63 @@ class IPFS {
this.storageProcessesLauncher = null; this.storageProcessesLauncher = null;
this.usingRunningNode = false; this.usingRunningNode = false;
this.modulesPath = dappPath(embark.config.embarkConfig.generationDir, constants.dappArtifacts.symlinkDir); this.modulesPath = dappPath(embark.config.embarkConfig.generationDir, constants.dappArtifacts.symlinkDir);
this.registered = false;
this.webServerConfig = embark.config.webServerConfig; this.webServerConfig = embark.config.webServerConfig;
this.blockchainConfig = embark.config.blockchainConfig; this.blockchainConfig = embark.config.blockchainConfig;
this.embark.events.setCommandHandler("module:ipfs:reset", (cb) => {
this.events.request("processes:stop", "ipfs", (err) => {
if (err) {
this.logger.error(__('Error stopping IPFS process'), err);
}
this.init(cb);
});
});
this.init();
}
init(callback = () => {}) {
if (!this.isIpfsStorageEnabledInTheConfig()) { if (!this.isIpfsStorageEnabledInTheConfig()) {
return this.events.emit("ipfs:process:started", null, false); this.events.emit("ipfs:process:started", null, false);
return callback();
}
if (!this.registered) {
this.registered = true;
this.setServiceCheck();
this.registerUploadCommand();
this.listenToCommands();
this.registerConsoleCommands();
this.events.request("processes:register", "ipfs", {
launchFn: (cb) => {
if(this.usingRunningNode) {
return cb(__("IPFS process is running in a separate process and cannot be started by Embark."));
}
this.startProcess((err, newProcessStarted) => {
this.addObjectToConsole();
this.events.emit("ipfs:process:started", err, newProcessStarted);
cb();
});
},
stopFn: (cb) => {
if(this.usingRunningNode) {
return cb(__("IPFS process is running in a separate process and cannot be stopped by Embark."));
}
this.stopProcess(cb);
}
});
} }
this.setServiceCheck();
this.registerUploadCommand();
this.listenToCommands();
this.registerConsoleCommands();
this.events.request("processes:register", "ipfs", {
launchFn: (cb) => {
if(this.usingRunningNode) {
return cb(__("IPFS process is running in a separate process and cannot be started by Embark."));
}
this.startProcess((err, newProcessStarted) => {
this.addObjectToConsole();
this.events.emit("ipfs:process:started", err, newProcessStarted);
cb();
});
},
stopFn: (cb) => {
if(this.usingRunningNode) {
return cb(__("IPFS process is running in a separate process and cannot be stopped by Embark."));
}
this.stopProcess(cb);
}
});
this.events.request("processes:launch", "ipfs", (err, msg) => { this.events.request("processes:launch", "ipfs", (err, msg) => {
if (err) { if (err) {
return this.logger.error(err); this.logger.error(err);
return callback(err);
} }
if (msg) { if (msg) {
this.logger.info(msg); this.logger.info(msg);
} }
callback();
}); });
// TODO: it will have the issue of waiting for the ipfs to start when the code is generator // TODO: it will have the issue of waiting for the ipfs to start when the code is generator
@ -110,11 +130,11 @@ class IPFS {
} }
_getNodeUrlConfig() { _getNodeUrlConfig() {
if (this.storageConfig.upload.provider === 'ipfs') { if (this.config.storageConfig.upload.provider === 'ipfs') {
return this.storageConfig.upload; return this.config.storageConfig.upload;
} }
for (let connection of this.storageConfig.dappConnection) { for (let connection of this.config.storageConfig.dappConnection) {
if (connection.provider === 'ipfs') { if (connection.provider === 'ipfs') {
return connection; return connection;
} }
@ -193,7 +213,7 @@ class IPFS {
this.storageProcessesLauncher = new StorageProcessesLauncher({ this.storageProcessesLauncher = new StorageProcessesLauncher({
logger: self.logger, logger: self.logger,
events: self.events, events: self.events,
storageConfig: self.storageConfig, storageConfig: self.config.storageConfig,
webServerConfig: self.webServerConfig, webServerConfig: self.webServerConfig,
blockchainConfig: self.blockchainConfig, blockchainConfig: self.blockchainConfig,
corsParts: self.embark.config.corsParts, corsParts: self.embark.config.corsParts,
@ -216,8 +236,8 @@ class IPFS {
this.embark.registerUploadCommand('ipfs', (cb) => { this.embark.registerUploadCommand('ipfs', (cb) => {
let upload_ipfs = new UploadIPFS({ let upload_ipfs = new UploadIPFS({
buildDir: self.buildDir || 'dist/', buildDir: self.buildDir || 'dist/',
storageConfig: self.storageConfig, storageConfig: self.config.storageConfig,
configIpfsBin: self.storageConfig.ipfs_bin || "ipfs", configIpfsBin: self.config.storageConfig.ipfs_bin || "ipfs",
env: this.embark.env env: this.embark.env
}); });
@ -253,7 +273,7 @@ class IPFS {
} }
isIpfsStorageEnabledInTheConfig() { isIpfsStorageEnabledInTheConfig() {
let {enabled, available_providers, dappConnection, upload} = this.storageConfig; let {enabled, available_providers, dappConnection, upload} = this.config.storageConfig;
return (enabled || this.embark.currentContext.includes(constants.contexts.upload)) && return (enabled || this.embark.currentContext.includes(constants.contexts.upload)) &&
( (
available_providers.includes('ipfs') && available_providers.includes('ipfs') &&

View File

@ -14,12 +14,15 @@ class Storage {
this.embark.events.once("module:storage:ready", cb); this.embark.events.once("module:storage:ready", cb);
}); });
this.embark.events.setCommandHandler("module:storage:reset", (cb) => { this.embark.events.setCommandHandler("module:storageJS:reset", (cb) => {
if (!this.isEnabled()) {
return cb();
}
this.ready = false; this.ready = false;
this.addSetProviders(cb); this.addSetProviders(cb);
}); });
if (!embark.config.storageConfig.enabled) { if (!this.isEnabled()) {
this.ready = true; this.ready = true;
return; return;
} }
@ -28,6 +31,10 @@ class Storage {
this.addSetProviders(() => {}); this.addSetProviders(() => {});
} }
isEnabled() {
return !!this.embark.config.storageConfig.enabled;
}
handleUploadCommand() { handleUploadCommand() {
const self = this; const self = this;
this.embark.events.setCommandHandler('storage:upload', (cb) => { this.embark.events.setCommandHandler('storage:upload', (cb) => {

View File

@ -13,9 +13,9 @@ class Swarm {
this.logger = embark.logger; this.logger = embark.logger;
this.events = embark.events; this.events = embark.events;
this.buildDir = embark.config.buildDir; this.buildDir = embark.config.buildDir;
this.storageConfig = embark.config.storageConfig; this.config = embark.config;
this.host = this.storageConfig.host; this.host = this.config.storageConfig.host;
this.port = this.storageConfig.port; this.port = this.config.storageConfig.port;
this.embark = embark; this.embark = embark;
this.fs = embark.fs; this.fs = embark.fs;
this.isServiceRegistered = false; this.isServiceRegistered = false;
@ -23,16 +23,32 @@ class Swarm {
this.storageProcessesLauncher = null; this.storageProcessesLauncher = null;
this.usingRunningNode = false; this.usingRunningNode = false;
this.modulesPath = dappPath(embark.config.embarkConfig.generationDir, constants.dappArtifacts.symlinkDir); this.modulesPath = dappPath(embark.config.embarkConfig.generationDir, constants.dappArtifacts.symlinkDir);
this.registered = false;
this.webServerConfig = embark.config.webServerConfig; this.webServerConfig = embark.config.webServerConfig;
this.blockchainConfig = embark.config.blockchainConfig; this.blockchainConfig = embark.config.blockchainConfig;
const cantDetermineUrl = this.storageConfig.upload.provider !== 'swarm' && !this.storageConfig.dappConnection.some(connection => connection.provider === 'swarm');
this.embark.events.setCommandHandler("module:swarm:reset", (cb) => {
this.events.request("processes:stop", "swarm", (err) => {
if (err) {
this.logger.error(__('Error stopping Swarm process'), err);
}
this.init(cb);
});
});
this.init();
}
init(callback = () => {}) {
const cantDetermineUrl = this.config.storageConfig.upload.provider !== 'swarm' && !this.config.storageConfig.dappConnection.some(connection => connection.provider === 'swarm');
if (this.isSwarmEnabledInTheConfig() && cantDetermineUrl) { if (this.isSwarmEnabledInTheConfig() && cantDetermineUrl) {
console.warn('\n===== Swarm module will not be loaded ====='); console.warn('\n===== Swarm module will not be loaded =====');
console.warn(`Swarm is enabled in the config, however the config is not setup to provide a URL for swarm and therefore the Swarm module will not be loaded. Please either change the ${'config/storage > upload'.bold} setting to Swarm or add the Swarm config to the ${'config/storage > dappConnection'.bold} array. Please see ${'https://embark.status.im/docs/storage_configuration.html'.underline} for more information.\n`); console.warn(`Swarm is enabled in the config, however the config is not setup to provide a URL for swarm and therefore the Swarm module will not be loaded. Please either change the ${'config/storage > upload'.bold} setting to Swarm or add the Swarm config to the ${'config/storage > dappConnection'.bold} array. Please see ${'https://embark.status.im/docs/storage_configuration.html'.underline} for more information.\n`);
return this.events.emit("swarm:process:started", null, false); this.events.emit("swarm:process:started", null, false);
return callback();
} }
if (!this.isSwarmEnabledInTheConfig()) { if (!this.isSwarmEnabledInTheConfig()) {
this.embark.registerConsoleCommand({ this.embark.registerConsoleCommand({
@ -42,44 +58,51 @@ class Swarm {
cb(); cb();
} }
}); });
return this.events.emit("swarm:process:started", null, false); this.events.emit("swarm:process:started", null, false);
return callback();
} }
this.providerUrl = buildUrl(this.storageConfig.upload.protocol, this.storageConfig.upload.host, this.storageConfig.upload.port); this.providerUrl = buildUrl(this.config.storageConfig.upload.protocol, this.config.storageConfig.upload.host, this.config.storageConfig.upload.port);
this.getUrl = this.storageConfig.upload.getUrl || this.providerUrl + '/bzz:/'; this.getUrl = this.config.storageConfig.upload.getUrl || this.providerUrl + '/bzz:/';
this.swarm = new SwarmAPI({gateway: this.providerUrl}); this.swarm = new SwarmAPI({gateway: this.providerUrl});
this.setServiceCheck(); if (!this.registered) {
this.registerUploadCommand(); this.registered = true;
this.listenToCommands(); this.setServiceCheck();
this.registerConsoleCommands(); this.registerUploadCommand();
this.events.request("processes:register", "swarm", { this.listenToCommands();
launchFn: (cb) => { this.registerConsoleCommands();
if(this.usingRunningNode) { this.events.request("processes:register", "swarm", {
return cb(__("Swarm process is running in a separate process and cannot be started by Embark.")); launchFn: (cb) => {
if(this.usingRunningNode) {
return cb(__("Swarm process is running in a separate process and cannot be started by Embark."));
}
this.startProcess((err, newProcessStarted) => {
this.addObjectToConsole();
this.events.emit("swarm:process:started", err, newProcessStarted);
cb();
});
},
stopFn: (cb) => {
if(this.usingRunningNode) {
return cb(__("Swarm process is running in a separate process and cannot be stopped by Embark."));
}
this.stopProcess(cb);
} }
this.startProcess((err, newProcessStarted) => { });
this.addObjectToConsole(); }
this.events.emit("swarm:process:started", err, newProcessStarted);
cb();
});
},
stopFn: (cb) => {
if(this.usingRunningNode) {
return cb(__("Swarm process is running in a separate process and cannot be stopped by Embark."));
}
this.stopProcess(cb);
}
});
this.events.request("processes:launch", "swarm", (err, msg) => { this.events.request("processes:launch", "swarm", (err, msg) => {
if (err) { if (err) {
return this.logger.error(err); this.logger.error(err);
return callback(err);
} }
if (msg) { if (msg) {
this.logger.info(msg); this.logger.info(msg);
} }
callback();
}); });
// TODO: it will have the issue of waiting for the ipfs to start when the code is generator // TODO: it will have the issue of waiting for the ipfs to start when the code is generator
@ -160,7 +183,7 @@ class Swarm {
this.storageProcessesLauncher = new StorageProcessesLauncher({ this.storageProcessesLauncher = new StorageProcessesLauncher({
logger: self.logger, logger: self.logger,
events: self.events, events: self.events,
storageConfig: self.storageConfig, storageConfig: self.config.storageConfig,
webServerConfig: self.webServerConfig, webServerConfig: self.webServerConfig,
corsParts: self.embark.config.corsParts, corsParts: self.embark.config.corsParts,
blockchainConfig: self.blockchainConfig, blockchainConfig: self.blockchainConfig,
@ -184,7 +207,7 @@ class Swarm {
this.embark.registerUploadCommand('swarm', (cb) => { this.embark.registerUploadCommand('swarm', (cb) => {
let upload_swarm = new UploadSwarm({ let upload_swarm = new UploadSwarm({
buildDir: self.buildDir || 'dist/', buildDir: self.buildDir || 'dist/',
storageConfig: self.storageConfig, storageConfig: self.config.storageConfig,
providerUrl: self.providerUrl, providerUrl: self.providerUrl,
swarm: self.swarm, swarm: self.swarm,
env: self.embark.env env: self.embark.env
@ -222,7 +245,7 @@ class Swarm {
} }
isSwarmEnabledInTheConfig() { isSwarmEnabledInTheConfig() {
let {enabled, available_providers, dappConnection, upload} = this.storageConfig; let {enabled, available_providers, dappConnection, upload} = this.config.storageConfig;
return (enabled || this.embark.currentContext.includes(constants.contexts.upload)) && return (enabled || this.embark.currentContext.includes(constants.contexts.upload)) &&
available_providers.includes('swarm') && available_providers.includes('swarm') &&
( (

View File

@ -1,6 +1,7 @@
import { __ } from 'embark-i18n'; import { __ } from 'embark-i18n';
import { deconstructUrl, prepareContractsConfig, buildUrl } from 'embark-utils'; import { deconstructUrl, prepareContractsConfig, buildUrl, recursiveMerge } from 'embark-utils';
import deepEqual from 'deep-equal'; import deepEqual from 'deep-equal';
import cloneDeep from 'lodash.clonedeep';
const async = require('async'); const async = require('async');
const web3Utils = require('web3-utils'); const web3Utils = require('web3-utils');
@ -15,6 +16,7 @@ class Test {
this.logger = options.logger; this.logger = options.logger;
this.ipc = options.ipc; this.ipc = options.ipc;
this.configObj = options.config; this.configObj = options.config;
this.originalConfigObj = cloneDeep(options.config);
this.ready = true; this.ready = true;
this.firstRunConfig = true; this.firstRunConfig = true;
this.error = false; this.error = false;
@ -30,6 +32,7 @@ class Test {
storage: {}, storage: {},
communication: {} communication: {}
}; };
this.needToRestetEmbarkJS = false;
this.events.setCommandHandler("blockchain:provider:contract:accounts:get", cb => { this.events.setCommandHandler("blockchain:provider:contract:accounts:get", cb => {
this.events.request("blockchain:getAccounts", cb); this.events.request("blockchain:getAccounts", cb);
@ -180,8 +183,10 @@ class Test {
Object.keys(this.moduleConfigs).forEach(moduleName => { Object.keys(this.moduleConfigs).forEach(moduleName => {
options[moduleName] = options[moduleName] || {}; options[moduleName] = options[moduleName] || {};
if (!deepEqual(options[moduleName], this.moduleConfigs[moduleName])) { if (!deepEqual(options[moduleName], this.moduleConfigs[moduleName])) {
restartModules.push(function (paraCb) { this.moduleConfigs[moduleName] = options[moduleName];
self.events.request(`config:${moduleName}Config:set`, options[moduleName], true, () => { this.needToRestetEmbarkJS = true;
restartModules.push((paraCb) => {
self.events.request(`config:${moduleName}Config:set`, recursiveMerge({}, self.originalConfigObj[`${moduleName}Config`], options[moduleName]), () => {
self.events.request(`module:${moduleName}:reset`, paraCb); self.events.request(`module:${moduleName}:reset`, paraCb);
}); });
}); });
@ -196,6 +201,7 @@ class Test {
config(options, callback) { config(options, callback) {
const self = this; const self = this;
self.needConfig = false; self.needConfig = false;
self.needToRestetEmbarkJS = false;
if (typeof (options) === 'function') { if (typeof (options) === 'function') {
callback = options; callback = options;
options = {}; options = {};
@ -258,6 +264,14 @@ class Test {
self.error = false; self.error = false;
next(null, accounts); next(null, accounts);
}); });
},
function checkIfNeedToResetEmbarkJS(accounts, next) {
if (!self.needToRestetEmbarkJS) {
return next(null, accounts);
}
self.events.request("runcode:embarkjs:reset", (err) => {
next(err, accounts);
});
} }
], (err, accounts) => { ], (err, accounts) => {
if (err) { if (err) {

View File

@ -4,8 +4,8 @@ export function last(array: any) {
return array[array.length - 1]; return array[array.length - 1];
} }
export function recursiveMerge(target: any, source: any) { export function recursiveMerge(...args: any[]) {
return merge.recursive(target, source); return merge.recursive(...args);
} }
export function compact(array: any) { export function compact(array: any) {

View File

@ -58,16 +58,8 @@ var Config = function(options) {
this.registerEvents(); this.registerEvents();
}; };
Config.prototype.setConfig = function(configName, newConfig, recursive, cb) { Config.prototype.setConfig = function(configName, newConfig, cb) {
if (typeof recursive === 'function') { this[configName] = newConfig;
cb = recursive;
recursive = false;
}
if (recursive) {
this[configName] = recursiveMerge(this[configName], newConfig);
} else {
this[configName] = newConfig;
}
cb(); cb();
}; };
@ -272,12 +264,12 @@ Config.prototype._doMergeConfig = function(config, defaultConfig, env) {
} }
return recursiveMerge(configObject.default || {}, configObject[env]); return recursiveMerge(configObject.default || {}, configObject[env]);
} else if (env !== false) { } else if (env !== false) {
this.logger.warn(__("No environment called %s found. Using defaults.", env)); this.logger.info(__("No environment called %s found. Using defaults.", env));
} }
return configObject; return configObject;
}; };
Config.prototype._mergeConfig = function(configFilePath, defaultConfig, env, enabledByDefault) { Config.prototype._loadAndMergeConfig = function(configFilePath, defaultConfig, env, enabledByDefault) {
const config = this._loadConfigFile(configFilePath, defaultConfig, enabledByDefault); const config = this._loadConfigFile(configFilePath, defaultConfig, enabledByDefault);
return this._doMergeConfig(config, defaultConfig, env, enabledByDefault); return this._doMergeConfig(config, defaultConfig, env, enabledByDefault);
}; };
@ -419,7 +411,7 @@ Config.prototype.loadContractsConfigFile = function() {
}); });
let configFilePath = this._getFileOrObject(this.configDir, 'contracts', 'contracts'); let configFilePath = this._getFileOrObject(this.configDir, 'contracts', 'contracts');
let newContractsConfig = this._mergeConfig(configFilePath, configObject, this.env); let newContractsConfig = this._loadAndMergeConfig(configFilePath, configObject, this.env);
if (newContractsConfig.contracts) { if (newContractsConfig.contracts) {
this.logger.error(__('`contracts` has been renamed `deploy` in contracts config\nFor more information: %s', embark5ChangesUrl.underline)); this.logger.error(__('`contracts` has been renamed `deploy` in contracts config\nFor more information: %s', embark5ChangesUrl.underline));
process.exit(1); process.exit(1);
@ -513,7 +505,7 @@ Config.prototype.loadStorageConfigFile = function() {
let configFilePath = this._getFileOrObject(this.configDir, 'storage', 'storage'); let configFilePath = this._getFileOrObject(this.configDir, 'storage', 'storage');
this.storageConfig = this._mergeConfig(configFilePath, configObject, this.env); this.storageConfig = this._loadAndMergeConfig(configFilePath, configObject, this.env);
this.events.emit('config:load:storage', this.storageConfig); this.events.emit('config:load:storage', this.storageConfig);
}; };
@ -527,7 +519,7 @@ Config.prototype.loadNameSystemConfigFile = function() {
let configFilePath = this._getFileOrObject(this.configDir, 'namesystem', 'namesystem'); let configFilePath = this._getFileOrObject(this.configDir, 'namesystem', 'namesystem');
this.namesystemConfig = this._mergeConfig(configFilePath, configObject, this.env); this.namesystemConfig = this._loadAndMergeConfig(configFilePath, configObject, this.env);
}; };
Config.prototype.loadCommunicationConfigFile = function() { Config.prototype.loadCommunicationConfigFile = function() {
@ -546,7 +538,7 @@ Config.prototype.loadCommunicationConfigFile = function() {
let configFilePath = this._getFileOrObject(this.configDir, 'communication', 'communication'); let configFilePath = this._getFileOrObject(this.configDir, 'communication', 'communication');
this.communicationConfig = this._mergeConfig(configFilePath, configObject, this.env); this.communicationConfig = this._loadAndMergeConfig(configFilePath, configObject, this.env);
this.events.emit('config:load:communication', this.communicationConfig); this.events.emit('config:load:communication', this.communicationConfig);
}; };
@ -562,7 +554,7 @@ Config.prototype.loadWebServerConfigFile = function() {
let configFilePath = this._getFileOrObject(this.configDir, 'webserver', 'webserver'); let configFilePath = this._getFileOrObject(this.configDir, 'webserver', 'webserver');
let webServerConfig = this._mergeConfig(configFilePath, configObject, false); let webServerConfig = this._loadAndMergeConfig(configFilePath, configObject, false);
if (webServerConfig.https){ if (webServerConfig.https){
try { try {

View File

@ -269,13 +269,23 @@ class Engine {
} }
storageService(_options) { storageService(_options) {
if (this.config.storageConfig.available_providers.includes("ipfs")) { this.registerModulePackage('embark-ipfs');
this.registerModulePackage('embark-ipfs'); this.registerModulePackage('embark-swarm');
}
if (this.config.storageConfig.available_providers.includes("swarm")) {
this.registerModulePackage('embark-swarm');
}
this.registerModulePackage('embark-storage', {plugins: this.plugins}); this.registerModulePackage('embark-storage', {plugins: this.plugins});
this.events.setCommandHandler("module:storage:reset", (cb) => {
async.parallel([
(paraCb) => {
this.events.request("module:ipfs:reset", paraCb);
},
(paraCb) => {
this.events.request("module:swarm:reset", paraCb);
},
(paraCb) => {
this.events.request("module:storageJS:reset", paraCb);
}
], cb);
});
} }
web3Service(options) { web3Service(options) {

View File

@ -1,4 +1,4 @@
/*globals describe, it*/ /*global describe, it*/
const { dappPath } = require('embark-utils'); const { dappPath } = require('embark-utils');
const Config = require('../lib/core/config.js'); const Config = require('../lib/core/config.js');
const Plugins = require('../lib/core/plugins.js'); const Plugins = require('../lib/core/plugins.js');
@ -38,18 +38,17 @@ describe('embark.Config', function () {
"wsPort": 8546, "wsPort": 8546,
"networkType": "custom", "networkType": "custom",
"isDev": false, "isDev": false,
"mineWhenNeeded": false, "mineWhenNeeded": true,
"nodiscover": true, "nodiscover": true,
"maxpeers": 0, "maxpeers": 0,
"targetGasLimit": 8000000, "targetGasLimit": 8000000,
"simulatorBlocktime": 0, "simulatorBlocktime": 0,
"clientMode": { "miningMode": "auto",
"miningMode": "auto" "endpoint": "ws://localhost:8546",
}, "isAutoEndpoint": true
"endpoint": "ws://localhost:8546"
}; };
assert.deepEqual(config.blockchainConfig, expectedConfig); assert.deepStrictEqual(config.blockchainConfig, expectedConfig);
}); });
it('should convert Ether units', function () { it('should convert Ether units', function () {
@ -73,23 +72,21 @@ describe('embark.Config', function () {
"wsPort": 8546, "wsPort": 8546,
"networkType": "custom", "networkType": "custom",
"isDev": false, "isDev": false,
"mineWhenNeeded": false, "mineWhenNeeded": true,
"nodiscover": true, "nodiscover": true,
"maxpeers": 0, "maxpeers": 0,
"targetGasLimit": 8000000,
"simulatorBlocktime": 0, "simulatorBlocktime": 0,
"clientMode": { "miningMode": "auto",
"miningMode": "auto", "gasPrice": "8000000",
"gasPrice": "8 Mwei", "targetGasLimit": "300000",
"targetGasLimit": "300 Kwei"
},
"accounts": [ "accounts": [
{ {
"password": "config/development/password", "password": "config/development/password",
"balance": "3000000000000000000" "balance": "3000000000000000000"
} }
], ],
"endpoint": "ws://localhost:8546" "endpoint": "ws://localhost:8546",
"isAutoEndpoint": true
}; };
let config = new Config({ let config = new Config({
@ -101,7 +98,7 @@ describe('embark.Config', function () {
config.logger = new TestLogger({}); config.logger = new TestLogger({});
config.loadBlockchainConfigFile(); config.loadBlockchainConfigFile();
assert.deepEqual(config.blockchainConfig, expectedConfig); assert.deepStrictEqual(config.blockchainConfig, expectedConfig);
}); });
it('should accept unitless gas values', function () { it('should accept unitless gas values', function () {
@ -125,23 +122,21 @@ describe('embark.Config', function () {
"wsPort": 8546, "wsPort": 8546,
"networkType": "custom", "networkType": "custom",
"isDev": false, "isDev": false,
"mineWhenNeeded": false, "mineWhenNeeded": true,
"nodiscover": true, "nodiscover": true,
"maxpeers": 0, "maxpeers": 0,
"targetGasLimit": 8000000, "simulatorBlocktime": 0,
"simulatorBlocktime": 0, "miningMode": "auto",
"clientMode": { "gasPrice": "8000000",
"miningMode": "auto", "targetGasLimit": "20000000",
"gasPrice": "8000000",
"targetGasLimit": "20000000"
},
"accounts": [ "accounts": [
{ {
"password": "config/development/password", "password": "config/development/password",
"balance": "3000000000000000000" "balance": "3000000000000000000"
} }
], ],
"endpoint": "ws://localhost:8546" "endpoint": "ws://localhost:8546",
"isAutoEndpoint": true
}; };
let config = new Config({ let config = new Config({
@ -153,7 +148,48 @@ describe('embark.Config', function () {
config.logger = new TestLogger({}); config.logger = new TestLogger({});
config.loadBlockchainConfigFile(); config.loadBlockchainConfigFile();
assert.deepEqual(config.blockchainConfig, expectedConfig); assert.deepStrictEqual(config.blockchainConfig, expectedConfig);
});
it('should use the specified endpoint', () => {
let expectedConfig = {
"enabled": true,
"client": "geth",
"proxy": true,
"datadir": ".embark/extNetwork/datadir",
"rpcHost": "localhost",
"rpcPort": 8545,
"rpcCorsDomain": {
"auto": true,
"additionalCors": []
},
"wsRPC": true,
"wsOrigins": {
"auto": true,
"additionalCors": []
},
"wsHost": "localhost",
"wsPort": 8546,
"networkType": "custom",
"isDev": false,
"nodiscover": true,
"maxpeers": 0,
"simulatorBlocktime": 0,
"miningMode": "dev",
"targetGasLimit": 8000000,
"endpoint": "http://mynetwork.com"
};
let config = new Config({
env: 'extNetwork',
configDir: 'test1/config/',
events: new Events(),
logger: new TestLogger({}),
plugins: new Plugins({plugins: {}})
});
config.loadBlockchainConfigFile();
assert.deepStrictEqual(config.blockchainConfig, expectedConfig);
}); });
}); });
@ -178,10 +214,10 @@ describe('embark.Config', function () {
} }
}; };
assert.deepEqual(config.contractsConfig, expectedConfig); assert.deepStrictEqual(config.contractsConfig, expectedConfig);
}); });
it('should replace occourences of `0x0` with full zero addresses', () => { it('should replace occurrences of `0x0` with full zero addresses', () => {
let expectedConfig = { let expectedConfig = {
versions: {'web3': '1.0.0-beta', solc: '0.5.0'}, versions: {'web3': '1.0.0-beta', solc: '0.5.0'},
dappConnection: ['$WEB3', 'localhost:8545'], dappConnection: ['$WEB3', 'localhost:8545'],
@ -208,7 +244,7 @@ describe('embark.Config', function () {
zeroAddressconfig.plugins = new Plugins({plugins: {}}); zeroAddressconfig.plugins = new Plugins({plugins: {}});
zeroAddressconfig.logger = new TestLogger({}); zeroAddressconfig.logger = new TestLogger({});
zeroAddressconfig.loadContractsConfigFile(); zeroAddressconfig.loadContractsConfigFile();
assert.deepEqual(zeroAddressconfig.contractsConfig, expectedConfig); assert.deepStrictEqual(zeroAddressconfig.contractsConfig, expectedConfig);
}); });
}); });
@ -265,7 +301,8 @@ describe('embark.Config', function () {
} }
]; ];
config.loadExternalContractsFiles(); config.loadExternalContractsFiles();
assert.deepEqual(config.contractsFiles, expected); const files = [Object.assign({}, config.contractsFiles[0]), Object.assign({}, config.contractsFiles[1]), Object.assign({}, config.contractsFiles[2])];
assert.deepStrictEqual(files, expected);
}); });
}); });
}); });

View File

@ -1,11 +1,11 @@
{ {
"myenv": { "myenv": {
"clientMode": { "clientConfig": {
"miningMode": "auto" "miningMode": "auto"
} }
}, },
"unitenv": { "unitenv": {
"clientMode": { "clientConfig": {
"miningMode": "auto", "miningMode": "auto",
"gasPrice": "8 Mwei", "gasPrice": "8 Mwei",
"targetGasLimit": "300 Kwei" "targetGasLimit": "300 Kwei"
@ -19,7 +19,7 @@
}, },
"unitlessenv": { "unitlessenv": {
"clientMode": { "clientConfig": {
"miningMode": "auto", "miningMode": "auto",
"gasPrice": "8000000", "gasPrice": "8000000",
"targetGasLimit": "20000000" "targetGasLimit": "20000000"
@ -46,5 +46,8 @@
"datadir": "yourdatadir", "datadir": "yourdatadir",
"networkId": "123", "networkId": "123",
"nodes": [] "nodes": []
},
"extNetwork": {
"endpoint": "http://mynetwork.com"
} }
} }

View File

@ -158,7 +158,8 @@ __embarkENS.setProvider = function(config) {
const ERROR_MESSAGE = 'ENS is not available in this chain'; const ERROR_MESSAGE = 'ENS is not available in this chain';
self.registration = config.registration; self.registration = config.registration;
self.env = config.env; self.env = config.env;
// FIXME EmbarkJS.onReady odesn't work. Possibility of a race condition self.ready = false;
// FIXME EmbarkJS.onReady doesn't work. Possibility of a race condition
EmbarkJS.Blockchain.blockchainConnector.getNetworkId() EmbarkJS.Blockchain.blockchainConnector.getNetworkId()
.then((id) => { .then((id) => {
const registryAddress = self.registryAddresses[id] || config.registryAddress; const registryAddress = self.registryAddresses[id] || config.registryAddress;
@ -178,8 +179,10 @@ __embarkENS.setProvider = function(config) {
address: config.resolverAddress, address: config.resolverAddress,
web3: EmbarkJS.Blockchain.blockchainConnector.getInstance() web3: EmbarkJS.Blockchain.blockchainConnector.getInstance()
}); });
self.ready = true;
}) })
.catch(err => { .catch(err => {
self.ready = true;
if (err.message.indexOf('Provider not set or invalid') > -1) { if (err.message.indexOf('Provider not set or invalid') > -1) {
console.warn(ERROR_MESSAGE); console.warn(ERROR_MESSAGE);
return; return;
@ -188,11 +191,28 @@ __embarkENS.setProvider = function(config) {
}); });
}; };
__embarkENS.waitForProviderReady = function() {
return new Promise((resolve, reject) => {
const self = this;
function checkReady() {
if (self.ready === undefined) {
return reject(providerNotSetError);
}
if (self.ready) {
if (!self.ens) {
return reject(providerNotSetError);
}
return resolve();
}
setTimeout(checkReady, 100);
}
checkReady();
});
};
__embarkENS.resolve = function (name, callback) { __embarkENS.resolve = function (name, callback) {
const resolve = async (name) => { const resolve = async (name) => {
if (!this.ens) { await this.waitForProviderReady();
throw new Error(providerNotSetError);
}
if (!EmbarkJS.Blockchain.blockchainConnector.getDefaultAccount()) { if (!EmbarkJS.Blockchain.blockchainConnector.getDefaultAccount()) {
throw new Error(defaultAccountNotSetError); throw new Error(defaultAccountNotSetError);
} }
@ -230,9 +250,7 @@ __embarkENS.resolve = function (name, callback) {
__embarkENS.lookup = function (address, callback) { __embarkENS.lookup = function (address, callback) {
const lookup = async (address) => { const lookup = async (address) => {
if (!this.ens) { await this.waitForProviderReady();
throw new Error(providerNotSetError);
}
if (!EmbarkJS.Blockchain.blockchainConnector.getDefaultAccount()) { if (!EmbarkJS.Blockchain.blockchainConnector.getDefaultAccount()) {
throw new Error(defaultAccountNotSetError); throw new Error(defaultAccountNotSetError);
} }