blob: 0fb7189b1c1002985d6534d45d9de02f310dedef [file] [log] [blame]
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package eventtest
import (
"context"
"io"
"strings"
"testing"
"github.com/google/go-cmp/cmp"
"golang.org/x/exp/event/adapter/logfmt"
)
type Info struct {
Name string
Msg string
Msgf string
}
type Hooks struct {
AStart func(ctx context.Context, a int) context.Context
AEnd func(ctx context.Context)
BStart func(ctx context.Context, b string) context.Context
BEnd func(ctx context.Context)
}
var (
initialList = []int{0, 1, 22, 333, 4444, 55555, 666666, 7777777}
stringList = []string{
"A value",
"Some other value",
"A nice longer value but not too long",
"V",
" ",
"ı",
"prime count of values",
}
A = Info{
Name: "A",
Msg: "a",
Msgf: "a where A=%d",
}
B = Info{
Name: "B",
Msg: "b",
Msgf: "b where B=%q",
}
)
const (
TimeFormat = logfmt.TimeFormat
LogfmtOutput = `
time="2020/03/05 14:27:48" level=info A=0 msg=a
time="2020/03/05 14:27:49" level=info B="A value" msg=b
time="2020/03/05 14:27:50" level=info A=1 msg=a
time="2020/03/05 14:27:51" level=info B="Some other value" msg=b
time="2020/03/05 14:27:52" level=info A=22 msg=a
time="2020/03/05 14:27:53" level=info B="Some other value" msg=b
time="2020/03/05 14:27:54" level=info A=333 msg=a
time="2020/03/05 14:27:55" level=info B=" " msg=b
time="2020/03/05 14:27:56" level=info A=4444 msg=a
time="2020/03/05 14:27:57" level=info B="prime count of values" msg=b
time="2020/03/05 14:27:58" level=info A=55555 msg=a
time="2020/03/05 14:27:59" level=info B=V msg=b
time="2020/03/05 14:28:00" level=info A=666666 msg=a
time="2020/03/05 14:28:01" level=info B="A value" msg=b
time="2020/03/05 14:28:02" level=info A=7777777 msg=a
time="2020/03/05 14:28:03" level=info B="A value" msg=b
`
LogfOutput = `
time="2020/03/05 14:27:48" level=info msg="a where A=0"
time="2020/03/05 14:27:49" level=info msg="b where B=\"A value\""
time="2020/03/05 14:27:50" level=info msg="a where A=1"
time="2020/03/05 14:27:51" level=info msg="b where B=\"Some other value\""
time="2020/03/05 14:27:52" level=info msg="a where A=22"
time="2020/03/05 14:27:53" level=info msg="b where B=\"Some other value\""
time="2020/03/05 14:27:54" level=info msg="a where A=333"
time="2020/03/05 14:27:55" level=info msg="b where B=\" \""
time="2020/03/05 14:27:56" level=info msg="a where A=4444"
time="2020/03/05 14:27:57" level=info msg="b where B=\"prime count of values\""
time="2020/03/05 14:27:58" level=info msg="a where A=55555"
time="2020/03/05 14:27:59" level=info msg="b where B=\"V\""
time="2020/03/05 14:28:00" level=info msg="a where A=666666"
time="2020/03/05 14:28:01" level=info msg="b where B=\"A value\""
time="2020/03/05 14:28:02" level=info msg="a where A=7777777"
time="2020/03/05 14:28:03" level=info msg="b where B=\"A value\""
`
)
type namedBenchmark struct {
name string
test func(ctx context.Context) func(*testing.B)
}
func benchA(ctx context.Context, hooks Hooks, a int) int {
ctx = hooks.AStart(ctx, a)
defer hooks.AEnd(ctx)
return benchB(ctx, hooks, a, stringList[a%len(stringList)])
}
func benchB(ctx context.Context, hooks Hooks, a int, b string) int {
ctx = hooks.BStart(ctx, b)
defer hooks.BEnd(ctx)
return a + len(b)
}
func runOnce(ctx context.Context, hooks Hooks) {
var acc int
for _, value := range initialList {
acc += benchA(ctx, hooks, value)
}
}
func RunBenchmark(b *testing.B, ctx context.Context, hooks Hooks) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
runOnce(ctx, hooks)
}
}
func TestBenchmark(t *testing.T, f func(io.Writer) context.Context, hooks Hooks, expect string) {
buf := strings.Builder{}
ctx := f(&buf)
runOnce(ctx, hooks)
got := strings.TrimSpace(buf.String())
expect = strings.TrimSpace(expect)
if diff := cmp.Diff(got, expect); diff != "" {
t.Error(diff)
}
}
func TestAllocs(t *testing.T, f func(io.Writer) context.Context, hooks Hooks, expect int) {
t.Helper()
var acc int
ctx := f(io.Discard)
got := int(testing.AllocsPerRun(5, func() {
for _, value := range initialList {
acc += benchA(ctx, hooks, value)
}
}))
if got != expect {
t.Errorf("Got %d allocs, expect %d", got, expect)
}
}