Skip to content
This repository has been archived by the owner on Nov 15, 2021. It is now read-only.

Add support for solidity-coverage #15

Merged
merged 6 commits into from
Nov 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28,294 changes: 16,741 additions & 11,553 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,11 @@
"ethereumjs-wallet": "^0.6.3",
"find-up": "^4.1.0",
"ganache-core": "^2.8.0",
"ganache-core-coverage": "https://github.com/OpenZeppelin/ganache-core-coverage/releases/download/2.5.3-coverage/ganache-core-coverage-2.5.3.tgz",
"lodash.merge": "^4.6.2",
"p-queue": "^6.2.0",
"semver": "^6.3.0",
"try-require": "^1.2.1",
"web3": "^1.2.2"
"web3": "1.2.2"
}
}
7 changes: 4 additions & 3 deletions src/config.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import config, { DEFAULT_GAS_LIMIT } from './config';
import config, { DEFAULT_BLOCK_GAS_LIMIT } from './config';

const defaultConfig = {
accounts: {
Expand All @@ -7,10 +7,11 @@ const defaultConfig = {
},
contracts: {
type: 'web3',
defaultGas: DEFAULT_GAS_LIMIT * 0.75,
defaultGas: DEFAULT_BLOCK_GAS_LIMIT * 0.75,
},

blockGasLimit: DEFAULT_GAS_LIMIT,
blockGasLimit: DEFAULT_BLOCK_GAS_LIMIT,
gasPrice: 20e9,
};

describe('config', (): void => {
Expand Down
41 changes: 34 additions & 7 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,22 @@ import fs from 'fs';
import findUp from 'find-up';
import merge from 'lodash.merge';

import { log } from './log';

import { Provider } from 'web3/providers';

const CONFIG_FILE = '.test-env.js';
const location = findUp.sync(CONFIG_FILE, { type: 'file' });

type Config = {
accounts: { amount: number; ether: number };
contracts: { type: string; defaultGas: number };
blockGasLimit: number;
gasPrice: number;
setupProvider: (baseProvider: Provider) => Promise<Provider>;
coverage: boolean;
};

const providedConfig: Partial<Config> = location !== undefined && fs.existsSync(location) ? require(location) : {};

export const DEFAULT_GAS_LIMIT = 8e6;
export const DEFAULT_BLOCK_GAS_LIMIT = 8e6;

const defaultConfig: Config = {
accounts: {
Expand All @@ -26,12 +27,38 @@ const defaultConfig: Config = {

contracts: {
type: 'web3',
defaultGas: DEFAULT_GAS_LIMIT * 0.75,
defaultGas: DEFAULT_BLOCK_GAS_LIMIT * 0.75,
},

blockGasLimit: DEFAULT_GAS_LIMIT,
blockGasLimit: DEFAULT_BLOCK_GAS_LIMIT,
gasPrice: 20e9, // 20 gigawei

setupProvider: async baseProvider => baseProvider,

coverage: false,
};

export default merge(defaultConfig, providedConfig);
function getConfig(): Config {
const location = findUp.sync(CONFIG_FILE, { type: 'file' });
const providedConfig: Partial<Config> = location !== undefined && fs.existsSync(location) ? require(location) : {};

const config: Config = merge(defaultConfig, providedConfig);

if (process.env.OZ_TEST_ENV_COVERAGE !== undefined) {
log('Running on coverage mode: overriding some configuration values');
config.coverage = true;

// Solidity coverage causes transactions to require much more gas. We need to:
// 1. increase the block gas limit so that transactions don't go over it
// 2. increase how much gas transactions send by default
// 3. reduce the gas price to prevent the account's funds from being affected by this too much

config.blockGasLimit = 0xfffffffffffff;
config.contracts.defaultGas = config.blockGasLimit * 0.75;
config.gasPrice = 1;
}

return config;
}

export default getConfig();
18 changes: 15 additions & 3 deletions src/ganache-server.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import ganache from 'ganache-core';
import ganacheNormal from 'ganache-core';
import ganacheCoverage from 'ganache-core-coverage';

import { Message, Options } from './setup-ganache';

Expand All @@ -9,9 +10,20 @@ function send(msg: Message): void {
process.send(msg);
}

function setupServer({ accountsConfig, gasLimit, gasPrice, coverage }: Options) {
const ganache = coverage ? ganacheCoverage : ganacheNormal;

return ganache.server({
accounts: accountsConfig,
gasLimit,
gasPrice: `0x${gasPrice.toString(16)}`,
allowUnlimitedContractSize: coverage,
emitFreeLogs: coverage,
});
}

process.once('message', (options: Options) => {
const { accountsConfig, gasLimit } = options;
const server = ganache.server({ accounts: accountsConfig, gasLimit });
const server = setupServer(options);

// An undefined port number makes ganache-core choose a random free port,
// which plays nicely with environments such as jest and ava, where multiple
Expand Down
16 changes: 6 additions & 10 deletions src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import semver from 'semver';
import { defaultSender } from './accounts';
import config from './config';
import { provider } from './setup-provider';

const colors = require('ansi-colors');
import { warn } from './log';

let configured = false;

const testHelpersPackage = tryRequire('@openzeppelin/test-helpers/package.json');
if (testHelpersPackage !== undefined) {
// TODO: skip if already configured?

// eslint-disable-next-line @typescript-eslint/no-var-requires
const configure = require('@openzeppelin/test-helpers/configure');

const version = testHelpersPackage.version;
Expand All @@ -23,23 +24,18 @@ if (testHelpersPackage !== undefined) {
abstraction: config.contracts.type,
defaultGas: config.contracts.defaultGas,
defaultSender,
}
},
});

configured = true;

} else if (semver.satisfies(version, '^0.5.0 <0.5.4')) { // Whitespaces indicate intersection ('and') in semver
} else if (semver.satisfies(version, '^0.5.0 <0.5.4')) {
// Whitespaces indicate intersection ('and') in semver
// Alternatively, 'environment' was available from 0.5.0, but the gas and
// sender could not be configured
configure({ provider, environment: config.contracts.type });

configured = true;

} else {
const warn = (msg: string) => {
console.log(`${colors.white.bgBlack('@openzeppelin/test-env')} ${colors.black.bgYellow('WARN')} ${msg}`);
};

warn(`Unknown version of @openzeppelin/test-helpers: '${version}', cannot configure`);
}
}
Expand Down
9 changes: 9 additions & 0 deletions src/log.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import colors from 'ansi-colors';

export function log(msg: string): void {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really like putting it in a separate file as soon as possible.

console.log(`${colors.white.bgBlack('@openzeppelin/test-env')} ${msg}`);
}

export function warn(msg: string): void {
log(`${colors.black.bgYellow('WARN')} ${msg}`);
}
6 changes: 5 additions & 1 deletion src/setup-ganache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,18 @@ export type AccountConfig = {
export type Options = {
accountsConfig: AccountConfig[];
gasLimit: number;
gasPrice: number;
coverage: boolean;
};

export default async function(): Promise<string> {
const server = fork(path.join(__dirname, 'ganache-server'));

const options: Options = {
accountsConfig,
gasLimit: config.blockGasLimit
gasLimit: config.blockGasLimit,
gasPrice: config.gasPrice,
coverage: config.coverage,
};
server.send(options);

Expand Down
10 changes: 10 additions & 0 deletions src/typing/ganache-core-coverage.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
declare module 'ganache-core-coverage' {
import ganache from 'ganache-core';

interface ServerCoverageOptions extends ganache.IServerOptions {
emitFreeLogs: boolean;
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function server(options?: ServerCoverageOptions): any;
}