diff --git a/core/util/utils_test.go b/core/util/utils_test.go index 6969f8b18b0..fcac4122751 100644 --- a/core/util/utils_test.go +++ b/core/util/utils_test.go @@ -21,6 +21,8 @@ import ( "strings" "testing" "time" + + "github.com/op/go-logging" ) func TestComputeCryptoHash(t *testing.T) { @@ -98,3 +100,21 @@ func TestFindMissingElements(t *testing.T) { } } } + +// This test checks go-logging is thread safe with regard to +// concurrent SetLevel invocation and log invocations. +// Fails without the concurrency fix (adding RWLock to level.go) +// In case the go-logging will be overwritten and its concurrency fix +// will be regressed, this test should fail. +func TestConcurrencyNotFail(t *testing.T) { + logger := logging.MustGetLogger("test") + go func() { + for i := 0; i < 100; i++ { + logging.SetLevel(logging.Level(logging.DEBUG), "test") + } + }() + + for i := 0; i < 100; i++ { + logger.Info("") + } +} diff --git a/vendor/github.com/op/go-logging/level.go b/vendor/github.com/op/go-logging/level.go index 98dd191873a..402178c03af 100644 --- a/vendor/github.com/op/go-logging/level.go +++ b/vendor/github.com/op/go-logging/level.go @@ -66,6 +66,7 @@ type LeveledBackend interface { } type moduleLeveled struct { + sync.RWMutex levels map[string]Level backend Backend formatter Formatter @@ -88,6 +89,8 @@ func AddModuleLevel(backend Backend) LeveledBackend { // GetLevel returns the log level for the given module. func (l *moduleLeveled) GetLevel(module string) Level { + l.RLock() + defer l.RUnlock() level, exists := l.levels[module] if exists == false { level, exists = l.levels[""] @@ -101,6 +104,8 @@ func (l *moduleLeveled) GetLevel(module string) Level { // SetLevel sets the log level for the given module. func (l *moduleLeveled) SetLevel(level Level, module string) { + l.Lock() + defer l.Unlock() l.levels[module] = level }