use of runner.config.TestScriptSpecification in project jade-data-repo by DataBiosphere.
the class TestRunner method executeTestConfiguration.
void executeTestConfiguration() throws Exception {
// specify any value overrides in the Helm chart, then deploy
if (!config.server.skipDeployment) {
// modifyHelmValuesAndDeploy();
}
// update any Kubernetes properties specified by the test configuration
if (!config.server.skipKubernetes) {
KubernetesClientUtils.buildKubernetesClientObject(config.server);
modifyKubernetesPostDeployment();
}
// get an instance of the API client per test user
for (TestUserSpecification testUser : config.testUsers) {
ApiClient apiClient = new ApiClient();
apiClient.setBasePath(config.server.uri);
GoogleCredentials userCredential = AuthenticationUtils.getDelegatedUserCredential(testUser);
AccessToken userAccessToken = AuthenticationUtils.getAccessToken(userCredential);
apiClient.setAccessToken(userAccessToken.getTokenValue());
apiClientsForUsers.put(testUser.name, apiClient);
}
// get an instance of each test script class
for (TestScriptSpecification testScriptSpecification : config.testScripts) {
try {
TestScript testScriptInstance = testScriptSpecification.scriptClass.newInstance();
// set the billing account for the test script to use
testScriptInstance.setBillingAccount(config.billingAccount);
// set any parameters specified by the configuration
testScriptInstance.setParameters(testScriptSpecification.parameters);
scripts.add(testScriptInstance);
} catch (IllegalAccessException | InstantiationException niEx) {
throw new IllegalArgumentException("Error calling constructor of TestScript class: " + testScriptSpecification.scriptClass.getName(), niEx);
}
}
// call the setup method of each test script
Exception setupExceptionThrown = callTestScriptSetups();
if (setupExceptionThrown != null) {
// ignore any exceptions thrown by cleanup methods
callTestScriptCleanups();
throw new RuntimeException("Error calling test script setup methods.", setupExceptionThrown);
}
// for each test script
List<ApiClient> apiClientList = new ArrayList<>(apiClientsForUsers.values());
for (int tsCtr = 0; tsCtr < scripts.size(); tsCtr++) {
TestScript testScript = scripts.get(tsCtr);
TestScriptSpecification testScriptSpecification = config.testScripts.get(tsCtr);
// add a description to the user journey threads/results that includes any parameters
String userJourneyDescription = testScriptSpecification.name;
if (testScriptSpecification.parameters != null) {
userJourneyDescription += ": " + String.join(",", testScriptSpecification.parameters);
}
// create a thread pool for running its user journeys
ThreadPoolExecutor threadPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(testScriptSpecification.numberToRunInParallel);
threadPools.add(threadPool);
// kick off the user journey(s), one per thread
List<UserJourneyThread> userJourneyThreads = new ArrayList<>();
for (int ujCtr = 0; ujCtr < testScriptSpecification.totalNumberToRun; ujCtr++) {
ApiClient apiClient = apiClientList.get(ujCtr % apiClientList.size());
userJourneyThreads.add(new UserJourneyThread(testScript, userJourneyDescription, apiClient));
}
// TODO: support different patterns of kicking off user journeys. here they're all queued at
// once
List<Future<UserJourneyResult>> userJourneyFutures = threadPool.invokeAll(userJourneyThreads);
userJourneyFutureLists.add(userJourneyFutures);
}
// wait until all threads either finish or time out
for (int ctr = 0; ctr < scripts.size(); ctr++) {
TestScriptSpecification testScriptSpecification = config.testScripts.get(ctr);
ThreadPoolExecutor threadPool = threadPools.get(ctr);
threadPool.shutdown();
long totalTerminationTime = testScriptSpecification.expectedTimeForEach * testScriptSpecification.totalNumberToRun;
boolean terminatedByItself = threadPool.awaitTermination(totalTerminationTime, testScriptSpecification.expectedTimeForEachUnitObj);
// if the threads didn't finish in the expected time, then send them interrupts
if (!terminatedByItself) {
threadPool.shutdownNow();
}
if (!threadPool.awaitTermination(secondsToWaitForPoolShutdown, TimeUnit.SECONDS)) {
System.out.println("Thread pool for test script " + ctr + " (" + testScriptSpecification.name + ") failed to terminate.");
}
}
// compile the results from all thread pools
for (int ctr = 0; ctr < scripts.size(); ctr++) {
List<Future<UserJourneyResult>> userJourneyFutureList = userJourneyFutureLists.get(ctr);
TestScriptSpecification testScriptSpecification = config.testScripts.get(ctr);
for (Future<UserJourneyResult> userJourneyFuture : userJourneyFutureList) {
UserJourneyResult result = null;
if (userJourneyFuture.isDone())
try {
// user journey thread completed and populated its own return object, which may include
// an exception
result = userJourneyFuture.get();
result.completed = true;
} catch (ExecutionException execEx) {
// user journey thread threw an exception and didn't populate its own return object
result = new UserJourneyResult(testScriptSpecification.name, "");
result.completed = false;
result.exceptionThrown = execEx;
}
else {
// user journey either was never started or got cancelled before it finished
result = new UserJourneyResult(testScriptSpecification.name, "");
result.completed = false;
}
userJourneyResults.add(result);
}
}
// call the cleanup method of each test script
Exception cleanupExceptionThrown = callTestScriptCleanups();
if (cleanupExceptionThrown != null) {
throw new RuntimeException("Error calling test script cleanup methods.", cleanupExceptionThrown);
}
// delete the deployment and restore any Kubernetes settings
if (!config.server.skipDeployment) {
deleteDeployment();
}
if (!config.server.skipKubernetes) {
restoreKubernetesSettings();
}
// cleanup data project
cleanupLeftoverTestData();
}
Aggregations