mirror of
https://github.com/yusing/godoxy.git
synced 2025-05-20 12:42:34 +02:00
148 lines
3.1 KiB
Go
148 lines
3.1 KiB
Go
package accesslog_test
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"testing"
|
|
"time"
|
|
|
|
. "github.com/yusing/go-proxy/internal/net/http/accesslog"
|
|
"github.com/yusing/go-proxy/internal/utils/strutils"
|
|
. "github.com/yusing/go-proxy/internal/utils/testing"
|
|
)
|
|
|
|
func TestParseRetention(t *testing.T) {
|
|
tests := []struct {
|
|
input string
|
|
expected *Retention
|
|
shouldErr bool
|
|
}{
|
|
{"30 days", &Retention{Days: 30}, false},
|
|
{"2 weeks", &Retention{Days: 14}, false},
|
|
{"last 5", &Retention{Last: 5}, false},
|
|
{"invalid input", &Retention{}, true},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.input, func(t *testing.T) {
|
|
r := &Retention{}
|
|
err := r.Parse(test.input)
|
|
if !test.shouldErr {
|
|
ExpectNoError(t, err)
|
|
} else {
|
|
ExpectDeepEqual(t, r, test.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
type mockFile struct {
|
|
data []byte
|
|
position int64
|
|
}
|
|
|
|
func (m *mockFile) Seek(offset int64, whence int) (int64, error) {
|
|
switch whence {
|
|
case io.SeekStart:
|
|
m.position = offset
|
|
case io.SeekCurrent:
|
|
m.position += offset
|
|
case io.SeekEnd:
|
|
m.position = int64(len(m.data)) + offset
|
|
}
|
|
return m.position, nil
|
|
}
|
|
|
|
func (m *mockFile) Write(p []byte) (n int, err error) {
|
|
m.data = append(m.data, p...)
|
|
n = len(p)
|
|
m.position += int64(n)
|
|
return
|
|
}
|
|
|
|
func (m *mockFile) Name() string {
|
|
return "mock"
|
|
}
|
|
|
|
func (m *mockFile) Read(p []byte) (n int, err error) {
|
|
if m.position >= int64(len(m.data)) {
|
|
return 0, io.EOF
|
|
}
|
|
n = copy(p, m.data[m.position:])
|
|
m.position += int64(n)
|
|
return n, nil
|
|
}
|
|
|
|
func (m *mockFile) ReadAt(p []byte, off int64) (n int, err error) {
|
|
if off >= int64(len(m.data)) {
|
|
return 0, io.EOF
|
|
}
|
|
n = copy(p, m.data[off:])
|
|
m.position += int64(n)
|
|
return n, nil
|
|
}
|
|
|
|
func (m *mockFile) Close() error {
|
|
return nil
|
|
}
|
|
|
|
func (m *mockFile) Truncate(size int64) error {
|
|
m.data = m.data[:size]
|
|
m.position = size
|
|
return nil
|
|
}
|
|
|
|
func (m *mockFile) Lock() {}
|
|
func (m *mockFile) Unlock() {}
|
|
|
|
func (m *mockFile) Count() int {
|
|
return bytes.Count(m.data[:m.position], []byte("\n"))
|
|
}
|
|
|
|
func (m *mockFile) Len() int64 {
|
|
return m.position
|
|
}
|
|
|
|
func TestRetentionCommonFormat(t *testing.T) {
|
|
file := mockFile{}
|
|
logger := NewAccessLogger(nil, &file, &Config{
|
|
Format: FormatCommon,
|
|
BufferSize: 1024,
|
|
})
|
|
for range 10 {
|
|
logger.Log(req, resp)
|
|
}
|
|
logger.Flush(true)
|
|
// test.Finish(nil)
|
|
|
|
ExpectEqual(t, logger.Config().Retention, nil)
|
|
ExpectTrue(t, file.Len() > 0)
|
|
ExpectEqual(t, file.Count(), 10)
|
|
|
|
t.Run("keep last", func(t *testing.T) {
|
|
logger.Config().Retention = strutils.MustParse[*Retention]("last 5")
|
|
ExpectEqual(t, logger.Config().Retention.Days, 0)
|
|
ExpectEqual(t, logger.Config().Retention.Last, 5)
|
|
ExpectNoError(t, logger.Rotate())
|
|
ExpectEqual(t, file.Count(), 5)
|
|
})
|
|
|
|
_ = file.Truncate(0)
|
|
|
|
timeNow := time.Now()
|
|
for i := range 10 {
|
|
logger.Formatter.(*CommonFormatter).GetTimeNow = func() time.Time {
|
|
return timeNow.AddDate(0, 0, -i)
|
|
}
|
|
logger.Log(req, resp)
|
|
}
|
|
logger.Flush(true)
|
|
|
|
t.Run("keep days", func(t *testing.T) {
|
|
logger.Config().Retention = strutils.MustParse[*Retention]("3 days")
|
|
ExpectEqual(t, logger.Config().Retention.Days, 3)
|
|
ExpectEqual(t, logger.Config().Retention.Last, 0)
|
|
ExpectNoError(t, logger.Rotate())
|
|
ExpectEqual(t, file.Count(), 3)
|
|
})
|
|
}
|