boulder/log/log_test.go

264 lines
6.6 KiB
Go
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package log
import (
"errors"
"fmt"
"log/syslog"
"net"
"strings"
"testing"
"time"
"github.com/jmhodges/clock"
"github.com/letsencrypt/boulder/test"
)
const stdoutLevel = 7
const syslogLevel = 7
func setup(t *testing.T) *impl {
// Write all logs to UDP on a high port so as to not bother the system
// which is running the test
writer, err := syslog.Dial("udp", "127.0.0.1:65530", syslog.LOG_INFO|syslog.LOG_LOCAL0, "")
test.AssertNotError(t, err, "Could not construct syslog object")
logger, err := New(writer, stdoutLevel, syslogLevel)
test.AssertNotError(t, err, "Could not construct syslog object")
impl, ok := logger.(*impl)
if !ok {
t.Fatalf("Wrong type returned from New: %T", logger)
}
return impl
}
func TestConstruction(t *testing.T) {
t.Parallel()
_ = setup(t)
}
func TestSingleton(t *testing.T) {
t.Parallel()
log1 := Get()
test.AssertNotNil(t, log1, "Logger shouldn't be nil")
log2 := Get()
test.AssertEquals(t, log1, log2)
audit := setup(t)
// Should not work
err := Set(audit)
test.AssertError(t, err, "Can't re-set")
// Verify no change
log4 := Get()
// Verify that log4 != log3
test.AssertNotEquals(t, log4, audit)
// Verify that log4 == log2 == log1
test.AssertEquals(t, log4, log2)
test.AssertEquals(t, log4, log1)
}
func TestConstructionNil(t *testing.T) {
t.Parallel()
_, err := New(nil, stdoutLevel, syslogLevel)
test.AssertError(t, err, "Nil shouldn't be permitted.")
}
func TestEmit(t *testing.T) {
t.Parallel()
log := setup(t)
log.AuditInfo("test message")
}
func TestEmitEmpty(t *testing.T) {
t.Parallel()
log := setup(t)
log.AuditInfo("")
}
func ExampleLogger() {
impl := setup(nil)
bw, ok := impl.w.(*bothWriter)
if !ok {
fmt.Printf("Wrong type of impl's writer: %T\n", impl.w)
return
}
bw.clk = clock.NewFake()
impl.AuditErr(errors.New("Error Audit"))
impl.Warning("Warning Audit")
// Output:
// E000000 log.test [AUDIT] Error Audit
// W000000 log.test Warning Audit
}
func TestSyslogMethods(t *testing.T) {
t.Parallel()
impl := setup(t)
impl.AuditInfo("audit-logger_test.go: audit-info")
impl.AuditErr(errors.New("audit-logger_test.go: audit-err"))
impl.Debug("audit-logger_test.go: debug")
impl.Err("audit-logger_test.go: err")
impl.Info("audit-logger_test.go: info")
impl.Warning("audit-logger_test.go: warning")
}
func TestPanic(t *testing.T) {
t.Parallel()
impl := setup(t)
defer impl.AuditPanic()
panic("Test panic")
// Can't assert anything here or golint gets angry
}
func TestAuditObject(t *testing.T) {
t.Parallel()
log := NewMock()
// Test a simple object
log.AuditObject("Prefix", "String")
if len(log.GetAllMatching("[AUDIT]")) != 1 {
t.Errorf("Failed to audit log simple object")
}
// Test a system object
log.Clear()
log.AuditObject("Prefix", t)
if len(log.GetAllMatching("[AUDIT]")) != 1 {
t.Errorf("Failed to audit log system object")
}
// Test a complex object
log.Clear()
type validObj struct {
A string
B string
}
var valid = validObj{A: "B", B: "C"}
log.AuditObject("Prefix", valid)
if len(log.GetAllMatching("[AUDIT]")) != 1 {
t.Errorf("Failed to audit log complex object")
}
// Test logging an unserializable object
log.Clear()
type invalidObj struct {
A chan string
}
var invalid = invalidObj{A: make(chan string)}
log.AuditObject("Prefix", invalid)
if len(log.GetAllMatching("[AUDIT]")) != 1 {
t.Errorf("Failed to audit log unserializable object %v", log.GetAllMatching("[AUDIT]"))
}
}
func TestTransmission(t *testing.T) {
t.Parallel()
l, err := newUDPListener("127.0.0.1:0")
test.AssertNotError(t, err, "Failed to open log server")
defer func() {
err = l.Close()
test.AssertNotError(t, err, "listener.Close returned error")
}()
fmt.Printf("Going to %s\n", l.LocalAddr().String())
writer, err := syslog.Dial("udp", l.LocalAddr().String(), syslog.LOG_INFO|syslog.LOG_LOCAL0, "")
test.AssertNotError(t, err, "Failed to find connect to log server")
impl, err := New(writer, stdoutLevel, syslogLevel)
test.AssertNotError(t, err, "Failed to construct audit logger")
data := make([]byte, 128)
impl.AuditInfo("audit-logger_test.go: audit-notice")
_, _, err = l.ReadFrom(data)
test.AssertNotError(t, err, "Failed to find packet")
impl.AuditErr(errors.New("audit-logger_test.go: audit-err"))
_, _, err = l.ReadFrom(data)
test.AssertNotError(t, err, "Failed to find packet")
impl.Debug("audit-logger_test.go: debug")
_, _, err = l.ReadFrom(data)
test.AssertNotError(t, err, "Failed to find packet")
impl.Err("audit-logger_test.go: err")
_, _, err = l.ReadFrom(data)
test.AssertNotError(t, err, "Failed to find packet")
impl.Info("audit-logger_test.go: info")
_, _, err = l.ReadFrom(data)
test.AssertNotError(t, err, "Failed to find packet")
impl.Warning("audit-logger_test.go: warning")
_, _, err = l.ReadFrom(data)
test.AssertNotError(t, err, "Failed to find packet")
}
func TestSyslogLevels(t *testing.T) {
t.Parallel()
l, err := newUDPListener("127.0.0.1:0")
test.AssertNotError(t, err, "Failed to open log server")
defer func() {
err = l.Close()
test.AssertNotError(t, err, "listener.Close returned error")
}()
fmt.Printf("Going to %s\n", l.LocalAddr().String())
writer, err := syslog.Dial("udp", l.LocalAddr().String(), syslog.LOG_INFO|syslog.LOG_LOCAL0, "")
test.AssertNotError(t, err, "Failed to find connect to log server")
// create a logger with syslog level debug
impl, err := New(writer, stdoutLevel, int(syslog.LOG_DEBUG))
test.AssertNotError(t, err, "Failed to construct audit logger")
data := make([]byte, 512)
// debug messages should be sent to the logger
impl.Debug("log_test.go: debug")
_, _, err = l.ReadFrom(data)
test.AssertNotError(t, err, "Failed to find packet")
test.Assert(t, strings.Contains(string(data), "log_test.go: debug"), "Failed to find log message")
// create a logger with syslog level info
impl, err = New(writer, stdoutLevel, int(syslog.LOG_INFO))
test.AssertNotError(t, err, "Failed to construct audit logger")
// debug messages should not be sent to the logger
impl.Debug("log_test.go: debug")
n, _, err := l.ReadFrom(data)
if n != 0 && err == nil {
t.Error("Failed to withhold debug log message")
}
}
func newUDPListener(addr string) (*net.UDPConn, error) {
l, err := net.ListenPacket("udp", addr)
if err != nil {
return nil, err
}
err = l.SetDeadline(time.Now().Add(100 * time.Millisecond))
if err != nil {
return nil, err
}
err = l.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
if err != nil {
return nil, err
}
err = l.SetWriteDeadline(time.Now().Add(100 * time.Millisecond))
if err != nil {
return nil, err
}
return l.(*net.UDPConn), nil
}