| // Copyright 2017 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| // Package testlog provides a back-channel communication path |
| // between tests and package os, so that cmd/go can see which |
| // environment variables and files a test consults. |
| package testlog |
| |
| import "sync/atomic" |
| |
| // Interface is the interface required of test loggers. |
| // The os package will invoke the interface's methods to indicate that |
| // it is inspecting the given environment variables or files. |
| // Multiple goroutines may call these methods simultaneously. |
| type Interface interface { |
| Getenv(key string) |
| Stat(file string) |
| Open(file string) |
| Chdir(dir string) |
| } |
| |
| // logger is the current logger Interface. |
| // We use an atomic.Value in case test startup |
| // is racing with goroutines started during init. |
| // That must not cause a race detector failure, |
| // although it will still result in limited visibility |
| // into exactly what those goroutines do. |
| var logger atomic.Value |
| |
| // SetLogger sets the test logger implementation for the current process. |
| // It must be called only once, at process startup. |
| func SetLogger(impl Interface) { |
| if logger.Load() != nil { |
| panic("testlog: SetLogger must be called only once") |
| } |
| logger.Store(&impl) |
| } |
| |
| // Logger returns the current test logger implementation. |
| // It returns nil if there is no logger. |
| func Logger() Interface { |
| impl := logger.Load() |
| if impl == nil { |
| return nil |
| } |
| return *impl.(*Interface) |
| } |
| |
| // Getenv calls Logger().Getenv, if a logger has been set. |
| func Getenv(name string) { |
| if log := Logger(); log != nil { |
| log.Getenv(name) |
| } |
| } |
| |
| // Open calls Logger().Open, if a logger has been set. |
| func Open(name string) { |
| if log := Logger(); log != nil { |
| log.Open(name) |
| } |
| } |
| |
| // Stat calls Logger().Stat, if a logger has been set. |
| func Stat(name string) { |
| if log := Logger(); log != nil { |
| log.Stat(name) |
| } |
| } |