From 5377a982c43b0cab8c88d6e097df0c158ae2fa20 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Tue, 15 Mar 2022 08:48:59 -0700 Subject: [PATCH] Move testing -> testr, deprecate, alias old names This avoids the pkg name overlap with standard "testing". --- README.md | 2 + testing/test.go | 102 +++++--------------------------------- testr/testr.go | 116 ++++++++++++++++++++++++++++++++++++++++++++ testr/testr_test.go | 52 ++++++++++++++++++++ 4 files changed, 182 insertions(+), 90 deletions(-) create mode 100644 testr/testr.go create mode 100644 testr/testr_test.go diff --git a/README.md b/README.md index 8e89e1b..ab59311 100644 --- a/README.md +++ b/README.md @@ -105,8 +105,10 @@ with higher verbosity means more (and less important) logs will be generated. There are implementations for the following logging libraries: - **a function** (can bridge to non-structured libraries): [funcr](https://github.com/go-logr/logr/tree/master/funcr) +- **a testing.T** (for use in Go tests, with JSON-like output): [testr](https://github.com/go-logr/logr/tree/master/testr) - **github.com/google/glog**: [glogr](https://github.com/go-logr/glogr) - **k8s.io/klog** (for Kubernetes): [klogr](https://git.k8s.io/klog/klogr) +- **a testing.T** (with klog-like text output): [ktesting](https://git.k8s.io/klog/ktesting) - **go.uber.org/zap**: [zapr](https://github.com/go-logr/zapr) - **log** (the Go standard library logger): [stdr](https://github.com/go-logr/stdr) - **github.com/sirupsen/logrus**: [logrusr](https://github.com/bombsimon/logrusr) diff --git a/testing/test.go b/testing/test.go index 92954e8..fda9401 100644 --- a/testing/test.go +++ b/testing/test.go @@ -14,102 +14,24 @@ See the License for the specific language governing permissions and limitations under the License. */ +// Package testing provides support for using logr in tests. +// Deprecated. See github.com/go-logr/logr/testr instead. package testing -import ( - "testing" - - "github.com/go-logr/logr" - "github.com/go-logr/logr/funcr" -) +import "github.com/go-logr/logr/testr" // NewTestLogger returns a logr.Logger that prints through a testing.T object. -// Info logs are only enabled at V(0). -func NewTestLogger(t *testing.T) logr.Logger { - l := &testlogger{ - Formatter: funcr.NewFormatter(funcr.Options{}), - t: t, - } - return logr.New(l) -} +// Deprecated. See github.com/go-logr/logr/testr.New instead. +var NewTestLogger = testr.New // Options carries parameters which influence the way logs are generated. -type Options struct { - // LogTimestamp tells the logger to add a "ts" key to log - // lines. This has some overhead, so some users might not want - // it. - LogTimestamp bool - - // Verbosity tells the logger which V logs to be write. - // Higher values enable more logs. - Verbosity int -} +// Deprecated. See github.com/go-logr/logr/testr.Options instead. +type Options = testr.Options // NewTestLoggerWithOptions returns a logr.Logger that prints through a testing.T object. -// In contrast to the simpler NewTestLogger, output formatting can be configured. -func NewTestLoggerWithOptions(t *testing.T, opts Options) logr.Logger { - l := &testlogger{ - Formatter: funcr.NewFormatter(funcr.Options{ - LogTimestamp: opts.LogTimestamp, - Verbosity: opts.Verbosity, - }), - t: t, - } - return logr.New(l) -} - -// Underlier exposes access to the underlying testing.T instance. Since -// callers only have a logr.Logger, they have to know which -// implementation is in use, so this interface is less of an -// abstraction and more of a way to test type conversion. -type Underlier interface { - GetUnderlying() *testing.T -} - -type testlogger struct { - funcr.Formatter - t *testing.T -} - -func (l testlogger) WithName(name string) logr.LogSink { - l.Formatter.AddName(name) - return &l -} - -func (l testlogger) WithValues(kvList ...interface{}) logr.LogSink { - l.Formatter.AddValues(kvList) - return &l -} - -func (l testlogger) GetCallStackHelper() func() { - return l.t.Helper -} - -func (l testlogger) Info(level int, msg string, kvList ...interface{}) { - prefix, args := l.FormatInfo(level, msg, kvList) - l.t.Helper() - if prefix != "" { - l.t.Logf("%s: %s", prefix, args) - } else { - l.t.Log(args) - } -} - -func (l testlogger) Error(err error, msg string, kvList ...interface{}) { - prefix, args := l.FormatError(err, msg, kvList) - l.t.Helper() - if prefix != "" { - l.t.Logf("%s: %s", prefix, args) - } else { - l.t.Log(args) - } -} - -func (l testlogger) GetUnderlying() *testing.T { - return l.t -} +// Deprecated. See github.com/go-logr/logr/testr.NewWithOptions instead. +var NewTestLoggerWithOptions = testr.NewWithOptions -// Assert conformance to the interfaces. -var _ logr.LogSink = &testlogger{} -var _ logr.CallStackHelperLogSink = &testlogger{} -var _ Underlier = &testlogger{} +// Underlier exposes access to the underlying testing.T instance. +// Deprecated. See github.com/go-logr/logr/testr.Underlier instead. +type Underlier = testr.Underlier diff --git a/testr/testr.go b/testr/testr.go new file mode 100644 index 0000000..6fa2783 --- /dev/null +++ b/testr/testr.go @@ -0,0 +1,116 @@ +/* +Copyright 2019 The logr Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package testr provides support for using logr in tests. +package testr + +import ( + "testing" + + "github.com/go-logr/logr" + "github.com/go-logr/logr/funcr" +) + +// New returns a logr.Logger that prints through a testing.T object. +// Info logs are only enabled at V(0). +func New(t *testing.T) logr.Logger { + l := &testlogger{ + Formatter: funcr.NewFormatter(funcr.Options{}), + t: t, + } + return logr.New(l) +} + +// Options carries parameters which influence the way logs are generated. +type Options struct { + // LogTimestamp tells the logger to add a "ts" key to log + // lines. This has some overhead, so some users might not want + // it. + LogTimestamp bool + + // Verbosity tells the logger which V logs to be write. + // Higher values enable more logs. + Verbosity int +} + +// NewWithOptions returns a logr.Logger that prints through a testing.T object. +// In contrast to the simpler New, output formatting can be configured. +func NewWithOptions(t *testing.T, opts Options) logr.Logger { + l := &testlogger{ + Formatter: funcr.NewFormatter(funcr.Options{ + LogTimestamp: opts.LogTimestamp, + Verbosity: opts.Verbosity, + }), + t: t, + } + return logr.New(l) +} + +// Underlier exposes access to the underlying testing.T instance. Since +// callers only have a logr.Logger, they have to know which +// implementation is in use, so this interface is less of an +// abstraction and more of a way to test type conversion. +type Underlier interface { + GetUnderlying() *testing.T +} + +type testlogger struct { + funcr.Formatter + t *testing.T +} + +func (l testlogger) WithName(name string) logr.LogSink { + l.Formatter.AddName(name) + return &l +} + +func (l testlogger) WithValues(kvList ...interface{}) logr.LogSink { + l.Formatter.AddValues(kvList) + return &l +} + +func (l testlogger) GetCallStackHelper() func() { + return l.t.Helper +} + +func (l testlogger) Info(level int, msg string, kvList ...interface{}) { + prefix, args := l.FormatInfo(level, msg, kvList) + l.t.Helper() + if prefix != "" { + l.t.Logf("%s: %s", prefix, args) + } else { + l.t.Log(args) + } +} + +func (l testlogger) Error(err error, msg string, kvList ...interface{}) { + prefix, args := l.FormatError(err, msg, kvList) + l.t.Helper() + if prefix != "" { + l.t.Logf("%s: %s", prefix, args) + } else { + l.t.Log(args) + } +} + +func (l testlogger) GetUnderlying() *testing.T { + return l.t +} + +// Assert conformance to the interfaces. +var _ logr.LogSink = &testlogger{} +var _ logr.CallStackHelperLogSink = &testlogger{} +var _ Underlier = &testlogger{} diff --git a/testr/testr_test.go b/testr/testr_test.go new file mode 100644 index 0000000..0d71a01 --- /dev/null +++ b/testr/testr_test.go @@ -0,0 +1,52 @@ +/* +Copyright 2021 The logr Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package testr + +import ( + "fmt" + "testing" + + "github.com/go-logr/logr" +) + +func TestLogger(t *testing.T) { + log := New(t) + log.Info("info") + log.V(0).Info("V(0).info") + log.V(1).Info("v(1).info") + log.Error(fmt.Errorf("error"), "error") + log.WithName("testing").Info("with prefix") + Helper(log, "hello world") + + log = NewWithOptions(t, Options{ + LogTimestamp: true, + Verbosity: 1, + }) + log.V(1).Info("v(1).info with options") +} + +func Helper(log logr.Logger, msg string) { + helper, log := log.WithCallStackHelper() + helper() + helper2(log, msg) +} + +func helper2(log logr.Logger, msg string) { + helper, log := log.WithCallStackHelper() + helper() + log.Info(msg) +}