Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move test timeouts to constants. #367

Merged
merged 2 commits into from Dec 8, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions .travis.yml
Expand Up @@ -6,6 +6,8 @@ jdk:
before_install:
- .travis_scripts/generate_keys.sh $encrypted_026743b97986_key $encrypted_026743b97986_iv
- .travis_scripts/setup_env.sh
script:
- ./mvnw test -Dmaven.javadoc.skip=true -Dtest.travisBuild=true
after_success:
- mvn jacoco:report coveralls:report
- .travis_scripts/javadocs.sh
Expand Down
9 changes: 6 additions & 3 deletions pom.xml
Expand Up @@ -302,9 +302,12 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<trimStackTrace>false</trimStackTrace>
</configuration>
<configuration>
<trimStackTrace>false</trimStackTrace>
<systemPropertyVariables>
<propertyName>test.travisBuild</propertyName>
</systemPropertyVariables>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
Expand Down
Expand Up @@ -21,7 +21,7 @@ public void concurrentTestsExecute()
throws Exception {
final AtomicLong l = new AtomicLong();
scheduleConcurrently(5, t -> l.getAndIncrement());
executeScheduled(5, 1000, TimeUnit.MILLISECONDS);
executeScheduled(5, PARAMETERS.TIMEOUT_SHORT);
assertThat(l.get())
.isEqualTo(5);
}
Expand All @@ -32,15 +32,17 @@ public void concurrentTestsThrowExceptions()
scheduleConcurrently(5, t -> {
throw new IOException("hi");
});
assertThatThrownBy(() -> executeScheduled(5, 1000, TimeUnit.MILLISECONDS))
assertThatThrownBy(() -> executeScheduled(5,
PARAMETERS.TIMEOUT_SHORT))
.isInstanceOf(IOException.class);
}

@Test
public void concurrentTestsTimeout()
throws Exception {
scheduleConcurrently(5, t -> Thread.sleep(10000));
assertThatThrownBy(() -> executeScheduled(5, 1, TimeUnit.MILLISECONDS))
assertThatThrownBy(() -> executeScheduled(5,
PARAMETERS.TIMEOUT_VERY_SHORT))
.isInstanceOf(CancellationException.class);
}

Expand Down
31 changes: 27 additions & 4 deletions test/src/test/java/org/corfudb/AbstractCorfuTest.java
Expand Up @@ -9,6 +9,7 @@
import org.junit.runner.Description;

import java.io.File;
import java.time.Duration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
Expand All @@ -21,6 +22,7 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

import static java.time.temporal.ChronoUnit.MILLIS;
import static org.assertj.core.api.Assertions.assertThat;
import static org.fusesource.jansi.Ansi.ansi;

Expand All @@ -31,26 +33,31 @@ public class AbstractCorfuTest {

public Set<Callable<Object>> scheduledThreads;
public Set<String> temporaryDirectories;

public String testStatus = "";

public static final CorfuTestParameters PARAMETERS =
new CorfuTestParameters();

@Rule
public TestRule watcher = new TestWatcher() {
@Override
protected void succeeded(Description description) {
if (!testStatus.equals("")) {
testStatus = " [" + testStatus + "]";
}
System.out.print(ansi().a("[").fg(Ansi.Color.GREEN).a("PASS").reset().a("]" + testStatus).newline());
System.out.print(ansi().a("[").fg(Ansi.Color.GREEN).a("PASS")
.reset().a("]" + testStatus).newline());
}

@Override
protected void failed(Throwable e, Description description) {
System.out.print(ansi().a("[").fg(Ansi.Color.RED).a("FAIL").reset().a("]").newline());
System.out.print(ansi().a("[").fg(Ansi.Color.RED)
.a("FAIL").reset().a("]").newline());
}

protected void starting(Description description) {
System.out.print(String.format("%-60s", description.getMethodName()));
System.out.print(String.format("%-60s", description
.getMethodName()));
System.out.flush();
}
};
Expand Down Expand Up @@ -148,6 +155,22 @@ public void scheduleConcurrently(int repetitions, CallableConsumer function) {
}
}

/**
* Execute any threads which were scheduled to run.
*
* @param maxConcurrency The maximum amount of concurrency to allow when
* running the threads
* @param duration The maximum length to run the tests before timing
* out.
* @throws Exception Any exception that was thrown by any thread while
* tests were run.
*/
public void executeScheduled(int maxConcurrency, Duration duration)
throws Exception {
executeScheduled(maxConcurrency, duration.toMillis(),
TimeUnit.MILLISECONDS);
}

