Skip to content

Commit f6c6e6e

Browse files
authored
Refactor gen_runner (#4310)
1 parent 6b51684 commit f6c6e6e

File tree

6 files changed

+306
-473
lines changed

6 files changed

+306
-473
lines changed

Makefile

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -234,11 +234,10 @@ gen_list:
234234
gen_%: MAYBE_VERBOSE := $(if $(filter true,$(verbose)),--verbose)
235235
gen_%: MAYBE_MODCHECK := $(if $(filter true,$(modcheck)),--modcheck)
236236
gen_%: MAYBE_THREADS := $(if $(threads),--threads=$(threads))
237-
gen_%: MAYBE_TESTS := $(if $(k),--case-list $(subst ${COMMA}, ,$(k)))
238-
gen_%: MAYBE_FORKS := $(if $(fork),--fork-list $(subst ${COMMA}, ,$(fork)))
239-
gen_%: MAYBE_PRESETS := $(if $(preset),--preset-list $(subst ${COMMA}, ,$(preset)))
237+
gen_%: MAYBE_TESTS := $(if $(k),--cases $(subst ${COMMA}, ,$(k)))
238+
gen_%: MAYBE_FORKS := $(if $(fork),--forks $(subst ${COMMA}, ,$(fork)))
239+
gen_%: MAYBE_PRESETS := $(if $(preset),--presets $(subst ${COMMA}, ,$(preset)))
240240
gen_%: pyspec
241-
@mkdir -p $(TEST_VECTOR_DIR)
242241
@$(PYTHON_VENV) $(GENERATOR_DIR)/$*/main.py \
243242
--output $(TEST_VECTOR_DIR) \
244243
$(MAYBE_VERBOSE) \
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import argparse
2+
import os
3+
import pathlib
4+
5+
6+
def parse_arguments(generator_name):
7+
parser = argparse.ArgumentParser(
8+
prog="gen-" + generator_name,
9+
description=f"Generate YAML test suite files for {generator_name}.",
10+
)
11+
parser.add_argument(
12+
"-o",
13+
"--output-dir",
14+
dest="output_dir",
15+
required=True,
16+
type=pathlib.Path,
17+
help="Directory into which the generated YAML files will be dumped.",
18+
)
19+
parser.add_argument(
20+
"--presets",
21+
dest="presets",
22+
nargs="*",
23+
type=str,
24+
default=[],
25+
required=False,
26+
help="Specify presets to run with. Allows all if no preset names are specified.",
27+
)
28+
parser.add_argument(
29+
"--forks",
30+
dest="forks",
31+
nargs="*",
32+
type=str,
33+
default=[],
34+
required=False,
35+
help="Specify forks to run with. Allows all if no fork names are specified.",
36+
)
37+
parser.add_argument(
38+
"--cases",
39+
dest="cases",
40+
nargs="*",
41+
type=str,
42+
default=[],
43+
required=False,
44+
help="Specify test cases to run with. Allows all if no test case names are specified.",
45+
)
46+
parser.add_argument(
47+
"--modcheck",
48+
action="store_true",
49+
default=False,
50+
help="Check generator modules, do not run any tests.",
51+
)
52+
parser.add_argument(
53+
"--verbose",
54+
action="store_true",
55+
default=False,
56+
help="Print more information to the console.",
57+
)
58+
parser.add_argument(
59+
"--threads",
60+
type=int,
61+
default=os.cpu_count(),
62+
help="Generate tests with N threads. Defaults to core count.",
63+
)
64+
return parser.parse_args()
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
from eth2spec.test import context
2+
from eth_utils import encode_hex
3+
from ruamel.yaml import YAML
4+
from snappy import compress
5+
6+
from .gen_typing import TestCase
7+
8+
9+
def get_default_yaml():
10+
yaml = YAML(pure=True)
11+
yaml.default_flow_style = None
12+
13+
def _represent_none(self, _):
14+
return self.represent_scalar("tag:yaml.org,2002:null", "null")
15+
16+
def _represent_str(self, data):
17+
if data.startswith("0x"):
18+
# Without this, a zero-byte hex string is represented without quotes.
19+
return self.represent_scalar("tag:yaml.org,2002:str", data, style="'")
20+
return self.represent_str(data)
21+
22+
yaml.representer.add_representer(type(None), _represent_none)
23+
yaml.representer.add_representer(str, _represent_str)
24+
25+
return yaml
26+
27+
28+
def get_cfg_yaml():
29+
# Spec config is using a YAML subset
30+
cfg_yaml = YAML(pure=True)
31+
cfg_yaml.default_flow_style = False # Emit separate line for each key
32+
33+
def cfg_represent_bytes(self, data):
34+
return self.represent_int(encode_hex(data))
35+
36+
cfg_yaml.representer.add_representer(bytes, cfg_represent_bytes)
37+
38+
def cfg_represent_quoted_str(self, data):
39+
return self.represent_scalar("tag:yaml.org,2002:str", data, style="'")
40+
41+
cfg_yaml.representer.add_representer(context.quoted_str, cfg_represent_quoted_str)
42+
return cfg_yaml
43+
44+
45+
class Dumper:
46+
"""Helper for dumping test case outputs (cfg, data, meta, ssz)."""
47+
48+
def __init__(self, default_yaml: YAML = None, cfg_yaml: YAML = None):
49+
self.default_yaml = default_yaml or get_default_yaml()
50+
self.cfg_yaml = cfg_yaml or get_cfg_yaml()
51+
52+
def dump_meta(self, test_case: TestCase, meta: dict) -> None:
53+
if not meta:
54+
return
55+
self._dump_yaml(test_case, "meta", meta, self.default_yaml)
56+
57+
def dump_cfg(self, test_case: TestCase, name: str, data: any) -> None:
58+
self._dump_yaml(test_case, name, data, self.cfg_yaml)
59+
60+
def dump_data(self, test_case: TestCase, name: str, data: any) -> None:
61+
self._dump_yaml(test_case, name, data, self.default_yaml)
62+
63+
def dump_ssz(self, test_case: TestCase, name: str, data: bytes) -> None:
64+
"""Compress and write SSZ data for test case."""
65+
path = test_case.dir / f"{name}.ssz_snappy"
66+
path.parent.mkdir(parents=True, exist_ok=True)
67+
with path.open("wb") as f:
68+
f.write(compress(data))
69+
70+
def _dump_yaml(self, test_case: TestCase, name: str, data: any, yaml_encoder: YAML) -> None:
71+
"""Helper to write YAML files for test case."""
72+
path = test_case.dir / f"{name}.yaml"
73+
path.parent.mkdir(parents=True, exist_ok=True)
74+
with path.open("w") as f:
75+
yaml_encoder.dump(data, f)

0 commit comments

Comments
 (0)