lib/quic/src/sim/clock.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

 1 const std = @import("std");
 2 
 3 /// A nanosecond counter a test owns and moves forward itself. A test holds a manual clock and
 4 /// passes its reading wherever a connection or a link asks for the current time. The clock starts
 5 /// at zero. A test alone moves the clock, so the test decides the exact instant of every step.
 6 pub const Clock = struct {
 7     now_ns: u64 = 0,
 8 
 9     /// Moves the clock forward by a given number of nanoseconds so a test puts a chosen span of
10     /// time between steps. At the largest representable instant the clock stops there, so the
11     /// reading never goes backward.
12     pub fn advance(self: *Clock, delta_ns: u64) void {
13         const previous = self.now_ns;
14         self.now_ns = std.math.add(u64, self.now_ns, delta_ns) catch
15             std.math.maxInt(u64);
16         std.debug.assert(self.now_ns >= previous);
17         if (self.now_ns != std.math.maxInt(u64)) {
18             std.debug.assert(self.now_ns - previous == delta_ns);
19         }
20     }
21 };
22 
23 test "manual clock advances by the requested nanoseconds" {
24     var clock = Clock{};
25     clock.advance(41);
26     try std.testing.expectEqual(@as(u64, 41), clock.now_ns);
27 }
28 
29 test "manual clock never moves backward at integer capacity" {
30     var clock = Clock{ .now_ns = std.math.maxInt(u64) - 1 };
31     clock.advance(2);
32     try std.testing.expectEqual(std.math.maxInt(u64), clock.now_ns);
33     clock.advance(1);
34     try std.testing.expectEqual(std.math.maxInt(u64), clock.now_ns);
35 }