github.com/kubeshop/testkube@v1.17.23/pkg/event/emitter_integration_test.go (about)

     1  package event
     2  
     3  import (
     4  	"context"
     5  	"os"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/kubeshop/testkube/pkg/utils/test"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  
    13  	"github.com/kubeshop/testkube/pkg/api/v1/testkube"
    14  	"github.com/kubeshop/testkube/pkg/event/bus"
    15  	"github.com/kubeshop/testkube/pkg/event/kind/dummy"
    16  )
    17  
    18  // tests based on real NATS event bus
    19  
    20  func GetTestNATSEmitter() *Emitter {
    21  	os.Setenv("DEBUG", "true")
    22  	// configure NATS event bus
    23  	nc, err := bus.NewNATSEncodedConnection(bus.ConnectionConfig{
    24  		NatsURI: "http://localhost:4222",
    25  	})
    26  
    27  	if err != nil {
    28  		panic(err)
    29  	}
    30  	return NewEmitter(bus.NewNATSBus(nc), "", nil)
    31  }
    32  
    33  func TestEmitter_NATS_Register_Integration(t *testing.T) {
    34  	test.IntegrationTest(t)
    35  
    36  	t.Run("Register adds new listener", func(t *testing.T) {
    37  		// given
    38  		emitter := GetTestNATSEmitter()
    39  		// when
    40  		emitter.Register(&dummy.DummyListener{Id: "l1"})
    41  
    42  		// then
    43  		assert.Equal(t, 1, len(emitter.Listeners))
    44  
    45  		t.Log("T1 completed")
    46  	})
    47  }
    48  
    49  func TestEmitter_NATS_Listen_Integration(t *testing.T) {
    50  	test.IntegrationTest(t)
    51  
    52  	t.Run("listener handles only given events based on selectors", func(t *testing.T) {
    53  		// given
    54  		emitter := GetTestNATSEmitter()
    55  		// given listener with matching selector
    56  		listener1 := &dummy.DummyListener{Id: "l1", SelectorString: "type=OnlyMe"}
    57  		// and listener with non-matching selector
    58  		listener2 := &dummy.DummyListener{Id: "l2", SelectorString: "type=NotMe"}
    59  
    60  		// and emitter with registered listeners
    61  		emitter.Register(listener1)
    62  		emitter.Register(listener2)
    63  
    64  		// listening emitter
    65  		ctx, cancel := context.WithCancel(context.Background())
    66  		defer cancel()
    67  
    68  		emitter.Listen(ctx)
    69  		// wait for listeners to start
    70  		time.Sleep(time.Millisecond * 50)
    71  
    72  		// events
    73  		event1 := newExampleTestEvent3()
    74  		event1.TestExecution.Labels = map[string]string{"type": "OnlyMe"}
    75  		event2 := newExampleTestEvent4()
    76  
    77  		// when
    78  		emitter.Notify(event1)
    79  		emitter.Notify(event2)
    80  
    81  		// then
    82  		time.Sleep(time.Millisecond * 100)
    83  
    84  		assert.Equal(t, 1, listener1.GetNotificationCount())
    85  		assert.Equal(t, 0, listener2.GetNotificationCount())
    86  		t.Log("T3 completed")
    87  	})
    88  
    89  }
    90  
    91  func TestEmitter_NATS_Notify_Integration(t *testing.T) {
    92  	test.IntegrationTest(t)
    93  
    94  	t.Run("notifies listeners in queue groups", func(t *testing.T) {
    95  		// given
    96  		emitter := GetTestNATSEmitter()
    97  		// and 2 listeners subscribed to the same queue
    98  		// * first on pod1
    99  		listener1 := &dummy.DummyListener{Id: "l3", NotificationCount: 0}
   100  		// * second on pod2
   101  		listener2 := &dummy.DummyListener{Id: "l3", NotificationCount: 0}
   102  
   103  		emitter.Register(listener1)
   104  		emitter.Register(listener2)
   105  
   106  		// and listening emitter
   107  		ctx, cancel := context.WithCancel(context.Background())
   108  		defer cancel()
   109  
   110  		emitter.Listen(ctx)
   111  		// wait for listeners to start
   112  		time.Sleep(time.Millisecond * 50)
   113  
   114  		// when event sent to queue group
   115  		emitter.Notify(newExampleTestEvent3())
   116  
   117  		time.Sleep(time.Millisecond * 100)
   118  
   119  		// then listeners should be notified at least once
   120  		assert.LessOrEqual(t, 1, listener2.GetNotificationCount()+listener1.GetNotificationCount())
   121  	})
   122  }
   123  
   124  func TestEmitter_NATS_Reconcile_Integration(t *testing.T) {
   125  	test.IntegrationTest(t)
   126  
   127  	t.Run("emitter refersh listeners in reconcile loop", func(t *testing.T) {
   128  		// given
   129  		emitter := GetTestNATSEmitter()
   130  		// given listener with matching selector
   131  		listener1 := &dummy.DummyListener{Id: "l1", SelectorString: "type=listener1"}
   132  		// and listener with second matic selector
   133  		listener2 := &dummy.DummyListener{Id: "l2", SelectorString: "type=listener2"}
   134  
   135  		// and emitter with registered listeners
   136  		emitter.Register(listener1)
   137  		emitter.Register(listener2)
   138  
   139  		// listening emitter
   140  		ctx, cancel := context.WithCancel(context.Background())
   141  		defer cancel()
   142  
   143  		emitter.Listen(ctx)
   144  		// wait for listeners to start
   145  		time.Sleep(time.Millisecond * 50)
   146  
   147  		// events
   148  		event1 := newExampleTestEvent3()
   149  		event1.TestExecution.Labels = map[string]string{"type": "listener1"}
   150  		event2 := newExampleTestEvent4()
   151  		event2.TestExecution.Labels = map[string]string{"type": "listener2"}
   152  
   153  		// when
   154  		emitter.Notify(event1)
   155  		emitter.Notify(event2)
   156  
   157  		time.Sleep(time.Millisecond * 50)
   158  		// then
   159  
   160  		assert.Equal(t, 1, listener1.GetNotificationCount())
   161  		assert.Equal(t, 1, listener2.GetNotificationCount())
   162  	})
   163  
   164  }
   165  
   166  func newExampleTestEvent3() testkube.Event {
   167  	return testkube.Event{
   168  		Id:            "eventID3",
   169  		Type_:         testkube.EventStartTest,
   170  		TestExecution: testkube.NewExecutionWithID("executionID3", "test/test", "test"),
   171  	}
   172  }
   173  
   174  func newExampleTestEvent4() testkube.Event {
   175  	return testkube.Event{
   176  		Id:            "eventID4",
   177  		Type_:         testkube.EventStartTest,
   178  		TestExecution: testkube.NewExecutionWithID("executionID4", "test/test", "test"),
   179  	}
   180  }