Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/notes/2.32.x.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ The `find-links` automatically injected by `pants.backend.plugin_development` is

Fixed inverted logic when setting noninteractive_process_output to only log failures.

#### Test

The `test` goal has a new `--show-all-batch-targets` option. When tests are batched via `batch_compatibility_tag`, the default output truncates the list of targets (e.g. `path/to:tests and 3 other files`). Enabling this option shows all target addresses in test result summaries and workunit descriptions, which is useful for understanding exactly which targets are grouped together in each test invocation.

### Backends

#### Docker
Expand Down
26 changes: 16 additions & 10 deletions src/python/pants/backend/python/goals/pytest_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -441,11 +441,14 @@ async def setup_pytest_for_target(
else:
timeout_seconds = timeout

run_description = request.field_sets[0].address.spec
if len(request.field_sets) > 1:
run_description = (
f"batch of {run_description} and {len(request.field_sets) - 1} other files"
)
if test_subsystem.show_all_batch_targets and len(request.field_sets) > 1:
run_description = ", ".join(fs.address.spec for fs in request.field_sets)
else:
run_description = request.field_sets[0].address.spec
if len(request.field_sets) > 1:
run_description = (
f"batch of {run_description} and {len(request.field_sets) - 1} other files"
)
process = await setup_venv_pex_process(
VenvPexProcess(
pytest_runner_pex,
Expand Down Expand Up @@ -533,11 +536,14 @@ async def run_python_tests(
last_result = results.last

def warning_description() -> str:
description = batch.elements[0].address.spec
if len(batch.elements) > 1:
description = (
f"batch containing {description} and {len(batch.elements) - 1} other files"
)
if test_subsystem.show_all_batch_targets and len(batch.elements) > 1:
description = ", ".join(fs.address.spec for fs in batch.elements)
else:
description = batch.elements[0].address.spec
if len(batch.elements) > 1:
description = (
f"batch containing {description} and {len(batch.elements) - 1} other files"
)
if batch.partition_metadata.description:
description = f"{description} ({batch.partition_metadata.description})"
return description
Expand Down
35 changes: 32 additions & 3 deletions src/python/pants/core/goals/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,23 @@ def default_process_cache_scope(self) -> ProcessCacheScope:
"""
),
)
show_all_batch_targets = BoolOption(
default=False,
help=softwrap(
"""
When tests are batched via `batch_compatibility_tag`, show all target addresses in
the batch in test result summaries, workunit descriptions, and warning messages.

By default, batched test descriptions are truncated to show only the first target
address (e.g. "path/to:tests and 3 other files"). When this option is enabled, all
target addresses in the batch are listed (e.g.
"path/to:tests, path/to:tests2, path/to:tests3, path/to:tests4").

This is useful for CI environments where you need to know exactly which targets
are grouped together in each test invocation.
"""
),
)

def report_dir(self, distdir: DistDir) -> PurePath:
return PurePath(self._report_dir.format(distdir=distdir.relpath))
Expand Down Expand Up @@ -1024,7 +1041,9 @@ async def run_tests(
test_result_info[result.addresses[0].spec] = {
"source": result.result_metadata.source(run_id).value
}
console.print_stderr(_format_test_summary(result, run_id, console))
console.print_stderr(
_format_test_summary(result, run_id, console, test_subsystem.show_all_batch_targets)
)

if result.extra_output and result.extra_output.files:
path_prefix = str(distdir.relpath / "test" / result.path_safe_description)
Expand Down Expand Up @@ -1121,7 +1140,12 @@ async def run_tests(
}


def _format_test_summary(result: TestResult, run_id: RunId, console: Console) -> str:
def _format_test_summary(
result: TestResult,
run_id: RunId,
console: Console,
show_all_batch_targets: bool = False,
) -> str:
"""Format the test summary printed to the console."""
assert result.result_metadata is not None, (
"Skipped test results should not be outputted in the test summary"
Expand Down Expand Up @@ -1164,7 +1188,12 @@ def _format_test_summary(result: TestResult, run_id: RunId, console: Console) ->
elapsed_secs = total_elapsed_ms / 1000
elapsed_print = f"in {elapsed_secs:.2f}s"

return f"{sigil} {result.description} {status}{attempt_msg} {elapsed_print}{source_desc}."
if show_all_batch_targets and len(result.addresses) > 1:
description = ", ".join(addr.spec for addr in result.addresses)
else:
description = result.description

return f"{sigil} {description} {status}{attempt_msg} {elapsed_print}{source_desc}."


def _format_test_rerun_command(results: Iterable[TestResult]) -> None | str:
Expand Down
10 changes: 6 additions & 4 deletions src/python/pants/core/goals/test_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ def run_test_rule(
shard="",
batch_size=1,
show_rerun_command=show_rerun_command,
show_all_batch_targets=False,
)
debug_adapter_subsystem = create_subsystem(
DebugAdapterSubsystem,
Expand Down Expand Up @@ -341,17 +342,18 @@ def mock_coverage_report_generation(
],
mock_calls={
"pants.core.goals.test.partition_tests": mock_partitioner,
"pants.core.environments.rules.resolve_single_environment_name": lambda _a: EnvironmentName(
None
"pants.core.environments.rules.resolve_single_environment_name": lambda _a: (
EnvironmentName(None)
),
"pants.core.goals.test.test_batch_to_debug_request": mock_debug_request,
"pants.core.goals.test.test_batch_to_debug_adapter_request": mock_debug_request,
"pants.core.goals.test.run_test_batch": mock_test_partition,
"pants.core.goals.test.create_coverage_report": mock_coverage_report_generation,
"pants.engine.internals.specs_rules.find_valid_field_sets_for_target_roots": mock_find_valid_field_sets,
"pants.engine.intrinsics.merge_digests": lambda _: EMPTY_DIGEST,
"pants.engine.intrinsics._interactive_process": lambda _p,
_e: InteractiveProcessResult(0),
"pants.engine.intrinsics._interactive_process": lambda _p, _e: (
InteractiveProcessResult(0)
),
},
union_membership=union_membership,
# We don't want temporary warnings to interfere with our expected output.
Expand Down
Loading