Fix logging tests

Signed-off-by: Steffen Vogel <post@steffenvogel.de>
This commit is contained in:
Steffen Vogel
2023-06-21 08:56:09 +02:00
parent 8e4961e1f7
commit c8e5858314
28 changed files with 250 additions and 186 deletions

View File

@@ -27,12 +27,11 @@ import (
)
func TestSuite(t *testing.T) {
test.SetupLogging()
RegisterFailHandler(Fail)
RunSpecs(t, "Config Suite")
}
var _ = test.SetupLogging()
var _ = Context("config", func() {
mkTempFile := func(contents string) *os.File {
dir := GinkgoT().TempDir()

View File

@@ -14,12 +14,11 @@ import (
)
func TestSuite(t *testing.T) {
test.SetupLogging()
RegisterFailHandler(Fail)
RunSpecs(t, "Crypto Suite")
}
var _ = test.SetupLogging()
var _ = Describe("nonce", func() {
It("can generate a valid nonce", func() {
nonce, err := crypto.GetNonce(100)

View File

@@ -14,12 +14,11 @@ import (
)
func TestSuite(t *testing.T) {
test.SetupLogging()
RegisterFailHandler(Fail)
RunSpecs(t, "Watcher Suite")
}
var _ = test.SetupLogging()
var _ = BeforeSuite(func() {
if !osx.HasAdminPrivileges() {
Skip("Insufficient privileges")

View File

@@ -14,12 +14,11 @@ import (
)
func TestSuite(t *testing.T) {
test.SetupLogging()
RegisterFailHandler(Fail)
RunSpecs(t, "Device Suite")
}
var _ = test.SetupLogging()
var _ = BeforeSuite(func() {
if !osx.HasAdminPrivileges() {
Skip("Insufficient privileges")

View File

@@ -13,8 +13,7 @@ import (
)
func TestSuite(t *testing.T) {
test.SetupLogging()
RegisterFailHandler(Fail)
RunSpecs(t, "ICE Suite")
}
var _ = test.SetupLogging()

View File

@@ -15,6 +15,8 @@ import (
"strings"
"go.uber.org/zap"
"github.com/stv0g/cunicu/pkg/log"
)
var (
@@ -204,7 +206,7 @@ func getRouteMTU(ip net.IP) (int, error) {
}
func run(args ...string) (string, error) {
cmd := exec.Command(args[0], args[1:]...)
cmd := exec.Command(args[0], args[1:]...) //nolint:gosec
out, err := cmd.CombinedOutput()
outStr := string(out)

View File

@@ -7,12 +7,14 @@ import (
"testing"
osx "github.com/stv0g/cunicu/pkg/os"
"github.com/stv0g/cunicu/test"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
func TestSuite(t *testing.T) {
test.SetupLogging()
RegisterFailHandler(Fail)
RunSpecs(t, "Link Suite")
}

View File

@@ -8,6 +8,8 @@ import (
"strconv"
"go.uber.org/zap"
"github.com/stv0g/cunicu/pkg/log"
)
type WindowsLink struct {

View File

@@ -63,6 +63,11 @@ var (
}
)
func ResetWidths() {
widthLevel.Store(0)
widthName.Store(0)
}
func ColorLevel(l zapcore.Level) string {
if color, ok := ColorLevels[l]; ok {
return color
@@ -74,14 +79,39 @@ func ColorLevel(l zapcore.Level) string {
}
type encoderConfig struct {
zapcore.EncoderConfig
ColorTime string
ColorContext string
ColorStacktrace string
ColorName string
ColorCaller string
ColorLevel func(lvl zapcore.Level) string
Function bool
Message bool
Time bool
Context bool
Stacktrace bool
Name bool
Caller bool
Level bool
// Configure the primitive representations of common complex types. For
// example, some users may want all time.Times serialized as floating-point
// seconds since epoch, while others may prefer ISO8601 strings.
EncodeLevel zapcore.LevelEncoder
EncodeTime zapcore.TimeEncoder
EncodeDuration zapcore.DurationEncoder
EncodeCaller zapcore.CallerEncoder
// Unlike the other primitive type encoders, EncodeName is optional. The
// zero value falls back to FullNameEncoder.
EncodeName zapcore.NameEncoder
// Configures the field separator used by the console encoder. Defaults
// to tab.
ConsoleSeparator string
LineEnding string
}
type encoder struct {
@@ -434,7 +464,7 @@ func (e *encoder) appendReflection(value any) error {
rvalue := reflect.ValueOf(value)
switch rvalue.Kind() {
case reflect.Chan, reflect.Func:
e.AppendString(fmt.Sprintf("%s(%d)", rvalue.Type(), rvalue.Pointer()))
e.AppendString(fmt.Sprintf("%T(%p)", value, value))
case reflect.Struct:
return e.appendReflectedStruct(rvalue)
case reflect.Map:
@@ -613,7 +643,7 @@ func (e *encoder) EncodeEntry(ent zapcore.Entry, fields []zapcore.Field) (*buffe
defer putEncoder(f)
// Time
if f.TimeKey != "" && f.EncodeTime != nil {
if f.Time && f.EncodeTime != nil {
f.addSeparator(e.fieldSeparator)
f.colored(e.ColorTime, func() {
f.EncodeTime(ent.Time, f)
@@ -621,17 +651,24 @@ func (e *encoder) EncodeEntry(ent zapcore.Entry, fields []zapcore.Field) (*buffe
}
// Level
if f.LevelKey != "" && f.EncodeLevel != nil {
f.addSeparator(e.fieldSeparator)
f.colored(e.ColorLevel(ent.Level), func() {
if f.Level && f.EncodeLevel != nil {
cb := func() {
f.aligned(&widthLevel, func() {
f.EncodeLevel(ent.Level, f)
})
})
}
f.addSeparator(e.fieldSeparator)
if e.ColorLevel != nil {
f.colored(e.ColorLevel(ent.Level), cb)
} else {
cb()
}
}
// Name
if ent.LoggerName != "" && f.NameKey != "" {
if f.Name && ent.LoggerName != "" {
nameEncoder := f.EncodeName
if nameEncoder == nil {
// Fall back to FullNameEncoder for backward compatibility.
@@ -647,14 +684,14 @@ func (e *encoder) EncodeEntry(ent zapcore.Entry, fields []zapcore.Field) (*buffe
}
if ent.Caller.Defined {
if f.CallerKey != "" && f.EncodeCaller != nil {
if f.Caller && f.EncodeCaller != nil {
f.addSeparator(e.fieldSeparator)
f.colored(e.ColorCaller, func() {
f.EncodeCaller(ent.Caller, f)
})
}
if f.FunctionKey != "" {
if f.Function {
f.addSeparator(e.fieldSeparator)
f.colored(e.ColorCaller, func() {
f.AppendString(ent.Caller.Function)
@@ -663,7 +700,7 @@ func (e *encoder) EncodeEntry(ent zapcore.Entry, fields []zapcore.Field) (*buffe
}
// Add the message itself.
if f.MessageKey != "" {
if f.Message {
f.addSeparator(e.fieldSeparator)
f.AppendString(ent.Message)
}
@@ -688,7 +725,7 @@ func (e *encoder) EncodeEntry(ent zapcore.Entry, fields []zapcore.Field) (*buffe
})
}
if f.StacktraceKey != "" && ent.Stack != "" {
if f.Stacktrace && ent.Stack != "" {
f.addSeparator(e.fieldSeparator)
f.colored(e.ColorStacktrace, func() {
f.buf.AppendString(ent.Stack)

View File

@@ -38,6 +38,10 @@ func (j jsonMarshaler) MarshalJSON() ([]byte, error) { return []byte(j), nil }
func (t failedMarshaler) MarshalText() ([]byte, error) { return []byte(t), errWelp }
var _ = Context("encoder", func() {
BeforeEach(func() {
ResetWidths()
})
DescribeTable("key",
func(
key string,
@@ -177,7 +181,7 @@ var _ = Context("encoder", func() {
},
Entry("nil", "<nil>", nil),
Entry("error", "welp", errWelp),
Entry("bytes", "bytes", []byte("bytes")),
Entry("bytes", "Ynl0ZXM=", []byte("bytes")),
Entry("stringer", "my-stringer", stringer("my-stringer")),
Entry("text marshaler", "marshaled-text", textMarshaler("marshaled-text")),
Entry("json marshaler", `{"json":"data"}`, jsonMarshaler(`{"json":"data"}`)),
@@ -413,8 +417,10 @@ var _ = Context("encoder", func() {
})
Describe("EncodeEntry", func() {
It("empty config with field", func() {
enc := newEncoder(encoderConfig{})
DescribeTable("empty config with field", func(color, expected string) {
enc := newEncoder(encoderConfig{
ColorContext: color,
})
enc.AddString("x", "y")
@@ -427,8 +433,11 @@ var _ = Context("encoder", func() {
)
Expect(err).To(Succeed())
Expect(buf.String()).To(Equal(tty.Mods("x=y a=b c=d", ColorContext) + "\n"))
})
Expect(buf.String()).To(Equal(expected))
},
Entry("with color", ColorContext, tty.Mods("x=y a=b c=d", ColorContext)+"\n"),
Entry("without color", "", "x=y a=b c=d\n"),
)
DescribeTable("with config",
func(
@@ -468,61 +477,109 @@ var _ = Context("encoder", func() {
},
Entry("empty",
"",
zapcore.EncoderConfig{},
encoderConfig{},
nil,
nil,
),
Entry("empty with fields",
"key=value",
encoderConfig{},
nil,
[]zapcore.Field{zap.String("key", "value")},
),
Entry("empty with fields and color",
tty.Mods("key=value", ColorContext),
zapcore.EncoderConfig{},
encoderConfig{ColorContext: ColorContext},
nil,
[]zapcore.Field{zap.String("key", "value")},
),
Entry("empty with context",
"message\tcontext=value field=value",
encoderConfig{Message: true},
func(enc zapcore.Encoder) { enc.AddString("context", "value") },
[]zapcore.Field{zap.String("field", "value")},
),
Entry("empty with context and color",
"message\t"+tty.Mods("context=value field=value", ColorContext),
zapcore.EncoderConfig{MessageKey: "M"},
encoderConfig{Message: true, ColorContext: ColorContext},
func(enc zapcore.Encoder) { enc.AddString("context", "value") },
[]zapcore.Field{zap.String("field", "value")},
),
Entry("EncodeTime",
"1000000001",
encoderConfig{Time: true, EncodeTime: zapcore.EpochNanosTimeEncoder},
nil,
nil,
),
Entry("EncodeTime with color",
tty.Mods("1000000001", ColorTime),
zapcore.EncoderConfig{TimeKey: "T", EncodeTime: zapcore.EpochNanosTimeEncoder},
encoderConfig{Time: true, EncodeTime: zapcore.EpochNanosTimeEncoder, ColorTime: ColorTime},
nil,
nil,
),
Entry("EncodeLevel",
"debug",
encoderConfig{Level: true, EncodeLevel: zapcore.LowercaseLevelEncoder},
nil,
nil,
),
Entry("EncodeLevel with color",
tty.Mods("debug", ColorLevels[zapcore.DebugLevel]),
zapcore.EncoderConfig{LevelKey: "L", EncodeLevel: zapcore.LowercaseLevelEncoder},
encoderConfig{Level: true, EncodeLevel: zapcore.LowercaseLevelEncoder, ColorLevel: ColorLevel},
nil,
nil,
),
Entry("EncodeName",
"test",
encoderConfig{Name: true, EncodeName: zapcore.FullNameEncoder},
nil,
nil,
),
Entry("EncodeName with color",
tty.Mods("test", ColorName),
zapcore.EncoderConfig{NameKey: "N", EncodeName: zapcore.FullNameEncoder},
encoderConfig{Name: true, EncodeName: zapcore.FullNameEncoder, ColorName: ColorName},
nil,
nil,
),
Entry("EncodeCaller",
"arthur/philip/dent/h2g2.go:42",
encoderConfig{Caller: true, EncodeCaller: zapcore.FullCallerEncoder},
nil,
nil,
),
Entry("EncodeCalle with color",
tty.Mods("arthur/philip/dent/h2g2.go:42", ColorCaller),
zapcore.EncoderConfig{CallerKey: "C", EncodeCaller: zapcore.FullCallerEncoder},
encoderConfig{Caller: true, EncodeCaller: zapcore.FullCallerEncoder, ColorCaller: ColorCaller},
nil,
nil,
),
Entry("EncodeMessage",
"message",
zapcore.EncoderConfig{MessageKey: "M"},
encoderConfig{Message: true},
nil,
nil,
),
Entry("StracktraceKey",
Entry("EncodeMessage with color",
"message",
encoderConfig{Message: true},
nil,
nil,
),
Entry("Stracktrace",
"stacktrace\nwith multiple lines\n\tand tabs\n",
encoderConfig{Stacktrace: true},
nil,
nil,
),
Entry("Stracktrace with color",
tty.Mods("stacktrace\nwith multiple lines\n\tand tabs\n", ColorStacktrace),
zapcore.EncoderConfig{StacktraceKey: "S"},
encoderConfig{Stacktrace: true, ColorStacktrace: ColorStacktrace},
nil,
nil,
),
Entry("LineEnding",
"",
zapcore.EncoderConfig{LineEnding: "<EOL>"},
encoderConfig{LineEnding: "<EOL>"},
nil,
nil,
),
@@ -536,7 +593,7 @@ var _ = Context("encoder", func() {
expected string,
timeEncoder zapcore.TimeEncoder,
) {
enc := newEncoder(encoderConfig{EncoderConfig: zapcore.EncoderConfig{EncodeTime: timeEncoder}})
enc := newEncoder(encoderConfig{EncodeTime: timeEncoder})
enc.quote = '"'
enc.AddTime("ts", ts)
@@ -555,7 +612,7 @@ var _ = Context("encoder", func() {
expected string,
durationEncoder zapcore.DurationEncoder,
) {
enc := newEncoder(encoderConfig{EncoderConfig: zapcore.EncoderConfig{EncodeDuration: durationEncoder}})
enc := newEncoder(encoderConfig{EncodeDuration: durationEncoder})
enc.quote = '"'
enc.AddDuration("duration", duration)

View File

@@ -80,7 +80,7 @@ var _ = Describe("filter", func() {
defer logger.Sync() //nolint:errcheck
rule := new(log.AtomicFilterRule)
rule.Store(log.NewFilterRule(log.MustParseRules("demo*")))
rule.Store(log.NewFilterRule(log.MustParseRules("*:demo*")))
logger = logger.WithOptions(zap.WrapCore(func(c zapcore.Core) zapcore.Core {
return log.NewFilteredCore(c, rule)
@@ -96,7 +96,7 @@ var _ = Describe("filter", func() {
})
It("new logger", func() {
logger, logs := makeLogger(log.MustParseRules("demo*"))
logger, logs := makeLogger(log.MustParseRules("*:demo*"))
defer logger.Sync() //nolint:errcheck
logger.Debug("hello world!")
@@ -141,8 +141,8 @@ var _ = Describe("filter", func() {
logger.Debug("hello multiverse!")
Expect(logs.All()).To(HaveExactElements(
MatchEntry(zapcore.Entry{Message: "hello city!"}),
MatchEntry(zapcore.Entry{Message: "hello solar system!"}),
MatchEntry(zapcore.Entry{Message: "hello planet!"}),
MatchEntry(zapcore.Entry{Message: "hello multiverse!"}),
))
})
@@ -396,29 +396,27 @@ var _ = Describe("filter", func() {
},
Entry("empty", "", "", nil),
Entry("everything", "*", everything, nil),
Entry("debug+", "debug+:*", everything, nil),
Entry("all-debug", "debug:*", allDebug, nil),
Entry("all-info", "info:*", allInfo, nil),
Entry("all-warn", "warn:*", allWarn, nil),
Entry("all-error", "error:*", allError, nil),
Entry("all-info-and-warn-1", "info,warn:*", "bcfgjknorsvwz034", nil),
Entry("all-info-and-warn-2", "info:* warn:*", "bcfgjknorsvwz034", nil),
Entry("warn+", "warn+:*", "cdghklopstwx0145", nil),
Entry("redundant-1", "info,info:* info:*", allInfo, nil),
Entry("redundant-2", "* *:* info:*", everything, nil),
Entry("foo-ns", "foo", "efgh", nil),
Entry("foo-ns-wildcard", "*:foo", "efgh", nil),
Entry("foo-ns-debug,info", "debug,info:foo", "ef", nil),
Entry("foo.star-ns", "foo.*", "qrstuvwx", nil),
Entry("foo.star-ns-wildcard", "*:foo.*", "qrstuvwx", nil),
Entry("foo.star-ns-debug,info", "debug,info:foo.*", "qruv", nil),
Entry("all-in-one", "*:foo debug:foo.* info,warn:bar error:*", "defghjklpqtux15", nil),
Entry("exclude-1", "info:test,foo*,-foo.foo", "fr", nil),
Entry("exclude-2", "info:test,foo*,-*.foo", "fr", nil),
Entry("exclude-3", "test,*.foo,-foo.*", "yz012345", nil),
Entry("exclude-4", "*,-foo,-bar", "abcdmnopqrstuvwxyz012345", nil),
Entry("exclude-5", "foo*,bar*,-foo.foo,-bar.foo", "efghijklqrst", nil),
Entry("exclude-6", "foo*,-foo.foo,bar*,-bar.foo", "efghijklqrst", nil),
Entry("debug+", "debug:*", everything, nil),
Entry("all-debug", "=debug:*", allDebug, nil),
Entry("all-info", "=info:*", allInfo, nil),
Entry("all-warn", "=warn:*", allWarn, nil),
Entry("all-error", "=error:*", allError, nil),
Entry("all-info-and-warn-1", "=info,=warn:*", "bcfgjknorsvwz034", nil),
Entry("all-info-and-warn-2", "=info:* =warn:*", "bcfgjknorsvwz034", nil),
Entry("warn+", "warn:*", "cdghklopstwx0145", nil),
Entry("redundant-1", "=info,=info:* =info:*", allInfo, nil),
Entry("redundant-2", "* *:* =info:*", everything, nil),
Entry("foo-ns", "*:foo", "efgh", nil),
Entry("foo-ns-debug,info", "=debug,=info:foo", "ef", nil),
Entry("foo.star-ns", "*:foo.*", "qrstuvwx", nil),
Entry("foo.star-ns-debug,info", "=debug,=info:foo.*", "qruv", nil),
Entry("all-in-one", "*:foo =debug:foo.* =info,=warn:bar error:*", "defghjklpqtux15", nil),
Entry("exclude-1", "=info:test,foo*,-foo.foo", "fr", nil),
Entry("exclude-2", "=info:test,foo*,-*.foo", "fr", nil),
Entry("exclude-3", "*:test,*.foo,-foo.*", "yz012345", nil),
Entry("exclude-4", "*:*,-foo,-bar", "abcdmnopqrstuvwxyz012345", nil),
Entry("exclude-5", "*:foo*,bar*,-foo.foo,-bar.foo", "efghijklqrst", nil),
Entry("exclude-6", "*:foo*,-foo.foo,bar*,-bar.foo", "efghijklqrst", nil),
Entry("invalid-left", "invalid:*", "", log.ErrUnsupportedKeyword),
Entry("missing-left", ":*", "", log.ErrBadSyntax),
Entry("missing-right", ":*", "", log.ErrBadSyntax),
@@ -451,35 +449,35 @@ var _ = Describe("filter", func() {
Expect(entry).To(BeNil())
}
},
Entry(nil, "", "", false),
Entry(nil, "", "foo", false),
Entry(nil, "*", "", true),
Entry(nil, "*", "foo", true),
Entry(nil, "*:foo", "", false),
Entry(nil, "*:foo", "foo", true),
Entry(nil, "*:foo", "bar", false),
Entry("1", "", "", false),
Entry("2", "", "foo", false),
Entry("3", "*", "", true),
Entry("4", "*", "foo", true),
Entry("5", "*:foo", "", false),
Entry("6", "*:foo", "foo", true),
Entry("7", "*:foo", "bar", false),
)
DescribeTable("any level",
func(name string, expected bool) {
logger, _ := makeLogger(log.MustParseRules("debug:*.* info:demo*"))
logger, _ := makeLogger(log.MustParseRules("=debug:*.* =info:demo*"))
if name != "" {
logger = logger.Named(name)
}
Expect(log.CheckAnyLevel(logger)).To(Equal(expected))
},
Entry(nil, "", false),
Entry(nil, "demo", true),
Entry(nil, "blahdemo", false),
Entry(nil, "demoblah", true),
Entry(nil, "blah", false),
Entry(nil, "blah.blah", true),
Entry("1", "", false),
Entry("2", "demo", true),
Entry("3", "blahdemo", false),
Entry("4", "demoblah", true),
Entry("5", "blah", false),
Entry("6", "blah.blah", true),
)
DescribeTable("level",
func(name string, lvl zapcore.Level, expected bool) {
logger, _ := makeLogger(log.MustParseRules("debug:*.* info:demo*"))
logger, _ := makeLogger(log.MustParseRules("=debug:*.* =info:demo*"))
if name != "" {
logger = logger.Named(name)
@@ -487,18 +485,18 @@ var _ = Describe("filter", func() {
Expect(log.CheckLevel(logger, lvl)).To(Equal(expected))
},
Entry(nil, "", zap.DebugLevel, false),
Entry(nil, "demo", zap.DebugLevel, false),
Entry(nil, "blahdemo", zap.DebugLevel, false),
Entry(nil, "demoblah", zap.DebugLevel, false),
Entry(nil, "blah", zap.DebugLevel, false),
Entry(nil, "blah.blah", zap.DebugLevel, true),
Entry(nil, "", zap.InfoLevel, false),
Entry(nil, "demo", zap.InfoLevel, true),
Entry(nil, "blahdemo", zap.InfoLevel, false),
Entry(nil, "demoblah", zap.InfoLevel, true),
Entry(nil, "blah", zap.InfoLevel, false),
Entry(nil, "blah.blah", zap.InfoLevel, false),
Entry("1", "", zap.DebugLevel, false),
Entry("2", "demo", zap.DebugLevel, false),
Entry("3", "blahdemo", zap.DebugLevel, false),
Entry("4", "demoblah", zap.DebugLevel, false),
Entry("5", "blah", zap.DebugLevel, false),
Entry("6", "blah.blah", zap.DebugLevel, true),
Entry("7", "", zap.InfoLevel, false),
Entry("8", "demo", zap.InfoLevel, true),
Entry("9", "blahdemo", zap.InfoLevel, false),
Entry("10", "demoblah", zap.InfoLevel, true),
Entry("11", "blah", zap.InfoLevel, false),
Entry("12", "blah.blah", zap.InfoLevel, false),
)
})
@@ -524,7 +522,7 @@ var _ = Describe("filter", func() {
})
It("Check", func() {
logger, logs := makeLogger(log.MustParseRules("debug:* info:demo*"))
logger, logs := makeLogger(log.MustParseRules("=debug:* =info:demo*"))
defer logger.Sync() //nolint:errcheck
ce := logger.Check(zap.DebugLevel, "a")

View File

@@ -7,6 +7,7 @@ package log
import (
"os"
"github.com/onsi/ginkgo/v2"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"google.golang.org/grpc/grpclog"
@@ -25,10 +26,13 @@ func DebugLevel(verbosity int) Level {
}
func openSink(path string) zapcore.WriteSyncer {
if path == "stdout" {
switch path {
case "stdout":
return os.Stdout
} else if path == "stderr" {
case "stderr":
return os.Stderr
case "ginkgo":
return &ginkgoSyncWriter{ginkgo.GinkgoWriter}
}
f, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0o644)
@@ -45,21 +49,20 @@ func (e *alwaysEnabled) Enabled(zapcore.Level) bool { return true }
func SetupLogging(rule string, paths []string, color bool) (logger *Logger, err error) {
cfg := encoderConfig{
EncoderConfig: zapcore.EncoderConfig{
TimeKey: "T",
LevelKey: "L",
NameKey: "N",
CallerKey: "C",
FunctionKey: zapcore.OmitKey,
MessageKey: "M",
StacktraceKey: "S",
ConsoleSeparator: " ",
LineEnding: zapcore.DefaultLineEnding,
EncodeTime: zapcore.TimeEncoderOfLayout("15:04:05.000000"),
EncodeDuration: zapcore.StringDurationEncoder,
EncodeCaller: zapcore.ShortCallerEncoder,
EncodeLevel: levelEncoder,
},
Time: true,
Level: true,
Name: true,
Message: true,
ConsoleSeparator: " ",
LineEnding: zapcore.DefaultLineEnding,
EncodeTime: zapcore.TimeEncoderOfLayout("15:04:05.000000"),
EncodeDuration: zapcore.StringDurationEncoder,
EncodeCaller: zapcore.ShortCallerEncoder,
EncodeLevel: levelEncoder,
}
if rule == "" {
rule = "*"
}
if color {
@@ -69,10 +72,6 @@ func SetupLogging(rule string, paths []string, color bool) (logger *Logger, err
cfg.ColorName = ColorName
cfg.ColorCaller = ColorCaller
cfg.ColorLevel = ColorLevel
} else {
cfg.ColorLevel = func(lvl zapcore.Level) string {
return ""
}
}
wss := []zapcore.WriteSyncer{}
@@ -89,10 +88,6 @@ func SetupLogging(rule string, paths []string, color bool) (logger *Logger, err
enc := newEncoder(cfg)
core := zapcore.NewCore(enc, ws, &alwaysEnabled{})
if rule == "" {
rule = "*"
}
filterRule, err := ParseFilterRule(rule)
if err != nil {
return nil, err

View File

@@ -8,7 +8,6 @@ import (
stdlog "log"
"os"
"path/filepath"
"regexp"
"testing"
"github.com/pion/zapion"
@@ -16,7 +15,6 @@ import (
"google.golang.org/grpc/grpclog"
"github.com/stv0g/cunicu/pkg/log"
"github.com/stv0g/cunicu/pkg/tty"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
@@ -43,11 +41,13 @@ var _ = Context("log", Label("broken-on-windows"), func() {
os.Setenv("GRPC_GO_LOG_VERBOSITY_LEVEL", "2")
os.Setenv("GRPC_GO_LOG_SEVERITY_LEVEL", lvl.String())
os.Setenv("PION_LOG", lvl.String())
log.ResetWidths()
})
JustBeforeEach(func() {
var err error
logger, err = log.SetupLogging("", []string{logPath}, true)
logger, err = log.SetupLogging("", []string{logPath}, false)
Expect(err).To(Succeed())
})
@@ -96,9 +96,9 @@ var _ = Context("log", Label("broken-on-windows"), func() {
Expect(err).To(Succeed(), "Failed to read standard log contents: %s", err)
Expect(logContents).NotTo(BeEmpty())
regexTime := regexpQuoteColor(`\d{2}:\d{2}:\d{2}.\d{6}`, log.ColorTime) + " "
regexLevel := regexpQuoteColor(lvl.String(), log.ColorLevel(lvl)) + " "
regexName := regexpQuoteColor(name, log.ColorName) + " "
regexTime := `\d{2}:\d{2}:\d{2}.\d{6} `
regexLevel := lvl.String() + " "
regexName := name + " "
var regex string
if name != "" {
@@ -110,11 +110,3 @@ var _ = Context("log", Label("broken-on-windows"), func() {
Expect(string(logContents)).To(MatchRegexp(regex), "Log output '%s' does not match regex '%s'", logContents, regex)
})
})
func regexpQuoteColor(str, color string) string {
if color == "" {
return str
}
return regexp.QuoteMeta(color) + str + regexp.QuoteMeta(tty.Reset)
}

18
pkg/log/sink_ginkgo.go Normal file
View File

@@ -0,0 +1,18 @@
// SPDX-FileCopyrightText: 2023 Steffen Vogel <post@steffenvogel.de>
// SPDX-License-Identifier: Apache-2.0
package log
import "github.com/onsi/ginkgo/v2"
type ginkgoSyncWriter struct {
ginkgo.GinkgoWriterInterface
}
func (w *ginkgoSyncWriter) Close() error {
return nil
}
func (w *ginkgoSyncWriter) Sync() error {
return nil
}

View File

@@ -15,12 +15,11 @@ import (
)
func TestSuite(t *testing.T) {
test.SetupLogging()
RegisterFailHandler(Fail)
RunSpecs(t, "Network Suite")
}
var _ = test.SetupLogging()
var _ = Context("endpoint comparisons", func() {
It("to be equal", func() {
a := net.UDPAddr{

View File

@@ -13,8 +13,7 @@ import (
)
func TestSuite(t *testing.T) {
test.SetupLogging()
RegisterFailHandler(Fail)
RunSpecs(t, "Protobuf Suite")
}
var _ = test.SetupLogging()

View File

@@ -18,12 +18,11 @@ import (
)
func TestSuite(t *testing.T) {
test.SetupLogging()
RegisterFailHandler(Fail)
RunSpecs(t, "Protobuf Suite")
}
var _ = test.SetupLogging()
var _ = Describe("message encryption", func() {
var c epdiscproto.Candidate
var ourKP, theirKP *crypto.KeyPair

View File

@@ -188,7 +188,7 @@ func extractToFile(buf []byte, filename, target string) (int64, error) {
return -1, err
}
n, err := io.Copy(dest, rd)
n, err := io.Copy(dest, rd) //nolint:gosec
if err != nil {
_ = dest.Close()
_ = os.Remove(dest.Name())

View File

@@ -8,6 +8,7 @@ import (
"testing"
"github.com/stv0g/cunicu/pkg/buildinfo"
"github.com/stv0g/cunicu/pkg/log"
"github.com/stv0g/cunicu/pkg/selfupdate"
"github.com/stv0g/cunicu/test"
@@ -16,14 +17,13 @@ import (
)
func TestSuite(t *testing.T) {
test.SetupLogging()
RegisterFailHandler(Fail)
RunSpecs(t, "Self-update Suite")
}
var logger = test.SetupLogging()
var _ = It("self-update", Pending, func() {
logger := logger.Named("self-update")
logger := log.Global.Named("self-update")
output := filepath.Join(GinkgoT().TempDir(), "cunicu")

View File

@@ -16,12 +16,11 @@ import (
)
func TestSuite(t *testing.T) {
test.SetupLogging()
RegisterFailHandler(Fail)
RunSpecs(t, "gRPC Backend Suite")
}
var _ = test.SetupLogging()
var _ = Describe("gRPC backend", func() {
var svr *grpc.Server
var l *net.TCPListener

View File

@@ -16,12 +16,11 @@ import (
)
func TestSuite(t *testing.T) {
test.SetupLogging()
RegisterFailHandler(Fail)
RunSpecs(t, "In-Process Backend Suite")
}
var _ = test.SetupLogging()
var _ = Describe("inprocess backend", func() {
u := url.URL{
Scheme: "inprocess",

View File

@@ -13,8 +13,7 @@ import (
)
func TestSuite(t *testing.T) {
test.SetupLogging()
RegisterFailHandler(Fail)
RunSpecs(t, "Signaling Suite")
}
var _ = test.SetupLogging()

View File

@@ -16,12 +16,11 @@ import (
)
func TestSuite(t *testing.T) {
test.SetupLogging()
RegisterFailHandler(Fail)
RunSpecs(t, "TTY Suite")
}
var _ = test.SetupLogging()
var _ = Context("IsATTY", func() {
if test.IsCI() {
It("is false in CI runners", func() {

View File

@@ -16,12 +16,11 @@ import (
)
func TestSuite(t *testing.T) {
test.SetupLogging()
RegisterFailHandler(Fail)
RunSpecs(t, "Slices Suite")
}
var _ = test.SetupLogging()
var _ = Context("slice", func() {
var s []int

View File

@@ -13,8 +13,7 @@ import (
)
func TestSuite(t *testing.T) {
test.SetupLogging()
RegisterFailHandler(Fail)
RunSpecs(t, "Types Suite")
}
var _ = test.SetupLogging()

View File

@@ -13,8 +13,7 @@ import (
)
func TestSuite(t *testing.T) {
test.SetupLogging()
RegisterFailHandler(Fail)
RunSpecs(t, "WireGuard Suite")
}
var _ = test.SetupLogging()

View File

@@ -6,30 +6,15 @@ package test
import (
"fmt"
"net/url"
"os"
"path/filepath"
"strings"
"github.com/onsi/ginkgo/v2"
"go.uber.org/zap"
"github.com/stv0g/cunicu/pkg/log"
"github.com/stv0g/cunicu/pkg/tty"
)
type writerWrapper struct {
ginkgo.GinkgoWriterInterface
}
func (w *writerWrapper) Close() error {
return nil
}
func (w *writerWrapper) Sync() error {
return nil
}
func SetupLogging() *log.Logger {
logger, err := SetupLoggingWithFile("", false)
if err != nil {
@@ -40,15 +25,7 @@ func SetupLogging() *log.Logger {
}
func SetupLoggingWithFile(fn string, truncate bool) (*log.Logger, error) {
if err := zap.RegisterSink("ginkgo", func(u *url.URL) (zap.Sink, error) {
return &writerWrapper{
GinkgoWriterInterface: ginkgo.GinkgoWriter,
}, nil
}); err != nil && !strings.Contains(err.Error(), "already registered") {
panic(err)
}
outputPaths := []string{"ginkgo:"}
outputPaths := []string{"ginkgo"}
if fn != "" {
// Create parent directories for log file

View File

@@ -14,12 +14,11 @@ import (
)
func TestSuite(t *testing.T) {
test.SetupLogging()
RegisterFailHandler(Fail)
RunSpecs(t, "Test Helper Suite")
}
var _ = test.SetupLogging()
var _ = Describe("entropy", func() {
Specify("that the entropy of an empty slice is zero", func() {
Expect(test.Entropy([]byte{})).To(BeNumerically("==", 0))