Skip to content

Commit fa40822

Browse files
authored
Merge pull request #3256 from vkarak/bugfix/optimize-testcase-queries
[bugfix] Optimize testcase queries over time period
2 parents 4dde6ec + e23a5e4 commit fa40822

File tree

1 file changed

+35
-15
lines changed

1 file changed

+35
-15
lines changed

reframe/frontend/reporting/storage.py

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -171,12 +171,12 @@ def store(self, report, report_file=None):
171171

172172
@time_function
173173
def _fetch_testcases_raw(self, condition):
174-
getprofiler().enter_region('sqlite query')
174+
# Retrieve relevant session info and index it in Python
175+
getprofiler().enter_region('sqlite session query')
175176
with self._db_connect(self._db_file()) as conn:
176-
query = ('SELECT session_uuid, testcases.uuid as uuid, json_blob '
177-
'FROM testcases '
178-
'JOIN sessions ON session_uuid == sessions.uuid '
179-
f'WHERE {condition}')
177+
query = ('SELECT uuid, json_blob FROM sessions WHERE uuid IN '
178+
'(SELECT DISTINCT session_uuid FROM testcases '
179+
f'WHERE {condition})')
180180
getlogger().debug(query)
181181

182182
# Create SQLite function for filtering using name patterns
@@ -185,10 +185,9 @@ def _fetch_testcases_raw(self, condition):
185185

186186
getprofiler().exit_region()
187187

188-
# Retrieve session info
189188
sessions = {}
190-
for session_uuid, uuid, json_blob in results:
191-
sessions.setdefault(session_uuid, json_blob)
189+
for uuid, json_blob in results:
190+
sessions.setdefault(uuid, json_blob)
192191

193192
# Join all sessions and decode them at once
194193
reports_blob = '[' + ','.join(sessions.values()) + ']'
@@ -200,14 +199,30 @@ def _fetch_testcases_raw(self, condition):
200199
for rpt in reports:
201200
sessions[rpt['session_info']['uuid']] = rpt
202201

203-
# Extract the test case data
202+
# Extract the test case data by extracting their UUIDs
203+
getprofiler().enter_region('sqlite testcase query')
204+
with self._db_connect(self._db_file()) as conn:
205+
query = f'SELECT uuid FROM testcases WHERE {condition}'
206+
getlogger().debug(query)
207+
conn.create_function('REGEXP', 2, self._db_matches)
208+
results = conn.execute(query).fetchall()
209+
210+
getprofiler().exit_region()
204211
testcases = []
205-
for session_uuid, uuid, json_blob in results:
206-
run_index, test_index = [int(x) for x in uuid.split(':')[1:]]
207-
report = sessions[session_uuid]
208-
testcases.append(
209-
report['runs'][run_index]['testcases'][test_index],
210-
)
212+
for uuid, *_ in results:
213+
session_uuid, run_index, test_index = uuid.split(':')
214+
run_index = int(run_index)
215+
test_index = int(test_index)
216+
try:
217+
report = sessions[session_uuid]
218+
except KeyError:
219+
# Since we do two separate queries, new testcases may have been
220+
# inserted to the DB meanwhile, so we ignore unknown sessions
221+
continue
222+
else:
223+
testcases.append(
224+
report['runs'][run_index]['testcases'][test_index],
225+
)
211226

212227
return testcases
213228

@@ -286,6 +301,9 @@ def _do_remove(self, uuid):
286301
prefix = os.path.dirname(self.__db_file)
287302
with FileLock(os.path.join(prefix, '.db.lock')):
288303
with self._db_connect(self._db_file()) as conn:
304+
# Enable foreign keys for delete action to have cascade effect
305+
conn.execute('PRAGMA foreign_keys = ON')
306+
289307
# Check first if the uuid exists
290308
query = f'SELECT * FROM sessions WHERE uuid == "{uuid}"'
291309
getlogger().debug(query)
@@ -301,6 +319,8 @@ def _do_remove2(self, uuid):
301319
prefix = os.path.dirname(self.__db_file)
302320
with FileLock(os.path.join(prefix, '.db.lock')):
303321
with self._db_connect(self._db_file()) as conn:
322+
# Enable foreign keys for delete action to have cascade effect
323+
conn.execute('PRAGMA foreign_keys = ON')
304324
query = (f'DELETE FROM sessions WHERE uuid == "{uuid}" '
305325
'RETURNING *')
306326
getlogger().debug(query)

0 commit comments

Comments
 (0)