...
1 package integration
2
3 import (
4 "encoding/json"
5 "fmt"
6 "io"
7 "strings"
8 "time"
9
10 "edge-infra.dev/test/framework"
11 )
12
13 type TestEvent struct {
14 Time *time.Time
15 Action string
16 Package string
17 Test string
18 Elapsed *float64
19 Output string
20 }
21
22 type TestCase struct {
23 State string
24 Output strings.Builder
25 Duration *time.Duration
26 }
27
28 type TestPackage struct {
29 Duration *time.Duration
30 State string
31 TestCases map[string]*TestCase
32 PackageName string
33 }
34
35
36 type TestResultsParser interface {
37 ParseTestResults(logs io.Reader, packageName string) (*TestPackage, error)
38 }
39
40
41 func ReportTestCases(f *framework.Framework, testPackage *TestPackage) {
42 f.Run(testPackage.PackageName, func() {
43 for testname, tc := range testPackage.TestCases {
44
45
46 f.Run(testname, func() {
47 f.Log(tc.Output.String())
48 switch tc.State {
49 case "skip":
50 f.Skip(testname, "skipped")
51 case "fail":
52 f.Fail("Failed")
53 case "pass":
54 default:
55 }
56 })
57 }
58 })
59 }
60
61
62 type JSONTestResultsParser struct{}
63
64
65 func (p JSONTestResultsParser) ParseTestResults(logs io.Reader, packageName string) (*TestPackage, error) {
66 testcases := make(map[string]*TestCase)
67
68
69 testCaseByName := func(name string) *TestCase {
70 if name == "" {
71 return nil
72 }
73 if _, ok := testcases[name]; !ok {
74 testcases[name] = &TestCase{}
75 }
76 return testcases[name]
77 }
78
79 dec := json.NewDecoder(logs)
80
81 var pkgDuration *time.Duration
82 var state string
83 for {
84 var e TestEvent
85 if err := dec.Decode(&e); err == io.EOF {
86 break
87 } else if err != nil {
88 return nil, fmt.Errorf("error decoding test output: %w", err)
89 }
90 switch s := e.Action; s {
91 case "run":
92 if c := testCaseByName(e.Test); c != nil {
93 c.State = s
94 }
95 case "output":
96 if c := testCaseByName(e.Test); c != nil {
97 c.Output.WriteString(e.Output)
98 }
99 case "skip":
100 if c := testCaseByName(e.Test); c != nil {
101 c.Output.WriteString(e.Output)
102 c.State, state = s, s
103 elapsed := time.Duration(*e.Elapsed * float64(time.Second))
104 c.Duration = &elapsed
105 }
106 case "fail", "pass":
107 elapsed := time.Duration(*e.Elapsed * float64(time.Second))
108 if c := testCaseByName(e.Test); c != nil {
109 c.State = s
110 c.Duration = &elapsed
111 } else {
112 state = s
113 pkgDuration = &elapsed
114 }
115 }
116 }
117 testpkg := TestPackage{Duration: pkgDuration, State: state, TestCases: testcases, PackageName: packageName}
118 return &testpkg, nil
119 }
120
View as plain text