time icon indicating copy to clipboard operation
time copied to clipboard

[Request] Add ManualClock type for discrete time changes

Open Mordil opened this issue 10 months ago • 0 comments

Motivation

In tests, especially those dealing with deadlines, it would be extremely helpful to test that events are firing when they're supposed to.

An example is having a scheduled queue with jobs running at deadlines, and the queue uses a ClockStrike under the hood to run every minute and check for jobs that have deadlines that passed.

Here's a snippet of what such a use case may have as a unit test with today's API

    describe("executing jobs") {
      it("runs jobs after deadline") {
        let queue = DataSyncQueue(client: apolloClient, clock: fastClock)
        await queue.modifyChimeTime(.seconds(1))

        let jobA = MockJob(priority: .every(1))
        let jobB = MockAJob(priority: .every(2))
        let jobC = MockBJob(priority: .every(5))

        await queue.addJob(jobA)
        await queue.addJob(jobB)
        await queue.addJob(jobC)
        await queue.startSync()

        try await Clocks.system.sleep(for: 1)

        // because of the scaled nature, we don't always get exactly 10 clock strikes per real world second
        // so we expect it to be ran at least a certain amount of times, + 1 to account for a "rounding up" timing error
        expect(jobA.timesJobRun).to(beWithin(8...10)) // for this one, we might only get 8 ticks in a second
        expect(jobB.timesJobRun).to(beWithin(4...5))
        expect(jobC.timesJobRun).to(beWithin(1...2))
      }

Request

The reliability of this test could be vastly improved if there was a ManualClock that allowed us to set now as a fixed point in time, and then only when we tell it to, it increments the current time and does any ClockStrikes as necessary.

Mordil avatar Apr 11 '24 18:04 Mordil