github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/pkg/log/configure_test.go (about) 1 package log_test 2 3 import ( 4 "bytes" 5 "context" 6 "os" 7 "sync" 8 "testing" 9 10 "github.com/kyma-incubator/compass/components/director/pkg/log" 11 "github.com/sirupsen/logrus" 12 "github.com/stretchr/testify/require" 13 ) 14 15 // TestMultipleGoroutinesDefaultLog validates that no race conditions occur when two go routines log using the default log 16 func TestMultipleGoroutinesDefaultLog(t *testing.T) { 17 _, err := log.Configure(context.TODO(), log.DefaultConfig()) 18 require.NoError(t, err) 19 wg := sync.WaitGroup{} 20 wg.Add(2) 21 go func() { 22 defer wg.Done() 23 log.D().Debug("message") 24 }() 25 go func() { 26 defer wg.Done() 27 log.D().Debug("message") 28 }() 29 wg.Wait() 30 } 31 32 // TestMultipleGoroutinesContextLog validates that no race conditions occur when two go routines log using the context log 33 func TestMultipleGoroutinesContextLog(t *testing.T) { 34 ctx, err := log.Configure(context.TODO(), log.DefaultConfig()) 35 require.NoError(t, err) 36 wg := sync.WaitGroup{} 37 wg.Add(2) 38 go func() { 39 defer wg.Done() 40 log.C(ctx).Debug("message") 41 }() 42 go func() { 43 defer wg.Done() 44 log.C(ctx).Debug("message") 45 }() 46 wg.Wait() 47 } 48 49 // TestMultipleGoroutinesMixedLog validates that no race conditions occur when two go routines log using both context and default log 50 func TestMultipleGoroutinesMixedLog(t *testing.T) { 51 ctx, err := log.Configure(context.TODO(), log.DefaultConfig()) 52 require.NoError(t, err) 53 wg := sync.WaitGroup{} 54 wg.Add(2) 55 go func() { 56 defer wg.Done() 57 log.C(ctx).Debug("message") 58 }() 59 go func() { 60 defer wg.Done() 61 log.D().Debug("message") 62 }() 63 wg.Wait() 64 } 65 66 func TestConfigureReturnsErrorWhenConfigIsInvalid(t *testing.T) { 67 var tests = []struct { 68 Msg string 69 ConfigProvider func() *log.Config 70 }{ 71 { 72 Msg: "Invalid log level", 73 ConfigProvider: func() *log.Config { 74 config := log.DefaultConfig() 75 config.Level = "invalid" 76 return config 77 }, 78 }, 79 { 80 Msg: "Missing Log Format", 81 ConfigProvider: func() *log.Config { 82 config := log.DefaultConfig() 83 config.Format = "" 84 return config 85 }, 86 }, 87 { 88 Msg: "Unsupported log format", 89 ConfigProvider: func() *log.Config { 90 config := log.DefaultConfig() 91 config.Format = "invalid" 92 return config 93 }, 94 }, 95 { 96 Msg: "Missing Output", 97 ConfigProvider: func() *log.Config { 98 config := log.DefaultConfig() 99 config.Output = "" 100 return config 101 }, 102 }, 103 { 104 Msg: "Unsupported output", 105 ConfigProvider: func() *log.Config { 106 config := log.DefaultConfig() 107 config.Output = "invalid" 108 return config 109 }, 110 }, 111 { 112 Msg: "Missing Bootstrap Correlation ID", 113 ConfigProvider: func() *log.Config { 114 config := log.DefaultConfig() 115 config.BootstrapCorrelationID = "" 116 return config 117 }, 118 }, 119 } 120 121 for _, test := range tests { 122 t.Run(test.Msg, func(t *testing.T) { 123 previousConfig := log.Configuration() 124 _, err := log.Configure(context.TODO(), test.ConfigProvider()) 125 require.Error(t, err) 126 currentConfig := log.Configuration() 127 require.Equal(t, previousConfig, currentConfig) 128 }) 129 } 130 } 131 132 func TestDefaultLoggerConfiguration(t *testing.T) { 133 config := log.DefaultConfig() 134 config.Level = "trace" 135 ctx, err := log.Configure(context.TODO(), config) 136 require.NoError(t, err) 137 require.Equal(t, log.C(ctx).Level, log.D().Level) 138 } 139 140 func TestConfigureFormat(t *testing.T) { 141 var tests = []struct { 142 Msg string 143 ConfigProvider func() *log.Config 144 ExpectedOutput []string 145 }{ 146 { 147 Msg: "text", 148 ConfigProvider: func() *log.Config { 149 config := log.DefaultConfig() 150 config.Format = "text" 151 return config 152 }, 153 ExpectedOutput: []string{"msg=Test"}, 154 }, 155 { 156 Msg: "json", 157 ConfigProvider: func() *log.Config { 158 config := log.DefaultConfig() 159 config.Format = "json" 160 return config 161 }, 162 ExpectedOutput: []string{"\"msg\":\"Test\""}, 163 }, 164 } 165 166 for _, test := range tests { 167 t.Run(test.Msg, func(t *testing.T) { 168 w := &bytes.Buffer{} 169 ctx, err := log.Configure(context.TODO(), test.ConfigProvider()) 170 require.NoError(t, err) 171 entry := log.LoggerFromContext(ctx) 172 entry.Logger.SetOutput(w) 173 defer entry.Logger.SetOutput(os.Stderr) // return default output 174 entry.Info("Test") 175 for _, out := range test.ExpectedOutput { 176 require.Contains(t, w.String(), out) 177 } 178 }) 179 } 180 } 181 182 func TestRegisterFormatterAddsItIfNotExists(t *testing.T) { 183 name := "formatter_name" 184 err := log.RegisterFormatter(name, &logrus.TextFormatter{}) 185 require.NoError(t, err) 186 187 config := log.DefaultConfig() 188 config.Format = name 189 _, err = log.Configure(context.TODO(), config) 190 require.NoError(t, err) 191 } 192 193 func TestRegisterFormatterReturnsErrorForAlreadyExistingFormat(t *testing.T) { 194 name := "text" 195 err := log.RegisterFormatter(name, &logrus.TextFormatter{}) 196 require.Error(t, err) 197 } 198 199 func TestConfigureWillReconfigureDefaultLoggerEvenIfEntryAlreadyExistsInTheContext(t *testing.T) { 200 config := log.DefaultConfig() 201 ctx, err := log.Configure(context.TODO(), config) 202 require.NoError(t, err) 203 204 config.Level = "trace" 205 ctx, err = log.Configure(ctx, config) 206 require.NoError(t, err) 207 208 require.Equal(t, log.C(ctx).Level, log.D().Level) 209 }