Skip to content

Commit ee49af5

Browse files
committed
applying the fix in more places
1 parent 2b09e79 commit ee49af5

File tree

7 files changed

+50
-46
lines changed

7 files changed

+50
-46
lines changed

test/conftest.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
from datetime import datetime
2+
from uuid import uuid4
23

34
import pytest
45
from groundlight import ExperimentalApi, Groundlight
56
from model import Detector, ImageQuery, ImageQueryTypeEnum, ResultTypeEnum
67

78

9+
def generate_test_detector_name(prefix: str = "Test") -> str:
10+
"""Generates a unique detector name with a timestamp and random suffix to avoid collisions in parallel CI."""
11+
return f"{prefix} {datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')}_{uuid4().hex[:8]}"
12+
13+
814
def pytest_configure(config): # pylint: disable=unused-argument
915
# Run environment check before tests
1016
gl = Groundlight()
@@ -25,20 +31,18 @@ def fixture_gl() -> Groundlight:
2531
@pytest.fixture(name="detector")
2632
def fixture_detector(gl: Groundlight) -> Detector:
2733
"""Creates a new Test detector."""
28-
name = f"Test {datetime.utcnow()}" # Need a unique name
2934
query = "Is there a dog?"
3035
pipeline_config = "never-review"
31-
return gl.create_detector(name=name, query=query, pipeline_config=pipeline_config)
36+
return gl.create_detector(name=generate_test_detector_name(), query=query, pipeline_config=pipeline_config)
3237

3338

3439
@pytest.fixture(name="count_detector")
3540
def fixture_count_detector(gl_experimental: ExperimentalApi) -> Detector:
3641
"""Creates a new Test detector."""
37-
name = f"Test {datetime.utcnow()}" # Need a unique name
3842
query = "How many dogs?"
3943
pipeline_config = "never-review-multi" # always predicts 0
4044
return gl_experimental.create_counting_detector(
41-
name=name, query=query, class_name="dog", pipeline_config=pipeline_config
45+
name=generate_test_detector_name(), query=query, class_name="dog", pipeline_config=pipeline_config
4246
)
4347

4448

test/integration/test_groundlight.py

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
import random
66
import string
77
import time
8-
from datetime import datetime
98
from typing import Any, Dict, Optional, Union
109

1110
import pytest
11+
from conftest import generate_test_detector_name
1212
from groundlight import Groundlight
1313
from groundlight.binary_labels import VALID_DISPLAY_LABELS, Label, convert_internal_label_to_display
1414
from groundlight.internalapi import ApiException, InternalApiError, NotFoundError
@@ -97,7 +97,7 @@ def test_create_groundlight_with_retries():
9797

9898

9999
def test_create_detector(gl: Groundlight):
100-
name = f"Test {datetime.utcnow()}" # Need a unique name
100+
name = generate_test_detector_name()
101101
query = "Is there a dog?"
102102
_detector = gl.create_detector(name=name, query=query)
103103
assert str(_detector)
@@ -107,20 +107,20 @@ def test_create_detector(gl: Groundlight):
107107
), "We expected the default confidence threshold to be used."
108108

109109
# Test creating dectors with other modes
110-
name = f"Test {datetime.utcnow()}" # Need a unique name
111-
count_detector = gl.create_detector(name=name, query=query, mode=ModeEnum.COUNT, class_names="dog")
110+
count_detector = gl.create_detector(
111+
name=generate_test_detector_name(), query=query, mode=ModeEnum.COUNT, class_names="dog"
112+
)
112113
assert str(count_detector)
113-
name = f"Test {datetime.utcnow()}" # Need a unique name
114114
multiclass_detector = gl.create_detector(
115-
name=name, query=query, mode=ModeEnum.MULTI_CLASS, class_names=["dog", "cat"]
115+
name=generate_test_detector_name(), query=query, mode=ModeEnum.MULTI_CLASS, class_names=["dog", "cat"]
116116
)
117117
assert str(multiclass_detector)
118118

119119

120120
def test_create_detector_with_pipeline_config(gl: Groundlight):
121121
# "never-review" is a special model that always returns the same result with 100% confidence.
122122
# It's useful for testing.
123-
name = f"Test never-review {datetime.utcnow()}" # Need a unique name
123+
name = generate_test_detector_name("Test never-review")
124124
query = "Is there a dog (always-pass)?"
125125
pipeline_config = "never-review"
126126
_detector = gl.create_detector(name=name, query=query, pipeline_config=pipeline_config)
@@ -129,7 +129,7 @@ def test_create_detector_with_pipeline_config(gl: Groundlight):
129129

