Skip to content

Commit

Permalink
formatting changes
Browse files Browse the repository at this point in the history
  • Loading branch information
tuturu-tech committed Jan 11, 2024
1 parent 30f0172 commit 1cae612
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 37 deletions.
7 changes: 6 additions & 1 deletion test_generator/fuzzers/Echidna.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from test_generator.templates.foundry_templates import templates
from test_generator.utils.encoding import parse_echidna_byte_string


class Echidna:
"""
Handles the generation of Foundry test files from Echidna reproducers
Expand Down Expand Up @@ -144,7 +145,11 @@ def _match_elementary_types(self, param: dict, recursive: bool) -> str:
hex_string = parse_echidna_byte_string(contents.strip('"'))
interpreted_string = f'hex"{hex_string}"'
if not recursive:
result = f"bytes{size}({interpreted_string})" if is_fixed_size else interpreted_string
result = (
f"bytes{size}({interpreted_string})"
if is_fixed_size
else interpreted_string
)
return result
else:
casting = f"bytes{size}({interpreted_string})"
Expand Down
14 changes: 8 additions & 6 deletions test_generator/utils/encoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import re

ascii_escape_map = {
"\\NUL": "\x00", # Null character
"\\NUL": "\x00", # Null character
"\\SOH": "\x01",
"\\STX": "\x02",
"\\ETX": "\x03",
Expand Down Expand Up @@ -32,17 +32,18 @@
"\\SP": "\x20",
"\\DEL": "\x7f",
"\\0": "\x00",
"\\a": "\x07", # Alert
"\\b": "\x08", # Backspace
"\\a": "\x07", # Alert
"\\b": "\x08", # Backspace
"\\f": "\x0c",
"\\n": "\x0a", # New line
"\\r": "\x0d",
"\\t": "\x09", # Horizontal Tab
"\\t": "\x09", # Horizontal Tab
"\\v": "\x0b", # Vertical Tab
}


def parse_echidna_byte_string(s: str) -> str:
""" Parses Haskell byte sequence into a Solidity hex literal"""
"""Parses Haskell byte sequence into a Solidity hex literal"""
# Replace Haskell-specific escapes with Python bytes
for key, value in ascii_escape_map.items():
s = s.replace(key, value)
Expand All @@ -58,5 +59,6 @@ def octal_to_byte(match):
# Convert to bytes and then to hexadecimal
return s.encode().hex()


def parse_medusa_byte_string(s: str) -> str:
return s.encode('utf-8').hex()
return s.encode("utf-8").hex()
18 changes: 14 additions & 4 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,38 @@
from test_generator.fuzzers.Echidna import Echidna
from test_generator.fuzzers.Medusa import Medusa


class TestGenerator:
def __init__(self, target, target_path, corpus_dir):
slither = Slither(target_path)
echidna = Echidna(target, f"echidna-corpora/{corpus_dir}", slither)
medusa = Medusa(target, f"medusa-corpora/{corpus_dir}", slither)
self.echidna_generator = FoundryTest("../src/", target, f"echidna-corpora/{corpus_dir}", "./test/", slither, echidna)
self.medusa_generator = FoundryTest("../src/", target, f"medusa-corpora/{corpus_dir}", "./test/", slither, medusa)
self.echidna_generator = FoundryTest(
"../src/", target, f"echidna-corpora/{corpus_dir}", "./test/", slither, echidna
)
self.medusa_generator = FoundryTest(
"../src/", target, f"medusa-corpora/{corpus_dir}", "./test/", slither, medusa
)

def echidna_generate_tests(self):
self.echidna_generator.create_poc()

def medusa_generate_tests(self):
self.medusa_generator.create_poc()


@pytest.fixture(autouse=True)
def change_test_dir(request, monkeypatch):
# Directory of the test file
test_dir = request.fspath.dirname

# Path to the test_data directory
data_dir = os.path.join(test_dir, 'test_data')
data_dir = os.path.join(test_dir, "test_data")

# Change the current working directory to test_data
monkeypatch.chdir(data_dir)


@pytest.fixture
def basic_types():
target = "BasicTypes"
Expand All @@ -38,6 +45,7 @@ def basic_types():

return TestGenerator(target, target_path, corpus_dir)


@pytest.fixture
def fixed_size_arrays():
target = "FixedArrays"
Expand All @@ -46,6 +54,7 @@ def fixed_size_arrays():

return TestGenerator(target, target_path, corpus_dir)


@pytest.fixture
def dynamic_arrays():
target = "DynamicArrays"
Expand All @@ -54,10 +63,11 @@ def dynamic_arrays():

return TestGenerator(target, target_path, corpus_dir)


@pytest.fixture
def structs_and_enums():
target = "TupleTypes"
target_path = "./src/TupleTypes.sol"
corpus_dir = "corpus-struct"

return TestGenerator(target, target_path, corpus_dir)
return TestGenerator(target, target_path, corpus_dir)
50 changes: 37 additions & 13 deletions tests/test_types_echidna.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
TEST_DATA_DIR = Path(__file__).resolve().parent / "test_data"
PATTERN = r"(\d+)\s+failing tests,\s+(\d+)\s+tests succeeded"


def test_echidna_basic_types(basic_types):
basic_types.echidna_generate_tests()
# Ensure the file was created
Expand All @@ -17,12 +18,17 @@ def test_echidna_basic_types(basic_types):
subprocess.run(["forge", "build", "--build-info"], capture_output=True, text=True, check=True)

# Ensure the file can be tested
result = subprocess.run(["forge", "test", "--match-contract", "BasicTypes_Echidna_Test"], capture_output=True, text=True, check=False)
result = subprocess.run(
["forge", "test", "--match-contract", "BasicTypes_Echidna_Test"],
capture_output=True,
text=True,
check=False,
)
output = result.stdout

# Remove ansi escape sequences
ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
result = ansi_escape.sub('', output)
ansi_escape = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
result = ansi_escape.sub("", output)

# Ensure all tests fail
match = re.search(PATTERN, result)
Expand All @@ -32,6 +38,7 @@ def test_echidna_basic_types(basic_types):
else:
assert False, "No tests were ran"


def test_echidna_fixed_array_types(fixed_size_arrays):
fixed_size_arrays.echidna_generate_tests()
# Ensure the file was created
Expand All @@ -42,12 +49,17 @@ def test_echidna_fixed_array_types(fixed_size_arrays):
subprocess.run(["forge", "build", "--build-info"], capture_output=True, text=True, check=True)

# Ensure the file can be tested
result = subprocess.run(["forge", "test", "--match-contract", "FixedArrays_Echidna_Test"], capture_output=True, text=True, check=False)
result = subprocess.run(
["forge", "test", "--match-contract", "FixedArrays_Echidna_Test"],
capture_output=True,
text=True,
check=False,
)
output = result.stdout

# Remove ansi escape sequences
ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
result = ansi_escape.sub('', output)
ansi_escape = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
result = ansi_escape.sub("", output)

# Ensure all tests fail
match = re.search(PATTERN, result)
Expand All @@ -57,6 +69,7 @@ def test_echidna_fixed_array_types(fixed_size_arrays):
else:
assert False, "No tests were ran"


def test_echidna_dynamic_array_types(dynamic_arrays):
dynamic_arrays.echidna_generate_tests()
# Ensure the file was created
Expand All @@ -67,12 +80,17 @@ def test_echidna_dynamic_array_types(dynamic_arrays):
subprocess.run(["forge", "build", "--build-info"], capture_output=True, text=True, check=True)

# Ensure the file can be tested
result = subprocess.run(["forge", "test", "--match-contract", "DynamicArrays_Echidna_Test"], capture_output=True, text=True, check=False)
result = subprocess.run(
["forge", "test", "--match-contract", "DynamicArrays_Echidna_Test"],
capture_output=True,
text=True,
check=False,
)
output = result.stdout

# Remove ansi escape sequences
ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
result = ansi_escape.sub('', output)
ansi_escape = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
result = ansi_escape.sub("", output)

# Ensure all tests fail
match = re.search(PATTERN, result)
Expand All @@ -82,6 +100,7 @@ def test_echidna_dynamic_array_types(dynamic_arrays):
else:
assert False, "No tests were ran"


def test_echidna_structs_and_enums(structs_and_enums):
structs_and_enums.echidna_generate_tests()
# Ensure the file was created
Expand All @@ -92,17 +111,22 @@ def test_echidna_structs_and_enums(structs_and_enums):
subprocess.run(["forge", "build", "--build-info"], capture_output=True, text=True, check=True)

# Ensure the file can be tested
result = subprocess.run(["forge", "test", "--match-contract", "TupleTypes_Echidna_Test"], capture_output=True, text=True, check=False)
result = subprocess.run(
["forge", "test", "--match-contract", "TupleTypes_Echidna_Test"],
capture_output=True,
text=True,
check=False,
)
output = result.stdout

# Remove ansi escape sequences
ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
result = ansi_escape.sub('', output)
ansi_escape = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
result = ansi_escape.sub("", output)

# Ensure all tests fail
match = re.search(PATTERN, result)
if match:
tests_passed = int(match.group(2))
assert tests_passed == 0
else:
assert False, "No tests were ran"
assert False, "No tests were ran"
50 changes: 37 additions & 13 deletions tests/test_types_medusa.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
TEST_DATA_DIR = Path(__file__).resolve().parent / "test_data"
PATTERN = r"(\d+)\s+failing tests,\s+(\d+)\s+tests succeeded"


def test_medusa_basic_types(basic_types):
basic_types.medusa_generate_tests()
# Ensure the file was created
Expand All @@ -17,12 +18,17 @@ def test_medusa_basic_types(basic_types):
subprocess.run(["forge", "build", "--build-info"], capture_output=True, text=True, check=True)

# Ensure the file can be tested
result = subprocess.run(["forge", "test", "--match-contract", "BasicTypes_Medusa_Test"], capture_output=True, text=True, check=False)
result = subprocess.run(
["forge", "test", "--match-contract", "BasicTypes_Medusa_Test"],
capture_output=True,
text=True,
check=False,
)
output = result.stdout

# Remove ansi escape sequences
ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
result = ansi_escape.sub('', output)
ansi_escape = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
result = ansi_escape.sub("", output)

# Ensure all tests fail
match = re.search(PATTERN, result)
Expand All @@ -32,6 +38,7 @@ def test_medusa_basic_types(basic_types):
else:
assert False, "No tests were ran"


def test_medusa_fixed_array_types(fixed_size_arrays):
fixed_size_arrays.medusa_generate_tests()
# Ensure the file was created
Expand All @@ -42,12 +49,17 @@ def test_medusa_fixed_array_types(fixed_size_arrays):
subprocess.run(["forge", "build", "--build-info"], capture_output=True, text=True, check=True)

# Ensure the file can be tested
result = subprocess.run(["forge", "test", "--match-contract", "FixedArrays_Medusa_Test"], capture_output=True, text=True, check=False)
result = subprocess.run(
["forge", "test", "--match-contract", "FixedArrays_Medusa_Test"],
capture_output=True,
text=True,
check=False,
)
output = result.stdout

# Remove ansi escape sequences
ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
result = ansi_escape.sub('', output)
ansi_escape = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
result = ansi_escape.sub("", output)

# Ensure all tests fail
match = re.search(PATTERN, result)
Expand All @@ -57,6 +69,7 @@ def test_medusa_fixed_array_types(fixed_size_arrays):
else:
assert False, "No tests were ran"


def test_medusa_dynamic_array_types(dynamic_arrays):
dynamic_arrays.medusa_generate_tests()
# Ensure the file was created
Expand All @@ -67,12 +80,17 @@ def test_medusa_dynamic_array_types(dynamic_arrays):
subprocess.run(["forge", "build", "--build-info"], capture_output=True, text=True, check=True)

# Ensure the file can be tested
result = subprocess.run(["forge", "test", "--match-contract", "DynamicArrays_Medusa_Test"], capture_output=True, text=True, check=False)
result = subprocess.run(
["forge", "test", "--match-contract", "DynamicArrays_Medusa_Test"],
capture_output=True,
text=True,
check=False,
)
output = result.stdout

# Remove ansi escape sequences
ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
result = ansi_escape.sub('', output)
ansi_escape = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
result = ansi_escape.sub("", output)

# Ensure all tests fail
match = re.search(PATTERN, result)
Expand All @@ -82,6 +100,7 @@ def test_medusa_dynamic_array_types(dynamic_arrays):
else:
assert False, "No tests were ran"


def test_medusa_structs_and_enums(structs_and_enums):
structs_and_enums.medusa_generate_tests()
# Ensure the file was created
Expand All @@ -92,17 +111,22 @@ def test_medusa_structs_and_enums(structs_and_enums):
subprocess.run(["forge", "build", "--build-info"], capture_output=True, text=True, check=True)

# Ensure the file can be tested
result = subprocess.run(["forge", "test", "--match-contract", "TupleTypes_Medusa_Test"], capture_output=True, text=True, check=False)
result = subprocess.run(
["forge", "test", "--match-contract", "TupleTypes_Medusa_Test"],
capture_output=True,
text=True,
check=False,
)
output = result.stdout

# Remove ansi escape sequences
ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
result = ansi_escape.sub('', output)
ansi_escape = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
result = ansi_escape.sub("", output)

# Ensure all tests fail
match = re.search(PATTERN, result)
if match:
tests_passed = int(match.group(2))
assert tests_passed == 0
else:
assert False, "No tests were ran"
assert False, "No tests were ran"

0 comments on commit 1cae612

Please sign in to comment.