|
1 | 1 | from typing import TypedDict |
2 | 2 | from datetime import datetime |
3 | 3 | from django.db import connection |
| 4 | +from itertools import repeat |
4 | 5 |
|
5 | 6 | from kernelCI_app.helpers.database import dict_fetchall |
6 | 7 | from kernelCI_app.cache import get_query_cache, set_query_cache |
@@ -339,15 +340,129 @@ def get_hardware_details_data( |
339 | 340 | return records |
340 | 341 |
|
341 | 342 |
|
| 343 | +def get_hardware_details_summary( |
| 344 | + *, |
| 345 | + hardware_id: str, |
| 346 | + origin: str, |
| 347 | + trees_with_selected_commits: list[Tree], |
| 348 | + start_datetime: datetime, |
| 349 | + end_datetime: datetime, |
| 350 | +): |
| 351 | + |
| 352 | + commit_hashes = [tree.head_git_commit_hash for tree in trees_with_selected_commits] |
| 353 | + |
| 354 | + query = """ |
| 355 | + (SELECT |
| 356 | + COUNT(distinct builds.id) AS count, |
| 357 | + checkouts.origin, |
| 358 | + builds.status AS status, |
| 359 | + count(incidents.id) AS known_issues, |
| 360 | + array[builds.compiler, builds.architecture] AS compiler_arch, |
| 361 | + builds.config_name, |
| 362 | + builds.misc->>'runtime' AS lab, |
| 363 | + tests.environment_misc->>'platform' AS platform, |
| 364 | + tests.environment_compatible, |
| 365 | + checkouts.origin, |
| 366 | + checkouts.tree_name, |
| 367 | + checkouts.git_repository_url, |
| 368 | + checkouts.git_commit_tags, |
| 369 | + checkouts.git_commit_name, |
| 370 | + checkouts.git_repository_branch, |
| 371 | + checkouts.git_commit_hash, |
| 372 | + true AS is_build, |
| 373 | + false AS is_test, |
| 374 | + false AS is_boot |
| 375 | + FROM |
| 376 | + builds |
| 377 | + INNER JOIN tests ON |
| 378 | + tests.build_id = builds.id |
| 379 | + INNER JOIN checkouts ON |
| 380 | + builds.checkout_id = checkouts.id |
| 381 | + LEFT OUTER JOIN incidents ON |
| 382 | + builds.id = incidents.build_id |
| 383 | + WHERE |
| 384 | + ( |
| 385 | + builds.config_name IS NOT NULL |
| 386 | + AND builds.id not like 'maestro:dummy_%%' |
| 387 | + AND (tests.environment_compatible @> ARRAY[%s]::TEXT[] |
| 388 | + OR tests.environment_misc ->> 'platform' = %s) |
| 389 | + ) |
| 390 | + AND builds.origin = %s |
| 391 | + AND builds.start_time >= %s |
| 392 | + AND builds.start_time <= %s |
| 393 | + AND checkouts.git_commit_hash IN ({0}) |
| 394 | + GROUP BY checkouts.id, builds.status, tests.environment_compatible, compiler_arch, |
| 395 | + builds.config_name, lab, platform, is_boot) |
| 396 | + UNION ALL |
| 397 | + (SELECT |
| 398 | + COUNT(*) AS tests_count, |
| 399 | + checkouts.origin, |
| 400 | + tests.status AS status, |
| 401 | + count(incidents.id) AS known_issues, |
| 402 | + array[builds.compiler, builds.architecture] AS compiler_arch, |
| 403 | + builds.config_name, |
| 404 | + tests.misc->>'runtime' AS lab, |
| 405 | + tests.environment_misc->>'platform' AS platform, |
| 406 | + tests.environment_compatible, |
| 407 | + checkouts.origin, |
| 408 | + checkouts.tree_name, |
| 409 | + checkouts.git_repository_url, |
| 410 | + checkouts.git_commit_tags, |
| 411 | + checkouts.git_commit_name, |
| 412 | + checkouts.git_repository_branch, |
| 413 | + checkouts.git_commit_hash, |
| 414 | + false AS is_build, |
| 415 | + true AS is_test, |
| 416 | + (tests.path like 'boot.%%' or tests.path = 'boot') AS is_boot |
| 417 | + FROM |
| 418 | + builds |
| 419 | + inner JOIN tests ON |
| 420 | + tests.build_id = builds.id |
| 421 | + INNER JOIN checkouts ON |
| 422 | + builds.checkout_id = checkouts.id |
| 423 | + LEFT OUTER JOIN incidents ON |
| 424 | + tests.id = incidents.test_id |
| 425 | + WHERE |
| 426 | + ( |
| 427 | + builds.config_name IS NOT NULL |
| 428 | + AND builds.id not like 'maestro:dummy_%%' |
| 429 | + AND (tests.environment_compatible @> ARRAY[%s]::TEXT[] |
| 430 | + OR tests.environment_misc ->> 'platform' = %s) |
| 431 | + ) |
| 432 | + AND tests.origin = %s |
| 433 | + AND tests.start_time >= %s |
| 434 | + AND tests.start_time <= %s |
| 435 | + AND checkouts.git_commit_hash IN ({0}) |
| 436 | + GROUP BY checkouts.id, tests.status, tests.environment_compatible, compiler_arch, |
| 437 | + builds.config_name, lab, platform, is_boot); |
| 438 | + """.format( |
| 439 | + ",".join(repeat("%s", len(commit_hashes))) |
| 440 | + ) |
| 441 | + |
| 442 | + params = [ |
| 443 | + hardware_id, |
| 444 | + hardware_id, |
| 445 | + origin, |
| 446 | + start_datetime, |
| 447 | + end_datetime, |
| 448 | + *commit_hashes, |
| 449 | + ] |
| 450 | + |
| 451 | + # TODO: check if we can reuse parameters to avoid double passing |
| 452 | + params = [*params, *params] |
| 453 | + |
| 454 | + with connection.cursor() as cursor: |
| 455 | + cursor.execute(query, params) |
| 456 | + query_rows = dict_fetchall(cursor) |
| 457 | + return query_rows |
| 458 | + |
| 459 | + |
342 | 460 | def query_records( |
343 | 461 | *, hardware_id: str, origin: str, trees: list[Tree], start_date: int, end_date: int |
344 | 462 | ) -> list[dict] | None: |
345 | 463 | commit_hashes = [tree.head_git_commit_hash for tree in trees] |
346 | 464 |
|
347 | | - # TODO Treat commit_hash collision (it can happen between repos) |
348 | | - with connection.cursor() as cursor: |
349 | | - cursor.execute( |
350 | | - """ |
| 465 | + query = """ |
351 | 466 | SELECT |
352 | 467 | tests.id, |
353 | 468 | tests.origin AS test_origin, |
@@ -411,19 +526,22 @@ def query_records( |
411 | 526 | ORDER BY |
412 | 527 | issues."_timestamp" DESC |
413 | 528 | """.format( |
414 | | - ",".join(["%s"] * len(commit_hashes)) |
415 | | - ), |
416 | | - [ |
417 | | - hardware_id, |
418 | | - hardware_id, |
419 | | - origin, |
420 | | - start_date, |
421 | | - end_date, |
422 | | - ] |
423 | | - + commit_hashes, |
424 | | - ) |
| 529 | + ",".join(["%s"] * len(commit_hashes)) |
| 530 | + ) |
425 | 531 |
|
426 | | - return dict_fetchall(cursor) |
| 532 | + params = [ |
| 533 | + hardware_id, |
| 534 | + hardware_id, |
| 535 | + origin, |
| 536 | + start_date, |
| 537 | + end_date, |
| 538 | + ] + commit_hashes |
| 539 | + |
| 540 | + # TODO Treat commit_hash collision (it can happen between repos) |
| 541 | + with connection.cursor() as cursor: |
| 542 | + cursor.execute(query, params) |
| 543 | + query_rows = dict_fetchall(cursor) |
| 544 | + return query_rows |
427 | 545 |
|
428 | 546 |
|
429 | 547 | def get_hardware_summary_data( |
|
0 commit comments