github.com/castai/kvisor@v1.7.1-0.20240516114728-b3572a2607b5/pkg/ebpftracer/tracer_cleanup_test.go (about) 1 package ebpftracer 2 3 import ( 4 "context" 5 "testing" 6 "time" 7 8 "github.com/stretchr/testify/require" 9 "go.uber.org/goleak" 10 ) 11 12 func TestCgroupCleanupLoop(t *testing.T) { 13 defer goleak.VerifyNone(t) 14 r := require.New(t) 15 16 tracer := buildTestTracer(withCgroupCleanupConfigured(100*time.Millisecond, 100*time.Millisecond)) 17 18 ctx, cancel := context.WithCancel(context.TODO()) 19 doneChan := make(chan struct{}, 1) 20 21 go func() { 22 tracer.cgroupCleanupLoop(ctx) 23 doneChan <- struct{}{} 24 }() 25 26 tracer.queueCgroupForRemoval(10) 27 tracer.queueCgroupForRemoval(20) 28 tracer.queueCgroupForRemoval(30) 29 30 tracer.cgroupCleanupMu.Lock() 31 r.Len(tracer.requestedCgroupCleanups, 3) 32 tracer.cgroupCleanupMu.Unlock() 33 34 r.Eventually(func() bool { 35 tracer.cgroupCleanupMu.Lock() 36 defer tracer.cgroupCleanupMu.Unlock() 37 return len(tracer.requestedCgroupCleanups) == 0 38 }, 5*time.Second, 100*time.Millisecond) 39 40 cancel() 41 42 select { 43 case <-doneChan: 44 case <-time.After(2 * time.Second): 45 t.Fatal("timeout reached!") 46 } 47 } 48 49 func TestGetCgroupsToCleanup(t *testing.T) { 50 type testCase struct { 51 title string 52 now time.Time 53 cleanupRequests []cgroupCleanupRequest 54 } 55 56 now := time.Now() 57 58 testCases := []testCase{ 59 { 60 title: "requests before and after", 61 now: now, 62 cleanupRequests: []cgroupCleanupRequest{ 63 { 64 cgroupID: 10, 65 cleanupAfter: now.Add(-10 * time.Second), 66 }, 67 { 68 cgroupID: 20, 69 cleanupAfter: now.Add(10 * time.Second), 70 }, 71 { 72 cgroupID: 30, 73 cleanupAfter: now.Add(15 * time.Second), 74 }, 75 }, 76 }, 77 { 78 title: "empty requests", 79 now: now, 80 }, 81 { 82 title: "only after", 83 now: now, 84 cleanupRequests: []cgroupCleanupRequest{ 85 { 86 cgroupID: 20, 87 cleanupAfter: now.Add(10 * time.Second), 88 }, 89 { 90 cgroupID: 30, 91 cleanupAfter: now.Add(15 * time.Second), 92 }, 93 }, 94 }, 95 { 96 title: "only before", 97 now: now, 98 cleanupRequests: []cgroupCleanupRequest{ 99 { 100 cgroupID: 20, 101 cleanupAfter: now.Add(-10 * time.Second), 102 }, 103 { 104 cgroupID: 30, 105 cleanupAfter: now.Add(-5 * time.Second), 106 }, 107 }, 108 }, 109 } 110 111 for _, test := range testCases { 112 t.Run(test.title, func(t *testing.T) { 113 r := require.New(t) 114 115 toCleanup, future := splitCleanupRequests(test.now, test.cleanupRequests) 116 117 for _, req := range toCleanup { 118 r.True(req.cleanupAfter.Before(test.now)) 119 } 120 for _, req := range future { 121 r.False(req.cleanupAfter.Before(test.now)) 122 } 123 }) 124 } 125 126 } 127 128 func withCgroupCleanupConfigured(cleanupTickRate time.Duration, cleanupDelay time.Duration) tracerOption { 129 return func(t *Tracer) { 130 t.cleanupTimerTickRate = cleanupTickRate 131 t.cgroupCleanupDelay = cleanupDelay 132 } 133 }