66 "fmt"
77 "os"
88 "os/exec"
9+ "path/filepath"
10+ "strings"
911 "time"
1012
1113 "github.com/briandowns/spinner"
@@ -21,6 +23,7 @@ import (
2123const (
2224 FlakyTestsExitCode = 1
2325 ErrorExitCode = 2
26+ RawOutputDir = "./flakeguard_raw_output"
2427)
2528
2629type runConfig struct {
@@ -252,27 +255,54 @@ func initializeRunner(cfg *runConfig) *runner.Runner {
252255 cfg .SelectTests ,
253256 cfg .IgnoreParentFailuresOnSubtests ,
254257 cfg .OmitOutputsOnSuccess ,
258+ RawOutputDir ,
255259 nil , // exec
256260 nil , // parser
257261 )
258262}
259263
260264// generateMainReport creates the initial test report from the main run results.
261265func generateMainReport (results []reports.TestResult , cfg * runConfig , goProject string ) (* reports.TestReport , error ) {
266+ // Get the JSON output paths from the raw output directory
267+ jsonOutputPaths , err := getJSONOutputPaths (RawOutputDir )
268+ if err != nil {
269+ log .Warn ().Err (err ).Msg ("Failed to get JSON output paths" )
270+ }
271+
262272 reportVal , err := reports .NewTestReport (results ,
263273 reports .WithGoProject (goProject ),
264274 reports .WithCodeOwnersPath (cfg .CodeownersPath ),
265275 reports .WithMaxPassRatio (cfg .MinPassRatio ),
266276 reports .WithGoRaceDetection (cfg .UseRace ),
267277 reports .WithExcludedTests (cfg .SkipTests ),
268278 reports .WithSelectedTests (cfg .SelectTests ),
279+ reports .WithJSONOutputPaths (jsonOutputPaths ),
269280 )
270281 if err != nil {
271282 return nil , err
272283 }
273284 return & reportVal , nil
274285}
275286
287+ // getJSONOutputPaths returns a list of JSON output files from the given directory
288+ func getJSONOutputPaths (dir string ) ([]string , error ) {
289+ files , err := os .ReadDir (dir )
290+ if err != nil {
291+ if os .IsNotExist (err ) {
292+ return nil , nil
293+ }
294+ return nil , fmt .Errorf ("failed to read directory %s: %w" , dir , err )
295+ }
296+
297+ var paths []string
298+ for _ , file := range files {
299+ if ! file .IsDir () && strings .HasSuffix (file .Name (), ".json" ) {
300+ paths = append (paths , filepath .Join (dir , file .Name ()))
301+ }
302+ }
303+ return paths , nil
304+ }
305+
276306// handleReruns manages the process of rerunning failed tests and reporting results.
277307func handleReruns (exitHandler * summaryAndExit , testRunner * runner.Runner , mainReport * reports.TestReport , cfg * runConfig , goProject string ) {
278308 failedTests := reports .FilterTests (mainReport .Results , func (tr reports.TestResult ) bool {
@@ -384,6 +414,20 @@ func handleNoReruns(exitHandler *summaryAndExit, mainReport *reports.TestReport,
384414 reports .RenderTestReport (& exitHandler .buffer , * mainReport , false , false )
385415
386416 if len (flakyTests ) > 0 {
417+ // Create a new report with only flaky tests to get their gotestsum output
418+ flakyReport , err := reports .NewTestReport (flakyTests ,
419+ reports .WithJSONOutputPaths (mainReport .JSONOutputPaths ),
420+ )
421+ if err != nil {
422+ log .Error ().Err (err ).Msg ("Error creating flaky tests report" )
423+ } else {
424+ fmt .Fprint (& exitHandler .buffer , "\n Flaky Test Logs:\n \n " )
425+ err := flakyReport .PrintGotestsumOutput (& exitHandler .buffer , "pkgname" )
426+ if err != nil {
427+ log .Error ().Err (err ).Msg ("Error printing gotestsum output for flaky tests" )
428+ }
429+ }
430+
387431 exitHandler .logMsgAndExit (zerolog .InfoLevel , "Found flaky tests." , FlakyTestsExitCode , map [string ]interface {}{
388432 "flaky_count" : len (flakyTests ),
389433 "stability_threshold" : fmt .Sprintf ("%.0f%%" , cfg .MinPassRatio * 100 ),
0 commit comments