fix text
This commit is contained in:
parent
2f577e60b6
commit
c1527d9b47
|
@ -4,32 +4,47 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"golang.org/x/sync/errgroup"
|
||||||
|
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NewParallelTestBuilder will return a New ParallelTestBuilder whose first run
|
||||||
|
// will lock until unlockOnce is closed and that will unlock after `runs`
|
||||||
|
// builds
|
||||||
|
func NewParallelTestBuilder(runs int) *ParallelTestBuilder {
|
||||||
|
pb := &ParallelTestBuilder{
|
||||||
|
unlockOnce: make(chan interface{}),
|
||||||
|
}
|
||||||
|
pb.wg.Add(runs)
|
||||||
|
return pb
|
||||||
|
}
|
||||||
|
|
||||||
|
// The ParallelTestBuilder's first run will lock
|
||||||
type ParallelTestBuilder struct {
|
type ParallelTestBuilder struct {
|
||||||
Prepared int
|
once sync.Once
|
||||||
Built int
|
unlockOnce chan interface{}
|
||||||
wg *sync.WaitGroup
|
|
||||||
m *sync.Mutex
|
wg sync.WaitGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *ParallelTestBuilder) Prepare(raws ...interface{}) ([]string, error) {
|
func (b *ParallelTestBuilder) Prepare(raws ...interface{}) ([]string, error) {
|
||||||
b.Prepared++
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *ParallelTestBuilder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) {
|
func (b *ParallelTestBuilder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) {
|
||||||
ui.Say(fmt.Sprintf("count: %d", b.Built))
|
b.once.Do(func() {
|
||||||
b.Built++
|
ui.Say("locking build")
|
||||||
|
<-b.unlockOnce
|
||||||
|
b.wg.Add(1) // avoid a panic
|
||||||
|
})
|
||||||
|
|
||||||
|
ui.Say("building")
|
||||||
b.wg.Done()
|
b.wg.Done()
|
||||||
b.m.Lock()
|
|
||||||
b.m.Unlock()
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,42 +72,29 @@ func testMetaParallel(t *testing.T, builder *ParallelTestBuilder) Meta {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBuildParallel(t *testing.T) {
|
func TestBuildParallel(t *testing.T) {
|
||||||
defer cleanup()
|
// testfile that running 6 builds, with first one locks 'forever', other
|
||||||
|
// builds should go through.
|
||||||
m := &sync.Mutex{}
|
b := NewParallelTestBuilder(5)
|
||||||
m.Lock()
|
|
||||||
expected := 2
|
|
||||||
wg := &sync.WaitGroup{}
|
|
||||||
wg.Add(expected)
|
|
||||||
b := &ParallelTestBuilder{
|
|
||||||
wg: wg,
|
|
||||||
m: m,
|
|
||||||
}
|
|
||||||
|
|
||||||
c := &BuildCommand{
|
c := &BuildCommand{
|
||||||
Meta: testMetaParallel(t, b),
|
Meta: testMetaParallel(t, b),
|
||||||
}
|
}
|
||||||
|
|
||||||
args := []string{
|
args := []string{
|
||||||
fmt.Sprintf("-parallel=%d", expected),
|
fmt.Sprintf("-parallel=2"),
|
||||||
filepath.Join(testFixture("parallel"), "template.json"),
|
filepath.Join(testFixture("parallel"), "template.json"),
|
||||||
}
|
}
|
||||||
|
|
||||||
go func(t *testing.T, c *BuildCommand) {
|
wg := errgroup.Group{}
|
||||||
|
|
||||||
|
wg.Go(func() error {
|
||||||
if code := c.Run(args); code != 0 {
|
if code := c.Run(args); code != 0 {
|
||||||
fatalCommand(t, c.Meta)
|
fatalCommand(t, c.Meta)
|
||||||
}
|
}
|
||||||
}(t, c)
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
wg.Wait()
|
b.wg.Wait() // ran 5 times
|
||||||
if b.Prepared != 6 {
|
close(b.unlockOnce) // unlock locking one
|
||||||
t.Errorf("Expected all builds to be prepared, was %d", b.Prepared)
|
wg.Wait() // wait for termination
|
||||||
}
|
|
||||||
|
|
||||||
if b.Built != expected {
|
|
||||||
t.Errorf("Expected only %d running/completed builds, was %d", expected, b.Built)
|
|
||||||
}
|
|
||||||
|
|
||||||
m.Unlock()
|
|
||||||
wg.Add(math.MaxInt32)
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue