From 583d93790f2f8d36feff6220a98f5bacf372e1c4 Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Mon, 6 May 2019 15:07:57 +0200 Subject: [PATCH] add tests for cancellation while building --- command/build_cancellation_test.go | 81 +++++++++++++++++++ command/build_parallel_test.go | 5 +- command/test-fixtures/parallel/1lock-5wg.json | 10 +++ command/test-fixtures/parallel/1lock.json | 7 +- command/test-fixtures/parallel/2lock-4wg.json | 10 +++ command/test-fixtures/parallel/2lock.json | 6 +- 6 files changed, 105 insertions(+), 14 deletions(-) create mode 100644 command/build_cancellation_test.go create mode 100644 command/test-fixtures/parallel/1lock-5wg.json create mode 100644 command/test-fixtures/parallel/2lock-4wg.json diff --git a/command/build_cancellation_test.go b/command/build_cancellation_test.go new file mode 100644 index 000000000..da8fd7838 --- /dev/null +++ b/command/build_cancellation_test.go @@ -0,0 +1,81 @@ +package command + +import ( + "context" + "path/filepath" + "testing" + "time" + + "github.com/google/go-cmp/cmp" +) + +func TestBuildCommand_RunContext_CtxCancel(t *testing.T) { + + tests := []struct { + name string + args []string + parallelPassingTests int + expected int + }{ + {"cancel 1 pending build - parallel=true", + []string{"-parallel=true", filepath.Join(testFixture("parallel"), "1lock-5wg.json")}, + 5, + 1, + }, + {"cancel in the middle with 2 pending builds - parallel=true", + []string{"-parallel=true", filepath.Join(testFixture("parallel"), "2lock-4wg.json")}, + 4, + 1, + }, + // {"cancel 1 locked build - debug - parallel=true", + // []string{"-parallel=true", "-debug=true", filepath.Join(testFixture("parallel"), "1lock.json")}, + // 5, + // 1, + // }, + // {"cancel 2 locked builds - debug - parallel=true", + // []string{"-parallel=true", "-debug=true", filepath.Join(testFixture("parallel"), "2lock.json")}, + // 4, + // 1, + // }, + // {"cancel 1 locked build - debug - parallel=false", + // []string{"-parallel=false", "-debug=true", filepath.Join(testFixture("parallel"), "1lock.json")}, + // 5, + // 1, + // }, + // {"cancel 2 locked builds - debug - parallel=false", + // []string{"-parallel=false", "-debug=true", filepath.Join(testFixture("parallel"), "2lock.json")}, + // 4, + // 1, + // }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + b := NewParallelTestBuilder(tt.parallelPassingTests) + locked := &LockedBuilder{unlock: make(chan interface{})} + c := &BuildCommand{ + Meta: testMetaParallel(t, b, locked), + } + + ctx, cancelCtx := context.WithCancel(context.Background()) + codeC := make(chan int) + go func() { + defer close(codeC) + codeC <- c.RunContext(ctx, tt.args) + }() + b.wg.Wait() // ran `tt.parallelPassingTests` times + cancelCtx() + + select { + case code := <-codeC: + if code != tt.expected { + t.Logf("wrong code: %s", cmp.Diff(code, tt.expected)) + fatalCommand(t, c.Meta) + } + case <-time.After(15 * time.Second): + t.Fatal("deadlock") + } + }) + } +} diff --git a/command/build_parallel_test.go b/command/build_parallel_test.go index 5acb1dbfc..b2b61484b 100644 --- a/command/build_parallel_test.go +++ b/command/build_parallel_test.go @@ -46,7 +46,6 @@ func (b *LockedBuilder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) select { case <-b.unlock: case <-ctx.Done(): - panic("crap") return nil, ctx.Err() } return nil, nil @@ -99,7 +98,7 @@ func TestBuildParallel_1(t *testing.T) { args := []string{ fmt.Sprintf("-parallel=true"), - filepath.Join(testFixture("parallel"), "1lock.json"), + filepath.Join(testFixture("parallel"), "1lock-5wg.json"), } wg := errgroup.Group{} @@ -128,7 +127,7 @@ func TestBuildParallel_2(t *testing.T) { args := []string{ fmt.Sprintf("-parallel-builds=3"), - filepath.Join(testFixture("parallel"), "2lock.json"), + filepath.Join(testFixture("parallel"), "2lock-4wg"), } wg := errgroup.Group{} diff --git a/command/test-fixtures/parallel/1lock-5wg.json b/command/test-fixtures/parallel/1lock-5wg.json new file mode 100644 index 000000000..966528d8f --- /dev/null +++ b/command/test-fixtures/parallel/1lock-5wg.json @@ -0,0 +1,10 @@ +{ + "builders": [ + {"type": "lock", "name": "build0"}, + {"type": "parallel-test", "name": "build1"}, + {"type": "parallel-test", "name": "build2"}, + {"type": "parallel-test", "name": "build3"}, + {"type": "parallel-test", "name": "build4"}, + {"type": "parallel-test", "name": "build5"} + ] +} \ No newline at end of file diff --git a/command/test-fixtures/parallel/1lock.json b/command/test-fixtures/parallel/1lock.json index 966528d8f..952f45dc0 100644 --- a/command/test-fixtures/parallel/1lock.json +++ b/command/test-fixtures/parallel/1lock.json @@ -1,10 +1,5 @@ { "builders": [ - {"type": "lock", "name": "build0"}, - {"type": "parallel-test", "name": "build1"}, - {"type": "parallel-test", "name": "build2"}, - {"type": "parallel-test", "name": "build3"}, - {"type": "parallel-test", "name": "build4"}, - {"type": "parallel-test", "name": "build5"} + {"type": "lock", "name": "build0"} ] } \ No newline at end of file diff --git a/command/test-fixtures/parallel/2lock-4wg.json b/command/test-fixtures/parallel/2lock-4wg.json new file mode 100644 index 000000000..59da8a36d --- /dev/null +++ b/command/test-fixtures/parallel/2lock-4wg.json @@ -0,0 +1,10 @@ +{ + "builders": [ + {"type": "lock", "name": "build0"}, + {"type": "parallel-test", "name": "build1"}, + {"type": "parallel-test", "name": "build2"}, + {"type": "lock", "name": "build3"}, + {"type": "parallel-test", "name": "build4"}, + {"type": "parallel-test", "name": "build5"} + ] +} \ No newline at end of file diff --git a/command/test-fixtures/parallel/2lock.json b/command/test-fixtures/parallel/2lock.json index 59da8a36d..af81f2692 100644 --- a/command/test-fixtures/parallel/2lock.json +++ b/command/test-fixtures/parallel/2lock.json @@ -1,10 +1,6 @@ { "builders": [ {"type": "lock", "name": "build0"}, - {"type": "parallel-test", "name": "build1"}, - {"type": "parallel-test", "name": "build2"}, - {"type": "lock", "name": "build3"}, - {"type": "parallel-test", "name": "build4"}, - {"type": "parallel-test", "name": "build5"} + {"type": "lock", "name": "build1"} ] } \ No newline at end of file