| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- package logger
- import (
- "os"
- "path/filepath"
- "strconv"
- "strings"
- "testing"
- "time"
- )
- // TestNewLoggerNoFile creates a logger without file logging.
- func TestNewLoggerNoFile(t *testing.T) {
- l, err := NewLogger("test", "", false)
- if err != nil {
- t.Fatalf("NewLogger returned error: %v", err)
- }
- if l == nil {
- t.Fatal("NewLogger returned nil")
- }
- if l.LogToFile {
- t.Error("LogToFile should be false")
- }
- }
- // TestNewLoggerWithFile creates a logger that writes to a temp directory.
- func TestNewLoggerWithFile(t *testing.T) {
- dir := t.TempDir()
- l, err := NewLogger("myapp", dir, true)
- if err != nil {
- t.Fatalf("NewLogger returned error: %v", err)
- }
- if l == nil {
- t.Fatal("NewLogger returned nil")
- }
- defer l.Close()
- if !l.LogToFile {
- t.Error("LogToFile should be true")
- }
- if l.CurrentLogFile == "" {
- t.Error("CurrentLogFile should be set")
- }
- if !strings.HasPrefix(filepath.Base(l.CurrentLogFile), "myapp_") {
- t.Errorf("log filename prefix unexpected: %s", l.CurrentLogFile)
- }
- // Verify the file was created on disk.
- if _, err := os.Stat(l.CurrentLogFile); os.IsNotExist(err) {
- t.Errorf("log file not created at %s", l.CurrentLogFile)
- }
- }
- // TestNewLoggerCreatesDirectory verifies that a missing log directory is created.
- func TestNewLoggerCreatesDirectory(t *testing.T) {
- base := t.TempDir()
- dir := filepath.Join(base, "subdir", "logs")
- l, err := NewLogger("prefix", dir, true)
- if err != nil {
- t.Fatalf("NewLogger returned error: %v", err)
- }
- defer l.Close()
- if _, err := os.Stat(dir); os.IsNotExist(err) {
- t.Errorf("log directory was not created: %s", dir)
- }
- }
- // TestNewTmpLogger creates a non-persistent logger.
- func TestNewTmpLogger(t *testing.T) {
- l, err := NewTmpLogger()
- if err != nil {
- t.Fatalf("NewTmpLogger returned error: %v", err)
- }
- if l == nil {
- t.Fatal("NewTmpLogger returned nil")
- }
- if l.LogToFile {
- t.Error("LogToFile should be false for tmp logger")
- }
- }
- // TestPrintAndLog calls PrintAndLog and confirms it does not panic.
- func TestPrintAndLog(t *testing.T) {
- l, err := NewTmpLogger()
- if err != nil {
- t.Fatalf("NewTmpLogger error: %v", err)
- }
- // PrintAndLog must not panic even without a file.
- l.PrintAndLog("TestTitle", "test message", nil)
- // Give the goroutine a moment to finish.
- time.Sleep(20 * time.Millisecond)
- }
- // TestLogNoFile verifies that Log does nothing when LogToFile is false.
- func TestLogNoFile(t *testing.T) {
- l, err := NewTmpLogger()
- if err != nil {
- t.Fatalf("NewTmpLogger error: %v", err)
- }
- // Should not panic.
- l.Log("title", "message", nil)
- }
- // TestLogInfoWritesToFile verifies that an info log entry is written to the file.
- func TestLogInfoWritesToFile(t *testing.T) {
- dir := t.TempDir()
- l, err := NewLogger("test", dir, true)
- if err != nil {
- t.Fatalf("NewLogger error: %v", err)
- }
- defer l.Close()
- l.Log("MyTitle", "hello world", nil)
- data, err := os.ReadFile(l.CurrentLogFile)
- if err != nil {
- t.Fatalf("ReadFile error: %v", err)
- }
- content := string(data)
- if !strings.Contains(content, "[INFO]") {
- t.Errorf("expected [INFO] in log, got: %s", content)
- }
- if !strings.Contains(content, "hello world") {
- t.Errorf("expected message in log, got: %s", content)
- }
- }
- // TestLogErrorWritesToFile verifies that an error log entry includes [ERROR] and the error text.
- func TestLogErrorWritesToFile(t *testing.T) {
- dir := t.TempDir()
- l, err := NewLogger("test", dir, true)
- if err != nil {
- t.Fatalf("NewLogger error: %v", err)
- }
- defer l.Close()
- l.Log("ErrTitle", "something broke", os.ErrNotExist)
- data, err := os.ReadFile(l.CurrentLogFile)
- if err != nil {
- t.Fatalf("ReadFile error: %v", err)
- }
- content := string(data)
- if !strings.Contains(content, "[ERROR]") {
- t.Errorf("expected [ERROR] in log, got: %s", content)
- }
- if !strings.Contains(content, os.ErrNotExist.Error()) {
- t.Errorf("expected error text in log, got: %s", content)
- }
- }
- // TestValidateAndUpdateLogFilepath_NoChange checks that no rotation occurs when
- // the expected filepath matches the current one.
- func TestValidateAndUpdateLogFilepath_NoChange(t *testing.T) {
- dir := t.TempDir()
- l, err := NewLogger("rotate", dir, true)
- if err != nil {
- t.Fatalf("NewLogger error: %v", err)
- }
- defer l.Close()
- original := l.CurrentLogFile
- l.ValidateAndUpdateLogFilepath()
- if l.CurrentLogFile != original {
- t.Errorf("file path changed unexpectedly: %s -> %s", original, l.CurrentLogFile)
- }
- }
- // TestValidateAndUpdateLogFilepath_MonthChange simulates a month change by
- // manually setting CurrentLogFile to an old path and calling ValidateAndUpdate.
- func TestValidateAndUpdateLogFilepath_MonthChange(t *testing.T) {
- dir := t.TempDir()
- l, err := NewLogger("rotate", dir, true)
- if err != nil {
- t.Fatalf("NewLogger error: %v", err)
- }
- defer l.Close()
- // Force a "month change" by pointing CurrentLogFile at a stale path.
- l.CurrentLogFile = filepath.Join(dir, "rotate_1999-1.log")
- l.ValidateAndUpdateLogFilepath()
- // After the call, CurrentLogFile should now be the expected current path.
- expected := l.getLogFilepath()
- if l.CurrentLogFile != expected {
- t.Errorf("expected CurrentLogFile %s, got %s", expected, l.CurrentLogFile)
- }
- // Verify the new file exists on disk.
- if _, err := os.Stat(l.CurrentLogFile); os.IsNotExist(err) {
- t.Errorf("rotated log file not created: %s", l.CurrentLogFile)
- }
- }
- // TestClose verifies that Close can be called on a file-backed logger without panicking.
- func TestClose(t *testing.T) {
- dir := t.TempDir()
- l, err := NewLogger("close", dir, true)
- if err != nil {
- t.Fatalf("NewLogger error: %v", err)
- }
- l.Close() // must not panic
- }
- // TestGetLogFilepath checks that the generated log filename contains the year and month.
- func TestGetLogFilepath(t *testing.T) {
- l := &Logger{
- Prefix: "app",
- LogFolder: "/tmp",
- }
- year, month, _ := time.Now().Date()
- path := l.getLogFilepath()
- if !strings.Contains(path, "app_") {
- t.Errorf("expected prefix in path: %s", path)
- }
- if !strings.Contains(path, strconv.Itoa(year)) {
- t.Errorf("expected year in path: %s", path)
- }
- if !strings.Contains(path, strconv.Itoa(int(month))) {
- t.Errorf("expected month in path: %s", path)
- }
- }
|