blob: 20a2d3205140ef311a7bad36d55378349c17aea0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0, which accompanies this distribution
* and is available at http://www.eclipse.org/legal/epl-v10.html.
*
* Contributors:
* Oracle - initial API and implementation
******************************************************************************/
package org.eclipse.jpt.utility.tests.internal;
import junit.framework.TestCase;
import org.eclipse.jpt.utility.internal.SynchronizedInt;
@SuppressWarnings("nls")
public class SynchronizedIntTests extends TestCase {
private volatile SynchronizedInt si;
private volatile boolean exCaught;
private volatile boolean timeoutOccurred;
volatile int value = 7;
private volatile long startTime;
private volatile long endTime;
private volatile int sIntValue;
public SynchronizedIntTests(String name) {
super(name);
}
@Override
protected void setUp() throws Exception {
super.setUp();
this.si = new SynchronizedInt();
this.exCaught = false;
this.timeoutOccurred = false;
this.startTime = 0;
this.endTime = 0;
this.sIntValue = 0;
}
@Override
protected void tearDown() throws Exception {
TestTools.clear(this);
super.tearDown();
}
public void testGetValue() throws Exception {
assertEquals(0, this.si.getValue());
}
public void testEqualsInt() throws Exception {
assertTrue(this.si.equals(0));
this.si.setValue(this.value);
assertTrue(this.si.equals(7));
}
public void testNotEqualsInt() throws Exception {
assertTrue(this.si.notEquals(7));
this.si.setValue(this.value);
assertTrue(this.si.notEquals(0));
}
public void testIsZero() throws Exception {
assertTrue(this.si.isZero());
this.si.setValue(this.value);
assertFalse(this.si.isZero());
}
public void testIsNotZero() throws Exception {
assertFalse(this.si.isNotZero());
this.si.setValue(this.value);
assertTrue(this.si.isNotZero());
}
public void testIsGreaterThan() throws Exception {
assertTrue(this.si.isGreaterThan(-1));
assertFalse(this.si.isGreaterThan(0));
assertFalse(this.si.isGreaterThan(1));
this.si.setValue(this.value);
assertTrue(this.si.isGreaterThan(-1));
assertFalse(this.si.isGreaterThan(7));
assertFalse(this.si.isGreaterThan(8));
}
public void testIsGreaterThanOrEqual() throws Exception {
assertTrue(this.si.isGreaterThanOrEqual(-1));
assertTrue(this.si.isGreaterThanOrEqual(0));
assertFalse(this.si.isGreaterThanOrEqual(1));
this.si.setValue(this.value);
assertTrue(this.si.isGreaterThanOrEqual(-1));
assertTrue(this.si.isGreaterThanOrEqual(7));
assertFalse(this.si.isGreaterThanOrEqual(8));
}
public void testIsLessThan() throws Exception {
assertFalse(this.si.isLessThan(-1));
assertFalse(this.si.isLessThan(0));
assertTrue(this.si.isLessThan(1));
this.si.setValue(this.value);
assertFalse(this.si.isLessThan(-1));
assertFalse(this.si.isLessThan(7));
assertTrue(this.si.isLessThan(8));
}
public void testIsLessThanOrEqual() throws Exception {
assertFalse(this.si.isLessThanOrEqual(-1));
assertTrue(this.si.isLessThanOrEqual(0));
assertTrue(this.si.isLessThanOrEqual(1));
this.si.setValue(this.value);
assertFalse(this.si.isLessThanOrEqual(-1));
assertTrue(this.si.isLessThanOrEqual(7));
assertTrue(this.si.isLessThanOrEqual(8));
}
public void testIsPositive() throws Exception {
assertFalse(this.si.isPositive());
this.si.setValue(this.value);
assertTrue(this.si.isPositive());
this.si.setValue(-3);
assertFalse(this.si.isPositive());
}
public void testIsNotPositive() throws Exception {
assertTrue(this.si.isNotPositive());
this.si.setValue(this.value);
assertFalse(this.si.isNotPositive());
this.si.setValue(-3);
assertTrue(this.si.isNotPositive());
}
public void testIsNegative() throws Exception {
assertFalse(this.si.isNegative());
this.si.setValue(this.value);
assertFalse(this.si.isNegative());
this.si.setValue(-3);
assertTrue(this.si.isNegative());
}
public void testIsNotNegative() throws Exception {
assertTrue(this.si.isNotNegative());
this.si.setValue(this.value);
assertTrue(this.si.isNotNegative());
this.si.setValue(-3);
assertFalse(this.si.isNotNegative());
}
public void testSetValue() throws Exception {
this.si.setValue(0);
assertEquals(0, this.si.getValue());
assertFalse(this.si.isNotZero());
assertTrue(this.si.isZero());
this.si.setValue(this.value);
assertEquals(this.value, this.si.getValue());
assertTrue(this.si.isNotZero());
assertFalse(this.si.isZero());
}
public void testAbs() throws Exception {
assertEquals(0, this.si.abs());
assertEquals(0, this.si.getValue());
this.si.setValue(this.value);
assertEquals(this.value, this.si.abs());
assertEquals(this.value, this.si.getValue());
this.si.setValue(-this.value);
assertEquals(this.value, this.si.abs());
assertEquals(this.value, this.si.getValue());
}
public void testNeg() throws Exception {
assertEquals(0, this.si.neg());
assertEquals(0, this.si.getValue());
this.si.setValue(this.value);
assertEquals(-this.value, this.si.neg());
assertEquals(-this.value, this.si.getValue());
this.si.setValue(-this.value);
assertEquals(this.value, this.si.neg());
assertEquals(this.value, this.si.getValue());
}
public void testSetZero() throws Exception {
this.si.setZero();
assertEquals(0, this.si.getValue());
assertFalse(this.si.isNotZero());
assertTrue(this.si.isZero());
}
public void testGetMutexThis() throws Exception {
assertSame(this.si, this.si.getMutex());
}
public void testEquals() throws Exception {
this.si.setValue(0);
SynchronizedInt so2 = new SynchronizedInt(0);
assertEquals(this.si, so2);
this.si.setValue(this.value);
assertFalse(this.si.equals(so2));
so2.setValue(this.value);
assertEquals(this.si, so2);
}
public void testHashCode() {
this.si.setValue(this.value);
assertEquals(this.value, this.si.hashCode());
this.si.setValue(0);
assertEquals(0, this.si.hashCode());
}
/**
* t2 will wait indefinitely until t1 sets the value to 0
*/
public void testWaitUntilZero() throws Exception {
this.verifyWaitUntilZero(0);
// no timeout occurs...
assertFalse(this.timeoutOccurred);
// ...and the value should be set to 0 by t2
assertEquals(0, this.si.getValue());
// make a reasonable guess about how long t2 took
long time = this.elapsedTime();
assertTrue("t2 finished a bit early (expected value should be > 150): " + time, time > 150);
}
/**
* t2 will time out waiting for t1 to set the value to 0
*/
public void testWaitUntilZeroTimeout() throws Exception {
this.verifyWaitUntilZero(20);
// timeout occurs...
assertTrue(this.timeoutOccurred);
// ...and the value will eventually be set to 0 by t1
assertEquals(0, this.si.getValue());
// make a reasonable guess about how long t2 took
long time = this.elapsedTime();
assertTrue("t2 finished a bit late (expected value should be < 150): " + time, time < 150);
}
private void verifyWaitUntilZero(long t2Timeout) throws Exception {
this.executeThreads(this.buildSetZeroCommand(), this.buildWaitUntilZeroCommand(t2Timeout));
}
/**
* t2 will wait indefinitely until t1 sets the value to 0;
* then t2 will set the value to 7
*/
public void testWaitToSetValue() throws Exception {
this.verifyWaitToSetValue(0);
// no timeout occurs...
assertFalse(this.timeoutOccurred);
// ...and the value should be set to an object by t2
assertTrue(this.si.isNotZero());
// make a reasonable guess about how long t2 took
long time = this.elapsedTime();
assertTrue("t2 finished a bit early (expected value should be > 150): " + time, time > 150);
}
/**
* t2 will time out waiting for t1 to set the value to 0
*/
public void testWaitToSetValueTimeout() throws Exception {
this.verifyWaitToSetValue(20);
// timeout occurs...
assertTrue(this.timeoutOccurred);
// ...and the value will eventually be set to null by t1
assertTrue(this.si.isZero());
// make a reasonable guess about how long t2 took
long time = this.elapsedTime();
assertTrue("t2 finished a bit late (expected value should be < 150): " + time, time < 150);
}
private void verifyWaitToSetValue(long t2Timeout) throws Exception {
this.executeThreads(this.buildSetZeroCommand(), this.buildWaitToSetValueCommand(t2Timeout));
}
/**
* t2 will wait until t1 is finished "initializing" the value;
* then t2 will get the newly-initialized value (42)
*/
public void testExecute() throws Exception {
this.si.setValue(0);
Runnable r1 = this.buildRunnable(this.buildInitializeValueCommand(), this.si, 0);
// give t1 a head start of 100 ms
Runnable r2 = this.buildRunnable(this.buildGetValueCommand(), this.si, 100);
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()) {
Thread.sleep(50);
}
assertFalse(this.exCaught);
assertEquals(42, this.si.getValue());
assertEquals(42, this.sIntValue);
// make a reasonable guess about how long t2 took
long time = this.elapsedTime();
assertTrue("t2 finished a bit early (expected value should be > 100): " + time, time > 300);
}
private void executeThreads(Command t1Command, Command t2Command) throws Exception {
this.si.setValue(this.value);
Runnable r1 = this.buildRunnable(t1Command, this.si, 200);
Runnable r2 = this.buildRunnable(t2Command, this.si, 0);
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()) {
Thread.sleep(50);
}
assertFalse(this.exCaught);
}
private Command buildSetZeroCommand() {
return new Command() {
public void execute(SynchronizedInt sInt) {
sInt.setZero();
}
};
}
private Command buildWaitUntilZeroCommand(final long timeout) {
return new Command() {
public void execute(SynchronizedInt sInt) throws Exception {
SynchronizedIntTests.this.setStartTime(System.currentTimeMillis());
SynchronizedIntTests.this.setTimeoutOccurred( ! sInt.waitUntilZero(timeout));
SynchronizedIntTests.this.setEndTime(System.currentTimeMillis());
}
};
}
private Command buildWaitToSetValueCommand(final long timeout) {
return new Command() {
public void execute(SynchronizedInt sInt) throws Exception {
SynchronizedIntTests.this.setStartTime(System.currentTimeMillis());
SynchronizedIntTests.this.setTimeoutOccurred( ! sInt.waitToSetValue(SynchronizedIntTests.this.value, timeout));
SynchronizedIntTests.this.setEndTime(System.currentTimeMillis());
}
};
}
private Command buildInitializeValueCommand() {
return new Command() {
public void execute(final SynchronizedInt sInt) throws Exception {
sInt.execute(
new org.eclipse.jpt.utility.Command() {
public void execute() {
// pretend to perform some long initialization process
try {
Thread.sleep(500);
} catch (Exception ex) {
SynchronizedIntTests.this.setExCaught(true);
}
sInt.setValue(42);
}
}
);
}
};
}
private Command buildGetValueCommand() {
return new Command() {
public void execute(SynchronizedInt sInt) throws Exception {
SynchronizedIntTests.this.setStartTime(System.currentTimeMillis());
SynchronizedIntTests.this.setSOValue(sInt.getValue());
SynchronizedIntTests.this.setEndTime(System.currentTimeMillis());
}
};
}
private Runnable buildRunnable(final Command command, final SynchronizedInt sInt, final long sleep) {
return new Runnable() {
public void run() {
try {
if (sleep != 0) {
Thread.sleep(sleep);
}
command.execute(sInt);
} catch (Exception ex) {
SynchronizedIntTests.this.setExCaught(true);
}
}
};
}
void setExCaught(boolean exCaught) {
this.exCaught = exCaught;
}
void setTimeoutOccurred(boolean timeoutOccurred) {
this.timeoutOccurred = timeoutOccurred;
}
void setStartTime(long startTime) {
this.startTime = startTime;
}
void setEndTime(long endTime) {
this.endTime = endTime;
}
private long elapsedTime() {
return this.endTime - this.startTime;
}
void setSOValue(int sIntValue) {
this.sIntValue = sIntValue;
}
// ********** Command interface **********
private interface Command {
void execute(SynchronizedInt sInt) throws Exception;
}
}