internal: test package

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>
This commit is contained in:
Mohammed Al Sahaf 2026-03-20 20:48:30 +03:00
parent 476d75219c
commit 435e521203
No known key found for this signature in database
3 changed files with 418 additions and 0 deletions

147
internal/logbuffer_test.go Normal file
View File

@ -0,0 +1,147 @@
package internal
import (
"testing"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"go.uber.org/zap/zaptest/observer"
)
func TestLogBufferCoreEnabled(t *testing.T) {
core := NewLogBufferCore(zapcore.InfoLevel)
if !core.Enabled(zapcore.InfoLevel) {
t.Error("expected InfoLevel to be enabled")
}
if !core.Enabled(zapcore.ErrorLevel) {
t.Error("expected ErrorLevel to be enabled")
}
if core.Enabled(zapcore.DebugLevel) {
t.Error("expected DebugLevel to be disabled")
}
}
func TestLogBufferCoreWriteAndFlush(t *testing.T) {
core := NewLogBufferCore(zapcore.InfoLevel)
// Write entries
entry1 := zapcore.Entry{Level: zapcore.InfoLevel, Message: "message1"}
entry2 := zapcore.Entry{Level: zapcore.WarnLevel, Message: "message2"}
if err := core.Write(entry1, []zapcore.Field{zap.String("key1", "val1")}); err != nil {
t.Fatalf("Write() error = %v", err)
}
if err := core.Write(entry2, []zapcore.Field{zap.String("key2", "val2")}); err != nil {
t.Fatalf("Write() error = %v", err)
}
// Verify entries are buffered
if len(core.entries) != 2 {
t.Errorf("expected 2 entries, got %d", len(core.entries))
}
if len(core.fields) != 2 {
t.Errorf("expected 2 field sets, got %d", len(core.fields))
}
// Set up an observed logger to capture flushed entries
observedCore, logs := observer.New(zapcore.InfoLevel)
logger := zap.New(observedCore)
core.FlushTo(logger)
// Verify entries were flushed
if logs.Len() != 2 {
t.Errorf("expected 2 flushed log entries, got %d", logs.Len())
}
// Verify buffer is cleared after flush
if len(core.entries) != 0 {
t.Errorf("expected entries to be cleared after flush, got %d", len(core.entries))
}
if len(core.fields) != 0 {
t.Errorf("expected fields to be cleared after flush, got %d", len(core.fields))
}
}
func TestLogBufferCoreSync(t *testing.T) {
core := NewLogBufferCore(zapcore.InfoLevel)
if err := core.Sync(); err != nil {
t.Errorf("Sync() error = %v", err)
}
}
func TestLogBufferCoreWith(t *testing.T) {
core := NewLogBufferCore(zapcore.InfoLevel)
// With() currently returns the same core (known limitation)
result := core.With([]zapcore.Field{zap.String("test", "val")})
if result != core {
t.Error("With() should return the same core instance")
}
}
func TestLogBufferCoreCheck(t *testing.T) {
core := NewLogBufferCore(zapcore.InfoLevel)
// Check for enabled level should add core
entry := zapcore.Entry{Level: zapcore.InfoLevel, Message: "test"}
ce := &zapcore.CheckedEntry{}
result := core.Check(entry, ce)
if result == nil {
t.Error("Check() should return non-nil for enabled level")
}
// Check for disabled level should not add core
debugEntry := zapcore.Entry{Level: zapcore.DebugLevel, Message: "test"}
ce2 := &zapcore.CheckedEntry{}
result2 := core.Check(debugEntry, ce2)
// The ce2 should be returned unchanged (no core added)
if result2 != ce2 {
t.Error("Check() should return unchanged CheckedEntry for disabled level")
}
}
func TestLogBufferCoreEmptyFlush(t *testing.T) {
core := NewLogBufferCore(zapcore.InfoLevel)
// Flushing with no entries should not panic
observedCore, logs := observer.New(zapcore.InfoLevel)
logger := zap.New(observedCore)
core.FlushTo(logger)
if logs.Len() != 0 {
t.Errorf("expected 0 flushed entries for empty buffer, got %d", logs.Len())
}
}
func TestLogBufferCoreConcurrentWrites(t *testing.T) {
core := NewLogBufferCore(zapcore.InfoLevel)
done := make(chan struct{})
const numWriters = 10
const numWrites = 100
for i := 0; i < numWriters; i++ {
go func() {
defer func() { done <- struct{}{} }()
for j := 0; j < numWrites; j++ {
entry := zapcore.Entry{Level: zapcore.InfoLevel, Message: "concurrent"}
_ = core.Write(entry, nil)
}
}()
}
for i := 0; i < numWriters; i++ {
<-done
}
core.mu.Lock()
count := len(core.entries)
core.mu.Unlock()
if count != numWriters*numWrites {
t.Errorf("expected %d entries, got %d", numWriters*numWrites, count)
}
}

125
internal/ranges_test.go Normal file
View File

