github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/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/loggo"
    10  	"github.com/juju/testing"
    11  	jc "github.com/juju/testing/checkers"
    12  	gc "gopkg.in/check.v1"
    13  	"gopkg.in/juju/names.v2"
    14  	"gopkg.in/juju/worker.v1"
    15  
    16  	"github.com/juju/juju/core/watcher"
    17  	"github.com/juju/juju/worker/logger"
    18  )
    19  
    20  // worstCase is used for timeouts when timing out
    21  // will fail the test. Raising this value should
    22  // not affect the overall running time of the tests
    23  // unless they fail.
    24  const worstCase = 5 * time.Second
    25  
    26  type LoggerSuite struct {
    27  	testing.IsolationSuite
    28  
    29  	loggerAPI *mockAPI
    30  	agent     names.Tag
    31  
    32  	value    string
    33  	override string
    34  }
    35  
    36  var _ = gc.Suite(&LoggerSuite{})
    37  
    38  func (s *LoggerSuite) SetUpTest(c *gc.C) {
    39  	s.IsolationSuite.SetUpTest(c)
    40  	s.loggerAPI = &mockAPI{
    41  		// IsolationSuite setup resets logging info, so just grab that.
    42  		config:  loggo.LoggerInfo(),
    43  		watcher: &mockNotifyWatcher{},
    44  	}
    45  	s.agent = names.NewMachineTag("42")
    46  	s.value = ""
    47  	s.override = ""
    48  }
    49  
    50  func (s *LoggerSuite) waitLoggingInfo(c *gc.C, expected string) {
    51  	timeout := time.After(worstCase)
    52  	for {
    53  		select {
    54  		case <-timeout:
    55  			c.Fatalf("timeout while waiting for logging info to change")
    56  		case <-time.After(10 * time.Millisecond):
    57  			loggerInfo := loggo.LoggerInfo()
    58  			if loggerInfo != expected {
    59  				c.Logf("logging is %q, still waiting", loggerInfo)
    60  				continue
    61  			}
    62  			return
    63  		}
    64  	}
    65  }
    66  
    67  func (s *LoggerSuite) makeLogger(c *gc.C) worker.Worker {
    68  	w, err := logger.NewLogger(s.loggerAPI, s.agent, s.override, func(v string) error {
    69  		s.value = v
    70  		return nil
    71  	})
    72  	c.Assert(err, jc.ErrorIsNil)
    73  	return w
    74  }
    75  
    76  func (s *LoggerSuite) TestRunStop(c *gc.C) {
    77  	loggingWorker := s.makeLogger(c)
    78  	c.Assert(worker.Stop(loggingWorker), gc.IsNil)
    79  }
    80  
    81  func (s *LoggerSuite) TestInitialState(c *gc.C) {
    82  	expected := s.loggerAPI.config
    83  
    84  	initial := "<root>=DEBUG;wibble=ERROR"
    85  	c.Assert(expected, gc.Not(gc.Equals), initial)
    86  
    87  	loggo.DefaultContext().ResetLoggerLevels()
    88  	err := loggo.ConfigureLoggers(initial)
    89  	c.Assert(err, jc.ErrorIsNil)
    90  
    91  	loggingWorker := s.makeLogger(c)
    92  	s.waitLoggingInfo(c, expected)
    93  	err = worker.Stop(loggingWorker)
    94  	c.Assert(err, jc.ErrorIsNil)
    95  
    96  	c.Check(s.value, gc.Equals, expected)
    97  	c.Check(s.loggerAPI.loggingTag, gc.Equals, s.agent)
    98  	c.Check(s.loggerAPI.watchingTag, gc.Equals, s.agent)
    99  }
   100  
   101  func (s *LoggerSuite) TestConfigOverride(c *gc.C) {
   102  	s.override = "test=TRACE"
   103  
   104  	loggo.DefaultContext().ResetLoggerLevels()
   105  	err := loggo.ConfigureLoggers("<root>=DEBUG;wibble=ERROR")
   106  	c.Assert(err, jc.ErrorIsNil)
   107  
   108  	loggingWorker := s.makeLogger(c)
   109  	defer worker.Stop(loggingWorker)
   110  
   111  	// When reset, the root defaults to WARNING.
   112  	expected := "<root>=WARNING;test=TRACE"
   113  	s.waitLoggingInfo(c, expected)
   114  }
   115  
   116  type mockNotifyWatcher struct {
   117  	changes chan struct{}
   118  }
   119  
   120  func (m *mockNotifyWatcher) Kill() {}
   121  
   122  func (m *mockNotifyWatcher) Wait() error {
   123  	return nil
   124  }
   125  
   126  func (m *mockNotifyWatcher) Changes() watcher.NotifyChannel {
   127  	return m.changes
   128  }
   129  
   130  var _ watcher.NotifyWatcher = (*mockNotifyWatcher)(nil)
   131  
   132  type mockAPI struct {
   133  	watcher *mockNotifyWatcher
   134  	config  string
   135  
   136  	loggingTag  names.Tag
   137  	watchingTag names.Tag
   138  }
   139  
   140  func (m *mockAPI) LoggingConfig(agentTag names.Tag) (string, error) {
   141  	m.loggingTag = agentTag
   142  	return m.config, nil
   143  }
   144  
   145  func (m *mockAPI) WatchLoggingConfig(agentTag names.Tag) (watcher.NotifyWatcher, error) {
   146  	m.watchingTag = agentTag
   147  	return m.watcher, nil
   148  }