Skip to content

Commit

Permalink
Merge pull request #372 from sc-forks/truffle-plugin
Browse files Browse the repository at this point in the history
0.7.0 Phase 1: opcode trace instrumentation & truffle plugin app architecture
  • Loading branch information
cgewecke authored Sep 25, 2019
2 parents 15fa08b + 00f32f6 commit 64a501b
Show file tree
Hide file tree
Showing 222 changed files with 502,424 additions and 4,031 deletions.
37 changes: 23 additions & 14 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,30 @@ step_install_nvm: &step_install_nvm
echo "[ -s \"$NVM_DIR/nvm.sh\" ] && . \"$NVM_DIR/nvm.sh\"" >> $BASH_ENV
jobs:
unit-test:
docker:
- image: circleci/node:8.15.0
machine: true
steps:
- checkout
- <<: *step_install_nvm
- run:
name: Delete any old node_modules
command: |
rm -rf node_modules/
- run:
name: Install yarn
command: |
npm install -g yarn
- run:
name: Install truffle (globally)
command: |
npm install -g truffle
- run:
name: Install dependencies
command: |
yarn
- run:
name: Run tests
command: |
npm run test-cov
npm run test:ci
- run:
name: Upload coverage
command: |
Expand All @@ -56,7 +64,6 @@ jobs:
name: Zeppelin E2E
command: |
./scripts/run-zeppelin.sh
e2e-metacoin:
machine: true
steps:
Expand All @@ -73,14 +80,16 @@ workflows:
- unit-test
- e2e-zeppelin
- e2e-metacoin
nightly:
triggers:
- schedule:
cron: "0 1 * * *" # 1am UTC
filters:
branches:
only:
- master
jobs:
- e2e-zeppelin
# TODO: re-enable.
# At the moment we're using forks so this is pointless
#nightly:
# triggers:
# - schedule:
# cron: "0 1 * * *" # 1am UTC
# filters:
# branches:
# only:
# - master
# jobs:
#- e2e-zeppelin
#- e2e-colony
7 changes: 4 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
allFiredEvents
scTopics
scDebugLog
coverage.json
coverage/
node_modules/
.changelog
.DS_Store
test/artifacts
test/cache
temp
.nyc_output/
4 changes: 4 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
test/
.circleci/
docs/
.nyc_output/
206 changes: 104 additions & 102 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,133 +1,110 @@
# solidity-coverage

