如何在 Hazelcast 中实现自定义时钟进行单元测试?

How to implement a custom clock in Hazelcast for unit testing?

在使用自定义到期持续时间测试我的一些代码时,我需要在 Hazelcast 实例中设置时钟时间,这与我在 Caffeine 缓存中使用自定义 Ticker 设置时间的方式非常相似。

我发现这在任何地方都没有记录,也没有任何问题。

跟踪 HazelcastInstance 的源代码后,如果您设置系统 属性、com.hazelcast.clock.impl

,则可以实现自定义时钟

这就是 Hazelcast 加载时钟的方式

package com.hazelcast.util;

...

public final class Clock {

    private static final ClockImpl CLOCK;
    private Clock() {
    }

    /** Returns the current time in ms for the configured {@link ClockImpl} */
    public static long currentTimeMillis() {
        return CLOCK.currentTimeMillis();
    }

    static {
        CLOCK = createClock();
    }

    static ClockImpl createClock() {
        String clockImplClassName = System.getProperty(ClockProperties.HAZELCAST_CLOCK_IMPL);
        if (clockImplClassName != null) {
            try {
                return ClassLoaderUtil.newInstance(null, clockImplClassName);
            } catch (Exception e) {
                throw rethrow(e);
            }
        }

        String clockOffset = System.getProperty(ClockProperties.HAZELCAST_CLOCK_OFFSET);
        long offset = 0L;
        if (clockOffset != null) {
            try {
                offset = Long.parseLong(clockOffset);
            } catch (NumberFormatException e) {
                throw rethrow(e);
            }
        }
        if (offset != 0L) {
            return new SystemOffsetClock(offset);
        }

        return new SystemClock();
    }
}

所以,要设置这个时钟,我们需要用我们自己的时钟设置系统 属性,

public class MyHazelcastCacheTest {
    static {
        // set unit test time travelling clock
        System.setProperty(ClockProperties.HAZELCAST_CLOCK_IMPL, TimeTravellingStaticClock.class.getName());
    }

    private void timeTravel(Clock clock) {
        TimeTravellingStaticClock.timeTravel(clock);
    }

    private void undoTimeTravel() {
        TimeTravellingStaticClock.undoTimeTravel();
    }

    private static class TimeTravellingStaticClock extends com.hazelcast.util.Clock.ClockImpl {
        private static Clock sClock = Clock.systemUTC();

        public TimeTravellingStaticClock() {
            // nothing
        }

        public static void timeTravel(Clock clock) {
            sClock = clock;
        }

        public static void undoTimeTravel() {
            sClock = Clock.systemUTC();
        }

        @Override
        protected long currentTimeMillis() {
            return sClock.millis();
        }
    }
}