mirror of
https://github.com/opencontainers/runc.git
synced 2025-12-24 11:50:58 +08:00
Commit b2f8a74d "clothed" the naked return as inflicted by gofumpt
v0.9.0. Since gofumpt v0.9.2 this rule was moved to "extra" category,
not enabled by default. The only other "extra" rule is to group adjacent
parameters with the same type, which also makes sense.
Enable gofumpt "extra" rules, and reformat the code accordingly.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
167 lines
3.3 KiB
Go
167 lines
3.3 KiB
Go
package logs
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
const msgErr = `"level":"error"`
|
|
|
|
func TestLoggingToFile(t *testing.T) {
|
|
l := runLogForwarding(t)
|
|
|
|
msg := `"level":"info","msg":"kitten"`
|
|
logToLogWriter(t, l, msg)
|
|
finish(t, l)
|
|
check(t, l, msg, msgErr)
|
|
}
|
|
|
|
func TestLogForwardingDoesNotStopOnJsonDecodeErr(t *testing.T) {
|
|
l := runLogForwarding(t)
|
|
|
|
logToLogWriter(t, l, `"invalid-json-with-kitten"`)
|
|
checkWait(t, l, msgErr, "")
|
|
|
|
truncateLogFile(t, l.file)
|
|
|
|
msg := `"level":"info","msg":"puppy"`
|
|
logToLogWriter(t, l, msg)
|
|
finish(t, l)
|
|
check(t, l, msg, msgErr)
|
|
}
|
|
|
|
func TestLogForwardingDoesNotStopOnLogLevelParsingErr(t *testing.T) {
|
|
l := runLogForwarding(t)
|
|
|
|
msg := `"level":"alert","msg":"puppy"`
|
|
logToLogWriter(t, l, msg)
|
|
checkWait(t, l, msgErr, msg)
|
|
|
|
truncateLogFile(t, l.file)
|
|
|
|
msg = `"level":"info","msg":"puppy"`
|
|
logToLogWriter(t, l, msg)
|
|
finish(t, l)
|
|
check(t, l, msg, msgErr)
|
|
}
|
|
|
|
func TestLogForwardingStopsAfterClosingTheWriter(t *testing.T) {
|
|
l := runLogForwarding(t)
|
|
|
|
msg := `"level":"info","msg":"sync"`
|
|
logToLogWriter(t, l, msg)
|
|
|
|
// Do not use finish() here as we check done pipe ourselves.
|
|
l.w.Close()
|
|
select {
|
|
case <-l.done:
|
|
case <-time.After(10 * time.Second):
|
|
t.Fatal("log forwarding did not stop after closing the pipe")
|
|
}
|
|
|
|
check(t, l, msg, msgErr)
|
|
}
|
|
|
|
func logToLogWriter(t *testing.T, l *log, message string) {
|
|
t.Helper()
|
|
_, err := l.w.Write([]byte("{" + message + "}\n"))
|
|
if err != nil {
|
|
t.Fatalf("failed to write %q to log writer: %v", message, err)
|
|
}
|
|
}
|
|
|
|
type log struct {
|
|
w io.WriteCloser
|
|
file *os.File
|
|
done chan error
|
|
}
|
|
|
|
func runLogForwarding(t *testing.T) *log {
|
|
t.Helper()
|
|
logR, logW, err := os.Pipe()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Cleanup(func() {
|
|
logR.Close()
|
|
logW.Close()
|
|
})
|
|
|
|
tempFile, err := os.CreateTemp("", "")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Cleanup(func() {
|
|
tempFile.Close()
|
|
os.Remove(tempFile.Name())
|
|
})
|
|
|
|
logrus.SetOutput(tempFile)
|
|
logrus.SetFormatter(&logrus.JSONFormatter{})
|
|
doneForwarding := ForwardLogs(logR)
|
|
|
|
return &log{w: logW, done: doneForwarding, file: tempFile}
|
|
}
|
|
|
|
func finish(t *testing.T, l *log) {
|
|
t.Helper()
|
|
l.w.Close()
|
|
if err := <-l.done; err != nil {
|
|
t.Fatalf("ForwardLogs: %v", err)
|
|
}
|
|
}
|
|
|
|
func truncateLogFile(t *testing.T, file *os.File) {
|
|
t.Helper()
|
|
|
|
err := file.Truncate(0)
|
|
if err != nil {
|
|
t.Fatalf("failed to truncate log file: %v", err)
|
|
}
|
|
}
|
|
|
|
// check checks that the file contains txt and does not contain notxt.
|
|
func check(t *testing.T, l *log, txt, notxt string) {
|
|
t.Helper()
|
|
contents, err := os.ReadFile(l.file.Name())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if txt != "" && !bytes.Contains(contents, []byte(txt)) {
|
|
t.Fatalf("%s does not contain %s", contents, txt)
|
|
}
|
|
if notxt != "" && bytes.Contains(contents, []byte(notxt)) {
|
|
t.Fatalf("%s does contain %s", contents, notxt)
|
|
}
|
|
}
|
|
|
|
// checkWait is like check, but if the file is empty,
|
|
// it waits until it's not.
|
|
func checkWait(t *testing.T, l *log, txt, notxt string) {
|
|
t.Helper()
|
|
const (
|
|
delay = 100 * time.Millisecond
|
|
iter = 3
|
|
)
|
|
for i := 0; ; i++ {
|
|
st, err := l.file.Stat()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if st.Size() > 0 {
|
|
break
|
|
}
|
|
if i == iter {
|
|
t.Fatalf("waited %s for file %s to be non-empty but it still is", iter*delay, l.file.Name())
|
|
}
|
|
time.Sleep(delay)
|
|
}
|
|
|
|
check(t, l, txt, notxt)
|
|
}
|