Skip to content

Commit 939334c

Browse files
authored
Merge pull request #66 from spencer-tb/tf-updates
Feature: Update `tf` to fill tests within sub-directories with depth > 1, change path defaults, add --no-output-structure option.
2 parents b028b0a + 4d62810 commit 939334c

File tree

4 files changed

+81
-32
lines changed

4 files changed

+81
-32
lines changed

README.md

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ Ethereum tests. [Further documentation](https://execution-spec-tests.readthedocs
99

1010
The following are required to either generate or develop tests:
1111

12-
1. Python `3.10.0`.
12+
1. Python >=`3.10.0`.
13+
- For dists. with the `apt` package manager ensure you have python `-dev` & `-venv` packages installed.
1314
2. [`go-ethereum`](https://github.com/ethereum/go-ethereum) `geth`'s `evm` utility must be accessible in the `PATH`, typically at the latest version. To get it:
1415
1. Install [the Go programming language](https://go.dev/doc/install) on your computer.
1516
2. Clone [the Geth repository](https://github.com/ethereum/go-ethereum).
@@ -36,7 +37,7 @@ After the installation, run this sanity check to ensure tests are generated.
3637
If everything is OK, you will see the beginning of the JSON format filled test.
3738

3839
```console
39-
tf --output="fixtures" --test-case yul
40+
tf --test-case yul
4041
head fixtures/example/example/yul.json
4142
```
4243

@@ -46,24 +47,31 @@ head fixtures/example/example/yul.json
4647
To generate all the tests defined in the `./fillers` sub-directory, run the `tf` command:
4748

4849
```console
49-
tf --output="fixtures"
50+
tf --filler-path="fillers" --output="fixtures"
5051
```
5152

53+
This is equivalent to running `tf` with no arguments. The paths`fillers/` and `fixtures/` are both defaults for the respective command.
54+
5255
Note that the test `post` conditions are tested against the output of the `geth` `evm` utility during test generation.
5356

54-
To generate all the tests in the `./fillers/vm` sub-directory (category), for example, run:
57+
To generate all the tests within the `./fillers/vm` directory (category), for example, run:
5558
```console
56-
tf --output="fixtures" --test-categories vm
59+
tf --test-categories vm
60+
```
61+
62+
This extends to sub-directories. To generate all specific tests within the `./fillers/vm/vm_arith/vm_add` sub-directory, run:
63+
```console
64+
tf --output="fixtures" --test-categories vm/vm_arith/vm_add
5765
```
5866

5967
To generate all the tests in the `./fillers/*/dup.py` modules, for example, run:
6068
```console
61-
tf --output="fixtures" --test-module dup
69+
tf --test-module dup
6270
```
6371

6472
To generate specific tests, such as `./fillers/*/*.py::test_dup`, for example, run (remove the `test_` prefix from the test case's function name):
6573
```console
66-
tf --output="fixtures" --test-case dup
74+
tf --test-case dup
6775
```
6876

6977
### Testing the Execution Spec Tests Framework
@@ -156,6 +164,9 @@ A new test can be added by either:
156164
the new test function(s).
157165
- Creating an entirely new category by adding a subdirectory in
158166
`fillers` with the appropriate source files and test functions.
167+
- Tests within multiple sub-directories must have a `__init__.py` file
168+
within each directory above it (and it own), to ensure the test is found by the test filler `tf`.
169+
159170

160171
### Test Spec Generator Functions
161172

docs/getting_started/01_quick_start.md

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
The following are required to either generate or develop tests:
66

77
1. Python `3.10.0`.
8+
- For dists. with the `apt` package manager ensure you have python `-dev` & `-venv` packages installed.
89
2. [`go-ethereum`](https://github.com/ethereum/go-ethereum) `geth`'s `evm` utility must be accessible in the `PATH`, typically at the latest version. To get it:
910
1. Install [the Go programming language](https://go.dev/doc/install) on your computer.
1011
2. Clone [the Geth repository](https://github.com/ethereum/go-ethereum).
@@ -31,7 +32,7 @@ After the installation, run this sanity check to ensure tests are generated.
3132
If everything is OK, you will see the beginning of the JSON format filled test.
3233

3334
```console
34-
tf --output="fixtures" --test-case yul
35+
tf --test-case yul
3536
head fixtures/example/example/yul.json
3637
```
3738

@@ -41,24 +42,32 @@ head fixtures/example/example/yul.json
4142
To generate all the tests defined in the `./fillers` sub-directory, run the `tf` command:
4243

4344
```console
44-
tf --output="fixtures"
45+
tf --filler-path="fillers" --output="fixtures"
4546
```
4647

47-
Note that the test `post` conditions are tested against the output of the `geth` `evm` utility during test generation.
48+
This is equivalent to running `tf` with no arguments. The paths`fillers/` and `fixtures/` are both defaults for the respective command.
49+
50+
!!! note
51+
The test `post` conditions are tested against the output of the `geth` `evm` utility during test generation.
4852

4953
To generate all the tests in the `./fillers/vm` sub-directory (category), for example, run:
5054
```console
51-
tf --output="fixtures" --test-categories vm
55+
tf --test-categories vm
56+
```
57+
58+
This extends to sub-directories. To generate all specific tests within the `./fillers/vm/vm_arith/vm_add` sub-directory, run:
59+
```console
60+
tf --output="fixtures" --test-categories vm/vm_arith/vm_add
5261
```
5362

5463
To generate all the tests in the `./fillers/*/dup.py` modules, for example, run:
5564
```console
56-
tf --output="fixtures" --test-module dup
65+
tf --test-module dup
5766
```
5867

5968
To generate specific tests, such as `./fillers/*/*.py::test_dup`, for example, run (remove the `test_` prefix from the test case's function name):
6069
```console
61-
tf --output="fixtures" --test-case dup
70+
tf --test-case dup
6271
```
6372

6473
## Testing the Execution Spec Tests Framework

docs/getting_started/03_writing_tests.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ A new test can be added by either:
4949
the new test function(s).
5050
- Creating an entirely new category by adding a subdirectory in
5151
`fillers` with the appropriate source files and test functions.
52+
- Tests within multiple sub-directories must have a `__init__.py` file
53+
within each directory above it (and it own), to ensure the test is found by the test filler `tf`.
5254

5355
## Test Spec Generator Functions
5456

src/ethereum_test_filling_tool/main.py

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,17 @@ def parse_arguments() -> argparse.Namespace:
4242

4343
parser.add_argument(
4444
"--filler-path",
45-
help="path to filler directives",
45+
help="path to filler directives, default: ./fillers",
46+
default="fillers",
47+
type=Path,
4648
)
4749

4850
parser.add_argument(
4951
"--output",
50-
help="directory to store filled test fixtures",
51-
default="out",
52+
help="directory to store filled test fixtures, \
53+
default: ./fixtures",
54+
default="fixtures",
55+
type=Path,
5256
)
5357

5458
parser.add_argument(
@@ -75,6 +79,12 @@ def parse_arguments() -> argparse.Namespace:
7579
+ "transition tool",
7680
)
7781

82+
parser.add_argument(
83+
"--no-output-structure",
84+
action="store_true",
85+
help="removes the folder structure from test fixture output",
86+
)
87+
7888
return parser.parse_args()
7989

8090
options: argparse.Namespace
@@ -88,10 +98,7 @@ def fill(self) -> None:
8898
"""
8999
Fill test fixtures.
90100
"""
91-
pkg_path = "fillers"
92-
93-
if self.options.filler_path is not None:
94-
pkg_path = self.options.filler_path
101+
pkg_path = self.options.filler_path
95102

96103
fillers = []
97104

@@ -131,7 +138,9 @@ def fill(self) -> None:
131138
name = filler.__filler_metadata__["name"]
132139
output_dir = os.path.join(
133140
self.options.output,
134-
*(filler.__filler_metadata__["module_path"]),
141+
*(filler.__filler_metadata__["module_path"])
142+
if self.options.no_output_structure is None
143+
else "",
135144
)
136145
os.makedirs(output_dir, exist_ok=True)
137146
path = os.path.join(output_dir, f"{name}.json")
@@ -157,17 +166,35 @@ def find_modules(root, include_pkg, include_modules):
157166
root,
158167
include=include_pkg if include_pkg is not None else ("*",),
159168
):
160-
for info in iter_modules([os.path.join(root, package)]):
161-
if not info.ispkg:
162-
module_full_name = package + "." + info.name
163-
if module_full_name not in modules:
164-
if not include_modules or include_modules in info.name:
165-
yield (
166-
package,
167-
info.name,
168-
info.module_finder.find_module(module_full_name),
169-
)
170-
modules.add(module_full_name)
169+
package = package.replace(
170+
".", "/"
171+
) # sub_package tests i.e 'vm.vm_tests'
172+
for info, package_path in recursive_iter_modules(root, package):
173+
module_full_name = package_path + "." + info.name
174+
if module_full_name not in modules:
175+
if not include_modules or include_modules in info.name:
176+
yield (
177+
package,
178+
info.name,
179+
info.module_finder.find_module(module_full_name),
180+
)
181+
modules.add(module_full_name)
182+
183+
184+
def recursive_iter_modules(root, package):
185+
"""
186+
Helper function for find_packages.
187+
Iterates through all sub-packages (packages within a package).
188+
Recursively navigates down the package tree until a new module is found.
189+
"""
190+
for info in iter_modules([os.path.join(root, package)]):
191+
if info.ispkg:
192+
yield from recursive_iter_modules(
193+
root, os.path.join(package, info.name)
194+
)
195+
else:
196+
package_path = package.replace("/", ".")
197+
yield info, package_path
171198

172199

173200
def main() -> None:

0 commit comments

Comments
 (0)