github.com/hashicorp/packer@v1.14.3/command/build_cancellation_test.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package command
     5  
     6  import (
     7  	"context"
     8  	"path/filepath"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/google/go-cmp/cmp"
    13  )
    14  
    15  func TestBuildCommand_RunContext_CtxCancel(t *testing.T) {
    16  
    17  	tests := []struct {
    18  		name                 string
    19  		args                 []string
    20  		parallelPassingTests int
    21  		expected             int
    22  	}{
    23  		{"cancel 1 pending build - parallel=true",
    24  			[]string{"-parallel-builds=10", filepath.Join(testFixture("parallel"), "1lock-5wg.json")},
    25  			5,
    26  			1,
    27  		},
    28  		{"cancel in the middle with 2 pending builds - parallel=true",
    29  			[]string{"-parallel-builds=10", filepath.Join(testFixture("parallel"), "2lock-4wg.json")},
    30  			4,
    31  			1,
    32  		},
    33  		{"cancel 1 locked build - debug - parallel=true",
    34  			[]string{"-parallel-builds=10", "-debug=true", filepath.Join(testFixture("parallel"), "1lock.json")},
    35  			0,
    36  			1,
    37  		},
    38  		{"cancel 2 locked builds - debug - parallel=true",
    39  			[]string{"-parallel-builds=10", "-debug=true", filepath.Join(testFixture("parallel"), "2lock.json")},
    40  			0,
    41  			1,
    42  		},
    43  		{"cancel 1 locked build - debug - parallel=false",
    44  			[]string{"-parallel-builds=1", "-debug=true", filepath.Join(testFixture("parallel"), "1lock.json")},
    45  			0,
    46  			1,
    47  		},
    48  		{"cancel 2 locked builds - debug - parallel=false",
    49  			[]string{"-parallel-builds=1", "-debug=true", filepath.Join(testFixture("parallel"), "2lock.json")},
    50  			0,
    51  			1,
    52  		},
    53  	}
    54  
    55  	for _, tt := range tests {
    56  		tt := tt
    57  		t.Run(tt.name, func(t *testing.T) {
    58  			t.Parallel()
    59  			b := NewParallelTestBuilder(tt.parallelPassingTests)
    60  			locked := &LockedBuilder{unlock: make(chan interface{})}
    61  			c := &BuildCommand{
    62  				Meta: testMetaParallel(t, b, locked),
    63  			}
    64  
    65  			ctx, cancelCtx := context.WithCancel(context.Background())
    66  			codeC := make(chan int)
    67  			go func() {
    68  				defer close(codeC)
    69  				cfg, ret := c.ParseArgs(tt.args)
    70  				if ret != 0 {
    71  					t.Error("ParseArgs failed.")
    72  					return
    73  				}
    74  				codeC <- c.RunContext(ctx, cfg)
    75  			}()
    76  			t.Logf("waiting for passing tests if any")
    77  			b.wg.Wait() // ran `tt.parallelPassingTests` times
    78  			t.Logf("cancelling context")
    79  			cancelCtx()
    80  
    81  			select {
    82  			case code := <-codeC:
    83  				if code != tt.expected {
    84  					t.Logf("wrong code: %s", cmp.Diff(code, tt.expected))
    85  					fatalCommand(t, c.Meta)
    86  				}
    87  			case <-time.After(15 * time.Second):
    88  				t.Fatal("deadlock")
    89  			}
    90  		})
    91  	}
    92  }