Skip to content

Commit c3a2bc1

Browse files
authored
First db tests (#114)
* First db tests * Update database.py
1 parent e73dbb7 commit c3a2bc1

File tree

4 files changed

+139
-20
lines changed

4 files changed

+139
-20
lines changed

test/NOT-USED-HOST

72 KB
Binary file not shown.

test/test_db_sqlite.py

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import logging
2+
3+
import pytest
4+
from sqlalchemy import func, select
5+
6+
from wadas._version import __dbversion__
7+
from wadas.domain.database import DataBase, SQLiteDataBase
8+
from wadas.domain.db_model import (
9+
ActuationEvent,
10+
Actuator,
11+
Camera,
12+
ClassifiedAnimals,
13+
DBMetadata,
14+
DetectionEvent,
15+
FeederActuator,
16+
FTPCamera,
17+
RoadSignActuator,
18+
USBCamera,
19+
camera_actuator_association,
20+
)
21+
22+
logger = logging.getLogger(__name__)
23+
24+
25+
@pytest.fixture
26+
def init():
27+
if DataBase.wadas_db_engine is not None:
28+
DataBase.destroy_instance()
29+
assert DataBase.wadas_db_engine is None
30+
assert DataBase.wadas_db is None
31+
if DataBase.wadas_db is not None:
32+
logger.debug("Found an active db instance before test execution...")
33+
DataBase.wadas_db = None
34+
35+
36+
@pytest.fixture()
37+
def db(init):
38+
assert DataBase.initialize(DataBase.DBTypes.SQLITE, ":memory:", None, "", "") is True
39+
db = DataBase.get_instance()
40+
session = DataBase.create_session()
41+
assert db.create_database() is True
42+
yield db, session
43+
DataBase.destroy_instance()
44+
45+
46+
def test_database_already_created(init):
47+
DataBase.wadas_db = True
48+
with pytest.raises(RuntimeError, match="Database instance already created."):
49+
SQLiteDataBase("NOT-USED-HOST")
50+
51+
52+
def test_database_already_initialized(init):
53+
DataBase.wadas_db = True
54+
assert DataBase.initialize(DataBase.DBTypes.SQLITE, "NOT-USED-HOST", None, "", "") is False
55+
56+
57+
def test_no_host(init):
58+
assert DataBase.initialize(DataBase.DBTypes.SQLITE, "", None, "", "") is False
59+
60+
61+
def test_unsupported_database(init):
62+
with pytest.raises(ValueError, match="Unsupported database type: DUMMY-DB-TYPE"):
63+
DataBase.initialize("DUMMY-DB-TYPE", "NOT-USED-HOST", None, "", "")
64+
65+
66+
def test_no_engine_and_no_database(init):
67+
with pytest.raises(RuntimeError, match="The database and db engine have not been initialized."):
68+
SQLiteDataBase.get_engine()
69+
70+
71+
def test_no_database(init):
72+
assert SQLiteDataBase.get_instance() is None
73+
74+
75+
def test_failing_on_destroy_instance(init):
76+
DataBase.wadas_db_engine = True
77+
SQLiteDataBase.destroy_instance()
78+
assert DataBase.wadas_db_engine is None
79+
80+
81+
def test_connection_string(db):
82+
db, session = db
83+
assert db is not None
84+
assert DataBase.wadas_db_engine is not None
85+
assert db.get_connection_string() == "sqlite:///:memory:"
86+
87+
88+
def test_database_not_initialized(init):
89+
assert SQLiteDataBase("NOT-USED-HOST").create_database() is False
90+
91+
92+
def test_serialize(init):
93+
assert SQLiteDataBase("NOT-USED-HOST").serialize() == {
94+
"host": "NOT-USED-HOST",
95+
"type": DataBase.DBTypes.SQLITE.value,
96+
"enabled": True,
97+
"version": __dbversion__,
98+
}
99+
assert SQLiteDataBase("NOT-USED-HOST2", False, "vX.Y.Z").serialize() == {
100+
"host": "NOT-USED-HOST2",
101+
"type": DataBase.DBTypes.SQLITE.value,
102+
"enabled": False,
103+
"version": "vX.Y.Z",
104+
}
105+
106+
107+
def test_empty_database(db):
108+
db, session = db
109+
assert session.execute(select(func.count()).select_from(ActuationEvent)).scalar() == 0
110+
assert session.execute(select(func.count()).select_from(Actuator)).scalar() == 0
111+
assert session.execute(select(func.count()).select_from(Camera)).scalar() == 0
112+
assert session.execute(select(func.count()).select_from(ClassifiedAnimals)).scalar() == 0
113+
assert session.execute(select(func.count()).select_from(DBMetadata)).scalar() == 0
114+
assert session.execute(select(func.count()).select_from(DetectionEvent)).scalar() == 0
115+
assert session.execute(select(func.count()).select_from(FeederActuator)).scalar() == 0
116+
assert session.execute(select(func.count()).select_from(FTPCamera)).scalar() == 0
117+
assert session.execute(select(func.count()).select_from(RoadSignActuator)).scalar() == 0
118+
assert session.execute(select(func.count()).select_from(USBCamera)).scalar() == 0
119+
assert (
120+
session.execute(select(func.count()).select_from(camera_actuator_association)).scalar() == 0
121+
)

wadas/domain/configuration.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ def save_configuration_to_file(file_, project_uuid):
325325
if FastAPIActuatorServer.actuator_server
326326
else ""
327327
),
328-
"database": DataBase.wadas_db.serialize() if DataBase.wadas_db else "",
328+
"database": db.serialize() if (db := DataBase.get_instance()) else "",
329329
}
330330

