268 lines
7.9 KiB
Go
268 lines
7.9 KiB
Go
// 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/letsencrypt/boulder/Godeps/_workspace/src/github.com/cactus/go-statsd-client/statsd"
|
|
"github.com/letsencrypt/boulder/test"
|
|
)
|
|
|
|
func TestConstruction(t *testing.T) {
|
|
t.Parallel()
|
|
writer, err := syslog.New(syslog.LOG_EMERG|syslog.LOG_KERN, "tag")
|
|
test.AssertNotError(t, err, "Could not construct syslog object")
|
|
|
|
stats, _ := statsd.NewNoopClient(nil)
|
|
_, err = NewAuditLogger(writer, stats)
|
|
test.AssertNotError(t, err, "Could not construct audit logger")
|
|
}
|
|
|
|
func TestSingleton(t *testing.T) {
|
|
t.Parallel()
|
|
log1 := GetAuditLogger()
|
|
test.AssertNotNil(t, log1, "Logger shouldn't be nil")
|
|
|
|
log2 := GetAuditLogger()
|
|
test.AssertEquals(t, log1, log2)
|
|
|
|
writer, err := syslog.New(syslog.LOG_EMERG|syslog.LOG_KERN, "tag")
|
|
test.AssertNotError(t, err, "Could not construct syslog object")
|
|
|
|
stats, _ := statsd.NewNoopClient(nil)
|
|
log3, err := NewAuditLogger(writer, stats)
|
|
test.AssertNotError(t, err, "Could not construct audit logger")
|
|
|
|
// Should not work
|
|
err = SetAuditLogger(log3)
|
|
test.AssertError(t, err, "Can't re-set")
|
|
|
|
// Verify no change
|
|
log4 := GetAuditLogger()
|
|
|
|
// Verify that log4 != log3
|
|
test.AssertNotEquals(t, log4, log3)
|
|
|
|
// Verify that log4 == log2 == log1
|
|
test.AssertEquals(t, log4, log2)
|
|
test.AssertEquals(t, log4, log1)
|
|
}
|
|
|
|
func TestDial(t *testing.T) {
|
|
t.Parallel()
|
|
stats, _ := statsd.NewNoopClient(nil)
|
|
_, err := Dial("", "", "tag", stats)
|
|
test.AssertNotError(t, err, "Could not construct audit logger")
|
|
}
|
|
|
|
func TestDialError(t *testing.T) {
|
|
t.Parallel()
|
|
stats, _ := statsd.NewNoopClient(nil)
|
|
_, err := Dial("_fail", "_fail", "tag", stats)
|
|
test.AssertError(t, err, "Audit Logger should have failed")
|
|
}
|
|
|
|
func TestConstructionNil(t *testing.T) {
|
|
t.Parallel()
|
|
stats, _ := statsd.NewNoopClient(nil)
|
|
_, err := NewAuditLogger(nil, stats)
|
|
test.AssertError(t, err, "Nil shouldn't be permitted.")
|
|
}
|
|
|
|
func TestEmit(t *testing.T) {
|
|
t.Parallel()
|
|
writer, err := syslog.New(syslog.LOG_EMERG|syslog.LOG_KERN, "tag")
|
|
test.AssertNotError(t, err, "Could not construct syslog object")
|
|
|
|
stats, _ := statsd.NewNoopClient(nil)
|
|
audit, err := NewAuditLogger(writer, stats)
|
|
test.AssertNotError(t, err, "Could not construct audit logger")
|
|
|
|
audit.Audit("test message")
|
|
}
|
|
|
|
func TestEmitEmpty(t *testing.T) {
|
|
t.Parallel()
|
|
writer, err := syslog.New(syslog.LOG_EMERG|syslog.LOG_KERN, "tag")
|
|
test.AssertNotError(t, err, "Could not construct syslog object")
|
|
|
|
stats, _ := statsd.NewNoopClient(nil)
|
|
audit, err := NewAuditLogger(writer, stats)
|
|
test.AssertNotError(t, err, "Could not construct audit logger")
|
|
|
|
audit.Audit("")
|
|
}
|
|
|
|
func TestEmitErrors(t *testing.T) {
|
|
t.Parallel()
|
|
stats, _ := statsd.NewNoopClient(nil)
|
|
audit, _ := Dial("", "", "tag", stats)
|
|
|
|
audit.AuditErr(errors.New("Error Audit"))
|
|
audit.WarningErr(errors.New("Warning Audit"))
|
|
}
|
|
|
|
func TestSyslogMethods(t *testing.T) {
|
|
t.Parallel()
|
|
// Write all logs to UDP on a high port so as to not bother the system
|
|
// which is running the test, particularly for Emerg()
|
|
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")
|
|
|
|
stats, _ := statsd.NewNoopClient(nil)
|
|
audit, err := NewAuditLogger(writer, stats)
|
|
test.AssertNotError(t, err, "Could not construct audit logger")
|
|
|
|
audit.Audit("audit-logger_test.go: audit-notice")
|
|
audit.Crit("audit-logger_test.go: critical")
|
|
audit.Debug("audit-logger_test.go: debug")
|
|
audit.Emerg("audit-logger_test.go: emerg")
|
|
audit.Err("audit-logger_test.go: err")
|
|
audit.Info("audit-logger_test.go: info")
|
|
audit.Notice("audit-logger_test.go: notice")
|
|
audit.Warning("audit-logger_test.go: warning")
|
|
audit.Alert("audit-logger_test.go: alert")
|
|
}
|
|
|
|
func TestPanic(t *testing.T) {
|
|
t.Parallel()
|
|
stats, _ := statsd.NewNoopClient(nil)
|
|
audit, _ := Dial("", "", "tag", stats)
|
|
defer audit.AuditPanic()
|
|
panic("Test panic")
|
|
// Can't assert anything here or golint gets angry
|
|
}
|
|
|
|
func TestAuditObject(t *testing.T) {
|
|
t.Parallel()
|
|
stats, _ := statsd.NewNoopClient(nil)
|
|
audit, _ := Dial("", "", "tag", stats)
|
|
|
|
// Test a simple object
|
|
err := audit.AuditObject("Prefix", "String")
|
|
test.AssertNotError(t, err, "Simple objects should be serializable")
|
|
|
|
// Test a system object
|
|
err = audit.AuditObject("Prefix", t)
|
|
test.AssertNotError(t, err, "System objects should be serializable")
|
|
|
|
// Test a complex object
|
|
type validObj struct {
|
|
A string
|
|
B string
|
|
}
|
|
var valid = validObj{A: "B", B: "C"}
|
|
err = audit.AuditObject("Prefix", valid)
|
|
test.AssertNotError(t, err, "Complex objects should be serializable")
|
|
|
|
type invalidObj struct {
|
|
A chan string
|
|
}
|
|
|
|
var invalid = invalidObj{A: make(chan string)}
|
|
err = audit.AuditObject("Prefix", invalid)
|
|
test.AssertError(t, err, "Invalid objects should fail serialization")
|
|
|
|
}
|
|
|
|
func TestEmergencyExit(t *testing.T) {
|
|
t.Parallel()
|
|
// Write all logs to UDP on a high port so as to not bother the system
|
|
// which is running the test, particularly for Emerg()
|
|
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")
|
|
|
|
stats, _ := statsd.NewNoopClient(nil)
|
|
audit, err := NewAuditLogger(writer, stats)
|
|
test.AssertNotError(t, err, "Could not construct audit logger")
|
|
|
|
called := false
|
|
|
|
audit.SetEmergencyExitFunc(func() { called = true })
|
|
audit.EmergencyExit("Emergency!")
|
|
test.AssertEquals(t, called, true)
|
|
}
|
|
|
|
func TestUnknownLoggingLevel(t *testing.T) {
|
|
t.Parallel()
|
|
stats, _ := statsd.NewNoopClient(nil)
|
|
audit, _ := Dial("", "", "tag", stats)
|
|
|
|
err := audit.logAtLevel("Logging.Unknown", "string")
|
|
test.AssertError(t, err, "Should have been unknown.")
|
|
}
|
|
|
|
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 l.Close()
|
|
|
|
stats, _ := statsd.NewNoopClient(nil)
|
|
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")
|
|
|
|
audit, err := NewAuditLogger(writer, stats)
|
|
test.AssertNotError(t, err, "Failed to construct audit logger")
|
|
|
|
data := make([]byte, 128)
|
|
|
|
audit.Audit("audit-logger_test.go: audit-notice")
|
|
_, _, err = l.ReadFrom(data)
|
|
test.AssertNotError(t, err, "Failed to find packet")
|
|
|
|
audit.Crit("audit-logger_test.go: critical")
|
|
_, _, err = l.ReadFrom(data)
|
|
test.AssertNotError(t, err, "Failed to find packet")
|
|
|
|
audit.Debug("audit-logger_test.go: debug")
|
|
_, _, err = l.ReadFrom(data)
|
|
test.AssertNotError(t, err, "Failed to find packet")
|
|
|
|
audit.Emerg("audit-logger_test.go: emerg")
|
|
_, _, err = l.ReadFrom(data)
|
|
test.AssertNotError(t, err, "Failed to find packet")
|
|
|
|
audit.Err("audit-logger_test.go: err")
|
|
_, _, err = l.ReadFrom(data)
|
|
test.AssertNotError(t, err, "Failed to find packet")
|
|
|
|
audit.Info("audit-logger_test.go: info")
|
|
_, _, err = l.ReadFrom(data)
|
|
test.AssertNotError(t, err, "Failed to find packet")
|
|
|
|
audit.Notice("audit-logger_test.go: notice")
|
|
_, _, err = l.ReadFrom(data)
|
|
test.AssertNotError(t, err, "Failed to find packet")
|
|
|
|
audit.Warning("audit-logger_test.go: warning")
|
|
_, _, err = l.ReadFrom(data)
|
|
test.AssertNotError(t, err, "Failed to find packet")
|
|
|
|
audit.Alert("audit-logger_test.go: alert")
|
|
_, _, 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
|
|
}
|
|
l.SetDeadline(time.Now().Add(100 * time.Millisecond))
|
|
l.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
|
|
l.SetWriteDeadline(time.Now().Add(100 * time.Millisecond))
|
|
return l.(*net.UDPConn), nil
|
|
}
|