mirror of
https://github.com/lukaszraczylo/kportal.git
synced 2026-06-05 23:03:40 +00:00
f41c316b2b
* Add configuration wizard.
287 lines
6.7 KiB
Go
287 lines
6.7 KiB
Go
package forward
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/nvm/kportal/internal/config"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestLogWriter_Write(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
prefix string
|
|
input string
|
|
expectedInLog string
|
|
description string
|
|
}{
|
|
{
|
|
name: "write simple message",
|
|
prefix: "[worker] ",
|
|
input: "test message",
|
|
expectedInLog: "[worker] test message",
|
|
description: "Should write message with prefix to log",
|
|
},
|
|
{
|
|
name: "write empty message",
|
|
prefix: "[test] ",
|
|
input: "",
|
|
expectedInLog: "[test] ",
|
|
description: "Should handle empty message",
|
|
},
|
|
{
|
|
name: "write multiline message",
|
|
prefix: "[fwd] ",
|
|
input: "line1\nline2",
|
|
expectedInLog: "[fwd] line1\nline2",
|
|
description: "Should handle multiline messages",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Test logWriter
|
|
originalWriter := &logWriter{prefix: tt.prefix}
|
|
|
|
n, err := originalWriter.Write([]byte(tt.input))
|
|
|
|
require.NoError(t, err, "Write should not return error")
|
|
assert.Equal(t, len(tt.input), n, "Write should return number of bytes written")
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestForwardWorker_GetForward(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
forward config.Forward
|
|
description string
|
|
}{
|
|
{
|
|
name: "get pod forward",
|
|
forward: config.Forward{
|
|
Resource: "pod/my-app",
|
|
LocalPort: 8080,
|
|
Port: 80,
|
|
Protocol: "tcp",
|
|
},
|
|
description: "Should return the forward configuration",
|
|
},
|
|
{
|
|
name: "get service forward",
|
|
forward: config.Forward{
|
|
Resource: "service/postgres",
|
|
LocalPort: 5432,
|
|
Port: 5432,
|
|
Protocol: "tcp",
|
|
},
|
|
description: "Should return service forward configuration",
|
|
},
|
|
{
|
|
name: "get forward with selector",
|
|
forward: config.Forward{
|
|
Resource: "pod",
|
|
Selector: "app=nginx,env=prod",
|
|
LocalPort: 8080,
|
|
Port: 80,
|
|
Protocol: "tcp",
|
|
},
|
|
description: "Should return forward with label selector",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Note: We can't easily test the full worker lifecycle without mocks,
|
|
// but we can test the constructor and simple getters
|
|
|
|
// This test would require proper mocking setup
|
|
// For now, we'll test the Forward struct directly
|
|
|
|
id := tt.forward.ID()
|
|
assert.NotEmpty(t, id, "Forward should have an ID")
|
|
|
|
forwardStr := tt.forward.String()
|
|
assert.NotEmpty(t, forwardStr, "Forward should have a string representation")
|
|
assert.Contains(t, forwardStr, tt.forward.Resource, "String should contain resource")
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestForwardWorker_IsRunning(t *testing.T) {
|
|
// This is a basic test of the goroutine state tracking
|
|
// Full integration tests would require mock dependencies
|
|
|
|
t.Run("worker state tracking", func(t *testing.T) {
|
|
// Test the concept of the done channel
|
|
doneChan := make(chan struct{})
|
|
|
|
// Initially, channel is open (worker would be running)
|
|
select {
|
|
case <-doneChan:
|
|
t.Fatal("doneChan should be open initially")
|
|
default:
|
|
// Expected: channel is open
|
|
}
|
|
|
|
// Close the channel (simulating worker done)
|
|
close(doneChan)
|
|
|
|
// Now channel should be closed
|
|
select {
|
|
case <-doneChan:
|
|
// Expected: channel is closed
|
|
default:
|
|
t.Fatal("doneChan should be closed after close")
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestForwardID(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
forward config.Forward
|
|
expectUnique bool
|
|
description string
|
|
}{
|
|
{
|
|
name: "unique IDs for different forwards",
|
|
forward: config.Forward{
|
|
Resource: "pod/app1",
|
|
LocalPort: 8080,
|
|
Port: 80,
|
|
},
|
|
expectUnique: true,
|
|
description: "Different forwards should have different IDs",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
id1 := tt.forward.ID()
|
|
|
|
// Create a different forward
|
|
fwd2 := config.Forward{
|
|
Resource: "pod/app2",
|
|
LocalPort: 8081,
|
|
Port: 80,
|
|
}
|
|
id2 := fwd2.ID()
|
|
|
|
if tt.expectUnique {
|
|
assert.NotEqual(t, id1, id2, "Different forwards should have different IDs")
|
|
}
|
|
|
|
// Same forward should produce same ID
|
|
id3 := tt.forward.ID()
|
|
assert.Equal(t, id1, id3, "Same forward should produce same ID")
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestForwardString(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
forward config.Forward
|
|
expectedContains []string
|
|
description string
|
|
}{
|
|
{
|
|
name: "pod forward string",
|
|
forward: config.Forward{
|
|
Resource: "pod/my-app",
|
|
LocalPort: 8080,
|
|
Port: 80,
|
|
},
|
|
expectedContains: []string{"pod/my-app", "8080", "80"},
|
|
description: "Should contain resource and ports",
|
|
},
|
|
{
|
|
name: "service forward string",
|
|
forward: config.Forward{
|
|
Resource: "service/postgres",
|
|
LocalPort: 5432,
|
|
Port: 5432,
|
|
},
|
|
expectedContains: []string{"service/postgres", "5432"},
|
|
description: "Should contain service and port",
|
|
},
|
|
{
|
|
name: "selector forward string",
|
|
forward: config.Forward{
|
|
Resource: "pod",
|
|
Selector: "app=nginx",
|
|
LocalPort: 8080,
|
|
Port: 80,
|
|
},
|
|
expectedContains: []string{"app=nginx", "8080", "80"},
|
|
description: "Should contain selector and ports",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := tt.forward.String()
|
|
|
|
assert.NotEmpty(t, result, "String representation should not be empty")
|
|
|
|
for _, expected := range tt.expectedContains {
|
|
assert.Contains(t, result, expected,
|
|
"String should contain %s", expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSleepWithBackoffConcept(t *testing.T) {
|
|
// Test the backoff concept without actually running a worker
|
|
t.Run("backoff delay increases", func(t *testing.T) {
|
|
// This tests the retry backoff behavior conceptually
|
|
delays := []int{1, 2, 4, 8, 10, 10, 10}
|
|
|
|
for i, expected := range delays {
|
|
// Simulate backoff calculation
|
|
delay := 1
|
|
for j := 0; j < i; j++ {
|
|
delay *= 2
|
|
if delay > 10 {
|
|
delay = 10
|
|
}
|
|
}
|
|
|
|
assert.Equal(t, expected, delay,
|
|
"Backoff at attempt %d should be %d", i, expected)
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestWorkerVerboseMode(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
verbose bool
|
|
description string
|
|
}{
|
|
{
|
|
name: "verbose mode enabled",
|
|
verbose: true,
|
|
description: "Worker should respect verbose flag",
|
|
},
|
|
{
|
|
name: "verbose mode disabled",
|
|
verbose: false,
|
|
description: "Worker should respect non-verbose flag",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Test that verbose flag is a boolean
|
|
assert.IsType(t, bool(true), tt.verbose)
|
|
|
|
// In a real worker, this would control logging
|
|
// For now, we just verify the type
|
|
})
|
|
}
|
|
}
|