33import sqlite3
44import logging
55import re
6+ import json
7+ import os
68
79import git_utils
810
@@ -121,9 +123,12 @@ def _try_explain_failing_at_head(
121123) -> FailureExplanation | None :
122124 query = (
123125 "SELECT failure_message FROM failures "
124- "WHERE source_type='postcommit' AND platform=?"
126+ "WHERE source_type='postcommit' AND platform=? AND test_file=?"
127+ )
128+ query_params = (
129+ platform ,
130+ test_failure ["name" ],
125131 )
126- query_params = (platform ,)
127132 if base_commit_index :
128133 min_commit_index = (
129134 base_commit_index - EXPLAINED_HEAD_MAX_COMMIT_INDEX_DIFFERENCE
@@ -175,8 +180,11 @@ def _try_explain_flaky_failure(
175180 FailureExplanation object explaining the test failure.
176181 """
177182 test_name_matches = db_connection .execute (
178- "SELECT failure_message, commit_index FROM failures WHERE source_type='postcommit' AND platform=?" ,
179- (platform ,),
183+ "SELECT failure_message, commit_index FROM failures WHERE source_type='postcommit' AND platform=? AND test_file=?" ,
184+ (
185+ platform ,
186+ test_failure ["name" ],
187+ ),
180188 ).fetchall ()
181189 commit_indices = []
182190 for failure_message , commit_index in test_name_matches :
@@ -194,17 +202,50 @@ def _try_explain_flaky_failure(
194202 return None
195203
196204
205+ def _log_explanation_request (
206+ explanation_request : TestExplanationRequest ,
207+ base_commit_index : int ,
208+ db_connection : sqlite3 .Connection ,
209+ explanations : list [FailureExplanation ],
210+ debug_folder : str ,
211+ ):
212+ explanation_log = {
213+ "request" : explanation_request ,
214+ "explanations" : explanations ,
215+ "base_commit_index" : base_commit_index ,
216+ "relevant_previous_failures" : [],
217+ }
218+ for failure in explanation_request ["failures" ]:
219+ test_name_matches = db_connection .execute (
220+ "SELECT failure_message, commit_index, test_file "
221+ "FROM failures WHERE source_type='postcommit' AND platform=? AND test_file=?" ,
222+ (
223+ explanation_request ["platform" ],
224+ failure ["name" ],
225+ ),
226+ ).fetchall ()
227+ explanation_log ["relevant_previous_failures" ].extend (test_name_matches )
228+ with open (
229+ os .path .join (
230+ debug_folder , str (base_commit_index ) + "-" + str (int (time .time ())) + ".txt"
231+ ),
232+ "w" ,
233+ ) as output_file :
234+ json .dump (explanation_log , output_file )
235+
236+
197237def explain_failures (
198238 explanation_request : TestExplanationRequest ,
199239 repository_path : str ,
200240 db_connection : sqlite3 .Connection ,
241+ debug_folder : str | None = None ,
201242) -> list [FailureExplanation ]:
202243 _canonicalize_failures (explanation_request ["failures" ])
203244 explanations = []
245+ commit_index = git_utils .get_commit_index (
246+ explanation_request ["base_commit_sha" ], repository_path , db_connection
247+ )
204248 for test_failure in explanation_request ["failures" ]:
205- commit_index = git_utils .get_commit_index (
206- explanation_request ["base_commit_sha" ], repository_path , db_connection
207- )
208249 # We want to try and explain flaky failures first. Otherwise we might
209250 # explain a flaky failure as a failure at head if there is a recent
210251 # failure in the last couple of commits.
@@ -229,6 +270,10 @@ def explain_failures(
229270 explanations .append (
230271 {"name" : test_failure ["name" ], "explained" : False , "reason" : None }
231272 )
273+ if debug_folder :
274+ _log_explanation_request (
275+ explanation_request , commit_index , db_connection , explanations , debug_folder
276+ )
232277 return explanations
233278
234279
0 commit comments