build the statelocker binary before running

this way we can signal it directly to amke sure it exits cleanly.
This commit is contained in:
James Bardin 2017-02-03 15:56:19 -05:00
parent bd65ddbcaa
commit f3e4c05250
2 changed files with 28 additions and 4 deletions

View File

@ -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. // 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. // deferFunc should be called in the caller to properly unlock the file.
func testLockState(path string) (func(), error) { 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() pr, pw, err := os.Pipe()
if err != nil { if err != nil {
cleanFunc()
return nil, err return nil, err
} }
defer pr.Close() defer pr.Close()
@ -550,6 +567,7 @@ func testLockState(path string) (func(), error) {
return nil, err return nil, err
} }
deferFunc := func() { deferFunc := func() {
cleanFunc()
locker.Process.Signal(syscall.SIGTERM) locker.Process.Signal(syscall.SIGTERM)
locker.Wait() locker.Wait()
} }
@ -562,7 +580,7 @@ func testLockState(path string) (func(), error) {
} }
if string(buf[:n]) != "LOCKED" { 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 return deferFunc, nil
} }

View File

@ -9,6 +9,7 @@ import (
"os" "os"
"os/signal" "os/signal"
"syscall" "syscall"
"time"
"github.com/hashicorp/terraform/state" "github.com/hashicorp/terraform/state"
) )
@ -38,6 +39,11 @@ func main() {
}() }()
c := make(chan os.Signal, 1) c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM) signal.Notify(c, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)
<-c
// timeout after 10 second in case we don't get cleaned up by the test
select {
case <-time.After(10 * time.Second):
case <-c:
}
} }