Skip to content

Commit 1b62775

Browse files
authored
Merge pull request #56 from linuxkit/fix-run-sharding
simplify shard algorithm to fix
2 parents 2262504 + 1424b7f commit 1b62775

File tree

7 files changed

+43
-43
lines changed

7 files changed

+43
-43
lines changed

cmd/list.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func init() {
3434
flags := listCmd.Flags()
3535
// shardPattern is 1-based (1/10, 3/10, 10/10) rather than normal computer 0-based (0/9, 2/9, 9/9), because it is easier for
3636
// humans to understand when calling the CLI.
37-
flags.StringVarP(&shardPattern, "shard", "s", "", "which shard to run, in form of 'N/M' where N is the shard number and M is the total number of shards, smallest shard number is 1")
37+
flags.StringVarP(&shardPattern, "shard", "s", "", "which shard to run, in form of 'N/M' where N is the shard number and M is the total number of shards, smallest shard number is 1. Shards are applied only to tests that would run, not those that would be skipped.")
3838
RootCmd.AddCommand(listCmd)
3939
}
4040

cmd/run.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func init() {
9393
flags.BoolVarP(&parallel, "parallel", "p", false, "Run multiple tests in parallel")
9494
// shardPattern is 1-based (1/10, 3/10, 10/10) rather than normal computer 0-based (0/9, 2/9, 9/9), because it is easier for
9595
// humans to understand when calling the CLI.
96-
flags.StringVarP(&shardPattern, "shard", "s", "", "which shard to run, in form of 'N/M' where N is the shard number and M is the total number of shards, smallest shard number is 1")
96+
flags.StringVarP(&shardPattern, "shard", "s", "", "which shard to run, in form of 'N/M' where N is the shard number and M is the total number of shards, smallest shard number is 1. Shards are applied only to tests that would run, not those that would be skipped.")
9797
RootCmd.AddCommand(runCmd)
9898
}
9999

local/group.go

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ func (g *Group) List(config RunConfig) []Info {
128128
}
129129

