fix for progress formatter summary in concurrency mode
see: https://github.com/DATA-DOG/godog/issues/161
Этот коммит содержится в:
родитель
96731eaefa
коммит
b730b9fd4b
1 изменённых файлов: 51 добавлений и 3 удалений
54
run.go
54
run.go
|
@ -8,6 +8,7 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/DATA-DOG/godog/colors"
|
"github.com/DATA-DOG/godog/colors"
|
||||||
)
|
)
|
||||||
|
@ -28,11 +29,22 @@ type runner struct {
|
||||||
initializer initializer
|
initializer initializer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *runner) concurrent(rate int) (failed bool) {
|
func (r *runner) concurrent(rate int, formatterFn func() Formatter) (failed bool) {
|
||||||
|
var useFmtCopy bool
|
||||||
|
var copyLock sync.Mutex
|
||||||
|
|
||||||
|
// special mode for progress-formatter
|
||||||
|
if _, ok := r.fmt.(*progress); ok {
|
||||||
|
useFmtCopy = true
|
||||||
|
}
|
||||||
|
|
||||||
queue := make(chan int, rate)
|
queue := make(chan int, rate)
|
||||||
for i, ft := range r.features {
|
for i, ft := range r.features {
|
||||||
queue <- i // reserve space in queue
|
queue <- i // reserve space in queue
|
||||||
|
ft := *ft
|
||||||
|
|
||||||
go func(fail *bool, feat *feature) {
|
go func(fail *bool, feat *feature) {
|
||||||
|
var fmtCopy Formatter
|
||||||
defer func() {
|
defer func() {
|
||||||
<-queue // free a space in queue
|
<-queue // free a space in queue
|
||||||
}()
|
}()
|
||||||
|
@ -46,12 +58,48 @@ func (r *runner) concurrent(rate int) (failed bool) {
|
||||||
strict: r.strict,
|
strict: r.strict,
|
||||||
features: []*feature{feat},
|
features: []*feature{feat},
|
||||||
}
|
}
|
||||||
|
if useFmtCopy {
|
||||||
|
fmtCopy = formatterFn()
|
||||||
|
suite.fmt = fmtCopy
|
||||||
|
} else {
|
||||||
|
suite.fmt = r.fmt
|
||||||
|
}
|
||||||
|
|
||||||
r.initializer(suite)
|
r.initializer(suite)
|
||||||
suite.run()
|
suite.run()
|
||||||
if suite.failed {
|
if suite.failed {
|
||||||
*fail = true
|
*fail = true
|
||||||
}
|
}
|
||||||
}(&failed, ft)
|
if useFmtCopy {
|
||||||
|
copyLock.Lock()
|
||||||
|
if d, ok := r.fmt.(*progress); ok {
|
||||||
|
if s, ok := fmtCopy.(*progress); ok {
|
||||||
|
func(source *progress, dest *progress) {
|
||||||
|
for _, v := range source.features {
|
||||||
|
dest.features = append(dest.features, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range source.failed {
|
||||||
|
dest.failed = append(dest.failed, v)
|
||||||
|
}
|
||||||
|
for _, v := range source.passed {
|
||||||
|
dest.passed = append(dest.passed, v)
|
||||||
|
}
|
||||||
|
for _, v := range source.skipped {
|
||||||
|
dest.skipped = append(dest.skipped, v)
|
||||||
|
}
|
||||||
|
for _, v := range source.undefined {
|
||||||
|
dest.undefined = append(dest.undefined, v)
|
||||||
|
}
|
||||||
|
for _, v := range source.pending {
|
||||||
|
dest.pending = append(dest.pending, v)
|
||||||
|
}
|
||||||
|
}(s, d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
copyLock.Unlock()
|
||||||
|
}
|
||||||
|
}(&failed, &ft)
|
||||||
}
|
}
|
||||||
// wait until last are processed
|
// wait until last are processed
|
||||||
for i := 0; i < rate; i++ {
|
for i := 0; i < rate; i++ {
|
||||||
|
@ -168,7 +216,7 @@ func RunWithOptions(suite string, contextInitializer func(suite *Suite), opt Opt
|
||||||
|
|
||||||
var failed bool
|
var failed bool
|
||||||
if opt.Concurrency > 1 {
|
if opt.Concurrency > 1 {
|
||||||
failed = r.concurrent(opt.Concurrency)
|
failed = r.concurrent(opt.Concurrency, func() Formatter { return formatter(suite, output) })
|
||||||
} else {
|
} else {
|
||||||
failed = r.run()
|
failed = r.run()
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче