Skip to content

Commit

Permalink
ci(influxdb): replace Tuple and Dict typing by tuple and dict, apply …
Browse files Browse the repository at this point in the history
…expected code formatting
  • Loading branch information
lucsorel committed Mar 8, 2024
1 parent 4ff505d commit c28bd8a
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 79 deletions.
12 changes: 5 additions & 7 deletions modules/influxdb/testcontainers/influxdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@
- because the InfluxDB clients are different for 1.x and 2.x versions,
so you won't have to install dependencies that you do not need
"""

from typing import Dict, Optional
from typing import Optional

from requests import get
from requests.exceptions import ConnectionError, ReadTimeout
Expand All @@ -44,16 +43,15 @@ class InfluxDbContainer(DockerContainer):
because their respective clients rely on different Python libraries which we don't want
to import at the same time.
"""

def __init__(
self,
# Docker image name
image: str,

# in the container, the default port for influxdb is often 8086 and not likely to change
container_port: int = 8086,
# specifies the port on the host machine where influxdb is exposed; a random available port otherwise
host_port: Optional[int] = None,

**docker_client_kw,
):
super().__init__(image=image, **docker_client_kw)
Expand All @@ -71,7 +69,7 @@ def get_url(self) -> str:
return f"http://{host}:{port}"

@wait_container_is_ready(ConnectionError, ReadTimeout)
def _health_check(self) -> Dict:
def _health_check(self) -> dict:
"""
Performs a health check on the running InfluxDB container.
The call is retried until it works thanks to the @wait_container_is_ready decorator.
Expand All @@ -83,13 +81,13 @@ def _health_check(self) -> Dict:
response.raise_for_status()

return response.json()

def get_influxdb_version(self) -> str:
"""
Returns the version of the InfluxDB service, as returned by the healthcheck.
"""

return self._health_check().get('version')
return self._health_check().get("version")

def start(self) -> "InfluxDbContainer":
"""
Expand Down
14 changes: 5 additions & 9 deletions modules/influxdb/testcontainers/influxdb1/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

from testcontainers.influxdb import InfluxDbContainer


class InfluxDb1Container(InfluxDbContainer):
"""
Docker container for InfluxDB 1.x.
Expand All @@ -31,19 +32,18 @@ class InfluxDb1Container(InfluxDbContainer):
>>> with InfluxDbContainer() as influxdb:
... version = influxdb.get_version()
"""

def __init__(
self,
image: str = "influxdb:1.8",

# in the container, the default port for influxdb is often 8086 and not likely to change
container_port: int = 8086,
# specifies the port on the host machine where influxdb is exposed; a random available port otherwise
host_port: Optional[int] = None,

**docker_client_kw,
):
super().__init__(image, container_port, host_port, **docker_client_kw)

def get_client(self, **client_kwargs):
"""
Returns an instance of the influxdb client, for InfluxDB 1.x versions.
Expand All @@ -56,14 +56,10 @@ def get_client(self, **client_kwargs):
- https://github.com/influxdata/influxdb-client-python#influxdb-18-api-compatibility
"""

return InfluxDBClient(
self.get_container_host_ip(),
self.get_exposed_port(self.container_port),
**client_kwargs
)
return InfluxDBClient(self.get_container_host_ip(), self.get_exposed_port(self.container_port), **client_kwargs)

def start(self) -> "InfluxDb1Container":
"""
Overridden for better typing reason
"""
return super().start()
return super().start()
17 changes: 6 additions & 11 deletions modules/influxdb/testcontainers/influxdb2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# under the License.

from os import getenv
from typing import Optional, Tuple
from typing import Optional

from influxdb_client import InfluxDBClient, Organization

