From f3e4c05250654fb536e7249e9a2dce77b8722ade Mon Sep 17 00:00:00 2001 From: James Bardin Date: Fri, 3 Feb 2017 15:56:19 -0500 Subject: [PATCH] build the statelocker binary before running this way we can signal it directly to amke sure it exits cleanly. --- command/command_test.go | 22 ++++++++++++++++++++-- command/testdata/statelocker.go | 10 ++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/command/command_test.go b/command/command_test.go index 9418e85711..d3bded69a8 100644 --- a/command/command_test.go +++ b/command/command_test.go @@ -536,9 +536,26 @@ func testRemoteState(t *testing.T, s *terraform.State, c int) (*terraform.Remote // testlockState calls a separate process to the lock the state file at path. // deferFunc should be called in the caller to properly unlock the file. func testLockState(path string) (func(), error) { - locker := exec.Command("go", "run", "testdata/statelocker.go", path) + // build and run the binary ourselves so we can quickly terminate it for cleanup + buildDir, err := ioutil.TempDir("", "locker") + if err != nil { + return nil, err + } + cleanFunc := func() { + os.RemoveAll(buildDir) + } + + lockBin := filepath.Join(buildDir, "statelocker") + out, err := exec.Command("go", "build", "-o", lockBin, "testdata/statelocker.go").CombinedOutput() + if err != nil { + cleanFunc() + return nil, fmt.Errorf("%s %s", err, out) + } + + locker := exec.Command(lockBin, path) pr, pw, err := os.Pipe() if err != nil { + cleanFunc() return nil, err } defer pr.Close() @@ -550,6 +567,7 @@ func testLockState(path string) (func(), error) { return nil, err } deferFunc := func() { + cleanFunc() locker.Process.Signal(syscall.SIGTERM) locker.Wait() } @@ -562,7 +580,7 @@ func testLockState(path string) (func(), error) { } if string(buf[:n]) != "LOCKED" { - return deferFunc, fmt.Errorf("statelocker wrote", string(buf[:n])) + return deferFunc, fmt.Errorf("statelocker wrote: %s", string(buf[:n])) } return deferFunc, nil } diff --git a/command/testdata/statelocker.go b/command/testdata/statelocker.go index a70e3d6dab..8f25f9d33f 100644 --- a/command/testdata/statelocker.go +++ b/command/testdata/statelocker.go @@ -9,6 +9,7 @@ import ( "os" "os/signal" "syscall" + "time" "github.com/hashicorp/terraform/state" ) @@ -38,6 +39,11 @@ func main() { }() c := make(chan os.Signal, 1) - signal.Notify(c, syscall.SIGINT, syscall.SIGTERM) - <-c + signal.Notify(c, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP) + + // timeout after 10 second in case we don't get cleaned up by the test + select { + case <-time.After(10 * time.Second): + case <-c: + } }