blob: e440528960ef060fcc6d2e042df13a60ffa0c93d [file] [log] [blame]
/*
* Copyright (C) 2016 Square, 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 okio;
import java.io.InterruptedIOException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.junit.After;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public final class WaitUntilNotifiedTest {
final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(0);
@After public void tearDown() {
executorService.shutdown();
}
@Test public synchronized void notified() throws InterruptedIOException {
Timeout timeout = new Timeout();
timeout.timeout(5000, TimeUnit.MILLISECONDS);
double start = now();
executorService.schedule(new Runnable() {
@Override public void run() {
synchronized (WaitUntilNotifiedTest.this) {
WaitUntilNotifiedTest.this.notify();
}
}
}, 1000, TimeUnit.MILLISECONDS);
timeout.waitUntilNotified(this);
assertElapsed(1000.0, start);
}
@Test public synchronized void timeout() {
TestUtil.INSTANCE.assumeNotWindows();
Timeout timeout = new Timeout();
timeout.timeout(1000, TimeUnit.MILLISECONDS);
double start = now();
try {
timeout.waitUntilNotified(this);
fail();
} catch (InterruptedIOException expected) {
assertEquals("timeout", expected.getMessage());
}
assertElapsed(1000.0, start);
}
@Test public synchronized void deadline() {
TestUtil.INSTANCE.assumeNotWindows();
Timeout timeout = new Timeout();
timeout.deadline(1000, TimeUnit.MILLISECONDS);
double start = now();
try {
timeout.waitUntilNotified(this);
fail();
} catch (InterruptedIOException expected) {
assertEquals("timeout", expected.getMessage());
}
assertElapsed(1000.0, start);
}
@Test public synchronized void deadlineBeforeTimeout() {
TestUtil.INSTANCE.assumeNotWindows();
Timeout timeout = new Timeout();
timeout.timeout(5000, TimeUnit.MILLISECONDS);
timeout.deadline(1000, TimeUnit.MILLISECONDS);
double start = now();
try {
timeout.waitUntilNotified(this);
fail();
} catch (InterruptedIOException expected) {
assertEquals("timeout", expected.getMessage());
}
assertElapsed(1000.0, start);
}
@Test public synchronized void timeoutBeforeDeadline() {
TestUtil.INSTANCE.assumeNotWindows();
Timeout timeout = new Timeout();
timeout.timeout(1000, TimeUnit.MILLISECONDS);
timeout.deadline(5000, TimeUnit.MILLISECONDS);
double start = now();
try {
timeout.waitUntilNotified(this);
fail();
} catch (InterruptedIOException expected) {
assertEquals("timeout", expected.getMessage());
}
assertElapsed(1000.0, start);
}
@Test public synchronized void deadlineAlreadyReached() {
TestUtil.INSTANCE.assumeNotWindows();
Timeout timeout = new Timeout();
timeout.deadlineNanoTime(System.nanoTime());
double start = now();
try {
timeout.waitUntilNotified(this);
fail();
} catch (InterruptedIOException expected) {
assertEquals("timeout", expected.getMessage());
}
assertElapsed(0.0, start);
}
@Test public synchronized void threadInterrupted() {
TestUtil.INSTANCE.assumeNotWindows();
Timeout timeout = new Timeout();
double start = now();
Thread.currentThread().interrupt();
try {
timeout.waitUntilNotified(this);
fail();
} catch (InterruptedIOException expected) {
assertEquals("interrupted", expected.getMessage());
assertTrue(Thread.interrupted());
}
assertElapsed(0.0, start);
}
@Test public synchronized void threadInterruptedOnThrowIfReached() throws Exception {
TestUtil.INSTANCE.assumeNotWindows();
Timeout timeout = new Timeout();
Thread.currentThread().interrupt();
try {
timeout.throwIfReached();
fail();
} catch (InterruptedIOException expected) {
assertEquals("interrupted", expected.getMessage());
assertTrue(Thread.interrupted());
}
}
/** Returns the nanotime in milliseconds as a double for measuring timeouts. */
private double now() {
return System.nanoTime() / 1000000.0d;
}
/**
* Fails the test unless the time from start until now is duration, accepting differences in
* -50..+450 milliseconds.
*/
private void assertElapsed(double duration, double start) {
assertEquals(duration, now() - start - 200d, 250.0);
}
}