Source file src/internal/testlog/log.go

     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.
     8  package testlog
     9  
    10  import "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.
    16  type 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.Pointer 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.
    29  var logger atomic.Pointer[Interface]
    30  
    31  // SetLogger sets the test logger implementation for the current process.
    32  // It must be called only once, at process startup.
    33  func SetLogger(impl Interface) {
    34  	if !logger.CompareAndSwap(nil, &impl) {
    35  		panic("testlog: SetLogger must be called only once")
    36  	}
    37  }
    38  
    39  // Logger returns the current test logger implementation.
    40  // It returns nil if there is no logger.
    41  func Logger() Interface {
    42  	impl := logger.Load()
    43  	if impl == nil {
    44  		return nil
    45  	}
    46  	return *impl
    47  }
    48  
    49  // Getenv calls Logger().Getenv, if a logger has been set.
    50  func Getenv(name string) {
    51  	if log := Logger(); log != nil {
    52  		log.Getenv(name)
    53  	}
    54  }
    55  
    56  // Open calls Logger().Open, if a logger has been set.
    57  func Open(name string) {
    58  	if log := Logger(); log != nil {
    59  		log.Open(name)
    60  	}
    61  }
    62  
    63  // Stat calls Logger().Stat, if a logger has been set.
    64  func Stat(name string) {
    65  	if log := Logger(); log != nil {
    66  		log.Stat(name)
    67  	}
    68  }
    69  

View as plain text