forked from timescale/doctor
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ci: Use testcontainer for running tests
Instead of relying on services to be set up properly, use `testcontainers` to create a container to run the test inside. Tests can use either `TimescaleDBTestCase` or `PostgreSQLTestCase` to select what kind of container to use. If a Postgres container is requested, it will be read from the environment variable `TEST_CONTAINER_POSTGRES` and Timescale containers will be read from `TEST_CONTAINER_TIMESCALE`.
- Loading branch information
Showing
6 changed files
with
110 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,3 @@ | ||
psycopg2>=2.9.2 | ||
psycopg2>=2.9.0 | ||
testcontainers>=3.7.0 | ||
packaging>=21.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
# Copyright 2023 Timescale, Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
"""Unit tests support for Timescale Doctor rules.""" | ||
|
||
import os | ||
import unittest | ||
|
||
from abc import ABCMeta | ||
|
||
import psycopg2 | ||
|
||
from psycopg2.extras import RealDictCursor | ||
from testcontainers.postgres import PostgresContainer | ||
|
||
class TestCase(unittest.TestCase, metaclass=ABCMeta): | ||
"""Base class for Timescale Doctor unit tests. | ||
Test cases are executed in a container that depends on the | ||
requirements of the test case. These are typically used together | ||
with the ``required`` decorator to attach an image to the test | ||
case and run the tests there. | ||
import doctor.unittest | ||
@doctor.unittest.requires('timescaledb') | ||
class TestCompressionRules(doctor.unittest.TestCase): | ||
... | ||
""" | ||
|
||
container_name = None | ||
|
||
@property | ||
def connection(self): | ||
"""Get database connection.""" | ||
return self.__connection | ||
|
||
@property | ||
def container(self): | ||
"""Get container the test is running in.""" | ||
return self.__container | ||
|
||
def run_rule(self, rule): | ||
"""Run rule and return messages.""" | ||
return rule.execute(self.connection, rule.message) | ||
|
||
@classmethod | ||
def setUpClass(cls): | ||
"""Start a container for the test case.""" | ||
assert cls.container_name is not None | ||
print("Container name:", cls.container_name) | ||
cls.__container = PostgresContainer(cls.container_name).start() | ||
connstring = cls.__container.get_connection_url().replace("+psycopg2", "") | ||
cls.__connection = psycopg2.connect(connstring, cursor_factory=RealDictCursor) | ||
|
||
@classmethod | ||
def tearDownClass(cls): | ||
"""Close the connection and stop the container.""" | ||
cls.__connection.close() | ||
cls.__container.stop() | ||
|
||
class TimescaleDBTestCase(TestCase): | ||
"""Base class for test cases that need TimescaleDB. | ||
It will read the container name from the environment variable | ||
"TEST_CONTAINER_TIMESCALE" if present, or default to | ||
"timescaledb:latest-pg15". | ||
""" | ||
|
||
container_name = os.environ.get('TEST_CONTAINER_TIMESCALE', 'timescale/timescaledb:latest-pg15') | ||
|
||
class PostgreSQLTestCase(TestCase): | ||
"""Base class for test cases that use plain PostgreSQL. | ||
It will read the container name from the environment variable | ||
"TEST_CONTAINER_POSTGRES" if present, or default to | ||
"postgres:latest". | ||
""" | ||
|
||
container_name = os.environ.get('TEST_CONTAINER_POSTGRES', 'postgres:latest') |