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  }