Skip to content

Commit

Permalink
feat(labels):Add common testcontainers labels (#519)
Browse files Browse the repository at this point in the history
- 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>
  • Loading branch information
3 people committed Apr 17, 2024
1 parent fefb9d0 commit e04b7ac
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 0 deletions.
12 changes: 12 additions & 0 deletions core/testcontainers/core/labels.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
import importlib
from typing import Optional
from uuid import uuid4

from testcontainers.core.config import testcontainers_config as c

SESSION_ID: str = str(uuid4())
TESTCONTAINERS_NAMESPACE = "org.testcontainers"

LABEL_TESTCONTAINERS = TESTCONTAINERS_NAMESPACE
LABEL_SESSION_ID = "org.testcontainers.session-id"
LABEL_VERSION = "org.testcontainers.version"
LABEL_LANG = "org.testcontainers.lang"


def create_labels(image: str, labels: Optional[dict[str, str]]) -> dict[str, str]:
if labels is None:
labels = {}
else:
for k in labels:
if k.startswith(TESTCONTAINERS_NAMESPACE):
raise ValueError("The org.testcontainers namespace is reserved for interal use")

labels[LABEL_LANG] = "python"
labels[LABEL_TESTCONTAINERS] = "true"
labels[LABEL_VERSION] = importlib.metadata.version("testcontainers")

if image == c.ryuk_image:
return labels
Expand Down
58 changes: 58 additions & 0 deletions core/tests/test_labels.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from testcontainers.core.labels import (
LABEL_LANG,
LABEL_SESSION_ID,
LABEL_TESTCONTAINERS,
LABEL_VERSION,
create_labels,
TESTCONTAINERS_NAMESPACE,
)
import pytest
from testcontainers.core.config import RYUK_IMAGE


def assert_in_with_value(labels: dict, label: str, value: str, known_before_test_time: bool) -> None:
assert label in labels
if known_before_test_time:
assert labels[label] == value


testdata = [
(LABEL_LANG, "python", True),
(LABEL_TESTCONTAINERS, "true", True),
(LABEL_SESSION_ID, "some", False),
(LABEL_VERSION, "some", False),
]


@pytest.mark.parametrize("label,value,known_before_test_time", testdata)
def test_containers_creates_expected_labels(label, value, known_before_test_time):
actual_labels = create_labels("not-ryuk", None)
assert_in_with_value(actual_labels, label, value, known_before_test_time)


def test_containers_throws_on_namespace_collision():
with pytest.raises(ValueError):
create_labels("not-ryuk", {TESTCONTAINERS_NAMESPACE: "fake"})


def test_containers_respect_custom_labels_if_no_collision():
custom_namespace = "org.foo.bar"
value = "fake"
actual_labels = create_labels("not-ryuk", {custom_namespace: value})
assert_in_with_value(actual_labels, custom_namespace, value, True)


def test_if_ryuk_no_session():
actual_labels = create_labels(RYUK_IMAGE, None)
assert LABEL_SESSION_ID not in actual_labels


def test_session_are_module_import_scoped():
"""
Asserts that sessions are a module-level variable and don't differ between invocation
"""
first_labels = create_labels("not-ryuk", None)
second_labels = create_labels("not-ryuk", None)
assert LABEL_SESSION_ID in first_labels
assert LABEL_SESSION_ID in second_labels
assert first_labels[LABEL_SESSION_ID] == second_labels[LABEL_SESSION_ID]

0 comments on commit e04b7ac

Please sign in to comment.