Files
releases/logging/logging_test.go
T
Stephan Renatus 2c90500a0b logging: avoid '%!F(MISSING)' in logs (#6555)
When only passing a single string into a Printf-style function, any %-format
specs in it will be filled accordingly; but there will be no arguments to use.

So now, we'll avoid calling the `{Debug,Info,Warn,Error}f` functions when we
lack arguments.

Signed-off-by: Stephan Renatus <stephan@styra.com>
2024-01-29 10:31:42 +01:00

182 lines
4.5 KiB
Go

package logging
import (
"bytes"
"context"
"crypto/rand"
"net/url"
"strings"
"testing"
"github.com/open-policy-agent/opa/internal/uuid"
)
func TestWithFields(t *testing.T) {
logger := New().WithFields(map[string]interface{}{"context": "contextvalue"})
var fieldvalue interface{}
var ok bool
if fieldvalue, ok = logger.(*StandardLogger).fields["context"]; !ok {
t.Fatal("Logger did not contain configured field")
}
if fieldvalue.(string) != "contextvalue" {
t.Fatal("Logger did not contain configured field value")
}
}
func TestCaptureWarningWithErrorSet(t *testing.T) {
buf := bytes.Buffer{}
logger := New()
logger.SetOutput(&buf)
logger.SetLevel(Error)
logger.Warn("This is a warning. Next time, I won't compile.")
logger.Error("Fix your issues. I'm not compiling.")
expected := []string{
`level=warning msg="This is a warning. Next time, I won't compile."`,
`level=error msg="Fix your issues. I'm not compiling."`,
}
for _, exp := range expected {
if !strings.Contains(buf.String(), exp) {
t.Errorf("expected string %q not found in logs", exp)
}
}
}
func TestNoFormattingForSingleString(t *testing.T) {
buf := bytes.Buffer{}
logger := New()
logger.SetOutput(&buf)
logger.SetLevel(Debug)
// NOTE(sr): This construction is somewhat realistic: If we fed logger.Error()
// a format string but no args, the golang linters would yell. The indirection
// taken here is enough to not trigger linters.
x := url.PathEscape("/foo/bar/bar")
logger.Debug(x)
logger.Info(x)
logger.Warn(x)
logger.Error(x)
exp := `"%2Ffoo%2Fbar%2Fbar"`
expected := []string{
`level=error msg=` + exp,
`level=warning msg=` + exp,
`level=info msg=` + exp,
`level=debug msg=` + exp,
}
for _, exp := range expected {
if !strings.Contains(buf.String(), exp) {
t.Errorf("expected string %q not found in logs", exp)
}
}
if t.Failed() {
t.Logf("actual output:\n%s", buf.String())
}
}
func TestWithFieldsOverrides(t *testing.T) {
logger := New().
WithFields(map[string]interface{}{"context": "contextvalue"}).
WithFields(map[string]interface{}{"context": "changedcontextvalue"})
var fieldvalue interface{}
var ok bool
if fieldvalue, ok = logger.(*StandardLogger).fields["context"]; !ok {
t.Fatal("Logger did not contain configured field")
}
if fieldvalue.(string) != "changedcontextvalue" {
t.Fatal("Logger did not contain configured field value")
}
}
func TestWithFieldsMerges(t *testing.T) {
logger := New().
WithFields(map[string]interface{}{"context": "contextvalue"}).
WithFields(map[string]interface{}{"anothercontext": "anothercontextvalue"})
var fieldvalue interface{}
var ok bool
if fieldvalue, ok = logger.(*StandardLogger).fields["context"]; !ok {
t.Fatal("Logger did not contain configured field")
}
if fieldvalue.(string) != "contextvalue" {
t.Fatal("Logger did not contain configured field value")
}
if fieldvalue, ok = logger.(*StandardLogger).fields["anothercontext"]; !ok {
t.Fatal("Logger did not contain configured field")
}
if fieldvalue.(string) != "anothercontextvalue" {
t.Fatal("Logger did not contain configured field value")
}
}
func TestRequestContextFields(t *testing.T) {
fields := RequestContext{
ClientAddr: "127.0.0.1",
ReqID: 1,
ReqMethod: "GET",
ReqPath: "/test",
}.Fields()
var fieldvalue interface{}
var ok bool
if fieldvalue, ok = fields["client_addr"]; !ok {
t.Fatal("Fields did not contain the client_addr field")
}
if fieldvalue.(string) != "127.0.0.1" {
t.Fatal("Fields did not contain the configured client_addr value")
}
if fieldvalue, ok = fields["req_id"]; !ok {
t.Fatal("Fields did not contain the req_id field")
}
if fieldvalue.(uint64) != 1 {
t.Fatal("Fields did not contain the configured req_id value")
}
if fieldvalue, ok = fields["req_method"]; !ok {
t.Fatal("Fields did not contain the req_method field")
}
if fieldvalue.(string) != "GET" {
t.Fatal("Fields did not contain the configured req_method value")
}
if fieldvalue, ok = fields["req_path"]; !ok {
t.Fatal("Fields did not contain the req_path field")
}
if fieldvalue.(string) != "/test" {
t.Fatal("Fields did not contain the configured req_path value")
}
}
func TestDecsionIDFromContext(t *testing.T) {
id, err := uuid.New(rand.Reader)
if err != nil {
t.Fatal(err)
}
ctx := WithDecisionID(context.Background(), id)
act, ok := DecisionIDFromContext(ctx)
if !ok {
t.Fatalf("expected 'ok' to be true")
}
if exp := id; act != exp {
t.Errorf("Expected %q to be %q", act, exp)
}
}