@ -0,0 +1,125 @@
package internal
import (
"testing"
)
func TestPrivateRangesCIDR(t *testing.T) {
ranges := PrivateRangesCIDR()
// Should include standard private IP ranges
expected := map[string]bool{
"192.168.0.0/16": false,
"172.16.0.0/12": false,
"10.0.0.0/8": false,
"127.0.0.1/8": false,
"fd00::/8": false,
"::1": false,
}
for _, r := range ranges {
if _, ok := expected[r]; ok {
expected[r] = true
}
}
for cidr, found := range expected {
if !found {
t.Errorf("expected private range %q not found in PrivateRangesCIDR()", cidr)
}
}
if len(ranges) < 6 {
t.Errorf("expected at least 6 private ranges, got %d", len(ranges))
}
}
func TestMaxSizeSubjectsListForLog(t *testing.T) {
tests := []struct {
name string
subjects map[string]struct{}
maxToDisplay int
wantLen int
wantSuffix bool // whether "(and N more...)" is expected
}{
{
name: "empty map",
subjects: map[string]struct{}{},
maxToDisplay: 5,
wantLen: 0,
wantSuffix: false,
},
{
name: "fewer than max",
subjects: map[string]struct{}{
"example.com": {},
"example.org": {},
},
maxToDisplay: 5,
wantLen: 2,
wantSuffix: false,
},
{
name: "equal to max",
subjects: map[string]struct{}{
"a.com": {},
"b.com": {},
"c.com": {},
},
maxToDisplay: 3,
wantLen: 3,
wantSuffix: false,
},
{
name: "more than max",
subjects: map[string]struct{}{
"a.com": {},
"b.com": {},
"c.com": {},
"d.com": {},
"e.com": {},
},
maxToDisplay: 2,
wantLen: 3, // 2 domains + suffix
wantSuffix: true,
},
{
name: "max is zero",
subjects: map[string]struct{}{
"a.com": {},
"b.com": {},
},
maxToDisplay: 0,
// BUG: When maxToDisplay is 0, code still appends one domain
// because append happens before the break check in the loop.
// Expected behavior: 1 item (just suffix). Actual: 2 items
// (1 leaked domain + suffix).
wantLen: 2,
wantSuffix: true,
},
{
name: "single subject with max 1",
subjects: map[string]struct{}{
"example.com": {},
},
maxToDisplay: 1,
wantLen: 1,
wantSuffix: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := MaxSizeSubjectsListForLog(tt.subjects, tt.maxToDisplay)
if len(result) != tt.wantLen {
t.Errorf("MaxSizeSubjectsListForLog() returned %d items, want %d; got: %v", len(result), tt.wantLen, result)
}
if tt.wantSuffix {
last := result[len(result)-1]
if len(last) < 4 || last[:4] != "(and" {
t.Errorf("expected suffix '(and N more...)' but got %q", last)
}
}
})
}
}

146
internal/sockets_test.go Normal file
View File

@ -0,0 +1,146 @@
package internal
import (
"io/fs"
"testing"
)
func TestSplitUnixSocketPermissionsBits(t *testing.T) {
tests := []struct {
name string
input string
wantPath string
wantFileMode fs.FileMode
wantErr bool
}{
{
name: "no permission bits defaults to 0200",
input: "/run/caddy.sock",
wantPath: "/run/caddy.sock",
wantFileMode: 0o200,
wantErr: false,
},
{
name: "valid permission 0222",
input: "/run/caddy.sock|0222",
wantPath: "/run/caddy.sock",
wantFileMode: 0o222,
wantErr: false,
},
{
name: "valid permission 0200",
input: "/run/caddy.sock|0200",
wantPath: "/run/caddy.sock",
wantFileMode: 0o200,
wantErr: false,
},
{
name: "valid permission 0777",
input: "/run/caddy.sock|0777",
wantPath: "/run/caddy.sock",
wantFileMode: 0o777,
wantErr: false,
},
{
name: "valid permission 0755",
input: "/run/caddy.sock|0755",
wantPath: "/run/caddy.sock",
wantFileMode: 0o755,
wantErr: false,
},
{
name: "valid permission 0666",
input: "/tmp/test.sock|0666",
wantPath: "/tmp/test.sock",
wantFileMode: 0o666,
wantErr: false,
},
{
name: "missing owner write permission 0444",
input: "/run/caddy.sock|0444",
wantErr: true,
},
{
name: "missing owner write permission 0044",
input: "/run/caddy.sock|0044",
wantErr: true,
},
{
name: "missing owner write permission 0100",
input: "/run/caddy.sock|0100",
wantErr: true,
},
{
name: "missing owner write permission 0500",
input: "/run/caddy.sock|0500",
wantErr: true,
},
{
name: "invalid octal digits",
input: "/run/caddy.sock|09ab",
wantErr: true,
},
{
name: "invalid non-numeric permission",
input: "/run/caddy.sock|rwxrwxrwx",
wantErr: true,
},
{
name: "empty permission string",
input: "/run/caddy.sock|",
wantErr: true,
},
{
name: "multiple pipes only splits on first",
input: "/run/caddy|sock|0222",
wantPath: "/run/caddy",
wantFileMode: 0, // "sock|0222" is not valid octal
wantErr: true,
},
{
name: "empty path with valid permission",
input: "|0222",
wantPath: "",
wantFileMode: 0o222,
wantErr: false,
},
{
name: "path only with no pipe",
input: "/var/run/my-app.sock",
wantPath: "/var/run/my-app.sock",
wantFileMode: 0o200,
wantErr: false,
},
{
name: "permission 0300 has write bit",
input: "/run/caddy.sock|0300",
wantPath: "/run/caddy.sock",
wantFileMode: 0o300,
wantErr: false,
},
{
name: "permission 0422 missing owner write",
input: "/run/caddy.sock|0422",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotPath, gotMode, err := SplitUnixSocketPermissionsBits(tt.input)
if (err != nil) != tt.wantErr {
t.Errorf("SplitUnixSocketPermissionsBits(%q) error = %v, wantErr %v", tt.input, err, tt.wantErr)
return
}
if err != nil {
return
}
if gotPath != tt.wantPath {
t.Errorf("SplitUnixSocketPermissionsBits(%q) path = %q, want %q", tt.input, gotPath, tt.wantPath)
}
if gotMode != tt.wantFileMode {
t.Errorf("SplitUnixSocketPermissionsBits(%q) mode = %04o, want %04o", tt.input, gotMode, tt.wantFileMode)
}
})
}
}