130130

131131
def test_create_detector_with_edge_pipeline_config(gl: Groundlight):
132-
name = f"Test edge-pipeline-config {datetime.utcnow()}"
132+
name = generate_test_detector_name("Test edge-pipeline-config")
133133
query = "Is there a dog (edge-config)?"
134134
_detector = gl.create_detector(
135135
name=name,
@@ -144,7 +144,7 @@ def test_create_detector_with_edge_pipeline_config(gl: Groundlight):
144144
def test_create_detector_with_confidence_threshold(gl: Groundlight):
145145
# "never-review" is a special model that always returns the same result with 100% confidence.
146146
# It's useful for testing.
147-
name = f"Test with confidence {datetime.utcnow()}" # Need a unique name
147+
name = generate_test_detector_name("Test with confidence")
148148
query = "Is there a dog in the image?"
149149
pipeline_config = "never-review"
150150
confidence_threshold = 0.825
@@ -198,7 +198,7 @@ def test_create_detector_with_confidence_threshold(gl: Groundlight):
198198

199199
@pytest.mark.skip_for_edge_endpoint(reason="The edge-endpoint does not support passing detector metadata.")
200200
def test_create_detector_with_everything(gl: Groundlight):
201-
name = f"Test {datetime.utcnow()}" # Need a unique name
201+
name = generate_test_detector_name()
202202
query = "Is there a dog?"
203203
group_name = "Test group"
204204
confidence_threshold = 0.825
@@ -234,7 +234,7 @@ def test_list_detectors(gl: Groundlight):
234234

235235
def test_get_or_create_detector(gl: Groundlight):
236236
# With a unique name, we should be creating a new detector.
237-
unique_name = f"Unique name {datetime.utcnow()}"
237+
unique_name = generate_test_detector_name()
238238
query = "Is there a dog?"
239239
detector = gl.get_or_create_detector(name=unique_name, query=query)
240240
assert str(detector)
@@ -411,7 +411,7 @@ def test_submit_image_query_with_low_request_timeout(gl: Groundlight, detector:
411411

412412
@pytest.mark.skip_for_edge_endpoint(reason="The edge-endpoint does not support passing detector metadata.")
413413
def test_create_detector_with_metadata(gl: Groundlight):
414-
name = f"Test {datetime.utcnow()}" # Need a unique name
414+
name = generate_test_detector_name()
415415
query = "Is there a dog?"
416416
metadata = generate_random_dict(target_size_bytes=200)
417417
detector = gl.create_detector(name=name, query=query, metadata=metadata)
@@ -423,7 +423,7 @@ def test_create_detector_with_metadata(gl: Groundlight):
423423

424424
@pytest.mark.skip_for_edge_endpoint(reason="The edge-endpoint does not support passing detector metadata.")
425425
def test_get_or_create_detector_with_metadata(gl: Groundlight):
426-
unique_name = f"Unique name {datetime.utcnow()}"
426+
unique_name = generate_test_detector_name()
427427
query = "Is there a dog?"
428428
metadata = generate_random_dict(target_size_bytes=200)
429429
detector = gl.get_or_create_detector(name=unique_name, query=query, metadata=metadata)
@@ -444,7 +444,7 @@ def test_get_or_create_detector_with_metadata(gl: Groundlight):
444444
],
445445
)
446446
def test_create_detector_with_invalid_metadata(gl: Groundlight, metadata_list: Any):
447-
name = f"Test {datetime.utcnow()}" # Need a unique name
447+
name = generate_test_detector_name()
448448
query = "Is there a dog?"
449449

450450
for metadata in metadata_list:
@@ -629,7 +629,7 @@ def test_list_image_queries(gl: Groundlight):
629629

