/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jena.atlas.lib ;
import static com.jayway.awaitility.Awaitility.await ;
import static org.apache.jena.atlas.lib.Lib.sleep ;
import java.util.concurrent.TimeUnit ;
import static java.util.concurrent.TimeUnit.* ;
import java.util.concurrent.atomic.AtomicInteger ;
import org.apache.jena.atlas.junit.BaseTest ;
import org.junit.Test ;
public class TestAlarmClock extends BaseTest {
/* Issues with MS Windows.
*
* Running some of these tests on windows is unreliable; sometimes they pass,
* sometimes one or more fails.
*
* This seems to be that when the CI server (ASF Jenkins, Windows VM)
* is under load then the ScheduledThreadPoolExecutor used by AlarmClock
* is unreliable.
*
* But setting the times so high for this slows the tests down a lot
* and makes some of them fairly pointless.
*
* The use of awaitility helps this - the timeouts can be set quite long
* and the polling done means the full wait time does not happen normally.
*/
private AtomicInteger count = new AtomicInteger(0) ;
private Runnable callback = ()->count.getAndIncrement() ;
@Test
public void alarm_01() {
AlarmClock alarmClock = new AlarmClock() ;
// Very long - never happens.
Alarm a = alarmClock.add(callback, 10000000) ;
alarmClock.cancel(a) ;
assertEquals(0, count.get()) ;
alarmClock.release() ;
}
private void awaitUntil(int value, long timePeriod, TimeUnit units) {
await()
.atMost(timePeriod, units)
.until(() -> {
return count.get() == value ;
}) ;
}
@Test
public void alarm_02() {
AlarmClock alarmClock = new AlarmClock() ;
// Short - happens.
Alarm a = alarmClock.add(callback, 10) ;
awaitUntil(1, 500, MILLISECONDS) ;
// try to cancel anyway.
alarmClock.cancel(a) ;
alarmClock.release() ;
}
@Test
public void alarm_03() {
AlarmClock alarmClock = new AlarmClock() ;
Alarm a1 = alarmClock.add(callback, 10) ;
Alarm a2 = alarmClock.add(callback, 1000000) ;
awaitUntil(1, 500, MILLISECONDS) ;
alarmClock.cancel(a2) ;
alarmClock.release() ;
}
@Test
public void alarm_04() {
AlarmClock alarmClock = new AlarmClock() ;
Alarm a1 = alarmClock.add(callback, 10) ;
Alarm a2 = alarmClock.add(callback, 20) ;
awaitUntil(2, 500, MILLISECONDS) ;
alarmClock.release() ;
}
@Test
public void alarm_05() {
AlarmClock alarmClock = new AlarmClock() ;
Alarm a = alarmClock.add(callback, 50) ;
alarmClock.reset(a, 20000) ;
sleep(150) ;
// Did not go off.
assertEquals(0, count.get()) ;
alarmClock.cancel(a);
alarmClock.release() ;
}
}