130130
// Gather gathers all runnable child groups and tests
131-
func (g *Group) Gather(config RunConfig, count int) ([]TestContainer, int) {
131+
func (g *Group) Gather(config RunConfig) ([]TestContainer, int) {
132132
sort.Sort(ByOrder(g.Children))
133133

134134
if !g.willRun(config) {
@@ -142,7 +142,7 @@ func (g *Group) Gather(config RunConfig, count int) ([]TestContainer, int) {
142142
}
143143

144144
for _, c := range g.Children {
145-
lst, childCount := c.Gather(config, count+subCount)
145+
lst, childCount := c.Gather(config)
146146
// if we had no runnable tests, do not bother adding the group init/deinit, just return the empty list
147147
if childCount == 0 {
148148
continue
@@ -165,8 +165,7 @@ func (g *Group) Run(config RunConfig) ([]Result, error) {
165165
// This gathers all of the individual tests and group init/deinit commands
166166
// all the way down, leading to a flat list we can execute, rather than recursion.
167167
// That should make it easier to break into shards.
168-
count := 0
169-
runnables, _ := g.Gather(config, count)
168+
runnables, _ := g.Gather(config)
170169
if len(runnables) == 0 {
171170
return []Result{{TestResult: Skip,
172171
Name: g.Name(),
@@ -184,21 +183,11 @@ func (g *Group) Run(config RunConfig) ([]Result, error) {
184183
wg.Add(1)
185184
go func(c TestContainer, cf RunConfig) {
186185
defer wg.Done()
187-
var isTest bool
188-
if _, ok := c.(*Test); ok {
189-
isTest = true
190-
}
191-
// Run() if one of the following is true: it is not a test; there are no start/end boundaries; the test is within the boundaries
192-
if !isTest || (config.start == 0 && config.count == 0) || (count >= config.start && config.start+config.count > count) {
193-
res, err := c.Run(cf)
194-
if err != nil {
195-
errCh <- err
196-
}
197-
resCh <- res
198-
}
199-
if isTest {
200-
count++
186+
res, err := c.Run(cf)
187+
if err != nil {
188+
errCh <- err
201189
}
190+
resCh <- res
202191
}(c, config)
203192
}
204193

local/groupcommand.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,6 @@ func (g GroupCommand) Order() int {
3838
}
3939

4040
// Gather satisfies the TestContainer interface
41-
func (g GroupCommand) Gather(config RunConfig, count int) ([]TestContainer, int) {
41+
func (g GroupCommand) Gather(config RunConfig) ([]TestContainer, int) {
4242
return []TestContainer{&g}, 0
4343
}

local/project.go

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"errors"
55
"fmt"
66
"path/filepath"
7+
8+
"github.com/linuxkit/rtf/logger"
79
)
810

911
// NewProject creates a new top-level Group at the provided path
@@ -52,11 +54,12 @@ func (p *Project) Run(config RunConfig) ([]Result, error) {
5254
return p.Group.Run(config)
5355
}
5456

55-
infos := p.Group.List(config)
56-
start, count := calculateShard(len(infos), p.shard, p.totalShards)
57-
58-
config.start = start
59-
config.count = count
57+
infos := p.List(config)
58+
config.restrictToTests = map[string]bool{}
59+
for _, info := range infos {
60+
config.restrictToTests[info.Name] = true
61+
}
62+
config.Logger.Log(logger.LevelInfo, fmt.Sprintf("restricting tests to %v", config.restrictToTests))
6063

6164
return p.Group.Run(config)
6265
}
@@ -67,6 +70,14 @@ func (p *Project) List(config RunConfig) []Info {
6770
if p.totalShards <= 1 {
6871
return infos
6972
}
70-
start, count := calculateShard(len(infos), p.shard, p.totalShards)
71-
return infos[start : start+count]
73+
// if sharding, we ignore tests that would be skipped
74+
var retInfos []Info
75+
for _, info := range infos {
76+
if info.TestResult == Skip {
77+
continue
78+
}
79+
retInfos = append(retInfos, info)
80+
}
81+
start, count := calculateShard(len(retInfos), p.shard, p.totalShards)
82+
return retInfos[start : start+count]
7283
}

local/test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ func (t *Test) List(config RunConfig) []Info {
8282
}
8383

8484
// Gather satisfies the TestContainer interface
85-
func (t *Test) Gather(config RunConfig, count int) ([]TestContainer, int) {
86-
if (config.start == 0 && config.count == 0) || (count >= config.start && config.start+config.count > count) {
85+
func (t *Test) Gather(config RunConfig) ([]TestContainer, int) {
86+
if len(config.restrictToTests) == 0 || config.restrictToTests[t.Name()] {
8787
return []TestContainer{t}, 1
8888
}
8989
return nil, 0
@@ -101,6 +101,7 @@ func (t *Test) Run(config RunConfig) ([]Result, error) {
101101
TestResult: Skip,
102102
}}, nil
103103
}
104+
config.Logger.Log(logger.LevelInfo, fmt.Sprintf("Running test %s", t.Name()))
104105

105106
if t.Tags.Repeat == 0 {
106107
// Always run at least once

local/types.go

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -160,18 +160,17 @@ type OSInfo struct {
160160

161161
// RunConfig contains runtime configuration information
162162
type RunConfig struct {
163-
Extra bool
164-
CaseDir string
165-
LogDir string
166-
Logger logger.LogDispatcher
167-
SystemInfo sysinfo.SystemInfo
168-
Labels map[string]bool
169-
NotLabels map[string]bool
170-
TestPattern string
171-
Parallel bool
172-
IncludeInit bool
173-
start int
174-
count int
163+
Extra bool
164+
CaseDir string
165+
LogDir string
166+
Logger logger.LogDispatcher
167+
SystemInfo sysinfo.SystemInfo
168+
Labels map[string]bool
169+
NotLabels map[string]bool
170+
TestPattern string
171+
Parallel bool
172+
IncludeInit bool
173+
restrictToTests map[string]bool
175174
}
176175

177176
// GroupCommand is a command that is runnable, either a test or pre/post script.
@@ -187,7 +186,7 @@ type TestContainer interface {
187186
Order() int
188187
List(config RunConfig) []Info
189188
Run(config RunConfig) ([]Result, error)
190-
Gather(config RunConfig, count int) ([]TestContainer, int)
189+
Gather(config RunConfig) ([]TestContainer, int)
191190
}
192191

193192
// ByOrder implements the sort.Sorter interface for TestContainer

0 commit comments

Comments
 (0)