/**
* Execute any threads which were scheduled to run.
*
Expand Down
95 changes: 95 additions & 0 deletions test/src/test/java/org/corfudb/CorfuTestParameters.java
@@ -0,0 +1,95 @@
package org.corfudb;

import lombok.Getter;

import java.time.Duration;

import static java.time.temporal.ChronoUnit.MILLIS;
import static java.time.temporal.ChronoUnit.MINUTES;
import static java.time.temporal.ChronoUnit.SECONDS;


/** This class contains automatically calculated parameters used for timeouts
* and concurrency throughout the infrastructure.
* Created by mwei on 12/8/16.
*/
public class CorfuTestParameters {
/** A very short timeout, typically in the order of a 100ms.
* You might expect a simple request to timeout in this timeframe.
*/
public final Duration TIMEOUT_VERY_SHORT;

/** A short timeout, typically in the order of 1s.
* You might expect a typical request to timeout in this timeframe.
*/
public final Duration TIMEOUT_SHORT;

/** A normal timeout, typical in the order of 10s.
* Your might expect a request like an IO flush to timeout in
* this timeframe.
*/
public final Duration TIMEOUT_NORMAL;

/** A long timeout, typically in the order of 1m.
* You would expect an entire unit test to timeout in this timeframe.
*/
public final Duration TIMEOUT_LONG;

/** The number of iterations to run for a small test.
* This will be about 100 by default, and should be used for operations
* which perform I/O.
*/
public final int NUM_ITERATIONS_LOW;

/** The number of iterations to run for a large test.
* This will be about 10,000 by default, and should be used for fast
* compute-only operations.
*/
public final int NUM_ITERATIONS_LARGE;

/** Used when the concurrency factor should be only one thread. */
public final int CONCURRENCY_ONE;

/** Used when there should be only two threads for a concurency test. */
public final int CONCURRENCY_TWO;

/** Used when a few threads, on the order of 10 should be used to
* cause the (un)expected behavior */
public final int CONCURRENCY_SOME;

/** Used when many threads, on the order of 100s should be used to
* cause the (un)expected behavior. */
public final int CONCURRENCY_LOTS;

public CorfuTestParameters(){

if (isTravisBuild()) {
System.out.println("Building on travis, increased timeouts, "
+ "shorter tests and reduced concurrency will be used.");
}
// Timeouts
TIMEOUT_VERY_SHORT = isTravisBuild() ? Duration.of(1, SECONDS) :
Duration.of(100, MILLIS);
TIMEOUT_SHORT = isTravisBuild() ? Duration.of(5, SECONDS) :
Duration.of(1, SECONDS);
TIMEOUT_NORMAL = isTravisBuild() ? Duration.of(20, SECONDS) :
Duration.of(10, SECONDS);
TIMEOUT_LONG = isTravisBuild() ? Duration.of(2, MINUTES):
Duration.of(1, MINUTES);

// Iterations
NUM_ITERATIONS_LOW = isTravisBuild() ? 10 : 100;
NUM_ITERATIONS_LARGE = isTravisBuild() ? 1_000 : 10_000;

// Concurrency
CONCURRENCY_ONE = 1;
CONCURRENCY_TWO = 2;
CONCURRENCY_SOME = isTravisBuild() ? 3 : 5;
CONCURRENCY_LOTS = isTravisBuild() ? 25 : 100;
}

@Getter(lazy=true)
private final boolean travisBuild = System.getProperty("test.travisBuild")
!= null && System.getProperty("test.travisBuild").toLowerCase()
.equals("true");
}
45 changes: 23 additions & 22 deletions test/src/test/java/org/corfudb/runtime/collections/FGMapTest.java
Expand Up @@ -65,12 +65,12 @@ public void sizeIsCorrect()
assertThat(testMap)
.isEmpty();

for (int i = 0; i < 100; i++) {
for (int i = 0; i < PARAMETERS.NUM_ITERATIONS_LOW; i++) {
testMap.put(Integer.toString(i), Integer.toString(i));
}

assertThat(testMap)
.hasSize(100);
.hasSize(PARAMETERS.NUM_ITERATIONS_LOW);
}

@Test
Expand All @@ -82,7 +82,7 @@ public void canNestTX()
assertThat(testMap)
.isEmpty();

for (int i = 0; i < 100; i++) {
for (int i = 0; i < PARAMETERS.NUM_ITERATIONS_LOW; i++) {
testMap.put(Integer.toString(i), Integer.toString(i));
}

Expand All @@ -92,9 +92,9 @@ public void canNestTX()
getRuntime().getObjectsView().TXEnd();

assertThat(testMap.size())
.isEqualTo(101);
.isEqualTo(PARAMETERS.NUM_ITERATIONS_LOW + 1);
assertThat(testMap.get("size"))
.isEqualTo("100");
.isEqualTo(Integer.toString(PARAMETERS.NUM_ITERATIONS_LOW));
}

@Test
Expand All @@ -106,12 +106,12 @@ public void canClear()
assertThat(testMap)
.isEmpty();

