From e4598759f941b18329e005f37a85c196e9f892ab Mon Sep 17 00:00:00 2001 From: Tim Huff Date: Tue, 7 Apr 2026 21:44:01 +0000 Subject: [PATCH 1/2] adjusting tests --- test/integration/test_groundlight.py | 8 ++++---- test/unit/test_cli.py | 2 ++ test/unit/test_experimental.py | 4 ++-- test/unit/test_images.py | 2 +- test/unit/test_labels.py | 10 +++++----- 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/test/integration/test_groundlight.py b/test/integration/test_groundlight.py index 6d69bb63..df49875d 100644 --- a/test/integration/test_groundlight.py +++ b/test/integration/test_groundlight.py @@ -859,7 +859,7 @@ def test_binary_detector(gl: Groundlight, detector_name: Callable): name = detector_name() created_detector = gl.create_binary_detector(name, "Is there a dog", confidence_threshold=0.0) assert created_detector is not None - binary_iq = gl.submit_image_query(created_detector, "test/assets/dog.jpeg") + binary_iq = gl.submit_image_query(created_detector, "test/assets/dog.jpeg", wait=0) assert binary_iq.result.label is not None @@ -870,7 +870,7 @@ def test_counting_detector(gl: Groundlight, detector_name: Callable): name = detector_name() created_detector = gl.create_counting_detector(name, "How many dogs", "dog", confidence_threshold=0.0) assert created_detector is not None - count_iq = gl.submit_image_query(created_detector, "test/assets/dog.jpeg") + count_iq = gl.submit_image_query(created_detector, "test/assets/dog.jpeg", wait=0) assert count_iq.result.count is not None @@ -903,7 +903,7 @@ def test_multiclass_detector(gl: Groundlight, detector_name: Callable): name, "What kind of dog is this?", class_names=class_names, confidence_threshold=0.0 ) assert created_detector is not None - mc_iq = gl.submit_image_query(created_detector, "test/assets/dog.jpeg") + mc_iq = gl.submit_image_query(created_detector, "test/assets/dog.jpeg", wait=0) assert mc_iq.result.label is not None assert mc_iq.result.label in class_names @@ -928,7 +928,7 @@ def test_delete_detector(gl: Groundlight, detector_name: Callable): # Create another detector to test deletion by ID string and that an attached image query is deleted name2 = detector_name("Test delete detector 2") detector2 = gl.create_detector(name=name2, query=query, pipeline_config=pipeline_config) - gl.submit_image_query(detector2, "test/assets/dog.jpeg") + gl.submit_image_query(detector2, "test/assets/dog.jpeg", wait=0) time.sleep(10) diff --git a/test/unit/test_cli.py b/test/unit/test_cli.py index 47911b70..7a52a6fc 100644 --- a/test/unit/test_cli.py +++ b/test/unit/test_cli.py @@ -81,6 +81,8 @@ def test_detector_and_image_queries(detector_name: Callable): "submit-image-query", det_id_on_create, "test/assets/cat.jpeg", + "--wait", + "0", ], stdout=subprocess.PIPE, stderr=subprocess.PIPE, diff --git a/test/unit/test_experimental.py b/test/unit/test_experimental.py index 9c2237e5..d90f075e 100644 --- a/test/unit/test_experimental.py +++ b/test/unit/test_experimental.py @@ -99,7 +99,7 @@ def test_text_recognition_detector(gl_experimental: ExperimentalApi, detector_na name, "What is the date and time?", confidence_threshold=0.0 ) assert created_detector is not None - mc_iq = gl_experimental.submit_image_query(created_detector, "test/assets/dog.jpeg") + mc_iq = gl_experimental.submit_image_query(created_detector, "test/assets/dog.jpeg", wait=0) assert mc_iq.result.text is not None @@ -112,7 +112,7 @@ def test_bounding_box_detector(gl_experimental: ExperimentalApi, detector_name: name, "Draw a bounding box around each dog in the image", "dog", confidence_threshold=0.0 ) assert created_detector is not None - bbox_iq = gl_experimental.submit_image_query(created_detector, "test/assets/dog.jpeg") + bbox_iq = gl_experimental.submit_image_query(created_detector, "test/assets/dog.jpeg", wait=0) assert bbox_iq.result.label is not None assert bbox_iq.rois is not None diff --git a/test/unit/test_images.py b/test/unit/test_images.py index 12220ade..af28d188 100644 --- a/test/unit/test_images.py +++ b/test/unit/test_images.py @@ -7,6 +7,6 @@ def test_get_image(gl_experimental: ExperimentalApi): name = f"Test {datetime.utcnow()}" det = gl_experimental.get_or_create_detector(name, "test_query") - iq = gl_experimental.submit_image_query(det, image="test/assets/dog.jpeg", wait=10) + iq = gl_experimental.submit_image_query(det, image="test/assets/dog.jpeg", wait=0) gl_experimental.get_image(iq.id) assert isinstance(PIL.Image.open(gl_experimental.get_image(iq.id)), PIL.Image.Image) diff --git a/test/unit/test_labels.py b/test/unit/test_labels.py index a504d1e4..bc51ba63 100644 --- a/test/unit/test_labels.py +++ b/test/unit/test_labels.py @@ -7,7 +7,7 @@ def test_binary_labels(gl_experimental: ExperimentalApi): name = f"Test binary labels{datetime.utcnow()}" det = gl_experimental.create_detector(name, "test_query") - iq1 = gl_experimental.submit_image_query(det, "test/assets/cat.jpeg") + iq1 = gl_experimental.submit_image_query(det, "test/assets/cat.jpeg", wait=0) gl_experimental.add_label(iq1, "YES") iq1 = gl_experimental.get_image_query(iq1.id) assert iq1.result.label == "YES" @@ -24,7 +24,7 @@ def test_binary_labels(gl_experimental: ExperimentalApi): def test_counting_labels(gl_experimental: ExperimentalApi): name = f"Test binary labels{datetime.utcnow()}" det = gl_experimental.create_counting_detector(name, "test_query", "test_object_class") - iq1 = gl_experimental.submit_image_query(det, "test/assets/cat.jpeg") + iq1 = gl_experimental.submit_image_query(det, "test/assets/cat.jpeg", wait=0) gl_experimental.add_label(iq1, 0) iq1 = gl_experimental.get_image_query(iq1.id) @@ -48,7 +48,7 @@ def test_counting_labels(gl_experimental: ExperimentalApi): def test_multiclass_labels(gl_experimental: ExperimentalApi): name = f"Test binary labels{datetime.utcnow()}" det = gl_experimental.create_multiclass_detector(name, "test_query", class_names=["apple", "banana", "cherry"]) - iq1 = gl_experimental.submit_image_query(det, "test/assets/cat.jpeg") + iq1 = gl_experimental.submit_image_query(det, "test/assets/cat.jpeg", wait=0) gl_experimental.add_label(iq1, "apple") iq1 = gl_experimental.get_image_query(iq1.id) assert iq1.result.label == "apple" @@ -69,7 +69,7 @@ def test_multiclass_labels(gl_experimental: ExperimentalApi): def test_bounding_box_labels(gl_experimental: ExperimentalApi): name = f"Test bounding box labels{datetime.utcnow()}" det = gl_experimental.create_bounding_box_detector(name, "test_query", "test_class") - iq1 = gl_experimental.submit_image_query(det, "test/assets/cat.jpeg") + iq1 = gl_experimental.submit_image_query(det, "test/assets/cat.jpeg", wait=0) gl_experimental.add_label(iq1, "NO_OBJECTS") iq1 = gl_experimental.get_image_query(iq1.id) assert iq1.result.label == "NO_OBJECTS" @@ -87,7 +87,7 @@ def test_bounding_box_labels(gl_experimental: ExperimentalApi): def test_text_recognition_labels(gl_experimental: ExperimentalApi): name = f"Test text recognition labels{datetime.utcnow()}" det = gl_experimental.create_text_recognition_detector(name, "test_query") - iq1 = gl_experimental.submit_image_query(det, "test/assets/cat.jpeg") + iq1 = gl_experimental.submit_image_query(det, "test/assets/cat.jpeg", wait=0) gl_experimental.add_label(iq1, "apple text") iq1 = gl_experimental.get_image_query(iq1.id) assert iq1.result.text == "apple text" From d79746d2c70ac3f0d453c91079f02ac61722542d Mon Sep 17 00:00:00 2001 From: Tim Huff Date: Tue, 7 Apr 2026 22:24:58 +0000 Subject: [PATCH 2/2] refining the tests --- test/conftest.py | 8 ++++++-- test/integration/test_groundlight.py | 22 +++++++++++----------- test/unit/test_http_retries.py | 2 +- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/test/conftest.py b/test/conftest.py index a3160457..3bcc3f5a 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -6,6 +6,10 @@ from groundlight import ExperimentalApi, Groundlight from model import Detector, ImageQuery, ImageQueryTypeEnum, ResultTypeEnum +# No test in the suite expects a human review answer, and the server already blocks ~6s +# for ML inference before returning. Client-side polling adds no value. +TEST_IQ_SUBMISSION_WAIT = 0.0 + def _generate_unique_detector_name(prefix: str = "Test") -> str: """Generates a detector name with a timestamp and random suffix to ensure uniqueness.""" @@ -31,7 +35,7 @@ def pytest_configure(config): # pylint: disable=unused-argument def fixture_gl() -> Groundlight: """Creates a Groundlight client object for testing.""" _gl = Groundlight() - _gl.DEFAULT_WAIT = 10 + _gl.DEFAULT_WAIT = TEST_IQ_SUBMISSION_WAIT return _gl @@ -84,7 +88,7 @@ def fixture_image_query_zero(gl_experimental: Groundlight, count_detector: Detec @pytest.fixture(name="gl_experimental") def fixture_gl_experimental() -> ExperimentalApi: _gl = ExperimentalApi() - _gl.DEFAULT_WAIT = 10 + _gl.DEFAULT_WAIT = TEST_IQ_SUBMISSION_WAIT return _gl diff --git a/test/integration/test_groundlight.py b/test/integration/test_groundlight.py index df49875d..ce56be98 100644 --- a/test/integration/test_groundlight.py +++ b/test/integration/test_groundlight.py @@ -274,14 +274,14 @@ def test_get_detector_by_name(gl: Groundlight, detector: Detector): def test_ask_confident(gl: Groundlight, detector: Detector): - _image_query = gl.ask_confident(detector=detector.id, image="test/assets/dog.jpeg", wait=10) + _image_query = gl.ask_confident(detector=detector.id, image="test/assets/dog.jpeg", wait=0) assert str(_image_query) assert isinstance(_image_query, ImageQuery) assert is_valid_display_result(_image_query.result) def test_ask_ml(gl: Groundlight, detector: Detector): - _image_query = gl.ask_ml(detector=detector.id, image="test/assets/dog.jpeg", wait=10) + _image_query = gl.ask_ml(detector=detector.id, image="test/assets/dog.jpeg", wait=0) assert str(_image_query) assert isinstance(_image_query, ImageQuery) assert is_valid_display_result(_image_query.result) @@ -294,21 +294,21 @@ def validate_image_query(_image_query: ImageQuery): assert is_valid_display_result(_image_query.result) _image_query = gl.submit_image_query( - detector=detector.id, image="test/assets/dog.jpeg", wait=10, human_review="NEVER" + detector=detector.id, image="test/assets/dog.jpeg", wait=0, human_review="NEVER" ) validate_image_query(_image_query) _image_query = gl.submit_image_query( - detector=detector.id, image="test/assets/dog.jpeg", wait=3, human_review="NEVER" + detector=detector.id, image="test/assets/dog.jpeg", wait=0, human_review="NEVER" ) validate_image_query(_image_query) _image_query = gl.submit_image_query( - detector=detector.id, image="test/assets/dog.jpeg", wait=10, patience_time=20, human_review="NEVER" + detector=detector.id, image="test/assets/dog.jpeg", wait=0, patience_time=20, human_review="NEVER" ) validate_image_query(_image_query) _image_query = gl.submit_image_query(detector=detector.id, image="test/assets/dog.jpeg", human_review="NEVER") validate_image_query(_image_query) _image_query = gl.submit_image_query( - detector=detector.id, image="test/assets/dog.jpeg", wait=180, confidence_threshold=0.75, human_review="NEVER" + detector=detector.id, image="test/assets/dog.jpeg", wait=0, confidence_threshold=0.75, human_review="NEVER" ) validate_image_query(_image_query) assert _image_query.result.confidence >= IQ_IMPROVEMENT_THRESHOLD @@ -316,7 +316,7 @@ def validate_image_query(_image_query: ImageQuery): def test_submit_image_query_blocking(gl: Groundlight, detector: Detector): _image_query = gl.submit_image_query( - detector=detector.id, image="test/assets/dog.jpeg", wait=10, human_review="NEVER" + detector=detector.id, image="test/assets/dog.jpeg", wait=0, human_review="NEVER" ) assert str(_image_query) assert isinstance(_image_query, ImageQuery) @@ -326,7 +326,7 @@ def test_submit_image_query_blocking(gl: Groundlight, detector: Detector): def test_submit_image_query_returns_yes(gl: Groundlight): # We use the "never-review" pipeline to guarantee a confident "yes" answer. detector = gl.get_or_create_detector(name="Always a dog", query="Is there a dog?", pipeline_config="never-review") - image_query = gl.submit_image_query(detector=detector, image="test/assets/dog.jpeg", wait=10, human_review="NEVER") + image_query = gl.submit_image_query(detector=detector, image="test/assets/dog.jpeg", wait=0, human_review="NEVER") assert image_query.result.label == Label.YES @@ -335,7 +335,7 @@ def test_submit_image_query_returns_text(gl: Groundlight): detector = gl.get_or_create_detector( name="Always same text", query="Is there a dog?", pipeline_config="constant-text-pred" ) - image_query = gl.submit_image_query(detector=detector, image="test/assets/dog.jpeg", wait=10, human_review="NEVER") + image_query = gl.submit_image_query(detector=detector, image="test/assets/dog.jpeg", wait=0, human_review="NEVER") assert isinstance(image_query.text, str) @@ -358,7 +358,7 @@ def test_submit_image_query_with_confidence_threshold(gl: Groundlight, detector: _image_query = gl.submit_image_query( detector=detector.id, image="test/assets/dog.jpeg", - wait=10, + wait=0, confidence_threshold=confidence_threshold, human_review="NEVER", ) @@ -370,7 +370,7 @@ def test_submit_image_query_with_id(gl: Groundlight, detector: Detector): # submit_image_query id = f"iq_{KsuidMs()}" _image_query = gl.submit_image_query( - detector=detector.id, image="test/assets/dog.jpeg", wait=10, human_review="NEVER", image_query_id=id + detector=detector.id, image="test/assets/dog.jpeg", wait=0, human_review="NEVER", image_query_id=id ) assert str(_image_query) assert isinstance(_image_query, ImageQuery) diff --git a/test/unit/test_http_retries.py b/test/unit/test_http_retries.py index 04b75393..54054806 100644 --- a/test/unit/test_http_retries.py +++ b/test/unit/test_http_retries.py @@ -80,7 +80,7 @@ def test_submit_image_query_attempts_retries(gl: Groundlight, detector_name: Cal expected_call_counts=TOTAL_RETRIES + 1, detector=detector_name(), image=IMAGE_FILE, - wait=1, + wait=0, )