github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/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.Entry{ 59 Level: loggo.Level(i), 60 Module: fmt.Sprintf("module%d", i), 61 Filename: fmt.Sprintf("filename%d", i), 62 Line: i, 63 Timestamp: now.Add(time.Duration(i)), 64 Message: fmt.Sprintf("message%d", i), 65 }) 66 } 67 68 for i := 0; i < numMessages; i++ { 69 c.Assert(*s.receiveOne(c), gc.DeepEquals, logsender.LogRecord{ 70 Time: now.Add(time.Duration(i)), 71 Module: fmt.Sprintf("module%d", i), 72 Location: fmt.Sprintf("filename%d:%d", i, i), 73 Level: loggo.Level(i), 74 Message: fmt.Sprintf("message%d", i), 75 }) 76 } 77 } 78 79 func (s *bufferedLogWriterSuite) TestLimiting(c *gc.C) { 80 write := func(msgNum int) { 81 s.writer.Write( 82 loggo.Entry{ 83 Level: loggo.INFO, 84 Module: "module", 85 Filename: "filename", 86 Line: 42, 87 Timestamp: time.Now(), 88 Message: fmt.Sprintf("log%d", msgNum), 89 }) 90 } 91 92 expect := func(msgNum, dropped int) { 93 rec := s.receiveOne(c) 94 c.Assert(rec.Message, gc.Equals, fmt.Sprintf("log%d", msgNum)) 95 c.Assert(rec.DroppedAfter, gc.Equals, dropped) 96 } 97 98 // Write more logs than the buffer allows. 99 for i := 0; i < maxLen+3; i++ { 100 write(i) 101 } 102 103 // Read some logs from the writer. 104 105 // Even though logs have been dropped, log 0 is still seen 106 // first. This is useful because means the time range for dropped 107 // logs can be observed. 108 expect(0, 2) // logs 1 and 2 dropped here 109 expect(3, 0) 110 expect(4, 0) 111 112 // Now write more logs, again exceeding the limit. 113 for i := maxLen + 3; i < maxLen+3+maxLen; i++ { 114 write(i) 115 } 116 117 // Read all the remaining logs off. 118 expect(5, 3) // logs 6, 7 and 8 logs dropped here 119 for i := 9; i < maxLen+3+maxLen; i++ { 120 expect(i, 0) 121 } 122 } 123 124 func (s *bufferedLogWriterSuite) TestClose(c *gc.C) { 125 s.writer.Close() 126 s.shouldClose = false // Prevent the usual teardown (calling Close twice will panic) 127 128 // Output channel closing means the bufferedLogWriterSuite loop 129 // has finished. 130 select { 131 case _, ok := <-s.writer.Logs(): 132 c.Assert(ok, jc.IsFalse) 133 case <-time.After(coretesting.LongWait): 134 c.Fatal("timed out waiting for output channel to close") 135 } 136 137 // Further Write attempts should fail. 138 c.Assert(func() { s.writeAndReceive(c) }, gc.PanicMatches, ".*send on closed channel") 139 } 140 141 func (s *bufferedLogWriterSuite) TestInstallBufferedLogWriter(c *gc.C) { 142 logsCh, err := logsender.InstallBufferedLogWriter(10) 143 c.Assert(err, jc.ErrorIsNil) 144 defer logsender.UninstallBufferedLogWriter() 145 146 logger := loggo.GetLogger("bufferedLogWriter-test") 147 148 for i := 0; i < 5; i++ { 149 logger.Infof("%d", i) 150 } 151 152 for i := 0; i < 5; i++ { 153 select { 154 case rec := <-logsCh: 155 c.Assert(rec.Message, gc.Equals, strconv.Itoa(i)) 156 case <-time.After(coretesting.LongWait): 157 c.Fatal("timed out waiting for logs") 158 } 159 } 160 } 161 162 func (s *bufferedLogWriterSuite) TestUninstallBufferedLogWriter(c *gc.C) { 163 _, err := logsender.InstallBufferedLogWriter(10) 164 c.Assert(err, jc.ErrorIsNil) 165 166 err = logsender.UninstallBufferedLogWriter() 167 c.Assert(err, jc.ErrorIsNil) 168 169 // Second uninstall attempt should fail 170 err = logsender.UninstallBufferedLogWriter() 171 c.Assert(err, gc.ErrorMatches, "failed to uninstall log buffering: .+") 172 } 173 174 func (s *bufferedLogWriterSuite) writeAndReceive(c *gc.C) { 175 now := time.Now() 176 s.writer.Write( 177 loggo.Entry{ 178 Level: loggo.INFO, 179 Module: "module", 180 Filename: "filename", 181 Line: 99, 182 Timestamp: now, 183 Message: "message", 184 }) 185 c.Assert(*s.receiveOne(c), gc.DeepEquals, logsender.LogRecord{ 186 Time: now, 187 Module: "module", 188 Location: "filename:99", 189 Level: loggo.INFO, 190 Message: "message", 191 }) 192 } 193 194 func (s *bufferedLogWriterSuite) receiveOne(c *gc.C) *logsender.LogRecord { 195 select { 196 case rec := <-s.writer.Logs(): 197 return rec 198 case <-time.After(coretesting.LongWait): 199 c.Fatal("timed out waiting for log record") 200 } 201 panic("should never get here") 202 }