Expand All @@ -33,15 +33,14 @@ class InfluxDb2Container(InfluxDbContainer):
>>> with InfluxDb2Container() as influxdb2:
... version = influxdb2.get_version()
"""

def __init__(
self,
image: str = "influxdb:latest",

# in the container, the default port for influxdb is often 8086 and not likely to change
container_port: int = 8086,
# specifies the port on the host machine where influxdb is exposed; a random available port otherwise
host_port: Optional[int] = None,

# parameters used by the InfluxDSB 2.x Docker container when spawned in setup mode
# (which is likely what you want). In setup mode, init_mode should be "setup" and all
# the other parameters should be set (via this constructor or their respective
Expand All @@ -53,7 +52,6 @@ def __init__(
org_name: Optional[str] = None,
bucket: Optional[str] = None,
retention: Optional[str] = None,

**docker_client_kw,
):
super().__init__(image, container_port, host_port, **docker_client_kw)
Expand All @@ -71,15 +69,16 @@ def __init__(
env_value = constructor_param or getenv(env_key)
if env_value:
self.with_env(env_key, env_value)


def start(self) -> "InfluxDb2Container":
"""
Overridden for better typing reason
"""
return super().start()

def get_client(self, token: str = None, org_name:str = None, **influxdb_client_kwargs) -> Tuple[InfluxDBClient, Organization]:
def get_client(
self, token: Optional[str] = None, org_name: Optional[str] = None, **influxdb_client_kwargs
) -> tuple[InfluxDBClient, Organization]:
"""
Returns an instance of the influxdb client with the associated test organization created
when the container is spawn; for InfluxDB 2.x versions.
Expand All @@ -95,11 +94,7 @@ def get_client(self, token: str = None, org_name:str = None, **influxdb_client_k
want) by giving its name to the 'org_name' parameter constructor.
"""

influxclient = InfluxDBClient(
self.get_url(),
token=token,
**influxdb_client_kwargs
)
influxclient = InfluxDBClient(self.get_url(), token=token, **influxdb_client_kwargs)

if org_name is None:
return influxclient, None
Expand Down
97 changes: 45 additions & 52 deletions modules/influxdb/tests/test_influxdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,28 +25,34 @@


@mark.parametrize(
["image", "influxdb_container_class", "exposed_port"], [
["image", "influxdb_container_class", "exposed_port"],
[
("influxdb:2.7", InfluxDb1Container, 8086),
("influxdb:1.8", InfluxDb2Container, 8086),
]
],
)
def test_influxdbcontainer_get_url(image : str, influxdb_container_class: Type[InfluxDbContainer], exposed_port: int):
def test_influxdbcontainer_get_url(image: str, influxdb_container_class: Type[InfluxDbContainer], exposed_port: int):
with influxdb_container_class(image, host_port=exposed_port) as influxdb_container:
connection_url = influxdb_container.get_url()
assert str(exposed_port) in connection_url


@mark.parametrize(
["image", "influxdb_container_class", "expected_version"], [
["image", "influxdb_container_class", "expected_version"],
[
("influxdb:1.8", InfluxDb1Container, "1.8.10"),
("influxdb:1.8.10", InfluxDb1Container, "1.8.10"),
("influxdb:2.7", InfluxDb2Container, "v2.7.4"),
("influxdb:2.7.4", InfluxDb2Container, "v2.7.4"),
]
],
)
def test_influxdbcontainer_get_influxdb_version(image: str, influxdb_container_class: Type[InfluxDbContainer], expected_version: str):
def test_influxdbcontainer_get_influxdb_version(
image: str, influxdb_container_class: Type[InfluxDbContainer], expected_version: str
):
with influxdb_container_class(image) as influxdb_container:
assert influxdb_container.get_influxdb_version() == expected_version


def test_influxdb1container_get_client():
"""
This is a test example showing how you could use testcontainers/influxdb for InfluxDB 1.x versions
Expand All @@ -61,36 +67,30 @@ def test_influxdb1container_get_client():
databases = influxdb1_client.get_list_database()
assert len(databases) == 1, "the InfluxDB container now contains one database"
assert databases[0] == {"name": "testcontainers"}

influxdb1_client.write_points([
{
"measurement": "influxdbcontainer",
"time": "1978-11-30T09:30:00Z",
"fields": {
"ratio": 0.42
}
}, {
"measurement": "influxdbcontainer",
"time": "1978-12-25T10:30:00Z",
"fields": {
"ratio": 0.55
}
},
], database="testcontainers")

influxdb1_client.write_points(
[
{"measurement": "influxdbcontainer", "time": "1978-11-30T09:30:00Z", "fields": {"ratio": 0.42}},
{"measurement": "influxdbcontainer", "time": "1978-12-25T10:30:00Z", "fields": {"ratio": 0.55}},
],
database="testcontainers",
)

