22from typing import Sequence
33
44
5- from django .db import connection
5+ from django .db import connections
66from kernelCI_app .helpers .logger import out
77from kernelCI_app .models import (
88 Checkouts ,
99 PendingTest ,
10- StatusChoices ,
11- SimplifiedStatusChoices ,
10+ PendingBuilds ,
1211 Tests ,
12+ Builds ,
13+ simplify_status ,
1314)
1415from kernelCI_app .utils import is_boot
15- from typing import Optional
1616
1717
18- def simplify_status (status : Optional [StatusChoices ]) -> SimplifiedStatusChoices :
19- if status == StatusChoices .PASS :
20- return SimplifiedStatusChoices .PASS
21- elif status == StatusChoices .FAIL :
22- return SimplifiedStatusChoices .FAIL
23- else :
24- return SimplifiedStatusChoices .INCONCLUSIVE
25-
26-
27- def convert_test (t : Tests ) -> PendingTest :
18+ def _convert_test (t : Tests ) -> PendingTest :
2819 return PendingTest (
2920 test_id = t .id ,
3021 origin = t .origin ,
@@ -36,14 +27,78 @@ def convert_test(t: Tests) -> PendingTest:
3627 )
3728
3829
30+ def _update_tree_listing (* , checkouts_instances : Sequence [Checkouts ]):
31+ """
32+ Whenever a checkout updates the latest_checkout table,
33+ we update the tree_listing table, zeroing the counts"""
34+
35+ t0 = time .time ()
36+ checkout_values = [
37+ (
38+ checkout .id ,
39+ checkout .origin ,
40+ checkout .tree_name ,
41+ checkout .git_repository_url ,
42+ checkout .git_repository_branch ,
43+ checkout .git_commit_hash ,
44+ checkout .git_commit_name ,
45+ checkout .git_commit_tags ,
46+ checkout .start_time ,
47+ checkout .origin_builds_finish_time ,
48+ checkout .origin_tests_finish_time ,
49+ )
50+ for checkout in checkouts_instances
51+ ]
52+
53+ with connections ["default" ].cursor () as cursor :
54+ # Set values as 0 when inserting a new tree and update as 0 when tree already exists
55+ cursor .executemany (
56+ """
57+ INSERT INTO tree_listing (
58+ checkout_id, origin, tree_name,
59+ git_repository_url, git_repository_branch, git_commit_hash,
60+ git_commit_name, git_commit_tags, start_time,
61+ origin_builds_finish_time, origin_tests_finish_time,
62+ pass_builds, fail_builds, inconclusive_builds,
63+ pass_boots, fail_boots, inconclusive_boots,
64+ pass_tests, fail_tests, inconclusive_tests
65+ )
66+ VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, 0, 0, 0, 0, 0, 0, 0, 0, 0)
67+ ON CONFLICT (origin, tree_name, git_repository_url, git_repository_branch)
68+ DO UPDATE SET
69+ checkout_id = EXCLUDED.checkout_id,
70+ git_commit_hash = EXCLUDED.git_commit_hash,
71+ git_commit_name = EXCLUDED.git_commit_name,
72+ git_commit_tags = EXCLUDED.git_commit_tags,
73+ start_time = EXCLUDED.start_time,
74+ origin_builds_finish_time = EXCLUDED.origin_builds_finish_time,
75+ origin_tests_finish_time = EXCLUDED.origin_tests_finish_time,
76+ pass_builds = 0,
77+ fail_builds = 0,
78+ inconclusive_builds = 0,
79+ pass_boots = 0,
80+ fail_boots = 0,
81+ inconclusive_boots = 0,
82+ pass_tests = 0,
83+ fail_tests = 0,
84+ inconclusive_tests = 0
85+ WHERE tree_listing.start_time < EXCLUDED.start_time
86+ """ ,
87+ checkout_values ,
88+ )
89+ out (
90+ f"upserted { len (checkouts_instances )} tree_listing trees in { time .time () - t0 :.3f} s"
91+ )
92+
93+
3994def aggregate_checkouts (checkouts_instances : Sequence [Checkouts ]) -> None :
4095 """
4196 Insert checkouts on latest_checkouts table,
4297 maintaining only the latest ones for each
4398 (origin, tree_name, git_repository_url, git_repository_branch) combination
4499 """
45100 t0 = time .time ()
46- values = [
101+ checkout_values = [
47102 (
48103 checkout .id ,
49104 checkout .origin ,
@@ -55,7 +110,7 @@ def aggregate_checkouts(checkouts_instances: Sequence[Checkouts]) -> None:
55110 for checkout in checkouts_instances
56111 ]
57112
58- with connection .cursor () as cursor :
113+ with connections [ "default" ] .cursor () as cursor :
59114 cursor .executemany (
60115 """
61116 INSERT INTO latest_checkout (
@@ -69,7 +124,7 @@ def aggregate_checkouts(checkouts_instances: Sequence[Checkouts]) -> None:
69124 checkout_id = EXCLUDED.checkout_id
70125 WHERE latest_checkout.start_time < EXCLUDED.start_time
71126 """ ,
72- values ,
127+ checkout_values ,
73128 )
74129 out (f"inserted { len (checkouts_instances )} checkouts in { time .time () - t0 :.3f} s" )
75130
@@ -80,7 +135,7 @@ def aggregate_tests(
80135 """Insert tests data on pending_tests table to be processed later"""
81136 t0 = time .time ()
82137 pending_tests = (
83- convert_test (test )
138+ _convert_test (test )
84139 for test in tests_instances
85140 if test .environment_misc and test .environment_misc .get ("platform" ) is not None
86141 )
@@ -95,9 +150,29 @@ def aggregate_tests(
95150 )
96151
97152
98- def aggregate_checkouts_and_tests (
153+ def aggregate_builds (
154+ build_instances : Sequence [Builds ],
155+ ) -> None :
156+ """Insert builds data on pending_builds table to be processed later"""
157+ t0 = time .time ()
158+ pending_builds = (PendingBuilds .from_builds (build ) for build in build_instances )
159+
160+ if pending_builds :
161+ pending_builds_inserted = PendingBuilds .objects .bulk_create (
162+ pending_builds ,
163+ ignore_conflicts = True ,
164+ )
165+ out (
166+ f"bulk_create pending_builds: n={ len (pending_builds_inserted )} in { time .time () - t0 :.3f} s"
167+ )
168+
169+
170+ def aggregate_checkouts_and_pendings (
99171 checkouts_instances : Sequence [Checkouts ],
100172 tests_instances : Sequence [Tests ],
173+ build_instances : Sequence [Builds ],
101174) -> None :
102175 aggregate_checkouts (checkouts_instances )
176+ _update_tree_listing (checkouts_instances = checkouts_instances )
103177 aggregate_tests (tests_instances )
178+ aggregate_builds (build_instances )
0 commit comments