kubernetes / utils

Non-Kubernetes-specific utility libraries which are consumed by multiple projects.
Apache License 2.0
328 stars 195 forks source link

FakeClock.Sleep calling FakeClock.Step may be unexpected #309

Open SOF3 opened 4 months ago

SOF3 commented 4 months ago

What happened:

Consider the following code (playground):

package main

import (
    "time"

    "k8s.io/utils/clock"
    clocktesting "k8s.io/utils/clock/testing"
)

func main() {
    clk := clocktesting.NewFakeClock(time.Now())
    go func(clk clock.Clock) {
        clk.Sleep(time.Second * 2)
        println("after 2 fakeclock seconds")
    }(clk)

    time.Sleep(time.Millisecond) // used to emulate race condition
    clk.Sleep(time.Second)
    println("after 1 fakeclock second")
}

The code above prints

after 2 fakeclock seconds
after 1 fakeclock second

When clk is changed to clock.RealClock{} (playground), the println lines are in correct order (1 -> 2).

What you expected to happen:

Intuitively, one would expect clk.Sleep(duration) to be identical to <-clk.After(duration). However, (*FakeClock).Sleep actually calls clk.Step instead, which immediately modifies the clock.

Suggested fix:

It would be a huge BC break to many testing packages if (*FakeClock).Sleep is changed to be passive. Documentation improvement would suffice, although deprecating Sleep would be great since Sleep doesn't always do what users intend. (imo, clk.Step is usually only intended in the main control flow of the unit test rather than other goroutines, so calling clk.Sleep from non-testing code is often unintended).

Alternatively, consider adding a ref-counted clock, where Sleep and After have identical behavior and the clock is only stepped when all refs are sleeping.

Environment: k8s.io/utils: fe8a2dddb1d00a41a4a4132ba33cb324aa7cd71c

k8s-triage-robot commented 1 month ago

The Kubernetes project currently lacks enough contributors to adequately respond to all issues.

This bot triages un-triaged issues according to the following rules:

You can:

Please send feedback to sig-contributor-experience at kubernetes/community.

/lifecycle stale

SOF3 commented 3 weeks ago

/remove-lifecycle stale