github.com/containers/podman/v4@v4.9.4/libpod/logs/log_test.go (about)

     1  package logs
     2  
     3  import (
     4  	"os"
     5  	"path/filepath"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  )
    11  
    12  var logTime time.Time
    13  
    14  func init() {
    15  	logTime, _ = time.Parse(LogTimeFormat, "2023-08-07T19:56:34.223758260-06:00")
    16  }
    17  
    18  func makeTestLogLine(typ, msg string) *LogLine {
    19  	return &LogLine{
    20  		Device:       "stdout",
    21  		ParseLogType: typ,
    22  		Msg:          msg,
    23  		Time:         logTime,
    24  	}
    25  }
    26  
    27  func TestGetTailLog(t *testing.T) {
    28  	tests := []struct {
    29  		name        string
    30  		fileContent string
    31  		tail        int
    32  		want        []*LogLine
    33  	}{
    34  		{
    35  			name: "simple tail",
    36  			fileContent: `2023-08-07T19:56:34.223758260-06:00 stdout F line1
    37  2023-08-07T19:56:34.223758260-06:00 stdout F line2
    38  2023-08-07T19:56:34.223758260-06:00 stdout F line3
    39  `,
    40  			tail: 2,
    41  			want: []*LogLine{makeTestLogLine("F", "line2"), makeTestLogLine("F", "line3")},
    42  		},
    43  		{
    44  			name: "simple tail with more tail than lines",
    45  			fileContent: `2023-08-07T19:56:34.223758260-06:00 stdout F line1
    46  2023-08-07T19:56:34.223758260-06:00 stdout F line2
    47  2023-08-07T19:56:34.223758260-06:00 stdout F line3
    48  `,
    49  			tail: 10,
    50  			want: []*LogLine{makeTestLogLine("F", "line1"), makeTestLogLine("F", "line2"), makeTestLogLine("F", "line3")},
    51  		},
    52  		{
    53  			name: "tail with partial logs",
    54  			fileContent: `2023-08-07T19:56:34.223758260-06:00 stdout F line1
    55  2023-08-07T19:56:34.223758260-06:00 stdout P lin
    56  2023-08-07T19:56:34.223758260-06:00 stdout F e2
    57  2023-08-07T19:56:34.223758260-06:00 stdout F line3
    58  `,
    59  			tail: 2,
    60  			want: []*LogLine{makeTestLogLine("P", "lin"), makeTestLogLine("F", "e2"), makeTestLogLine("F", "line3")},
    61  		},
    62  		{
    63  			name: "tail with partial logs and more than lines",
    64  			fileContent: `2023-08-07T19:56:34.223758260-06:00 stdout F line1
    65  2023-08-07T19:56:34.223758260-06:00 stdout P lin
    66  2023-08-07T19:56:34.223758260-06:00 stdout F e2
    67  2023-08-07T19:56:34.223758260-06:00 stdout F line3
    68  `,
    69  			tail: 10,
    70  			want: []*LogLine{makeTestLogLine("F", "line1"), makeTestLogLine("P", "lin"), makeTestLogLine("F", "e2"), makeTestLogLine("F", "line3")},
    71  		},
    72  		{
    73  			name: "multiple partial lines in a row",
    74  			fileContent: `2023-08-07T19:56:34.223758260-06:00 stdout F line1
    75  2023-08-07T19:56:34.223758260-06:00 stdout P l
    76  2023-08-07T19:56:34.223758260-06:00 stdout P i
    77  2023-08-07T19:56:34.223758260-06:00 stdout P n
    78  2023-08-07T19:56:34.223758260-06:00 stdout P e
    79  2023-08-07T19:56:34.223758260-06:00 stdout F 2
    80  2023-08-07T19:56:34.223758260-06:00 stdout F line3
    81  `,
    82  			tail: 2,
    83  			want: []*LogLine{makeTestLogLine("P", "l"), makeTestLogLine("P", "i"), makeTestLogLine("P", "n"),
    84  				makeTestLogLine("P", "e"), makeTestLogLine("F", "2"), makeTestLogLine("F", "line3")},
    85  		},
    86  		{
    87  			name: "partial line at the end",
    88  			fileContent: `2023-08-07T19:56:34.223758260-06:00 stdout F line1
    89  2023-08-07T19:56:34.223758260-06:00 stdout P lin
    90  `,
    91  			tail: 1,
    92  			want: []*LogLine{makeTestLogLine("P", "lin")},
    93  		},
    94  	}
    95  	for _, tt := range tests {
    96  		tt := tt
    97  		t.Run(tt.name, func(t *testing.T) {
    98  			dir := t.TempDir()
    99  			file := filepath.Join(dir, "log")
   100  			f, err := os.Create(file)
   101  			assert.NoError(t, err, "create log file")
   102  			_, err = f.WriteString(tt.fileContent)
   103  			assert.NoError(t, err, "write log file")
   104  			f.Close()
   105  			got, err := getTailLog(file, tt.tail)
   106  			assert.NoError(t, err, "getTailLog()")
   107  			assert.Equal(t, tt.want, got, "log lines")
   108  		})
   109  	}
   110  }
   111  
   112  func TestGetTailLogBigFiles(t *testing.T) {
   113  	dir := t.TempDir()
   114  	file := filepath.Join(dir, "log")
   115  	f, err := os.Create(file)
   116  	assert.NoError(t, err, "create log file")
   117  	want := make([]*LogLine, 0, 2000)
   118  	for i := 0; i < 1000; i++ {
   119  		_, err = f.WriteString(`2023-08-07T19:56:34.223758260-06:00 stdout P lin
   120  2023-08-07T19:56:34.223758260-06:00 stdout F e2
   121  `)
   122  		assert.NoError(t, err, "write log file")
   123  		want = append(want, makeTestLogLine("P", "lin"), makeTestLogLine("F", "e2"))
   124  	}
   125  	f.Close()
   126  
   127  	// try a big tail greater than the lines
   128  	got, err := getTailLog(file, 5000)
   129  	assert.NoError(t, err, "getTailLog()")
   130  	assert.Equal(t, want, got, "all log lines")
   131  
   132  	// try a smaller than lines tail
   133  	got, err = getTailLog(file, 100)
   134  	assert.NoError(t, err, "getTailLog()")
   135  	// this will return the last 200 lines because of partial + full and we only count full lines for tail.
   136  	assert.Equal(t, want[1800:2000], got, "tail 100 log lines")
   137  }