Skip to content

Commit 376b492

Browse files
committed
chore: modify test cases
1 parent 3a0d454 commit 376b492

File tree

1 file changed

+97
-208
lines changed

1 file changed

+97
-208
lines changed

cmd/internal/kube/daemonset/pod_args_test.go

Lines changed: 97 additions & 208 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@ import (
55
"testing"
66
"time"
77

8-
"github.com/akitasoftware/akita-libs/akid"
9-
"github.com/akitasoftware/akita-libs/tags"
108
"github.com/stretchr/testify/assert"
11-
"github.com/stretchr/testify/require"
129
)
1310

1411
// TestPodArgs_StateTransitions tests basic valid state transitions
@@ -228,51 +225,6 @@ func TestPodArgs_ConcurrentAccess(t *testing.T) {
228225
assert.Equal(t, PodRunning, podArgs.PodTrafficMonitorState, "Final state should be PodRunning")
229226
})
230227

231-
t.Run("Concurrent reads while state is being changed", func(t *testing.T) {
232-
podArgs := NewPodArgs("test-pod")
233-
podArgs.PodTrafficMonitorState = PodPending
234-
235-
var wg sync.WaitGroup
236-
readResults := make(chan PodTrafficMonitorState, 100)
237-
238-
// Start a goroutine that continuously changes state
239-
wg.Add(1)
240-
go func() {
241-
defer wg.Done()
242-
for i := 0; i < 10; i++ {
243-
podArgs.changePodTrafficMonitorState(PodRunning, PodPending)
244-
time.Sleep(1 * time.Millisecond)
245-
podArgs.changePodTrafficMonitorState(PodPending, PodRunning)
246-
time.Sleep(1 * time.Millisecond)
247-
}
248-
}()
249-
250-
// Start multiple goroutines reading state
251-
for i := 0; i < 5; i++ {
252-
wg.Add(1)
253-
go func() {
254-
defer wg.Done()
255-
for j := 0; j < 20; j++ {
256-
readResults <- podArgs.PodTrafficMonitorState
257-
time.Sleep(1 * time.Millisecond)
258-
}
259-
}()
260-
}
261-
262-
wg.Wait()
263-
close(readResults)
264-
265-
// Verify all read results are valid states
266-
validStates := map[PodTrafficMonitorState]bool{
267-
PodPending: true,
268-
PodRunning: true,
269-
}
270-
271-
for state := range readResults {
272-
assert.True(t, validStates[state], "Read state should be valid: %s", state)
273-
}
274-
})
275-
276228
t.Run("Race condition between state change and markAsPruneReady", func(t *testing.T) {
277229
podArgs := NewPodArgs("test-pod")
278230
podArgs.PodTrafficMonitorState = TrafficMonitoringEnded
@@ -446,166 +398,6 @@ func TestPodArgs_EdgeCases(t *testing.T) {
446398
assert.NoError(t, err)
447399
assert.Equal(t, PodRunning, podArgs.PodTrafficMonitorState)
448400
})
449-
450-
t.Run("State transition with nil allowed states", func(t *testing.T) {
451-
podArgs := NewPodArgs("test-pod")
452-
podArgs.PodTrafficMonitorState = PodPending
453-
454-
// Nil allowed states should allow any transition
455-
err := podArgs.changePodTrafficMonitorState(PodRunning)
456-
assert.NoError(t, err)
457-
assert.Equal(t, PodRunning, podArgs.PodTrafficMonitorState)
458-
})
459-
460-
t.Run("NewPodArgs creates valid instance", func(t *testing.T) {
461-
podArgs := NewPodArgs("test-pod")
462-
463-
assert.Equal(t, "test-pod", podArgs.PodName)
464-
assert.NotNil(t, podArgs.TraceTags)
465-
assert.NotNil(t, podArgs.StopChan)
466-
assert.Equal(t, 2, cap(podArgs.StopChan))
467-
assert.Equal(t, PodTrafficMonitorState(""), podArgs.PodTrafficMonitorState) // Zero value
468-
})
469-
470-
t.Run("PodArgs fields are properly initialized", func(t *testing.T) {
471-
podArgs := NewPodArgs("test-pod")
472-
473-
// Test that fields can be set and retrieved
474-
podArgs.InsightsProjectID = akid.ServiceID{}
475-
podArgs.ContainerUUID = "test-container-uuid"
476-
podArgs.ReproMode = true
477-
podArgs.DropNginxTraffic = true
478-
podArgs.AgentRateLimit = 100.0
479-
podArgs.PodCreds = PodCreds{
480-
InsightsAPIKey: "test-key",
481-
InsightsEnvironment: "test-env",
482-
}
483-
podArgs.TraceTags = tags.SingletonTags{"test": "value"}
484-
485-
assert.Equal(t, akid.ServiceID{}, podArgs.InsightsProjectID)
486-
assert.Equal(t, "test-container-uuid", podArgs.ContainerUUID)
487-
assert.True(t, podArgs.ReproMode)
488-
assert.True(t, podArgs.DropNginxTraffic)
489-
assert.Equal(t, 100.0, podArgs.AgentRateLimit)
490-
assert.Equal(t, "test-key", podArgs.PodCreds.InsightsAPIKey)
491-
assert.Equal(t, "test-env", podArgs.PodCreds.InsightsEnvironment)
492-
assert.Equal(t, tags.SingletonTags{"test": "value"}, podArgs.TraceTags)
493-
})
494-
495-
t.Run("isTrafficMonitoringInFinalState function", func(t *testing.T) {
496-
finalStates := []PodTrafficMonitorState{
497-
TrafficMonitoringEnded,
498-
TrafficMonitoringFailed,
499-
RemovePodFromMap,
500-
}
501-
502-
nonFinalStates := []PodTrafficMonitorState{
503-
PodPending,
504-
PodRunning,
505-
PodSucceeded,
506-
PodFailed,
507-
PodTerminated,
508-
TrafficMonitoringRunning,
509-
DaemonSetShutdown,
510-
}
511-
512-
for _, state := range finalStates {
513-
podArgs := NewPodArgs("test-pod")
514-
podArgs.PodTrafficMonitorState = state
515-
assert.True(t, isTrafficMonitoringInFinalState(podArgs), "State %s should be final", state)
516-
}
517-
518-
for _, state := range nonFinalStates {
519-
podArgs := NewPodArgs("test-pod")
520-
podArgs.PodTrafficMonitorState = state
521-
assert.False(t, isTrafficMonitoringInFinalState(podArgs), "State %s should not be final", state)
522-
}
523-
})
524-
}
525-
526-
// TestPodArgs_ConcurrencyStress tests performance under concurrent load
527-
func TestPodArgs_ConcurrencyStress(t *testing.T) {
528-
t.Run("High-frequency state transitions", func(t *testing.T) {
529-
podArgs := NewPodArgs("test-pod")
530-
podArgs.PodTrafficMonitorState = PodPending
531-
532-
var wg sync.WaitGroup
533-
successCount := 0
534-
var mu sync.Mutex
535-
536-
// Start 100 goroutines doing rapid state transitions
537-
for i := 0; i < 100; i++ {
538-
wg.Add(1)
539-
go func() {
540-
defer wg.Done()
541-
for j := 0; j < 10; j++ {
542-
err := podArgs.changePodTrafficMonitorState(PodRunning, PodPending)
543-
if err == nil {
544-
mu.Lock()
545-
successCount++
546-
mu.Unlock()
547-
// Change back to allow others to succeed
548-
podArgs.changePodTrafficMonitorState(PodPending, PodRunning)
549-
}
550-
}
551-
}()
552-
}
553-
554-
wg.Wait()
555-
556-
// Should have many successful transitions
557-
assert.True(t, successCount > 0, "Should have successful transitions")
558-
})
559-
560-
t.Run("Large number of concurrent PodArgs objects", func(t *testing.T) {
561-
const numPods = 100
562-
podArgsList := make([]*PodArgs, numPods)
563-
564-
// Create many PodArgs objects
565-
for i := 0; i < numPods; i++ {
566-
podArgsList[i] = NewPodArgs("test-pod-" + string(rune(i)))
567-
podArgsList[i].PodTrafficMonitorState = PodPending
568-
}
569-
570-
var wg sync.WaitGroup
571-
successCount := 0
572-
var mu sync.Mutex
573-
574-
// Start goroutines for each PodArgs
575-
for i := 0; i < numPods; i++ {
576-
wg.Add(1)
577-
go func(podArgs *PodArgs) {
578-
defer wg.Done()
579-
err := podArgs.changePodTrafficMonitorState(PodRunning, PodPending)
580-
if err == nil {
581-
mu.Lock()
582-
successCount++
583-
mu.Unlock()
584-
}
585-
}(podArgsList[i])
586-
}
587-
588-
wg.Wait()
589-
590-
// All should succeed since they're different objects
591-
assert.Equal(t, numPods, successCount, "All PodArgs should transition successfully")
592-
})
593-
594-
t.Run("Memory pressure scenarios", func(t *testing.T) {
595-
// Test that we can create many PodArgs without memory issues
596-
const numPods = 1000
597-
podArgsList := make([]*PodArgs, numPods)
598-
599-
for i := 0; i < numPods; i++ {
600-
podArgsList[i] = NewPodArgs("test-pod-" + string(rune(i)))
601-
require.NotNil(t, podArgsList[i])
602-
}
603-
604-
// Verify all are accessible
605-
for i := 0; i < numPods; i++ {
606-
assert.Equal(t, "test-pod-"+string(rune(i)), podArgsList[i].PodName)
607-
}
608-
})
609401
}
610402

