diff options
Diffstat (limited to 'compiler_wrapper/testutil_test.go')
-rw-r--r-- | compiler_wrapper/testutil_test.go | 51 |
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 |