Skip to content

Commit f7af71b

Browse files
sangwaclaude
andcommitted
test: add tests for tdxVerifyOpt, NewTimestamp, shutdownCtx, and rate limiter cleanup
Fill testable coverage gaps identified during review: - tdxVerifyOpt: all three branches (disabled, enabled without getter, enabled with getter) - NewTimestamp: RFC 3339 format, second truncation, UTC, freshness - shutdownCtx: nil context fallback (pre-Run) and set context path - rateLimiterMap.cleanup: stale entry removal and empty map safety Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 8ab2817 commit f7af71b

3 files changed

Lines changed: 129 additions & 0 deletions

File tree

internal/crl_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,41 @@ func TestCRLURLsForEvidence(t *testing.T) {
165165
})
166166
}
167167

168+
func TestTdxVerifyOpt(t *testing.T) {
169+
t.Run("revocation disabled", func(t *testing.T) {
170+
s := &Server{cfg: &Config{RevocationEnabled: false}}
171+
opt := s.tdxVerifyOpt()
172+
if opt.CheckRevocations {
173+
t.Error("expected CheckRevocations=false when revocation is disabled")
174+
}
175+
if opt.Getter != nil {
176+
t.Error("expected nil Getter when revocation is disabled")
177+
}
178+
})
179+
180+
t.Run("revocation enabled without getter", func(t *testing.T) {
181+
s := &Server{cfg: &Config{RevocationEnabled: true}}
182+
opt := s.tdxVerifyOpt()
183+
if !opt.CheckRevocations {
184+
t.Error("expected CheckRevocations=true when revocation is enabled")
185+
}
186+
// Getter is nil when tdxGetter is not configured — the library
187+
// falls back to its default HTTP client.
188+
})
189+
190+
t.Run("revocation enabled with getter", func(t *testing.T) {
191+
getter := &cachedHTTPSGetter{}
192+
s := &Server{cfg: &Config{RevocationEnabled: true}, tdxGetter: getter}
193+
opt := s.tdxVerifyOpt()
194+
if !opt.CheckRevocations {
195+
t.Error("expected CheckRevocations=true")
196+
}
197+
if opt.Getter != getter {
198+
t.Error("expected Getter to be the configured tdxGetter")
199+
}
200+
})
201+
}
202+
168203
func TestSevsnpRevocationChecker(t *testing.T) {
169204
t.Run("nil cache returns nil checker", func(t *testing.T) {
170205
s := &Server{}

internal/ratelimit_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,35 @@ func TestRateLimitMiddleware_TimeoutReturns429(t *testing.T) {
188188
}
189189
}
190190

191+
func TestRateLimiterMap_Cleanup(t *testing.T) {
192+
m := newRateLimiterMap(1.0, 1)
193+
194+
// Create two entries: one "old" and one "recent".
195+
_ = m.get("old-ip")
196+
_ = m.get("recent-ip")
197+
198+
// Manually backdate the "old" entry.
199+
if val, ok := m.entries.Load("old-ip"); ok {
200+
val.(*rateLimiterEntry).lastSeen = time.Now().Add(-10 * time.Minute)
201+
}
202+
203+
// Cleanup with 5m maxAge should remove "old-ip" but keep "recent-ip".
204+
m.cleanup(5 * time.Minute)
205+
206+
if _, ok := m.entries.Load("old-ip"); ok {
207+
t.Error("expected old-ip to be cleaned up")
208+
}
209+
if _, ok := m.entries.Load("recent-ip"); !ok {
210+
t.Error("expected recent-ip to survive cleanup")
211+
}
212+
}
213+
214+
func TestRateLimiterMap_Cleanup_EmptyMap(t *testing.T) {
215+
m := newRateLimiterMap(1.0, 1)
216+
// Should not panic on empty map.
217+
m.cleanup(5 * time.Minute)
218+
}
219+
191220
func TestRateLimitMiddleware_PerIPIsolation(t *testing.T) {
192221
s := &Server{
193222
logger: slog.New(slog.NewJSONHandler(io.Discard, nil)),

internal/server_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"os"
1111
"path/filepath"
1212
"testing"
13+
"time"
1314

1415
"github.com/gofiber/fiber/v2"
1516
)
@@ -340,6 +341,70 @@ func TestErrorHandler_PlainError_OpaqueMessage(t *testing.T) {
340341
// NewLogger
341342
// ---------------------------------------------------------------------------
342343

344+
// ---------------------------------------------------------------------------
345+
// NewTimestamp
346+
// ---------------------------------------------------------------------------
347+
348+
func TestNewTimestamp_Format(t *testing.T) {
349+
ts := NewTimestamp()
350+
// Must be valid RFC 3339.
351+
parsed, err := time.Parse(time.RFC3339, ts)
352+
if err != nil {
353+
t.Fatalf("NewTimestamp() = %q, not valid RFC 3339: %v", ts, err)
354+
}
355+
// Must be truncated to seconds (no sub-second component).
356+
if parsed.Nanosecond() != 0 {
357+
t.Errorf("NewTimestamp() has sub-second precision: %v", parsed)
358+
}
359+
// Must be in UTC.
360+
if parsed.Location() != time.UTC {
361+
t.Errorf("NewTimestamp() not in UTC: %v", parsed.Location())
362+
}
363+
}
364+
365+
func TestNewTimestamp_Freshness(t *testing.T) {
366+
before := time.Now().UTC().Truncate(time.Second)
367+
ts := NewTimestamp()
368+
after := time.Now().UTC().Truncate(time.Second).Add(time.Second)
369+
370+
parsed, _ := time.Parse(time.RFC3339, ts)
371+
if parsed.Before(before) || parsed.After(after) {
372+
t.Errorf("NewTimestamp() = %v, not within [%v, %v]", parsed, before, after)
373+
}
374+
}
375+
376+
// ---------------------------------------------------------------------------
377+
// shutdownCtx
378+
// ---------------------------------------------------------------------------
379+
380+
func TestShutdownCtx_NilCtx(t *testing.T) {
381+
s := &Server{} // ctx is nil (pre-Run state)
382+
ctx := s.shutdownCtx()
383+
if ctx == nil {
384+
t.Fatal("shutdownCtx() returned nil, want context.Background()")
385+
}
386+
// Should not be cancelled.
387+
select {
388+
case <-ctx.Done():
389+
t.Error("shutdownCtx() context should not be cancelled")
390+
default:
391+
}
392+
}
393+
394+
func TestShutdownCtx_SetCtx(t *testing.T) {
395+
parent, cancel := context.WithCancel(context.Background())
396+
defer cancel()
397+
s := &Server{ctx: parent}
398+
ctx := s.shutdownCtx()
399+
if ctx != parent {
400+
t.Error("shutdownCtx() should return the server's context when set")
401+
}
402+
}
403+
404+
// ---------------------------------------------------------------------------
405+
// NewLogger
406+
// ---------------------------------------------------------------------------
407+
343408
func TestNewLogger_JSONFormat(t *testing.T) {
344409
cfg := &Config{LogFormat: "json", LogLevel: slog.LevelInfo}
345410
logger := NewLogger(cfg)

0 commit comments

Comments
 (0)