630630
def test_list_image_queries_with_filter(gl: Groundlight):
631631
# We want a fresh detector so we know exactly what image queries are associated with it
632-
detector = gl.create_detector(name=f"Test {datetime.utcnow()}", query="Is there a dog?")
632+
detector = gl.create_detector(name=generate_test_detector_name(), query="Is there a dog?")
633633
image_query_yes = gl.ask_async(detector=detector.id, image="test/assets/dog.jpeg", human_review="NEVER")
634634
image_query_no = gl.ask_async(detector=detector.id, image="test/assets/cat.jpeg", human_review="NEVER")
635635
iq_ids = [image_query_yes.id, image_query_no.id]
@@ -859,7 +859,7 @@ def test_binary_detector(gl: Groundlight):
859859
"""
860860
verify that we can create and submit to a binary detector
861861
"""
862-
name = f"Test {datetime.utcnow()}"
862+
name = generate_test_detector_name()
863863
created_detector = gl.create_binary_detector(name, "Is there a dog", confidence_threshold=0.0)
864864
assert created_detector is not None
865865
binary_iq = gl.submit_image_query(created_detector, "test/assets/dog.jpeg")
@@ -870,7 +870,7 @@ def test_counting_detector(gl: Groundlight):
870870
"""
871871
verify that we can create and submit to a counting detector
872872
"""
873-
name = f"Test {datetime.utcnow()}"
873+
name = generate_test_detector_name()
874874
created_detector = gl.create_counting_detector(name, "How many dogs", "dog", confidence_threshold=0.0)
875875
assert created_detector is not None
876876
count_iq = gl.submit_image_query(created_detector, "test/assets/dog.jpeg")
@@ -881,7 +881,7 @@ def test_counting_detector_async(gl: Groundlight):
881881
"""
882882
verify that we can create and submit to a counting detector
883883
"""
884-
name = f"Test {datetime.utcnow()}"
884+
name = generate_test_detector_name()
885885
created_detector = gl.create_counting_detector(name, "How many dogs", "dog", confidence_threshold=0.0)
886886
assert created_detector is not None
887887
async_iq = gl.ask_async(created_detector, "test/assets/dog.jpeg")
@@ -900,7 +900,7 @@ def test_multiclass_detector(gl: Groundlight):
900900
"""
901901
verify that we can create and submit to a multi-class detector
902902
"""
903-
name = f"Test {datetime.utcnow()}"
903+
name = generate_test_detector_name()
904904
class_names = ["Golden Retriever", "Labrador Retriever", "Poodle"]
905905
created_detector = gl.create_multiclass_detector(
906906
name, "What kind of dog is this?", class_names=class_names, confidence_threshold=0.0
@@ -916,7 +916,7 @@ def test_delete_detector(gl: Groundlight):
916916
Test deleting a detector by both ID and object, and verify proper error handling.
917917
"""
918918
# Create a detector to delete
919-
name = f"Test delete detector {datetime.utcnow()}"
919+
name = generate_test_detector_name("Test delete detector")
920920
query = "Is there a dog to delete?"
921921
pipeline_config = "never-review"
922922
detector = gl.create_detector(name=name, query=query, pipeline_config=pipeline_config)
@@ -929,7 +929,7 @@ def test_delete_detector(gl: Groundlight):
929929
gl.get_detector(detector.id)
930930

931931
# Create another detector to test deletion by ID string and that an attached image query is deleted
932-
name2 = f"Test delete detector 2 {datetime.utcnow()}"
932+
name2 = generate_test_detector_name("Test delete detector 2")
933933
detector2 = gl.create_detector(name=name2, query=query, pipeline_config=pipeline_config)
934934
gl.submit_image_query(detector2, "test/assets/dog.jpeg")
935935

@@ -959,7 +959,7 @@ def test_create_detector_with_invalid_priming_group_id(gl: Groundlight):
959959
Note: PrimingGroup IDs are provided by Groundlight representatives. If you would like to
960960
use a priming_group_id, please reach out to your Groundlight representative.
961961
"""
962-
name = f"Test invalid priming {datetime.utcnow()}"
962+
name = generate_test_detector_name("Test invalid priming")
963963
query = "Is there a dog?"
964964
pipeline_config = "never-review"
965965
priming_group_id = "prgrp_nonexistent12345678901234567890"

test/integration/test_groundlight_expensive.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
# pylint: disable=wildcard-import,unused-wildcard-import,redefined-outer-name,import-outside-toplevel
88
import random
99
import time
10-
from datetime import datetime
1110

1211
import pytest
12+
from conftest import generate_test_detector_name
1313
from groundlight import Groundlight
1414
from groundlight.internalapi import iq_is_answered, iq_is_confident
1515
from groundlight.optional_imports import *
@@ -31,7 +31,7 @@ def fixture_gl() -> Groundlight:
3131

3232
@pytest.mark.skip(reason="This test requires a human labeler who does not need to be in the testing loop")
3333
def test_human_label(gl: Groundlight):
34-
detector = gl.create_detector(name=f"Test {datetime.utcnow()}", query="Is there a dog?")
34+
detector = gl.create_detector(name=generate_test_detector_name(), query="Is there a dog?")
3535
img_query = gl.submit_image_query(
3636
detector=detector.id, image="test/assets/dog.jpeg", wait=60, human_review="ALWAYS"
3737
)
@@ -61,7 +61,7 @@ def test_detector_improvement(gl: Groundlight):
6161

6262
random.seed(2741)
6363

64-
name = f"Test test_detector_improvement {datetime.utcnow()}" # Need a unique name
64+
name = generate_test_detector_name("Test test_detector_improvement")
6565
query = "Is there a dog?"
6666
detector = gl.create_detector(name=name, query=query)
6767

@@ -126,7 +126,7 @@ def test_ask_method_quality(gl: Groundlight, detector: Detector):
126126
# asks for some level of quality on how fast ask_ml is and that we will get a confident result from ask_confident
127127
fast_always_yes_iq = gl.ask_ml(detector=detector.id, image="test/assets/dog.jpeg", wait=0)
128128
assert iq_is_answered(fast_always_yes_iq)
129-
name = f"Test {datetime.utcnow()}" # Need a unique name
129+
name = generate_test_detector_name()
130130
query = "Is there a dog?"
131131
detector = gl.create_detector(name=name, query=query, confidence_threshold=0.8)
132132
fast_iq = gl.ask_ml(detector=detector.id, image="test/assets/dog.jpeg", wait=0)

test/unit/test_cli.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import os
22
import re
33
import subprocess
4-
from datetime import datetime
54
from unittest.mock import patch
65

6+
from conftest import generate_test_detector_name
7+
78

89
def test_whoami():
910
completed_process = subprocess.run(
@@ -25,7 +26,7 @@ def test_list_detector():
2526

2627
def test_detector_and_image_queries():
2728
# test creating a detector
28-
test_detector_name = f"testdetector {datetime.utcnow()}"
29+
test_detector_name = generate_test_detector_name("testdetector")
2930
completed_process = subprocess.run(
3031
[
3132
"groundlight",

test/unit/test_detector_reset.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import time
2-
from datetime import datetime
32

43
import pytest
4+
from conftest import generate_test_detector_name
55
from groundlight import ExperimentalApi
66
from groundlight_openapi_client.exceptions import NotFoundException
77

88

99
@pytest.mark.skip(reason="This is an expensive test, reset may take some time")
1010
def test_reset_retry(gl_experimental: ExperimentalApi):
1111
# Reset the detector, retrying in case the reset is still ongoing
12-
det = gl_experimental.create_detector(f"Test {datetime.utcnow()}", "test_query")
12+
det = gl_experimental.create_detector(generate_test_detector_name(), "test_query")
1313
iq = gl_experimental.submit_image_query(det, "test/assets/cat.jpeg")
1414
gl_experimental.reset_detector(det.id)
1515
success = False
@@ -30,7 +30,7 @@ def test_reset_retry(gl_experimental: ExperimentalApi):
3030
def test_reset_training(gl_experimental: ExperimentalApi):
3131
# If we reset a detector, we should have low confidence after the reset
3232
low_confidence_threshold = 0.6
33-
det = gl_experimental.create_detector(f"Test {datetime.utcnow()}", "is this a cat")
33+
det = gl_experimental.create_detector(generate_test_detector_name(), "is this a cat")
3434
gl_experimental.reset_detector(det.id)
3535
iq = gl_experimental.submit_image_query(det, "test/assets/cat.jpeg", human_review="NEVER")
3636
assert iq.result.confidence < low_confidence_threshold

test/unit/test_experimental.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import time
2-
from datetime import datetime, timezone
32

43
import pytest
4+
from conftest import generate_test_detector_name
55
from groundlight import ExperimentalApi
66
from model import Detector, ImageQuery
77

@@ -10,7 +10,7 @@ def test_detector_groups(gl_experimental: ExperimentalApi):
1010
"""
1111
verify that we can create a detector group and retrieve it
1212
"""
13-
name = f"Test {datetime.utcnow()}"
13+
name = generate_test_detector_name()
1414
created_group = gl_experimental.create_detector_group(name)
1515
all_groups = gl_experimental.list_detector_groups()
1616
assert created_group in all_groups
@@ -34,7 +34,7 @@ def test_update_detector_name(gl_experimental: ExperimentalApi, detector: Detect
3434
"""
3535
verify that we can update the name of a detector
3636
"""
37-
new_name = f"Test {datetime.utcnow()}"
37+
new_name = generate_test_detector_name()
3838
gl_experimental.update_detector_name(detector.id, new_name)
3939
updated_detector = gl_experimental.get_detector(detector.id)
4040
assert updated_detector.name == new_name
@@ -44,7 +44,7 @@ def test_update_detector_status(gl_experimental: ExperimentalApi):
4444
"""
4545
verify that we can update the status of a detector
4646
"""
47-
detector = gl_experimental.get_or_create_detector(f"test {datetime.utcnow()}", "Is there a dog?")
47+
detector = gl_experimental.get_or_create_detector(generate_test_detector_name(), "Is there a dog?")
4848
gl_experimental.update_detector_status(detector.id, False)
4949
updated_detector = gl_experimental.get_detector(detector.id)
5050
assert updated_detector.status.value == "OFF"
@@ -57,7 +57,7 @@ def test_update_detector_escalation_type(gl_experimental: ExperimentalApi):
5757
"""
5858
verify that we can update the escalation type of a detector
5959
"""
60-
detector = gl_experimental.get_or_create_detector(f"test {datetime.utcnow()}", "Is there a dog?")
60+
detector = gl_experimental.get_or_create_detector(generate_test_detector_name(), "Is there a dog?")
6161
gl_experimental.update_detector_escalation_type(detector.id, "NO_HUMAN_LABELING")
6262
updated_detector = gl_experimental.get_detector(detector.id)
6363
updated_detector.escalation_type == "NO_HUMAN_LABELING"
@@ -94,7 +94,7 @@ def test_text_recognition_detector(gl_experimental: ExperimentalApi):
9494
"""
9595
verify that we can create and submit to a text recognition detector
9696
"""
97-
name = f"Test {datetime.utcnow()}"
97+
name = generate_test_detector_name()
9898
created_detector = gl_experimental.create_text_recognition_detector(
9999
name, "What is the date and time?", confidence_threshold=0.0
100100
)
@@ -107,7 +107,7 @@ def test_bounding_box_detector(gl_experimental: ExperimentalApi):
107107
"""
108108
Verify that we can create and submit to a bounding box detector
109109
"""
110-
name = f"Test {datetime.now(timezone.utc)}"
110+
name = generate_test_detector_name()
111111
created_detector = gl_experimental.create_bounding_box_detector(
112112
name, "Draw a bounding box around each dog in the image", "dog", confidence_threshold=0.0
113113
)
@@ -121,7 +121,7 @@ def test_bounding_box_detector_async(gl_experimental: ExperimentalApi):
121121
"""
122122
Verify that we can create and submit to a bounding box detector with ask_async
123123
"""
124-
name = f"Test {datetime.now(timezone.utc)}"
124+
name = generate_test_detector_name()
125125
created_detector = gl_experimental.create_bounding_box_detector(
126126
name, "Draw a bounding box around each dog in the image", "dog", confidence_threshold=0.0
127127
)

test/unit/test_http_retries.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
1-
from datetime import datetime
21
from typing import Any, Callable
32
from unittest import mock
4-
from uuid import uuid4
53

64
import pytest
5+
from conftest import generate_test_detector_name
76
from groundlight import Groundlight
87
from groundlight.binary_labels import Label
98
from groundlight.internalapi import InternalApiError
109
from model import Detector
1110

1211
DEFAULT_CONFIDENCE_THRESHOLD = 0.9
13-
DETECTOR_NAME = f"test detector_{datetime.utcnow().strftime('%Y=%m-%d %H:%M:%S')}_{uuid4().hex[:8]}"
12+
DETECTOR_NAME = generate_test_detector_name()
1413
TOTAL_RETRIES = 3
1514
STATUS_CODES = range(500, 505)
1615
IMAGE_FILE = "test/assets/dog.jpeg"

0 commit comments

Comments
 (0)