boulder/log/log_test.go

229 lines
5.4 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.

// Copyright 2014 ISRG. All rights reserved
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package log
import (
"errors"
"fmt"
"log/syslog"
"net"
"testing"
"time"
"github.com/jmhodges/clock"
"github.com/letsencrypt/boulder/test"
)
const stdoutLevel = 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)
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)
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)
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 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
}