Add ethereum regression tests (#763)

* Clean some unused variables

* Add basic infrastructure

* Add real eth regression tests

* Use check_call

* Suppress stdout

* Make 705 work

* Less error prone way of testing
This commit is contained in:
Mark Mossberg 2018-02-22 13:04:01 -08:00 committed by GitHub
parent 8e47a6ebe9
commit d0f69c755c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 70 additions and 4 deletions

6
tests/binaries/676.sol Normal file
View File

@ -0,0 +1,6 @@
contract C {
uint public n=0;
function f() public{
n = block.number;
}
}

5
tests/binaries/678.sol Normal file
View File

@ -0,0 +1,5 @@
contract C {
function f() public returns(bytes32){
return "abc";
}
}

10
tests/binaries/701.sol Normal file
View File

@ -0,0 +1,10 @@
contract C {
function reveal(uint x, bytes32 hash) returns (bool) {
if (sha3(x) == hash) {
return true;
}
return false;
}
}

2
tests/binaries/705.sol Normal file
View File

@ -0,0 +1,2 @@
import "imp.sol";

7
tests/binaries/714.sol Normal file
View File

@ -0,0 +1,7 @@
contract C {
function() {
if (msg.data[0] == 1) {
return;
}
}
}

9
tests/binaries/735.sol Normal file
View File

@ -0,0 +1,9 @@
contract SS {
address recvr;
function setme() {
recvr = msg.sender;
}
function sui() {
suicide(recvr);
}
}

6
tests/binaries/760.sol Normal file
View File

@ -0,0 +1,6 @@
contract TEST {
function Test_SignedInteger_AdditionOverflow(int x) public {
int y = x + x;
assert(y > 0);
}
}

2
tests/binaries/imp.sol Normal file
View File

@ -0,0 +1,2 @@
contract C {
}

View File

@ -31,6 +31,16 @@ class IntegrationTest(unittest.TestCase):
return set(vitems)
def _simple_cli_run(self, filename):
"""
Simply run the Manticore command line with `filename`
:param filename: Name of file inside the `tests/binaries` directory
:return:
"""
dirname = os.path.dirname(__file__)
filename = '{}/binaries/{}'.format(dirname, filename)
subprocess.check_call(['python', '-m', 'manticore', filename], stdout=subprocess.PIPE)
def _runWithTimeout(self, procargs, logfile, timeout=1200):
with open(os.path.join(os.pardir, logfile), "w") as output:
@ -51,7 +61,6 @@ class IntegrationTest(unittest.TestCase):
filename = os.path.abspath(os.path.join(dirname, 'binaries/arguments_linux_amd64'))
self.assertTrue(filename.startswith(os.getcwd()))
filename = filename[len(os.getcwd())+1:]
data = file(filename,'rb').read()
workspace = '%s/workspace'%self.test_dir
t = time.time()
with open(os.path.join(os.pardir, '%s/output.log'%self.test_dir), "w") as output:
@ -88,7 +97,6 @@ class IntegrationTest(unittest.TestCase):
filename = os.path.abspath(os.path.join(dirname, 'binaries/arguments_linux_amd64'))
self.assertTrue(filename.startswith(os.getcwd()))
filename = filename[len(os.getcwd())+1:]
data = file(filename,'rb').read()
workspace = '%s/workspace'%self.test_dir
assertions = '%s/assertions.txt'%self.test_dir
file(assertions,'w').write('0x0000000000401003 ZF == 1')
@ -108,8 +116,6 @@ class IntegrationTest(unittest.TestCase):
filename = os.path.abspath(os.path.join(dirname, 'binaries/cadet_decree_x86'))
self.assertTrue(filename.startswith(os.getcwd()))
filename = filename[len(os.getcwd())+1:]
SE = os.path.join(dirname, '../main.py')
data = file(filename,'rb').read()
workspace = '%s/workspace'%self.test_dir
self._runWithTimeout(['python', '-m', 'manticore',
'--workspace', workspace,
@ -121,6 +127,19 @@ class IntegrationTest(unittest.TestCase):
actual = self._loadVisitedSet(os.path.join(dirname, '%s/visited.txt'%workspace))
self.assertTrue(len(actual) > 100 )
def test_eth_regressions(self):
contracts = [676, 678, 701, 714, 735, 760]
for contract in contracts:
self._simple_cli_run('{}.sol'.format(contract))
def test_eth_705(self):
# This test needs to run inside tests/binaries because the contract imports a file
# that is in the tests/binaries dir
dirname = os.path.dirname(__file__)
old_cwd = os.getcwd()
os.chdir('{}/binaries'.format(dirname))
self._simple_cli_run('705.sol')
os.chdir(old_cwd)
if __name__ == '__main__':
unittest.main()