blob: 381c292143f07e3c3d2c7dfcb334bf57e063dfb9 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package logger
import (
"bytes"
"context"
"fmt"
"os"
"reflect"
"regexp"
"sort"
"testing"
"go.fuchsia.dev/fuchsia/tools/lib/color"
)
func TestWithContext(t *testing.T) {
logger := NewLogger(DebugLevel, color.NewColor(color.ColorAuto), os.Stdout, os.Stderr, "")
ctx := context.Background()
if v, ok := ctx.Value(globalLoggerKeyType{}).(*Logger); ok || v != nil {
t.Fatalf("Default context should not have globalLoggerKeyType. Expected: \nnil\n but got: \n%+v ", v)
}
ctx = WithLogger(ctx, logger)
if v, ok := ctx.Value(globalLoggerKeyType{}).(*Logger); !ok || v == nil {
t.Fatalf("Updated context should have globalLoggerKeyType, but got nil")
}
}
func TestNewLogger(t *testing.T) {
prefix := "testprefix "
logger := NewLogger(InfoLevel, color.NewColor(color.ColorAuto), nil, nil, prefix)
logFlags, errFlags := logger.goLogger.Flags(), logger.goErrorLogger.Flags()
correctFlags := (Ldate | Lmicroseconds)
if logFlags != correctFlags || errFlags != correctFlags {
t.Fatalf("New loggers should have the proper flags set for both standard and error logging. Expected: \n%+v and %+v\n but got: \n%+v and %+v", correctFlags, correctFlags, logFlags, errFlags)
}
logPrefix := logger.prefix
if logPrefix != prefix {
t.Fatalf("New loggers should use the specified prefix on creation. Expected: \n%+v\n but got: \n%+v", prefix, logPrefix)
}
}
func TestNewLoggerSetFlags(t *testing.T) {
flags := Ldate | Lshortfile
logger := NewLogger(InfoLevel, color.NewColor(color.ColorAuto), nil, nil, "")
logger.SetFlags(flags)
logFlags, errFlags := logger.goLogger.Flags(), logger.goErrorLogger.Flags()
if logFlags != flags || errFlags != flags {
t.Fatalf("Loggers should have the flags passed into `SetFlags`. Expected: \n%+v and %+v\n but got: \n%+v and %+v", flags, flags, logFlags, errFlags)
}
}
func TestLogLevel(t *testing.T) {
level := InfoLevel
if level.String() != "info" {
t.Errorf("InfoLevel.String() should return %q, got %q", "info", level.String())
}
level.Set("debug")
if level != DebugLevel {
t.Errorf("LogLevel.Set() should change the level's value, but value is still %q", level.String())
}
}
func TestCallDepth(t *testing.T) {
prefix := "cdprefix "
infoLog, errLog := "Info log", "Error log"
outBuffer, errBuffer := new(bytes.Buffer), new(bytes.Buffer)
logger := NewLogger(DebugLevel, color.NewColor(color.ColorAuto), outBuffer, errBuffer, prefix)
logger.SetFlags(Ldate | Lshortfile)
logger.Infof(infoLog)
logger.Errorf(errLog)
outBytes, errBytes := outBuffer.Bytes(), errBuffer.Bytes()
matched, err := regexp.Match(
fmt.Sprintf(`\d{4}\/\d{2}\/\d{2} logger_test.go:\d+: %s%s`, prefix, infoLog),
outBytes)
if err != nil || !matched {
t.Fatalf("Stdout output was not as expected. Got: %s", outBytes)
}
matched, err = regexp.Match(
fmt.Sprintf(`\d{4}\/\d{2}\/\d{2} logger_test.go:\d+: %s%s%s`, prefix, regexp.QuoteMeta(logger.color.Red("ERROR: ")), errLog),
errBytes)
if err != nil || !matched {
t.Fatalf("Stderr output was not as expected. Got: %s", errBytes)
}
}
type counterPrefixer struct {
counter int
}
func (p *counterPrefixer) String() string {
p.counter++
return fmt.Sprintf("%d ", p.counter)
}
func TestCustomPrefix(t *testing.T) {
infoLog, errLog := "Info log", "Error log"
outBuffer, errBuffer := new(bytes.Buffer), new(bytes.Buffer)
logger := NewLogger(DebugLevel, color.NewColor(color.ColorAuto), outBuffer, errBuffer, &counterPrefixer{})
logger.SetFlags(Ldate | Lshortfile)
logger.Infof(infoLog)
logger.Errorf(errLog)
outBytes, errBytes := outBuffer.Bytes(), errBuffer.Bytes()
matched, err := regexp.Match(
fmt.Sprintf(`\d{4}\/\d{2}\/\d{2} logger_test.go:\d+: 1 %s`, infoLog),
outBytes)
if err != nil || !matched {
t.Fatalf("Stdout output was not as expected. Got: %s", outBytes)
}
matched, err = regexp.Match(
fmt.Sprintf(`\d{4}\/\d{2}\/\d{2} logger_test.go:\d+: 2 %s%s`, regexp.QuoteMeta(logger.color.Red("ERROR: ")), errLog),
errBytes)
if err != nil || !matched {
t.Fatalf("Stderr output was not as expected. Got: %s", errBytes)
}
}
func TestAllLevels(t *testing.T) {
allLevels := AllLevels()
if len(allLevels) != len(levelToName) {
t.Fatalf("len(allLevels) = %d, want %d", len(allLevels), len(levelToName))
}
levelToNameViaAllLevels := make(map[LogLevel]string)
for _, level := range allLevels {
levelToNameViaAllLevels[level] = level.String()
}
if !reflect.DeepEqual(levelToNameViaAllLevels, levelToName) {
t.Fatalf("levelToNameViaAllLevels = %#v, want %#v", levelToNameViaAllLevels, levelToName)
}
if !sort.SliceIsSorted(allLevels, func(i, j int) bool { return allLevels[i] < allLevels[j] }) {
t.Fatalf("expected allLevels to be sorted; allLevels = %#v", allLevels)
}
}