orionis 0.591.0__py3-none-any.whl → 0.593.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- orionis/foundation/config/testing/entities/testing.py +0 -16
- orionis/metadata/framework.py +1 -1
- orionis/test/contracts/unit_test.py +0 -81
- orionis/test/core/unit_test.py +737 -604
- orionis/test/output/printer.py +258 -174
- orionis/test/records/logs.py +223 -83
- orionis/test/view/render.py +45 -17
- {orionis-0.591.0.dist-info → orionis-0.593.0.dist-info}/METADATA +1 -1
- {orionis-0.591.0.dist-info → orionis-0.593.0.dist-info}/RECORD +12 -12
- {orionis-0.591.0.dist-info → orionis-0.593.0.dist-info}/WHEEL +0 -0
- {orionis-0.591.0.dist-info → orionis-0.593.0.dist-info}/licenses/LICENCE +0 -0
- {orionis-0.591.0.dist-info → orionis-0.593.0.dist-info}/top_level.txt +0 -0
orionis/test/records/logs.py
CHANGED
@@ -1,44 +1,59 @@
|
|
1
|
-
import json
|
2
|
-
import sqlite3
|
3
1
|
from pathlib import Path
|
4
2
|
from typing import Dict, List, Optional, Tuple
|
5
|
-
|
3
|
+
import json
|
4
|
+
import sqlite3
|
6
5
|
from orionis.test.contracts.logs import ITestLogs
|
6
|
+
from orionis.test.exceptions import OrionisTestPersistenceError, OrionisTestValueError
|
7
7
|
|
8
8
|
class TestLogs(ITestLogs):
|
9
9
|
|
10
10
|
def __init__(
|
11
11
|
self,
|
12
|
-
storage_path: str
|
12
|
+
storage_path: str | Path,
|
13
|
+
db_name: str = 'tests.sqlite',
|
14
|
+
table_name: str = 'reports'
|
13
15
|
) -> None:
|
14
16
|
"""
|
15
|
-
Initialize
|
17
|
+
Initialize a TestLogs instance, configuring the SQLite database location and connection.
|
16
18
|
|
17
19
|
Parameters
|
18
20
|
----------
|
19
|
-
storage_path : str
|
20
|
-
Directory path where the SQLite database file
|
21
|
-
will be created
|
21
|
+
storage_path : str or Path
|
22
|
+
Directory path where the SQLite database file will be stored. If the directory does not exist,
|
23
|
+
it will be created automatically.
|
24
|
+
db_name : str, optional
|
25
|
+
Name of the SQLite database file. Defaults to 'tests.sqlite'.
|
26
|
+
table_name : str, optional
|
27
|
+
Name of the table used to store test reports. Defaults to 'reports'.
|
22
28
|
|
23
29
|
Returns
|
24
30
|
-------
|
25
31
|
None
|
32
|
+
This method does not return any value.
|
33
|
+
|
34
|
+
Notes
|
35
|
+
-----
|
36
|
+
The database connection is not established during initialization; it is set to None and will be
|
37
|
+
created when needed. The database path is resolved to an absolute path.
|
26
38
|
"""
|
27
|
-
# Set the database file and table names
|
28
|
-
self.__db_name = 'tests.sqlite'
|
29
|
-
self.__table_name = 'reports'
|
30
39
|
|
31
|
-
#
|
32
|
-
|
40
|
+
# Store the database file and table names as private attributes
|
41
|
+
self.__db_name = db_name
|
42
|
+
self.__table_name = table_name
|
43
|
+
|
44
|
+
# Convert storage_path to Path object if it is a string
|
45
|
+
db_path = Path(storage_path) if isinstance(storage_path, str) else storage_path
|
46
|
+
|
47
|
+
# Append the database file name to the directory path
|
33
48
|
db_path = db_path / self.__db_name
|
34
49
|
|
35
|
-
# Ensure the parent directory exists
|
50
|
+
# Ensure the parent directory for the database exists
|
36
51
|
db_path.parent.mkdir(parents=True, exist_ok=True)
|
37
52
|
|
38
|
-
# Store the
|
53
|
+
# Store the absolute path to the database file
|
39
54
|
self.__db_path = db_path.resolve()
|
40
55
|
|
41
|
-
# Initialize the database connection
|
56
|
+
# Initialize the database connection attribute to None
|
42
57
|
self._conn: Optional[sqlite3.Connection] = None
|
43
58
|
|
44
59
|
def __connect(
|
@@ -47,21 +62,33 @@ class TestLogs(ITestLogs):
|
|
47
62
|
"""
|
48
63
|
Establish a connection to the SQLite database if not already connected.
|
49
64
|
|
65
|
+
Parameters
|
66
|
+
----------
|
67
|
+
None
|
68
|
+
|
69
|
+
Returns
|
70
|
+
-------
|
71
|
+
None
|
72
|
+
This method does not return any value. It sets up the database connection as a side effect.
|
73
|
+
|
50
74
|
Raises
|
51
75
|
------
|
52
76
|
OrionisTestPersistenceError
|
53
77
|
If a database connection error occurs.
|
54
78
|
|
55
|
-
|
56
|
-
|
57
|
-
|
79
|
+
Notes
|
80
|
+
-----
|
81
|
+
This method initializes the SQLite connection only if it is not already established.
|
82
|
+
It configures the connection for improved concurrency using WAL mode and sets the synchronous
|
83
|
+
mode to NORMAL for better performance. The connection is stored in the `_conn` attribute.
|
58
84
|
"""
|
85
|
+
|
59
86
|
# Only connect if there is no existing connection
|
60
87
|
if self._conn is None:
|
61
88
|
|
62
89
|
try:
|
63
90
|
|
64
|
-
# Attempt to establish a new SQLite connection
|
91
|
+
# Attempt to establish a new SQLite connection with custom settings
|
65
92
|
self._conn = sqlite3.connect(
|
66
93
|
database=str(self.__db_path),
|
67
94
|
timeout=5.0,
|
@@ -70,40 +97,54 @@ class TestLogs(ITestLogs):
|
|
70
97
|
autocommit=True
|
71
98
|
)
|
72
99
|
|
73
|
-
#
|
100
|
+
# Enable Write-Ahead Logging for better concurrency
|
74
101
|
self._conn.execute("PRAGMA journal_mode=WAL;")
|
102
|
+
|
103
|
+
# Set synchronous mode to NORMAL for performance
|
75
104
|
self._conn.execute("PRAGMA synchronous=NORMAL;")
|
76
105
|
|
77
106
|
except (sqlite3.Error, Exception) as e:
|
78
107
|
|
79
108
|
# Raise a custom exception if connection fails
|
80
|
-
raise OrionisTestPersistenceError(
|
109
|
+
raise OrionisTestPersistenceError(
|
110
|
+
f"Failed to connect to SQLite database at '{self.__db_path}': {e}"
|
111
|
+
)
|
81
112
|
|
82
113
|
def __createTableIfNotExists(
|
83
114
|
self
|
84
115
|
) -> bool:
|
85
116
|
"""
|
86
|
-
|
117
|
+
Ensures that the reports table exists in the SQLite database, creating it if necessary.
|
118
|
+
|
119
|
+
Parameters
|
120
|
+
----------
|
121
|
+
None
|
87
122
|
|
88
123
|
Returns
|
89
124
|
-------
|
90
125
|
bool
|
91
|
-
True if the table was created or already exists.
|
126
|
+
Returns True if the table was created or already exists.
|
92
127
|
|
93
128
|
Raises
|
94
129
|
------
|
95
130
|
OrionisTestPersistenceError
|
96
|
-
|
131
|
+
Raised if table creation fails due to a database error.
|
132
|
+
|
133
|
+
Notes
|
134
|
+
-----
|
135
|
+
This method establishes a connection to the SQLite database and attempts to create the reports
|
136
|
+
table with the required schema if it does not already exist. The schema includes fields for
|
137
|
+
storing the report as JSON, test statistics, and a timestamp. The method commits the transaction
|
138
|
+
if successful, rolls back on error, and always closes the connection at the end.
|
97
139
|
"""
|
98
140
|
# Establish a connection to the database
|
99
141
|
self.__connect()
|
100
142
|
|
101
143
|
try:
|
102
|
-
|
103
144
|
# Create a cursor to execute SQL commands
|
104
145
|
cursor = self._conn.cursor()
|
105
146
|
|
106
|
-
# Create the table with the required schema if it does not exist
|
147
|
+
# Create the reports table with the required schema if it does not exist
|
107
148
|
cursor.execute(f'''
|
108
149
|
CREATE TABLE IF NOT EXISTS {self.__table_name} (
|
109
150
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
@@ -128,16 +169,18 @@ class TestLogs(ITestLogs):
|
|
128
169
|
except sqlite3.Error as e:
|
129
170
|
|
130
171
|
# Roll back the transaction if an error occurs
|
131
|
-
if self._conn:
|
172
|
+
if isinstance(self._conn, sqlite3.Connection):
|
132
173
|
self._conn.rollback()
|
133
174
|
|
134
175
|
# Raise a custom exception with the error details
|
135
|
-
raise OrionisTestPersistenceError(
|
176
|
+
raise OrionisTestPersistenceError(
|
177
|
+
f"Failed to create or verify table '{self.__table_name}' in database '{self.__db_name}' at '{self.__db_path}': {e}"
|
178
|
+
)
|
136
179
|
|
137
180
|
finally:
|
138
181
|
|
139
|
-
#
|
140
|
-
if self._conn:
|
182
|
+
# Always close the database connection after the operation
|
183
|
+
if isinstance(self._conn, sqlite3.Connection):
|
141
184
|
self.__close()
|
142
185
|
self._conn = None
|
143
186
|
|
@@ -146,43 +189,58 @@ class TestLogs(ITestLogs):
|
|
146
189
|
report: Dict
|
147
190
|
) -> bool:
|
148
191
|
"""
|
149
|
-
|
192
|
+
Inserts a test report into the reports table in the SQLite database.
|
150
193
|
|
151
194
|
Parameters
|
152
195
|
----------
|
153
196
|
report : dict
|
154
|
-
Dictionary containing the report data. Must include keys:
|
197
|
+
Dictionary containing the report data. Must include the following keys:
|
155
198
|
'total_tests', 'passed', 'failed', 'errors', 'skipped', 'total_time', 'success_rate', 'timestamp'.
|
199
|
+
The entire report will be serialized and stored in the 'json' column.
|
156
200
|
|
157
201
|
Returns
|
158
202
|
-------
|
159
203
|
bool
|
160
|
-
True if the report was successfully inserted.
|
204
|
+
Returns True if the report was successfully inserted into the database.
|
161
205
|
|
162
206
|
Raises
|
163
207
|
------
|
164
208
|
OrionisTestPersistenceError
|
165
|
-
If
|
209
|
+
If an error occurs while inserting the report into the database.
|
166
210
|
OrionisTestValueError
|
167
|
-
If required fields are missing from the report.
|
211
|
+
If any required fields are missing from the report.
|
212
|
+
|
213
|
+
Notes
|
214
|
+
-----
|
215
|
+
This method validates the presence of all required fields in the report dictionary (except 'json', which is
|
216
|
+
handled by serializing the entire report). The report is inserted as a new row in the reports table, with the
|
217
|
+
full dictionary stored as a JSON string in the 'json' column and individual fields mapped to their respective
|
218
|
+
columns. The database connection is managed internally and closed after the operation.
|
168
219
|
"""
|
169
|
-
|
220
|
+
|
221
|
+
# List of required fields for the report (excluding 'json', which is handled separately)
|
170
222
|
fields = [
|
171
223
|
"json", "total_tests", "passed", "failed", "errors",
|
172
224
|
"skipped", "total_time", "success_rate", "timestamp"
|
173
225
|
]
|
174
226
|
|
175
|
-
# Check for missing required fields
|
227
|
+
# Check for missing required fields in the report dictionary
|
176
228
|
missing = []
|
177
229
|
for key in fields:
|
178
230
|
if key not in report and key != "json":
|
179
231
|
missing.append(key)
|
232
|
+
|
233
|
+
# If any required fields are missing, raise an exception
|
180
234
|
if missing:
|
181
|
-
raise OrionisTestValueError(
|
235
|
+
raise OrionisTestValueError(
|
236
|
+
f"The report is missing the following required fields: {', '.join(missing)}"
|
237
|
+
)
|
182
238
|
|
183
239
|
# Establish a connection to the database
|
184
240
|
self.__connect()
|
241
|
+
|
185
242
|
try:
|
243
|
+
|
186
244
|
# Prepare the SQL query to insert the report data
|
187
245
|
query = f'''
|
188
246
|
INSERT INTO {self.__table_name} (
|
@@ -191,10 +249,10 @@ class TestLogs(ITestLogs):
|
|
191
249
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
192
250
|
'''
|
193
251
|
|
194
|
-
#
|
252
|
+
# Create a cursor for executing the SQL statement
|
195
253
|
cursor = self._conn.cursor()
|
196
254
|
|
197
|
-
#
|
255
|
+
# Insert the report data, serializing the entire report as JSON for the 'json' column
|
198
256
|
cursor.execute(query, (
|
199
257
|
json.dumps(report),
|
200
258
|
report["total_tests"],
|
@@ -207,23 +265,27 @@ class TestLogs(ITestLogs):
|
|
207
265
|
report["timestamp"]
|
208
266
|
))
|
209
267
|
|
210
|
-
# Commit the transaction to
|
268
|
+
# Commit the transaction to persist the new report
|
211
269
|
self._conn.commit()
|
212
270
|
|
213
|
-
# Return True
|
271
|
+
# Return True to indicate successful insertion
|
214
272
|
return True
|
215
273
|
|
216
274
|
except sqlite3.Error as e:
|
217
275
|
|
218
276
|
# Roll back the transaction if an error occurs during insertion
|
219
|
-
if self._conn:
|
277
|
+
if isinstance(self._conn, sqlite3.Connection):
|
220
278
|
self._conn.rollback()
|
221
|
-
|
279
|
+
|
280
|
+
# Raise a custom exception with the error details
|
281
|
+
raise OrionisTestPersistenceError(
|
282
|
+
f"Failed to insert report into table '{self.__table_name}' in database '{self.__db_name}' at '{self.__db_path}': {e}"
|
283
|
+
)
|
222
284
|
|
223
285
|
finally:
|
224
286
|
|
225
287
|
# Ensure the database connection is closed after the operation
|
226
|
-
if self._conn:
|
288
|
+
if isinstance(self._conn, sqlite3.Connection):
|
227
289
|
self.__close()
|
228
290
|
self._conn = None
|
229
291
|
|
@@ -233,19 +295,20 @@ class TestLogs(ITestLogs):
|
|
233
295
|
last: Optional[int] = None
|
234
296
|
) -> List[Tuple]:
|
235
297
|
"""
|
236
|
-
Retrieve a specified number of report records from the database.
|
298
|
+
Retrieve a specified number of report records from the database, either the earliest or latest entries.
|
237
299
|
|
238
300
|
Parameters
|
239
301
|
----------
|
240
302
|
first : int or None, optional
|
241
|
-
|
303
|
+
The number of earliest reports to retrieve, ordered by ascending ID. Must be a positive integer.
|
242
304
|
last : int or None, optional
|
243
|
-
|
305
|
+
The number of latest reports to retrieve, ordered by descending ID. Must be a positive integer.
|
244
306
|
|
245
307
|
Returns
|
246
308
|
-------
|
247
|
-
|
248
|
-
|
309
|
+
List[Tuple]
|
310
|
+
A list of tuples, where each tuple represents a row from the reports table. Each tuple contains:
|
311
|
+
(id, json, total_tests, passed, failed, errors, skipped, total_time, success_rate, timestamp).
|
249
312
|
|
250
313
|
Raises
|
251
314
|
------
|
@@ -253,24 +316,31 @@ class TestLogs(ITestLogs):
|
|
253
316
|
If both 'first' and 'last' are specified, or if either is not a positive integer.
|
254
317
|
OrionisTestPersistenceError
|
255
318
|
If there is an error retrieving reports from the database.
|
319
|
+
|
320
|
+
Notes
|
321
|
+
-----
|
322
|
+
Only one of 'first' or 'last' can be specified at a time. If neither is provided, no records are returned.
|
323
|
+
The method ensures proper connection management and closes the database connection after retrieval.
|
256
324
|
"""
|
325
|
+
|
257
326
|
# Ensure that only one of 'first' or 'last' is specified
|
258
327
|
if first is not None and last is not None:
|
259
328
|
raise OrionisTestValueError(
|
260
|
-
"
|
329
|
+
"You cannot specify both 'first' and 'last' parameters at the same time. Please provide only one."
|
261
330
|
)
|
262
331
|
|
263
332
|
# Validate 'first' parameter if provided
|
264
333
|
if first is not None:
|
265
334
|
if not isinstance(first, int) or first <= 0:
|
266
|
-
raise OrionisTestValueError("'first' must be
|
335
|
+
raise OrionisTestValueError("'first' must be a positive integer greater than zero.")
|
267
336
|
|
268
337
|
# Validate 'last' parameter if provided
|
269
338
|
if last is not None:
|
270
339
|
if not isinstance(last, int) or last <= 0:
|
271
|
-
raise OrionisTestValueError("'last' must be
|
340
|
+
raise OrionisTestValueError("'last' must be a positive integer greater than zero.")
|
272
341
|
|
273
342
|
# Determine the order and quantity of records to retrieve
|
343
|
+
# If 'last' is specified, order by descending ID; otherwise, ascending
|
274
344
|
order = 'DESC' if last is not None else 'ASC'
|
275
345
|
quantity = first if first is not None else last
|
276
346
|
|
@@ -286,21 +356,23 @@ class TestLogs(ITestLogs):
|
|
286
356
|
query = f"SELECT * FROM {self.__table_name} ORDER BY id {order} LIMIT ?"
|
287
357
|
cursor.execute(query, (quantity,))
|
288
358
|
|
289
|
-
# Fetch all matching records
|
359
|
+
# Fetch all matching records from the database
|
290
360
|
results = cursor.fetchall()
|
291
361
|
|
292
|
-
# Return the list of report records
|
362
|
+
# Return the list of report records as tuples
|
293
363
|
return results
|
294
364
|
|
295
365
|
except sqlite3.Error as e:
|
296
366
|
|
297
367
|
# Raise a custom exception if retrieval fails
|
298
|
-
raise OrionisTestPersistenceError(
|
368
|
+
raise OrionisTestPersistenceError(
|
369
|
+
f"An error occurred while retrieving reports from table '{self.__table_name}' in database '{self.__db_name}' at '{self.__db_path}': {e}"
|
370
|
+
)
|
299
371
|
|
300
372
|
finally:
|
301
373
|
|
302
374
|
# Ensure the database connection is closed after the operation
|
303
|
-
if self._conn:
|
375
|
+
if isinstance(self._conn, sqlite3.Connection):
|
304
376
|
self.__close()
|
305
377
|
self._conn = None
|
306
378
|
|
@@ -308,42 +380,56 @@ class TestLogs(ITestLogs):
|
|
308
380
|
self
|
309
381
|
) -> bool:
|
310
382
|
"""
|
311
|
-
|
383
|
+
Drops the reports table from the SQLite database, effectively clearing all stored test history.
|
384
|
+
|
385
|
+
Parameters
|
386
|
+
----------
|
387
|
+
None
|
312
388
|
|
313
389
|
Returns
|
314
390
|
-------
|
315
391
|
bool
|
316
|
-
True if the table was successfully dropped or did not exist.
|
392
|
+
Returns True if the reports table was successfully dropped or did not exist. If the operation
|
393
|
+
completes without raising an exception, the database is considered reset.
|
317
394
|
|
318
395
|
Raises
|
319
396
|
------
|
320
397
|
OrionisTestPersistenceError
|
321
398
|
If an SQLite error occurs while attempting to drop the table.
|
399
|
+
|
400
|
+
Notes
|
401
|
+
-----
|
402
|
+
This method establishes a connection to the SQLite database and attempts to drop the reports table
|
403
|
+
specified by `self.__table_name`. If the table does not exist, the operation completes silently.
|
404
|
+
The database connection is closed after the operation, regardless of success or failure.
|
322
405
|
"""
|
406
|
+
|
323
407
|
# Establish a connection to the database
|
324
408
|
self.__connect()
|
325
409
|
|
326
410
|
try:
|
327
411
|
|
328
|
-
# Create a cursor and execute the DROP TABLE statement
|
412
|
+
# Create a cursor and execute the DROP TABLE statement to remove the reports table
|
329
413
|
cursor = self._conn.cursor()
|
330
414
|
cursor.execute(f'DROP TABLE IF EXISTS {self.__table_name}')
|
331
415
|
|
332
416
|
# Commit the transaction to apply the changes
|
333
417
|
self._conn.commit()
|
334
418
|
|
335
|
-
# Return True to indicate the reset was successful
|
419
|
+
# Return True to indicate the reset was successful or the table did not exist
|
336
420
|
return True
|
337
421
|
|
338
422
|
except sqlite3.Error as e:
|
339
423
|
|
340
424
|
# Raise a custom exception if the reset fails
|
341
|
-
raise OrionisTestPersistenceError(
|
425
|
+
raise OrionisTestPersistenceError(
|
426
|
+
f"Failed to reset the reports table '{self.__table_name}' in database '{self.__db_name}' at '{self.__db_path}': {e}"
|
427
|
+
)
|
342
428
|
|
343
429
|
finally:
|
344
430
|
|
345
431
|
# Ensure the database connection is closed after the operation
|
346
|
-
if self._conn:
|
432
|
+
if isinstance(self._conn, sqlite3.Connection):
|
347
433
|
self.__close()
|
348
434
|
self._conn = None
|
349
435
|
|
@@ -353,13 +439,30 @@ class TestLogs(ITestLogs):
|
|
353
439
|
"""
|
354
440
|
Close the active SQLite database connection if it exists.
|
355
441
|
|
442
|
+
This method safely closes the current SQLite database connection if it is open.
|
443
|
+
It ensures that resources are released and the connection attribute is reset to None.
|
444
|
+
This is important for preventing resource leaks and maintaining proper connection management
|
445
|
+
within the TestLogs class.
|
446
|
+
|
356
447
|
Returns
|
357
448
|
-------
|
358
449
|
None
|
450
|
+
This method does not return any value. The side effect is that the database connection
|
451
|
+
is closed and the internal connection attribute is set to None.
|
452
|
+
|
453
|
+
Notes
|
454
|
+
-----
|
455
|
+
This method should be called after database operations to ensure the connection is properly closed.
|
456
|
+
It checks if the `_conn` attribute is an active `sqlite3.Connection` before attempting to close it.
|
359
457
|
"""
|
360
|
-
|
361
|
-
if
|
458
|
+
|
459
|
+
# Check if there is an active SQLite connection before closing
|
460
|
+
if isinstance(self._conn, sqlite3.Connection):
|
461
|
+
|
462
|
+
# Close the database connection to release resources
|
362
463
|
self._conn.close()
|
464
|
+
|
465
|
+
# Reset the connection attribute to None
|
363
466
|
self._conn = None
|
364
467
|
|
365
468
|
def create(
|
@@ -367,48 +470,73 @@ class TestLogs(ITestLogs):
|
|
367
470
|
report: Dict
|
368
471
|
) -> bool:
|
369
472
|
"""
|
370
|
-
|
473
|
+
Inserts a new test report into the database after ensuring the reports table exists.
|
371
474
|
|
372
475
|
Parameters
|
373
476
|
----------
|
374
477
|
report : dict
|
375
|
-
Dictionary containing the test report data. Must include all required fields
|
478
|
+
Dictionary containing the test report data. Must include all required fields:
|
479
|
+
'total_tests', 'passed', 'failed', 'errors', 'skipped', 'total_time', 'success_rate', 'timestamp'.
|
480
|
+
The entire report will be serialized and stored in the 'json' column.
|
376
481
|
|
377
482
|
Returns
|
378
483
|
-------
|
379
484
|
bool
|
380
|
-
True if the report was successfully inserted.
|
485
|
+
True if the report was successfully inserted into the database; otherwise, raises an exception.
|
381
486
|
|
382
487
|
Raises
|
383
488
|
------
|
384
489
|
OrionisTestPersistenceError
|
385
|
-
If
|
490
|
+
If a database error occurs during table creation or report insertion.
|
386
491
|
OrionisTestValueError
|
387
|
-
If required fields are missing from the report.
|
492
|
+
If required fields are missing from the report dictionary.
|
493
|
+
|
494
|
+
Notes
|
495
|
+
-----
|
496
|
+
This method first ensures that the reports table exists in the database. It then validates and inserts
|
497
|
+
the provided report dictionary as a new row, storing the full report as a JSON string and mapping individual
|
498
|
+
fields to their respective columns. The database connection is managed internally and closed after the operation.
|
388
499
|
"""
|
389
|
-
|
500
|
+
|
501
|
+
# Ensure the reports table exists before attempting to insert the report
|
390
502
|
self.__createTableIfNotExists()
|
391
503
|
|
392
|
-
# Insert the report into the database and return
|
504
|
+
# Insert the report into the database and return True if successful
|
393
505
|
return self.__insertReport(report)
|
394
506
|
|
395
507
|
def reset(
|
396
508
|
self
|
397
509
|
) -> bool:
|
398
510
|
"""
|
399
|
-
|
511
|
+
Drops the reports table from the SQLite database, effectively clearing all stored test history.
|
512
|
+
|
513
|
+
This method attempts to remove the reports table specified by `self.__table_name` from the database.
|
514
|
+
If the table does not exist, the operation completes without error. The database connection is managed
|
515
|
+
internally and closed after the operation.
|
516
|
+
|
517
|
+
Parameters
|
518
|
+
----------
|
519
|
+
None
|
400
520
|
|
401
521
|
Returns
|
402
522
|
-------
|
403
523
|
bool
|
404
|
-
True if the reports table was successfully dropped or did not exist.
|
524
|
+
Returns True if the reports table was successfully dropped or did not exist. If the operation
|
525
|
+
completes without raising an exception, the database is considered reset.
|
405
526
|
|
406
527
|
Raises
|
407
528
|
------
|
408
529
|
OrionisTestPersistenceError
|
409
|
-
If
|
530
|
+
If an SQLite error occurs while attempting to drop the table.
|
531
|
+
|
532
|
+
Notes
|
533
|
+
-----
|
534
|
+
This method is useful for clearing all test report history from the database, such as during test
|
535
|
+
environment resets or cleanup operations.
|
410
536
|
"""
|
411
|
-
|
537
|
+
|
538
|
+
# Attempt to drop the reports table and reset the database.
|
539
|
+
# Returns True if successful or if the table did not exist.
|
412
540
|
return self.__resetDatabase()
|
413
541
|
|
414
542
|
def get(
|
@@ -417,19 +545,23 @@ class TestLogs(ITestLogs):
|
|
417
545
|
last: Optional[int] = None
|
418
546
|
) -> List[Tuple]:
|
419
547
|
"""
|
420
|
-
Retrieve test
|
548
|
+
Retrieve a specified number of test report records from the database.
|
421
549
|
|
422
550
|
Parameters
|
423
551
|
----------
|
424
552
|
first : int or None, optional
|
425
|
-
|
553
|
+
The number of earliest reports to retrieve, ordered by ascending ID. Must be a positive integer.
|
554
|
+
If specified, returns the oldest reports.
|
426
555
|
last : int or None, optional
|
427
|
-
|
556
|
+
The number of latest reports to retrieve, ordered by descending ID. Must be a positive integer.
|
557
|
+
If specified, returns the most recent reports.
|
428
558
|
|
429
559
|
Returns
|
430
560
|
-------
|
431
|
-
|
432
|
-
|
561
|
+
List[Tuple]
|
562
|
+
A list of tuples, where each tuple represents a row from the reports table:
|
563
|
+
(id, json, total_tests, passed, failed, errors, skipped, total_time, success_rate, timestamp).
|
564
|
+
If neither `first` nor `last` is provided, an empty list is returned.
|
433
565
|
|
434
566
|
Raises
|
435
567
|
------
|
@@ -437,6 +569,14 @@ class TestLogs(ITestLogs):
|
|
437
569
|
If both 'first' and 'last' are specified, or if either is not a positive integer.
|
438
570
|
OrionisTestPersistenceError
|
439
571
|
If there is an error retrieving reports from the database.
|
572
|
+
|
573
|
+
Notes
|
574
|
+
-----
|
575
|
+
Only one of `first` or `last` can be specified at a time. The method delegates the retrieval
|
576
|
+
logic to the internal `__getReports` method, which handles database connection management and
|
577
|
+
query execution.
|
440
578
|
"""
|
441
|
-
|
579
|
+
|
580
|
+
# Delegate the retrieval logic to the internal __getReports method.
|
581
|
+
# This ensures proper validation and database access.
|
442
582
|
return self.__getReports(first, last)
|