for (int i = 0; i < 100; i++) {
for (int i = 0; i < PARAMETERS.NUM_ITERATIONS_LOW; i++) {
testMap.put(Integer.toString(i), Integer.toString(i));
}

assertThat(testMap)
.hasSize(100);
.hasSize(PARAMETERS.NUM_ITERATIONS_LOW);

testMap.put("a", "b");
testMap.clear();
Expand All @@ -129,7 +129,7 @@ public void canClearInTX()
.isEmpty();

getRuntime().getObjectsView().TXBegin();
for (int i = 0; i < 100; i++) {
for (int i = 0; i < PARAMETERS.NUM_ITERATIONS_LOW; i++) {
testMap.put(Integer.toString(i), Integer.toString(i));
}
testMap.clear();
Expand All @@ -145,21 +145,22 @@ public void canClearInTX()
@SuppressWarnings("unchecked")
public void canVaryBucketCount()
throws Exception {
FGMap<String, String> testMap = getDefaultRuntime().getObjectsView().open("hello", FGMap.class, 101);
FGMap<String, String> testMap = getDefaultRuntime().getObjectsView().open("hello", FGMap.class,
PARAMETERS.NUM_ITERATIONS_LOW + 1);
testMap.clear();
assertThat(testMap)
.isEmpty();

for (int i = 0; i < 100; i++) {
for (int i = 0; i < PARAMETERS.NUM_ITERATIONS_LOW; i++) {
testMap.put(Integer.toString(i), Integer.toString(i));
}

FGMap<String, String> testMap2 = getRuntime().getObjectsView().open("hello", FGMap.class,
EnumSet.of(ObjectOpenOptions.NO_CACHE));
assertThat(testMap2)
.hasSize(100);
.hasSize(PARAMETERS.NUM_ITERATIONS_LOW);
assertThat(testMap2.getNumBuckets())
.isEqualTo(101);
.isEqualTo(PARAMETERS.NUM_ITERATIONS_LOW + 1);
}


Expand All @@ -171,8 +172,8 @@ public void loadsFollowedByGetsConcurrent()

Map<String, String> testMap = getRuntime().getObjectsView().open(UUID.randomUUID(), FGMap.class);

final int num_threads = 5;
final int num_records = 50;
final int num_threads = PARAMETERS.CONCURRENCY_SOME;
final int num_records = PARAMETERS.NUM_ITERATIONS_LOW;
testMap.clear();

scheduleConcurrently(num_threads, threadNumber -> {
Expand All @@ -184,7 +185,7 @@ public void loadsFollowedByGetsConcurrent()
});

long startTime = System.currentTimeMillis();
executeScheduled(num_threads, 30, TimeUnit.SECONDS);
executeScheduled(num_threads, PARAMETERS.TIMEOUT_LONG);
calculateRequestsPerSecond("WPS", num_records * num_threads, startTime);

scheduleConcurrently(num_threads, threadNumber -> {
Expand All @@ -196,7 +197,7 @@ public void loadsFollowedByGetsConcurrent()
});

startTime = System.currentTimeMillis();
executeScheduled(num_threads, 30, TimeUnit.SECONDS);
executeScheduled(num_threads, PARAMETERS.TIMEOUT_LONG);
calculateRequestsPerSecond("RPS", num_records * num_threads, startTime);
}

Expand All @@ -208,8 +209,8 @@ public void abortRateIsLowForSimpleTX()

Map<String, String> testMap = getRuntime().getObjectsView().open(UUID.randomUUID(), FGMap.class);

final int num_threads = 5;
final int num_records = 100;
final int num_threads = PARAMETERS.CONCURRENCY_SOME;
final int num_records = PARAMETERS.NUM_ITERATIONS_LOW;
AtomicInteger aborts = new AtomicInteger();
testMap.clear();

Expand All @@ -228,7 +229,7 @@ public void abortRateIsLowForSimpleTX()
});

long startTime = System.currentTimeMillis();
executeScheduled(num_threads, 30, TimeUnit.SECONDS);
executeScheduled(num_threads, PARAMETERS.TIMEOUT_LONG);
calculateRequestsPerSecond("TPS", num_records * num_threads, startTime);

calculateAbortRate(aborts.get(), num_records * num_threads);
Expand All @@ -243,8 +244,8 @@ public void checkClearCalls()
Map<String, String> testMap = getRuntime().getObjectsView()
.open(UUID.randomUUID(), FGMap.class, 20);

final int num_threads = 5;
final int num_records = 100;
final int num_threads = PARAMETERS.CONCURRENCY_SOME;
final int num_records = PARAMETERS.NUM_ITERATIONS_LOW;

scheduleConcurrently(num_threads, threadNumber -> {
int base = threadNumber * num_records;
Expand All @@ -256,7 +257,7 @@ public void checkClearCalls()
});

long startTime = System.currentTimeMillis();
executeScheduled(num_threads, 30, TimeUnit.SECONDS);
executeScheduled(num_threads, PARAMETERS.TIMEOUT_LONG);
calculateRequestsPerSecond("OPS", num_records * num_threads, startTime);
}
}