/**
* Copyright 2011-2012 Akiban Technologies, 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 com.persistit.unit;
import static com.persistit.util.ThreadSequencer.addSchedule;
import static com.persistit.util.ThreadSequencer.allocate;
import static com.persistit.util.ThreadSequencer.array;
import static com.persistit.util.ThreadSequencer.disableSequencer;
import static com.persistit.util.ThreadSequencer.enableSequencer;
import static com.persistit.util.ThreadSequencer.sequence;
import static com.persistit.util.ThreadSequencer.sequencerHistory;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import com.persistit.util.Debug;
public class ThreadSequencerTest {
final static int A = allocate("A");
final static int B = allocate("B");
final static int C = allocate("C");
final static int D = allocate("D");
final static int E = allocate("E");
final static int F = allocate("F");
final static int X = allocate("X");
@Test
public void sequenceTwoThreads() throws Exception {
enableSequencer(true);
addSchedule(array(A, B, C), array(A));
addSchedule(array(F, B, C), array(B));
addSchedule(array(F, C, D), array(C));
addSchedule(array(F, D, E), array(D));
addSchedule(array(E, X), array(X, E, F));
final StringBuilder sb = new StringBuilder();
final Runnable r1 = new Runnable() {
@Override
public void run() {
Debug.debugPause(0.2f, 10);
sequence(C);
sb.append("C");
Debug.debugPause(0.2f, 10);
sequence(E);
sb.append("E");
Debug.debugPause(0.2f, 10);
}
};
final Runnable r2 = new Runnable() {
@Override
public void run() {
Debug.debugPause(0.2f, 10);
sequence(B);
sb.append("B");
Debug.debugPause(0.2f, 10);
sequence(D);
sb.append("D");
Debug.debugPause(0.2f, 10);
sequence(X);
}
};
for (int count = 0; count < 10; count++) {
sb.setLength(0);
final Thread t1 = new Thread(r1);
final Thread t2 = new Thread(r2);
t1.setDaemon(true);
t2.setDaemon(true);
t1.start();
t2.start();
Thread.sleep(100);
sb.append("A");
sequence(A);
sequence(F);
t1.join(1000);
t2.join(1000);
assertTrue(!t1.isAlive());
assertTrue(!t2.isAlive());
assertEquals("ABCDE", sb.toString());
final String history = sequencerHistory();
/*
* The history varies, and testing for validity is complicated; The
* ABCDE test confirms correct execution order
*/
assertTrue(history.contains("+A"));
}
disableSequencer();
}
}