Skip to content

Commit 51c70de

Browse files
committed
Add cmd to aggregate all test results
1 parent 8fcbb59 commit 51c70de

File tree

5 files changed

+101
-28
lines changed

5 files changed

+101
-28
lines changed

tools/flakeguard/cmd/aggregate.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"log"
6+
7+
"github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard/reports"
8+
"github.com/spf13/cobra"
9+
)
10+
11+
var AggregateAllCmd = &cobra.Command{
12+
Use: "aggregate-all",
13+
Short: "Aggregate all test results and output them to a file",
14+
Run: func(cmd *cobra.Command, args []string) {
15+
resultsFolderPath, _ := cmd.Flags().GetString("results-path")
16+
outputPath, _ := cmd.Flags().GetString("output-json")
17+
18+
// Aggregate all test results
19+
allResults, err := reports.AggregateTestResults(resultsFolderPath)
20+
if err != nil {
21+
log.Fatalf("Error aggregating results: %v", err)
22+
}
23+
24+
// Output all results to JSON file
25+
if outputPath != "" && len(allResults) > 0 {
26+
if err := saveResults(outputPath, allResults); err != nil {
27+
log.Fatalf("Error writing aggregated results to file: %v", err)
28+
}
29+
fmt.Printf("Aggregated test results saved to %s\n", outputPath)
30+
} else {
31+
fmt.Println("No test results found.")
32+
}
33+
},
34+
}
35+
36+
func init() {
37+
AggregateAllCmd.Flags().String("results-path", "testresult/", "Path to the folder containing JSON test result files")
38+
AggregateAllCmd.Flags().String("output-json", "all_tests.json", "Path to output the aggregated test results in JSON format")
39+
}

tools/flakeguard/cmd/aggregate_failed.go

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,44 +10,44 @@ import (
1010
"github.com/spf13/cobra"
1111
)
1212

