blob: ab3f7dfb48e407423e84f50fdcd33113e445fd05 [file] [log] [blame]
/*
* 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 libcore.java.lang;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.LockSupport;
import libcore.java.lang.ref.FinalizationTester;
public class OldThreadTest extends junit.framework.TestCase {
static class SimpleThread implements Runnable {
int delay;
public void run() {
try {
synchronized (this) {
this.notify();
this.wait(delay);
}
} catch (InterruptedException e) {
return;
}
}
public SimpleThread(int d) {
if (d >= 0)
delay = d;
}
}
@SuppressWarnings("DeadThread")
public void test_ConstructorLjava_lang_ThreadGroupLjava_lang_RunnableLjava_lang_StringL$L() {
ThreadGroup tg = new ThreadGroup("Test Group2");
st = new Thread(tg, new SimpleThread(1), "SimpleThread3", 1);
assertTrue("Constructed incorrect thread", (st.getThreadGroup() == tg)
&& st.getName().equals("SimpleThread3"));
st.start();
try {
st.join();
} catch (InterruptedException e) {
}
tg.destroy();
try {
new Thread(tg, new SimpleThread(1), "SimpleThread3",
Integer.MAX_VALUE);
fail("StackOverflowError/OutOfMemoryError is not thrown.");
} catch(IllegalThreadStateException itse) {
//expected
}
}
public void test_dumpStack() {
try {
PrintStream savedErr = System.err;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
System.setErr(new PrintStream(baos));
Thread.dumpStack();
System.setErr(savedErr);
String s = new String(baos.toByteArray());
assertTrue(s.contains("java.lang.Thread.dumpStack"));
} catch(Exception e) {
fail("Unexpected exception was thrown: " + e.toString());
}
}
class MonitoredClass {
public synchronized void enterLocked() {
boolean b = Thread.holdsLock(this);
assertTrue("Thread should hold lock for object", b);
}
public void enterNonLocked() {
boolean b = Thread.holdsLock(this);
assertFalse("Thread should not hold lock for object", b);
}
}
boolean wasInterrupted = false;
public void test_joinWithSpuriousInterruption() throws InterruptedException {
final Thread parker = new Thread() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
// we used to get spurious wakeups upon unparking
LockSupport.park();
}
}
};
Thread unparker = new Thread() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(100);
LockSupport.unpark(parker);
} catch (InterruptedException expected) {
}
}
}
};
long startNanos = System.nanoTime();
parker.start();
unparker.start();
parker.join(500, 500000);
long netWaitTime = System.nanoTime() - startNanos;
assertTrue("Expected to wait at least 500000000ns, but was " + netWaitTime + "ns",
netWaitTime > 500000000);
}
public void test_setContextClassLoader() {
ClassLoader pcl = new ClassLoader() {};
st = new Thread();
st.setContextClassLoader(pcl);
assertEquals(pcl, st.getContextClassLoader());
st.setContextClassLoader(null);
assertNull(st.getContextClassLoader());
}
public void test_setDaemonZ() {
st = new Thread(new SimpleThread(5));
st.start();
try {
st.setDaemon(false);
fail("setDaemon() must throw exception for started thread");
} catch (IllegalThreadStateException ex) {
// We expect this one.
}
}
private Thread launchFiveSecondFakeThread() {
Thread thread = new Thread() {
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// Ignore
}
}
};
thread.start();
return thread;
}
/**
* java.lang.Thread#sleep(long)
*/
public void test_sleepJ() {
// Note: Not too much we can test here that can be reliably measured.
// Check that basic behavior is about right (with some tolerance)
long stime = System.currentTimeMillis();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
fail("Unexpected InterruptedException was thrown");
}
long ftime = System.currentTimeMillis();
assertTrue("Failed to sleep long enough", (ftime - stime) >= 500);
assertTrue("Failed to wake up early enough", (ftime - stime) <= 1500);
// Check that interrupt works
st = new Thread() {
public void run() {
try {
sleep(1000);
} catch(InterruptedException ie) {
wasInterrupted = true;
}
}
};
st.start();
try {
Thread.sleep(500);
} catch(InterruptedException e) {
fail("Unexpected InterruptedException was thrown");
}
st.interrupt();
try {
Thread.sleep(500);
} catch(InterruptedException e) {
fail("Unexpected InterruptedException was thrown");
}
assertTrue(wasInterrupted);
}
public void test_sleepJI() {
// Note: Not too much we can test here that can be reliably measured.
// Check that basic behavior is about right (with some tolerance)
long stime = System.currentTimeMillis();
try {
Thread.sleep(1000, 99999);
} catch (InterruptedException e) {
fail("Unexpected InterruptedException was thrown");
}
long ftime = System.currentTimeMillis();
assertTrue("Failed to sleep long enough", (ftime - stime) >= 500);
assertTrue("Failed to wake up early enough", (ftime - stime) <= 1500);
// Check that interrupt works
st = new Thread() {
public void run() {
try {
sleep(1000, 9999);
} catch(InterruptedException ie) {
wasInterrupted = true;
}
}
};
st.start();
try {
Thread.sleep(500, 9999);
} catch(InterruptedException e) {
fail("Unexpected InterruptedException was thrown");
}
st.interrupt();
try {
Thread.sleep(500);
} catch(InterruptedException e) {
fail("Unexpected InterruptedException was thrown");
}
assertTrue(wasInterrupted);
}
public void test_yield() {
Counter [] countersNotYeld = new Counter[10];
for(int i = 0; i < 10; i++) {
countersNotYeld[i] = new Counter(false);
}
Counter countersYeld = new Counter(true);
try {
Thread.sleep(1100);
} catch(InterruptedException ie) {}
for(Counter c:countersNotYeld) {
assertTrue(countersYeld.counter == c.counter);
}
}
class Counter extends Thread {
public int counter = 0;
boolean isDoYield = false;
public Counter(boolean isDoYield) {
this.isDoYield = isDoYield;
start();
}
public void run() {
for(int i = 0; i < 1000; i++) {
if(isDoYield)
yield();
counter ++;
}
}
}
public void test_getState() throws InterruptedException {
Thread.State state = Thread.currentThread().getState();
assertNotNull(state);
assertEquals(Thread.State.RUNNABLE, state);
run = true;
final Semaphore sem = new Semaphore(0);
final Object lock = new Object();
Thread th = new Thread() {
@Override
public void run() {
while (!sem.hasQueuedThreads()) {}
sem.release();
// RUNNABLE
while (run) {}
try {
// WAITING
sem.acquire();
} catch (InterruptedException e) {
fail("InterruptedException was thrown.");
}
// BLOCKED
synchronized (lock) {
lock.equals(new Object());
}
synchronized (lock) {
try {
sem.release();
// TIMED_WAITING
lock.wait(Long.MAX_VALUE);
} catch (InterruptedException e) {
// expected
}
}
// TERMINATED upon return
}
};
assertEquals(Thread.State.NEW, th.getState());
th.start();
sem.acquire();
assertEquals(Thread.State.RUNNABLE, th.getState());
run = false;
Thread.sleep(200);
assertEquals(Thread.State.WAITING, th.getState());
synchronized (lock) {
sem.release();
long start = System.currentTimeMillis();
while(start + 1000 > System.currentTimeMillis()) {}
assertEquals(Thread.State.BLOCKED, th.getState());
}
sem.acquire();
synchronized (lock) {
assertEquals(Thread.State.TIMED_WAITING, th.getState());
th.interrupt();
}
th.join(1000);
assertEquals(Thread.State.TERMINATED, th.getState());
}
volatile boolean run;
public void test_holdsLock() {
MonitoredClass monitor = new MonitoredClass();
monitor.enterLocked();
monitor.enterNonLocked();
try {
Thread.holdsLock(null);
fail("NullPointerException was not thrown.");
} catch(NullPointerException npe) {
//expected
}
}
@SuppressWarnings("deprecation")
public void test_stop() {
Thread thread = launchFiveSecondFakeThread();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// Ignore
}
try {
thread.stop();
fail();
} catch (UnsupportedOperationException expected) {
}
}
public void test_start() {
Thread thr = new Thread();
thr.start();
try {
thr.start();
} catch(IllegalThreadStateException itse){
//expected
}
}
@SuppressWarnings("deprecation")
public void test_stopLjava_lang_Throwable_subtest0() {
Thread thread = new Thread() {
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// Ignore
}
}
};
thread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// Ignore
}
try {
thread.stop(new Exception("Oops!"));
fail();
} catch (UnsupportedOperationException expected) {
}
}
@SuppressWarnings("deprecation")
public void test_suspend() {
Thread thread = launchFiveSecondFakeThread();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// Ignore
}
try {
thread.suspend();
fail();
} catch (UnsupportedOperationException expected) {
}
}
Thread st, ct, spinner;
@Override
protected void tearDown() {
try {
if (st != null)
st.interrupt();
} catch (Exception e) {
}
try {
if (spinner != null)
spinner.interrupt();
} catch (Exception e) {
}
try {
if (ct != null)
ct.interrupt();
} catch (Exception e) {
}
try {
spinner = null;
st = null;
ct = null;
FinalizationTester.induceFinalization();
} catch (Exception e) {
}
}
}