public void start(List<AlarmCallback> allCallbacks) {
        LocalDateTime now = LocalDateTime.now();
        lastExecuteTime = now;
        Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> {
            try {
                final List<AlarmMessage> alarmMessageList = new ArrayList<>(30);
                LocalDateTime checkTime = LocalDateTime.now();
                int minutes = Minutes.minutesBetween(lastExecuteTime, checkTime).getMinutes();
                boolean[] hasExecute = new boolean[]{false};
                alarmRulesWatcher.getRunningContext().values().forEach(ruleList -> ruleList.forEach(runningRule -> {
                    if (minutes > 0) {
                        runningRule.moveTo(checkTime);
                        /*
                         * Don't run in the first quarter per min, avoid to trigger false alarm.
                         */
                        if (checkTime.getSecondOfMinute() > 15) {
                            hasExecute[0] = true;
                            alarmMessageList.addAll(runningRule.check());
                        }
                    }
                }));
                // Set the last execute time, and make sure the second is `00`, such as: 18:30:00
                if (hasExecute[0]) {
                    lastExecuteTime = checkTime.withSecondOfMinute(0).withMillisOfSecond(0);
                }

                if (!alarmMessageList.isEmpty()) {
                    for (AlarmCallback callback : allCallbacks) {
                        try {
                            callback.doAlarm(alarmMessageList);
                        } catch (Exception e) {
                            LOGGER.error(e.getMessage(), e);
                        }
                    }
                }
            } catch (Exception e) {
                LOGGER.error(e.getMessage(), e);
            }
        }, 10, 10, TimeUnit.SECONDS);
    }
@Test
    public void testTriggerTimePoint() throws InterruptedException {
        String test = System.getProperty("AlarmCoreTest");
        if (test == null) {
            return;
        }

        Rules emptyRules = new Rules();
        emptyRules.setRules(new ArrayList<>(0));
        AlarmCore core = new AlarmCore(new AlarmRulesWatcher(emptyRules, null));

        Map<String, List<RunningRule>> runningContext = Whitebox.getInternalState(core, "runningContext");

        List<RunningRule> rules = new ArrayList<>(1);
        RunningRule mockRule = mock(RunningRule.class);

        List<LocalDateTime> checkTime = new LinkedList<>();
        final boolean[] isAdd = {true};

        doAnswer((Answer<Object>) mock -> {
            if (isAdd[0]) {
                checkTime.add(LocalDateTime.now());
            }
            return new ArrayList<>(0);
        }).when(mockRule).check();

        rules.add(mockRule);
        runningContext.put("mock", rules);

        core.start(new ArrayList<>(0));

        for (int i = 0; i < 10; i++) {
            Thread.sleep(60 * 1000L);
            if (checkTime.size() >= 3) {
                isAdd[0] = false;
                Assertions.assertTrue(checkTimePoints(checkTime));
                break;
            }
            if (i == 9) {
                Assertions.assertTrue(false);
            }
        }
    }