Skip to content

Commit

Permalink
fix(tests): integration timeout handling
Browse files Browse the repository at this point in the history
Updated the Tracee integration tests to address a bug with the
time.After usage. Previously, at each iteration of the loop, the
time.After was reset whenever its corresponding select clause was
reached. This behavior resulted in the creation of a new timer on each
loop iteration without freeing the previous one, leading to a memory
leak.

The solution involved replacing time.After with a dedicated
timeoutTicker, ensuring consistent timeout handling without unnecessary
resource consumption.
  • Loading branch information
geyslan committed Oct 31, 2023
1 parent c58f1bb commit f3ee19d
Showing 1 changed file with 35 additions and 18 deletions.
53 changes: 35 additions & 18 deletions tests/integration/tracee.go
Expand Up @@ -125,7 +125,6 @@ func startTracee(ctx context.Context, t *testing.T, cfg config.Config, output *c
err = trc.Init(ctx)
require.NoError(t, err)

t.Logf("started tracee...\n")
go func() {
err := trc.Run(ctx)
require.NoError(t, err, "tracee run failed")
Expand All @@ -149,17 +148,22 @@ func prepareCapture() *config.CaptureConfig {
// wait for tracee to start (or timeout)
// in case of timeout, the test will fail
func waitForTraceeStart(t *testing.T, trc *tracee.Tracee) {
const checkTimeout = 10 * time.Second
ticker := time.NewTicker(100 * time.Millisecond)
const timeout = 10 * time.Second

statusCheckTicker := time.NewTicker(100 * time.Millisecond)
defer statusCheckTicker.Stop()
timeoutTicker := time.NewTicker(timeout)
defer timeoutTicker.Stop()

for {
select {
case <-ticker.C:
case <-statusCheckTicker.C:
if trc.Running() {
t.Logf(">>> started tracee ...")
return
}
case <-time.After(checkTimeout):
t.Logf("timed out on running tracee\n")
case <-timeoutTicker.C:
t.Logf("timed out on waiting for tracee to start")
t.FailNow()
}
}
Expand All @@ -168,18 +172,22 @@ func waitForTraceeStart(t *testing.T, trc *tracee.Tracee) {
// wait for tracee to stop (or timeout)
// in case of timeout, the test will continue since all tests already passed
func waitForTraceeStop(t *testing.T, trc *tracee.Tracee) {
const checkTimeout = 10 * time.Second
ticker := time.NewTicker(100 * time.Millisecond)
const timeout = 10 * time.Second

statusCheckTicker := time.NewTicker(100 * time.Millisecond)
defer statusCheckTicker.Stop()
timeoutTicker := time.NewTicker(timeout)
defer timeoutTicker.Stop()

for {
select {
case <-ticker.C:
case <-statusCheckTicker.C:
if !trc.Running() {
t.Logf("stopped tracee\n")
t.Logf("<<< stopped tracee")
return
}
case <-time.After(checkTimeout):
t.Logf("timed out on stopping tracee\n")
case <-timeoutTicker.C:
t.Logf("timed out on stopping tracee")
return
}
}
Expand All @@ -188,18 +196,27 @@ func waitForTraceeStop(t *testing.T, trc *tracee.Tracee) {
// wait for tracee buffer to fill up with expected number of events (or timeout)
// in case of timeout, the test will fail
func waitForTraceeOutputEvents(t *testing.T, actual *eventBuffer, now time.Time, expectedEvts int, failOnTimeout bool) {
const checkTimeout = 5 * time.Second
ticker := time.NewTicker(100 * time.Millisecond)
const timeout = 5 * time.Second

statusCheckTicker := time.NewTicker(100 * time.Millisecond)
defer statusCheckTicker.Stop()
timeoutTicker := time.NewTicker(timeout)
defer timeoutTicker.Stop()

t.Logf("waiting for %d event(s) for %s", expectedEvts, timeout.String())
defer t.Logf("done waiting for %d event(s)", expectedEvts)

for {
select {
case <-ticker.C:
if actual.len() >= expectedEvts {
case <-statusCheckTicker.C:
len := actual.len()
t.Logf("got %d event(s) so far", len)
if len >= expectedEvts {
return
}
case <-time.After(checkTimeout):
case <-timeoutTicker.C:
if failOnTimeout {
t.Logf("timed out on output\n")
t.Logf("timed out on waiting for %d event(s)", expectedEvts)
t.FailNow()
}
return
Expand Down

0 comments on commit f3ee19d

Please sign in to comment.