package com.yahoo.dtf.junit;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import junit.framework.JUnit4TestAdapter;
import junit.framework.TestCase;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import com.yahoo.dtf.DTFConstants;
import com.yahoo.dtf.DTFNode;
import com.yahoo.dtf.actions.Action;
import com.yahoo.dtf.actions.flowcontrol.Sequence;
import com.yahoo.dtf.actions.share.ShareOperation;
import com.yahoo.dtf.actions.util.EmptyAction;
import com.yahoo.dtf.exception.DTFException;
import com.yahoo.dtf.exception.ParseException;
import com.yahoo.dtf.exception.PropertyException;
import com.yahoo.dtf.share.Share;
import com.yahoo.dtf.share.ShareFactory;
/**
*
* @author rlgomes
*/
public class ShareSuite extends DTFJUnitTest {
@BeforeClass
public static void startUpNode() {
System.setProperty("dtf.node.type", DTFConstants.DTFX_ID);
System.setProperty("dtf.node.name", "dummy");
try {
DTFNode.init();
} catch (DTFException e) {
e.printStackTrace();
TestCase.fail("Unable to initialize DTF teststack.");
}
}
@Test(timeout=600000)
public void createSetAndDestroy() throws DTFException {
ArrayList<String> shares = ShareFactory.getShareNames();
for (int i = 0; i < shares.size(); i++) {
Share share = ShareFactory.getShare(shares.get(i), "TESTSHARE");
share.set(new Sequence());
share.get(false).execute();
ShareOperation.getShares().remove("TESTSHARE");
}
}
@Ignore
private static class SimpleSetter implements Runnable {
private Share share;
private int iterations;
private Throwable failure = null;
public SimpleSetter(Share share, int iterations) throws PropertyException, ParseException {
this.share = share;
this.iterations = iterations;
}
public void run() {
try {
for (long j = 0; j < iterations; j++) {
Sequence sequence = new Sequence();
share.set(sequence);
}
} catch (Throwable t) {
failure = t;
}
}
public Throwable getFailure() {
return failure;
}
}
@Ignore
private static class SimpleGetter implements Runnable {
private Share share;
private String sharename;
private long iterations;
private boolean blockncheck = false;
private Throwable failure = null;
public SimpleGetter(Share share, String sharename, long iterations, boolean blockncheck) {
this.share = share;
this.sharename = sharename;
this.iterations = iterations;
this.blockncheck = blockncheck;
}
public void run() {
try {
for (long j = 0; j < iterations; j++) {
Action action = share.get(blockncheck);
assert (action != null) :
"Share [" + sharename + "] returns nulls! this is not valid";
// no EmptyAction acceptable when blocking.
if ( blockncheck ) {
assert !(action instanceof EmptyAction) :
" when blocking on get you must return an action.";
}
action.execute();
}
} catch (Throwable t) {
failure= t;
}
}
public Throwable getFailure() {
return failure;
}
}
@Test(timeout=600000)
public void concurrentAccess() throws DTFException {
ArrayList<String> shares = ShareFactory.getShareNames();
final int ITERATIONS = getConfig().getPropertyAsInt("iterations", 50000);
for (int i = 0; i < shares.size(); i++) {
ExecutorService exec = Executors.newFixedThreadPool(10);
getLogger().info("Testing [" + shares.get(i) + "]");
final String sharename = shares.get(i);
final Share share = ShareFactory.getShare(sharename, "TESTSHARE");
ArrayList<SimpleSetter> setters = new ArrayList<SimpleSetter>();
ArrayList<SimpleGetter> getters = new ArrayList<SimpleGetter>();
for (int s = 0; s < 5; s++) {
SimpleSetter ss = new SimpleSetter(share,ITERATIONS);
setters.add(ss);
exec.execute(ss);
}
for (int g = 0; g < 5; g++) {
SimpleGetter sg = new SimpleGetter(share,sharename,ITERATIONS,false);
getters.add(sg);
exec.execute(sg);
}
exec.shutdown();
try {
exec.awaitTermination(600000, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
TestCase.fail("Unable to wait for termination of threads.");
break;
}
for (int t = 0; t < setters.size(); t++) {
if ( setters.get(t).getFailure() != null ) {
setters.get(t).getFailure().printStackTrace();
TestCase.fail("failed to execute setter.");
}
}
for (int t = 0; t < getters.size(); t++) {
if ( getters.get(t).getFailure() != null ) {
getters.get(t).getFailure().printStackTrace();
TestCase.fail("failed to execute getter.");
}
}
ShareOperation.getShares().remove("TESTSHARE");
}
}
@Test(timeout=600000)
public void validateBlockingGets() throws DTFException {
ArrayList<String> shares = new ArrayList<String>();
shares.add("queue");
final int ITERATIONS = getConfig().getPropertyAsInt("iterations", 100);
for (int i = 0; i < shares.size(); i++) {
ExecutorService exec = Executors.newFixedThreadPool(10);
getLogger().info("Testing [" + shares.get(i) + "]");
final String sharename = shares.get(i);
final Share share = ShareFactory.getShare(sharename, "TESTSHARE");
ArrayList<SimpleSetter> setters = new ArrayList<SimpleSetter>();
ArrayList<SimpleGetter> getters = new ArrayList<SimpleGetter>();
for (int s = 0; s < 3; s++) {
SimpleSetter ss = new SimpleSetter(share,ITERATIONS);
setters.add(ss);
exec.execute(ss);
}
for (int g = 0; g < 3; g++) {
SimpleGetter sg = new SimpleGetter(share,sharename,ITERATIONS,true);
getters.add(sg);
exec.execute(sg);
}
exec.shutdown();
try {
exec.awaitTermination(600000, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
TestCase.fail("Unable to wait for termination of threads.");
break;
}
for (int t = 0; t < setters.size(); t++) {
if ( setters.get(t).getFailure() != null ) {
setters.get(t).getFailure().printStackTrace();
TestCase.fail("failed to execute setter.");
}
}
for (int t = 0; t < getters.size(); t++) {
if ( getters.get(t).getFailure() != null ) {
getters.get(t).getFailure().printStackTrace();
TestCase.fail("failed to execute getter.");
}
}
ShareOperation.getShares().remove("TESTSHARE");
}
}
public static junit.framework.Test suite() {
return new JUnit4TestAdapter(ShareSuite.class);
}
}