SERVER-112866 suggest valid targets if bazel test +blah doesn't match anything (#42990)
GitOrigin-RevId: 62ce070cb6884e8da5b7a29875536cb7e244e7bd
This commit is contained in:
committed by
MongoDB Bot
parent
34e8e3d1dd
commit
12dc078d3a
@@ -1,3 +1,4 @@
|
||||
import difflib
|
||||
import os
|
||||
import pathlib
|
||||
import platform
|
||||
@@ -183,7 +184,20 @@ def test_runner_interface(
|
||||
):
|
||||
bin_targets.append(bin_target)
|
||||
real_target = bin_target
|
||||
replacements[arg] = [real_target]
|
||||
if not real_target:
|
||||
# Target not found - suggest similar ones and pass through
|
||||
suggestions = difflib.get_close_matches(test_name, sources_to_bin.keys(), n=5)
|
||||
error_msg = f"WARNING: Target '{arg}' not found"
|
||||
if suggestions:
|
||||
error_msg += "\n\nDid you mean one of these?\n"
|
||||
for suggestion in suggestions:
|
||||
error_msg += f" +{suggestion}\n"
|
||||
else:
|
||||
error_msg += " and no similar targets."
|
||||
print(error_msg, file=sys.stderr)
|
||||
# Pass through the argument unchanged: it might be an important argument
|
||||
else:
|
||||
replacements[arg] = [real_target]
|
||||
else:
|
||||
# defer source targets to see if we can skip redundant tests
|
||||
source_targets[test_name] = [arg, real_target]
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import sys
|
||||
import unittest
|
||||
from contextlib import redirect_stderr
|
||||
from io import StringIO
|
||||
|
||||
sys.path.append(".")
|
||||
|
||||
@@ -10,6 +12,23 @@ from bazel.wrapper_hook.plus_interface import (
|
||||
)
|
||||
|
||||
|
||||
def validate_first_suggestion(stderr_output: str, expected_suggestion: str):
|
||||
assert (
|
||||
"Did you mean one of these?" in stderr_output
|
||||
), f"Expected 'Did you mean one of these?' in stderr, got: {stderr_output}"
|
||||
|
||||
suggestion_section = stderr_output.split("Did you mean one of these?")[1]
|
||||
first_suggestion_line = [
|
||||
line.strip()
|
||||
for line in suggestion_section.split("\n")
|
||||
if line.strip() and line.strip().startswith("+")
|
||||
][0]
|
||||
|
||||
assert (
|
||||
first_suggestion_line == expected_suggestion
|
||||
), f"Expected first suggestion to be '{expected_suggestion}', got '{first_suggestion_line}'"
|
||||
|
||||
|
||||
class Tests(unittest.TestCase):
|
||||
def test_single_source_file(self):
|
||||
def buildozer_output(autocomplete_query):
|
||||
@@ -80,7 +99,9 @@ class Tests(unittest.TestCase):
|
||||
"+some_feature",
|
||||
]
|
||||
|
||||
result = test_runner_interface(args, False, buildozer_output)
|
||||
stderr_capture = StringIO()
|
||||
with redirect_stderr(stderr_capture):
|
||||
result = test_runner_interface(args, False, buildozer_output)
|
||||
|
||||
assert result == [
|
||||
"test",
|
||||
@@ -92,6 +113,10 @@ class Tests(unittest.TestCase):
|
||||
"--test_arg=source1|source2",
|
||||
]
|
||||
|
||||
# Verify that the warning for +some_feature was captured
|
||||
stderr_output = stderr_capture.getvalue()
|
||||
assert "WARNING: Target '+some_feature' not found" in stderr_output
|
||||
|
||||
def test_single_bin_file(self):
|
||||
def buildozer_output(autocomplete_query):
|
||||
return "//some:test [source1.cpp source2.cpp]"
|
||||
@@ -185,7 +210,9 @@ class Tests(unittest.TestCase):
|
||||
|
||||
args = ["wrapper_hook", "test", "+source1", "+source2", "+source3", "+source4"]
|
||||
|
||||
result = test_runner_interface(args, False, buildozer_output)
|
||||
stderr_capture = StringIO()
|
||||
with redirect_stderr(stderr_capture):
|
||||
result = test_runner_interface(args, False, buildozer_output)
|
||||
|
||||
assert result == [
|
||||
"test",
|
||||
@@ -195,6 +222,10 @@ class Tests(unittest.TestCase):
|
||||
"--test_arg=source1|source3|source4",
|
||||
]
|
||||
|
||||
# Verify that the warning for +source2 was captured
|
||||
stderr_output = stderr_capture.getvalue()
|
||||
assert "WARNING: Target '+source2' not found" in stderr_output
|
||||
|
||||
def test_prefixes(self):
|
||||
def buildozer_output(autocomplete_query):
|
||||
return "//some:test [source1.cpp source2.cpp source3.cpp s+ource4.cpp]"
|
||||
@@ -210,6 +241,64 @@ class Tests(unittest.TestCase):
|
||||
"--test_arg=source1|source2|source3",
|
||||
]
|
||||
|
||||
def test_target_not_found_with_suggestions(self):
|
||||
"""Test that unrecognized targets pass through unchanged (not a test target)."""
|
||||
|
||||
def buildozer_output(autocomplete_query):
|
||||
return "//some:test [bson_obj_test.cpp bson_element_test.cpp other_test.cpp]"
|
||||
|
||||
args = ["wrapper_hook", "test", "+bsonobj_test"] # Typo: missing underscore
|
||||
|
||||
stderr_capture = StringIO()
|
||||
with redirect_stderr(stderr_capture):
|
||||
result = test_runner_interface(args, False, buildozer_output)
|
||||
|
||||
# Should pass through unchanged since it's not a recognized target
|
||||
assert result == ["test", "+bsonobj_test"]
|
||||
|
||||
# Check that suggestions were printed
|
||||
stderr_output = stderr_capture.getvalue()
|
||||
validate_first_suggestion(stderr_output, "+bson_obj_test")
|
||||
|
||||
def test_target_not_found_no_close_matches(self):
|
||||
"""Test that completely unrecognized targets pass through unchanged."""
|
||||
|
||||
def buildozer_output(autocomplete_query):
|
||||
return "//some:test [bson_obj_test.cpp other_test.cpp]"
|
||||
|
||||
args = ["wrapper_hook", "test", "+xyz123"] # Completely different target
|
||||
|
||||
stderr_capture = StringIO()
|
||||
with redirect_stderr(stderr_capture):
|
||||
result = test_runner_interface(args, False, buildozer_output)
|
||||
|
||||
# Should pass through unchanged
|
||||
assert result == ["test", "+xyz123"]
|
||||
|
||||
# Check that "no similar targets" message was printed
|
||||
stderr_output = stderr_capture.getvalue()
|
||||
assert (
|
||||
"and no similar targets" in stderr_output
|
||||
), f"Expected 'and no similar targets' in stderr output, got: {stderr_output}"
|
||||
|
||||
def test_target_not_found_partial_match(self):
|
||||
"""Test that partial matches still pass through when not found."""
|
||||
|
||||
def buildozer_output(autocomplete_query):
|
||||
return "//some:test [bson_obj_test.cpp bson_element_test.cpp bson_utf8_test.cpp]"
|
||||
|
||||
args = ["wrapper_hook", "test", "+bson_obj"] # Missing '_test' suffix
|
||||
|
||||
stderr_capture = StringIO()
|
||||
with redirect_stderr(stderr_capture):
|
||||
result = test_runner_interface(args, False, buildozer_output)
|
||||
|
||||
# Should pass through unchanged
|
||||
assert result == ["test", "+bson_obj"]
|
||||
|
||||
stderr_output = stderr_capture.getvalue()
|
||||
validate_first_suggestion(stderr_output, "+bson_obj_test")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user