如何在 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();
}
}
}
在使用自定义到期持续时间测试我的一些代码时,我需要在 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();
}
}
}