go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/common/logging/teelogger/teelogger_test.go (about)

     1  // Copyright 2015 The LUCI Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package teelogger
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  	"testing"
    21  
    22  	. "github.com/smartystreets/goconvey/convey"
    23  	"go.chromium.org/luci/common/logging"
    24  	"go.chromium.org/luci/common/logging/memlogger"
    25  )
    26  
    27  func TestTeeLogger(t *testing.T) {
    28  	Convey(`A new TeeLogger instance`, t, func() {
    29  		l1 := logging.Get(
    30  			memlogger.Use(context.Background())).(*memlogger.MemLogger)
    31  		l2 := logging.Get(
    32  			memlogger.Use(context.Background())).(*memlogger.MemLogger)
    33  		l3 := logging.Get(
    34  			memlogger.Use(context.Background())).(*memlogger.MemLogger)
    35  		factories := []logging.Factory{
    36  			func(_ context.Context) logging.Logger { return l1 },
    37  			func(_ context.Context) logging.Logger { return l2 },
    38  			func(_ context.Context) logging.Logger { return l3 },
    39  		}
    40  		Convey("Set level Debug", func() {
    41  			ctx := Use(context.Background(), factories...)
    42  			ctx = logging.SetLevel(ctx, logging.Debug)
    43  			teeLog := logging.Get(ctx)
    44  			for _, entry := range []struct {
    45  				L logging.Level
    46  				F func(string, ...any)
    47  				T string
    48  			}{
    49  				{logging.Debug, teeLog.Debugf, "DEBU"},
    50  				{logging.Info, teeLog.Infof, "INFO"},
    51  				{logging.Warning, teeLog.Warningf, "WARN"},
    52  				{logging.Error, teeLog.Errorf, "ERRO"},
    53  			} {
    54  				Convey(fmt.Sprintf("Can log to %s", entry.L), func() {
    55  					entry.F("%s", entry.T)
    56  					for _, logger := range []*memlogger.MemLogger{l1, l2, l3} {
    57  						So(len(logger.Messages()), ShouldEqual, 1)
    58  						msg := logger.Get(entry.L, entry.T, map[string]any(nil))
    59  						So(msg, ShouldNotBeNil)
    60  						So(msg.CallDepth, ShouldEqual, 3)
    61  					}
    62  				})
    63  			}
    64  		})
    65  		Convey("Set level as Warning", func() {
    66  			ctx := Use(context.Background(), factories...)
    67  			ctx = logging.SetLevel(ctx, logging.Warning)
    68  			teeLog := logging.Get(ctx)
    69  			for _, entry := range []struct {
    70  				L logging.Level
    71  				F func(string, ...any)
    72  				T string
    73  				E bool
    74  			}{
    75  				{logging.Debug, teeLog.Debugf, "DEBU", false},
    76  				{logging.Info, teeLog.Infof, "INFO", false},
    77  				{logging.Warning, teeLog.Warningf, "WARN", true},
    78  				{logging.Error, teeLog.Errorf, "ERRO", true},
    79  			} {
    80  				Convey(fmt.Sprintf("Can log to %s", entry.L), func() {
    81  					entry.F("%s", entry.T)
    82  					for _, logger := range []*memlogger.MemLogger{l1, l2, l3} {
    83  						if entry.E {
    84  							So(len(logger.Messages()), ShouldEqual, 1)
    85  							msg := logger.Get(entry.L, entry.T, map[string]any(nil))
    86  							So(msg, ShouldNotBeNil)
    87  							So(msg.CallDepth, ShouldEqual, 3)
    88  						} else {
    89  							So(len(logger.Messages()), ShouldEqual, 0)
    90  						}
    91  					}
    92  				})
    93  			}
    94  		})
    95  		Convey("Uses context logger", func() {
    96  			ctx := memlogger.Use(context.Background())
    97  			logger := logging.Get(ctx).(*memlogger.MemLogger)
    98  
    99  			teeCtx := Use(ctx)
   100  			logging.Get(teeCtx).Infof("Testing 1 2")
   101  			messages := logger.Messages()
   102  
   103  			// Make sure context logger doesn't get called
   104  			So(len(messages), ShouldEqual, 1)
   105  			msg := messages[0]
   106  			So(msg.CallDepth, ShouldEqual, 3)
   107  			So(msg.Msg, ShouldEqual, "Testing 1 2")
   108  		})
   109  	})
   110  }
   111  
   112  func TestTeeFilteredLogger(t *testing.T) {
   113  	Convey(`A new TeeLogger instance`, t, func() {
   114  		lD := logging.Get(memlogger.Use(context.Background())).(*memlogger.MemLogger)
   115  		lI := logging.Get(memlogger.Use(context.Background())).(*memlogger.MemLogger)
   116  		lW := logging.Get(memlogger.Use(context.Background())).(*memlogger.MemLogger)
   117  		lE := logging.Get(memlogger.Use(context.Background())).(*memlogger.MemLogger)
   118  		makeFactory := func(l logging.Logger) logging.Factory {
   119  			return func(_ context.Context) logging.Logger { return l }
   120  		}
   121  		filtereds := []Filtered{
   122  			{makeFactory(lD), logging.Debug},
   123  			{makeFactory(lI), logging.Info},
   124  			{makeFactory(lW), logging.Warning},
   125  			{makeFactory(lE), logging.Error},
   126  		}
   127  		ctx := UseFiltered(context.Background(), filtereds...)
   128  		// The context level is ignored, even we set it.
   129  		ctx = logging.SetLevel(ctx, logging.Error)
   130  		teeLog := logging.Get(ctx)
   131  
   132  		for _, entry := range []struct {
   133  			L logging.Level
   134  			F func(string, ...any)
   135  			T string
   136  			// Loggers which have messages.
   137  			GoodLogger []*memlogger.MemLogger
   138  			// Loggers which do not have messages.
   139  			BadLogger []*memlogger.MemLogger
   140  		}{
   141  			{logging.Debug, teeLog.Debugf, "DEBU",
   142  				[]*memlogger.MemLogger{lD},
   143  				[]*memlogger.MemLogger{lI, lW, lE}},
   144  			{logging.Info, teeLog.Infof, "INFO",
   145  				[]*memlogger.MemLogger{lD, lI},
   146  				[]*memlogger.MemLogger{lW, lE}},
   147  			{logging.Warning, teeLog.Warningf, "WARN",
   148  				[]*memlogger.MemLogger{lD, lI, lW},
   149  				[]*memlogger.MemLogger{lE}},
   150  			{logging.Error, teeLog.Errorf, "ERRO",
   151  				[]*memlogger.MemLogger{lD, lI, lW, lE},
   152  				[]*memlogger.MemLogger{}},
   153  		} {
   154  			Convey(fmt.Sprintf("Can log to %s", entry.L), func() {
   155  				entry.F("%s", entry.T)
   156  				for _, l := range entry.GoodLogger {
   157  					So(len(l.Messages()), ShouldEqual, 1)
   158  					msg := l.Get(entry.L, entry.T, map[string]any(nil))
   159  					So(msg, ShouldNotBeNil)
   160  					So(msg.CallDepth, ShouldEqual, 3)
   161  				}
   162  				for _, l := range entry.BadLogger {
   163  					So(len(l.Messages()), ShouldEqual, 0)
   164  				}
   165  			})
   166  		}
   167  		Convey("Use context logger with context level Debug", func() {
   168  			ctx := memlogger.Use(context.Background())
   169  			logger := logging.Get(ctx).(*memlogger.MemLogger)
   170  
   171  			teeCtx := UseFiltered(ctx)
   172  			teeCtx = logging.SetLevel(teeCtx, logging.Debug)
   173  			l := logging.Get(teeCtx)
   174  			So(l, ShouldNotBeNil)
   175  			l.Infof("Info testing 1 2")
   176  			messages := logger.Messages()
   177  
   178  			// Make sure context logger doesn't get called
   179  			So(len(messages), ShouldEqual, 1)
   180  			msg := messages[0]
   181  			So(msg.CallDepth, ShouldEqual, 3)
   182  			So(msg.Msg, ShouldEqual, "Info testing 1 2")
   183  		})
   184  		Convey("Use context logger with context level Warning", func() {
   185  			ctx := memlogger.Use(context.Background())
   186  			logger := logging.Get(ctx).(*memlogger.MemLogger)
   187  
   188  			teeCtx := UseFiltered(ctx)
   189  			teeCtx = logging.SetLevel(teeCtx, logging.Warning)
   190  			logging.Get(teeCtx).Infof("Info testing 1 2")
   191  			messages := logger.Messages()
   192  
   193  			// Make sure context logger doesn't have messages
   194  			So(len(messages), ShouldEqual, 0)
   195  		})
   196  	})
   197  }