foundry-rs / foundry

Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.
https://getfoundry.sh
Apache License 2.0
8.31k stars 1.76k forks source link

Add identifier to running test to allow introspection (test name, test file, test runner) #5826

Open holic opened 1 year ago

holic commented 1 year ago

Component

Forge

Describe the feature you would like

I have a few test files that each call vm.ffi to run a separate process during setUp. However, the tests running in parallel causes trouble for that specific process.

I'd like to be able to identify which test is being run (either the test function name, test file name, or some arbitrary test runner ID) so that I can pass it into vm.ffi process as an extra argument to separate executions of that process.

I could work around this by writing to some temporary file, but I'd like to do avoid fs writes and leaving around tmp files.

Additional context

No response

mds1 commented 1 year ago

Another workaround is to use msg.data or msg.data[0:4] as the extra ffi argument, but this will of course only give you the function selector+calldata, not the file name. So it's not guaranteed to be unique if you have the same test function sigs in multiple files

holic commented 1 year ago

That's not a bad idea! Although I am using vm.ffi inside setUp which would have the same function selector for each test file.

I was also wondering if I could introspect the test bytecode. Does the test file have its bytecode at address(this) in tests?

mds1 commented 1 year ago

That's not a bad idea! Although I am using vm.ffi inside setUp which would have the same function selector for each test file.

This might not work the way you expect. setUp is run one time and then the resulting state is cached to use at the beginning of each test in the contract.

I was also wondering if I could introspect the test bytecode. Does the test file have its bytecode at address(this) in tests?

IIUC, then yes with address(this).code

holic commented 1 year ago

This might not work the way you expect. setUp is run one time and then the resulting state is cached to use at the beginning of each test in the contract.

Yep, that's intended! My specific use case is calling out to a deploy script that just needs to happen once per test file/contract.

holic commented 1 year ago

I tried to ask this a few times in the Telegram chat, but got no reply, so hoping I can get an answer here:

If I run a test against an anvil node and inside the test I call vm.ffi to spawn a separate process that creates contracts on that same anvil node, will the test be aware of that chain state? Or will its state be stuck as a fork of when the test started (prior to creating contracts)?

mds1 commented 1 year ago

forge will query the chain for state/code as needed then cache the response, so the answer depends on your exact setup. It should be easy to test this to get an answer for your specific case