Skip to content

Commit

Permalink
workflows, readme update
Browse files Browse the repository at this point in the history
  • Loading branch information
tuturu-tech committed Jan 11, 2024
1 parent b626a7e commit 590810e
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 10 deletions.
49 changes: 49 additions & 0 deletions .github/workflows/black.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
name: Black

defaults:
run:
# To load bashrc
shell: bash -ieo pipefail {0}

on:
pull_request:
branches: [main, dev]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
name: Black
runs-on: ubuntu-latest

steps:
- name: Checkout Code
uses: actions/checkout@v4

- name: Set up Python 3.8
uses: actions/setup-python@v4
with:
python-version: 3.8

- name: Install dependencies
run: |
pip install .
pip install deepdiff numpy
mkdir -p .github/linters
cp pyproject.toml .github/linters
- name: Black
uses: github/super-linter/[email protected]
if: always()
env:
# run linter on everything to catch preexisting problems
VALIDATE_ALL_CODEBASE: true
DEFAULT_BRANCH: master
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Run only black
VALIDATE_PYTHON_BLACK: true
PYTHON_BLACK_CONFIG_FILE: pyproject.toml
49 changes: 49 additions & 0 deletions .github/workflows/mypy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
name: Mypy

defaults:
run:
# To load bashrc
shell: bash -ieo pipefail {0}

on:
pull_request:
branches: [master, dev]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
name: Mypy
runs-on: ubuntu-latest

steps:
- name: Checkout Code
uses: actions/checkout@v4

- name: Set up Python 3.8
uses: actions/setup-python@v4
with:
python-version: 3.8

- name: Install dependencies
run: |
pip install .
pip install types-setuptools
mkdir -p .github/linters
cp mypy.ini .github/linters
- name: Mypy
uses: github/super-linter/[email protected]
if: always()
env:
# run linter on everything to catch preexisting problems
VALIDATE_ALL_CODEBASE: true
DEFAULT_BRANCH: master
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Run only black
VALIDATE_PYTHON_MYPY: true
PYTHON_MYPY_CONFIG_FILE: mypy.ini
50 changes: 50 additions & 0 deletions .github/workflows/pylint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
name: Pylint

defaults:
run:
# To load bashrc
shell: bash -ieo pipefail {0}

on:
pull_request:
branches: [main, dev]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
name: Pylint
runs-on: ubuntu-latest

steps:
- name: Checkout Code
uses: actions/checkout@v4

- name: Set up Python 3.8
uses: actions/setup-python@v4
with:
python-version: 3.8

- name: Install dependencies
run: |
pip install .
pip install deepdiff numpy
mkdir -p .github/linters
cp pyproject.toml .github/linters
- name: Pylint
uses: github/super-linter/[email protected]
if: always()
env:
# run linter on everything to catch preexisting problems
VALIDATE_ALL_CODEBASE: true
DEFAULT_BRANCH: master
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Run only pylint
VALIDATE_PYTHON: true
VALIDATE_PYTHON_PYLINT: true
PYTHON_PYLINT_CONFIG_FILE: pyproject.toml
30 changes: 20 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,36 @@

# Automated tool for generating Foundry unit tests for smart contract fuzzer failed properties

