Try something like 
github.com/facebookgo/clock

On Thursday, 28 January 2021 at 21:15:50 UTC Christian Worm Mortensen wrote:

> Hi!
>
> Suppose I want to unit test this function:
>
> func generator() <-chan int {
> ret := make(chan int)
> go func() {
> for i := 0; i < 10; i++ {
> ret <- i
> time.Sleep(time.Second)
> }
> }()
> return ret
> }
>
> What is a good way to do that? One way is to do it is like this:
>
> func testGenerator() {
> start := time.Now()
> g := generator()
> for i := 0; i < 10; i++ {
> v := <-g
> if v != i {
> panic("Wrong value")
> }
> }
> elapsed := time.Now().Sub(start)
> if elapsed < 9*time.Second || elapsed > 11*time.Second {
> panic("Wrong execution time")
> }
> }
>
> However there are several issues with this:
>
> 1) The unit test takes a long time to run - 10 seconds.
> 2) The unit test is fragile to fluctuations in CPU availability
> 3) The unit test is not very accurate
>
> Of course this is a simple example. But what if I want to test a 
> complicated piece of code with many go routines interacting in complicated 
> ways and with long timeouts?
>
> In other programming languages, I have been able to implement a form of 
> virtual time which increases only when all threads are waiting for time to 
> increase. This allows functions like generator above to be tested basically 
> instantly and this has been extremely useful for me in many projects over 
> the years.
>
> Can I do something similar in Go? I would expect I would need to wrap 
> time.Now, time.Sleep and time.After which I will be happy to do.
>
> I can see that Go has a deadlock detector. If somehow it was possible to 
> have Go start a new Go routine when a deadlock was detected, I think it 
> would be pretty straight forward to implement virtual time as described. I 
> could then do something like:
>
> runtime.registerDeadlockCallback(func () {
>   // Increase virtual time and by that:
>   //  * Make one or more wrapped time.Sleep calls return or 
>   //  * Write to one or more channels returned by wrapped time.After.
> })
>
> Obviously this would only be needed for test code, not production code.
>
> Thanks,
>
> Christian
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/d58a4e2a-eead-4ec9-b9a9-c0a43a699e89n%40googlegroups.com.

Reply via email to