331331
with open(file_, "w") as yaml_file:

wadas/domain/database.py

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,14 @@ def __init__(self, description: str, project_uuid):
6767
class DataBase(ABC):
6868
"""Base Class to handle DB object."""
6969

70-
wadas_db = None # Singleton instance of the database
71-
wadas_db_engine = None # Singleton engine associated with the database
72-
7370
class DBTypes(Enum):
7471
SQLITE = "SQLite"
7572
MYSQL = "MySQL"
7673
MARIADB = "MariaDB"
7774

75+
wadas_db = None # Singleton instance of the database
76+
wadas_db_engine = None # Singleton engine associated with the database
77+
7878
def __init__(self, host, enabled=True, version=__dbversion__):
7979
"""Constructor is not public, no external code should call this directly"""
8080

@@ -135,19 +135,17 @@ def initialize(
135135
):
136136
"""Initialize the singleton database instance."""
137137

138-
if cls.wadas_db is not None:
138+
if DataBase.wadas_db is not None:
139139
logger.error("Database is already initialized.")
140140
return False
141141

142-
sb_instance = cls._create_instance(
142+
DataBase.wadas_db = cls._create_instance(
143143
db_type, host, port, username, database_name, enabled=True, version=__dbversion__
144144
)
145-
if sb_instance:
146-
cls.wadas_db = sb_instance
147-
else:
145+
if not DataBase.wadas_db:
148146
return False
149147

150-
cls.wadas_db_engine = create_engine(cls.wadas_db.get_connection_string())
148+
DataBase.wadas_db_engine = create_engine(DataBase.wadas_db.get_connection_string())
151149
if log:
152150
logger.info("%s database initialized.", db_type.value)
153151
return True
@@ -159,14 +157,14 @@ def get_engine(cls):
159157
160158
:return: SQLAlchemy engine instance.
161159
"""
162-
if cls.wadas_db_engine is None:
163-
if cls.wadas_db is None:
160+
if DataBase.wadas_db_engine is None:
161+
if DataBase.wadas_db is None:
164162
logger.error("The database and db engine have not been initialized.")
165163
raise RuntimeError("The database and db engine have not been initialized.")
166164
else:
167165
logger.debug("Initializing engine...")
168-
cls.wadas_db_engine = create_engine(cls.wadas_db.get_connection_string())
169-
return cls.wadas_db_engine
166+
DataBase.wadas_db_engine = create_engine(DataBase.wadas_db.get_connection_string())
167+
return DataBase.wadas_db_engine
170168

171169
@classmethod
172170
def get_instance(cls):
@@ -175,23 +173,23 @@ def get_instance(cls):
175173
176174
:return: The current database instance.
177175
"""
178-
if cls.wadas_db is None:
176+
if DataBase.wadas_db is None:
179177
logger.debug("The database has not been initialized. Call 'initialize' first.")
180178
return None
181-
return cls.wadas_db
179+
return DataBase.wadas_db
182180

183181
@classmethod
184182
def destroy_instance(cls):
185183
"""Destroy the current database instance and release resources."""
186184

187185
logger.debug("Destroying db instance...")
188-
if cls.wadas_db_engine:
186+
if DataBase.wadas_db_engine:
189187
try:
190-
cls.wadas_db_engine.dispose()
188+
DataBase.wadas_db_engine.dispose()
191189
except Exception:
192190
logger.warning("Failed to dispose the database engine.")
193-
cls.wadas_db_engine = None
194-
cls.wadas_db = None
191+
DataBase.wadas_db_engine = None
192+
DataBase.wadas_db = None
195193

196194
@classmethod
197195
def create_session(cls):

0 commit comments

Comments
 (0)