如何使用ginkgo/gomega测试无限循环/递归?

huangapple go评论90阅读模式
英文:

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

问题

我有一个使用golang编写的函数,它递归地遍历一个JSON字符串,并将自定义引用替换为它们引用的JSON文档。我刚刚注意到我忘记处理循环引用,它们的出现会导致无限递归。

在修复之前,我想为这种情况编写一个测试(使用ginkgo/gomega),这样我就可以验证我的解决方案是否有效,并且如果我再次遇到这个问题并且出现错误,我会注意到。

但是,我该如何做到"如果此函数调用在内未返回,则中止它并使测试失败"?

Gomega的Eventually有一个超时时间,但如果函数已经在运行,它不会中止函数,因此在这种情况下它将永远阻塞。

我在这个例子中找到了如何使用select和通道检查超时的示例,但据我所了解,不可能从外部终止一个goroutine - 所以我的函数将继续在后台运行,消耗资源?

检查无限递归的最佳方法是什么?

英文:

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?

答案1

得分: 3

你无法中止正在运行的函数。函数必须通过context.Context或通道来支持中止操作。如果你想要支持超时或中止操作,你需要改变或重构你的函数。函数本身必须支持这一点,例如,它必须监视context.Context,并在取消请求时提前返回。有关详细信息和示例,请参见https://stackoverflow.com/questions/62002729/terminating-function-execution-if-a-context-is-cancelled/62002965#62002965

相关链接:

https://stackoverflow.com/questions/28240133/cancel-a-blocking-operation-in-go/28240299#28240299

https://stackoverflow.com/questions/51704212/cancelling-user-specific-goroutines/51704258#51704258

英文:

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 https://stackoverflow.com/questions/62002729/terminating-function-execution-if-a-context-is-cancelled/62002965#62002965

See related:

https://stackoverflow.com/questions/28240133/cancel-a-blocking-operation-in-go/28240299#28240299

https://stackoverflow.com/questions/51704212/cancelling-user-specific-goroutines/51704258#51704258

huangapple
  • 本文由 发表于 2022年1月11日 21:13:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/70667439.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定