Search code examples
gotestingrecursionginkgogomega

How to test for infinite loop/recursion with ginkgo/gomega?


I have a golang function which recursively steps through a json string and replaces custom references with the json document they are referencing. I just noticed that I forgot to handle cyclic references, whose occurrence will lead to endless recursion. Before I fix this, I'd like to write a test for this case (using ginkgo/gomega), so I can verify that my solution works and I will notice if I ever break it and run into this problem again.

But how do I do something like if this function call does not return within <timeout>, abort it and fail the test?

Gomega's Eventually has a timeout, but it doesn't abort the function if it is already running, so it will block forever in this case.

I found this example for how to check for a timeout using select and channels, but from what I understood, it is not possible to terminate a goroutine from outside - so my function will continue to run in the background, eating up resources?

What is the best way to check for infinite recursion?


Solution

  • You can't abort a running function. The function has to support abortion, idiomatically through a context.Context or a channel. If you want to support timeout or abortion, you have to change / refactor your function. And the function itself has to support this, e.g. it has to monitor the context.Context and return early if cancellation was requested. For details and example, see Terminating function execution if a context is cancelled

    See related:

    cancel a blocking operation in Go

    Cancelling user specific goroutines