# retrieves the inserted datapoints
datapoints_set: ResultSet = influxdb1_client.query("select ratio from influxdbcontainer;", database="testcontainers")
datapoints_set: ResultSet = influxdb1_client.query(
"select ratio from influxdbcontainer;", database="testcontainers"
)
datapoints = list(datapoints_set.get_points())
assert len(datapoints) == 2, '2 datapoints are retrieved'
assert len(datapoints) == 2, "2 datapoints are retrieved"

datapoint = datapoints[0]
assert datapoint['time'] == "1978-11-30T09:30:00Z"
assert datapoint['ratio'] == 0.42
assert datapoint["time"] == "1978-11-30T09:30:00Z"
assert datapoint["ratio"] == 0.42

datapoint = datapoints[1]
assert datapoint['time'] == "1978-12-25T10:30:00Z"
assert datapoint['ratio'] == 0.55
assert datapoint["time"] == "1978-12-25T10:30:00Z"
assert datapoint["ratio"] == 0.55


def test_influxdb2container_get_client():
"""
Expand All @@ -103,43 +103,36 @@ def test_influxdb2container_get_client():
password="secret-password",
org_name="testcontainers-org",
bucket="my-init-bucket",
admin_token="secret-token"
admin_token="secret-token",
) as influxdb2_container:
influxdb2_client, test_org = influxdb2_container.get_client(token="secret-token", org_name="testcontainers-org")
assert influxdb2_client.ping(), "the client can connect to the InfluxDB instance"

# ensures that the bucket does not exist yet
buckets_api = influxdb2_client.buckets_api()
bucket: Bucket = buckets_api.find_bucket_by_name("testcontainers")
assert bucket is None, 'the test bucket does not exist yet'
assert bucket is None, "the test bucket does not exist yet"

# creates a test bucket and insert a point
buckets_api.create_bucket(bucket_name="testcontainers", org=test_org)
bucket: Bucket = buckets_api.find_bucket_by_name("testcontainers")
assert bucket.name == "testcontainers", 'the test bucket now exists'
assert bucket.name == "testcontainers", "the test bucket now exists"

write_api = influxdb2_client.write_api(write_options=SYNCHRONOUS)
write_api.write("testcontainers", "testcontainers-org", [
{
"measurement": "influxdbcontainer",
"time": "1978-11-30T09:30:00Z",
"fields": {
"ratio": 0.42
}
}, {
"measurement": "influxdbcontainer",
"time": "1978-12-25T10:30:00Z",
"fields": {
"ratio": 0.55
}
},
])
write_api.write(
"testcontainers",
"testcontainers-org",
[
{"measurement": "influxdbcontainer", "time": "1978-11-30T09:30:00Z", "fields": {"ratio": 0.42}},
{"measurement": "influxdbcontainer", "time": "1978-12-25T10:30:00Z", "fields": {"ratio": 0.55}},
],
)

# retrieves the inserted datapoints
query_api = influxdb2_client.query_api()
tables = query_api.query('from(bucket: "testcontainers") |> range(start: 1978-11-01T22:00:00Z)', org=test_org)
results = tables.to_values(['_measurement', '_field', '_time', '_value'])
assert len(results) == 2, '2 datapoints were retrieved'
assert results[0] == ['influxdbcontainer', 'ratio', datetime.fromisoformat('1978-11-30T09:30:00+00:00'), 0.42]
assert results[1] == ['influxdbcontainer', 'ratio', datetime.fromisoformat('1978-12-25T10:30:00+00:00'), 0.55]
results = tables.to_values(["_measurement", "_field", "_time", "_value"])

assert len(results) == 2, "2 datapoints were retrieved"
assert results[0] == ["influxdbcontainer", "ratio", datetime.fromisoformat("1978-11-30T09:30:00+00:00"), 0.42]
assert results[1] == ["influxdbcontainer", "ratio", datetime.fromisoformat("1978-12-25T10:30:00+00:00"), 0.55]

0 comments on commit c28bd8a

Please sign in to comment.