mirror of https://github.com/apache/jclouds.git
Merge pull request #260 from aledsage/Issue-763-More-Testing
Issue 763: more testing
This commit is contained in:
commit
51e2b40aa9
|
@ -25,6 +25,10 @@ import static org.easymock.EasyMock.verify;
|
||||||
import static org.jclouds.scriptbuilder.domain.Statements.exec;
|
import static org.jclouds.scriptbuilder.domain.Statements.exec;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.easymock.IAnswer;
|
||||||
import org.jclouds.Constants;
|
import org.jclouds.Constants;
|
||||||
import org.jclouds.compute.domain.ExecResponse;
|
import org.jclouds.compute.domain.ExecResponse;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
@ -36,6 +40,7 @@ import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
|
||||||
import org.jclouds.concurrent.MoreExecutors;
|
import org.jclouds.concurrent.MoreExecutors;
|
||||||
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||||
import org.jclouds.domain.LoginCredentials;
|
import org.jclouds.domain.LoginCredentials;
|
||||||
|
import org.jclouds.predicates.RetryablePredicateTest;
|
||||||
import org.jclouds.scriptbuilder.InitBuilder;
|
import org.jclouds.scriptbuilder.InitBuilder;
|
||||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||||
import org.jclouds.scriptbuilder.domain.Statement;
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
|
@ -43,6 +48,7 @@ import org.jclouds.ssh.SshClient;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Functions;
|
import com.google.common.base.Functions;
|
||||||
|
import com.google.common.base.Stopwatch;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
|
@ -99,6 +105,37 @@ public class RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDefault() {
|
public void testDefault() {
|
||||||
|
runDefaults(null, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRepeatedlyChecksIfInitScriptCompleted() {
|
||||||
|
final List<Long> callTimes = new ArrayList<Long>();
|
||||||
|
final int succeedOnAttempt = 3;
|
||||||
|
final Stopwatch stopwatch = new Stopwatch();
|
||||||
|
stopwatch.start();
|
||||||
|
|
||||||
|
IAnswer<ExecResponse> answerForScriptStatus = new IAnswer<ExecResponse>() {
|
||||||
|
private int count = 0;
|
||||||
|
@Override
|
||||||
|
public ExecResponse answer() throws Throwable {
|
||||||
|
callTimes.add(stopwatch.elapsedMillis());
|
||||||
|
String stdout = (++count < succeedOnAttempt) ? "someresult" : "";
|
||||||
|
return new ExecResponse(stdout, "", 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
runDefaults(answerForScriptStatus, succeedOnAttempt);
|
||||||
|
|
||||||
|
// Expect checking-status to be called repeatedly, until process had finished
|
||||||
|
RetryablePredicateTest.assertCallTimes(callTimes, 0, 500, (int)(500+(500*1.5)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param answerForScriptStatus Answer to use for `jclouds-script-0 status`, or null for default of succeed immediately
|
||||||
|
* @param timesForScriptStatus Num times to expect call for `jclouds-script-0 status`; ignored if answer is null
|
||||||
|
*/
|
||||||
|
private void runDefaults(IAnswer<ExecResponse> answerForScriptStatus, int timesForScriptStatus) {
|
||||||
Statement command = exec("doFoo");
|
Statement command = exec("doFoo");
|
||||||
NodeMetadata node = new NodeMetadataBuilder().ids("id").state(NodeState.RUNNING).credentials(
|
NodeMetadata node = new NodeMetadataBuilder().ids("id").state(NodeState.RUNNING).credentials(
|
||||||
new LoginCredentials("tester", "testpassword!", null, false)).build();
|
new LoginCredentials("tester", "testpassword!", null, false)).build();
|
||||||
|
@ -124,7 +161,11 @@ public class RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest {
|
||||||
expect(sshClient.exec("sudo ./jclouds-script-0 start")).andReturn(new ExecResponse("", "", 0));
|
expect(sshClient.exec("sudo ./jclouds-script-0 start")).andReturn(new ExecResponse("", "", 0));
|
||||||
|
|
||||||
// signal the command completed
|
// signal the command completed
|
||||||
expect(sshClient.exec("./jclouds-script-0 status")).andReturn(new ExecResponse("", "", 1));
|
if (answerForScriptStatus == null) {
|
||||||
|
expect(sshClient.exec("./jclouds-script-0 status")).andReturn(new ExecResponse("", "", 1)).times(1);
|
||||||
|
} else {
|
||||||
|
expect(sshClient.exec("./jclouds-script-0 status")).andAnswer(answerForScriptStatus).times(timesForScriptStatus);
|
||||||
|
}
|
||||||
expect(sshClient.exec("./jclouds-script-0 tail")).andReturn(new ExecResponse("out", "", 0));
|
expect(sshClient.exec("./jclouds-script-0 tail")).andReturn(new ExecResponse("out", "", 0));
|
||||||
expect(sshClient.exec("./jclouds-script-0 tailerr")).andReturn(new ExecResponse("err", "", 0));
|
expect(sshClient.exec("./jclouds-script-0 tailerr")).andReturn(new ExecResponse("err", "", 0));
|
||||||
|
|
||||||
|
@ -242,4 +283,5 @@ public class RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest {
|
||||||
|
|
||||||
verify(sshClient);
|
verify(sshClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,13 +18,15 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.predicates;
|
package org.jclouds.predicates;
|
||||||
|
|
||||||
|
import static org.testng.Assert.fail;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import com.google.common.base.Joiner;
|
|
||||||
import org.testng.Assert;
|
import org.testng.Assert;
|
||||||
import org.testng.annotations.BeforeMethod;
|
import org.testng.annotations.BeforeMethod;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
@ -33,9 +35,6 @@ import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
import com.google.common.base.Stopwatch;
|
import com.google.common.base.Stopwatch;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import org.testng.collections.Lists;
|
|
||||||
|
|
||||||
import static org.testng.Assert.fail;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -46,6 +45,9 @@ public class RetryablePredicateTest {
|
||||||
// Grace must be reasonably big; Thread.sleep can take a bit longer to wake up sometimes...
|
// Grace must be reasonably big; Thread.sleep can take a bit longer to wake up sometimes...
|
||||||
public static int SLOW_BUILD_SERVER_GRACE = 250;
|
public static int SLOW_BUILD_SERVER_GRACE = 250;
|
||||||
|
|
||||||
|
// Sometimes returns sooner than timer would predict (e.g. observed 2999ms, when expected 3000ms)
|
||||||
|
public static int EARLY_RETURN_GRACE = 10;
|
||||||
|
|
||||||
private Stopwatch stopwatch;
|
private Stopwatch stopwatch;
|
||||||
|
|
||||||
@BeforeMethod
|
@BeforeMethod
|
||||||
|
@ -123,7 +125,7 @@ public class RetryablePredicateTest {
|
||||||
stopwatch.start();
|
stopwatch.start();
|
||||||
predicate.apply("");
|
predicate.apply("");
|
||||||
long duration = stopwatch.elapsedMillis();
|
long duration = stopwatch.elapsedMillis();
|
||||||
assertOrdered(2998, duration, 3000+SLOW_BUILD_SERVER_GRACE);
|
assertOrdered(3000-EARLY_RETURN_GRACE, duration, 3000+SLOW_BUILD_SERVER_GRACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -137,8 +139,8 @@ public class RetryablePredicateTest {
|
||||||
predicate.apply("");
|
predicate.apply("");
|
||||||
long duration = stopwatch.elapsedMillis();
|
long duration = stopwatch.elapsedMillis();
|
||||||
|
|
||||||
assertOrdered(2500, duration, 2500+SLOW_BUILD_SERVER_GRACE);
|
assertOrdered(2500-EARLY_RETURN_GRACE, duration, 2500+SLOW_BUILD_SERVER_GRACE);
|
||||||
assertCallFrequency(rawPredicate.callTimes, 0, 1000, 1000+1500);
|
assertCallTimes(rawPredicate.callTimes, 0, 1000, 1000+1500);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -153,8 +155,8 @@ public class RetryablePredicateTest {
|
||||||
predicate.apply("");
|
predicate.apply("");
|
||||||
long duration = stopwatch.elapsedMillis();
|
long duration = stopwatch.elapsedMillis();
|
||||||
|
|
||||||
assertOrdered(2000, duration, 2000+SLOW_BUILD_SERVER_GRACE);
|
assertOrdered(2000-EARLY_RETURN_GRACE, duration, 2000+SLOW_BUILD_SERVER_GRACE);
|
||||||
assertCallFrequency(rawPredicate.callTimes, 0, 1000, 2000);
|
assertCallTimes(rawPredicate.callTimes, 0, 1000, 2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class RepeatedAttemptsPredicate implements Predicate<String> {
|
private static class RepeatedAttemptsPredicate implements Predicate<String> {
|
||||||
|
@ -175,27 +177,21 @@ public class RetryablePredicateTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertCallFrequency(List<Long> actual, Integer... expected) {
|
@Test(enabled=false) // not a test, but picked up as such because public
|
||||||
|
public static void assertCallTimes(List<Long> actual, Integer... expected) {
|
||||||
Assert.assertEquals(actual.size(), expected.length);
|
Assert.assertEquals(actual.size(), expected.length);
|
||||||
for (int i = 0; i < expected.length; i++) {
|
for (int i = 0; i < expected.length; i++) {
|
||||||
long callTime = actual.get(i);
|
long callTime = actual.get(i);
|
||||||
assertOrdered(expected[i], callTime, expected[i]+SLOW_BUILD_SERVER_GRACE);
|
assertOrdered(expected[i]-EARLY_RETURN_GRACE, callTime, expected[i]+SLOW_BUILD_SERVER_GRACE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertOrdered(long... values) {
|
private static void assertOrdered(long... values) {
|
||||||
long prevVal = values[0];
|
long prevVal = values[0];
|
||||||
for (long val : values) {
|
for (long val : values) {
|
||||||
if (val < prevVal) {
|
if (val < prevVal) {
|
||||||
fail(String.format("%s should be ordered", asString(values)));
|
fail(String.format("%s should be ordered", Arrays.toString(values)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String asString(long... values) {
|
|
||||||
List<Long> result = Lists.newArrayList(values.length);
|
|
||||||
for(long element : values) result.add(element);
|
|
||||||
|
|
||||||
return "[" + Joiner.on(", ").join(result) + "]";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue