aboutsummaryrefslogtreecommitdiff
path: root/compiler_wrapper/testutil_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'compiler_wrapper/testutil_test.go')
-rw-r--r--compiler_wrapper/testutil_test.go51
1 files changed, 51 insertions, 0 deletions
diff --git a/compiler_wrapper/testutil_test.go b/compiler_wrapper/testutil_test.go
index 21b7169d..035f2373 100644
--- a/compiler_wrapper/testutil_test.go
+++ b/compiler_wrapper/testutil_test.go
@@ -14,7 +14,10 @@ import (
"path/filepath"
"regexp"
"strings"
+ "sync"
+ "syscall"
"testing"
+ "time"
)
const (
@@ -43,8 +46,15 @@ type testContext struct {
stdinBuffer bytes.Buffer
stdoutBuffer bytes.Buffer
stderrBuffer bytes.Buffer
+
+ umaskRestoreAction func()
}
+// We have some tests which modify our umask, and other tests which depend upon the value of our
+// umask remaining consistent. This lock serializes those. Please use `NoteTestWritesToUmask()` and
+// `NoteTestDependsOnUmask()` on `testContext` rather than using this directly.
+var umaskModificationLock sync.RWMutex
+
func withTestContext(t *testing.T, work func(ctx *testContext)) {
t.Parallel()
tempDir, err := ioutil.TempDir("", "compiler_wrapper")
@@ -62,11 +72,48 @@ func withTestContext(t *testing.T, work func(ctx *testContext)) {
}
ctx.updateConfig(&config{})
+ defer ctx.maybeReleaseUmaskDependency()
work(&ctx)
}
var _ env = (*testContext)(nil)
+func (ctx *testContext) umask(mask int) (oldmask int) {
+ if ctx.umaskRestoreAction == nil {
+ panic("Umask operations requested in test without declaring a umask dependency")
+ }
+ return syscall.Umask(mask)
+}
+
+func (ctx *testContext) initUmaskDependency(lockFn func(), unlockFn func()) {
+ if ctx.umaskRestoreAction != nil {
+ // Use a panic so we get a backtrace.
+ panic("Multiple notes of a test depending on the value of `umask` given -- tests " +
+ "are only allowed up to one.")
+ }
+
+ lockFn()
+ ctx.umaskRestoreAction = unlockFn
+}
+
+func (ctx *testContext) maybeReleaseUmaskDependency() {
+ if ctx.umaskRestoreAction != nil {
+ ctx.umaskRestoreAction()
+ }
+}
+
+// Note that the test depends on a stable value for the process' umask.
+func (ctx *testContext) NoteTestReadsFromUmask() {
+ ctx.initUmaskDependency(umaskModificationLock.RLock, umaskModificationLock.RUnlock)
+}
+
+// Note that the test modifies the process' umask. This implies a dependency on the process' umask,
+// so it's an error to call both NoteTestWritesToUmask and NoteTestReadsFromUmask from the same
+// test.
+func (ctx *testContext) NoteTestWritesToUmask() {
+ ctx.initUmaskDependency(umaskModificationLock.Lock, umaskModificationLock.Unlock)
+}
+
func (ctx *testContext) getenv(key string) (string, bool) {
for i := len(ctx.env) - 1; i >= 0; i-- {
entry := ctx.env[i]
@@ -114,6 +161,10 @@ func (ctx *testContext) run(cmd *command, stdin io.Reader, stdout io.Writer, std
return nil
}
+func (ctx *testContext) runWithTimeout(cmd *command, duration time.Duration) error {
+ return ctx.exec(cmd)
+}
+
func (ctx *testContext) exec(cmd *command) error {
ctx.cmdCount++
ctx.lastCmd = cmd