mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-31 15:25:57 +00:00
Add unit test for kuberuntime container logs.
This commit is contained in:
parent
8e376dc843
commit
35195ef50e
269
pkg/kubelet/kuberuntime/kuberuntime_logs_test.go
Normal file
269
pkg/kubelet/kuberuntime/kuberuntime_logs_test.go
Normal file
@ -0,0 +1,269 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
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 kuberuntime
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
)
|
||||
|
||||
func TestLogOptions(t *testing.T) {
|
||||
var (
|
||||
line = int64(8)
|
||||
bytes = int64(64)
|
||||
timestamp = unversioned.Now()
|
||||
sinceseconds = int64(10)
|
||||
)
|
||||
for c, test := range []struct {
|
||||
apiOpts *api.PodLogOptions
|
||||
expect *logOptions
|
||||
}{
|
||||
{ // empty options
|
||||
apiOpts: &api.PodLogOptions{},
|
||||
expect: &logOptions{tail: -1, bytes: -1},
|
||||
},
|
||||
{ // test tail lines
|
||||
apiOpts: &api.PodLogOptions{TailLines: &line},
|
||||
expect: &logOptions{tail: line, bytes: -1},
|
||||
},
|
||||
{ // test limit bytes
|
||||
apiOpts: &api.PodLogOptions{LimitBytes: &bytes},
|
||||
expect: &logOptions{tail: -1, bytes: bytes},
|
||||
},
|
||||
{ // test since timestamp
|
||||
apiOpts: &api.PodLogOptions{SinceTime: ×tamp},
|
||||
expect: &logOptions{tail: -1, bytes: -1, since: timestamp.Time},
|
||||
},
|
||||
{ // test since seconds
|
||||
apiOpts: &api.PodLogOptions{SinceSeconds: &sinceseconds},
|
||||
expect: &logOptions{tail: -1, bytes: -1, since: timestamp.Add(-10 * time.Second)},
|
||||
},
|
||||
} {
|
||||
t.Logf("TestCase #%d: %+v", c, test)
|
||||
opts := newLogOptions(test.apiOpts, timestamp.Time)
|
||||
assert.Equal(t, test.expect, opts)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseLog(t *testing.T) {
|
||||
timestamp, err := time.Parse(timeFormat, "2016-10-20T18:39:20.57606443Z")
|
||||
assert.NoError(t, err)
|
||||
msg := &logMessage{}
|
||||
for c, test := range []struct {
|
||||
line string
|
||||
msg *logMessage
|
||||
err bool
|
||||
}{
|
||||
{ // Docker log format stdout
|
||||
line: `{"log":"docker stdout test log","stream":"stdout","time":"2016-10-20T18:39:20.57606443Z"}` + "\n",
|
||||
msg: &logMessage{
|
||||
timestamp: timestamp,
|
||||
stream: stdoutType,
|
||||
log: []byte("docker stdout test log"),
|
||||
},
|
||||
},
|
||||
{ // Docker log format stderr
|
||||
line: `{"log":"docker stderr test log","stream":"stderr","time":"2016-10-20T18:39:20.57606443Z"}` + "\n",
|
||||
msg: &logMessage{
|
||||
timestamp: timestamp,
|
||||
stream: stderrType,
|
||||
log: []byte("docker stderr test log"),
|
||||
},
|
||||
},
|
||||
{ // CRI log format stdout
|
||||
line: "2016-10-20T18:39:20.57606443Z stdout cri stdout test log\n",
|
||||
msg: &logMessage{
|
||||
timestamp: timestamp,
|
||||
stream: stdoutType,
|
||||
log: []byte("cri stdout test log\n"),
|
||||
},
|
||||
},
|
||||
{ // CRI log format stderr
|
||||
line: "2016-10-20T18:39:20.57606443Z stderr cri stderr test log\n",
|
||||
msg: &logMessage{
|
||||
timestamp: timestamp,
|
||||
stream: stderrType,
|
||||
log: []byte("cri stderr test log\n"),
|
||||
},
|
||||
},
|
||||
{ // Unsupported Log format
|
||||
line: "unsupported log format test log\n",
|
||||
msg: &logMessage{},
|
||||
err: true,
|
||||
},
|
||||
} {
|
||||
t.Logf("TestCase #%d: %+v", c, test)
|
||||
parse, err := getParseFunc([]byte(test.line))
|
||||
if test.err {
|
||||
assert.Error(t, err)
|
||||
continue
|
||||
}
|
||||
assert.NoError(t, err)
|
||||
err = parse([]byte(test.line), msg)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, test.msg, msg)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteLogs(t *testing.T) {
|
||||
timestamp := time.Unix(1234, 4321)
|
||||
log := "abcdefg\n"
|
||||
|
||||
for c, test := range []struct {
|
||||
stream streamType
|
||||
since time.Time
|
||||
timestamp bool
|
||||
expectStdout string
|
||||
expectStderr string
|
||||
}{
|
||||
{ // stderr log
|
||||
stream: stderrType,
|
||||
expectStderr: log,
|
||||
},
|
||||
{ // stdout log
|
||||
stream: stdoutType,
|
||||
expectStdout: log,
|
||||
},
|
||||
{ // since is after timestamp
|
||||
stream: stdoutType,
|
||||
since: timestamp.Add(1 * time.Second),
|
||||
},
|
||||
{ // timestamp enabled
|
||||
stream: stderrType,
|
||||
timestamp: true,
|
||||
expectStderr: timestamp.Format(timeFormat) + " " + log,
|
||||
},
|
||||
} {
|
||||
t.Logf("TestCase #%d: %+v", c, test)
|
||||
msg := &logMessage{
|
||||
timestamp: timestamp,
|
||||
stream: test.stream,
|
||||
log: []byte(log),
|
||||
}
|
||||
stdoutBuf := bytes.NewBuffer(nil)
|
||||
stderrBuf := bytes.NewBuffer(nil)
|
||||
w := newLogWriter(stdoutBuf, stderrBuf, &logOptions{since: test.since, timestamp: test.timestamp, bytes: -1})
|
||||
err := w.write(msg)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, test.expectStdout, stdoutBuf.String())
|
||||
assert.Equal(t, test.expectStderr, stderrBuf.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteLogsWithBytesLimit(t *testing.T) {
|
||||
timestamp := time.Unix(1234, 4321)
|
||||
timestampStr := timestamp.Format(timeFormat)
|
||||
log := "abcdefg\n"
|
||||
|
||||
for c, test := range []struct {
|
||||
stdoutLines int
|
||||
stderrLines int
|
||||
bytes int
|
||||
timestamp bool
|
||||
expectStdout string
|
||||
expectStderr string
|
||||
}{
|
||||
{ // limit bytes less than one line
|
||||
stdoutLines: 3,
|
||||
bytes: 3,
|
||||
expectStdout: "abc",
|
||||
},
|
||||
{ // limit bytes accross lines
|
||||
stdoutLines: 3,
|
||||
bytes: len(log) + 3,
|
||||
expectStdout: "abcdefg\nabc",
|
||||
},
|
||||
{ // limit bytes more than all lines
|
||||
stdoutLines: 3,
|
||||
bytes: 3 * len(log),
|
||||
expectStdout: "abcdefg\nabcdefg\nabcdefg\n",
|
||||
},
|
||||
{ // limit bytes for stderr
|
||||
stderrLines: 3,
|
||||
bytes: len(log) + 3,
|
||||
expectStderr: "abcdefg\nabc",
|
||||
},
|
||||
{ // limit bytes for both stdout and stderr, stdout first.
|
||||
stdoutLines: 1,
|
||||
stderrLines: 2,
|
||||
bytes: len(log) + 3,
|
||||
expectStdout: "abcdefg\n",
|
||||
expectStderr: "abc",
|
||||
},
|
||||
{ // limit bytes with timestamp
|
||||
stdoutLines: 3,
|
||||
timestamp: true,
|
||||
bytes: len(timestampStr) + 1 + len(log) + 2,
|
||||
expectStdout: timestampStr + " " + log + timestampStr[:2],
|
||||
},
|
||||
} {
|
||||
t.Logf("TestCase #%d: %+v", c, test)
|
||||
msg := &logMessage{
|
||||
timestamp: timestamp,
|
||||
log: []byte(log),
|
||||
}
|
||||
stdoutBuf := bytes.NewBuffer(nil)
|
||||
stderrBuf := bytes.NewBuffer(nil)
|
||||
w := newLogWriter(stdoutBuf, stderrBuf, &logOptions{timestamp: test.timestamp, bytes: int64(test.bytes)})
|
||||
for i := 0; i < test.stdoutLines; i++ {
|
||||
msg.stream = stdoutType
|
||||
if err := w.write(msg); err != nil {
|
||||
assert.EqualError(t, err, errMaximumWrite.Error())
|
||||
}
|
||||
}
|
||||
for i := 0; i < test.stderrLines; i++ {
|
||||
msg.stream = stderrType
|
||||
if err := w.write(msg); err != nil {
|
||||
assert.EqualError(t, err, errMaximumWrite.Error())
|
||||
}
|
||||
}
|
||||
assert.Equal(t, test.expectStdout, stdoutBuf.String())
|
||||
assert.Equal(t, test.expectStderr, stderrBuf.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestTail(t *testing.T) {
|
||||
line := strings.Repeat("a", blockSize)
|
||||
testBytes := []byte(line + "\n" +
|
||||
line + "\n" +
|
||||
line + "\n" +
|
||||
line + "\n" +
|
||||
line[blockSize/2:]) // incomplete line
|
||||
|
||||
for c, test := range []struct {
|
||||
n int64
|
||||
start int64
|
||||
}{
|
||||
{n: -1, start: 0},
|
||||
{n: 0, start: int64(len(line)+1) * 4},
|
||||
{n: 1, start: int64(len(line)+1) * 3},
|
||||
{n: 9999, start: 0},
|
||||
} {
|
||||
t.Logf("TestCase #%d: %+v", c, test)
|
||||
r := bytes.NewReader(testBytes)
|
||||
s, err := tail(r, test.n)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, s, test.start)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user