github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/monitor/internal/k8s/event_retry_handler_test.go (about)

     1  package k8smonitor
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/golang/mock/gomock"
    10  	"go.aporeto.io/enforcerd/internal/extractors/containermetadata"
    11  	"go.aporeto.io/enforcerd/internal/extractors/containermetadata/mockcontainermetadata"
    12  )
    13  
    14  func Test_calculateWaitTime(t *testing.T) {
    15  	tests := []struct {
    16  		name  string
    17  		retry uint
    18  		want  time.Duration
    19  	}{
    20  		{
    21  			retry: 0,
    22  			want:  0,
    23  		},
    24  		{
    25  			retry: 1,
    26  			want:  retryWaittimeUnit * time.Duration(1),
    27  		},
    28  		{
    29  			retry: 2,
    30  			want:  retryWaittimeUnit * time.Duration(1),
    31  		},
    32  		{
    33  			retry: 3,
    34  			want:  retryWaittimeUnit * time.Duration(2),
    35  		},
    36  		{
    37  			retry: 4,
    38  			want:  retryWaittimeUnit * time.Duration(3),
    39  		},
    40  		{
    41  			retry: 5,
    42  			want:  retryWaittimeUnit * time.Duration(5),
    43  		},
    44  		{
    45  			retry: 6,
    46  			want:  retryWaittimeUnit * time.Duration(8),
    47  		},
    48  		{
    49  			retry: 7,
    50  			want:  retryWaittimeUnit * time.Duration(13),
    51  		},
    52  		{
    53  			retry: 8,
    54  			want:  retryWaittimeUnit * time.Duration(21),
    55  		},
    56  		{
    57  			retry: 9,
    58  			want:  retryWaittimeUnit * time.Duration(34),
    59  		},
    60  		{
    61  			retry: 10,
    62  			want:  retryWaittimeUnit * time.Duration(55),
    63  		},
    64  		{
    65  			retry: 1000000,
    66  			want:  retryWaittimeUnit * time.Duration(55),
    67  		},
    68  	}
    69  	for _, tt := range tests {
    70  		t.Run(tt.name, func(t *testing.T) {
    71  			if got := calculateWaitTime(tt.retry); got != tt.want {
    72  				t.Errorf("calculateWaitTime() = %v, want %v", got, tt.want)
    73  			}
    74  		})
    75  	}
    76  }
    77  
    78  func Test_newStartEventRetryFunc(t *testing.T) {
    79  	oldRetryWaittimeUnit := retryWaittimeUnit
    80  	defer func() {
    81  		retryWaittimeUnit = oldRetryWaittimeUnit
    82  	}()
    83  	retryWaittimeUnit = 0
    84  
    85  	// used by the test which needs a cancelled context
    86  	cancelledCtx, cancel := context.WithCancel(context.Background())
    87  	cancel()
    88  
    89  	tests := []struct {
    90  		name               string
    91  		mainCtx            context.Context
    92  		startEventHandler  unitTestStartEvent
    93  		retry              uint
    94  		prepare            func(t *testing.T, extractor *mockcontainermetadata.MockCommonContainerMetadataExtractor, kmd *mockcontainermetadata.MockCommonKubernetesContainerMetadata)
    95  		expectedStartEvent bool
    96  	}{
    97  		{
    98  			name:              "not a pod sandbox",
    99  			mainCtx:           context.Background(),
   100  			startEventHandler: newUnitTestStartEventHandler(0, nil),
   101  			prepare: func(t *testing.T, extractor *mockcontainermetadata.MockCommonContainerMetadataExtractor, kmd *mockcontainermetadata.MockCommonKubernetesContainerMetadata) {
   102  				kmd.EXPECT().Kind().Return(containermetadata.PodContainer).Times(2)
   103  				kmd.EXPECT().ID().Return("containerID").Times(1)
   104  			},
   105  		},
   106  		{
   107  			name:              "main context is already cancelled",
   108  			mainCtx:           cancelledCtx,
   109  			startEventHandler: newUnitTestStartEventHandler(0, nil),
   110  			prepare: func(t *testing.T, extractor *mockcontainermetadata.MockCommonContainerMetadataExtractor, kmd *mockcontainermetadata.MockCommonKubernetesContainerMetadata) {
   111  				kmd.EXPECT().Kind().Return(containermetadata.PodSandbox).Times(1)
   112  				kmd.EXPECT().ID().Return("containerID").Times(1)
   113  			},
   114  		},
   115  		{
   116  			name:              "sandbox does not exist any longer",
   117  			mainCtx:           context.Background(),
   118  			startEventHandler: newUnitTestStartEventHandler(0, nil),
   119  			prepare: func(t *testing.T, extractor *mockcontainermetadata.MockCommonContainerMetadataExtractor, kmd *mockcontainermetadata.MockCommonKubernetesContainerMetadata) {
   120  				kmd.EXPECT().Kind().Return(containermetadata.PodSandbox).Times(1)
   121  				kmd.EXPECT().ID().Return("containerID").Times(3)
   122  				extractor.EXPECT().Has(gomock.Eq(containermetadata.NewRuncArguments(containermetadata.StartAction, "containerID"))).Return(false).Times(1)
   123  			},
   124  		},
   125  		{
   126  			name:              "retrying with success",
   127  			mainCtx:           context.Background(),
   128  			startEventHandler: newUnitTestStartEventHandler(1, nil),
   129  			prepare: func(t *testing.T, extractor *mockcontainermetadata.MockCommonContainerMetadataExtractor, kmd *mockcontainermetadata.MockCommonKubernetesContainerMetadata) {
   130  				kmd.EXPECT().Kind().Return(containermetadata.PodSandbox).Times(1)
   131  				kmd.EXPECT().ID().Return("containerID").Times(2)
   132  				extractor.EXPECT().Has(gomock.Eq(containermetadata.NewRuncArguments(containermetadata.StartAction, "containerID"))).Return(true).Times(1)
   133  			},
   134  			expectedStartEvent: true,
   135  		},
   136  		{
   137  			name:              "retrying with error",
   138  			mainCtx:           context.Background(),
   139  			startEventHandler: newUnitTestStartEventHandler(1, fmt.Errorf("start event failed")),
   140  			prepare: func(t *testing.T, extractor *mockcontainermetadata.MockCommonContainerMetadataExtractor, kmd *mockcontainermetadata.MockCommonKubernetesContainerMetadata) {
   141  				kmd.EXPECT().Kind().Return(containermetadata.PodSandbox).Times(1)
   142  				kmd.EXPECT().ID().Return("containerID").Times(3)
   143  				kmd.EXPECT().PodName().Return("podName").Times(1)
   144  				kmd.EXPECT().PodNamespace().Return("podNamespace").Times(1)
   145  				kmd.EXPECT().PodUID().Return("podUID").Times(1)
   146  				extractor.EXPECT().Has(gomock.Eq(containermetadata.NewRuncArguments(containermetadata.StartAction, "containerID"))).Return(true).Times(1)
   147  			},
   148  			expectedStartEvent: true,
   149  		},
   150  	}
   151  	for _, tt := range tests {
   152  		t.Run(tt.name, func(t *testing.T) {
   153  			ctrl := gomock.NewController(t)
   154  			extractor := mockcontainermetadata.NewMockCommonContainerMetadataExtractor(ctrl)
   155  			kmd := mockcontainermetadata.NewMockCommonKubernetesContainerMetadata(ctrl)
   156  			ctx, cancel := context.WithCancel(tt.mainCtx)
   157  			startEventRetry := newStartEventRetryFunc(ctx, extractor, tt.startEventHandler.f())
   158  			tt.prepare(t, extractor, kmd)
   159  			startEventRetry(kmd, tt.retry)
   160  			tt.startEventHandler.wait()
   161  			if tt.expectedStartEvent != tt.startEventHandler.called() {
   162  				t.Errorf("startEventHandler.called() = %v, want %v", tt.startEventHandler.called(), tt.expectedStartEvent)
   163  			}
   164  			cancel()
   165  			ctrl.Finish()
   166  		})
   167  	}
   168  }