github.com/kubeshop/testkube@v1.17.23/pkg/triggers/lease_test.go (about)

     1  package triggers
     2  
     3  import (
     4  	"context"
     5  	"sync"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/golang/mock/gomock"
    10  	"github.com/stretchr/testify/assert"
    11  
    12  	"github.com/kubeshop/testkube/pkg/log"
    13  )
    14  
    15  func TestService_runLeaseChecker(t *testing.T) {
    16  	t.Parallel()
    17  
    18  	t.Run("should send true through leaseChan when lease identifier matches", func(t *testing.T) {
    19  		t.Parallel()
    20  
    21  		mockCtrl := gomock.NewController(t)
    22  		defer mockCtrl.Finish()
    23  
    24  		ctx, cancel := context.WithTimeout(context.Background(), 130*time.Millisecond)
    25  		defer cancel()
    26  
    27  		mockLeaseBackend := NewMockLeaseBackend(mockCtrl)
    28  		testClusterID := "testkube-api"
    29  		testIdentifier := "test-host-1"
    30  		mockLeaseBackend.EXPECT().TryAcquire(gomock.Any(), testIdentifier, testClusterID).Return(true, nil)
    31  
    32  		s := &Service{
    33  			identifier:         testIdentifier,
    34  			clusterID:          testClusterID,
    35  			leaseBackend:       mockLeaseBackend,
    36  			leaseCheckInterval: 100 * time.Millisecond,
    37  			logger:             log.DefaultLogger,
    38  		}
    39  
    40  		leaseChan := make(chan bool)
    41  		go s.runLeaseChecker(ctx, leaseChan)
    42  
    43  		select {
    44  		case <-ctx.Done():
    45  			t.Errorf("did not receive lease response in expected timeframe")
    46  		case lease := <-leaseChan:
    47  			assert.True(t, lease, "instance should acquire lease")
    48  		}
    49  	})
    50  
    51  	t.Run("should send false through leaseChan when lease identifier do not match", func(t *testing.T) {
    52  		t.Parallel()
    53  
    54  		mockCtrl := gomock.NewController(t)
    55  		defer mockCtrl.Finish()
    56  
    57  		ctx, cancel := context.WithTimeout(context.Background(), 130*time.Millisecond)
    58  		defer cancel()
    59  
    60  		mockLeaseBackend := NewMockLeaseBackend(mockCtrl)
    61  		mockLeaseBackend.EXPECT().TryAcquire(gomock.Any(), "test-host-1", "testkube-api").Return(false, nil)
    62  
    63  		s := &Service{
    64  			identifier:         "test-host-1",
    65  			clusterID:          "testkube-api",
    66  			leaseBackend:       mockLeaseBackend,
    67  			leaseCheckInterval: 100 * time.Millisecond,
    68  			logger:             log.DefaultLogger,
    69  		}
    70  
    71  		leaseChan := make(chan bool)
    72  		go s.runLeaseChecker(ctx, leaseChan)
    73  
    74  		select {
    75  		case <-ctx.Done():
    76  			t.Errorf("did not receive lease response in expected timeframe")
    77  		case lease := <-leaseChan:
    78  			assert.False(t, lease, "instance should not acquire lease")
    79  		}
    80  	})
    81  }
    82  
    83  func TestService_runLeaseChecker_multipleInstances(t *testing.T) {
    84  	t.Parallel()
    85  
    86  	t.Run("only one instance should acquire lease successfully", func(t *testing.T) {
    87  		t.Parallel()
    88  
    89  		mockCtrl := gomock.NewController(t)
    90  		defer mockCtrl.Finish()
    91  
    92  		ctx, cancel := context.WithTimeout(context.Background(), 130*time.Millisecond)
    93  		defer cancel()
    94  
    95  		mockLeaseBackend1 := NewMockLeaseBackend(mockCtrl)
    96  		mockLeaseBackend1.EXPECT().TryAcquire(gomock.Any(), "test-host-1", "testkube-api").Return(true, nil)
    97  		mockLeaseBackend2 := NewMockLeaseBackend(mockCtrl)
    98  		mockLeaseBackend2.EXPECT().TryAcquire(gomock.Any(), "test-host-2", "testkube-api").Return(false, nil)
    99  
   100  		s1 := &Service{
   101  			identifier:         "test-host-1",
   102  			clusterID:          "testkube-api",
   103  			leaseBackend:       mockLeaseBackend1,
   104  			leaseCheckInterval: 100 * time.Millisecond,
   105  			logger:             log.DefaultLogger,
   106  		}
   107  
   108  		leaseChan1 := make(chan bool)
   109  		go s1.runLeaseChecker(ctx, leaseChan1)
   110  
   111  		s2 := &Service{
   112  			identifier:         "test-host-2",
   113  			clusterID:          "testkube-api",
   114  			leaseBackend:       mockLeaseBackend2,
   115  			leaseCheckInterval: 100 * time.Millisecond,
   116  			logger:             log.DefaultLogger,
   117  		}
   118  
   119  		leaseChan2 := make(chan bool)
   120  		go s2.runLeaseChecker(ctx, leaseChan2)
   121  
   122  		wg := sync.WaitGroup{}
   123  		wg.Add(2)
   124  		go func() {
   125  			defer wg.Done()
   126  			select {
   127  			case <-ctx.Done():
   128  				t.Errorf("did not receive lease from test-host-1")
   129  			case lease := <-leaseChan1:
   130  				assert.True(t, lease, "first instance should acquire lease")
   131  			}
   132  		}()
   133  
   134  		go func() {
   135  			defer wg.Done()
   136  			select {
   137  			case <-ctx.Done():
   138  				t.Errorf("did not receive lease from test-host-1")
   139  			case lease := <-leaseChan2:
   140  				assert.False(t, lease, "second instance should not acquire lease")
   141  			}
   142  		}()
   143  
   144  		wg.Wait()
   145  	})
   146  }