github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/worker/logsender/bufferedlogwriter_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENSE file for details. 3 4 package logsender_test 5 6 import ( 7 "fmt" 8 "strconv" 9 "time" 10 11 "github.com/juju/loggo" 12 jc "github.com/juju/testing/checkers" 13 gc "gopkg.in/check.v1" 14 15 coretesting "github.com/juju/juju/testing" 16 "github.com/juju/juju/worker/logsender" 17 ) 18 19 const maxLen = 6 20 21 type bufferedLogWriterSuite struct { 22 coretesting.BaseSuite 23 writer *logsender.BufferedLogWriter 24 shouldClose bool 25 } 26 27 var _ = gc.Suite(&bufferedLogWriterSuite{}) 28 29 func (s *bufferedLogWriterSuite) SetUpTest(c *gc.C) { 30 s.BaseSuite.SetUpTest(c) 31 s.writer = logsender.NewBufferedLogWriter(maxLen) 32 s.shouldClose = true 33 } 34 35 func (s *bufferedLogWriterSuite) TearDownTest(c *gc.C) { 36 if s.shouldClose { 37 s.writer.Close() 38 } 39 s.BaseSuite.TearDownTest(c) 40 } 41 42 func (s *bufferedLogWriterSuite) TestOne(c *gc.C) { 43 s.writeAndReceive(c) 44 } 45 46 func (s *bufferedLogWriterSuite) TestMultiple(c *gc.C) { 47 for i := 0; i < 10; i++ { 48 s.writeAndReceive(c) 49 } 50 } 51 52 func (s *bufferedLogWriterSuite) TestBuffering(c *gc.C) { 53 // Write several log message before attempting to read them out. 54 const numMessages = 5 55 now := time.Now() 56 for i := 0; i < numMessages; i++ { 57 s.writer.Write( 58 loggo.Level(i), 59 fmt.Sprintf("module%d", i), 60 fmt.Sprintf("filename%d", i), 61 i, // line number 62 now.Add(time.Duration(i)), 63 fmt.Sprintf("message%d", i), 64 ) 65 } 66 67 for i := 0; i < numMessages; i++ { 68 c.Assert(*s.receiveOne(c), gc.DeepEquals, logsender.LogRecord{ 69 Time: now.Add(time.Duration(i)), 70 Module: fmt.Sprintf("module%d", i), 71 Location: fmt.Sprintf("filename%d:%d", i, i), 72 Level: loggo.Level(i), 73 Message: fmt.Sprintf("message%d", i), 74 }) 75 } 76 } 77 78 func (s *bufferedLogWriterSuite) TestLimiting(c *gc.C) { 79 write := func(msgNum int) { 80 s.writer.Write(loggo.INFO, "module", "filename", 42, time.Now(), fmt.Sprintf("log%d", msgNum)) 81 } 82 83 expect := func(msgNum, dropped int) { 84 rec := s.receiveOne(c) 85 c.Assert(rec.Message, gc.Equals, fmt.Sprintf("log%d", msgNum)) 86 c.Assert(rec.DroppedAfter, gc.Equals, dropped) 87 } 88 89 // Write more logs than the buffer allows. 90 for i := 0; i < maxLen+3; i++ { 91 write(i) 92 } 93 94 // Read some logs from the writer. 95 96 // Even though logs have been dropped, log 0 is still seen 97 // first. This is useful because means the time range for dropped 98 // logs can be observed. 99 expect(0, 2) // logs 1 and 2 dropped here 100 expect(3, 0) 101 expect(4, 0) 102 103 // Now write more logs, again exceeding the limit. 104 for i := maxLen + 3; i < maxLen+3+maxLen; i++ { 105 write(i) 106 } 107 108 // Read all the remaining logs off. 109 expect(5, 3) // logs 6, 7 and 8 logs dropped here 110 for i := 9; i < maxLen+3+maxLen; i++ { 111 expect(i, 0) 112 } 113 } 114 115 func (s *bufferedLogWriterSuite) TestClose(c *gc.C) { 116 s.writer.Close() 117 s.shouldClose = false // Prevent the usual teardown (calling Close twice will panic) 118 119 // Output channel closing means the bufferedLogWriterSuite loop 120 // has finished. 121 select { 122 case _, ok := <-s.writer.Logs(): 123 c.Assert(ok, jc.IsFalse) 124 case <-time.After(coretesting.LongWait): 125 c.Fatal("timed out waiting for output channel to close") 126 } 127 128 // Further Write attempts should fail. 129 c.Assert(func() { s.writeAndReceive(c) }, gc.PanicMatches, ".*send on closed channel") 130 } 131 132 func (s *bufferedLogWriterSuite) TestInstallBufferedLogWriter(c *gc.C) { 133 logsCh, err := logsender.InstallBufferedLogWriter(10) 134 c.Assert(err, jc.ErrorIsNil) 135 defer logsender.UninstallBufferedLogWriter() 136 137 logger := loggo.GetLogger("bufferedLogWriter-test") 138 139 for i := 0; i < 5; i++ { 140 logger.Infof("%d", i) 141 } 142 143 for i := 0; i < 5; i++ { 144 select { 145 case rec := <-logsCh: 146 c.Assert(rec.Message, gc.Equals, strconv.Itoa(i)) 147 case <-time.After(coretesting.LongWait): 148 c.Fatal("timed out waiting for logs") 149 } 150 } 151 } 152 153 func (s *bufferedLogWriterSuite) TestUninstallBufferedLogWriter(c *gc.C) { 154 _, err := logsender.InstallBufferedLogWriter(10) 155 c.Assert(err, jc.ErrorIsNil) 156 157 err = logsender.UninstallBufferedLogWriter() 158 c.Assert(err, jc.ErrorIsNil) 159 160 // Second uninstall attempt should fail 161 err = logsender.UninstallBufferedLogWriter() 162 c.Assert(err, gc.ErrorMatches, "failed to uninstall log buffering: .+") 163 } 164 165 func (s *bufferedLogWriterSuite) writeAndReceive(c *gc.C) { 166 now := time.Now() 167 s.writer.Write(loggo.INFO, "module", "filename", 99, now, "message") 168 c.Assert(*s.receiveOne(c), gc.DeepEquals, logsender.LogRecord{ 169 Time: now, 170 Module: "module", 171 Location: "filename:99", 172 Level: loggo.INFO, 173 Message: "message", 174 }) 175 } 176 177 func (s *bufferedLogWriterSuite) receiveOne(c *gc.C) *logsender.LogRecord { 178 select { 179 case rec := <-s.writer.Logs(): 180 return rec 181 case <-time.After(coretesting.LongWait): 182 c.Fatal("timed out waiting for log record") 183 } 184 panic("should never get here") 185 }