@@ -25,6 +25,7 @@ import (
2525 "elastic/apm-lambda-extension/logsapi"
2626 "encoding/json"
2727 "fmt"
28+ "github.com/stretchr/testify/suite"
2829 "net"
2930 "net/http"
3031 "net/http/httptest"
@@ -283,193 +284,169 @@ func eventQueueGenerator(inputQueue []MockEvent, eventsChannel chan MockEvent) {
283284}
284285
285286// TESTS
286- func TestMain (m * testing.M ) {
287+ type MainUnitTestsSuite struct {
288+ suite.Suite
289+ eventsChannel chan MockEvent
290+ lambdaServer * httptest.Server
291+ apmServer * httptest.Server
292+ apmServerInternals * APMServerInternals
293+ ctx context.Context
294+ cancel context.CancelFunc
295+ }
296+
297+ func TestMainUnitTestsSuite (t * testing.T ) {
298+ suite .Run (t , new (MainUnitTestsSuite ))
299+ }
300+
301+ // This function executes before each test case
302+ func (suite * MainUnitTestsSuite ) SetupTest () {
303+ suite .ctx , suite .cancel = context .WithCancel (context .Background ())
287304 http .DefaultServeMux = new (http.ServeMux )
288- code := m .Run ()
289- os .Exit (code )
305+ suite .eventsChannel = make (chan MockEvent , 100 )
306+ suite .lambdaServer , suite .apmServer , suite .apmServerInternals = initMockServers (suite .eventsChannel )
307+ extension .SetApmServerTransportState (extension .Healthy , suite .ctx )
290308}
291309
292- // TestStandardEventsChain checks a nominal sequence of events (fast APM server, only one standard event)
293- func TestStandardEventsChain ( t * testing. T ) {
294- eventsChannel := make ( chan MockEvent , 100 )
295- lambdaServer , apmServer , apmServerInternals := initMockServers ( eventsChannel )
296- defer lambdaServer . Close ()
297- defer apmServer . Close ()
310+ // This function executes after each test case
311+ func ( suite * MainUnitTestsSuite ) TearDownTest ( ) {
312+ suite . lambdaServer . Close ( )
313+ suite . apmServer . Close ( )
314+ suite . cancel ()
315+ }
298316
317+ // TestStandardEventsChain checks a nominal sequence of events (fast APM server, only one standard event)
318+ func (suite * MainUnitTestsSuite ) TestStandardEventsChain () {
299319 eventsChain := []MockEvent {
300320 {Type : InvokeStandard , APMServerBehavior : TimelyResponse , ExecutionDuration : 1 , Timeout : 5 },
301321 }
302- eventQueueGenerator (eventsChain , eventsChannel )
303- assert .NotPanics (t , main )
304- assert .True (t , strings .Contains (apmServerInternals .Data , string (TimelyResponse )))
322+ eventQueueGenerator (eventsChain , suite . eventsChannel )
323+ assert .NotPanics (suite . T () , main )
324+ assert .True (suite . T () , strings .Contains (suite . apmServerInternals .Data , string (TimelyResponse )))
305325}
306326
307327// TestFlush checks if the flushed param does not cause a panic or an unexpected behavior
308- func TestFlush (t * testing.T ) {
309- eventsChannel := make (chan MockEvent , 100 )
310- lambdaServer , apmServer , apmServerInternals := initMockServers (eventsChannel )
311- defer lambdaServer .Close ()
312- defer apmServer .Close ()
313-
328+ func (suite * MainUnitTestsSuite ) TestFlush () {
314329 eventsChain := []MockEvent {
315330 {Type : InvokeStandardFlush , APMServerBehavior : TimelyResponse , ExecutionDuration : 1 , Timeout : 5 },
316331 }
317- eventQueueGenerator (eventsChain , eventsChannel )
318- assert .NotPanics (t , main )
319- assert .True (t , strings .Contains (apmServerInternals .Data , string (TimelyResponse )))
332+ eventQueueGenerator (eventsChain , suite . eventsChannel )
333+ assert .NotPanics (suite . T () , main )
334+ assert .True (suite . T () , strings .Contains (suite . apmServerInternals .Data , string (TimelyResponse )))
320335}
321336
322337// TestWaitGroup checks if there is no race condition between the main waitgroups (issue #128)
323- func TestWaitGroup (t * testing.T ) {
324- eventsChannel := make (chan MockEvent , 100 )
325- lambdaServer , apmServer , apmServerInternals := initMockServers (eventsChannel )
326- defer lambdaServer .Close ()
327- defer apmServer .Close ()
328-
338+ func (suite * MainUnitTestsSuite ) TestWaitGroup () {
329339 eventsChain := []MockEvent {
330340 {Type : InvokeWaitgroupsRace , APMServerBehavior : TimelyResponse , ExecutionDuration : 1 , Timeout : 500 },
331341 }
332- eventQueueGenerator (eventsChain , eventsChannel )
333- assert .NotPanics (t , main )
334- assert .True (t , strings .Contains (apmServerInternals .Data , string (TimelyResponse )))
342+ eventQueueGenerator (eventsChain , suite . eventsChannel )
343+ assert .NotPanics (suite . T () , main )
344+ assert .True (suite . T () , strings .Contains (suite . apmServerInternals .Data , string (TimelyResponse )))
335345}
336346
337347// TestAPMServerDown tests that main does not panic nor runs indefinitely when the APM server is inactive.
338- func TestAPMServerDown (t * testing.T ) {
339- eventsChannel := make (chan MockEvent , 100 )
340- lambdaServer , apmServer , apmServerInternals := initMockServers (eventsChannel )
341- defer lambdaServer .Close ()
342- apmServer .Close ()
343-
348+ func (suite * MainUnitTestsSuite ) TestAPMServerDown () {
349+ suite .apmServer .Close ()
344350 eventsChain := []MockEvent {
345351 {Type : InvokeStandard , APMServerBehavior : TimelyResponse , ExecutionDuration : 1 , Timeout : 5 },
346352 }
347- eventQueueGenerator (eventsChain , eventsChannel )
348- assert .NotPanics (t , main )
349- assert .False (t , strings .Contains (apmServerInternals .Data , string (TimelyResponse )))
353+ eventQueueGenerator (eventsChain , suite . eventsChannel )
354+ assert .NotPanics (suite . T () , main )
355+ assert .False (suite . T () , strings .Contains (suite . apmServerInternals .Data , string (TimelyResponse )))
350356}
351357
352358// TestAPMServerHangs tests that main does not panic nor runs indefinitely when the APM server does not respond.
353- func TestAPMServerHangs (t * testing.T ) {
354- extension .SetApmServerTransportState (extension .Healthy , context .Background ())
355- eventsChannel := make (chan MockEvent , 100 )
356- lambdaServer , apmServer , apmServerInternals := initMockServers (eventsChannel )
357- defer lambdaServer .Close ()
358- defer apmServer .Close ()
359-
359+ func (suite * MainUnitTestsSuite ) TestAPMServerHangs () {
360360 eventsChain := []MockEvent {
361361 {Type : InvokeStandard , APMServerBehavior : Hangs , ExecutionDuration : 1 , Timeout : 5 },
362362 }
363- eventQueueGenerator (eventsChain , eventsChannel )
364- assert .NotPanics (t , main )
365- assert .False (t , strings .Contains (apmServerInternals .Data , string (Hangs )))
366- apmServerInternals .UnlockSignalChannel <- struct {}{}
363+ eventQueueGenerator (eventsChain , suite . eventsChannel )
364+ assert .NotPanics (suite . T () , main )
365+ assert .False (suite . T () , strings .Contains (suite . apmServerInternals .Data , string (Hangs )))
366+ suite . apmServerInternals .UnlockSignalChannel <- struct {}{}
367367}
368368
369369// TestAPMServerRecovery tests a scenario where the APM server recovers after hanging.
370370// The default forwarder timeout is 3 seconds, so we wait 5 seconds until we unlock that hanging state.
371371// Hence, the APM server is waked up just in time to process the TimelyResponse data frame.
372- func TestAPMServerRecovery (t * testing.T ) {
373- extension .SetApmServerTransportState (extension .Healthy , context .Background ())
372+ func (suite * MainUnitTestsSuite ) TestAPMServerRecovery () {
374373 if err := os .Setenv ("ELASTIC_APM_DATA_FORWARDER_TIMEOUT_SECONDS" , "1" ); err != nil {
375- t .Fail ()
374+ suite . T () .Fail ()
376375 }
377376 if err := os .Setenv ("ELASTIC_APM_LOG_LEVEL" , "trace" ); err != nil {
378- t .Fail ()
377+ suite . T () .Fail ()
379378 }
380- eventsChannel := make (chan MockEvent , 100 )
381- lambdaServer , apmServer , apmServerInternals := initMockServers (eventsChannel )
382- defer lambdaServer .Close ()
383- defer apmServer .Close ()
384379
385380 eventsChain := []MockEvent {
386381 {Type : InvokeStandard , APMServerBehavior : Hangs , ExecutionDuration : 1 , Timeout : 5 },
387382 {Type : InvokeStandard , APMServerBehavior : TimelyResponse , ExecutionDuration : 1 , Timeout : 5 },
388383 }
389- eventQueueGenerator (eventsChain , eventsChannel )
384+ eventQueueGenerator (eventsChain , suite . eventsChannel )
390385 go func () {
391386 time .Sleep (2500 * time .Millisecond ) // Cannot multiply time.Second by a float
392- apmServerInternals .UnlockSignalChannel <- struct {}{}
387+ suite . apmServerInternals .UnlockSignalChannel <- struct {}{}
393388 }()
394- assert .NotPanics (t , main )
395- assert .True (t , strings .Contains (apmServerInternals .Data , string (Hangs )))
396- assert .True (t , strings .Contains (apmServerInternals .Data , string (TimelyResponse )))
389+ assert .NotPanics (suite . T () , main )
390+ assert .True (suite . T () , strings .Contains (suite . apmServerInternals .Data , string (Hangs )))
391+ assert .True (suite . T () , strings .Contains (suite . apmServerInternals .Data , string (TimelyResponse )))
397392 if err := os .Setenv ("ELASTIC_APM_DATA_FORWARDER_TIMEOUT_SECONDS" , "" ); err != nil {
398- t .Fail ()
393+ suite . T () .Fail ()
399394 }
400395}
401396
402397// TestGracePeriodHangs verifies that the WaitforGracePeriod goroutine ends when main() ends.
403398// This can be checked by asserting that apmTransportStatus is pending after the execution of main.
404- func TestGracePeriodHangs ( t * testing. T ) {
399+ func ( suite * MainUnitTestsSuite ) TestGracePeriodHangs ( ) {
405400 extension .ApmServerTransportState .Status = extension .Pending
406401 extension .ApmServerTransportState .ReconnectionCount = 100
407- eventsChannel := make (chan MockEvent , 100 )
408- lambdaServer , apmServer , apmServerInternals := initMockServers (eventsChannel )
409- defer lambdaServer .Close ()
410- defer apmServer .Close ()
411402
412403 eventsChain := []MockEvent {
413404 {Type : InvokeStandard , APMServerBehavior : Hangs , ExecutionDuration : 1 , Timeout : 5 },
414405 }
415- eventQueueGenerator (eventsChain , eventsChannel )
416- assert .NotPanics (t , main )
406+ eventQueueGenerator (eventsChain , suite . eventsChannel )
407+ assert .NotPanics (suite . T () , main )
417408
418409 time .Sleep (100 * time .Millisecond )
419- apmServerInternals .UnlockSignalChannel <- struct {}{}
420- defer assert .Equal (t , extension .IsTransportStatusHealthyOrPending (), true )
410+ suite . apmServerInternals .UnlockSignalChannel <- struct {}{}
411+ defer assert .Equal (suite . T () , extension .IsTransportStatusHealthyOrPending (), true )
421412}
422413
423414// TestAPMServerCrashesDuringExecution tests that main does not panic nor runs indefinitely when the APM server crashes
424415// during execution.
425- func TestAPMServerCrashesDuringExecution (t * testing.T ) {
426- eventsChannel := make (chan MockEvent , 100 )
427- lambdaServer , apmServer , apmServerInternals := initMockServers (eventsChannel )
428- defer lambdaServer .Close ()
429- defer apmServer .Close ()
430-
416+ func (suite * MainUnitTestsSuite ) TestAPMServerCrashesDuringExecution () {
431417 eventsChain := []MockEvent {
432418 {Type : InvokeStandard , APMServerBehavior : Crashes , ExecutionDuration : 1 , Timeout : 5 },
433419 }
434- eventQueueGenerator (eventsChain , eventsChannel )
435- assert .NotPanics (t , main )
436- assert .False (t , strings .Contains (apmServerInternals .Data , string (Crashes )))
420+ eventQueueGenerator (eventsChain , suite . eventsChannel )
421+ assert .NotPanics (suite . T () , main )
422+ assert .False (suite . T () , strings .Contains (suite . apmServerInternals .Data , string (Crashes )))
437423}
438424
439425// TestFullChannel checks that an overload of APM data chunks is handled correctly, events dropped beyond the 100th one
440426// if no space left in channel, no panic, no infinite hanging.
441- func TestFullChannel (t * testing.T ) {
442- eventsChannel := make (chan MockEvent , 1000 )
443- lambdaServer , apmServer , apmServerInternals := initMockServers (eventsChannel )
444- defer lambdaServer .Close ()
445- defer apmServer .Close ()
446-
427+ func (suite * MainUnitTestsSuite ) TestFullChannel () {
447428 eventsChain := []MockEvent {
448429 {Type : InvokeMultipleTransactionsOverload , APMServerBehavior : TimelyResponse , ExecutionDuration : 0.1 , Timeout : 5 },
449430 }
450- eventQueueGenerator (eventsChain , eventsChannel )
451- assert .NotPanics (t , main )
452- assert .True (t , strings .Contains (apmServerInternals .Data , string (TimelyResponse )))
431+ eventQueueGenerator (eventsChain , suite . eventsChannel )
432+ assert .NotPanics (suite . T () , main )
433+ assert .True (suite . T () , strings .Contains (suite . apmServerInternals .Data , string (TimelyResponse )))
453434}
454435
455436// TestFullChannelSlowAPMServer tests what happens when the APM Data channel is full and the APM server is slow
456437// (send strategy : background)
457- func TestFullChannelSlowAPMServer ( t * testing. T ) {
438+ func ( suite * MainUnitTestsSuite ) TestFullChannelSlowAPMServer ( ) {
458439 if err := os .Setenv ("ELASTIC_APM_SEND_STRATEGY" , "background" ); err != nil {
459- t .Fail ()
440+ suite . T () .Fail ()
460441 }
461- eventsChannel := make (chan MockEvent , 1000 )
462- lambdaServer , apmServer , _ := initMockServers (eventsChannel )
463- defer lambdaServer .Close ()
464- defer apmServer .Close ()
465442
466443 eventsChain := []MockEvent {
467444 {Type : InvokeMultipleTransactionsOverload , APMServerBehavior : SlowResponse , ExecutionDuration : 0.01 , Timeout : 5 },
468445 }
469- eventQueueGenerator (eventsChain , eventsChannel )
470- assert .NotPanics (t , main )
446+ eventQueueGenerator (eventsChain , suite . eventsChannel )
447+ assert .NotPanics (suite . T () , main )
471448 // The test should not hang
472449 if err := os .Setenv ("ELASTIC_APM_SEND_STRATEGY" , "syncflush" ); err != nil {
473- t .Fail ()
450+ suite . T () .Fail ()
474451 }
475452}
0 commit comments