|
|
@ -15,17 +15,17 @@ const gasPriceHex = 0x01; // Low gas price |
|
|
|
* Coverage Runner |
|
|
|
* Coverage Runner |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
class App { |
|
|
|
class App { |
|
|
|
constructor(config){ |
|
|
|
constructor(config) { |
|
|
|
this.coverageDir = './coverageEnv'; // Env that instrumented .sols are tested in
|
|
|
|
this.coverageDir = './coverageEnv'; // Env that instrumented .sols are tested in
|
|
|
|
|
|
|
|
|
|
|
|
// Options
|
|
|
|
// Options
|
|
|
|
this.network = ''; // Default truffle network execution flag
|
|
|
|
this.network = ''; // Default truffle network execution flag
|
|
|
|
this.silence = ''; // Default log level: configurable by --silence
|
|
|
|
this.silence = ''; // Default log level passed to shell
|
|
|
|
this.log = console.log; |
|
|
|
this.log = console.log; |
|
|
|
|
|
|
|
|
|
|
|
// Other
|
|
|
|
// Other
|
|
|
|
this.testrpcProcess; // ref to testrpc server we need to close on exit
|
|
|
|
this.testrpcProcess = null; // ref to testrpc server we need to close on exit
|
|
|
|
this.events; // ref to string loaded from 'allFiredEvents'
|
|
|
|
this.events = null; // ref to string array loaded from 'allFiredEvents'
|
|
|
|
this.testsErrored = null; // flag set to non-null if truffle tests error
|
|
|
|
this.testsErrored = null; // flag set to non-null if truffle tests error
|
|
|
|
this.coverage = new CoverageMap(); // initialize a coverage map
|
|
|
|
this.coverage = new CoverageMap(); // initialize a coverage map
|
|
|
|
|
|
|
|
|
|
|
@ -44,14 +44,13 @@ class App { |
|
|
|
this.setLoggingLevel(config.silent); |
|
|
|
this.setLoggingLevel(config.silent); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------- Methods ------------------------------------------------
|
|
|
|
// -------------------------------------- Methods ------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Generates a copy of the target project configured for solidity-coverage and saves to |
|
|
|
* Generates a copy of the target project configured for solidity-coverage and saves to |
|
|
|
* the coverage environment folder. Process exits(1) if try fails |
|
|
|
* the coverage environment folder. Process exits(1) if try fails |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
generateCoverageEnvironment(){ |
|
|
|
generateCoverageEnvironment() { |
|
|
|
|
|
|
|
|
|
|
|
this.log('Generating coverage environment'); |
|
|
|
this.log('Generating coverage environment'); |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
try { |
|
|
@ -76,7 +75,7 @@ class App { |
|
|
|
|
|
|
|
|
|
|
|
// No coverage network defaults to the dev network on port 8555, high gas / low price.
|
|
|
|
// No coverage network defaults to the dev network on port 8555, high gas / low price.
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
const trufflejs = defaultTruffleConfig(this.port, gasLimitHex, gasPriceHex) |
|
|
|
const trufflejs = defaultTruffleConfig(this.port, gasLimitHex, gasPriceHex); |
|
|
|
fs.writeFileSync(`${this.coverageDir}/truffle.js`, trufflejs); |
|
|
|
fs.writeFileSync(`${this.coverageDir}/truffle.js`, trufflejs); |
|
|
|
} |
|
|
|
} |
|
|
|
} catch (err) { |
|
|
|
} catch (err) { |
|
|
@ -93,8 +92,7 @@ class App { |
|
|
|
* + Save instrumented contract in the coverage environment folder where covered tests will run |
|
|
|
* + Save instrumented contract in the coverage environment folder where covered tests will run |
|
|
|
* + Add instrumentation info to the coverage map |
|
|
|
* + Add instrumentation info to the coverage map |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
instrumentTarget(){ |
|
|
|
instrumentTarget() { |
|
|
|
|
|
|
|
|
|
|
|
this.skipFiles = this.skipFiles.map(contract => `${this.coverageDir}/contracts/${contract}`); |
|
|
|
this.skipFiles = this.skipFiles.map(contract => `${this.coverageDir}/contracts/${contract}`); |
|
|
|
this.skipFiles.push(`${this.coverageDir}/contracts/Migrations.sol`); |
|
|
|
this.skipFiles.push(`${this.coverageDir}/contracts/Migrations.sol`); |
|
|
|
|
|
|
|
|
|
|
@ -126,9 +124,8 @@ class App { |
|
|
|
* Changes here should be also be added to the before() block of test/run.js). |
|
|
|
* Changes here should be also be added to the before() block of test/run.js). |
|
|
|
* @return {Promise} Resolves when testrpc prints 'Listening' to std out / norpc is true. |
|
|
|
* @return {Promise} Resolves when testrpc prints 'Listening' to std out / norpc is true. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
launchTestrpc(){ |
|
|
|
launchTestrpc() { |
|
|
|
return new Promise((resolve, reject) => { |
|
|
|
return new Promise((resolve, reject) => { |
|
|
|
|
|
|
|
|
|
|
|
if (!this.norpc) { |
|
|
|
if (!this.norpc) { |
|
|
|
const defaultRpcOptions = `--gasLimit ${gasLimitHex} --accounts ${this.accounts} --port ${this.port}`; |
|
|
|
const defaultRpcOptions = `--gasLimit ${gasLimitHex} --accounts ${this.accounts} --port ${this.port}`; |
|
|
|
const options = this.testrpcOptions || defaultRpcOptions; |
|
|
|
const options = this.testrpcOptions || defaultRpcOptions; |
|
|
@ -137,8 +134,8 @@ class App { |
|
|
|
// Launch
|
|
|
|
// Launch
|
|
|
|
this.testrpcProcess = childprocess.exec(command + options, null, (err, stdout, stderr) => { |
|
|
|
this.testrpcProcess = childprocess.exec(command + options, null, (err, stdout, stderr) => { |
|
|
|
if (err) { |
|
|
|
if (err) { |
|
|
|
if(stdout) this.log(`testRpc stdout:\n${stdout}`); |
|
|
|
if (stdout) this.log(`testRpc stdout:\n${stdout}`); |
|
|
|
if(stderr) this.log(`testRpc stderr:\n${stderr}`); |
|
|
|
if (stderr) this.log(`testRpc stderr:\n${stderr}`); |
|
|
|
this.cleanUp('testRpc errored after launching as a childprocess.'); |
|
|
|
this.cleanUp('testRpc errored after launching as a childprocess.'); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
@ -153,7 +150,7 @@ class App { |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
return resolve(); |
|
|
|
return resolve(); |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
@ -162,10 +159,8 @@ class App { |
|
|
|
* as its own statement for command line options to work, apparently. |
|
|
|
* as its own statement for command line options to work, apparently. |
|
|
|
* Also reads the 'allFiredEvents' log. |
|
|
|
* Also reads the 'allFiredEvents' log. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
runTestCommand(){ |
|
|
|
runTestCommand() { |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
try { |
|
|
|
|
|
|
|
|
|
|
|
const defaultCommand = `truffle test ${this.network} ${this.silence}`; |
|
|
|
const defaultCommand = `truffle test ${this.network} ${this.silence}`; |
|
|
|
const command = this.testCommand || defaultCommand; |
|
|
|
const command = this.testCommand || defaultCommand; |
|
|
|
this.log(`Running: ${command}\n(this can take a few seconds)...`); |
|
|
|
this.log(`Running: ${command}\n(this can take a few seconds)...`); |
|
|
@ -196,8 +191,7 @@ class App { |
|
|
|
/** |
|
|
|
/** |
|
|
|
* Generate coverage / write coverage report / run istanbul |
|
|
|
* Generate coverage / write coverage report / run istanbul |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
generateReport(){ |
|
|
|
generateReport() { |
|
|
|
|
|
|
|
|
|
|
|
const collector = new istanbul.Collector(); |
|
|
|
const collector = new istanbul.Collector(); |
|
|
|
const reporter = new istanbul.Reporter(); |
|
|
|
const reporter = new istanbul.Reporter(); |
|
|
|
|
|
|
|
|
|
|
@ -220,9 +214,8 @@ class App { |
|
|
|
} catch (err) { |
|
|
|
} catch (err) { |
|
|
|
const msg = 'There was a problem generating the coverage map / running Istanbul.\n'; |
|
|
|
const msg = 'There was a problem generating the coverage map / running Istanbul.\n'; |
|
|
|
this.cleanUp(msg + err); |
|
|
|
this.cleanUp(msg + err); |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// ------------------------------------------ Utils ----------------------------------------------
|
|
|
|
// ------------------------------------------ Utils ----------------------------------------------
|
|
|
@ -231,7 +224,7 @@ class App { |
|
|
|
* Allows config to turn logging off (for CI) |
|
|
|
* Allows config to turn logging off (for CI) |
|
|
|
* @param {Boolean} isSilent |
|
|
|
* @param {Boolean} isSilent |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
setLoggingLevel(isSilent){ |
|
|
|
setLoggingLevel(isSilent) { |
|
|
|
if (isSilent) { |
|
|
|
if (isSilent) { |
|
|
|
this.silence = '> /dev/null 2>&1'; |
|
|
|
this.silence = '> /dev/null 2>&1'; |
|
|
|
this.log = () => {}; |
|
|
|
this.log = () => {}; |
|
|
|