`test-generator` is a Python tool that generates unit tests from [Echidna](https://github.com/crytic/echidna) and [Medusa](https://github.com/crytic/medusa/tree/master) failed properties, using the generated reproducer files. It uses [Slither](https://github.com/crytic/slither) for determining types and jinja2 for generating strings from string templates.
`test-generator` is a Python tool that generates unit tests from [Echidna](https://github.com/crytic/echidna) and [Medusa](https://github.com/crytic/medusa/tree/master) failed properties, using the generated reproducer files. It uses [Slither](https://github.com/crytic/slither) for determining types and jinja2 for generating the test files using string templates.

**Disclaimer**: Please note that `test-generator` is **under development**. Currently, not all Solidity types are supported and some types (like `bytes*`, and `string`) might be improperly decoded from the corpora call sequences.

## Features
`test-generator` provides support for:
- ✔️ Generating Foundry unit tests from the fuzzer corpus of single entry point fuzzing harnesses
- ✔️ Medusa and Echidna corpora
- ✔️ Solidity types: `bool`,`uint*`, `int*`, `address`, `struct`, `enum`, single-dimensional fixed-size arrays and dynamic arrays, multi-dimensional fixed-size arrays.

## Installation and pre-requisites

In order to be able to use test-generator, you will need to install it first:
In order to be able to use `test-generator`, you will need to install it first:

```bash
git clone [email protected]:crytic/test-generator.git
cd test-generator
pip3 install -e .
```

These commands will install all the Python libraries and tools required to run test-generator. However, it won't install Echidna or Medusa, so you will need to download and install the latest version yourself from its official releases ([Echidna](https://github.com/crytic/echidna/releases), [Medusa](https://github.com/crytic/medusa/releases)).
These commands will install all the Python libraries and tools required to run `test-generator`. However, it won't install Echidna or Medusa, so you will need to download and install the latest version yourself from its official releases ([Echidna](https://github.com/crytic/echidna/releases), [Medusa](https://github.com/crytic/medusa/releases)).

## Example

In order to generate a test file for the [BasicTypes.sol](test/src/BasicTypes.sol) contract, based on the Echidna corpus reproducers for this contract ([corpus-basic](test/echidna-corpora/corpus-basic/)), we need to `cd` into the `test` directory which contains the Foundry project and run the command:
```
In order to generate a test file for the [BasicTypes.sol](test/src/BasicTypes.sol) contract, based on the Echidna corpus reproducers for this contract ([corpus-basic](tests/test_data/echidna-corpora/corpus-basic/)), we need to `cd` into the `tests/test_data` directory which contains the Foundry project and run the command:
```bash
test-generator ./src/BasicTypes.sol --corpus-dir echidna-corpora/corpus-basic --contract "BasicTypes" --test-directory "./test/" --inheritance-path "../src/" --fuzzer echidna
```

Running this command should generate a `BasicTypes_Echidna_Test.sol` file in the [tests](/test/test/) directory of the Foundry project.

## Supported input types

The tool currently supports all elementary types (uint*, int*, bool, address, bytes, bytes*, string), one-dimensional fixed-size and dynamic arrays, structs, and enums. Any other types may or may not work.
Running this command should generate a `BasicTypes_Echidna_Test.sol` file in the [tests](/tests/test_data/test/) directory of the Foundry project.

## Command-line options

Expand All @@ -38,3 +42,9 @@ Additional options are available for the script:
- `-td`/`--test-directory` `path_to_test_directory`: The path to the test directory relative to the working directory.
- `-i`/`--inheritance-path` `relative_path_to_contract`: The relative path from the test directory to the contract (used for inheritance).
- `-f`/`--fuzzer` `fuzzer_name`: The name of the fuzzer, currently supported: `echidna` and `medusa`

## Contributing
For information about how to contribute to this project, check out the [CONTRIBUTING](CONTRIBUTING.md) guidelines.

## License
test-generator is licensed and distributed under the [AGPLv3](LICENSE).
8 changes: 8 additions & 0 deletions test_generator/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import argparse
import jinja2

from pkg_resources import require

from slither import Slither
from slither.core.declarations.contract import Contract
from test_generator.utils.crytic_print import CryticPrint
Expand Down Expand Up @@ -109,6 +111,12 @@ def main() -> None:
dest="selected_fuzzer",
help="Define the fuzzer used. Valid inputs: 'echidna', 'medusa'",
)
parser.add_argument(
"--version",
help="displays the current version",
version=require("test-generator")[0].version,
action="version",
)

args = parser.parse_args()
file_path = args.file_path
Expand Down

0 comments on commit 590810e

Please sign in to comment.