611403
// TestPodArgs_StateTransitionSequence tests complete state transition sequences
@@ -663,3 +455,100 @@ func TestPodArgs_StateTransitionSequence(t *testing.T) {
663455
assert.Equal(t, RemovePodFromMap, podArgs.PodTrafficMonitorState)
664456
})
665457
}
458+
459+
// --- DaemonSet Shutdown and State Transition Tests ---
460+
461+
func TestPodArgs_DaemonShutdown(t *testing.T) {
462+
tests := []struct {
463+
name string
464+
initialState PodTrafficMonitorState
465+
expectedError bool
466+
expectedState PodTrafficMonitorState
467+
}{
468+
{"TrafficMonitoringRunning to DaemonSetShutdown", TrafficMonitoringRunning, false, DaemonSetShutdown},
469+
{"PodRunning to DaemonSetShutdown", PodRunning, false, DaemonSetShutdown},
470+
{"PodPending to DaemonSetShutdown", PodPending, false, DaemonSetShutdown},
471+
{"PodSucceeded to DaemonSetShutdown", PodSucceeded, false, DaemonSetShutdown},
472+
{"PodFailed to DaemonSetShutdown", PodFailed, false, DaemonSetShutdown},
473+
{"PodTerminated to DaemonSetShutdown", PodTerminated, false, DaemonSetShutdown},
474+
{"TrafficMonitoringEnded to DaemonSetShutdown", TrafficMonitoringEnded, true, TrafficMonitoringEnded},
475+
{"TrafficMonitoringFailed to DaemonSetShutdown", TrafficMonitoringFailed, true, TrafficMonitoringFailed},
476+
{"RemovePodFromMap to DaemonSetShutdown", RemovePodFromMap, true, RemovePodFromMap},
477+
}
478+
for _, tt := range tests {
479+
t.Run(tt.name, func(t *testing.T) {
480+
podArgs := NewPodArgs("test-pod")
481+
podArgs.PodTrafficMonitorState = tt.initialState
482+
err := podArgs.changePodTrafficMonitorState(DaemonSetShutdown)
483+
if tt.expectedError {
484+
assert.Error(t, err)
485+
assert.Contains(t, err.Error(), "already in final state")
486+
} else {
487+
assert.NoError(t, err)
488+
assert.Equal(t, tt.expectedState, podArgs.PodTrafficMonitorState)
489+
}
490+
})
491+
}
492+
}
493+
494+
func TestPodArgs_DaemonShutdownConcurrency(t *testing.T) {
495+
t.Run("Multiple goroutines trying to change state during shutdown", func(t *testing.T) {
496+
podArgs := NewPodArgs("test-pod")
497+
podArgs.PodTrafficMonitorState = TrafficMonitoringRunning
498+
var wg sync.WaitGroup
499+
errors := make(chan error, 10)
500+
successCount := 0
501+
var mu sync.Mutex
502+
for i := 0; i < 10; i++ {
503+
wg.Add(1)
504+
go func() {
505+
defer wg.Done()
506+
err := podArgs.changePodTrafficMonitorState(DaemonSetShutdown)
507+
if err == nil {
508+
mu.Lock()
509+
successCount++
510+
mu.Unlock()
511+
}
512+
errors <- err
513+
}()
514+
}
515+
wg.Wait()
516+
close(errors)
517+
errorCount := 0
518+
for err := range errors {
519+
if err != nil {
520+
errorCount++
521+
}
522+
}
523+
assert.Equal(t, 1, successCount)
524+
assert.Equal(t, 9, errorCount)
525+
assert.Equal(t, DaemonSetShutdown, podArgs.PodTrafficMonitorState)
526+
})
527+
528+
t.Run("Race condition between daemon shutdown and normal state transitions", func(t *testing.T) {
529+
podArgs := NewPodArgs("test-pod")
530+
podArgs.PodTrafficMonitorState = TrafficMonitoringRunning
531+
var wg sync.WaitGroup
532+
errors := make(chan error, 2)
533+
wg.Add(2)
534+
go func() {
535+
defer wg.Done()
536+
err := podArgs.changePodTrafficMonitorState(TrafficMonitoringEnded, TrafficMonitoringRunning)
537+
errors <- err
538+
}()
539+
go func() {
540+
defer wg.Done()
541+
err := podArgs.changePodTrafficMonitorState(DaemonSetShutdown)
542+
errors <- err
543+
}()
544+
wg.Wait()
545+
close(errors)
546+
errorCount := 0
547+
for err := range errors {
548+
if err != nil {
549+
errorCount++
550+
}
551+
}
552+
assert.Equal(t, 1, errorCount)
553+
})
554+
}

0 commit comments

Comments
 (0)