github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/client/pluginmanager/group_test.go (about)

     1  package pluginmanager
     2  
     3  import (
     4  	"context"
     5  	"sync"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/hashicorp/nomad/ci"
    10  	"github.com/hashicorp/nomad/helper/testlog"
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  func TestPluginGroup_RegisterAndRun(t *testing.T) {
    15  	ci.Parallel(t)
    16  	require := require.New(t)
    17  
    18  	var hasRun bool
    19  	var wg sync.WaitGroup
    20  	wg.Add(1)
    21  	manager := &MockPluginManager{RunF: func() {
    22  		hasRun = true
    23  		wg.Done()
    24  	}}
    25  
    26  	group := New(testlog.HCLogger(t))
    27  	require.NoError(group.RegisterAndRun(manager))
    28  	wg.Wait()
    29  	require.True(hasRun)
    30  }
    31  
    32  func TestPluginGroup_Shutdown(t *testing.T) {
    33  	ci.Parallel(t)
    34  	require := require.New(t)
    35  
    36  	var stack []int
    37  	var stackMu sync.Mutex
    38  	var runWg sync.WaitGroup
    39  	var shutdownWg sync.WaitGroup
    40  	group := New(testlog.HCLogger(t))
    41  	for i := 1; i < 4; i++ {
    42  		i := i
    43  		runWg.Add(1)
    44  		shutdownWg.Add(1)
    45  		manager := &MockPluginManager{RunF: func() {
    46  			stackMu.Lock()
    47  			defer stackMu.Unlock()
    48  			defer runWg.Done()
    49  			stack = append(stack, i)
    50  		}, ShutdownF: func() {
    51  			stackMu.Lock()
    52  			defer stackMu.Unlock()
    53  			defer shutdownWg.Done()
    54  			idx := len(stack) - 1
    55  			val := stack[idx]
    56  			require.Equal(i, val)
    57  			stack = stack[:idx]
    58  		}}
    59  		require.NoError(group.RegisterAndRun(manager))
    60  		runWg.Wait()
    61  	}
    62  	group.Shutdown()
    63  	shutdownWg.Wait()
    64  	require.Empty(stack)
    65  
    66  	require.Error(group.RegisterAndRun(&MockPluginManager{}))
    67  }
    68  
    69  func TestPluginGroup_WaitForFirstFingerprint(t *testing.T) {
    70  	ci.Parallel(t)
    71  	require := require.New(t)
    72  
    73  	managerCh := make(chan struct{})
    74  	manager := &MockPluginManager{
    75  		RunF:                      func() {},
    76  		WaitForFirstFingerprintCh: managerCh,
    77  	}
    78  
    79  	// close immediately to beat the context timeout
    80  	close(managerCh)
    81  
    82  	group := New(testlog.HCLogger(t))
    83  	require.NoError(group.RegisterAndRun(manager))
    84  
    85  	ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
    86  	defer cancel()
    87  
    88  	groupCh, err := group.WaitForFirstFingerprint(ctx)
    89  	require.NoError(err)
    90  
    91  	select {
    92  	case <-groupCh:
    93  	case <-time.After(100 * time.Millisecond):
    94  		t.Fatal("expected groupCh to be closed")
    95  	}
    96  }
    97  
    98  func TestPluginGroup_WaitForFirstFingerprint_Timeout(t *testing.T) {
    99  	ci.Parallel(t)
   100  	require := require.New(t)
   101  
   102  	managerCh := make(chan struct{})
   103  	manager := &MockPluginManager{
   104  		RunF:                      func() {},
   105  		WaitForFirstFingerprintCh: managerCh,
   106  	}
   107  
   108  	group := New(testlog.HCLogger(t))
   109  	require.NoError(group.RegisterAndRun(manager))
   110  
   111  	ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond)
   112  	defer cancel()
   113  
   114  	groupCh, err := group.WaitForFirstFingerprint(ctx)
   115  
   116  	select {
   117  	case <-groupCh:
   118  	case <-time.After(100 * time.Millisecond):
   119  		t.Fatal("expected groupCh to be closed due to context timeout")
   120  	}
   121  	require.NoError(err)
   122  }