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 }