13-
var AggregateFailedTestsCmd = &cobra.Command{
13+
var AggregateFailedCmd = &cobra.Command{
1414
Use: "aggregate-failed",
15-
Short: "Aggregate test results and output only failed tests based on a threshold",
15+
Short: "Aggregate all test results, then filter and output only failed tests based on a threshold",
1616
Run: func(cmd *cobra.Command, args []string) {
17-
folderPath, _ := cmd.Flags().GetString("folder-path")
17+
resultsFolderPath, _ := cmd.Flags().GetString("results-path")
1818
outputPath, _ := cmd.Flags().GetString("output-json")
1919
threshold, _ := cmd.Flags().GetFloat64("threshold")
2020

21-
// Aggregate and merge results from the specified folder
22-
allResults, err := reports.AggregateTestResults(folderPath)
21+
// Aggregate all test results
22+
allResults, err := reports.AggregateTestResults(resultsFolderPath)
2323
if err != nil {
2424
log.Fatalf("Error aggregating results: %v", err)
2525
}
2626

27-
// Filter failed tests based on threshold
28-
failedTests := reports.FilterFailedTests(allResults, threshold)
29-
30-
// Format PassRatio as a percentage for display
31-
for i := range failedTests {
32-
failedTests[i].PassRatioPercentage = fmt.Sprintf("%.0f%%", failedTests[i].PassRatio*100)
27+
// Filter to only include failed tests based on threshold
28+
var failedResults []reports.TestResult
29+
for _, result := range allResults {
30+
if result.PassRatio < threshold && !result.Skipped {
31+
failedResults = append(failedResults, result)
32+
}
3333
}
3434

35-
// Output failed tests to JSON file
36-
if outputPath != "" && len(failedTests) > 0 {
37-
if err := saveResults(outputPath, failedTests); err != nil {
38-
log.Fatalf("Error writing failed tests to file: %v", err)
35+
// Output failed results to JSON file
36+
if outputPath != "" && len(failedResults) > 0 {
37+
if err := saveResults(outputPath, failedResults); err != nil {
38+
log.Fatalf("Error writing failed results to file: %v", err)
3939
}
40-
fmt.Printf("Aggregated failed test results saved to %s\n", outputPath)
40+
fmt.Printf("Filtered failed test results saved to %s\n", outputPath)
4141
} else {
4242
fmt.Println("No failed tests found based on the specified threshold.")
4343
}
4444
},
4545
}
4646

4747
func init() {
48-
AggregateFailedTestsCmd.Flags().String("folder-path", "testresult/", "Path to the folder containing JSON test result files")
49-
AggregateFailedTestsCmd.Flags().String("output-json", "failed_tests.json", "Path to output the aggregated failed test results in JSON format")
50-
AggregateFailedTestsCmd.Flags().Float64("threshold", 0.8, "Threshold for considering a test as failed")
48+
AggregateFailedCmd.Flags().String("results-path", "testresult/", "Path to the folder containing JSON test result files")
49+
AggregateFailedCmd.Flags().String("output-json", "failed_tests.json", "Path to output the filtered failed test results in JSON format")
50+
AggregateFailedCmd.Flags().Float64("threshold", 0.8, "Threshold for considering a test as failed")
5151
}
5252

5353
// Helper function to save results to JSON file

tools/flakeguard/main.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ func init() {
2828

2929
rootCmd.AddCommand(cmd.FindTestsCmd)
3030
rootCmd.AddCommand(cmd.RunTestsCmd)
31-
rootCmd.AddCommand(cmd.AggregateFailedTestsCmd)
31+
rootCmd.AddCommand(cmd.AggregateAllCmd)
32+
rootCmd.AddCommand(cmd.AggregateFailedCmd)
3233
}
3334

3435
func main() {

tools/flakeguard/reports/reports.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"io"
77
"os"
88
"path/filepath"
9+
"sort"
910
"strings"
1011
)
1112

@@ -53,7 +54,7 @@ func FilterSkippedTests(results []TestResult) []TestResult {
5354
return skippedTests
5455
}
5556

56-
// Helper function to aggregate all JSON test results from a folder
57+
// AggregateTestResults aggregates all JSON test results.
5758
func AggregateTestResults(folderPath string) ([]TestResult, error) {
5859
// Map to hold unique tests based on their TestName and TestPackage
5960
testMap := make(map[string]TestResult)
@@ -83,15 +84,14 @@ func AggregateTestResults(folderPath string) ([]TestResult, error) {
8384
existingResult.Durations = append(existingResult.Durations, result.Durations...)
8485
existingResult.Outputs = append(existingResult.Outputs, result.Outputs...)
8586

86-
// Calculate total successful runs and aggregate pass ratio
87+
// Calculate total successful runs for correct pass ratio calculation
8788
successfulRuns := existingResult.PassRatio*float64(existingResult.Runs) + result.PassRatio*float64(result.Runs)
8889
existingResult.Runs = totalRuns
8990
existingResult.PassRatio = successfulRuns / float64(totalRuns)
9091
existingResult.Skipped = existingResult.Skipped && result.Skipped // Mark as skipped only if all occurrences are skipped
9192

9293
// Update the map with the aggregated result
9394
testMap[key] = existingResult
94-
9595
} else {
9696
// Add new entry to the map
9797
testMap[key] = result
@@ -110,6 +110,12 @@ func AggregateTestResults(folderPath string) ([]TestResult, error) {
110110
result.PassRatioPercentage = fmt.Sprintf("%.0f%%", result.PassRatio*100)
111111
aggregatedResults = append(aggregatedResults, result)
112112
}
113+
114+
// Sort by PassRatio in ascending order
115+
sort.Slice(aggregatedResults, func(i, j int) bool {
116+
return aggregatedResults[i].PassRatio < aggregatedResults[j].PassRatio
117+
})
118+
113119
return aggregatedResults, nil
114120
}
115121

tools/flakeguard/reports/reports_test.go

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import (
44
"bytes"
55
"encoding/json"
66
"fmt"
7-
"io/ioutil"
87
"os"
98
"path/filepath"
9+
"sort"
1010
"strings"
1111
"testing"
1212
)
@@ -115,14 +115,24 @@ func TestPrintTests(t *testing.T) {
115115
}
116116
}
117117

118-
// Helper function to write temporary JSON files for testing
118+
// Sorts TestResult slice by TestName and TestPackage for consistent comparison
119+
func sortTestResults(results []TestResult) {
120+
sort.Slice(results, func(i, j int) bool {
121+
if results[i].TestName == results[j].TestName {
122+
return results[i].TestPackage < results[j].TestPackage
123+
}
124+
return results[i].TestName < results[j].TestName
125+
})
126+
}
127+
128+
// Helper function to write a JSON file for testing
119129
func writeTempJSONFile(t *testing.T, dir string, filename string, data interface{}) string {
120130
filePath := filepath.Join(dir, filename)
121131
fileData, err := json.Marshal(data)
122132
if err != nil {
123133
t.Fatalf("Failed to marshal JSON: %v", err)
124134
}
125-
if err := ioutil.WriteFile(filePath, fileData, 0644); err != nil {
135+
if err := os.WriteFile(filePath, fileData, 0644); err != nil {
126136
t.Fatalf("Failed to write JSON file: %v", err)
127137
}
128138
return filePath
@@ -143,7 +153,7 @@ func TestAggregateTestResults(t *testing.T) {
143153
expectedOutput []TestResult
144154
}{
145155
{
146-
description: "Unique test results, no aggregation",
156+
description: "Unique test results without aggregation",
147157
inputFiles: []interface{}{
148158
[]TestResult{
149159
{
@@ -154,6 +164,7 @@ func TestAggregateTestResults(t *testing.T) {
154164
Skipped: false,
155165
Runs: 2,
156166
Durations: []float64{0.01, 0.02},
167+
Outputs: []string{"Output1", "Output2"},
157168
},
158169
},
159170
[]TestResult{
@@ -165,6 +176,7 @@ func TestAggregateTestResults(t *testing.T) {
165176
Skipped: false,
166177
Runs: 4,
167178
Durations: []float64{0.05, 0.05, 0.05, 0.05},
179+
Outputs: []string{"Output3", "Output4", "Output5", "Output6"},
168180
},
169181
},
170182
},
@@ -177,6 +189,7 @@ func TestAggregateTestResults(t *testing.T) {
177189
Skipped: false,
178190
Runs: 2,
179191
Durations: []float64{0.01, 0.02},
192+
Outputs: []string{"Output1", "Output2"},
180193
},
181194
{
182195
TestName: "TestB",
@@ -186,11 +199,12 @@ func TestAggregateTestResults(t *testing.T) {
186199
Skipped: false,
187200
Runs: 4,
188201
Durations: []float64{0.05, 0.05, 0.05, 0.05},
202+
Outputs: []string{"Output3", "Output4", "Output5", "Output6"},
189203
},
190204
},
191205
},
192206
{
193-
description: "Duplicate test results, aggregation of PassRatio and Durations",
207+
description: "Duplicate test results with aggregation",
194208
inputFiles: []interface{}{
195209
[]TestResult{
196210
{
@@ -201,6 +215,7 @@ func TestAggregateTestResults(t *testing.T) {
201215
Skipped: false,
202216
Runs: 2,
203217
Durations: []float64{0.1, 0.1},
218+
Outputs: []string{"Output7", "Output8"},
204219
},
205220
},
206221
[]TestResult{
@@ -212,6 +227,7 @@ func TestAggregateTestResults(t *testing.T) {
212227
Skipped: false,
213228
Runs: 2,
214229
Durations: []float64{0.2, 0.2},
230+
Outputs: []string{"Output9", "Output10"},
215231
},
216232
},
217233
},
@@ -224,6 +240,7 @@ func TestAggregateTestResults(t *testing.T) {
224240
Skipped: false,
225241
Runs: 4,
226242
Durations: []float64{0.1, 0.1, 0.2, 0.2},
243+
Outputs: []string{"Output7", "Output8", "Output9", "Output10"},
227244
},
228245
},
229246
},
@@ -239,6 +256,7 @@ func TestAggregateTestResults(t *testing.T) {
239256
Skipped: true,
240257
Runs: 3,
241258
Durations: []float64{0.1, 0.2, 0.1},
259+
Outputs: []string{"Output11", "Output12", "Output13"},
242260
},
243261
},
244262
[]TestResult{
@@ -250,6 +268,7 @@ func TestAggregateTestResults(t *testing.T) {
250268
Skipped: true,
251269
Runs: 2,
252270
Durations: []float64{0.15, 0.15},
271+
Outputs: []string{"Output14", "Output15"},
253272
},
254273
},
255274
},
@@ -262,6 +281,7 @@ func TestAggregateTestResults(t *testing.T) {
262281
Skipped: true, // Should remain true as all runs are skipped
263282
Runs: 5,
264283
Durations: []float64{0.1, 0.2, 0.1, 0.15, 0.15},
284+
Outputs: []string{"Output11", "Output12", "Output13", "Output14", "Output15"},
265285
},
266286
},
267287
},
@@ -280,6 +300,10 @@ func TestAggregateTestResults(t *testing.T) {
280300
t.Fatalf("AggregateTestResults failed: %v", err)
281301
}
282302

303+
// Sort both result and expectedOutput for consistent comparison
304+
sortTestResults(result)
305+
sortTestResults(tc.expectedOutput)
306+
283307
// Compare the result with the expected output
284308
if len(result) != len(tc.expectedOutput) {
285309
t.Fatalf("Expected %d results, got %d", len(tc.expectedOutput), len(result))
@@ -299,6 +323,9 @@ func TestAggregateTestResults(t *testing.T) {
299323
if len(got.Durations) != len(expected.Durations) {
300324
t.Errorf("Result %d - expected %d durations, got %d", i, len(expected.Durations), len(got.Durations))
301325
}
326+
if len(got.Outputs) != len(expected.Outputs) {
327+
t.Errorf("Result %d - expected %d outputs, got %d", i, len(expected.Outputs), len(got.Outputs))
328+
}
302329
}
303330
})
304331
}

0 commit comments

Comments
 (0)