package uk.ac.uea.threadr.tests;
import static org.junit.Assert.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.atomic.AtomicLong;
import org.junit.Test;
import uk.ac.uea.threadr.ThreadSafety;
import uk.ac.uea.threadr.ThreadSafe;
import uk.ac.uea.threadr.ThreadTest;
import uk.ac.uea.threadr.internal.testing.SafetyTester;
import uk.ac.uea.threadr.tests.references.ReferenceTask;
import uk.ac.uea.threadr.tests.references.ReferenceTest;
import uk.ac.uea.threadr.tests.references.ReferenceUnsafeTask;
import uk.ac.uea.threadr.tests.references.ReferenceVMTask;
/**
* Tests the functionality of the {@link SafetyTester} class for Threadr.
*
* @author Jordan Woerner
*/
@SuppressWarnings("unused")
public final class SafetyTesterTests {
/**
* Tests the thread safety testing mechanism for a variety of cases.
*/
@Test
public final void testTestingOutput() {
SafetyTester tester = new SafetyTester();
assertEquals("Failed thread safe class.", ThreadSafety.THREAD,
tester.testSafety(new ReferenceTask()));
assertEquals("Failed VM safe class.", ThreadSafety.VM,
tester.testSafety(new ReferenceVMTask()));
assertEquals("Failed unsafe test class.", ThreadSafety.SEQUENTIAL,
tester.testSafety(new ReferenceUnsafeTask()));
assertEquals("Failed forced safety test class", ThreadSafety.THREAD,
tester.testSafety(new ForcedSafe()));
assertNotEquals("Failed unsafe complex type checks.",
ThreadSafety.THREAD,
tester.testSafety(new ComplexUnsafeTypes()));
assertEquals("Failed safe complex type checks.", ThreadSafety.THREAD,
tester.testSafety(new ComplexSafeTypes()));
}
/**
* Ensures that the SafetyTester class accepts user written tests
* correctly. Test will fail should anything other than
* {@link ThreadSafety#SEQUENTIAL} be returned.
*/
@Test
public final void testProvidedTests() {
SafetyTester tester = new SafetyTester();
Set<ThreadTest> tests = new HashSet<>();
tests.add(new ReferenceTest());
tester.provideTests(tests);
assertEquals("Incorrect test result returned.",
ThreadSafety.SEQUENTIAL, tester.testSafety(new ReferenceTask()));
}
/**
* This class should be counted as thread safe as the thread safety
* violations within have been marked using the {@link ThreadSafe}
* annotation.
*/
private final static class ForcedSafe {
private int someInt = 50;
@ThreadSafe
private static int someStaticInt = 50;
protected static final int someStaticFinalInt = 50;
@ThreadSafe
public static int someStaticPublicInt = 50;
}
/**
* This class uses complex reference types that are not thread safe.
*/
private final static class ComplexUnsafeTypes {
private static final long serialVersionUID = 1L;
private ArrayList<?> unsafeList = new ArrayList<>();
public long publicLong = 5000000L;
}
/**
* This class also uses complex reference types, however the types are
* thread safe implementations and usages.
*/
private final static class ComplexSafeTypes implements Serializable {
private static final long serialVersionUID = 1L;
private List<?> safeList = Collections.synchronizedList(new ArrayList<>());
public AtomicLong publicLong = new AtomicLong(5000000L);
}
}