1// Copyright 2017 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5// Package testlog provides a back-channel communication path 6// between tests and package os, so that cmd/go can see which 7// environment variables and files a test consults. 8package testlog 9 10import "sync/atomic" 11 12// Interface is the interface required of test loggers. 13// The os package will invoke the interface's methods to indicate that 14// it is inspecting the given environment variables or files. 15// Multiple goroutines may call these methods simultaneously. 16type Interface interface { 17 Getenv(key string) 18 Stat(file string) 19 Open(file string) 20 Chdir(dir string) 21} 22 23// logger is the current logger Interface. 24// We use an atomic.Value in case test startup 25// is racing with goroutines started during init. 26// That must not cause a race detector failure, 27// although it will still result in limited visibility 28// into exactly what those goroutines do. 29var logger atomic.Value 30 31// SetLogger sets the test logger implementation for the current process. 32// It must be called only once, at process startup. 33func SetLogger(impl Interface) { 34 if logger.Load() != nil { 35 panic("testlog: SetLogger must be called only once") 36 } 37 logger.Store(&impl) 38} 39 40// Logger returns the current test logger implementation. 41// It returns nil if there is no logger. 42func Logger() Interface { 43 impl := logger.Load() 44 if impl == nil { 45 return nil 46 } 47 return *impl.(*Interface) 48} 49 50// Getenv calls Logger().Getenv, if a logger has been set. 51func Getenv(name string) { 52 if log := Logger(); log != nil { 53 log.Getenv(name) 54 } 55} 56 57// Open calls Logger().Open, if a logger has been set. 58func Open(name string) { 59 if log := Logger(); log != nil { 60 log.Open(name) 61 } 62} 63 64// Stat calls Logger().Stat, if a logger has been set. 65func Stat(name string) { 66 if log := Logger(); log != nil { 67 log.Stat(name) 68 } 69} 70