Skip to content

Commit ed88341

Browse files
authored
fix: out of range error + use local variables (#4)
1 parent 377e5cb commit ed88341

File tree

2 files changed

+101
-55
lines changed

2 files changed

+101
-55
lines changed

main.go

+26-54
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,22 @@ import (
1414
"unsafe"
1515
)
1616

17-
var bucketIndex *int
18-
var bucketCount *int
19-
var directoriesToExclude *string
20-
var packagesToExclude *string
21-
22-
var directoriesToExcludeList []string
23-
var packagesToExcludeList []string
24-
2517
// Buckets must be called to get the test bucket feature working.
2618
// It will modify the tests present in the testing.M struct.
2719
func Buckets(m *testing.M) {
20+
var bucketIndex int
21+
var bucketCount int
22+
23+
var directoriesToExclude []string
24+
var packagesToExclude []string
25+
2826
if v := os.Getenv("BUCKET"); v != "" {
2927
//nolint: gomnd // use 64 bits for parsing
3028
n, err := strconv.ParseInt(v, 0, 64)
3129
if err != nil {
3230
panic(fmt.Sprintf("unable to parse BUCKET %s: %v", v, err))
3331
}
34-
i := int(n)
35-
bucketIndex = &i
32+
bucketIndex = int(n)
3633
}
3734

3835
if v := os.Getenv("TOTAL_BUCKETS"); v != "" {
@@ -41,59 +38,33 @@ func Buckets(m *testing.M) {
4138
if err != nil {
4239
panic(fmt.Sprintf("unable to parse BUCKET_COUNT %s: %v", v, err))
4340
}
44-
i := int(n)
45-
bucketCount = &i
41+
bucketCount = int(n)
4642
}
4743

4844
if v := os.Getenv("EXCLUDE_DIRECTORIES"); v != "" {
49-
directoriesToExclude = &v
50-
}
51-
52-
if v := os.Getenv("EXCLUDE_PACKAGES"); v != "" {
53-
packagesToExclude = &v
54-
}
55-
56-
if directoriesToExclude != nil {
57-
directoriesToExcludeList = strings.FieldsFunc(*directoriesToExclude, func(r rune) bool {
45+
directoriesToExclude = strings.FieldsFunc(v, func(r rune) bool {
5846
return r == ',' || r == ';'
5947
})
60-
for i := range directoriesToExcludeList {
61-
directoriesToExcludeList[i] = filepath.ToSlash(directoriesToExcludeList[i])
48+
for i := range directoriesToExclude {
49+
directoriesToExclude[i] = filepath.ToSlash(directoriesToExclude[i])
6250
}
6351
}
64-
if packagesToExclude != nil {
65-
packagesToExcludeList = strings.FieldsFunc(*packagesToExclude, func(r rune) bool {
52+
53+
if v := os.Getenv("EXCLUDE_PACKAGES"); v != "" {
54+
packagesToExclude = strings.FieldsFunc(v, func(r rune) bool {
6655
return r == ',' || r == ';'
6756
})
6857
}
6958

70-
if !isBucketFeatureEnabled() && !isDirectoriesToExcludeEnabled() && !isPackagesToExcludeEnabled() {
59+
if (bucketCount == 0 || bucketIndex >= bucketCount) && (len(directoriesToExclude) == 0 && len(packagesToExclude) == 0) {
7160
return
7261
}
7362

7463
v := reflect.ValueOf(m).Elem()
7564
testsField := v.FieldByName("tests")
7665
//nolint: gosec // allow the usage of unsafe so we can get the test slice.
7766
ptr := unsafe.Pointer(testsField.UnsafeAddr())
78-
filterTests((*[]testing.InternalTest)(ptr))
79-
}
80-
func isBucketFeatureEnabled() bool {
81-
if bucketCount == nil || bucketIndex == nil {
82-
return false
83-
}
84-
85-
if *bucketCount <= 0 || *bucketIndex < 0 || *bucketIndex >= *bucketCount {
86-
return false
87-
}
88-
return true
89-
}
90-
91-
func isDirectoriesToExcludeEnabled() bool {
92-
return len(directoriesToExcludeList) > 0
93-
}
94-
95-
func isPackagesToExcludeEnabled() bool {
96-
return len(packagesToExcludeList) > 0
67+
filterTests((*[]testing.InternalTest)(ptr), bucketIndex, bucketCount, directoriesToExclude, packagesToExclude)
9768
}
9869

9970
func getSourceFile(f func(*testing.T)) string {
@@ -153,39 +124,40 @@ dirLoop:
153124
return false
154125
}
155126

156-
func filterTests(tests *[]testing.InternalTest) {
157-
if isDirectoriesToExcludeEnabled() {
127+
func filterTests(tests *[]testing.InternalTest, bucketIndex, bucketCount int, directoriesToExclude, packagesToExclude []string) {
128+
if len(directoriesToExclude) > 0 {
158129
for i := len(*tests) - 1; i >= 0; i-- {
159130
file := getSourceFile((*tests)[i].F)
160131
if file == "" {
161132
fmt.Printf("unable to find source of %s\n", (*tests)[i].Name)
162133
continue
163134
}
164135

165-
if isFileInDir(filepath.ToSlash(file), directoriesToExcludeList...) {
136+
if isFileInDir(filepath.ToSlash(file), directoriesToExclude...) {
166137
*tests = append((*tests)[:i], (*tests)[i+1:]...)
167138
}
168139
}
169140
}
170-
if isPackagesToExcludeEnabled() {
141+
if len(packagesToExclude) > 0 {
171142
for i := len(*tests) - 1; i >= 0; i-- {
172143
pkg := getPackageName((*tests)[i].F)
173144
if pkg == "" {
174145
fmt.Printf("unable to find package of %s\n", (*tests)[i].Name)
175146
continue
176147
}
177-
if isFileInDir(pkg, packagesToExcludeList...) {
148+
if isFileInDir(pkg, packagesToExclude...) {
178149
*tests = append((*tests)[:i], (*tests)[i+1:]...)
179150
}
180151
}
181152
}
182-
if isBucketFeatureEnabled() {
183-
perBucket := int(math.Ceil(float64(len(*tests)) / float64(*bucketCount)))
184153

185-
from := *bucketIndex * perBucket
154+
if bucketCount > 0 && bucketIndex >= 0 && bucketIndex < bucketCount {
155+
perBucket := int(math.Ceil(float64(len(*tests)) / float64(bucketCount)))
156+
157+
from := bucketIndex * perBucket
186158
to := from + perBucket
187159

188-
if to > len(*tests) {
160+
if to > len(*tests)-1 {
189161
to = len(*tests)
190162
}
191163

main_test.go

+75-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ func subTest(t *testing.T, env []string, coverProfile, packageName string, testS
106106
cmd.Env = append(os.Environ(), env...)
107107

108108
if err := cmd.Run(); err != nil {
109-
t.Fatal(err)
109+
t.Fatal(err, buf.String())
110110
}
111111

112112
type test struct {
@@ -163,3 +163,77 @@ func subTest(t *testing.T, env []string, coverProfile, packageName string, testS
163163
}
164164
}
165165
}
166+
167+
func Test_filterTestsBuckets(t *testing.T) {
168+
testCases := []struct {
169+
name string
170+
testCount int
171+
bucketCount int
172+
buckets []int
173+
}{
174+
{
175+
"1/1",
176+
1,
177+
1,
178+
[]int{1},
179+
},
180+
{
181+
"1/2",
182+
1,
183+
2,
184+
[]int{1, 0},
185+
},
186+
{
187+
"3/2",
188+
3,
189+
2,
190+
[]int{2, 1},
191+
},
192+
{
193+
"4/2",
194+
4,
195+
2,
196+
[]int{2, 2},
197+
},
198+
{
199+
"5/2",
200+
5,
201+
2,
202+
[]int{3, 2},
203+
},
204+
{
205+
"11/3",
206+
11,
207+
3,
208+
[]int{4, 4, 3},
209+
},
210+
{
211+
"12/3",
212+
12,
213+
3,
214+
[]int{4, 4, 4},
215+
},
216+
{
217+
"13/3",
218+
13,
219+
3,
220+
[]int{5, 5, 3},
221+
},
222+
}
223+
for _, tt := range testCases {
224+
tt := tt
225+
t.Run(tt.name, func(t *testing.T) {
226+
for i := 0; i < tt.bucketCount; i++ {
227+
tests := make([]testing.InternalTest, tt.testCount)
228+
for j := 0; j < tt.testCount; j++ {
229+
tests[j].Name = fmt.Sprintf("Test%d", j)
230+
}
231+
filterTests(&tests, i, tt.bucketCount, nil, nil)
232+
233+
if tt.buckets[i] != len(tests) {
234+
t.Fatalf("expected %d tests in bucket %d but got %d", tt.buckets[i], i, len(tests))
235+
}
236+
}
237+
})
238+
}
239+
}

0 commit comments

Comments
 (0)