Files
coredns/plugin/log/log_test.go

280 lines
5.9 KiB
Go
Raw Normal View History

2016-03-18 20:57:35 +00:00
package log
2016-03-19 11:16:08 +00:00
import (
"bytes"
"context"
"io"
2016-03-19 11:16:08 +00:00
"log"
"strings"
"testing"
"github.com/coredns/coredns/plugin/pkg/dnstest"
clog "github.com/coredns/coredns/plugin/pkg/log"
pkg/replace: make it more efficient. (#2544) * pkg/replace: make it more efficient. Remove the map that is allocated on every write and make it more static, but just defining a function that gets called for a label and returns its value. Remove the interface definition and just implement what is needed in our case. Add benchmark test for replace as well. Extend metadata test to test multiple values (pretty sure this didn't work, but there wasn't a test for it, so can't be sure). Update all callers to use it - concurrent use should be fine as we pass everything by value. Benchmarks in replacer: new: BenchmarkReplacer-4 300000 4717 ns/op 240 B/op 8 allocs/op old: BenchmarkReplacer-4 300000 4368 ns/op 384 B/op 11 allocs/op Added benchmark function to the old code to test it. ~~~ func BenchmarkReplacer(b *testing.B) { w := dnstest.NewRecorder(&test.ResponseWriter{}) r := new(dns.Msg) r.SetQuestion("example.org.", dns.TypeHINFO) r.MsgHdr.AuthenticatedData = true b.ResetTimer() b.ReportAllocs() repl := New(context.TODO(), r, w, "") for i := 0; i < b.N; i++ { repl.Replace("{type} {name} {size}") } } ~~~ New code contains (of course a different one). The amount of ops is more, which might be good to look at some more. For all the allocations is seems it was quite performant. This looks to be 50% faster, and there is less allocations in log plugin: old: BenchmarkLogged-4 20000 70526 ns/op new: BenchmarkLogged-4 30000 57558 ns/op Signed-off-by: Miek Gieben <miek@miek.nl> * Stickler bot Signed-off-by: Miek Gieben <miek@miek.nl> * Improve test coverage Signed-off-by: Miek Gieben <miek@miek.nl> * typo Signed-off-by: Miek Gieben <miek@miek.nl> * Add test for malformed log lines Signed-off-by: Miek Gieben <miek@miek.nl>
2019-02-12 07:38:49 +00:00
"github.com/coredns/coredns/plugin/pkg/replacer"
"github.com/coredns/coredns/plugin/pkg/response"
"github.com/coredns/coredns/plugin/test"
2016-03-19 11:16:08 +00:00
"github.com/miekg/dns"
)
func init() { clog.Discard() }
2016-03-18 20:57:35 +00:00
func TestLoggedStatus(t *testing.T) {
rule := Rule{
2016-03-19 11:16:08 +00:00
NameScope: ".",
2016-03-18 20:57:35 +00:00
Format: DefaultLogFormat,
Class: map[response.Class]struct{}{response.All: {}},
2016-03-18 20:57:35 +00:00
}
var f bytes.Buffer
log.SetOutput(&f)
2016-03-18 20:57:35 +00:00
logger := Logger{
Rules: []Rule{rule},
Next: test.ErrorHandler(),
pkg/replace: make it more efficient. (#2544) * pkg/replace: make it more efficient. Remove the map that is allocated on every write and make it more static, but just defining a function that gets called for a label and returns its value. Remove the interface definition and just implement what is needed in our case. Add benchmark test for replace as well. Extend metadata test to test multiple values (pretty sure this didn't work, but there wasn't a test for it, so can't be sure). Update all callers to use it - concurrent use should be fine as we pass everything by value. Benchmarks in replacer: new: BenchmarkReplacer-4 300000 4717 ns/op 240 B/op 8 allocs/op old: BenchmarkReplacer-4 300000 4368 ns/op 384 B/op 11 allocs/op Added benchmark function to the old code to test it. ~~~ func BenchmarkReplacer(b *testing.B) { w := dnstest.NewRecorder(&test.ResponseWriter{}) r := new(dns.Msg) r.SetQuestion("example.org.", dns.TypeHINFO) r.MsgHdr.AuthenticatedData = true b.ResetTimer() b.ReportAllocs() repl := New(context.TODO(), r, w, "") for i := 0; i < b.N; i++ { repl.Replace("{type} {name} {size}") } } ~~~ New code contains (of course a different one). The amount of ops is more, which might be good to look at some more. For all the allocations is seems it was quite performant. This looks to be 50% faster, and there is less allocations in log plugin: old: BenchmarkLogged-4 20000 70526 ns/op new: BenchmarkLogged-4 30000 57558 ns/op Signed-off-by: Miek Gieben <miek@miek.nl> * Stickler bot Signed-off-by: Miek Gieben <miek@miek.nl> * Improve test coverage Signed-off-by: Miek Gieben <miek@miek.nl> * typo Signed-off-by: Miek Gieben <miek@miek.nl> * Add test for malformed log lines Signed-off-by: Miek Gieben <miek@miek.nl>
2019-02-12 07:38:49 +00:00
repl: replacer.New(),
2016-03-18 20:57:35 +00:00
}
2016-03-19 11:16:08 +00:00
ctx := context.TODO()
r := new(dns.Msg)
r.SetQuestion("example.org.", dns.TypeA)
2016-03-18 20:57:35 +00:00
rec := dnstest.NewRecorder(&test.ResponseWriter{})
2016-03-18 20:57:35 +00:00
2016-03-19 11:16:08 +00:00
rcode, _ := logger.ServeDNS(ctx, rec, r)
if rcode != 2 {
t.Errorf("Expected rcode to be 2 - was: %d", rcode)
2016-03-18 20:57:35 +00:00
}
logged := f.String()
if !strings.Contains(logged, "A IN example.org. udp 29 false 512") {
t.Errorf("Expected it to be logged. Logged string: %s", logged)
}
}
func TestLoggedClassDenial(t *testing.T) {
rule := Rule{
NameScope: ".",
Format: DefaultLogFormat,
Class: map[response.Class]struct{}{response.Denial: {}},
}
var f bytes.Buffer
log.SetOutput(&f)
logger := Logger{
Rules: []Rule{rule},
Next: test.ErrorHandler(),
pkg/replace: make it more efficient. (#2544) * pkg/replace: make it more efficient. Remove the map that is allocated on every write and make it more static, but just defining a function that gets called for a label and returns its value. Remove the interface definition and just implement what is needed in our case. Add benchmark test for replace as well. Extend metadata test to test multiple values (pretty sure this didn't work, but there wasn't a test for it, so can't be sure). Update all callers to use it - concurrent use should be fine as we pass everything by value. Benchmarks in replacer: new: BenchmarkReplacer-4 300000 4717 ns/op 240 B/op 8 allocs/op old: BenchmarkReplacer-4 300000 4368 ns/op 384 B/op 11 allocs/op Added benchmark function to the old code to test it. ~~~ func BenchmarkReplacer(b *testing.B) { w := dnstest.NewRecorder(&test.ResponseWriter{}) r := new(dns.Msg) r.SetQuestion("example.org.", dns.TypeHINFO) r.MsgHdr.AuthenticatedData = true b.ResetTimer() b.ReportAllocs() repl := New(context.TODO(), r, w, "") for i := 0; i < b.N; i++ { repl.Replace("{type} {name} {size}") } } ~~~ New code contains (of course a different one). The amount of ops is more, which might be good to look at some more. For all the allocations is seems it was quite performant. This looks to be 50% faster, and there is less allocations in log plugin: old: BenchmarkLogged-4 20000 70526 ns/op new: BenchmarkLogged-4 30000 57558 ns/op Signed-off-by: Miek Gieben <miek@miek.nl> * Stickler bot Signed-off-by: Miek Gieben <miek@miek.nl> * Improve test coverage Signed-off-by: Miek Gieben <miek@miek.nl> * typo Signed-off-by: Miek Gieben <miek@miek.nl> * Add test for malformed log lines Signed-off-by: Miek Gieben <miek@miek.nl>
2019-02-12 07:38:49 +00:00
repl: replacer.New(),
}
ctx := context.TODO()
r := new(dns.Msg)
r.SetQuestion("example.org.", dns.TypeA)
rec := dnstest.NewRecorder(&test.ResponseWriter{})
logger.ServeDNS(ctx, rec, r)
logged := f.String()
if len(logged) != 0 {
t.Errorf("Expected it not to be logged, but got string: %s", logged)
}
}
func TestLoggedClassError(t *testing.T) {
rule := Rule{
NameScope: ".",
Format: DefaultLogFormat,
Class: map[response.Class]struct{}{response.Error: {}},
}
var f bytes.Buffer
log.SetOutput(&f)
logger := Logger{
Rules: []Rule{rule},
Next: test.ErrorHandler(),
pkg/replace: make it more efficient. (#2544) * pkg/replace: make it more efficient. Remove the map that is allocated on every write and make it more static, but just defining a function that gets called for a label and returns its value. Remove the interface definition and just implement what is needed in our case. Add benchmark test for replace as well. Extend metadata test to test multiple values (pretty sure this didn't work, but there wasn't a test for it, so can't be sure). Update all callers to use it - concurrent use should be fine as we pass everything by value. Benchmarks in replacer: new: BenchmarkReplacer-4 300000 4717 ns/op 240 B/op 8 allocs/op old: BenchmarkReplacer-4 300000 4368 ns/op 384 B/op 11 allocs/op Added benchmark function to the old code to test it. ~~~ func BenchmarkReplacer(b *testing.B) { w := dnstest.NewRecorder(&test.ResponseWriter{}) r := new(dns.Msg) r.SetQuestion("example.org.", dns.TypeHINFO) r.MsgHdr.AuthenticatedData = true b.ResetTimer() b.ReportAllocs() repl := New(context.TODO(), r, w, "") for i := 0; i < b.N; i++ { repl.Replace("{type} {name} {size}") } } ~~~ New code contains (of course a different one). The amount of ops is more, which might be good to look at some more. For all the allocations is seems it was quite performant. This looks to be 50% faster, and there is less allocations in log plugin: old: BenchmarkLogged-4 20000 70526 ns/op new: BenchmarkLogged-4 30000 57558 ns/op Signed-off-by: Miek Gieben <miek@miek.nl> * Stickler bot Signed-off-by: Miek Gieben <miek@miek.nl> * Improve test coverage Signed-off-by: Miek Gieben <miek@miek.nl> * typo Signed-off-by: Miek Gieben <miek@miek.nl> * Add test for malformed log lines Signed-off-by: Miek Gieben <miek@miek.nl>
2019-02-12 07:38:49 +00:00
repl: replacer.New(),
}
ctx := context.TODO()
r := new(dns.Msg)
r.SetQuestion("example.org.", dns.TypeA)
rec := dnstest.NewRecorder(&test.ResponseWriter{})
logger.ServeDNS(ctx, rec, r)
logged := f.String()
if !strings.Contains(logged, "SERVFAIL") {
t.Errorf("Expected it to be logged. Logged string: %s", logged)
2016-03-18 20:57:35 +00:00
}
}
func TestLogged(t *testing.T) {
tests := []struct {
Rules []Rule
Domain string
ShouldLog bool
ShouldString string
ShouldNOTString string // for test format
}{
// case for NameScope
{
Rules: []Rule{
{
NameScope: "example.org.",
Format: DefaultLogFormat,
Class: map[response.Class]struct{}{response.All: {}},
},
},
Domain: "example.org.",
ShouldLog: true,
ShouldString: "A IN example.org.",
},
{
Rules: []Rule{
{
NameScope: "example.org.",
Format: DefaultLogFormat,
Class: map[response.Class]struct{}{response.All: {}},
},
},
Domain: "example.net.",
ShouldLog: false,
ShouldString: "",
},
{
Rules: []Rule{
{
NameScope: "example.org.",
Format: DefaultLogFormat,
Class: map[response.Class]struct{}{response.All: {}},
},
{
NameScope: "example.net.",
Format: DefaultLogFormat,
Class: map[response.Class]struct{}{response.All: {}},
},
},
Domain: "example.net.",
ShouldLog: true,
ShouldString: "A IN example.net.",
},
// case for format
{
Rules: []Rule{
{
NameScope: ".",
Format: "{type} {class}",
Class: map[response.Class]struct{}{response.All: {}},
},
},
Domain: "example.org.",
ShouldLog: true,
ShouldString: "A IN",
ShouldNOTString: "example.org",
},
{
Rules: []Rule{
{
NameScope: ".",
Format: "{remote}:{port}",
Class: map[response.Class]struct{}{response.All: {}},
},
},
Domain: "example.org.",
ShouldLog: true,
ShouldString: "10.240.0.1:40212",
ShouldNOTString: "A IN example.org",
},
{
Rules: []Rule{
{
NameScope: ".",
Format: CombinedLogFormat,
Class: map[response.Class]struct{}{response.All: {}},
},
},
Domain: "example.org.",
ShouldLog: true,
ShouldString: "\"0\"",
},
{
Rules: []Rule{
{
NameScope: ".",
Format: CombinedLogFormat,
Class: map[response.Class]struct{}{response.All: {}},
},
},
Domain: "foo.%s.example.org.",
ShouldLog: true,
ShouldString: "foo.%s.example.org.",
ShouldNOTString: "%!s(MISSING)",
},
}
for _, tc := range tests {
var f bytes.Buffer
log.SetOutput(&f)
logger := Logger{
Rules: tc.Rules,
Next: test.ErrorHandler(),
pkg/replace: make it more efficient. (#2544) * pkg/replace: make it more efficient. Remove the map that is allocated on every write and make it more static, but just defining a function that gets called for a label and returns its value. Remove the interface definition and just implement what is needed in our case. Add benchmark test for replace as well. Extend metadata test to test multiple values (pretty sure this didn't work, but there wasn't a test for it, so can't be sure). Update all callers to use it - concurrent use should be fine as we pass everything by value. Benchmarks in replacer: new: BenchmarkReplacer-4 300000 4717 ns/op 240 B/op 8 allocs/op old: BenchmarkReplacer-4 300000 4368 ns/op 384 B/op 11 allocs/op Added benchmark function to the old code to test it. ~~~ func BenchmarkReplacer(b *testing.B) { w := dnstest.NewRecorder(&test.ResponseWriter{}) r := new(dns.Msg) r.SetQuestion("example.org.", dns.TypeHINFO) r.MsgHdr.AuthenticatedData = true b.ResetTimer() b.ReportAllocs() repl := New(context.TODO(), r, w, "") for i := 0; i < b.N; i++ { repl.Replace("{type} {name} {size}") } } ~~~ New code contains (of course a different one). The amount of ops is more, which might be good to look at some more. For all the allocations is seems it was quite performant. This looks to be 50% faster, and there is less allocations in log plugin: old: BenchmarkLogged-4 20000 70526 ns/op new: BenchmarkLogged-4 30000 57558 ns/op Signed-off-by: Miek Gieben <miek@miek.nl> * Stickler bot Signed-off-by: Miek Gieben <miek@miek.nl> * Improve test coverage Signed-off-by: Miek Gieben <miek@miek.nl> * typo Signed-off-by: Miek Gieben <miek@miek.nl> * Add test for malformed log lines Signed-off-by: Miek Gieben <miek@miek.nl>
2019-02-12 07:38:49 +00:00
repl: replacer.New(),
}
ctx := context.TODO()
r := new(dns.Msg)
r.SetQuestion(tc.Domain, dns.TypeA)
rec := dnstest.NewRecorder(&test.ResponseWriter{})
_, err := logger.ServeDNS(ctx, rec, r)
if err != nil {
t.Fatal(err)
}
logged := f.String()
if !tc.ShouldLog && len(logged) != 0 {
t.Errorf("Expected it not to be logged, but got string: %s", logged)
}
if tc.ShouldLog && !strings.Contains(logged, tc.ShouldString) {
t.Errorf("Expected it to contains: %s. Logged string: %s", tc.ShouldString, logged)
}
if tc.ShouldLog && tc.ShouldNOTString != "" && strings.Contains(logged, tc.ShouldNOTString) {
t.Errorf("Expected it to NOT contains: %s. Logged string: %s", tc.ShouldNOTString, logged)
}
}
}
func BenchmarkLogged(b *testing.B) {
log.SetOutput(io.Discard)
rule := Rule{
NameScope: ".",
Format: DefaultLogFormat,
Class: map[response.Class]struct{}{response.All: {}},
}
logger := Logger{
Rules: []Rule{rule},
Next: test.ErrorHandler(),
pkg/replace: make it more efficient. (#2544) * pkg/replace: make it more efficient. Remove the map that is allocated on every write and make it more static, but just defining a function that gets called for a label and returns its value. Remove the interface definition and just implement what is needed in our case. Add benchmark test for replace as well. Extend metadata test to test multiple values (pretty sure this didn't work, but there wasn't a test for it, so can't be sure). Update all callers to use it - concurrent use should be fine as we pass everything by value. Benchmarks in replacer: new: BenchmarkReplacer-4 300000 4717 ns/op 240 B/op 8 allocs/op old: BenchmarkReplacer-4 300000 4368 ns/op 384 B/op 11 allocs/op Added benchmark function to the old code to test it. ~~~ func BenchmarkReplacer(b *testing.B) { w := dnstest.NewRecorder(&test.ResponseWriter{}) r := new(dns.Msg) r.SetQuestion("example.org.", dns.TypeHINFO) r.MsgHdr.AuthenticatedData = true b.ResetTimer() b.ReportAllocs() repl := New(context.TODO(), r, w, "") for i := 0; i < b.N; i++ { repl.Replace("{type} {name} {size}") } } ~~~ New code contains (of course a different one). The amount of ops is more, which might be good to look at some more. For all the allocations is seems it was quite performant. This looks to be 50% faster, and there is less allocations in log plugin: old: BenchmarkLogged-4 20000 70526 ns/op new: BenchmarkLogged-4 30000 57558 ns/op Signed-off-by: Miek Gieben <miek@miek.nl> * Stickler bot Signed-off-by: Miek Gieben <miek@miek.nl> * Improve test coverage Signed-off-by: Miek Gieben <miek@miek.nl> * typo Signed-off-by: Miek Gieben <miek@miek.nl> * Add test for malformed log lines Signed-off-by: Miek Gieben <miek@miek.nl>
2019-02-12 07:38:49 +00:00
repl: replacer.New(),
}
ctx := context.TODO()
r := new(dns.Msg)
r.SetQuestion("example.org.", dns.TypeA)
rec := dnstest.NewRecorder(&test.ResponseWriter{})
for b.Loop() {
logger.ServeDNS(ctx, rec, r)
}
}