blob: 7f7bea97f89abb93b7b04613203e8a461231d094 [file] [log] [blame]
// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package log_test
import (
"bytes"
"os"
"testing"
"io"
"android.googlesource.com/platform/tools/gpu/framework/assert"
"android.googlesource.com/platform/tools/gpu/framework/log"
)
func TestHandlerContext(t *testing.T) {
ctx := log.Background()
id := 0
ctx = ctx.Handler(func(log.Record) { id = 1 })
log.GetHandler(ctx)(log.Record{})
if id != 1 {
t.Errorf("Context did not install Handler correctly, got %v", id)
}
ctx = ctx.Handler(func(log.Record) { id = 2 })
log.GetHandler(ctx)(log.Record{})
if id != 2 {
t.Errorf("Context did not override Handler correctly, got %v", id)
}
}
type handlerTest struct {
severity log.Severity
message string
expect string
}
var tests = []handlerTest{
{log.EmergencyLevel, "Hello", "Emergency:Hello\n"},
{log.AlertLevel, "Hello", "Alert:Hello\n"},
{log.CriticalLevel, "Hello", "Critical:Hello\n"},
{log.ErrorLevel, "Hello", "Error:Hello\n"},
{log.WarningLevel, "Hello", "Warning:Hello\n"},
{log.NoticeLevel, "Hello", "Notice:Hello\n"},
{log.InfoLevel, "Hello", "Info:Hello\n"},
{log.DebugLevel, "Hello", "Debug:Hello\n"},
}
func testHandler(handler log.Handler, test handlerTest) {
handler(log.Background().Severity(test.severity).Record(test.message))
}
func TestWriter(t *testing.T) {
buf := &bytes.Buffer{}
handler := log.Writer(log.Normal, buf)
for _, test := range tests {
buf.Reset()
testHandler(handler, test)
got := buf.String()
if got != test.expect {
t.Errorf("Got %v expected %v", got, test.expect)
}
}
}
type trapped struct {
file **os.File
old *os.File
r *os.File
w *os.File
}
// Trap replaces file with a pipe, but does nothing to make writes to that pipe non blocking
func trap(file **os.File) trapped {
t := trapped{file: file, old: *file}
t.r, t.w, _ = os.Pipe()
*file = t.w
return t
}
// read collects closes the pipe, and then collects everything written to it.
// there is an implicit assumption that the os will buffer inside the pipe everything we wrote to it
// if the os buffer is not big enough, the write will block
func (t trapped) read() string {
t.w.Close()
buf := &bytes.Buffer{}
io.Copy(buf, t.r)
*t.file = t.old
return buf.String()
}
func TestStdout(t *testing.T) {
for _, test := range tests {
stdout := trap(&os.Stdout)
testHandler(log.Stdout(log.Normal), test)
got := stdout.read()
if got != test.expect {
t.Errorf("Got %v expected %v", got, test.expect)
}
}
}
func TestStderr(t *testing.T) {
for _, test := range tests {
stderr := trap(&os.Stderr)
testHandler(log.Stderr(log.Normal), test)
got := stderr.read()
if got != test.expect {
t.Errorf("Got %v expected %v", got, test.expect)
}
}
}
func TestStd(t *testing.T) {
for _, test := range tests {
stdout := trap(&os.Stdout)
stderr := trap(&os.Stderr)
testHandler(log.Std(log.Normal), test)
gotErr := stderr.read()
gotOut := stdout.read()
var expectErr, expectOut string
if test.severity <= log.ErrorLevel {
expectErr = test.expect
} else {
expectOut = test.expect
}
if gotErr != expectErr {
t.Errorf("Got Stderr %v expected %v", gotErr, expectErr)
}
if gotOut != expectOut {
t.Errorf("Got Stdout %v expected %v", gotOut, expectOut)
}
}
}
func TestTestingStdout(t *testing.T) {
const expect = "Info:Hello\n"
stdout := trap(&os.Stdout)
assert.Context(nil).Print("Hello")
got := stdout.read()
if got != expect {
t.Errorf("Got %v expected %v", got, expect)
}
}
func pingHandler(c chan struct{}, h log.Handler) log.Handler {
return func(r log.Record) {
h(r)
c <- struct{}{}
}
}
func TestChannel(t *testing.T) {
buf := &bytes.Buffer{}
ping := make(chan struct{})
handler, closer := log.Channel(pingHandler(ping, log.Writer(log.Normal, buf)))
defer closer()
for _, test := range tests {
buf.Reset()
testHandler(handler, test)
<-ping
got := buf.String()
if got != test.expect {
t.Errorf("Got %v expected %v", got, test.expect)
}
}
}
func TestFork(t *testing.T) {
aBuf := &bytes.Buffer{}
bBuf := &bytes.Buffer{}
cBuf := &bytes.Buffer{}
handler := log.Fork(
log.Writer(log.Normal, aBuf),
log.Writer(log.Normal, bBuf),
log.Writer(log.Normal, cBuf))
for _, test := range tests {
aBuf.Reset()
bBuf.Reset()
cBuf.Reset()
testHandler(handler, test)
if aBuf.String() != test.expect {
t.Errorf("For a got %q expected %q", aBuf.String(), test.expect)
}
if bBuf.String() != test.expect {
t.Errorf("For a got %q expected %q", bBuf.String(), test.expect)
}
if cBuf.String() != test.expect {
t.Errorf("For a got %q expected %q", cBuf.String(), test.expect)
}
}
}
func TestLimitSplit(t *testing.T) {
lowBuf := &bytes.Buffer{}
highBuf := &bytes.Buffer{}
for limit := log.EmergencyLevel; limit <= log.DebugLevel; limit++ {
handler := log.LimitSplit(limit, log.Writer(log.Normal, highBuf), log.Writer(log.Normal, lowBuf))
for _, test := range tests {
lowBuf.Reset()
highBuf.Reset()
testHandler(handler, test)
gotLow := lowBuf.String()
gotHigh := highBuf.String()
expectLow := ""
expectHigh := ""
if test.severity <= limit {
expectHigh = test.expect
} else {
expectLow = test.expect
}
if gotLow != expectLow {
t.Errorf("For %v got low %q expected %q", limit, gotLow, expectLow)
}
if gotHigh != expectHigh {
t.Errorf("For %v got high %q expected %q", limit, gotHigh, expectHigh)
}
}
}
}