add step list for server creation
All checks were successful
Release and Deploy / build (push) Successful in 9m5s
Release and Deploy / deploy (push) Successful in 26s

This commit is contained in:
Fran Jurmanović
2025-09-18 22:24:51 +02:00
parent 901dbe697e
commit 4004d83411
80 changed files with 950 additions and 2554 deletions

View File

@@ -11,28 +11,22 @@ import (
)
func TestInMemoryCache_Set_Get_Success(t *testing.T) {
// Setup
c := cache.NewInMemoryCache()
// Test data
key := "test-key"
value := "test-value"
duration := 5 * time.Minute
// Set value in cache
c.Set(key, value, duration)
// Get value from cache
result, found := c.Get(key)
tests.AssertEqual(t, true, found)
tests.AssertEqual(t, value, result)
}
func TestInMemoryCache_Get_NotFound(t *testing.T) {
// Setup
c := cache.NewInMemoryCache()
// Try to get non-existent key
result, found := c.Get("non-existent-key")
tests.AssertEqual(t, false, found)
if result != nil {
@@ -41,43 +35,33 @@ func TestInMemoryCache_Get_NotFound(t *testing.T) {
}
func TestInMemoryCache_Set_Get_NoExpiration(t *testing.T) {
// Setup
c := cache.NewInMemoryCache()
// Test data
key := "test-key"
value := "test-value"
// Set value without expiration (duration = 0)
c.Set(key, value, 0)
// Get value from cache
result, found := c.Get(key)
tests.AssertEqual(t, true, found)
tests.AssertEqual(t, value, result)
}
func TestInMemoryCache_Expiration(t *testing.T) {
// Setup
c := cache.NewInMemoryCache()
// Test data
key := "test-key"
value := "test-value"
duration := 1 * time.Millisecond // Very short duration
duration := 1 * time.Millisecond
// Set value in cache
c.Set(key, value, duration)
// Verify it's initially there
result, found := c.Get(key)
tests.AssertEqual(t, true, found)
tests.AssertEqual(t, value, result)
// Wait for expiration
time.Sleep(2 * time.Millisecond)
// Try to get expired value
result, found = c.Get(key)
tests.AssertEqual(t, false, found)
if result != nil {
@@ -86,26 +70,20 @@ func TestInMemoryCache_Expiration(t *testing.T) {
}
func TestInMemoryCache_Delete(t *testing.T) {
// Setup
c := cache.NewInMemoryCache()
// Test data
key := "test-key"
value := "test-value"
duration := 5 * time.Minute
// Set value in cache
c.Set(key, value, duration)
// Verify it's there
result, found := c.Get(key)
tests.AssertEqual(t, true, found)
tests.AssertEqual(t, value, result)
// Delete the key
c.Delete(key)
// Verify it's gone
result, found = c.Get(key)
tests.AssertEqual(t, false, found)
if result != nil {
@@ -114,37 +92,29 @@ func TestInMemoryCache_Delete(t *testing.T) {
}
func TestInMemoryCache_Overwrite(t *testing.T) {
// Setup
c := cache.NewInMemoryCache()
// Test data
key := "test-key"
value1 := "test-value-1"
value2 := "test-value-2"
duration := 5 * time.Minute
// Set first value
c.Set(key, value1, duration)
// Verify first value
result, found := c.Get(key)
tests.AssertEqual(t, true, found)
tests.AssertEqual(t, value1, result)
// Overwrite with second value
c.Set(key, value2, duration)
// Verify second value
result, found = c.Get(key)
tests.AssertEqual(t, true, found)
tests.AssertEqual(t, value2, result)
}
func TestInMemoryCache_Multiple_Keys(t *testing.T) {
// Setup
c := cache.NewInMemoryCache()
// Test data
testData := map[string]string{
"key1": "value1",
"key2": "value2",
@@ -152,22 +122,18 @@ func TestInMemoryCache_Multiple_Keys(t *testing.T) {
}
duration := 5 * time.Minute
// Set multiple values
for key, value := range testData {
c.Set(key, value, duration)
}
// Verify all values
for key, expectedValue := range testData {
result, found := c.Get(key)
tests.AssertEqual(t, true, found)
tests.AssertEqual(t, expectedValue, result)
}
// Delete one key
c.Delete("key2")
// Verify key2 is gone but others remain
result, found := c.Get("key2")
tests.AssertEqual(t, false, found)
if result != nil {
@@ -184,10 +150,8 @@ func TestInMemoryCache_Multiple_Keys(t *testing.T) {
}
func TestInMemoryCache_Complex_Objects(t *testing.T) {
// Setup
c := cache.NewInMemoryCache()
// Test with complex object (User struct)
user := &model.User{
ID: uuid.New(),
Username: "testuser",
@@ -196,15 +160,12 @@ func TestInMemoryCache_Complex_Objects(t *testing.T) {
key := "user:" + user.ID.String()
duration := 5 * time.Minute
// Set user in cache
c.Set(key, user, duration)
// Get user from cache
result, found := c.Get(key)
tests.AssertEqual(t, true, found)
tests.AssertNotNil(t, result)
// Verify it's the same user
cachedUser, ok := result.(*model.User)
tests.AssertEqual(t, true, ok)
tests.AssertEqual(t, user.ID, cachedUser.ID)
@@ -212,33 +173,27 @@ func TestInMemoryCache_Complex_Objects(t *testing.T) {
}
func TestInMemoryCache_GetOrSet_CacheHit(t *testing.T) {
// Setup
c := cache.NewInMemoryCache()
// Pre-populate cache
key := "test-key"
expectedValue := "cached-value"
c.Set(key, expectedValue, 5*time.Minute)
// Track if fetcher is called
fetcherCalled := false
fetcher := func() (string, error) {
fetcherCalled = true
return "fetcher-value", nil
}
// Use GetOrSet - should return cached value
result, err := cache.GetOrSet(c, key, 5*time.Minute, fetcher)
tests.AssertNoError(t, err)
tests.AssertEqual(t, expectedValue, result)
tests.AssertEqual(t, false, fetcherCalled) // Fetcher should not be called
tests.AssertEqual(t, false, fetcherCalled)
}
func TestInMemoryCache_GetOrSet_CacheMiss(t *testing.T) {
// Setup
c := cache.NewInMemoryCache()
// Track if fetcher is called
fetcherCalled := false
expectedValue := "fetcher-value"
fetcher := func() (string, error) {
@@ -248,35 +203,29 @@ func TestInMemoryCache_GetOrSet_CacheMiss(t *testing.T) {
key := "test-key"
// Use GetOrSet - should call fetcher and cache result
result, err := cache.GetOrSet(c, key, 5*time.Minute, fetcher)
tests.AssertNoError(t, err)
tests.AssertEqual(t, expectedValue, result)
tests.AssertEqual(t, true, fetcherCalled) // Fetcher should be called
tests.AssertEqual(t, true, fetcherCalled)
// Verify value is now cached
cachedResult, found := c.Get(key)
tests.AssertEqual(t, true, found)
tests.AssertEqual(t, expectedValue, cachedResult)
}
func TestInMemoryCache_GetOrSet_FetcherError(t *testing.T) {
// Setup
c := cache.NewInMemoryCache()
// Fetcher that returns error
fetcher := func() (string, error) {
return "", tests.ErrorForTesting("fetcher error")
}
key := "test-key"
// Use GetOrSet - should return error
result, err := cache.GetOrSet(c, key, 5*time.Minute, fetcher)
tests.AssertError(t, err, "")
tests.AssertEqual(t, "", result)
// Verify nothing is cached
cachedResult, found := c.Get(key)
tests.AssertEqual(t, false, found)
if cachedResult != nil {
@@ -285,10 +234,8 @@ func TestInMemoryCache_GetOrSet_FetcherError(t *testing.T) {
}
func TestInMemoryCache_TypeSafety(t *testing.T) {
// Setup
c := cache.NewInMemoryCache()
// Test type safety with GetOrSet
userFetcher := func() (*model.User, error) {
return &model.User{
ID: uuid.New(),
@@ -298,13 +245,11 @@ func TestInMemoryCache_TypeSafety(t *testing.T) {
key := "user-key"
// Use GetOrSet with User type
user, err := cache.GetOrSet(c, key, 5*time.Minute, userFetcher)
tests.AssertNoError(t, err)
tests.AssertNotNil(t, user)
tests.AssertEqual(t, "testuser", user.Username)
// Verify correct type is cached
cachedResult, found := c.Get(key)
tests.AssertEqual(t, true, found)
cachedUser, ok := cachedResult.(*model.User)
@@ -313,26 +258,21 @@ func TestInMemoryCache_TypeSafety(t *testing.T) {
}
func TestInMemoryCache_Concurrent_Access(t *testing.T) {
// Setup
c := cache.NewInMemoryCache()
// Test concurrent access
key := "concurrent-key"
value := "concurrent-value"
duration := 5 * time.Minute
// Run concurrent operations
done := make(chan bool, 3)
// Goroutine 1: Set value
go func() {
c.Set(key, value, duration)
done <- true
}()
// Goroutine 2: Get value
go func() {
time.Sleep(1 * time.Millisecond) // Small delay to ensure Set happens first
time.Sleep(1 * time.Millisecond)
result, found := c.Get(key)
if found {
tests.AssertEqual(t, value, result)
@@ -340,19 +280,16 @@ func TestInMemoryCache_Concurrent_Access(t *testing.T) {
done <- true
}()
// Goroutine 3: Delete value
go func() {
time.Sleep(2 * time.Millisecond) // Delay to ensure Set and Get happen first
time.Sleep(2 * time.Millisecond)
c.Delete(key)
done <- true
}()
// Wait for all goroutines to complete
for i := 0; i < 3; i++ {
<-done
}
// Verify value is deleted
result, found := c.Get(key)
tests.AssertEqual(t, false, found)
if result != nil {
@@ -361,7 +298,6 @@ func TestInMemoryCache_Concurrent_Access(t *testing.T) {
}
func TestServerStatusCache_GetStatus_NeedsRefresh(t *testing.T) {
// Setup
config := model.CacheConfig{
ExpirationTime: 5 * time.Minute,
ThrottleTime: 1 * time.Second,
@@ -371,14 +307,12 @@ func TestServerStatusCache_GetStatus_NeedsRefresh(t *testing.T) {
serviceName := "test-service"
// Initial call - should need refresh
status, needsRefresh := cache.GetStatus(serviceName)
tests.AssertEqual(t, model.StatusUnknown, status)
tests.AssertEqual(t, true, needsRefresh)
}
func TestServerStatusCache_UpdateStatus_GetStatus(t *testing.T) {
// Setup
config := model.CacheConfig{
ExpirationTime: 5 * time.Minute,
ThrottleTime: 1 * time.Second,
@@ -389,17 +323,14 @@ func TestServerStatusCache_UpdateStatus_GetStatus(t *testing.T) {
serviceName := "test-service"
expectedStatus := model.StatusRunning
// Update status
cache.UpdateStatus(serviceName, expectedStatus)
// Get status - should return cached value
status, needsRefresh := cache.GetStatus(serviceName)
tests.AssertEqual(t, expectedStatus, status)
tests.AssertEqual(t, false, needsRefresh)
}
func TestServerStatusCache_Throttling(t *testing.T) {
// Setup
config := model.CacheConfig{
ExpirationTime: 5 * time.Minute,
ThrottleTime: 100 * time.Millisecond,
@@ -409,58 +340,44 @@ func TestServerStatusCache_Throttling(t *testing.T) {
serviceName := "test-service"
// Update status
cache.UpdateStatus(serviceName, model.StatusRunning)
// Immediate call - should return cached value
status, needsRefresh := cache.GetStatus(serviceName)
tests.AssertEqual(t, model.StatusRunning, status)
tests.AssertEqual(t, false, needsRefresh)
// Call within throttle time - should return cached/default status
status, needsRefresh = cache.GetStatus(serviceName)
tests.AssertEqual(t, model.StatusRunning, status)
tests.AssertEqual(t, false, needsRefresh)
// Wait for throttle time to pass
time.Sleep(150 * time.Millisecond)
// Call after throttle time - don't check the specific value of needsRefresh
// as it may vary depending on the implementation
_, _ = cache.GetStatus(serviceName)
// Test passes if we reach this point without errors
}
func TestServerStatusCache_Expiration(t *testing.T) {
// Setup
config := model.CacheConfig{
ExpirationTime: 50 * time.Millisecond, // Very short expiration
ExpirationTime: 50 * time.Millisecond,
ThrottleTime: 10 * time.Millisecond,
DefaultStatus: model.StatusUnknown,
}
cache := model.NewServerStatusCache(config)
serviceName := "test-service"
// Update status
cache.UpdateStatus(serviceName, model.StatusRunning)
// Immediate call - should return cached value
status, needsRefresh := cache.GetStatus(serviceName)
tests.AssertEqual(t, model.StatusRunning, status)
tests.AssertEqual(t, false, needsRefresh)
// Wait for expiration
time.Sleep(60 * time.Millisecond)
// Call after expiration - should need refresh
status, needsRefresh = cache.GetStatus(serviceName)
tests.AssertEqual(t, true, needsRefresh)
}
func TestServerStatusCache_InvalidateStatus(t *testing.T) {
// Setup
config := model.CacheConfig{
ExpirationTime: 5 * time.Minute,
ThrottleTime: 1 * time.Second,
@@ -470,25 +387,20 @@ func TestServerStatusCache_InvalidateStatus(t *testing.T) {
serviceName := "test-service"
// Update status
cache.UpdateStatus(serviceName, model.StatusRunning)
// Verify it's cached
status, needsRefresh := cache.GetStatus(serviceName)
tests.AssertEqual(t, model.StatusRunning, status)
tests.AssertEqual(t, false, needsRefresh)
// Invalidate status
cache.InvalidateStatus(serviceName)
// Should need refresh now
status, needsRefresh = cache.GetStatus(serviceName)
tests.AssertEqual(t, model.StatusUnknown, status)
tests.AssertEqual(t, true, needsRefresh)
}
func TestServerStatusCache_Clear(t *testing.T) {
// Setup
config := model.CacheConfig{
ExpirationTime: 5 * time.Minute,
ThrottleTime: 1 * time.Second,
@@ -496,23 +408,19 @@ func TestServerStatusCache_Clear(t *testing.T) {
}
cache := model.NewServerStatusCache(config)
// Update multiple services
services := []string{"service1", "service2", "service3"}
for _, service := range services {
cache.UpdateStatus(service, model.StatusRunning)
}
// Verify all are cached
for _, service := range services {
status, needsRefresh := cache.GetStatus(service)
tests.AssertEqual(t, model.StatusRunning, status)
tests.AssertEqual(t, false, needsRefresh)
}
// Clear cache
cache.Clear()
// All should need refresh now
for _, service := range services {
status, needsRefresh := cache.GetStatus(service)
tests.AssertEqual(t, model.StatusUnknown, status)
@@ -521,30 +429,23 @@ func TestServerStatusCache_Clear(t *testing.T) {
}
func TestLookupCache_SetGetClear(t *testing.T) {
// Setup
cache := model.NewLookupCache()
// Test data
key := "lookup-key"
value := map[string]string{"test": "data"}
// Set value
cache.Set(key, value)
// Get value
result, found := cache.Get(key)
tests.AssertEqual(t, true, found)
tests.AssertNotNil(t, result)
// Verify it's the same data
resultMap, ok := result.(map[string]string)
tests.AssertEqual(t, true, ok)
tests.AssertEqual(t, "data", resultMap["test"])
// Clear cache
cache.Clear()
// Should be gone now
result, found = cache.Get(key)
tests.AssertEqual(t, false, found)
if result != nil {
@@ -553,7 +454,6 @@ func TestLookupCache_SetGetClear(t *testing.T) {
}
func TestServerConfigCache_Configuration(t *testing.T) {
// Setup
config := model.CacheConfig{
ExpirationTime: 5 * time.Minute,
ThrottleTime: 1 * time.Second,
@@ -571,17 +471,14 @@ func TestServerConfigCache_Configuration(t *testing.T) {
ConfigVersion: model.IntString(1),
}
// Initial get - should miss
result, found := cache.GetConfiguration(serverID)
tests.AssertEqual(t, false, found)
if result != nil {
t.Fatal("Expected nil result, got non-nil")
}
// Update cache
cache.UpdateConfiguration(serverID, configuration)
// Get from cache - should hit
result, found = cache.GetConfiguration(serverID)
tests.AssertEqual(t, true, found)
tests.AssertNotNil(t, result)
@@ -590,7 +487,6 @@ func TestServerConfigCache_Configuration(t *testing.T) {
}
func TestServerConfigCache_InvalidateServerCache(t *testing.T) {
// Setup
config := model.CacheConfig{
ExpirationTime: 5 * time.Minute,
ThrottleTime: 1 * time.Second,
@@ -602,11 +498,9 @@ func TestServerConfigCache_InvalidateServerCache(t *testing.T) {
configuration := model.Configuration{UdpPort: model.IntString(9231)}
assistRules := model.AssistRules{StabilityControlLevelMax: model.IntString(0)}
// Update multiple configs for server
cache.UpdateConfiguration(serverID, configuration)
cache.UpdateAssistRules(serverID, assistRules)
// Verify both are cached
configResult, found := cache.GetConfiguration(serverID)
tests.AssertEqual(t, true, found)
tests.AssertNotNil(t, configResult)
@@ -615,10 +509,8 @@ func TestServerConfigCache_InvalidateServerCache(t *testing.T) {
tests.AssertEqual(t, true, found)
tests.AssertNotNil(t, assistResult)
// Invalidate server cache
cache.InvalidateServerCache(serverID)
// Both should be gone
configResult, found = cache.GetConfiguration(serverID)
tests.AssertEqual(t, false, found)
if configResult != nil {