From 4031593ea8871d3d0883ee92b4316af4d27cb7e1 Mon Sep 17 00:00:00 2001 From: djuka Date: Sat, 21 Feb 2026 04:35:20 +0000 Subject: [PATCH] T26: Testovi za endpoint zadnjih 20 linija loga Co-Authored-By: Claude Opus 4.6 --- code/internal/server/logs_test.go | 161 ++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 code/internal/server/logs_test.go diff --git a/code/internal/server/logs_test.go b/code/internal/server/logs_test.go new file mode 100644 index 0000000..3b7c29f --- /dev/null +++ b/code/internal/server/logs_test.go @@ -0,0 +1,161 @@ +package server + +import ( + "net/http" + "net/http/httptest" + "os" + "path/filepath" + "strings" + "testing" +) + +func TestHandleLogsTail_OK(t *testing.T) { + srv := setupTestServer(t) + + logFile := filepath.Join(t.TempDir(), "test.log") + lines := make([]string, 25) + for i := range lines { + lines[i] = "linija " + string(rune('A'+i)) + } + os.WriteFile(logFile, []byte(strings.Join(lines, "\n")+"\n"), 0644) + srv.Config.LogFile = logFile + + req := httptest.NewRequest(http.MethodGet, "/api/logs/tail", nil) + w := httptest.NewRecorder() + srv.Router.ServeHTTP(w, req) + + if w.Code != http.StatusOK { + t.Fatalf("expected 200, got %d", w.Code) + } + + got := strings.Split(strings.TrimRight(w.Body.String(), "\n"), "\n") + if len(got) != maxLogLines { + t.Fatalf("expected %d lines, got %d", maxLogLines, len(got)) + } + // First returned line should be line 6 (index 5) since we have 25 lines, tail 20 + if got[0] != "linija F" { + t.Errorf("expected first line 'linija F', got %q", got[0]) + } +} + +func TestHandleLogsTail_LessThan20Lines(t *testing.T) { + srv := setupTestServer(t) + + logFile := filepath.Join(t.TempDir(), "test.log") + os.WriteFile(logFile, []byte("prva\ndruga\ntreca\n"), 0644) + srv.Config.LogFile = logFile + + req := httptest.NewRequest(http.MethodGet, "/api/logs/tail", nil) + w := httptest.NewRecorder() + srv.Router.ServeHTTP(w, req) + + if w.Code != http.StatusOK { + t.Fatalf("expected 200, got %d", w.Code) + } + + got := strings.Split(strings.TrimRight(w.Body.String(), "\n"), "\n") + if len(got) != 3 { + t.Fatalf("expected 3 lines, got %d", len(got)) + } +} + +func TestHandleLogsTail_NoLogFile(t *testing.T) { + srv := setupTestServer(t) + // LogFile is empty string by default in test config + + req := httptest.NewRequest(http.MethodGet, "/api/logs/tail", nil) + w := httptest.NewRecorder() + srv.Router.ServeHTTP(w, req) + + if w.Code != http.StatusOK { + t.Fatalf("expected 200, got %d", w.Code) + } + + if !strings.Contains(w.Body.String(), "KAOS_LOG_FILE") { + t.Error("expected message about KAOS_LOG_FILE not being set") + } +} + +func TestHandleLogsTail_FileNotFound(t *testing.T) { + srv := setupTestServer(t) + srv.Config.LogFile = "/tmp/nonexistent-kaos-test-log-12345.log" + + req := httptest.NewRequest(http.MethodGet, "/api/logs/tail", nil) + w := httptest.NewRecorder() + srv.Router.ServeHTTP(w, req) + + if w.Code != http.StatusOK { + t.Fatalf("expected 200, got %d", w.Code) + } + + if !strings.Contains(w.Body.String(), "ne postoji") { + t.Error("expected message about file not existing") + } +} + +func TestHandleLogsTail_Max20Lines(t *testing.T) { + srv := setupTestServer(t) + + logFile := filepath.Join(t.TempDir(), "test.log") + lines := make([]string, 100) + for i := range lines { + lines[i] = "log line" + } + os.WriteFile(logFile, []byte(strings.Join(lines, "\n")+"\n"), 0644) + srv.Config.LogFile = logFile + + req := httptest.NewRequest(http.MethodGet, "/api/logs/tail", nil) + w := httptest.NewRecorder() + srv.Router.ServeHTTP(w, req) + + if w.Code != http.StatusOK { + t.Fatalf("expected 200, got %d", w.Code) + } + + got := strings.Split(strings.TrimRight(w.Body.String(), "\n"), "\n") + if len(got) > maxLogLines { + t.Errorf("expected max %d lines, got %d", maxLogLines, len(got)) + } +} + +func TestTailLines(t *testing.T) { + tests := []struct { + name string + text string + n int + expected int + }{ + {"empty", "", 20, 1}, + {"less than n", "a\nb\nc", 20, 3}, + {"exact n", "a\nb\nc", 3, 3}, + {"more than n", "a\nb\nc\nd\ne", 3, 3}, + {"trailing newline", "a\nb\nc\n", 2, 2}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := tailLines(tt.text, tt.n) + if len(got) != tt.expected { + t.Errorf("tailLines(%q, %d) = %d lines, want %d", tt.text, tt.n, len(got), tt.expected) + } + }) + } +} + +func TestTailLines_Content(t *testing.T) { + text := "first\nsecond\nthird\nfourth\nfifth\n" + got := tailLines(text, 3) + + if len(got) != 3 { + t.Fatalf("expected 3 lines, got %d", len(got)) + } + if got[0] != "third" { + t.Errorf("expected 'third', got %q", got[0]) + } + if got[1] != "fourth" { + t.Errorf("expected 'fourth', got %q", got[1]) + } + if got[2] != "fifth" { + t.Errorf("expected 'fifth', got %q", got[2]) + } +}