Skip to content

Commit e04b7ac

Browse files
bearritobstrausseralexanderankin
authoredApr 17, 2024··
feat(labels):Add common testcontainers labels (#519)
- Closes: #510 Aligns with other test container projects Example: I also contribute to go project, those labels look like ``` "maintainer": "docker@couchbase.com", "org.opencontainers.image.ref.name": "ubuntu", "org.opencontainers.image.version": "20.04", "org.testcontainers": "true", "org.testcontainers.lang": "go", "org.testcontainers.sessionId": "e01aa90cfb75a53fbd53776b8c2eb84a99e3f1c8a7103512468cf75735421176", "org.testcontainers.version": "0.30.0" ``` Java appears to do similar - https://github.com/testcontainers/testcontainers-java/blob/main/core/src/main/java/org/testcontainers/DockerClientFactory.java#L51 I didn't add in the image info as there wasn't an obvious way to get a handle on that nor obvious value. Another thing is that the python prefers `session-id` to `sessionId`. I'm not sure if there are any cross-language reasons to have those be identical, I left it alone. Also this adds in tests for the label code. --------- Co-authored-by: bstrausser <bstrausser@locusrobotics.com> Co-authored-by: David Ankin <daveankin@gmail.com>
1 parent fefb9d0 commit e04b7ac

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed
 

‎core/testcontainers/core/labels.py

+12
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,29 @@
1+
import importlib
12
from typing import Optional
23
from uuid import uuid4
34

45
from testcontainers.core.config import testcontainers_config as c
56

67
SESSION_ID: str = str(uuid4())
8+
TESTCONTAINERS_NAMESPACE = "org.testcontainers"
9+
10+
LABEL_TESTCONTAINERS = TESTCONTAINERS_NAMESPACE
711
LABEL_SESSION_ID = "org.testcontainers.session-id"
12+
LABEL_VERSION = "org.testcontainers.version"
813
LABEL_LANG = "org.testcontainers.lang"
914

1015

1116
def create_labels(image: str, labels: Optional[dict[str, str]]) -> dict[str, str]:
1217
if labels is None:
1318
labels = {}
19+
else:
20+
for k in labels:
21+
if k.startswith(TESTCONTAINERS_NAMESPACE):
22+
raise ValueError("The org.testcontainers namespace is reserved for interal use")
23+
1424
labels[LABEL_LANG] = "python"
25+
labels[LABEL_TESTCONTAINERS] = "true"
26+
labels[LABEL_VERSION] = importlib.metadata.version("testcontainers")
1527

1628
if image == c.ryuk_image:
1729
return labels

‎core/tests/test_labels.py

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
from testcontainers.core.labels import (
2+
LABEL_LANG,
3+
LABEL_SESSION_ID,
4+
LABEL_TESTCONTAINERS,
5+
LABEL_VERSION,
6+
create_labels,
7+
TESTCONTAINERS_NAMESPACE,
8+
)
9+
import pytest
10+
from testcontainers.core.config import RYUK_IMAGE
11+
12+
13+
def assert_in_with_value(labels: dict, label: str, value: str, known_before_test_time: bool) -> None:
14+
assert label in labels
15+
if known_before_test_time:
16+
assert labels[label] == value
17+
18+
19+
testdata = [
20+
(LABEL_LANG, "python", True),
21+
(LABEL_TESTCONTAINERS, "true", True),
22+
(LABEL_SESSION_ID, "some", False),
23+
(LABEL_VERSION, "some", False),
24+
]
25+
26+
27+
@pytest.mark.parametrize("label,value,known_before_test_time", testdata)
28+
def test_containers_creates_expected_labels(label, value, known_before_test_time):
29+
actual_labels = create_labels("not-ryuk", None)
30+
assert_in_with_value(actual_labels, label, value, known_before_test_time)
31+
32+
33+
def test_containers_throws_on_namespace_collision():
34+
with pytest.raises(ValueError):
35+
create_labels("not-ryuk", {TESTCONTAINERS_NAMESPACE: "fake"})
36+
37+
38+
def test_containers_respect_custom_labels_if_no_collision():
39+
custom_namespace = "org.foo.bar"
40+
value = "fake"
41+
actual_labels = create_labels("not-ryuk", {custom_namespace: value})
42+
assert_in_with_value(actual_labels, custom_namespace, value, True)
43+
44+
45+
def test_if_ryuk_no_session():
46+
actual_labels = create_labels(RYUK_IMAGE, None)
47+
assert LABEL_SESSION_ID not in actual_labels
48+
49+
50+
def test_session_are_module_import_scoped():
51+
"""
52+
Asserts that sessions are a module-level variable and don't differ between invocation
53+
"""
54+
first_labels = create_labels("not-ryuk", None)
55+
second_labels = create_labels("not-ryuk", None)
56+
assert LABEL_SESSION_ID in first_labels
57+
assert LABEL_SESSION_ID in second_labels
58+
assert first_labels[LABEL_SESSION_ID] == second_labels[LABEL_SESSION_ID]

0 commit comments

Comments
 (0)
Please sign in to comment.