Skip to content

Add init_expr keyword argument to runtests#237

Open
nickrobinson251 wants to merge 3 commits intomainfrom
npr-claude-init-expr
Open

Add init_expr keyword argument to runtests#237
nickrobinson251 wants to merge 3 commits intomainfrom
npr-claude-init-expr

Conversation

@nickrobinson251
Copy link
Member

Summary

  • Add new init_expr keyword argument that runs initialization code before any tests
  • Unlike worker_init_expr, init_expr also works when nworkers=0
  • When nworkers>0, runs on each worker process (same as worker_init_expr)
  • When nworkers=0, runs in the main process before test execution
  • Error if both init_expr and worker_init_expr are specified

Test plan

  • Added integration tests for init_expr with nworkers=0
  • Added integration tests for init_expr with nworkers>0
  • Added test that specifying both init_expr and worker_init_expr throws ArgumentError

🤖 Generated with Claude Code

Add a new `init_expr` keyword argument that behaves like `worker_init_expr`
but also runs when `nworkers=0`. When `nworkers>0`, it runs on each worker
process before any tests. When `nworkers=0`, it runs in the main process
before test execution.

It is an error to specify both `init_expr` and `worker_init_expr`.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a new init_expr keyword argument to runtests that provides a unified way to run initialization code before tests, working consistently across both single-process (nworkers=0) and multi-process (nworkers>0) execution modes. This replaces the need for worker_init_expr which only works in multi-process mode.

Changes:

  • Added init_expr parameter to runtests function with validation
  • Implemented execution logic for both single-process and multi-process modes
  • Added mutual exclusivity check to prevent using both init_expr and worker_init_expr

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
test/testfiles/_init_expr_test.jl New test file that verifies init_expr sets a global variable before test execution
test/integrationtests.jl Integration tests covering init_expr functionality in both execution modes and error handling
src/ReTestItems.jl Core implementation adding init_expr parameter, validation, execution logic, and documentation

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

timeout_profile_wait >= 0 || throw(ArgumentError("`timeout_profile_wait` must be a non-negative number, got $(repr(timeout_profile_wait))"))
test_end_expr.head === :block || throw(ArgumentError("`test_end_expr` must be a `:block` expression, got a `$(repr(test_end_expr.head))` expression"))
init_expr.head === :block || throw(ArgumentError("`init_expr` must be a `:block` expression, got a `$(repr(init_expr.head))` expression"))
(length(init_expr.args) > 0 && length(worker_init_expr.args) > 0) && throw(ArgumentError("Cannot specify both `init_expr` and `worker_init_expr`. Use `init_expr` instead."))
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

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

The validation allows both init_expr and worker_init_expr to be specified as long as one is empty (default Expr(:block)). This could lead to confusion where a user explicitly passes init_expr=Expr(:block) alongside worker_init_expr with actual code, and it would be accepted. Consider checking if either parameter was explicitly provided rather than just checking if they contain code. Alternatively, document this behavior clearly or reject any combination where both parameters are non-default.

Copilot uses AI. Check for mistakes.
# the workers won't be able to collect it if they get under memory pressure.
GC.gc(true)
# Use init_expr if set, otherwise use worker_init_expr (they are mutually exclusive)
effective_init_expr = length(cfg.init_expr.args) > 0 ? cfg.init_expr : cfg.worker_init_expr
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

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

This logic to select between init_expr and worker_init_expr is duplicated in three places (lines 485, 656, and implicitly at 497, 663, 762). Consider extracting this into a helper function or computing effective_init_expr once in the _Config struct to reduce duplication and ensure consistency.

Suggested change
effective_init_expr = length(cfg.init_expr.args) > 0 ? cfg.init_expr : cfg.worker_init_expr
_effective_init_expr(cfg) = length(cfg.init_expr.args) > 0 ? cfg.init_expr : cfg.worker_init_expr
effective_init_expr = _effective_init_expr(cfg)

Copilot uses AI. Check for mistakes.
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.

1 participant