Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ feat(gentest): use jinja2 templating in gentest #900

Merged
merged 11 commits into from
Oct 18, 2024

Conversation

raxhvl
Copy link
Contributor

@raxhvl raxhvl commented Oct 17, 2024

🗒️ Description

This PR introduces the use of Jinja2 templates for generating test scripts, contained within a new gentest package that includes self-contained templates and related modules.

src/cli/gentest
├── 📁 templates/blockchain_test  [Jinja2 templates]
│   └── transaction.py.j2 [Template for creating transaction based gentest]
├── 📄 __init__.py
├── 📄 request_manager.py [A request manager Ethereum  RPC calls]
├── 📄 cli.py [CLI interface for generating blockchain test scripts]
└── 📄 test_providers.py  [Context providers for creating test scripts]

Notes on code refactoring

The code has been refactored for simplicity. For instance, the previous implementation used a RemoteTransaction dataclass:

@dataclass()
class RemoteTransaction:
    """
    Remote transaction structure
    """

    block_number: int
    tr_hash: Hash
    transaction: Transaction

This required nested calls like tr.transaction:

if address == tr.transaction.sender:

The class has been flattened by making it inherit from the Transaction type, which now provides Pydantic validations out of the box:

    class RemoteTransaction(Transaction):
        """
        Model that represents a transaction.
        """

        block_number: HexNumber
        tx_hash: Hash

source

This results in a simpler interface:

if address == self.transaction.sender:

source

More importantly, pydantic rightly identified that to field of transaction can be null which is now handled:

assert transaction.to is not None

source

The test_providers module provides a predictable interface that provides context for the templates and is designed to play nice with unit testing.

Future Improvements

The generated tests can be further improved later. This PR focuses solely on the migration process, allowing for testing by diffing the generated tests against those from the main branch.

🔗 Related Issues

closes #863

✅ Checklist

  • All: Set appropriate labels for the changes.
  • All: Considered squashing commits to improve commit history.
  • All: Added an entry to CHANGELOG.md.
  • All: Considered updating the online docs in the ./docs/ directory.
  • Tests: All converted JSON/YML tests from ethereum/tests have been added to converted-ethereum-tests.txt.
  • Tests: A PR with removal of converted JSON/YML tests from ethereum/tests have been opened.
  • Tests: Included the type and version of evm t8n tool used to locally execute test cases: e.g., ref with commit hash or geth 1.13.1-stable-3f40e65.
  • Tests: Ran mkdocs serve locally and verified the auto-generated docs for new tests in the Test Case Reference are correctly formatted.

Copy link
Member

@danceratopz danceratopz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Looks like a great start to adding jinja2 templating!

I know it wasn't the focus of your PR, but I couldn't help but try and improve the output a little. The suggestions below should ensure that the generated output passes flake8/isort/mypy checks, but I might have missed something :)

src/cli/gentest/test_providers.py Outdated Show resolved Hide resolved
src/cli/gentest/test_providers.py Outdated Show resolved Hide resolved
src/cli/gentest/request_manager.py Outdated Show resolved Hide resolved
src/cli/gentest/__init__.py Outdated Show resolved Hide resolved
@raxhvl
Copy link
Contributor Author

raxhvl commented Oct 18, 2024

I passed tx_hash to the template. This gets rid of the verbose methods like _get_module_docstring, _get_test_name, and _get_test_docstring. Generally, whenever I see long strings or \n in code, I take it as an indication that the Python code has borrowed some templating logic. The TODOs I left follow this reasoning, and I will revisit them at some point.

@danceratopz
Copy link
Member

The TODOs I left follow this reasoning, and I will revisit them at some point.

Got it!

Copy link
Member

@danceratopz danceratopz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for including the suggestions!

@danceratopz danceratopz merged commit 295879d into ethereum:main Oct 18, 2024
3 checks passed
@danceratopz danceratopz changed the title ✨ feat(gentest): Migrate gentest to Jinja2 ✨ feat(gentest): use jinja2 templating in gentest Oct 18, 2024
@danceratopz danceratopz changed the title ✨ feat(gentest): use jinja2 templating in gentest ✨ feat(gentest): use jinja2 templating in gentest Oct 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

🔀(gentest): use jinja2 templates to structure python output
2 participants