You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ntool/nlog/rotatelogger_test.go

349 lines
9.0 KiB
Go

package nlog
import (
"git.noahlan.cn/noahlan/ntool/nfs"
"git.noahlan.cn/noahlan/ntool/nrandom"
"os"
"path/filepath"
"syscall"
"testing"
"time"
"git.noahlan.cn/noahlan/ntool/ntest/assert"
)
func TestDailyRotateRuleMarkRotated(t *testing.T) {
var rule DailyRotateRule
rule.MarkRotated()
assert.Equal(t, getNowDate(), rule.rotatedTime)
}
func TestDailyRotateRuleOutdatedFiles(t *testing.T) {
var rule DailyRotateRule
assert.Empty(t, rule.OutdatedFiles())
rule.days = 1
assert.Empty(t, rule.OutdatedFiles())
rule.gzip = true
assert.Empty(t, rule.OutdatedFiles())
}
func TestDailyRotateRuleShallRotate(t *testing.T) {
var rule DailyRotateRule
rule.rotatedTime = time.Now().Add(time.Hour * 24).Format(dateFormat)
assert.True(t, rule.ShallRotate(0))
}
func TestSizeLimitRotateRuleMarkRotated(t *testing.T) {
var rule SizeLimitRotateRule
rule.MarkRotated()
assert.Equal(t, getNowDateInRFC3339Format(), rule.rotatedTime)
}
func TestSizeLimitRotateRuleOutdatedFiles(t *testing.T) {
var rule SizeLimitRotateRule
assert.Empty(t, rule.OutdatedFiles())
rule.days = 1
assert.Empty(t, rule.OutdatedFiles())
rule.gzip = true
assert.Empty(t, rule.OutdatedFiles())
rule.maxBackups = 0
assert.Empty(t, rule.OutdatedFiles())
}
func TestSizeLimitRotateRuleShallRotate(t *testing.T) {
var rule SizeLimitRotateRule
rule.rotatedTime = time.Now().Add(time.Hour * 24).Format(fileTimeFormat)
rule.maxSize = 0
assert.False(t, rule.ShallRotate(0))
rule.maxSize = 100
assert.False(t, rule.ShallRotate(0))
assert.True(t, rule.ShallRotate(101*megaBytes))
}
func TestRotateLoggerClose(t *testing.T) {
filename, err := nfs.OSTempFilenameWithContent("foo")
assert.Nil(t, err)
if len(filename) > 0 {
defer os.Remove(filename)
}
logger, err := NewLogger(filename, new(DailyRotateRule), false)
assert.Nil(t, err)
assert.Nil(t, logger.Close())
}
func TestRotateLoggerGetBackupFilename(t *testing.T) {
filename, err := nfs.OSTempFilenameWithContent("foo")
assert.Nil(t, err)
if len(filename) > 0 {
defer os.Remove(filename)
}
logger, err := NewLogger(filename, new(DailyRotateRule), false)
assert.Nil(t, err)
assert.True(t, len(logger.getBackupFilename()) > 0)
logger.backup = ""
assert.True(t, len(logger.getBackupFilename()) > 0)
}
func TestRotateLoggerMayCompressFile(t *testing.T) {
old := os.Stdout
os.Stdout = os.NewFile(0, os.DevNull)
defer func() {
os.Stdout = old
}()
filename, err := nfs.OSTempFilenameWithContent("foo")
assert.Nil(t, err)
if len(filename) > 0 {
defer os.Remove(filename)
}
logger, err := NewLogger(filename, new(DailyRotateRule), false)
assert.Nil(t, err)
logger.maybeCompressFile(filename)
_, err = os.Stat(filename)
assert.Nil(t, err)
}
func TestRotateLoggerMayCompressFileTrue(t *testing.T) {
old := os.Stdout
os.Stdout = os.NewFile(0, os.DevNull)
defer func() {
os.Stdout = old
}()
filename, err := nfs.OSTempFilenameWithContent("foo")
assert.Nil(t, err)
logger, err := NewLogger(filename, new(DailyRotateRule), true)
assert.Nil(t, err)
if len(filename) > 0 {
defer os.Remove(filepath.Base(logger.getBackupFilename()) + ".gz")
}
logger.maybeCompressFile(filename)
_, err = os.Stat(filename)
assert.NotNil(t, err)
}
func TestRotateLoggerRotate(t *testing.T) {
filename, err := nfs.OSTempFilenameWithContent("foo")
assert.Nil(t, err)
logger, err := NewLogger(filename, new(DailyRotateRule), true)
assert.Nil(t, err)
if len(filename) > 0 {
defer func() {
os.Remove(logger.getBackupFilename())
os.Remove(filepath.Base(logger.getBackupFilename()) + ".gz")
}()
}
err = logger.rotate()
switch v := err.(type) {
case *os.LinkError:
// avoid rename error on docker container
assert.Equal(t, syscall.EXDEV, v.Err)
case *os.PathError:
// ignore remove error for tests,
// files are cleaned in GitHub actions.
assert.Equal(t, "remove", v.Op)
default:
assert.Nil(t, err)
}
}
func TestRotateLoggerWrite(t *testing.T) {
filename, err := nfs.OSTempFilenameWithContent("foo")
assert.Nil(t, err)
rule := new(DailyRotateRule)
logger, err := NewLogger(filename, rule, true)
assert.Nil(t, err)
if len(filename) > 0 {
defer func() {
os.Remove(logger.getBackupFilename())
os.Remove(filepath.Base(logger.getBackupFilename()) + ".gz")
}()
}
// the following write calls cannot be changed to Write, because of DATA RACE.
logger.write([]byte(`foo`))
rule.rotatedTime = time.Now().Add(-time.Hour * 24).Format(dateFormat)
logger.write([]byte(`bar`))
logger.Close()
logger.write([]byte(`baz`))
}
func TestLogWriterClose(t *testing.T) {
assert.Nil(t, newLogWriter(nil).Close())
}
func TestRotateLoggerWithSizeLimitRotateRuleClose(t *testing.T) {
filename, err := nfs.OSTempFilenameWithContent("foo")
assert.Nil(t, err)
if len(filename) > 0 {
defer os.Remove(filename)
}
logger, err := NewLogger(filename, new(SizeLimitRotateRule), false)
assert.Nil(t, err)
assert.Nil(t, logger.Close())
}
func TestRotateLoggerGetBackupWithSizeLimitRotateRuleFilename(t *testing.T) {
filename, err := nfs.OSTempFilenameWithContent("foo")
assert.Nil(t, err)
if len(filename) > 0 {
defer os.Remove(filename)
}
logger, err := NewLogger(filename, new(SizeLimitRotateRule), false)
assert.Nil(t, err)
assert.True(t, len(logger.getBackupFilename()) > 0)
logger.backup = ""
assert.True(t, len(logger.getBackupFilename()) > 0)
}
func TestRotateLoggerWithSizeLimitRotateRuleMayCompressFile(t *testing.T) {
old := os.Stdout
os.Stdout = os.NewFile(0, os.DevNull)
defer func() {
os.Stdout = old
}()
filename, err := nfs.OSTempFilenameWithContent("foo")
assert.Nil(t, err)
if len(filename) > 0 {
defer os.Remove(filename)
}
logger, err := NewLogger(filename, new(SizeLimitRotateRule), false)
assert.Nil(t, err)
logger.maybeCompressFile(filename)
_, err = os.Stat(filename)
assert.Nil(t, err)
}
func TestRotateLoggerWithSizeLimitRotateRuleMayCompressFileTrue(t *testing.T) {
old := os.Stdout
os.Stdout = os.NewFile(0, os.DevNull)
defer func() {
os.Stdout = old
}()
filename, err := nfs.OSTempFilenameWithContent("foo")
assert.Nil(t, err)
logger, err := NewLogger(filename, new(SizeLimitRotateRule), true)
assert.Nil(t, err)
if len(filename) > 0 {
defer os.Remove(filepath.Base(logger.getBackupFilename()) + ".gz")
}
logger.maybeCompressFile(filename)
_, err = os.Stat(filename)
assert.NotNil(t, err)
}
func TestRotateLoggerWithSizeLimitRotateRuleMayCompressFileFailed(t *testing.T) {
old := os.Stdout
os.Stdout = os.NewFile(0, os.DevNull)
defer func() {
os.Stdout = old
}()
filename := nrandom.NewUUIDV7().String()
logger, err := NewLogger(filename, new(SizeLimitRotateRule), true)
defer os.Remove(filename)
if assert.NoError(t, err) {
assert.NotPanics(t, func() {
logger.maybeCompressFile(nrandom.NewUUIDV7().String())
})
}
}
func TestRotateLoggerWithSizeLimitRotateRuleRotate(t *testing.T) {
filename, err := nfs.OSTempFilenameWithContent("foo")
assert.Nil(t, err)
logger, err := NewLogger(filename, new(SizeLimitRotateRule), true)
assert.Nil(t, err)
if len(filename) > 0 {
defer func() {
os.Remove(logger.getBackupFilename())
os.Remove(filepath.Base(logger.getBackupFilename()) + ".gz")
}()
}
err = logger.rotate()
switch v := err.(type) {
case *os.LinkError:
// avoid rename error on docker container
assert.Equal(t, syscall.EXDEV, v.Err)
case *os.PathError:
// ignore remove error for tests,
// files are cleaned in GitHub actions.
assert.Equal(t, "remove", v.Op)
default:
assert.Nil(t, err)
}
}
func TestRotateLoggerWithSizeLimitRotateRuleWrite(t *testing.T) {
filename, err := nfs.OSTempFilenameWithContent("foo")
assert.Nil(t, err)
rule := new(SizeLimitRotateRule)
logger, err := NewLogger(filename, rule, true)
assert.Nil(t, err)
if len(filename) > 0 {
defer func() {
os.Remove(logger.getBackupFilename())
os.Remove(filepath.Base(logger.getBackupFilename()) + ".gz")
}()
}
// the following write calls cannot be changed to Write, because of DATA RACE.
logger.write([]byte(`foo`))
rule.rotatedTime = time.Now().Add(-time.Hour * 24).Format(dateFormat)
logger.write([]byte(`bar`))
logger.Close()
logger.write([]byte(`baz`))
}
func BenchmarkRotateLogger(b *testing.B) {
filename := "./test.log"
filename2 := "./test2.log"
dailyRotateRuleLogger, err1 := NewLogger(
filename,
DefaultRotateRule(
filename,
backupFileDelimiter,
1,
true,
),
true,
)
if err1 != nil {
b.Logf("Failed to new daily rotate rule logger: %v", err1)
b.FailNow()
}
sizeLimitRotateRuleLogger, err2 := NewLogger(
filename2,
NewSizeLimitRotateRule(
filename,
backupFileDelimiter,
1,
100,
10,
true,
),
true,
)
if err2 != nil {
b.Logf("Failed to new size limit rotate rule logger: %v", err1)
b.FailNow()
}
defer func() {
dailyRotateRuleLogger.Close()
sizeLimitRotateRuleLogger.Close()
os.Remove(filename)
os.Remove(filename2)
}()
b.Run("daily rotate rule", func(b *testing.B) {
for i := 0; i < b.N; i++ {
dailyRotateRuleLogger.write([]byte("testing\ntesting\n"))
}
})
b.Run("size limit rotate rule", func(b *testing.B) {
for i := 0; i < b.N; i++ {
sizeLimitRotateRuleLogger.write([]byte("testing\ntesting\n"))
}
})
}