2.0.0 4803e67

setup_test.go RawHistoryFolder

1package logging
2
3import (
4	"os"
5	"path/filepath"
6	"testing"
7
8	"github.com/rs/zerolog"
9	"github.com/stretchr/testify/assert"
10	"github.com/stretchr/testify/require"
11	"gordon/internal/config"
12)
13
14func TestSetup_LoggingDisabled(t *testing.T) {
15	cfg := &config.Config{
16		Logging: config.LoggingConfig{
17			Enabled: false,
18		},
19	}
20
21	err := Setup(cfg)
22	require.NoError(t, err)
23
24	// Should have console loggers set
25	assert.NotNil(t, MainLogger)
26	assert.NotNil(t, ProxyLogger)
27}
28
29func TestSetup_LoggingEnabled(t *testing.T) {
30	// Create temporary directory for test logs
31	tempDir := t.TempDir()
32
33	cfg := &config.Config{
34		Logging: config.LoggingConfig{
35			Enabled:           true,
36			Dir:               tempDir,
37			ContainerLogDir:   "containers",
38			MainLogFile:       "gordon.log",
39			ProxyLogFile:      "proxy.log",
40			Level:             "info",
41			MaxSize:           10,
42			MaxBackups:        3,
43			MaxAge:            7,
44			Compress:          true,
45		},
46	}
47
48	err := Setup(cfg)
49	require.NoError(t, err)
50
51	// Check directories were created
52	assert.DirExists(t, tempDir)
53	assert.DirExists(t, filepath.Join(tempDir, "containers"))
54
55	// Check directory permissions (allow for different umask settings)
56	info, err := os.Stat(tempDir)
57	require.NoError(t, err)
58	assert.True(t, info.Mode().IsDir())
59
60	containerDirInfo, err := os.Stat(filepath.Join(tempDir, "containers"))
61	require.NoError(t, err)
62	assert.True(t, containerDirInfo.Mode().IsDir())
63
64	// Check loggers are initialized
65	assert.NotNil(t, MainLogger)
66	assert.NotNil(t, ProxyLogger)
67
68	// Check global log level was set
69	assert.Equal(t, zerolog.InfoLevel, zerolog.GlobalLevel())
70}
71
72func TestSetup_InvalidLogLevel(t *testing.T) {
73	tempDir := t.TempDir()
74
75	cfg := &config.Config{
76		Logging: config.LoggingConfig{
77			Enabled:           true,
78			Dir:               tempDir,
79			ContainerLogDir:   "containers",
80			MainLogFile:       "gordon.log",
81			ProxyLogFile:      "proxy.log",
82			Level:             "invalid_level",
83			MaxSize:           10,
84			MaxBackups:        3,
85			MaxAge:            7,
86			Compress:          false,
87		},
88	}
89
90	err := Setup(cfg)
91	require.NoError(t, err)
92
93	// Should default to info level
94	assert.Equal(t, zerolog.InfoLevel, zerolog.GlobalLevel())
95}
96
97func TestSetup_CreateDirectoryError(t *testing.T) {
98	// Try to create logs in a path that doesn't exist and can't be created
99	cfg := &config.Config{
100		Logging: config.LoggingConfig{
101			Enabled:           true,
102			Dir:               "/invalid/path/that/cannot/be/created",
103			ContainerLogDir:   "containers",
104			MainLogFile:       "gordon.log",
105			ProxyLogFile:      "proxy.log",
106			Level:             "info",
107			MaxSize:           10,
108			MaxBackups:        3,
109			MaxAge:            7,
110			Compress:          false,
111		},
112	}
113
114	err := Setup(cfg)
115	assert.Error(t, err)
116	assert.Contains(t, err.Error(), "failed to create logs directory")
117}
118
119func TestSetup_CreateContainerDirectoryError(t *testing.T) {
120	tempDir := t.TempDir()
121	
122	// Create a file where the container directory should be
123	containerPath := filepath.Join(tempDir, "containers")
124	err := os.WriteFile(containerPath, []byte("blocking file"), 0644)
125	require.NoError(t, err)
126
127	cfg := &config.Config{
128		Logging: config.LoggingConfig{
129			Enabled:           true,
130			Dir:               tempDir,
131			ContainerLogDir:   "containers",
132			MainLogFile:       "gordon.log",
133			ProxyLogFile:      "proxy.log",
134			Level:             "info",
135			MaxSize:           10,
136			MaxBackups:        3,
137			MaxAge:            7,
138			Compress:          false,
139		},
140	}
141
142	err = Setup(cfg)
143	assert.Error(t, err)
144	assert.Contains(t, err.Error(), "failed to create container logs directory")
145}
146
147func TestSetup_DifferentLogLevels(t *testing.T) {
148	testCases := []struct {
149		name     string
150		level    string
151		expected zerolog.Level
152	}{
153		{"debug level", "debug", zerolog.DebugLevel},
154		{"info level", "info", zerolog.InfoLevel},
155		{"warn level", "warn", zerolog.WarnLevel},
156		{"error level", "error", zerolog.ErrorLevel},
157		{"fatal level", "fatal", zerolog.FatalLevel},
158		{"panic level", "panic", zerolog.PanicLevel},
159		{"trace level", "trace", zerolog.TraceLevel},
160		{"disabled level", "disabled", zerolog.Disabled},
161	}
162
163	for _, tc := range testCases {
164		t.Run(tc.name, func(t *testing.T) {
165			tempDir := t.TempDir()
166
167			cfg := &config.Config{
168				Logging: config.LoggingConfig{
169					Enabled:           true,
170					Dir:               tempDir,
171					ContainerLogDir:   "containers",
172					MainLogFile:       "gordon.log",
173					ProxyLogFile:      "proxy.log",
174					Level:             tc.level,
175					MaxSize:           10,
176					MaxBackups:        3,
177					MaxAge:            7,
178					Compress:          false,
179				},
180			}
181
182			err := Setup(cfg)
183			require.NoError(t, err)
184			assert.Equal(t, tc.expected, zerolog.GlobalLevel())
185		})
186	}
187}
188
189func TestGetContainerLogWriter_LoggingDisabled(t *testing.T) {
190	cfg := &config.Config{
191		Logging: config.LoggingConfig{
192			Enabled: false,
193		},
194	}
195
196	writer, err := GetContainerLogWriter(cfg, "container123", "test-container")
197	assert.Error(t, err)
198	assert.Nil(t, writer)
199	assert.Contains(t, err.Error(), "logging is disabled")
200}
201
202func TestGetContainerLogWriter_Success(t *testing.T) {
203	tempDir := t.TempDir()
204
205	cfg := &config.Config{
206		Logging: config.LoggingConfig{
207			Enabled:           true,
208			Dir:               tempDir,
209			ContainerLogDir:   "containers",
210			MaxSize:           10,
211			MaxBackups:        3,
212			MaxAge:            7,
213			Compress:          true,
214		},
215	}
216
217	containerID := "container123"
218	containerName := "test-container"
219
220	writer, err := GetContainerLogWriter(cfg, containerID, containerName)
221	require.NoError(t, err)
222	require.NotNil(t, writer)
223
224	// Check container log directory was created
225	containerLogDir := filepath.Join(tempDir, "containers")
226	assert.DirExists(t, containerLogDir)
227
228	// Check directory permissions  
229	info, err := os.Stat(containerLogDir)
230	require.NoError(t, err)
231	assert.True(t, info.Mode().IsDir())
232
233	// Check writer configuration
234	expectedLogFile := filepath.Join(containerLogDir, "container123.log")
235	assert.Equal(t, expectedLogFile, writer.Filename)
236	assert.Equal(t, 10, writer.MaxSize)
237	assert.Equal(t, 3, writer.MaxBackups)
238	assert.Equal(t, 7, writer.MaxAge)
239	assert.True(t, writer.Compress)
240
241	// Check symlink was created
242	symlinkPath := filepath.Join(containerLogDir, "test-container.log")
243	_, err = os.Lstat(symlinkPath)
244	assert.NoError(t, err, "Symlink should exist")
245
246	// Verify symlink points to correct target
247	target, err := os.Readlink(symlinkPath)
248	require.NoError(t, err)
249	assert.Equal(t, "container123.log", target)
250}
251
252func TestGetContainerLogWriter_WithoutContainerName(t *testing.T) {
253	tempDir := t.TempDir()
254
255	cfg := &config.Config{
256		Logging: config.LoggingConfig{
257			Enabled:           true,
258			Dir:               tempDir,
259			ContainerLogDir:   "containers",
260			MaxSize:           10,
261			MaxBackups:        3,
262			MaxAge:            7,
263			Compress:          false,
264		},
265	}
266
267	containerID := "container456"
268
269	writer, err := GetContainerLogWriter(cfg, containerID, "")
270	require.NoError(t, err)
271	require.NotNil(t, writer)
272
273	// Check no symlink was created
274	containerLogDir := filepath.Join(tempDir, "containers")
275	symlinkPath := filepath.Join(containerLogDir, ".log")
276	_, err = os.Lstat(symlinkPath)
277	assert.Error(t, err, "No symlink should exist for empty container name")
278}
279
280func TestGetContainerLogWriter_ContainerNameSameAsID(t *testing.T) {
281	tempDir := t.TempDir()
282
283	cfg := &config.Config{
284		Logging: config.LoggingConfig{
285			Enabled:           true,
286			Dir:               tempDir,
287			ContainerLogDir:   "containers",
288			MaxSize:           10,
289			MaxBackups:        3,
290			MaxAge:            7,
291			Compress:          false,
292		},
293	}
294
295	containerID := "container789"
296
297	writer, err := GetContainerLogWriter(cfg, containerID, containerID)
298	require.NoError(t, err)
299	require.NotNil(t, writer)
300
301	// Check no symlink was created when name equals ID
302	containerLogDir := filepath.Join(tempDir, "containers")
303	symlinkPath := filepath.Join(containerLogDir, "container789.log")
304	
305	// The symlink path would be the same as the actual log file, so no symlink should be created
306	info, err := os.Lstat(symlinkPath)
307	if err == nil {
308		// If it exists, it should be a regular file, not a symlink
309		assert.Equal(t, 0, info.Mode()&os.ModeSymlink, "Should not be a symlink")
310	}
311}
312
313func TestGetContainerLogWriter_ReplaceExistingSymlink(t *testing.T) {
314	tempDir := t.TempDir()
315	containerLogDir := filepath.Join(tempDir, "containers")
316	err := os.MkdirAll(containerLogDir, 0700)
317	require.NoError(t, err)
318
319	cfg := &config.Config{
320		Logging: config.LoggingConfig{
321			Enabled:           true,
322			Dir:               tempDir,
323			ContainerLogDir:   "containers",
324			MaxSize:           10,
325			MaxBackups:        3,
326			MaxAge:            7,
327			Compress:          false,
328		},
329	}
330
331	containerName := "test-container"
332	symlinkPath := filepath.Join(containerLogDir, "test-container.log")
333
334	// Create existing symlink
335	err = os.Symlink("old-target.log", symlinkPath)
336	require.NoError(t, err)
337
338	// Create new container log writer
339	containerID := "new-container123"
340	writer, err := GetContainerLogWriter(cfg, containerID, containerName)
341	require.NoError(t, err)
342	require.NotNil(t, writer)
343
344	// Check symlink was replaced
345	target, err := os.Readlink(symlinkPath)
346	require.NoError(t, err)
347	assert.Equal(t, "new-container123.log", target)
348}
349
350func TestGetContainerLogWriter_CreateDirectoryError(t *testing.T) {
351	// Create a file where the container directory should be
352	tempDir := t.TempDir()
353	containerPath := filepath.Join(tempDir, "containers")
354	err := os.WriteFile(containerPath, []byte("blocking file"), 0644)
355	require.NoError(t, err)
356
357	cfg := &config.Config{
358		Logging: config.LoggingConfig{
359			Enabled:           true,
360			Dir:               tempDir,
361			ContainerLogDir:   "containers",
362			MaxSize:           10,
363			MaxBackups:        3,
364			MaxAge:            7,
365			Compress:          false,
366		},
367	}
368
369	writer, err := GetContainerLogWriter(cfg, "container123", "test-container")
370	assert.Error(t, err)
371	assert.Nil(t, writer)
372	assert.Contains(t, err.Error(), "failed to create container log directory")
373}
374
375func TestClose(t *testing.T) {
376	// Test that Close() doesn't panic and can be called multiple times
377	assert.NotPanics(t, func() {
378		Close()
379		Close() // Should be safe to call multiple times
380	})
381}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close