Skip to content

Commit 2256387

Browse files
committed
UPSTREAM: <carry>: Ensure balanced brackets in annotated test names
We recently started marking tests with apigroups, and in one case we missed the closing bracket on the annotation resulting in the test being erroneously skipped. This adds a check in the annotation generation, and errors when brackets are unbalanced. ``` Example: $ ./hack/verify-generated.sh FAILURE after 12.870s: hack/verify-generated.sh:13: executing '/home/stbenjam/go/src/github.com/openshift/origin/hack/update-generated.sh' expecting success: the command returned the wrong error code Standard output from the command: Nov 4 14:11:25.026: INFO: Enabling in-tree volume drivers Nov 4 14:11:25.026: INFO: Warning: deprecated ENABLE_STORAGE_GCE_PD_DRIVER used. This will be removed in a future release. Use --enabled-volume-drivers=gcepd instead Nov 4 14:11:25.026: INFO: Enabled gcepd and windows-gcepd in-tree volume drivers Standard error from the command: failed: unbalanced brackets in test name: [Top Level] [sig-scheduling][Early] The openshift-console console pods [apigroup:console.openshift.io should be scheduled on different nodes ^ ```
1 parent 9f4dd65 commit 2256387

File tree

2 files changed

+102
-3
lines changed

2 files changed

+102
-3
lines changed

openshift-hack/e2e/annotate/annotate.go

+47-3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ var reHasSig = regexp.MustCompile(`\[sig-[\w-]+\]`)
1717

1818
// Run generates tests annotations for the targeted package.
1919
func Run() {
20+
var errors []string
21+
2022
if len(os.Args) != 2 && len(os.Args) != 3 {
2123
fmt.Fprintf(os.Stderr, "error: requires exactly one argument\n")
2224
os.Exit(1)
@@ -26,6 +28,9 @@ func Run() {
2628
generator := newGenerator()
2729
ginkgo.GetSuite().BuildTree()
2830
ginkgo.GetSuite().WalkTests(generator.generateRename)
31+
if len(generator.errors) > 0 {
32+
errors = append(errors, generator.errors...)
33+
}
2934

3035
renamer := newRenamerFromGenerated(generator.output)
3136
// generated file has a map[string]string in the following format:
@@ -49,7 +54,6 @@ func Run() {
4954
// Upstream sigs map to teams (if you have representation on that sig, you
5055
// own those tests in origin)
5156
// Downstream sigs: sig-imageregistry, sig-builds, sig-devex
52-
var errors []string
5357
for from, to := range generator.output {
5458
if !reHasSig.MatchString(from) && !reHasSig.MatchString(to) {
5559
errors = append(errors, fmt.Sprintf("all tests must define a [sig-XXXX] tag or have a rule %q", from))
@@ -131,8 +135,7 @@ func newGenerator() *ginkgoTestRenamer {
131135
stringMatches: stringMatches,
132136
matches: matches,
133137
excludedTestsFilter: excludedTestsFilter,
134-
135-
output: make(map[string]string),
138+
output: make(map[string]string),
136139
}
137140
}
138141

@@ -158,6 +161,8 @@ type ginkgoTestRenamer struct {
158161
output map[string]string
159162
// map of unmatched test names
160163
missing map[string]struct{}
164+
// a list of errors to display
165+
errors []string
161166
}
162167

163168
func (r *ginkgoTestRenamer) updateNodeText(name string, node types.TestSpec) {
@@ -226,6 +231,9 @@ func (r *ginkgoTestRenamer) generateRename(name string, node types.TestSpec) {
226231
newLabels += " [Suite:k8s]"
227232
}
228233

234+
if err := checkBalancedBrackets(newName); err != nil {
235+
r.errors = append(r.errors, err.Error())
236+
}
229237
r.output[name] = newLabels
230238
}
231239

@@ -239,3 +247,39 @@ func (r *ginkgoTestRenamer) generateRename(name string, node types.TestSpec) {
239247
func isGoModulePath(packagePath, module, modulePath string) bool {
240248
return regexp.MustCompile(fmt.Sprintf(`\b%s(@[^/]*|)/%s\b`, regexp.QuoteMeta(module), regexp.QuoteMeta(modulePath))).MatchString(packagePath)
241249
}
250+
251+
// checkBalancedBrackets ensures that square brackets are balanced in generated test
252+
// names. If they are not, it returns an error with the name of the test and a guess
253+
// where the unmatched bracket(s) are.
254+
func checkBalancedBrackets(testName string) error {
255+
stack := make([]int, 0, len(testName))
256+
for idx, c := range testName {
257+
if c == '[' {
258+
stack = append(stack, idx)
259+
} else if c == ']' {
260+
// case when we start off with a ]
261+
if len(stack) == 0 {
262+
stack = append(stack, idx)
263+
} else {
264+
stack = stack[:len(stack)-1]
265+
}
266+
}
267+
}
268+
269+
if len(stack) > 0 {
270+
msg := testName + "\n"
271+
outerLoop:
272+
for i := 0; i < len(testName); i++ {
273+
for _, loc := range stack {
274+
if i == loc {
275+
msg += "^"
276+
continue outerLoop
277+
}
278+
}
279+
msg += " "
280+
}
281+
return fmt.Errorf("unbalanced brackets in test name:\n%s\n", msg)
282+
}
283+
284+
return nil
285+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package annotate
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"testing"
7+
)
8+
9+
func Test_checkBalancedBrackets(t *testing.T) {
10+
tests := []struct {
11+
testCase string
12+
testName string
13+
wantErr bool
14+
}{
15+
{
16+
testCase: "balanced brackets succeeds",
17+
testName: "[sig-storage] Test that storage [apigroup:storage.openshift.io] actually works [Driver:azure][Serial][Late]",
18+
wantErr: false,
19+
},
20+
{
21+
testCase: "unbalanced brackets errors",
22+
testName: "[sig-storage] Test that storage [apigroup:storage.openshift.io actually works [Driver:azure][Serial][Late]",
23+
wantErr: true,
24+
},
25+
{
26+
testCase: "start with close bracket errors",
27+
testName: "[sig-storage] test with a random bracket ]",
28+
wantErr: true,
29+
},
30+
{
31+
testCase: "multiple unbalanced brackets errors",
32+
testName: "[sig-storage Test that storage [apigroup:storage.openshift.io actually works [Driver:azure]",
33+
wantErr: true,
34+
},
35+
{
36+
testCase: "balanced deeply nested brackets succeeds",
37+
testName: "[[[[[[some weird test with deeply nested brackets]]]]]]",
38+
wantErr: false,
39+
},
40+
{
41+
testCase: "unbalanced deeply nested brackets errors",
42+
testName: "[[[[[[some weird test with deeply nested brackets]]]]]",
43+
wantErr: true,
44+
},
45+
}
46+
for _, tt := range tests {
47+
t.Run(tt.testCase, func(t *testing.T) {
48+
if err := checkBalancedBrackets(tt.testName); (err != nil) != tt.wantErr {
49+
t.Errorf("checkBalancedBrackets() error = %v, wantErr %v", err, tt.wantErr)
50+
} else if err != nil {
51+
fmt.Fprintf(os.Stderr, "checkBalancedBrackets() success, found expected err = \n%s\n", err.Error())
52+
}
53+
})
54+
}
55+
}

0 commit comments

Comments
 (0)