package log import ( e "errors" "testing" "math/rand" ) // Extends the default environment configuration-provider to set the level to // "debug" (so none of our messages get filtered). type testConfigurationProvider struct { levelName LogLevelName } func newTestConfigurationProvider(levelName LogLevelName) ConfigurationProvider { if levelName == "" { levelName = levelNameError } return &testConfigurationProvider{ levelName: levelName, } } func (ec *testConfigurationProvider) Format() string { return "" } func (ec *testConfigurationProvider) DefaultAdapterName() string { return "" } func (ec *testConfigurationProvider) LevelName() LogLevelName { return ec.levelName } func (ec *testConfigurationProvider) IncludeNouns() string { return "" } func (ec *testConfigurationProvider) ExcludeNouns() string { return "" } func (ec *testConfigurationProvider) ExcludeBypassLevelName() LogLevelName { return "" } // A test logging-adapter that sets flags as certain messages are received. type testLogAdapter struct { id int debugTriggered bool infoTriggered bool warningTriggered bool errorTriggered bool } func newTestLogAdapter() LogAdapter { return &testLogAdapter{ id: rand.Int(), } } func (tla *testLogAdapter) Debugf(lc *LogContext, message *string) error { tla.debugTriggered = true return nil } func (tla *testLogAdapter) Infof(lc *LogContext, message *string) error { tla.infoTriggered = true return nil } func (tla *testLogAdapter) Warningf(lc *LogContext, message *string) error { tla.warningTriggered = true return nil } func (tla *testLogAdapter) Errorf(lc *LogContext, message *string) error { tla.errorTriggered = true return nil } // Tests func TestConfigurationOverride(t *testing.T) { cs := getConfigState() defer func() { setConfigState(cs) }() levelName = "xyz" // Overwrite configuration, first thing. tcp := newTestConfigurationProvider(levelNameDebug) LoadConfiguration(tcp) if levelName != levelNameDebug { t.Fatalf("The test configuration-provider didn't override the level properly: [%s]", levelName) } } func TestConfigurationLevelDirectOverride(t *testing.T) { // Overwrite configuration, first thing. tcp := newTestConfigurationProvider("") LoadConfiguration(tcp) ClearAdapters() tla1 := newTestLogAdapter() AddAdapter("test", tla1) l := NewLoggerWithAdapterName("logTest", "test") // Usually we don't configure until the first message. Force it. l.doConfigure(false) tla2 := l.Adapter().(*testLogAdapter) if tla2.debugTriggered != false { t.Fatalf("Debug flag should've been FALSE initially but wasn't.") } // Set the level high to prevent logging, first. levelName = levelNameError // Force a reconfig (which will bring in the new level). l.doConfigure(true) // Re-retrieve. This is reconstructed during reconfiguration. tla3 := l.Adapter().(*testLogAdapter) l.Debugf(nil, "Debug message") if tla3.debugTriggered != false { t.Fatalf("Debug message not through but wasn't supposed to.") } // Now, set the level low to allow logging. levelName = levelNameDebug // Force a reconfig (which will bring in the new level). l.doConfigure(true) // Re-retrieve. This is reconstructed during reconfiguration. tla4 := l.Adapter().(*testLogAdapter) l.Debugf(nil, "Debug message") if tla4.debugTriggered == false { t.Fatalf("Debug message not getting through.") } } func TestConfigurationLevelProviderOverride(t *testing.T) { cs := getConfigState() defer func() { setConfigState(cs) }() // Overwrite configuration, first thing. tcp := newTestConfigurationProvider("") LoadConfiguration(tcp) ClearAdapters() tla1 := newTestLogAdapter() AddAdapter("test", tla1) l := NewLoggerWithAdapterName("logTest", "test") // Usually we don't configure until the first message. Force it. l.doConfigure(false) tla2 := l.Adapter().(*testLogAdapter) if tla2.debugTriggered != false { t.Fatalf("Debug flag should've been FALSE initially but wasn't.") } // Set the level high to prevent logging, first. tcp = newTestConfigurationProvider(levelNameError) LoadConfiguration(tcp) // Force a reconfig (which will bring in the new level). l.doConfigure(true) // Re-retrieve. This is reconstructed during reconfiguration. tla3 := l.Adapter().(*testLogAdapter) l.Debugf(nil, "Debug message") if tla3.debugTriggered != false { t.Fatalf("Debug message not through but wasn't supposed to.") } // Now, set the level low to allow logging. tcp = newTestConfigurationProvider(levelNameDebug) LoadConfiguration(tcp) // Force a reconfig (which will bring in the new level). l.doConfigure(true) // Re-retrieve. This is reconstructed during reconfiguration. tla4 := l.Adapter().(*testLogAdapter) l.Debugf(nil, "Debug message") if tla4.debugTriggered == false { t.Fatalf("Debug message not getting through.") } } func TestDefaultAdapterAssignment(t *testing.T) { SetDefaultAdapterName("") ClearAdapters() tla := newTestLogAdapter() AddAdapter("test1", tla) an := GetDefaultAdapterName() if an == "" { t.Fatalf("Default adapter not set after registration.") } an = GetDefaultAdapterName() if an != "test1" { t.Fatalf("Default adapter not set to our adapter after registration: [%v]", an) } SetDefaultAdapterName("test2") an = GetDefaultAdapterName() if an != "test2" { t.Fatalf("SetDefaultAdapterName() did not set default adapter correctly: [%v]", an) } } func TestAdapter(t *testing.T) { cs := getConfigState() defer func() { setConfigState(cs) }() // Overwrite configuration, first thing. tcp := newTestConfigurationProvider(levelNameDebug) LoadConfiguration(tcp) ClearAdapters() tla1 := newTestLogAdapter() AddAdapter("test", tla1) l := NewLoggerWithAdapterName("logTest", "test") l.doConfigure(false) tla2 := l.Adapter().(*testLogAdapter) l.Debugf(nil, "Debug message") if tla2.debugTriggered == false { t.Fatalf("Debug message not getting through.") } l.Infof(nil, "Info message") if tla2.infoTriggered == false { t.Fatalf("Info message not getting through.") } l.Warningf(nil, "Warning message") if tla2.warningTriggered == false { t.Fatalf("Warning message not getting through.") } err := e.New("an error happened") l.Errorf(nil, err, "Error message") if tla2.errorTriggered == false { t.Fatalf("Error message not getting through.") } } func TestStaticConfiguration(t *testing.T) { scp := NewStaticConfigurationProvider() cs := getConfigState() defer func() { setConfigState(cs) }() scp.SetFormat("aa") scp.SetDefaultAdapterName("bb") scp.SetLevelName("cc") scp.SetIncludeNouns("dd") scp.SetExcludeNouns("ee") scp.SetExcludeBypassLevelName("ff") LoadConfiguration(scp) if format != "aa" { t.Fatalf("Static configuration provider was not set correctly: format") } if defaultAdapterName != "bb" { t.Fatalf("Static configuration provider was not set correctly: defaultAdapterName") } if levelName != "cc" { t.Fatalf("Static configuration provider was not set correctly: levelName") } if includeNouns != "dd" { t.Fatalf("Static configuration provider was not set correctly: includeNouns") } if excludeNouns != "ee" { t.Fatalf("Static configuration provider was not set correctly: excludeNouns") } if excludeBypassLevelName != "ff" { t.Fatalf("Static configuration provider was not set correctly: excludeBypassLevelName") } } func TestNoAdapter(t *testing.T) { ClearAdapters() l := NewLogger("logTest") if l.Adapter() != nil { t.Fatalf("Logger has an adapter at init when no adapters were available.") } l.doConfigure(false) if l.Adapter() != nil { t.Fatalf("Logger has an adapter after configuration no adapters were available.") } // Should execute, but nothing will happen. err := e.New("an error happened") l.Errorf(nil, err, "Error message") } func TestNewLogger(t *testing.T) { noun := "logTest" l := NewLogger(noun) if l.noun != noun { t.Fatalf("Noun not correct: [%s]", l.noun) } } func TestNewLoggerWithAdapterName(t *testing.T) { noun := "logTest" originalDefaultAdapterName := GetDefaultAdapterName() adapterName := "abcdef" cla := NewConsoleLogAdapter() AddAdapter(adapterName, cla) SetDefaultAdapterName(adapterName) defer func() { SetDefaultAdapterName(originalDefaultAdapterName) delete(adapters, adapterName) }() l := NewLoggerWithAdapterName(noun, adapterName) if l.noun != noun { t.Fatalf("Noun not correct: [%s]", l.noun) } else if l.an != adapterName { t.Fatalf("Adapter-name not correct: [%s]", l.an) } } func TestIs__unwrapped__hit(t *testing.T) { e1 := e.New("test error") if Is(e1, e1) != true { t.Fatalf("Is() should be true for an unwrapped success") } } func TestIs__unwrapped__miss(t *testing.T) { e1 := e.New("test error") e2 := e.New("test error 2") if Is(e1, e2) != false { t.Fatalf("Is() should be false for an unwrapped failure") } } func TestIs__wrapped__hit(t *testing.T) { e2 := e.New("test error") e1 := Wrap(e2) if Is(e1, e2) != true { t.Fatalf("Is() should be true for a wrapped success") } } func TestIs__wrapped__miss(t *testing.T) { e1 := Errorf("test error") e2 := e.New("test error 2") if Is(e1, e2) != false { t.Fatalf("Is() should be false for a wrapped failure") } }