github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/tools/test_monitor/level3/process_summary3_results.go (about) 1 package main 2 3 import ( 4 "encoding/json" 5 "os" 6 "sort" 7 8 "github.com/onflow/flow-go/tools/test_monitor/common" 9 ) 10 11 // generateLevel3Summary processes a level 2 summary and produces level 3 summary which summarizes: 12 // most failed tests, tests with exceptions, longest running tests. 13 func generateLevel3Summary(level2FilePath string, propertyFileDirectory string) common.Level3Summary { 14 15 config := common.ReadProperties(propertyFileDirectory) 16 17 var level2Summary common.Level2Summary 18 19 level2JsonBytes, err := os.ReadFile(level2FilePath) 20 common.AssertNoError(err, "error reading level 2 json") 21 22 err = json.Unmarshal(level2JsonBytes, &level2Summary) 23 common.AssertNoError(err, "error unmarshalling level 2 test run") 24 25 // there should be at least 1 level 2 test result in the supplied file 26 // if the json format is different in the supplied file, there won't be a marshalling error thrown 27 // this is an indirect way to tell if the json format was wrong (i.e. not a level 2 json format) 28 if len(level2Summary.TestResultsMap) == 0 { 29 panic("invalid summary 2 file - no test results found") 30 } 31 32 // create lists to keep track of 3 main things 33 // 1. tests with exceptions (ordered by most exceptions) 34 // 2. tests with failures (ordered by most failures) 35 // 3. tests with durations > 0 (ordered by longest durations) 36 37 exceptionsTRS := []common.Level2TestResult{} 38 failuresTRS := []common.Level2TestResult{} 39 durationTRS := []common.Level2TestResult{} 40 41 // go through all level 2 test results to figure out grouping for tests with 42 // most failures, exceptions, longest running 43 for _, trs := range level2Summary.TestResultsMap { 44 if trs.Exceptions > 0 { 45 exceptionsTRS = append(exceptionsTRS, *trs) 46 } 47 if trs.Failed > 0 && trs.FailureRate >= config.FailureThresholdPercent { 48 failuresTRS = append(failuresTRS, *trs) 49 } 50 if trs.AverageDuration > 0 && trs.AverageDuration >= config.DurationThresholdSeconds { 51 durationTRS = append(durationTRS, *trs) 52 } 53 } 54 55 // sort no result slice from most no results to least - that's why less function compares in reverse order 56 sort.Slice(exceptionsTRS, func(i, j int) bool { 57 return (exceptionsTRS[i].Exceptions > exceptionsTRS[j].Exceptions) 58 }) 59 60 // sort failures slice from most failures to least - that's why less function compares in reverse order 61 sort.Slice(failuresTRS, func(i, j int) bool { 62 return failuresTRS[i].FailureRate > failuresTRS[j].FailureRate 63 }) 64 65 // sort duration slice from longest duration to shortest - that's why less function compares in reverse order 66 sort.Slice(durationTRS, func(i, j int) bool { 67 return durationTRS[i].AverageDuration > durationTRS[j].AverageDuration 68 }) 69 70 var level3Summary common.Level3Summary 71 level3Summary.Exceptions = exceptionsTRS 72 73 // total # of failed tests that satisfy min failure threshold 74 level3Summary.MostFailuresTotal = len(failuresTRS) 75 76 // check if # of failures exceeded max failures to return 77 if len(failuresTRS) > config.FailuresSliceMax { 78 // truncate slice to return only the first config.FailuresSliceMax failures 79 failuresTRS = failuresTRS[:config.FailuresSliceMax] 80 } 81 level3Summary.MostFailures = failuresTRS 82 83 // total # of long tests that satisfy min duration threshold 84 level3Summary.LongestRunningTotal = len(durationTRS) 85 86 // check if # of durations exceeded max durations to return 87 if len(durationTRS) > config.DurationSliceMax { 88 // truncate slice to return only the first config.DurationSliceMax durations 89 durationTRS = durationTRS[:config.DurationSliceMax] 90 } 91 level3Summary.LongestRunning = durationTRS 92 93 return level3Summary 94 } 95 96 func main() { 97 // need to pass in single argument of where level 1 summary files exist 98 if len(os.Args[1:]) != 2 { 99 panic("wrong number of arguments - expected arguments 1) path of level 2 file 2) directory of property file") 100 } 101 102 level3Summary := generateLevel3Summary(os.Args[1], os.Args[2]) 103 common.SaveToFile("level3-summary.json", level3Summary) 104 }