/** * Copyright 2014 Netflix, Inc. * * Licensed 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 rx.schedulers; import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.anyLong; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import org.junit.Test; import org.mockito.InOrder; import org.mockito.Mockito; import rx.Observable; import rx.Observable.OnSubscribe; import rx.Scheduler; import rx.Subscriber; import rx.Subscription; import rx.functions.Action0; import rx.functions.Func1; public class TestSchedulerTest { @SuppressWarnings("unchecked") // mocking is unchecked, unfortunately @Test public final void testPeriodicScheduling() { final Func1<Long, Void> calledOp = mock(Func1.class); final TestScheduler scheduler = new TestScheduler(); final Scheduler.Worker inner = scheduler.createWorker(); try { inner.schedulePeriodically(new Action0() { @Override public void call() { System.out.println(scheduler.now()); calledOp.call(scheduler.now()); } }, 1, 2, TimeUnit.SECONDS); verify(calledOp, never()).call(anyLong()); InOrder inOrder = Mockito.inOrder(calledOp); scheduler.advanceTimeBy(999L, TimeUnit.MILLISECONDS); inOrder.verify(calledOp, never()).call(anyLong()); scheduler.advanceTimeBy(1L, TimeUnit.MILLISECONDS); inOrder.verify(calledOp, times(1)).call(1000L); scheduler.advanceTimeBy(1999L, TimeUnit.MILLISECONDS); inOrder.verify(calledOp, never()).call(3000L); scheduler.advanceTimeBy(1L, TimeUnit.MILLISECONDS); inOrder.verify(calledOp, times(1)).call(3000L); scheduler.advanceTimeBy(5L, TimeUnit.SECONDS); inOrder.verify(calledOp, times(1)).call(5000L); inOrder.verify(calledOp, times(1)).call(7000L); inner.unsubscribe(); scheduler.advanceTimeBy(11L, TimeUnit.SECONDS); inOrder.verify(calledOp, never()).call(anyLong()); } finally { inner.unsubscribe(); } } @SuppressWarnings("unchecked") // mocking is unchecked, unfortunately @Test public final void testPeriodicSchedulingUnsubscription() { final Func1<Long, Void> calledOp = mock(Func1.class); final TestScheduler scheduler = new TestScheduler(); final Scheduler.Worker inner = scheduler.createWorker(); try { final Subscription subscription = inner.schedulePeriodically(new Action0() { @Override public void call() { System.out.println(scheduler.now()); calledOp.call(scheduler.now()); } }, 1, 2, TimeUnit.SECONDS); verify(calledOp, never()).call(anyLong()); InOrder inOrder = Mockito.inOrder(calledOp); scheduler.advanceTimeBy(999L, TimeUnit.MILLISECONDS); inOrder.verify(calledOp, never()).call(anyLong()); scheduler.advanceTimeBy(1L, TimeUnit.MILLISECONDS); inOrder.verify(calledOp, times(1)).call(1000L); scheduler.advanceTimeBy(1999L, TimeUnit.MILLISECONDS); inOrder.verify(calledOp, never()).call(3000L); scheduler.advanceTimeBy(1L, TimeUnit.MILLISECONDS); inOrder.verify(calledOp, times(1)).call(3000L); scheduler.advanceTimeBy(5L, TimeUnit.SECONDS); inOrder.verify(calledOp, times(1)).call(5000L); inOrder.verify(calledOp, times(1)).call(7000L); subscription.unsubscribe(); scheduler.advanceTimeBy(11L, TimeUnit.SECONDS); inOrder.verify(calledOp, never()).call(anyLong()); } finally { inner.unsubscribe(); } } @Test public final void testImmediateUnsubscribes() { TestScheduler s = new TestScheduler(); final Scheduler.Worker inner = s.createWorker(); final AtomicInteger counter = new AtomicInteger(0); try { inner.schedule(new Action0() { @Override public void call() { counter.incrementAndGet(); System.out.println("counter: " + counter.get()); inner.schedule(this); } }); inner.unsubscribe(); assertEquals(0, counter.get()); } finally { inner.unsubscribe(); } } @Test public final void testImmediateUnsubscribes2() { TestScheduler s = new TestScheduler(); final Scheduler.Worker inner = s.createWorker(); try { final AtomicInteger counter = new AtomicInteger(0); final Subscription subscription = inner.schedule(new Action0() { @Override public void call() { counter.incrementAndGet(); System.out.println("counter: " + counter.get()); inner.schedule(this); } }); subscription.unsubscribe(); assertEquals(0, counter.get()); } finally { inner.unsubscribe(); } } @Test public final void testNestedSchedule() { final TestScheduler scheduler = new TestScheduler(); final Scheduler.Worker inner = scheduler.createWorker(); try { final Action0 calledOp = mock(Action0.class); Observable<Object> poller; poller = Observable.create(new OnSubscribe<Object>() { @Override public void call(final Subscriber<? super Object> aSubscriber) { inner.schedule(new Action0() { @Override public void call() { if (!aSubscriber.isUnsubscribed()) { calledOp.call(); inner.schedule(this, 5, TimeUnit.SECONDS); } } }); } }); InOrder inOrder = Mockito.inOrder(calledOp); Subscription sub; sub = poller.subscribe(); scheduler.advanceTimeTo(6, TimeUnit.SECONDS); inOrder.verify(calledOp, times(2)).call(); sub.unsubscribe(); scheduler.advanceTimeTo(11, TimeUnit.SECONDS); inOrder.verify(calledOp, never()).call(); sub = poller.subscribe(); scheduler.advanceTimeTo(12, TimeUnit.SECONDS); inOrder.verify(calledOp, times(1)).call(); } finally { inner.unsubscribe(); } } }