-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathvalidate_results.go
More file actions
135 lines (121 loc) · 2.64 KB
/
validate_results.go
File metadata and controls
135 lines (121 loc) · 2.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package main
import (
"encoding/json"
"fmt"
"os"
"reflect"
"gopkg.in/yaml.v2"
)
type ResultsFile []map[string]interface{}
type TestConfigs []map[string]interface{}
func main() {
refPath := "results.json.reference"
genPath := "results.json"
testsPath := "e2e-testconfig.yaml"
ref, err := readResults(refPath)
if err != nil {
fmt.Fprintf(os.Stderr, "Reference file error: %v\n", err)
os.Exit(1)
}
gen, err := readResults(genPath)
if err != nil {
fmt.Fprintf(os.Stderr, "Generated file error: %v\n", err)
os.Exit(1)
}
tests, err := readTests(testsPath)
if err != nil {
fmt.Fprintf(os.Stderr, "Tests file error: %v\n", err)
os.Exit(1)
}
numTests := len(tests)
println("Number of tests in e2e-testconfig.yaml:", numTests)
if len(gen) != numTests {
fmt.Fprintf(os.Stderr, "results.json should contain %d test results, found %d\n", numTests, len(gen))
os.Exit(1)
}
if !similarStructure(ref, gen) {
fmt.Fprintf(os.Stderr, "results.json structure does not match reference\n")
os.Exit(1)
}
fmt.Println("results.json is valid and matches reference structure.")
}
func readResults(path string) (ResultsFile, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, err
}
var results ResultsFile
if err := json.Unmarshal(data, &results); err != nil {
return nil, err
}
return results, nil
}
func readTests(path string) (TestConfigs, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, err
}
var tests TestConfigs
if err := yaml.Unmarshal(data, &tests); err != nil {
return nil, err
}
return tests, nil
}
func similarStructure(a, b ResultsFile) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if !compareTypes(a[i], b[i]) {
return false
}
}
return true
}
func compareTypes(a, b map[string]interface{}) bool {
if len(a) != len(b) {
return false
}
for k, va := range a {
vb, ok := b[k]
if !ok {
return false
}
if !sameType(va, vb) {
return false
}
}
return true
}
func sameType(a, b interface{}) bool {
ta := reflect.TypeOf(a)
tb := reflect.TypeOf(b)
if ta == nil || tb == nil {
return ta == tb
}
if ta.Kind() != tb.Kind() {
return false
}
switch ta.Kind() {
case reflect.Map:
ma, ok1 := a.(map[string]interface{})
mb, ok2 := b.(map[string]interface{})
if !ok1 || !ok2 {
return false
}
return compareTypes(ma, mb)
case reflect.Slice:
sa, ok1 := a.([]interface{})
sb, ok2 := b.([]interface{})
if !ok1 || !ok2 {
return false
}
// Compare first element type if slices are non-empty
if len(sa) > 0 && len(sb) > 0 {
return sameType(sa[0], sb[0])
}
return len(sa) == len(sb)
default:
return ta.Kind() == tb.Kind()
}
}