github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/worker/syslogger/worker_test.go (about) 1 // Copyright 2022 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package syslogger_test 5 6 import ( 7 "bytes" 8 "fmt" 9 "io" 10 "strings" 11 "time" 12 13 "github.com/juju/testing" 14 "go.uber.org/mock/gomock" 15 gc "gopkg.in/check.v1" 16 17 corelogger "github.com/juju/juju/core/logger" 18 coretesting "github.com/juju/juju/testing" 19 "github.com/juju/juju/worker/syslogger" 20 ) 21 22 type WorkerSuite struct { 23 stub testing.Stub 24 } 25 26 var _ = gc.Suite(&WorkerSuite{}) 27 28 func (s *WorkerSuite) SetUpTest(c *gc.C) { 29 s.stub.ResetCalls() 30 } 31 32 func (s *WorkerSuite) TestLogCreation(c *gc.C) { 33 _, err := syslogger.NewWorker(syslogger.WorkerConfig{ 34 NewLogger: func(priority syslogger.Priority, tag string) (io.WriteCloser, error) { 35 s.stub.MethodCall(s, "NewLogger", priority, tag) 36 return nil, nil 37 }, 38 }) 39 c.Assert(err, gc.IsNil) 40 s.stub.CheckCallNames(c, strings.Split(strings.Repeat("NewLogger,", 7), ",")[:7]...) 41 for _, call := range s.stub.Calls() { 42 arg := call.Args[0].(syslogger.Priority) 43 c.Assert(arg >= syslogger.LOG_CRIT && arg <= syslogger.LOG_DEBUG, gc.Equals, true) 44 } 45 } 46 47 func (s *WorkerSuite) TestLog(c *gc.C) { 48 now := time.Now() 49 buf := new(bytes.Buffer) 50 w, err := syslogger.NewWorker(syslogger.WorkerConfig{ 51 NewLogger: func(priority syslogger.Priority, tag string) (io.WriteCloser, error) { 52 return closer{buf}, nil 53 }, 54 }) 55 c.Assert(err, gc.IsNil) 56 wrk := w.(syslogger.SysLogger) 57 err = wrk.Log([]corelogger.LogRecord{{ 58 Time: now, 59 Entity: "foo", 60 Module: "bar", 61 Message: "baz", 62 ModelUUID: coretesting.ModelTag.Id(), 63 }}) 64 c.Assert(err, gc.IsNil) 65 66 dateTime := now.In(time.UTC).Format("2006-01-02 15:04:05") 67 c.Assert(buf.String(), gc.Equals, fmt.Sprintf("%s foo bar.deadbe baz\n", dateTime)) 68 } 69 70 func (s *WorkerSuite) TestClosingLogBeforeWriting(c *gc.C) { 71 ctrl := gomock.NewController(c) 72 defer ctrl.Finish() 73 74 mockWriter := syslogger.NewMockWriteCloser(ctrl) 75 mockWriter.EXPECT().Close().Times(7) 76 77 now := time.Now() 78 w, err := syslogger.NewWorker(syslogger.WorkerConfig{ 79 NewLogger: func(priority syslogger.Priority, tag string) (io.WriteCloser, error) { 80 return mockWriter, nil 81 }, 82 }) 83 c.Assert(err, gc.IsNil) 84 85 w.Kill() 86 c.Assert(w.Wait(), gc.IsNil) 87 88 wrk := w.(syslogger.SysLogger) 89 err = wrk.Log([]corelogger.LogRecord{{ 90 Time: now, 91 Entity: "foo", 92 Module: "bar", 93 Message: "baz", 94 ModelUUID: coretesting.ModelTag.Id(), 95 }}) 96 c.Assert(err, gc.IsNil) 97 } 98 99 func (s *WorkerSuite) TestClosingLogWhilstWriting(c *gc.C) { 100 ctrl := gomock.NewController(c) 101 defer ctrl.Finish() 102 103 mockWriter := syslogger.NewMockWriteCloser(ctrl) 104 mockWriter.EXPECT().Write(gomock.Any()).MinTimes(1) 105 mockWriter.EXPECT().Close().Times(7) 106 107 now := time.Now() 108 w, err := syslogger.NewWorker(syslogger.WorkerConfig{ 109 NewLogger: func(priority syslogger.Priority, tag string) (io.WriteCloser, error) { 110 return mockWriter, nil 111 }, 112 }) 113 c.Assert(err, gc.IsNil) 114 115 done := make(chan struct{}) 116 go func() { 117 c.Assert(w.Wait(), gc.IsNil) 118 close(done) 119 }() 120 go func() { 121 wrk := w.(syslogger.SysLogger) 122 for { 123 select { 124 case <-done: 125 return 126 case <-time.After(time.Millisecond): 127 err = wrk.Log([]corelogger.LogRecord{{ 128 Time: now, 129 Entity: "foo", 130 Module: "bar", 131 Message: "baz", 132 ModelUUID: coretesting.ModelTag.Id(), 133 }}) 134 c.Assert(err, gc.IsNil) 135 } 136 } 137 }() 138 go func() { 139 <-time.After(time.Millisecond * 10) 140 w.Kill() 141 }() 142 select { 143 case <-done: 144 case <-time.After(testing.ShortWait): 145 c.Fatal("failed waiting for test to complete") 146 } 147 } 148 149 type closer struct { 150 io.Writer 151 } 152 153 func (c closer) Close() error { return nil }