[![Join the chat at https://gitter.im/sc-forks/solidity-coverage](https://badges.gitter.im/sc-forks/solidity-coverage.svg)](https://gitter.im/sc-forks/solidity-coverage?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![npm version](https://badge.fury.io/js/solidity-coverage.svg)](https://badge.fury.io/js/solidity-coverage)
[![CircleCI](https://circleci.com/gh/sc-forks/solidity-coverage.svg?style=svg)](https://circleci.com/gh/sc-forks/solidity-coverage)
[![codecov](https://codecov.io/gh/sc-forks/solidity-coverage/branch/master/graph/badge.svg)](https://codecov.io/gh/sc-forks/solidity-coverage)

### Code coverage for Solidity testing
![coverage example](https://cdn-images-1.medium.com/max/800/1*uum8t-31bUaa6dTRVVhj6w.png)

+ For more details about what this is, how it works and potential limitations, see
[the accompanying article](https://blog.colony.io/code-coverage-for-solidity-eecfa88668c2).
+ `solidity-coverage` is in development and **its accuracy is unknown.** If you
find discrepancies between the coverage report and your suite's behavior, please open an
[issue](https://github.com/sc-forks/solidity-coverage/issues).
+ `solidity-coverage` is [Solcover](https://github.com/JoinColony/solcover)

### Install
[![Gitter chat](https://badges.gitter.im/sc-forks/solidity-coverage.svg)][18]
![npm (tag)](https://img.shields.io/npm/v/solidity-coverage/beta)
[![CircleCI](https://circleci.com/gh/sc-forks/solidity-coverage.svg?style=svg)][20]
[![codecov](https://codecov.io/gh/sc-forks/solidity-coverage/branch/beta/graph/badge.svg)][21]

## Code coverage for Solidity testing
![coverage example][22]

+ For more details about what this is, how it works and potential limitations,
see [the accompanying article][16].
+ `solidity-coverage` is [Solcover][17]

## Install
```
$ npm install --save-dev solidity-coverage
$ npm install --save-dev solidity-coverage@beta
```

### Run
Set a `coverage` network in truffle-config.js (see [Network Configuration](#network-configuration)) and then run:
## Truffle V5

**Add** this package to your plugins array in `truffle-config.js`
```javascript
module.exports = {
networks: {...},
plugins: ["solidity-coverage"]
}
```
$ npx solidity-coverage
**Run**
```
truffle run coverage [command-options]
```

### Usage notes:
+ For pragma solidity >=0.4.22 <0.6.0 / Petersburg / Truffle v4 and v5
+ Tests run more slowly while coverage is being generated.
+ Your contracts will be double-compiled and a (long) delay between compilation and
the beginning of test execution is possible if your contracts are large.
+ Truffle should be globallly installed in your environment.. If you prefer running truffle as
a local dependency, please see [this section](https://github.com/sc-forks/solidity-coverage/blob/master/docs/faq.md#running-truffle-as-a-local-dependency) of the FAQ.
+ If your suite uses native Solidity testing or accesses contracts via mocks stored in `tests/` (a la Zeppelin), coverage will trigger test errors because it can't control the way truffle compiles that folder. Mocks should be relocated to the root `contracts` directory. More on why this is necessary at issue [146](https://github.com/sc-forks/solidity-coverage/issues/146)

### Network Configuration
## Usage notes:
+ Coverage runs tests a little more slowly.
+ Coverage launches its own in-process ganache server.
+ You can set [ganache options][1] using the `providerOptions` key in your `.solcover.js` [config][15].
+ Coverage [distorts gas consumption][13]. Tests that check exact gas consumption should be skipped.

By default, this tool connects to a coverage-enabled fork of ganache-cli
called **testrpc-sc** on port 8555.
+ it's a dependency - there's nothing extra to download.
+ the solidity-coverage command launches it automatically in the background. (See [this section of the FAQ](https://github.com/sc-forks/solidity-coverage/blob/master/docs/faq.md#running-testrpc-sc-on-its-own) if you need to launch it separately yourself)
## Command Options
| Option <img width=200/> | Example <img width=750/>| Description <img width=1000/> |
|--------------|------------------------------------|--------------------------------|
| file | `--file="test/registry/*.js"` | Filename or glob describing a subset of JS tests to run. (Globs must be enclosed by quotes.)|
| solcoverjs | `--solcoverjs ./../.solcover.js` | Relative path from working directory to config. Useful for monorepo packages that share settings. (Path must be "./" prefixed) |
| network | `--network development` | Use network settings defined in the Truffle config |
| temp[<sup>*</sup>][14] | `--temp build` | :warning: **Caution** :warning: Path to a *disposable* folder to store compilation artifacts in. Useful when your test setup scripts include hard-coded paths to a build directory. [More...][14] |
| version | | Version info |
| help | | Usage notes |

In `truffle-config.js`, add a coverage network following the example below.
[<sup>*</sup> Advanced use][14]

**Example**
```javascript
module.exports = {
networks: {
development: {
host: "localhost",
port: 8545,
network_id: "*"
},
coverage: {
host: "localhost",
network_id: "*",
port: 8555, // <-- If you change this, also set the port option in .solcover.js.
gas: 0xfffffffffff, // <-- Use this high gas value
gasPrice: 0x01 // <-- Use this low gas price
},
...etc...
}
};
```
### Options
## Config Options

Additional options can be specified in a `.solcover.js` config file located in
the root directory of your project.
Additional options can be specified in a `.solcover.js` config file located in the root directory
of your project.

**Example:**
```javascript
module.exports = {
port: 6545,
testrpcOptions: '-p 6545 -u 0x54fd80d6ae7584d8e9a19fe1df43f04e5282cc43',
testCommand: 'mocha --timeout 5000',
norpc: true,
dir: './secretDirectory',
copyPackages: ['openzeppelin-solidity'],
skipFiles: ['Routers/EtherRouter.sol']
skipFiles: ['Routers/EtherRouter.sol']
};
```


| Option | Type | Default | Description |
| Option <img width=200/>| Type <img width=200/> | Default <img width=700/> | Description <img width=1000/> |
| ------ | ---- | ------- | ----------- |
| accounts | *Number* | 35 | Number of accounts to launch testrpc with. |
| port | *Number* | 8555 | Port to run testrpc on / have truffle connect to |
| norpc | *Boolean* | false | Prevent solidity-coverage from launching its own testrpc. Useful if you are managing a complex test suite with a [shell script](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/ed872ca0a11c4926f8bb91dd103bea1378a3384c/scripts/coverage.sh) |
| testCommand | *String* | `truffle test` | Run an arbitrary test command. ex: `mocha --timeout 5000`. NB: Also set the `port` option to whatever your tests require (probably 8545). |
| testrpcOptions | *String* | `--port 8555` | options to append to a command line invocation of testrpc. NB: Using this overwrites the defaults so always specify a port in this string *and* in the `port` option |
| copyNodeModules | *Boolean* | false | :warning: **DEPRECATED** use `copyPackages` instead :warning: Copies `node_modules` into the coverage environment. May significantly increase the time for coverage to complete if enabled. Useful if your contracts import solidity files from an npm installed package (and your node_modules is small). |
| copyPackages | *Array* | `[]` | Copies specific `node_modules` packages into the coverage environment. May significantly reduce the time for coverage to complete compared to `copyNodeModules`. Useful if your contracts import solidity files from an npm installed package. |
| skipFiles | *Array* | `['Migrations.sol']` | Array of contracts or folders (with paths expressed relative to the `contracts` directory) that should be skipped when doing instrumentation. `Migrations.sol` is skipped by default, and does not need to be added to this configuration option if it is used. |
| deepSkip | boolean | false | Use this if instrumentation hangs on large, skipped files (like Oraclize). It's faster. |
| dir | *String* | `.` | Solidity-coverage copies all the assets in your root directory (except `node_modules`) to a special folder where it instruments the contracts and executes the tests. `dir` allows you to define a relative path from the root directory to those assets. Useful if your contracts & tests are within their own folder as part of a larger project.|
| buildDirPath | *String* | `/build/contracts` | Build directory path for compiled smart contracts

### FAQ

Solutions to common problems people run into:

+ [Running out of gas](https://github.com/sc-forks/solidity-coverage/blob/master/docs/faq.md#running-out-of-gas)
+ [Running out of memory (locally and in CI)](https://github.com/sc-forks/solidity-coverage/blob/master/docs/faq.md#running-out-of-memory-locally-and-in-ci)
+ [Running out of time (in mocha)](https://github.com/sc-forks/solidity-coverage/blob/master/docs/faq.md#running-out-of-time-in-mocha)
+ [Running on windows](https://github.com/sc-forks/solidity-coverage/blob/master/docs/faq.md#running-on-windows)
+ [Running testrpc-sc on its own](https://github.com/sc-forks/solidity-coverage/blob/master/docs/faq.md#running-testrpc-sc-on-its-own)
+ [Running truffle as a local dependency](https://github.com/sc-forks/solidity-coverage/blob/master/docs/faq.md#running-truffle-as-a-local-dependency)
+ [Integrating into CI](https://github.com/sc-forks/solidity-coverage/blob/master/docs/faq.md#continuous-integration-installing-metacoin-on-travisci-with-coveralls)
+ [Why are asserts and requires highlighted as branch points?](https://github.com/sc-forks/solidity-coverage/blob/master/docs/faq.md#why-has-my-branch-coverage-decreased-why-is-assert-being-shown-as-a-branch-point)


### Example reports
+ [metacoin](https://sc-forks.github.io/metacoin/) (Istanbul HTML)
+ [openzeppelin-solidity](https://coveralls.io/github/OpenZeppelin/openzeppelin-solidity?branch=master) (Coveralls)

### Contribution Guidelines

Contributions are welcome! If you're opening a PR that adds features please consider writing some
[unit tests](https://github.com/sc-forks/solidity-coverage/tree/master/test) for them. Bugs can be
reported in the [issues](https://github.com/sc-forks/solidity-coverage/issues).
| silent | *Boolean* | false | Suppress logging output |
| client | *Object* | `require("ganache-core")` | Useful if you need a specific ganache version. |
| providerOptions | *Object* | `{ }` | [ganache-core options][1] |
| skipFiles | *Array* | `['Migrations.sol']` | Array of contracts or folders (with paths expressed relative to the `contracts` directory) that should be skipped when doing instrumentation. |
| istanbulReporter | *Array* | `['html', 'lcov', 'text']` | [Istanbul coverage reporters][2] |
| mocha | *Object* | `{ }` | [Mocha options][3] to merge into existing mocha config. `grep` and `invert` are useful for skipping certain tests under coverage using tags in the test descriptions.|
| onServerReady[<sup>*</sup>][14] | *Function* | | Hook run *after* server is launched, *before* the tests execute. Useful if you need to use the Oraclize bridge or have setup scripts which rely on the server's availability. [More...][14] |
| onCompileComplete[<sup>*</sup>][14] | *Function* | | Hook run *after* compilation completes, *before* tests are run. Useful if you have secondary compilation steps or need to modify built artifacts. [More...][14]|
| onTestsComplete[<sup>*</sup>][14] | *Function* | | Hook run *after* the tests complete, *before* Istanbul reports are generated.|
| onIstanbulComplete[<sup>*</sup>][14] | *Function* | | Hook run *after* the Istanbul reports are generated, *before* the ganache server is shut down. Useful if you need to clean resources up.|

[<sup>*</sup> Advanced use][14]

## FAQ

Common problems & questions:

+ [Running in CI][7]
+ [Running out of gas][4]
+ [Running out of time][6]
+ [Running out of memory][5]
+ [Why are `require` statements highlighted as branch points?][8]


## Example reports
+ [metacoin][9] (Istanbul HTML)
+ [openzeppelin-solidity][10](Coveralls)

## Contribution Guidelines

Contributions are welcome! If you're opening a PR that adds features or options *please consider
writing full [unit tests][11] for them*. (We've built simple fixtures for almost everything
and are happy to add some for your case if necessary).

Set up the development environment with:
```
$ git clone https://github.com/sc-forks/solidity-coverage.git
$ yarn
```

### Contributors
## Contributors
+ [@area](https://github.com/area)
+ [@cgewecke](https://github.com/cgewecke)
+ [@adriamb](https://github.com/adriamb)
Expand All @@ -146,3 +123,28 @@ $ yarn
+ [@pinkiebell](https://github.com/pinkiebell)
+ [@obernardovieira](https://github.com/obernardovieira)
+ [@angus-hamill](https://github.com/angus-hamill)
+ [@kandrianov](https://github.com/kandrianov)
+ [@yxliang01](https://github.com/yxliang01)

[1]: https://github.com/trufflesuite/ganache-core#options
[2]: https://istanbul.js.org/docs/advanced/alternative-reporters/
[3]: https://mochajs.org/api/mocha
[4]: https://github.com/sc-forks/solidity-coverage/blob/beta/docs/faq.md#running-out-of-gas
[5]: https://github.com/sc-forks/solidity-coverage/blob/beta/docs/faq.md#running-out-of-memory
[6]: https://github.com/sc-forks/solidity-coverage/blob/beta/docs/faq.md#running-out-of-time
[7]: https://github.com/sc-forks/solidity-coverage/blob/beta/docs/faq.md#continuous-integration
[8]: https://github.com/sc-forks/solidity-coverage/blob/beta/docs/faq.md#notes-on-branch-coverage
[9]: https://sc-forks.github.io/metacoin/
[10]: https://coveralls.io/github/OpenZeppelin/openzeppelin-solidity?branch=master
[11]: https://github.com/sc-forks/solidity-coverage/tree/beta/test/units
[12]: https://github.com/sc-forks/solidity-coverage/issues
[13]: https://github.com/sc-forks/solidity-coverage/blob/beta/docs/faq.md#notes-on-gas-distortion
[14]: https://github.com/sc-forks/solidity-coverage/blob/beta/docs/advanced.md
[15]: #config-options
[16]: https://blog.colony.io/code-coverage-for-solidity-eecfa88668c2
[17]: https://github.com/JoinColony/solcover
[18]: https://gitter.im/sc-forks/solidity-coverage?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
[19]: https://badge.fury.io/js/solidity-coverage
[20]: https://circleci.com/gh/sc-forks/solidity-coverage
[21]: https://codecov.io/gh/sc-forks/solidity-coverage
[22]: https://cdn-images-1.medium.com/max/800/1*uum8t-31bUaa6dTRVVhj6w.png
23 changes: 0 additions & 23 deletions bin/exec.js

This file was deleted.

18 changes: 18 additions & 0 deletions buidler.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

// Mute compiler warnings - this will need to be addressed properly in
// the Buidler plugin by overloading TASK_COMPILE_COMPILE.
const originalLog = console.log;
console.warn = () => {};
console.log = val => val === '\n' ? null : originalLog(val);

module.exports = {
solc: {
version: "0.5.8"
},
paths: {
artifacts: "./test/artifacts",
cache: "./test/cache",
test: "./test/units",
sources: "./test/sources/contracts",
}
}
8 changes: 8 additions & 0 deletions dist/bin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
Logs a warning / informational message when user tries to
invoke 'solidity-coverage' as a shell command. This file
is listed as the package.json "bin".
*/
const AppUI = require('../lib/ui').AppUI;

(new AppUI()).report('command');
Empty file added dist/buidler.plugin.js
Empty file.
Loading

0 comments on commit 64a501b

Please sign in to comment.