Best K6 code snippet using js.Require
jetstream_test.go
Source:jetstream_test.go
1package handlers2import (3 "errors"4 "fmt"5 "testing"6 "time"7 kymalogger "github.com/kyma-project/kyma/common/logging/logger"8 eventingv1alpha1 "github.com/kyma-project/kyma/components/eventing-controller/api/v1alpha1"9 "github.com/kyma-project/kyma/components/eventing-controller/logger"10 "github.com/kyma-project/kyma/components/eventing-controller/pkg/env"11 "github.com/kyma-project/kyma/components/eventing-controller/pkg/handlers/eventtype"12 evtesting "github.com/kyma-project/kyma/components/eventing-controller/testing"13 "github.com/nats-io/nats-server/v2/server"14 "github.com/nats-io/nats.go"15 "github.com/stretchr/testify/require"16)17const (18 defaultStreamName = "kyma"19)20type jetStreamClient struct {21 nats.JetStreamContext22 natsConn *nats.Conn23}24// TestJetStreamInitialize_NoStreamExists tests if a stream is25// created when no stream exists in JetStream.26func TestJetStreamInitialize_NoStreamExists(t *testing.T) {27 // given28 testEnvironment := setupTestEnvironment(t)29 natsConfig, jsClient := testEnvironment.natsConfig, testEnvironment.jsClient30 defer testEnvironment.natsServer.Shutdown()31 defer jsClient.natsConn.Close()32 // No stream exists33 _, err := jsClient.StreamInfo(natsConfig.JSStreamName)34 require.True(t, errors.Is(err, nats.ErrStreamNotFound))35 // when36 initErr := testEnvironment.jsBackend.Initialize(nil)37 // then38 // A stream is created39 require.NoError(t, initErr)40 streamInfo, err := jsClient.StreamInfo(natsConfig.JSStreamName)41 require.NoError(t, err)42 require.NotNil(t, streamInfo)43}44// TestJetStreamInitialize_StreamExists tests if a stream is45// reused and not created when a stream exists in JetStream.46func TestJetStreamInitialize_StreamExists(t *testing.T) {47 // given48 testEnvironment := setupTestEnvironment(t)49 natsConfig, jsClient := testEnvironment.natsConfig, testEnvironment.jsClient50 defer testEnvironment.natsServer.Shutdown()51 defer jsClient.natsConn.Close()52 // A stream already exists53 createdStreamInfo, err := jsClient.AddStream(&nats.StreamConfig{54 Name: natsConfig.JSStreamName,55 Storage: nats.MemoryStorage,56 })57 require.NotNil(t, createdStreamInfo)58 require.NoError(t, err)59 // when60 initErr := testEnvironment.jsBackend.Initialize(nil)61 // then62 // No new stream should be created63 require.NoError(t, initErr)64 reusedStreamInfo, err := jsClient.StreamInfo(natsConfig.JSStreamName)65 require.NoError(t, err)66 require.Equal(t, reusedStreamInfo.Created, createdStreamInfo.Created)67}68// TestJetStream_SubscriptionDeletion tests the creation and deletion69// of a JetStream subscription on the NATS server.70func TestJetStream_SubscriptionDeletion(t *testing.T) {71 // given72 testEnvironment := setupTestEnvironment(t)73 jsBackend := testEnvironment.jsBackend74 defer testEnvironment.natsServer.Shutdown()75 defer testEnvironment.jsClient.natsConn.Close()76 initErr := jsBackend.Initialize(nil)77 require.NoError(t, initErr)78 // create New Subscriber79 subscriber := evtesting.NewSubscriber()80 defer subscriber.Shutdown()81 require.True(t, subscriber.IsRunning())82 defaultMaxInflight := 983 defaultSubsConfig := env.DefaultSubscriptionConfig{MaxInFlightMessages: defaultMaxInflight}84 // create a new Subscription85 sub := evtesting.NewSubscription("sub", "foo",86 evtesting.WithNotCleanFilter(),87 evtesting.WithSinkURL(subscriber.SinkURL),88 evtesting.WithStatusConfig(defaultSubsConfig),89 )90 addJSCleanEventTypesToStatus(sub, testEnvironment.cleaner, jsBackend)91 // when92 err := jsBackend.SyncSubscription(sub)93 // then94 require.NoError(t, err)95 data := "sampledata"96 require.NoError(t, SendEventToJetStream(jsBackend, data))97 expectedDataInStore := fmt.Sprintf("\"%s\"", data)98 require.NoError(t, subscriber.CheckEvent(expectedDataInStore))99 // when100 require.NoError(t, jsBackend.DeleteSubscription(sub))101 // then102 newData := "test-data"103 require.NoError(t, SendEventToJetStream(jsBackend, newData))104 // Check for the event that it did not reach subscriber105 notExpectedNewDataInStore := fmt.Sprintf("\"%s\"", newData)106 require.Error(t, subscriber.CheckEvent(notExpectedNewDataInStore))107}108// TestJetStreamSubAfterSync_NoChange tests the SyncSubscription method109// when there is no change in the subscription then the method should110// not re-create NATS subjects on nats-server.111func TestJetStreamSubAfterSync_NoChange(t *testing.T) {112 // given113 testEnvironment := setupTestEnvironment(t)114 jsBackend := testEnvironment.jsBackend115 defer testEnvironment.natsServer.Shutdown()116 defer testEnvironment.jsClient.natsConn.Close()117 initErr := jsBackend.Initialize(nil)118 require.NoError(t, initErr)119 // create New Subscribers120 subscriber1 := evtesting.NewSubscriber()121 defer subscriber1.Shutdown()122 require.True(t, subscriber1.IsRunning())123 defaultMaxInflight := 9124 defaultSubsConfig := env.DefaultSubscriptionConfig{MaxInFlightMessages: defaultMaxInflight}125 // create a new Subscription126 sub := evtesting.NewSubscription("sub", "foo",127 evtesting.WithNotCleanFilter(),128 evtesting.WithSinkURL(subscriber1.SinkURL),129 evtesting.WithStatusConfig(defaultSubsConfig),130 )131 addJSCleanEventTypesToStatus(sub, testEnvironment.cleaner, jsBackend)132 // when133 err := jsBackend.SyncSubscription(sub)134 // then135 require.NoError(t, err)136 // get cleaned subject137 subject, err := getCleanSubject(sub.Spec.Filter.Filters[0], testEnvironment.cleaner)138 require.NoError(t, err)139 require.NotEmpty(t, subject)140 // test if subscription is working properly by sending an event141 // and checking if it is received by the subscriber142 data := fmt.Sprintf("data-%s", time.Now().Format(time.RFC850))143 expectedDataInStore := fmt.Sprintf("\"%s\"", data)144 require.NoError(t, SendEventToJetStream(jsBackend, data))145 require.NoError(t, subscriber1.CheckEvent(expectedDataInStore))146 // set metadata on NATS subscriptions147 msgLimit, bytesLimit := 2048, 2048148 require.Len(t, jsBackend.subscriptions, 1)149 for _, jsSub := range jsBackend.subscriptions {150 require.True(t, jsSub.IsValid())151 require.NoError(t, jsSub.SetPendingLimits(msgLimit, bytesLimit))152 }153 // given154 // no change in subscription155 // when156 err = jsBackend.SyncSubscription(sub)157 // then158 require.NoError(t, err)159 // check if the NATS subscription are the same (have same metadata)160 // by comparing the metadata of nats subscription161 require.Len(t, jsBackend.subscriptions, 1)162 jsSubject := jsBackend.GetJsSubjectToSubscribe(subject)163 jsSubKey := jsBackend.GenerateJsSubKey(jsSubject, sub)164 jsSub := jsBackend.subscriptions[jsSubKey]165 require.NotNil(t, jsSub)166 require.True(t, jsSub.IsValid())167 // check the metadata, if they are now same then it means that NATS subscription168 // were not re-created by SyncSubscription method169 subMsgLimit, subBytesLimit, err := jsSub.PendingLimits()170 require.NoError(t, err)171 require.Equal(t, subMsgLimit, msgLimit)172 require.Equal(t, subBytesLimit, bytesLimit)173 // test if subscription is working properly by sending an event174 // and checking if it is received by the subscriber175 data = fmt.Sprintf("data-%s", time.Now().Format(time.RFC850))176 expectedDataInStore = fmt.Sprintf("\"%s\"", data)177 require.NoError(t, SendEventToJetStream(jsBackend, data))178 require.NoError(t, subscriber1.CheckEvent(expectedDataInStore))179}180// TestJetStreamSubAfterSync_SinkChange tests the SyncSubscription method181// when only the sink is changed in subscription, then it should not re-create182// NATS subjects on nats-server.183func TestJetStreamSubAfterSync_SinkChange(t *testing.T) {184 // given185 testEnvironment := setupTestEnvironment(t)186 jsBackend := testEnvironment.jsBackend187 defer testEnvironment.natsServer.Shutdown()188 defer testEnvironment.jsClient.natsConn.Close()189 initErr := jsBackend.Initialize(nil)190 require.NoError(t, initErr)191 // create New Subscribers192 subscriber1 := evtesting.NewSubscriber()193 defer subscriber1.Shutdown()194 require.True(t, subscriber1.IsRunning())195 subscriber2 := evtesting.NewSubscriber()196 defer subscriber2.Shutdown()197 require.True(t, subscriber2.IsRunning())198 defaultMaxInflight := 9199 defaultSubsConfig := env.DefaultSubscriptionConfig{MaxInFlightMessages: defaultMaxInflight}200 // create a new Subscription201 sub := evtesting.NewSubscription("sub", "foo",202 evtesting.WithNotCleanFilter(),203 evtesting.WithSinkURL(subscriber1.SinkURL),204 evtesting.WithStatusConfig(defaultSubsConfig),205 )206 addJSCleanEventTypesToStatus(sub, testEnvironment.cleaner, jsBackend)207 // when208 err := jsBackend.SyncSubscription(sub)209 // then210 require.NoError(t, err)211 // get cleaned subject212 subject, err := getCleanSubject(sub.Spec.Filter.Filters[0], testEnvironment.cleaner)213 require.NoError(t, err)214 require.NotEmpty(t, subject)215 // test if subscription is working properly by sending an event216 // and checking if it is received by the subscriber217 data := fmt.Sprintf("data-%s", time.Now().Format(time.RFC850))218 expectedDataInStore := fmt.Sprintf("\"%s\"", data)219 require.NoError(t, SendEventToJetStream(jsBackend, data))220 require.NoError(t, subscriber1.CheckEvent(expectedDataInStore))221 // set metadata on NATS subscriptions222 msgLimit, bytesLimit := 2048, 2048223 require.Len(t, jsBackend.subscriptions, 1)224 for _, jsSub := range jsBackend.subscriptions {225 require.True(t, jsSub.IsValid())226 require.NoError(t, jsSub.SetPendingLimits(msgLimit, bytesLimit))227 }228 // given229 // NATS subscription should not be re-created in sync when sink is changed.230 // change the sink231 sub.Spec.Sink = subscriber2.SinkURL232 // when233 err = jsBackend.SyncSubscription(sub)234 // then235 require.NoError(t, err)236 // check if the NATS subscription are the same (have same metadata)237 // by comparing the metadata of nats subscription238 require.Len(t, jsBackend.subscriptions, 1)239 jsSubject := jsBackend.GetJsSubjectToSubscribe(subject)240 jsSubKey := jsBackend.GenerateJsSubKey(jsSubject, sub)241 jsSub := jsBackend.subscriptions[jsSubKey]242 require.NotNil(t, jsSub)243 require.True(t, jsSub.IsValid())244 // check the metadata, if they are now same then it means that NATS subscription245 // were not re-created by SyncSubscription method246 subMsgLimit, subBytesLimit, err := jsSub.PendingLimits()247 require.NoError(t, err)248 require.Equal(t, subMsgLimit, msgLimit)249 require.Equal(t, subBytesLimit, bytesLimit)250 // Test if the subscription is working for new sink only251 data = fmt.Sprintf("data-%s", time.Now().Format(time.RFC850))252 expectedDataInStore = fmt.Sprintf("\"%s\"", data)253 require.NoError(t, SendEventToJetStream(jsBackend, data))254 // Old sink should not have received the event, the new sink should have255 require.Error(t, subscriber1.CheckEvent(expectedDataInStore))256 require.NoError(t, subscriber2.CheckEvent(expectedDataInStore))257}258// TestJetStreamSubAfterSync_FiltersChange tests the SyncSubscription method259// when the filters are changed in subscription.260func TestJetStreamSubAfterSync_FiltersChange(t *testing.T) {261 // given262 testEnvironment := setupTestEnvironment(t)263 jsBackend := testEnvironment.jsBackend264 defer testEnvironment.natsServer.Shutdown()265 defer testEnvironment.jsClient.natsConn.Close()266 initErr := jsBackend.Initialize(nil)267 require.NoError(t, initErr)268 subscriber := evtesting.NewSubscriber()269 defer subscriber.Shutdown()270 require.True(t, subscriber.IsRunning())271 defaultMaxInflight := 9272 defaultSubsConfig := env.DefaultSubscriptionConfig{MaxInFlightMessages: defaultMaxInflight}273 sub := evtesting.NewSubscription("sub", "foo",274 evtesting.WithNotCleanFilter(),275 evtesting.WithSinkURL(subscriber.SinkURL),276 evtesting.WithStatusConfig(defaultSubsConfig),277 )278 addJSCleanEventTypesToStatus(sub, testEnvironment.cleaner, jsBackend)279 // when280 err := jsBackend.SyncSubscription(sub)281 // then282 require.NoError(t, err)283 // get cleaned subject284 subject, err := getCleanSubject(sub.Spec.Filter.Filters[0], testEnvironment.cleaner)285 require.NoError(t, err)286 require.NotEmpty(t, subject)287 // test if subscription is working properly by sending an event288 // and checking if it is received by the subscriber289 data := fmt.Sprintf("data-%s", time.Now().Format(time.RFC850))290 expectedDataInStore := fmt.Sprintf("\"%s\"", data)291 require.NoError(t, SendEventToJetStream(jsBackend, data))292 require.NoError(t, subscriber.CheckEvent(expectedDataInStore))293 // set metadata on NATS subscriptions294 // so that we can later verify if the nats subscriptions are the same (not re-created by Sync)295 msgLimit, bytesLimit := 2048, 2048296 require.Len(t, jsBackend.subscriptions, 1)297 for _, jsSub := range jsBackend.subscriptions {298 require.True(t, jsSub.IsValid())299 require.NoError(t, jsSub.SetPendingLimits(msgLimit, bytesLimit))300 }301 // given302 // Now, change the filter in subscription303 sub.Spec.Filter.Filters[0].EventType.Value = fmt.Sprintf("%schanged", evtesting.OrderCreatedEventTypeNotClean)304 // Sync the subscription status305 addJSCleanEventTypesToStatus(sub, testEnvironment.cleaner, jsBackend)306 // when307 err = jsBackend.SyncSubscription(sub)308 // then309 require.NoError(t, err)310 // get new cleaned subject311 newSubject, err := getCleanSubject(sub.Spec.Filter.Filters[0], testEnvironment.cleaner)312 require.NoError(t, err)313 require.NotEmpty(t, newSubject)314 // check if the NATS subscription are NOT the same after sync315 // because the subscriptions should have being re-created for new subject316 require.Len(t, jsBackend.subscriptions, 1)317 jsSubject := jsBackend.GetJsSubjectToSubscribe(newSubject)318 jsSubKey := jsBackend.GenerateJsSubKey(jsSubject, sub)319 jsSub := jsBackend.subscriptions[jsSubKey]320 require.NotNil(t, jsSub)321 require.True(t, jsSub.IsValid())322 // check the metadata, if they are NOT same then it means that NATS subscription323 // were re-created by SyncSubscription method324 subMsgLimit, subBytesLimit, err := jsSub.PendingLimits()325 require.NoError(t, err)326 require.NotEqual(t, subMsgLimit, msgLimit)327 require.NotEqual(t, subBytesLimit, bytesLimit)328 // Test if subscription is working for new subject only329 data = fmt.Sprintf("data-%s", time.Now().Format(time.RFC850))330 expectedDataInStore = fmt.Sprintf("\"%s\"", data)331 // Send an event on old subject332 require.NoError(t, SendEventToJetStream(jsBackend, data))333 // The sink should not receive any event for old subject334 require.Error(t, subscriber.CheckEvent(expectedDataInStore))335 // Now, send an event on new subject336 require.NoError(t, SendEventToJetStreamOnEventType(jsBackend, newSubject, data))337 // The sink should receive the event for new subject338 require.NoError(t, subscriber.CheckEvent(expectedDataInStore))339}340// TestJetStreamSubAfterSync_FilterAdded tests the SyncSubscription method341// when a new filter is added in subscription.342func TestJetStreamSubAfterSync_FilterAdded(t *testing.T) {343 // given344 testEnvironment := setupTestEnvironment(t)345 jsBackend := testEnvironment.jsBackend346 defer testEnvironment.natsServer.Shutdown()347 defer testEnvironment.jsClient.natsConn.Close()348 initErr := jsBackend.Initialize(nil)349 require.NoError(t, initErr)350 // Create a new subscriber351 subscriber := evtesting.NewSubscriber()352 defer subscriber.Shutdown()353 require.True(t, subscriber.IsRunning())354 defaultMaxInflight := 9355 defaultSubsConfig := env.DefaultSubscriptionConfig{MaxInFlightMessages: defaultMaxInflight}356 // Create a subscription with single filter357 sub := evtesting.NewSubscription("sub", "foo",358 evtesting.WithNotCleanFilter(),359 evtesting.WithSinkURL(subscriber.SinkURL),360 evtesting.WithStatusConfig(defaultSubsConfig),361 )362 addJSCleanEventTypesToStatus(sub, testEnvironment.cleaner, jsBackend)363 // when364 err := jsBackend.SyncSubscription(sub)365 // then366 require.NoError(t, err)367 // get cleaned subject368 firstSubject, err := getCleanSubject(sub.Spec.Filter.Filters[0], testEnvironment.cleaner)369 require.NoError(t, err)370 require.NotEmpty(t, firstSubject)371 // set metadata on NATS subscriptions372 // so that we can later verify if the nats subscriptions are the same (not re-created by Sync)373 msgLimit, bytesLimit := 2048, 2048374 require.Len(t, jsBackend.subscriptions, 1)375 for _, jsSub := range jsBackend.subscriptions {376 require.True(t, jsSub.IsValid())377 require.NoError(t, jsSub.SetPendingLimits(msgLimit, bytesLimit))378 }379 // Now, add a new filter to subscription380 newFilter := sub.Spec.Filter.Filters[0].DeepCopy()381 newFilter.EventType.Value = fmt.Sprintf("%snew1", evtesting.OrderCreatedEventTypeNotClean)382 sub.Spec.Filter.Filters = append(sub.Spec.Filter.Filters, newFilter)383 // get new cleaned subject384 secondSubject, err := getCleanSubject(newFilter, testEnvironment.cleaner)385 require.NoError(t, err)386 require.NotEmpty(t, secondSubject)387 addJSCleanEventTypesToStatus(sub, testEnvironment.cleaner, jsBackend)388 // when389 err = jsBackend.SyncSubscription(sub)390 // then391 require.NoError(t, err)392 // Check if total existing NATS subscriptions are correct393 // Because we have two filters (i.e. two subjects)394 require.Len(t, jsBackend.subscriptions, 2)395 // Verify that the nats subscriptions for first subject was not re-created396 jsSubject := jsBackend.GetJsSubjectToSubscribe(firstSubject)397 jsSubKey := jsBackend.GenerateJsSubKey(jsSubject, sub)398 jsSub := jsBackend.subscriptions[jsSubKey]399 require.NotNil(t, jsSub)400 require.True(t, jsSub.IsValid())401 // check the metadata, if they are now same then it means that NATS subscription402 // were not re-created by SyncSubscription method403 subMsgLimit, subBytesLimit, err := jsSub.PendingLimits()404 require.NoError(t, err)405 require.Equal(t, subMsgLimit, msgLimit)406 require.Equal(t, subBytesLimit, bytesLimit)407 // Test if subscription is working for both subjects408 // Send an event on first subject409 data := fmt.Sprintf("data-%s", time.Now().Format(time.RFC850))410 expectedDataInStore := fmt.Sprintf("\"%s\"", data)411 require.NoError(t, SendEventToJetStream(jsBackend, data))412 // The sink should receive event for first subject413 require.NoError(t, subscriber.CheckEvent(expectedDataInStore))414 // Now, send an event on second subject415 data = fmt.Sprintf("data-%s", time.Now().Format(time.RFC850))416 expectedDataInStore = fmt.Sprintf("\"%s\"", data)417 require.NoError(t, SendEventToJetStreamOnEventType(jsBackend, secondSubject, data))418 // The sink should receive the event for second subject419 require.NoError(t, subscriber.CheckEvent(expectedDataInStore))420}421// TestJetStreamSubAfterSync_FilterRemoved tests the SyncSubscription method422// when a filter is removed from subscription.423func TestJetStreamSubAfterSync_FilterRemoved(t *testing.T) {424 // given425 testEnvironment := setupTestEnvironment(t)426 jsBackend := testEnvironment.jsBackend427 defer testEnvironment.natsServer.Shutdown()428 defer testEnvironment.jsClient.natsConn.Close()429 initErr := jsBackend.Initialize(nil)430 require.NoError(t, initErr)431 // Create a new subscriber432 subscriber := evtesting.NewSubscriber()433 defer subscriber.Shutdown()434 require.True(t, subscriber.IsRunning())435 defaultMaxInflight := 9436 defaultSubsConfig := env.DefaultSubscriptionConfig{MaxInFlightMessages: defaultMaxInflight}437 // Create a subscription with two filters438 sub := evtesting.NewSubscription("sub", "foo",439 evtesting.WithNotCleanFilter(),440 evtesting.WithSinkURL(subscriber.SinkURL),441 evtesting.WithStatusConfig(defaultSubsConfig),442 )443 // add a second filter444 newFilter := sub.Spec.Filter.Filters[0].DeepCopy()445 newFilter.EventType.Value = fmt.Sprintf("%snew1", evtesting.OrderCreatedEventTypeNotClean)446 sub.Spec.Filter.Filters = append(sub.Spec.Filter.Filters, newFilter)447 addJSCleanEventTypesToStatus(sub, testEnvironment.cleaner, jsBackend)448 // when449 err := jsBackend.SyncSubscription(sub)450 // then451 require.NoError(t, err)452 // get cleaned subjects453 firstSubject, err := getCleanSubject(sub.Spec.Filter.Filters[0], testEnvironment.cleaner)454 require.NoError(t, err)455 require.NotEmpty(t, firstSubject)456 secondSubject, err := getCleanSubject(sub.Spec.Filter.Filters[1], testEnvironment.cleaner)457 require.NoError(t, err)458 require.NotEmpty(t, secondSubject)459 // Check if total existing NATS subscriptions are correct460 // Because we have two filters (i.e. two subjects)461 require.Len(t, jsBackend.subscriptions, 2)462 // set metadata on NATS subscriptions463 // so that we can later verify if the nats subscriptions are the same (not re-created by Sync)464 msgLimit, bytesLimit := 2048, 2048465 for _, jsSub := range jsBackend.subscriptions {466 require.True(t, jsSub.IsValid())467 require.NoError(t, jsSub.SetPendingLimits(msgLimit, bytesLimit))468 }469 // given470 // Now, remove the second filter from subscription471 sub.Spec.Filter.Filters = sub.Spec.Filter.Filters[:1]472 addJSCleanEventTypesToStatus(sub, testEnvironment.cleaner, jsBackend)473 // when474 err = jsBackend.SyncSubscription(sub)475 // then476 require.NoError(t, err)477 // Check if total existing NATS subscriptions are correct478 require.Len(t, jsBackend.subscriptions, 1)479 // Verify that the nats subscriptions for first subject was not re-created480 jsSubject := jsBackend.GetJsSubjectToSubscribe(firstSubject)481 jsSubKey := jsBackend.GenerateJsSubKey(jsSubject, sub)482 jsSub := jsBackend.subscriptions[jsSubKey]483 require.NotNil(t, jsSub)484 require.True(t, jsSub.IsValid())485 // check the metadata, if they are now same then it means that NATS subscription486 // were not re-created by SyncSubscription method487 subMsgLimit, subBytesLimit, err := jsSub.PendingLimits()488 require.NoError(t, err)489 require.Equal(t, subMsgLimit, msgLimit)490 require.Equal(t, subBytesLimit, bytesLimit)491 // Test if subscription is working for first subject only492 // Send an event on first subject493 data := fmt.Sprintf("data-%s", time.Now().Format(time.RFC850))494 expectedDataInStore := fmt.Sprintf("\"%s\"", data)495 require.NoError(t, SendEventToJetStream(jsBackend, data))496 // The sink should receive event for first subject497 require.NoError(t, subscriber.CheckEvent(expectedDataInStore))498 // Now, send an event on second subject499 data = fmt.Sprintf("data-%s", time.Now().Format(time.RFC850))500 expectedDataInStore = fmt.Sprintf("\"%s\"", data)501 require.NoError(t, SendEventToJetStreamOnEventType(jsBackend, secondSubject, data))502 // The sink should NOT receive the event for second subject503 require.Error(t, subscriber.CheckEvent(expectedDataInStore))504}505// TestJetStreamSubAfterSync_MultipleSubs tests the SyncSubscription method506// when there are two subscriptions and the filter is changed in one subscription507// it should not affect the NATS subscriptions of other Kyma subscriptions.508func TestJetStreamSubAfterSync_MultipleSubs(t *testing.T) {509 // given510 testEnvironment := setupTestEnvironment(t)511 jsBackend := testEnvironment.jsBackend512 defer testEnvironment.natsServer.Shutdown()513 defer testEnvironment.jsClient.natsConn.Close()514 initErr := jsBackend.Initialize(nil)515 require.NoError(t, initErr)516 // Create a new subscriber517 subscriber := evtesting.NewSubscriber()518 defer subscriber.Shutdown()519 require.True(t, subscriber.IsRunning())520 defaultMaxInflight := 9521 defaultSubsConfig := env.DefaultSubscriptionConfig{MaxInFlightMessages: defaultMaxInflight}522 // Create two subscriptions with single filter523 sub := evtesting.NewSubscription("sub", "foo",524 evtesting.WithNotCleanFilter(),525 evtesting.WithSinkURL(subscriber.SinkURL),526 evtesting.WithStatusConfig(defaultSubsConfig),527 )528 addJSCleanEventTypesToStatus(sub, testEnvironment.cleaner, jsBackend)529 // when530 err := jsBackend.SyncSubscription(sub)531 // then532 require.NoError(t, err)533 // given534 sub2 := evtesting.NewSubscription("sub2", "foo",535 evtesting.WithNotCleanFilter(),536 evtesting.WithSinkURL(subscriber.SinkURL),537 evtesting.WithStatusConfig(defaultSubsConfig),538 )539 addJSCleanEventTypesToStatus(sub2, testEnvironment.cleaner, jsBackend)540 // when541 err = jsBackend.SyncSubscription(sub2)542 // then543 require.NoError(t, err)544 // Check if total existing NATS subscriptions are correct545 // Because we have two subscriptions546 require.Len(t, jsBackend.subscriptions, 2)547 // set metadata on NATS subscriptions548 // so that we can later verify if the nats subscriptions are the same (not re-created by Sync)549 msgLimit, bytesLimit := 2048, 2048550 for _, jsSub := range jsBackend.subscriptions {551 require.True(t, jsSub.IsValid())552 require.NoError(t, jsSub.SetPendingLimits(msgLimit, bytesLimit))553 }554 // Now, change the filter in subscription 1555 sub.Spec.Filter.Filters[0].EventType.Value = fmt.Sprintf("%schanged", evtesting.OrderCreatedEventTypeNotClean)556 addJSCleanEventTypesToStatus(sub, testEnvironment.cleaner, jsBackend)557 // when558 err = jsBackend.SyncSubscription(sub)559 // then560 require.NoError(t, err)561 // get new cleaned subject from subscription 1562 newSubject, err := getCleanSubject(sub.Spec.Filter.Filters[0], testEnvironment.cleaner)563 require.NoError(t, err)564 require.NotEmpty(t, newSubject)565 // Check if total existing NATS subscriptions are correct566 // Because we have two subscriptions567 require.Len(t, jsBackend.subscriptions, 2)568 // check if the NATS subscription are NOT the same after sync for subscription 1569 // because the subscriptions should have being re-created for new subject570 jsSubject := jsBackend.GetJsSubjectToSubscribe(newSubject)571 jsSubKey := jsBackend.GenerateJsSubKey(jsSubject, sub)572 jsSub := jsBackend.subscriptions[jsSubKey]573 require.NotNil(t, jsSub)574 require.True(t, jsSub.IsValid())575 // check the metadata, if they are now same then it means that NATS subscription576 // were not re-created by SyncSubscription method577 subMsgLimit, subBytesLimit, err := jsSub.PendingLimits()578 require.NoError(t, err)579 require.NotEqual(t, subMsgLimit, msgLimit)580 require.NotEqual(t, subBytesLimit, bytesLimit)581 // get cleaned subject for subscription 2582 cleanSubjectSub2, err := getCleanSubject(sub2.Spec.Filter.Filters[0], testEnvironment.cleaner)583 require.NoError(t, err)584 require.NotEmpty(t, cleanSubjectSub2)585 // check if the NATS subscription are same after sync for subscription 2586 // because the subscriptions should NOT have being re-created as587 // subscription 2 was not modified588 jsSubject = jsBackend.GetJsSubjectToSubscribe(cleanSubjectSub2)589 jsSubKey = jsBackend.GenerateJsSubKey(jsSubject, sub2)590 jsSub = jsBackend.subscriptions[jsSubKey]591 require.NotNil(t, jsSub)592 require.True(t, jsSub.IsValid())593 // check the metadata, if they are now same then it means that NATS subscription594 // were not re-created by SyncSubscription method595 subMsgLimit, subBytesLimit, err = jsSub.PendingLimits()596 require.NoError(t, err)597 require.Equal(t, subMsgLimit, msgLimit)598 require.Equal(t, subBytesLimit, bytesLimit)599}600// TestJetStream_isJsSubAssociatedWithKymaSub tests the isJsSubAssociatedWithKymaSub method.601func TestJetStream_isJsSubAssociatedWithKymaSub(t *testing.T) {602 // given603 testEnvironment := setupTestEnvironment(t)604 jsBackend := testEnvironment.jsBackend605 defer testEnvironment.natsServer.Shutdown()606 defer testEnvironment.jsClient.natsConn.Close()607 initErr := jsBackend.Initialize(nil)608 require.NoError(t, initErr)609 // create subscription 1 and its JetStream subscription610 cleanSubject1 := "subOne"611 sub1 := evtesting.NewSubscription(cleanSubject1, "foo", evtesting.WithNotCleanFilter())612 jsSub1Key := jsBackend.GenerateJsSubKey(613 jsBackend.GetJsSubjectToSubscribe(cleanSubject1),614 sub1)615 // create subscription 2 and its JetStream subscription616 cleanSubject2 := "subOneTwo"617 sub2 := evtesting.NewSubscription(cleanSubject2, "foo", evtesting.WithNotCleanFilter())618 jsSub2Key := jsBackend.GenerateJsSubKey(619 jsBackend.GetJsSubjectToSubscribe(cleanSubject2),620 sub2)621 testCases := []struct {622 name string623 givenJSSubKey string624 givenKymaSubKey *eventingv1alpha1.Subscription625 wantResult bool626 }{627 {628 name: "",629 givenJSSubKey: jsSub1Key,630 givenKymaSubKey: sub1,631 wantResult: true,632 },633 {634 name: "",635 givenJSSubKey: jsSub2Key,636 givenKymaSubKey: sub2,637 wantResult: true,638 },639 {640 name: "",641 givenJSSubKey: jsSub1Key,642 givenKymaSubKey: sub2,643 wantResult: false,644 },645 {646 name: "",647 givenJSSubKey: jsSub2Key,648 givenKymaSubKey: sub1,649 wantResult: false,650 },651 }652 for _, tC := range testCases {653 testCase := tC654 t.Run(testCase.name, func(t *testing.T) {655 gotResult, err := jsBackend.isJsSubAssociatedWithKymaSub(656 tC.givenJSSubKey,657 tC.givenKymaSubKey)658 require.Equal(t, gotResult, tC.wantResult)659 require.NoError(t, err)660 })661 }662}663// TestMultipleJSSubscriptionsToSameEvent tests the behaviour of JS664// when multiple subscriptions need to receive the same event.665func TestMultipleJSSubscriptionsToSameEvent(t *testing.T) {666 // given667 testEnvironment := setupTestEnvironment(t)668 jsBackend := testEnvironment.jsBackend669 defer testEnvironment.natsServer.Shutdown()670 defer testEnvironment.jsClient.natsConn.Close()671 initErr := jsBackend.Initialize(nil)672 require.NoError(t, initErr)673 defaultMaxInflight := 1674 defaultSubsConfig := env.DefaultSubscriptionConfig{MaxInFlightMessages: defaultMaxInflight}675 subscriber := evtesting.NewSubscriber()676 defer subscriber.Shutdown()677 require.True(t, subscriber.IsRunning())678 // Create 3 subscriptions having the same sink and the same event type679 var subs [3]*eventingv1alpha1.Subscription680 for i := 0; i < len(subs); i++ {681 subs[i] = evtesting.NewSubscription(fmt.Sprintf("sub-%d", i), "foo",682 evtesting.WithNotCleanFilter(),683 evtesting.WithSinkURL(subscriber.SinkURL),684 evtesting.WithStatusConfig(defaultSubsConfig),685 )686 addJSCleanEventTypesToStatus(subs[i], testEnvironment.cleaner, jsBackend)687 // when688 err := jsBackend.SyncSubscription(subs[i])689 // then690 require.NoError(t, err)691 }692 // Send only one event. It should be multiplexed to 3 by NATS, cause 3 subscriptions exist693 data := "sampledata"694 require.NoError(t, SendEventToJetStream(jsBackend, data))695 // Check for the 3 events that should be received by the subscriber696 expectedDataInStore := fmt.Sprintf("\"%s\"", data)697 for i := 0; i < len(subs); i++ {698 require.NoError(t, subscriber.CheckEvent(expectedDataInStore))699 }700 // Delete all 3 subscription701 for i := 0; i < len(subs); i++ {702 require.NoError(t, jsBackend.DeleteSubscription(subs[i]))703 }704 // Check if all subscriptions are deleted in NATS705 // Send an event again which should not be delivered to subscriber706 newData := "test-data"707 require.NoError(t, SendEventToJetStream(jsBackend, newData))708 // Check for the event that did not reach the subscriber709 // Store should never return newdata hence CheckEvent should fail to match newdata710 notExpectedNewDataInStore := fmt.Sprintf("\"%s\"", newData)711 require.Error(t, subscriber.CheckEvent(notExpectedNewDataInStore))712}713// TestJSSubscriptionWithDuplicateFilters tests the subscription behaviour714// when duplicate filters are added.715func TestJSSubscriptionWithDuplicateFilters(t *testing.T) {716 // given717 testEnvironment := setupTestEnvironment(t)718 jsBackend := testEnvironment.jsBackend719 defer testEnvironment.natsServer.Shutdown()720 defer testEnvironment.jsClient.natsConn.Close()721 initErr := jsBackend.Initialize(nil)722 require.NoError(t, initErr)723 defaultSubsConfig := env.DefaultSubscriptionConfig{MaxInFlightMessages: 9}724 subscriber := evtesting.NewSubscriber()725 defer subscriber.Shutdown()726 require.True(t, subscriber.IsRunning())727 sub := evtesting.NewSubscription("sub", "foo",728 evtesting.WithFilter("", evtesting.OrderCreatedEventType),729 evtesting.WithFilter("", evtesting.OrderCreatedEventType),730 evtesting.WithSinkURL(subscriber.SinkURL),731 evtesting.WithStatusConfig(defaultSubsConfig),732 )733 addJSCleanEventTypesToStatus(sub, testEnvironment.cleaner, jsBackend)734 // when735 err := jsBackend.SyncSubscription(sub)736 // then737 require.NoError(t, err)738 data := "sampledata"739 require.NoError(t, SendEventToJetStream(jsBackend, data))740 expectedDataInStore := fmt.Sprintf("\"%s\"", data)741 require.NoError(t, subscriber.CheckEvent(expectedDataInStore))742 // There should be no more!743 require.Error(t, subscriber.CheckEvent(expectedDataInStore))744}745// TestJSSubscriptionWithMaxInFlightChange tests the maxAckPending746// to be equal to the MaxInFlightMessages when the server is not running.747func TestJSSubscriptionWithMaxInFlightChange(t *testing.T) {748 // given749 testEnvironment := setupTestEnvironment(t)750 jsBackend := testEnvironment.jsBackend751 defer testEnvironment.natsServer.Shutdown()752 defer testEnvironment.jsClient.natsConn.Close()753 initErr := jsBackend.Initialize(nil)754 require.NoError(t, initErr)755 // create New Subscriber756 subscriber := evtesting.NewSubscriber()757 subscriber.Shutdown() // shutdown the subscriber intentionally here758 require.False(t, subscriber.IsRunning())759 defaultMaxInflight := 16760 defaultSubsConfig := env.DefaultSubscriptionConfig{MaxInFlightMessages: defaultMaxInflight}761 // create a new Subscription762 sub := evtesting.NewSubscription("sub", "foo",763 evtesting.WithNotCleanFilter(),764 evtesting.WithSinkURL(subscriber.SinkURL),765 evtesting.WithStatusConfig(defaultSubsConfig),766 )767 addJSCleanEventTypesToStatus(sub, testEnvironment.cleaner, jsBackend)768 // when769 err := jsBackend.SyncSubscription(sub)770 // then771 require.NoError(t, err)772 // when773 // send 2 * defaultMaxInflight number of events774 for i := 0; i < 2*defaultMaxInflight; i++ {775 data := fmt.Sprintf("sampledata%d", i)776 require.NoError(t, SendEventToJetStream(jsBackend, data))777 }778 // then779 require.Eventually(t, func() bool {780 consumerName := jsBackend.GenerateJsSubKey(sub.Status.CleanEventTypes[0], sub)781 // fetch consumer info from JetStream782 consumerInfo, err := jsBackend.jsCtx.ConsumerInfo(jsBackend.config.JSStreamName, consumerName)783 require.NoError(t, err)784 // since our subscriber is not in running state,785 // so these events will be pending for receiving an ACK from dispatchers786 // check consumer current maxAckPending787 return consumerInfo.NumAckPending == defaultMaxInflight788 }, 10*time.Second, 200*time.Millisecond)789}790// TestJSSubscriptionUsingCESDK tests that eventing works with Cloud events.791func TestJSSubscriptionUsingCESDK(t *testing.T) {792 // given793 testEnvironment := setupTestEnvironment(t)794 jsBackend := testEnvironment.jsBackend795 defer testEnvironment.natsServer.Shutdown()796 defer testEnvironment.jsClient.natsConn.Close()797 initErr := jsBackend.Initialize(nil)798 require.NoError(t, initErr)799 defaultSubsConfig := env.DefaultSubscriptionConfig{MaxInFlightMessages: 1}800 subscriber := evtesting.NewSubscriber()801 defer subscriber.Shutdown()802 require.True(t, subscriber.IsRunning())803 sub := evtesting.NewSubscription("sub", "foo",804 evtesting.WithOrderCreatedFilter(),805 evtesting.WithSinkURL(subscriber.SinkURL),806 evtesting.WithStatusConfig(defaultSubsConfig),807 )808 addJSCleanEventTypesToStatus(sub, testEnvironment.cleaner, jsBackend)809 // when810 err := jsBackend.SyncSubscription(sub)811 // then812 require.NoError(t, err)813 subject := evtesting.CloudEventType814 require.NoError(t, SendBinaryCloudEventToJetStream(jsBackend, jsBackend.GetJsSubjectToSubscribe(subject), evtesting.CloudEventData))815 require.NoError(t, subscriber.CheckEvent(evtesting.CloudEventData))816 require.NoError(t, SendStructuredCloudEventToJetStream(jsBackend, jsBackend.GetJsSubjectToSubscribe(subject), evtesting.StructuredCloudEvent))817 require.NoError(t, subscriber.CheckEvent("\""+evtesting.EventData+"\""))818 require.NoError(t, jsBackend.DeleteSubscription(sub))819}820func TestJetStreamServerRestart_WithReconnectDisabled(t *testing.T) {821 // given822 testEnvironment := setupTestEnvironment(t)823 jsBackend := testEnvironment.jsBackend824 defer testEnvironment.natsServer.Shutdown()825 defer testEnvironment.jsClient.natsConn.Close()826 // Do not reconnect once server is shutdown827 jsBackend.config.MaxReconnects = 0828 initErr := jsBackend.Initialize(nil)829 require.NoError(t, initErr)830 defaultSubsConfig := env.DefaultSubscriptionConfig{MaxInFlightMessages: 10}831 subscriber := evtesting.NewSubscriber()832 defer subscriber.Shutdown()833 require.True(t, subscriber.IsRunning())834 // Create a subscription835 sub := evtesting.NewSubscription("sub", "foo",836 evtesting.WithNotCleanFilter(),837 evtesting.WithSinkURL(subscriber.SinkURL),838 evtesting.WithStatusConfig(defaultSubsConfig),839 )840 addJSCleanEventTypesToStatus(sub, testEnvironment.cleaner, jsBackend)841 // when842 err := jsBackend.SyncSubscription(sub)843 // then844 require.NoError(t, err)845 ev1data := "sampledata"846 require.NoError(t, SendEventToJetStream(jsBackend, ev1data))847 expectedEv1Data := fmt.Sprintf("\"%s\"", ev1data)848 require.NoError(t, subscriber.CheckEvent(expectedEv1Data))849 testEnvironment.natsServer.Shutdown()850 require.Eventually(t, func() bool {851 return !jsBackend.conn.IsConnected()852 }, 30*time.Second, 2*time.Second)853 _ = evtesting.RunNatsServerOnPort(854 evtesting.WithPort(testEnvironment.natsPort),855 evtesting.WithJetStreamEnabled())856 _, err = testEnvironment.jsClient.StreamInfo(defaultStreamName)857 require.True(t, errors.Is(err, nats.ErrStreamNotFound))858 // sync the subscription again to reconnect and859 // recreate the stream and consumer860 err = jsBackend.SyncSubscription(sub)861 require.NoError(t, err)862 _, err = testEnvironment.jsClient.StreamInfo(defaultStreamName)863 require.NoError(t, err)864 ev2data := "newsampledata"865 require.NoError(t, SendEventToJetStream(jsBackend, ev2data))866 expectedEv2Data := fmt.Sprintf("\"%s\"", ev2data)867 require.NoError(t, subscriber.CheckEvent(expectedEv2Data))868}869func TestJetStreamServerRestart_WithReconnectEnabled(t *testing.T) {870 // given871 testEnvironment := setupTestEnvironment(t)872 jsBackend := testEnvironment.jsBackend873 defer testEnvironment.natsServer.Shutdown()874 defer testEnvironment.jsClient.natsConn.Close()875 initErr := jsBackend.Initialize(nil)876 require.NoError(t, initErr)877 defaultSubsConfig := env.DefaultSubscriptionConfig{MaxInFlightMessages: 10}878 subscriber := evtesting.NewSubscriber()879 defer subscriber.Shutdown()880 require.True(t, subscriber.IsRunning())881 // Create a subscription882 sub := evtesting.NewSubscription("sub", "foo",883 evtesting.WithNotCleanFilter(),884 evtesting.WithSinkURL(subscriber.SinkURL),885 evtesting.WithStatusConfig(defaultSubsConfig),886 )887 addJSCleanEventTypesToStatus(sub, testEnvironment.cleaner, jsBackend)888 // when889 err := jsBackend.SyncSubscription(sub)890 // then891 require.NoError(t, err)892 ev1data := "sampledata"893 require.NoError(t, SendEventToJetStream(jsBackend, ev1data))894 expectedEv1Data := fmt.Sprintf("\"%s\"", ev1data)895 require.NoError(t, subscriber.CheckEvent(expectedEv1Data))896 testEnvironment.natsServer.Shutdown()897 require.Eventually(t, func() bool {898 return !jsBackend.conn.IsConnected()899 }, 30*time.Second, 2*time.Second)900 _ = evtesting.RunNatsServerOnPort(901 evtesting.WithPort(testEnvironment.natsPort),902 evtesting.WithJetStreamEnabled())903 testEnvironment.natsServer.Shutdown()904 require.Eventually(t, func() bool {905 return jsBackend.conn.IsConnected()906 }, 30*time.Second, 2*time.Second)907 _, err = testEnvironment.jsClient.StreamInfo(defaultStreamName)908 require.NoError(t, err)909 // sync the subscription again to reconnect and sync consumers910 err = jsBackend.SyncSubscription(sub)911 require.NoError(t, err)912 ev2data := "newsampledata"913 require.NoError(t, SendEventToJetStream(jsBackend, ev2data))914 expectedEv2Data := fmt.Sprintf("\"%s\"", ev2data)915 require.NoError(t, subscriber.CheckEvent(expectedEv2Data))916}917func TestJetStreamServerRestart_WithFileStorage(t *testing.T) {918 // given919 testEnvironment := setupTestEnvironment(t)920 jsBackend := testEnvironment.jsBackend921 defer testEnvironment.natsServer.Shutdown()922 defer testEnvironment.jsClient.natsConn.Close()923 // use File storage to restore streams924 jsBackend.config.JSStreamStorageType = JetStreamStorageTypeFile925 initErr := jsBackend.Initialize(nil)926 require.NoError(t, initErr)927 defaultSubsConfig := env.DefaultSubscriptionConfig{MaxInFlightMessages: 10}928 subscriber := evtesting.NewSubscriber()929 defer subscriber.Shutdown()930 require.True(t, subscriber.IsRunning())931 // Create a subscription932 sub := evtesting.NewSubscription("sub", "foo",933 evtesting.WithNotCleanFilter(),934 evtesting.WithSinkURL(subscriber.SinkURL),935 evtesting.WithStatusConfig(defaultSubsConfig),936 )937 addJSCleanEventTypesToStatus(sub, testEnvironment.cleaner, jsBackend)938 // when939 err := jsBackend.SyncSubscription(sub)940 // then941 require.NoError(t, err)942 ev1data := "sampledata"943 require.NoError(t, SendEventToJetStream(jsBackend, ev1data))944 expectedEv1Data := fmt.Sprintf("\"%s\"", ev1data)945 require.NoError(t, subscriber.CheckEvent(expectedEv1Data))946 testEnvironment.natsServer.Shutdown()947 require.Eventually(t, func() bool {948 return !jsBackend.conn.IsConnected()949 }, 30*time.Second, 2*time.Second)950 _ = evtesting.RunNatsServerOnPort(951 evtesting.WithPort(testEnvironment.natsPort),952 evtesting.WithJetStreamEnabled())953 require.Eventually(t, func() bool {954 return jsBackend.conn.IsConnected()955 }, 60*time.Second, 2*time.Second)956 // check that the stream is still present957 _, err = testEnvironment.jsClient.StreamInfo(defaultStreamName)958 require.NoError(t, err)959 ev2data := "newsampledata"960 require.NoError(t, SendEventToJetStream(jsBackend, ev2data))961 expectedEv2Data := fmt.Sprintf("\"%s\"", ev2data)962 require.NoError(t, subscriber.CheckEvent(expectedEv2Data))963 // cleanup the stream from file storage964 err = testEnvironment.jsClient.DeleteStream(defaultStreamName)965 require.NoError(t, err)966}967func defaultNatsConfig(url string) env.NatsConfig {968 return env.NatsConfig{969 URL: url,970 MaxReconnects: 10,971 ReconnectWait: 3 * time.Second,972 JSStreamName: defaultStreamName,973 JSStreamStorageType: JetStreamStorageTypeMemory,974 JSStreamRetentionPolicy: JetStreamRetentionPolicyInterest,975 }976}977// getJetStreamClient creates a client with JetStream context, or fails the caller test.978func getJetStreamClient(t *testing.T, serverURL string) *jetStreamClient {979 conn, err := nats.Connect(serverURL)980 if err != nil {981 t.Error(err.Error())982 }983 jsCtx, err := conn.JetStream()984 if err != nil {985 conn.Close()986 t.Error(err.Error())987 }988 return &jetStreamClient{989 JetStreamContext: jsCtx,990 natsConn: conn,991 }992}993func addJSCleanEventTypesToStatus(sub *eventingv1alpha1.Subscription, cleaner eventtype.Cleaner, jsBackend *JetStream) {994 cleanedSubjects, _ := GetCleanSubjects(sub, cleaner)995 sub.Status.CleanEventTypes = jsBackend.GetJetStreamSubjects(cleanedSubjects)996}997// TestEnvironment provides mocked resources for tests.998type TestEnvironment struct {999 jsBackend *JetStream1000 logger *logger.Logger1001 natsServer *server.Server1002 jsClient *jetStreamClient1003 natsConfig env.NatsConfig1004 cleaner eventtype.Cleaner1005 natsPort int1006}1007// setupTestEnvironment is a TestEnvironment constructor1008func setupTestEnvironment(t *testing.T) *TestEnvironment {1009 natsServer, natsPort := startNATSServer(evtesting.WithJetStreamEnabled())1010 natsConfig := defaultNatsConfig(natsServer.ClientURL())1011 defaultLogger, err := logger.New(string(kymalogger.JSON), string(kymalogger.INFO))1012 require.NoError(t, err)1013 jsClient := getJetStreamClient(t, natsConfig.URL)1014 jsBackend := NewJetStream(natsConfig, defaultLogger)1015 cleaner := createEventTypeCleaner(evtesting.EventTypePrefix, evtesting.ApplicationNameNotClean, defaultLogger)1016 return &TestEnvironment{1017 jsBackend: jsBackend,1018 logger: defaultLogger,1019 natsServer: natsServer,1020 jsClient: jsClient,1021 natsConfig: natsConfig,1022 cleaner: cleaner,1023 natsPort: natsPort,1024 }1025}...
asset_test.go
Source:asset_test.go
...47 panic(err)48 }49 assert.Contain("square", content)50}51func TestRequireDirective(t *testing.T) {52 assert.Test = t53 Config.BundleAssets = true54 defer func() {55 Config.BundleAssets = false56 }()57 content, err := ReadAsset("/assets/javascripts/require2.js")58 if err != nil {59 panic(err)60 }61 assert.Equal(`@normal.js62@sub/normal.js63`, content)64 content, err = ReadAsset("/assets/stylesheets/require2.css")65 if err != nil {66 panic(err)67 }68 assert.Equal(`normal.css69sub/normal.css70`, content)71}72func TestReadingAssetsWithRequire(t *testing.T) {73 assert.Test = t74 Config.BundleAssets = true75 var content string76 var err error77 content, _ = ReadAsset("/assets/javascripts/require.js")78 assert.Contain("@sub/normal.js", content)79 assert.Contain("@sub/normal1.coffee", content)80 assert.Contain("@sub/require.js", content)81 assert.Contain("@normal.js", content)82 assert.Contain("@normal1.coffee", content)83 assert.Contain("@require.js", content)84 content, _ = ReadAsset("/assets/javascripts/require.coffee")85 assert.Contain("@normal.js", content)86 assert.Contain("@require.coffee", content)...
bundle_test.go
Source:bundle_test.go
1package trainCommand2import (3 "github.com/shaoshing/train"4 "github.com/shaoshing/gotest"5 "io/ioutil"6 "testing"7)8func init() {9 train.Config.Verbose = true10}11func assertEqual(path, content string) {12 c, err := ioutil.ReadFile(path)13 if err != nil {14 panic(err)15 }16 assert.Equal(content, string(c))17}18func TestCommand(t *testing.T) {19 assert.Test = t20 assert.TrueM(prepareEnv(), "Unable to prepare env for cmd tests")21 removeAssets()22 copyAssets()23 assertEqual("public/assets/javascripts/normal.js", "normal.js\n")24 assertEqual("public/assets/javascripts/require.js", `//= require javascripts/normal25//= require javascripts/sub/require26require.js27`)28 assertEqual("public/assets/stylesheets/require.css", `/*29 *= require stylesheets/normal30 *= require stylesheets/sub/require31 */32require.css33`)34 bundleAssets()35 assertEqual("public/assets/javascripts/normal.js", "normal.js\n")36 assertEqual("public/assets/javascripts/require.js", `normal.js37sub/normal.js38sub/require.js39require.js40`)41 assertEqual("public/assets/stylesheets/require.css", `normal.css42sub/normal.css43sub/require.css44require.css45`)46 assertEqual("public/assets/stylesheets/font.css", `h1 {47 color: green; }`)48 assertEqual("public/assets/stylesheets/app.css", `h1 {49 color: green; }50h2 {51 color: green; }`)52 assertEqual("public/assets/stylesheets/scss.css", `h2 {53 color: green; }`)54 assertEqual("public/assets/javascripts/app.js", `(function() {55 var a;56 a = 12;57}).call(this);58`)59 compressAssets()60 assertEqual("public/assets/javascripts/require.js", `normal.js;sub/normal.js;sub/require.js;require.js;`)61 assertEqual("public/assets/javascripts/require-min.js", `Please62Do63Not64Compresee65Me66`)67 fingerPrintAssets()68 assertEqual("public/assets/stylesheets/font.css", `h1{color:green}`) // should keep original assets69 train.LoadManifestInfo()70 assertEqual("public"+train.ManifestInfo["/assets/stylesheets/font.css"], `h1{color:green}`)71 removeAssets()72}...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!