github.com/cilium/cilium@v1.16.2/pkg/kvstore/store/watchstoremgr_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package store
     5  
     6  import (
     7  	"context"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/stretchr/testify/require"
    12  
    13  	"github.com/cilium/cilium/pkg/kvstore"
    14  )
    15  
    16  func TestWatchStoreManager(t *testing.T) {
    17  	runnable := func(mgr func() WatchStoreManager) func(t *testing.T) {
    18  		return func(t *testing.T) {
    19  			ch := make(chan *KVPair, 3)
    20  			run := func(ctx context.Context, str string) {
    21  				ch <- NewKVPair(str, "")
    22  				<-ctx.Done()
    23  			}
    24  
    25  			mgr := mgr()
    26  			mgr.Register("bar", func(ctx context.Context) { run(ctx, "bar") })
    27  			mgr.Register("bax", func(ctx context.Context) { run(ctx, "baz") })
    28  			mgr.Register("qux", func(ctx context.Context) { run(ctx, "qux") })
    29  
    30  			ctx, cancel := context.WithCancel(context.Background())
    31  			completed := make(chan struct{})
    32  			go func() {
    33  				mgr.Run(ctx)
    34  				close(completed)
    35  			}()
    36  
    37  			defer func() {
    38  				cancel()
    39  
    40  				select {
    41  				case <-completed:
    42  				case <-time.After(100 * time.Millisecond):
    43  					require.Fail(t, "Manager didn't stop properly after closing the context")
    44  				}
    45  			}()
    46  
    47  			var started []string
    48  			started = append(started, eventually(ch).Key)
    49  			started = append(started, eventually(ch).Key)
    50  			started = append(started, eventually(ch).Key)
    51  
    52  			require.ElementsMatch(t, started, []string{"bar", "baz", "qux"})
    53  		}
    54  	}
    55  
    56  	f, _ := GetFactory(t)
    57  	t.Run("sync", runnable(func() WatchStoreManager {
    58  		backend := NewFakeLWBackend(t, kvstore.SyncedPrefix+"/foo/", []kvstore.KeyValueEvent{
    59  			{Typ: kvstore.EventTypeListDone},
    60  			{Typ: kvstore.EventTypeCreate, Key: "not-registered"},
    61  			{Typ: kvstore.EventTypeCreate, Key: "bar"},
    62  			{Typ: kvstore.EventTypeCreate, Key: "bax"},
    63  			{Typ: kvstore.EventTypeCreate, Key: "qux"},
    64  		})
    65  
    66  		return f.NewWatchStoreManager(backend, "foo")
    67  	}))
    68  
    69  	t.Run("immediate", runnable(func() WatchStoreManager {
    70  		return NewWatchStoreManagerImmediate("foo")
    71  	}))
    72  }
    73  
    74  func TestWatchStoreManagerPanic(t *testing.T) {
    75  	runnable := func(mgr func() WatchStoreManager) func(t *testing.T) {
    76  		return func(t *testing.T) {
    77  			mgr := mgr()
    78  
    79  			ctx, cancel := context.WithCancel(context.Background())
    80  			cancel()
    81  
    82  			mgr.Run(ctx)
    83  
    84  			require.Panics(t, func() { mgr.Register("foo", func(ctx context.Context) {}) },
    85  				"mgr.Register should panic after Run was called")
    86  			require.Panics(t, func() { mgr.Run(ctx) }, "mgr.Run should panic when already started")
    87  		}
    88  	}
    89  	f, _ := GetFactory(t)
    90  	t.Run("sync", runnable(func() WatchStoreManager {
    91  		backend := NewFakeLWBackend(t, kvstore.SyncedPrefix+"/foo/", nil)
    92  		return f.NewWatchStoreManager(backend, "foo")
    93  	}))
    94  
    95  	t.Run("immediate", runnable(func() WatchStoreManager {
    96  		return NewWatchStoreManagerImmediate("foo")
    97  	}))
    98  }