[test-improver] Improve tests for logger common package#3114
Conversation
…LogLine coverage
- Replace t.Errorf/t.Fatal patterns with testify assertions:
- TestInitLogFile_InvalidDirectory: use require.Error instead of if/t.Fatal
- TestInitLogFile_EmptyFileName: use require.Error instead of if/t.Fatal
- TestInitLogger_FileLogger/JSONLLogger/MarkdownLogger: replace t.Errorf
in error-handler callbacks with boolean flag + assert.False
- TestInitLogger_FileLoggerFallback/JSONLLoggerError/MarkdownLoggerFallback:
replace t.Errorf in setup-handler callbacks with boolean flag + assert.False
- TestInitLogger_SetupError: same pattern for error-handler callback
- Add TestFormatLogLine to cover the previously untested formatLogLine function:
- Tests all four log levels (INFO, WARN, ERROR, DEBUG)
- Verifies bracket structure [timestamp] [level] [category] message
- Validates RFC3339 UTC timestamp format and time window
- Tests format string interpolation with args
- Tests empty category edge case
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Improves unit tests for the internal/logger common helpers by making assertions more idiomatic and adding direct coverage for the shared log-line formatting helper.
Changes:
- Replaced
t.Errorf/t.Fatalpatterns inside callbacks with boolean flags plusassert/requireassertions for clearer intent. - Improved error-path tests for
initLogFileto assert errors after safely closing any returned file handle. - Added direct subtests for
formatLogLineoutput structure, message formatting, and RFC3339 UTC timestamp parsing.
Show a summary per file
| File | Description |
|---|---|
| internal/logger/common_test.go | Refactors existing tests to use consistent testify assertions and adds direct unit tests for formatLogLine. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comments suppressed due to low confidence (2)
internal/logger/common_test.go:515
- This test assumes "/root/nonexistent/directory" is unwritable to trigger the error path. If tests run with elevated privileges, initLogFile may succeed and this assertion about error-handler behavior becomes flaky. Prefer constructing a deterministic failure (e.g., temp file used as a directory component, or temp dir with permissions removed) so the error path is guaranteed.
// Use a non-writable directory to trigger error
logDir := "/root/nonexistent/directory"
fileName := "test.jsonl"
errorHandlerCalled := false
setupHandlerCalled := false
internal/logger/common_test.go:591
- Using "/root/nonexistent/directory" to force initLogFile failure can be flaky when tests run as root (or in containers with different permission models). To keep this fallback test stable across environments, consider forcing failure via a temp dir with permissions removed, or by attempting to create a subdirectory under a regular file (as done in TestInitLogFile_InvalidDirectory).
// Use a non-writable directory to trigger error
logDir := "/root/nonexistent/directory"
fileName := "test.md"
errorHandlerCalled := false
setupHandlerCalled := false
- Files reviewed: 1/1 changed files
- Comments generated: 1
| // Use a non-writable directory to trigger error | ||
| logDir := "/root/nonexistent/directory" | ||
| fileName := "test.log" | ||
|
|
||
| errorHandlerCalled := false |
There was a problem hiding this comment.
These fallback tests rely on "/root/nonexistent/directory" being non-writable. In CI (or local) runs as root, initLogFile may succeed and the test will fail (unlike TestInitLogFile_UnwritableDirectory, which skips when writable). Consider making the directory reliably unwritable using a temp dir with chmod 000 / read-only permissions, or using the existing "file-as-directory component" approach from TestInitLogFile_InvalidDirectory to force initLogFile to fail deterministically.
This issue also appears in the following locations of the same file:
- line 510
- line 586
See below for a potential fix:
// Use a path with a file as a directory component to trigger error deterministically.
tmpDir := t.TempDir()
fileAsDir := filepath.Join(tmpDir, "not-a-directory")
err := os.WriteFile(fileAsDir, []byte("test"), 0644)
require.NoError(err)
logDir := filepath.Join(fileAsDir, "nonexistent")
Test Improvements:
internal/logger/common_test.goFile Analyzed
internal/logger/common_test.gointernal/loggerImprovements Made
1. Better Testify Patterns — Replace
t.Errorf/t.Fatalwith Idiomatic AssertionsProblem: Several tests used
t.Errorf("should not be called")inside callback closures andt.Fatalinsideif err == nilguards instead of proper testify patterns.TestInitLogFile_InvalidDirectory— replacedif err == nil { file.Close(); t.Fatal(...) }withrequire.Error(err, ...)after closing any file handleTestInitLogFile_EmptyFileName— same pattern; addedrequire := require.New(t)so the test uses testifyrequire.ErrorconsistentlyTestInitLogger_FileLogger— replacedt.Errorf("Error handler should not be called")inside callback with aerrorHandlerCalledboolean flag +assert.False(errorHandlerCalled, ...)TestInitLogger_FileLoggerFallback— replacedt.Errorfin setup callback withsetupHandlerCalledflag +assert.FalseTestInitLogger_JSONLLogger— same improvement as FileLoggerTestInitLogger_JSONLLoggerError— same improvement as FileLoggerFallbackTestInitLogger_MarkdownLogger— same improvement as FileLoggerTestInitLogger_MarkdownLoggerFallback— same improvement as FileLoggerFallbackTestInitLogger_SetupError— replacedt.Errorfin error-handler callback with flag +assert.FalseThe boolean flag pattern makes the intent explicit alongside the other post-call assertions and avoids mixing raw
t.Errorfwith testify assertions in the same test.2. Increased Coverage — Direct Tests for
formatLogLineProblem: The
formatLogLinefunction incommon.gowas exercised only indirectly throughFileLogger.Log()andServerFileLogger, but had no direct unit tests. The function is responsible for the canonical log line format used across all file-based loggers.TestFormatLogLinewith subtests covering:INFO,WARN,ERROR,DEBUG) appear in bracketscount=%d name=%s)^\[\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z\] \[INFO\] \[auth\] event occurred$[]bracket pair3. Cleaner & More Stable Tests
"strings"and"time"imports for the newTestFormatLogLinetestt.Errorfwithassert/requirein the same testsrequire.Errorstops the testWhy These Changes?
internal/logger/common_test.gotests the core initialization primitives (closeLogFile,initLogFile,initLogger) used by all logger types in the package. TheformatLogLinefunction — which defines the log line format for all operational logs — was entirely untested directly. Thet.Errorfcallback pattern, while valid Go, was inconsistent with the testify style used throughout the rest of the file.Generated by Test Improver Workflow
Focuses on better patterns, increased coverage, and more stable tests