github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/worker/logger/logger_test.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package logger_test
     5  
     6  import (
     7  	"time"
     8  
     9  	"github.com/juju/errors"
    10  	"github.com/juju/loggo"
    11  	"github.com/juju/names/v5"
    12  	"github.com/juju/testing"
    13  	jc "github.com/juju/testing/checkers"
    14  	"github.com/juju/worker/v3"
    15  	gc "gopkg.in/check.v1"
    16  
    17  	"github.com/juju/juju/core/watcher"
    18  	"github.com/juju/juju/worker/logger"
    19  )
    20  
    21  type LoggerSuite struct {
    22  	testing.IsolationSuite
    23  
    24  	context   *loggo.Context
    25  	agent     names.Tag
    26  	loggerAPI *mockAPI
    27  	config    logger.WorkerConfig
    28  
    29  	value string
    30  }
    31  
    32  var _ = gc.Suite(&LoggerSuite{})
    33  
    34  func (s *LoggerSuite) SetUpTest(c *gc.C) {
    35  	s.IsolationSuite.SetUpTest(c)
    36  	s.context = loggo.NewContext(loggo.DEBUG)
    37  	s.agent = names.NewMachineTag("42")
    38  	s.loggerAPI = &mockAPI{
    39  		config:  s.context.Config().String(),
    40  		watcher: &mockNotifyWatcher{},
    41  	}
    42  	s.config = logger.WorkerConfig{
    43  		Context: s.context,
    44  		API:     s.loggerAPI,
    45  		Tag:     s.agent,
    46  		Logger:  loggo.GetLogger("test"),
    47  		Callback: func(v string) error {
    48  			s.value = v
    49  			return nil
    50  		},
    51  	}
    52  	s.value = ""
    53  }
    54  
    55  func (s *LoggerSuite) TestMissingContext(c *gc.C) {
    56  	s.config.Context = nil
    57  	w, err := logger.NewLogger(s.config)
    58  	c.Assert(w, gc.IsNil)
    59  	c.Assert(err, jc.Satisfies, errors.IsNotValid)
    60  	c.Assert(err.Error(), gc.Equals, "missing logging context not valid")
    61  }
    62  
    63  func (s *LoggerSuite) TestMissingAPI(c *gc.C) {
    64  	s.config.API = nil
    65  	w, err := logger.NewLogger(s.config)
    66  	c.Assert(w, gc.IsNil)
    67  	c.Assert(err, jc.Satisfies, errors.IsNotValid)
    68  	c.Assert(err.Error(), gc.Equals, "missing api not valid")
    69  }
    70  
    71  func (s *LoggerSuite) TestMissingLogger(c *gc.C) {
    72  	s.config.Logger = nil
    73  	w, err := logger.NewLogger(s.config)
    74  	c.Assert(w, gc.IsNil)
    75  	c.Assert(err, jc.Satisfies, errors.IsNotValid)
    76  	c.Assert(err.Error(), gc.Equals, "missing logger not valid")
    77  }
    78  
    79  func (s *LoggerSuite) waitLoggingInfo(c *gc.C, expected string) {
    80  	timeout := time.After(testing.LongWait)
    81  	for {
    82  		select {
    83  		case <-timeout:
    84  			c.Fatalf("timeout while waiting for logging info to change")
    85  		case <-time.After(10 * time.Millisecond):
    86  			loggerInfo := s.context.Config().String()
    87  			if loggerInfo != expected {
    88  				c.Logf("logging is %q, still waiting", loggerInfo)
    89  				continue
    90  			}
    91  			return
    92  		}
    93  	}
    94  }
    95  
    96  func (s *LoggerSuite) makeLogger(c *gc.C) worker.Worker {
    97  	w, err := logger.NewLogger(s.config)
    98  	c.Assert(err, jc.ErrorIsNil)
    99  	return w
   100  }
   101  
   102  func (s *LoggerSuite) TestRunStop(c *gc.C) {
   103  	loggingWorker := s.makeLogger(c)
   104  	c.Assert(worker.Stop(loggingWorker), gc.IsNil)
   105  }
   106  
   107  func (s *LoggerSuite) TestInitialState(c *gc.C) {
   108  	expected := s.context.Config().String()
   109  
   110  	initial := "<root>=DEBUG;wibble=ERROR"
   111  	c.Assert(expected, gc.Not(gc.Equals), initial)
   112  
   113  	s.context.ResetLoggerLevels()
   114  	err := s.context.ConfigureLoggers(initial)
   115  	c.Assert(err, jc.ErrorIsNil)
   116  
   117  	loggingWorker := s.makeLogger(c)
   118  	s.waitLoggingInfo(c, expected)
   119  	err = worker.Stop(loggingWorker)
   120  	c.Assert(err, jc.ErrorIsNil)
   121  
   122  	c.Check(s.value, gc.Equals, expected)
   123  	c.Check(s.loggerAPI.loggingTag, gc.Equals, s.agent)
   124  	c.Check(s.loggerAPI.watchingTag, gc.Equals, s.agent)
   125  }
   126  
   127  func (s *LoggerSuite) TestConfigOverride(c *gc.C) {
   128  	s.config.Override = "test=TRACE"
   129  
   130  	s.context.ResetLoggerLevels()
   131  	err := s.context.ConfigureLoggers("<root>=DEBUG;wibble=ERROR")
   132  	c.Assert(err, jc.ErrorIsNil)
   133  
   134  	loggingWorker := s.makeLogger(c)
   135  	defer worker.Stop(loggingWorker)
   136  
   137  	// When reset, the root defaults to WARNING.
   138  	expected := "<root>=WARNING;test=TRACE"
   139  	s.waitLoggingInfo(c, expected)
   140  }
   141  
   142  type mockNotifyWatcher struct {
   143  	changes chan struct{}
   144  }
   145  
   146  func (m *mockNotifyWatcher) Kill() {}
   147  
   148  func (m *mockNotifyWatcher) Wait() error {
   149  	return nil
   150  }
   151  
   152  func (m *mockNotifyWatcher) Changes() watcher.NotifyChannel {
   153  	return m.changes
   154  }
   155  
   156  var _ watcher.NotifyWatcher = (*mockNotifyWatcher)(nil)
   157  
   158  type mockAPI struct {
   159  	watcher *mockNotifyWatcher
   160  	config  string
   161  
   162  	loggingTag  names.Tag
   163  	watchingTag names.Tag
   164  }
   165  
   166  func (m *mockAPI) LoggingConfig(agentTag names.Tag) (string, error) {
   167  	m.loggingTag = agentTag
   168  	return m.config, nil
   169  }
   170  
   171  func (m *mockAPI) WatchLoggingConfig(agentTag names.Tag) (watcher.NotifyWatcher, error) {
   172  	m.watchingTag = agentTag
   173  	return m.watcher, nil
   174  }