blob: a63a6ec263ab1e0cab2818fe449ead0447c4a490 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.qpid.disttest;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import javax.naming.Context;
import org.apache.qpid.disttest.controller.Controller;
import org.apache.qpid.disttest.controller.ResultsForAllTests;
import org.apache.qpid.disttest.controller.config.Config;
import org.apache.qpid.disttest.controller.config.ConfigReader;
import org.apache.qpid.disttest.db.ResultsDbWriter;
import org.apache.qpid.disttest.jms.ControllerJmsDelegate;
import org.apache.qpid.disttest.results.CompositeResultsWriter;
import org.apache.qpid.disttest.results.ResultsCsvWriter;
import org.apache.qpid.disttest.results.ResultsXmlWriter;
import org.apache.qpid.disttest.results.aggregation.Aggregator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ControllerRunner extends AbstractRunner
{
private static final Logger LOGGER = LoggerFactory.getLogger(ControllerRunner.class);
public static final String TEST_CONFIG_PROP = "test-config";
public static final String DISTRIBUTED_PROP = "distributed";
public static final String OUTPUT_DIR_PROP = "outputdir";
public static final String WRITE_TO_DB = "writeToDb";
public static final String RUN_ID = "runId";
public static final String REGISTRATION_TIMEOUT = "registrationTimeout";
public static final String COMMAND_RESPONSE_TIMEOUT = "commandResponseTimeout";
public static final String HILL_CLIMB = "hill-climb";
public static final String HILL_CLIMBER_MAX_NUMBER_OF_RUNS = "hill-climber.max-runs";
public static final String HILL_CLIMBER_START_TARGET_RATE = "hill-climber.start-target-rate";
public static final String HILL_CLIMBER_PRODUCTION_TO_TARGET_RATIO_SUCCESS_THRESHOLD = "hill-climber.production-to-target-ratio-success-threshold";
public static final String HILL_CLIMBER_CONSUMPTION_TO_PRODUCTION_RATIO_SUCCESS_THRESHOLD = "hill-climber.consumption-to-production-ratio-success-threshold";
public static final String HILL_CLIMBER_MINIMUM_DELTA = "hill-climber.minimum-delta";
public static final String HILL_CLIMBER_BIAS = "hill-climber.bias";
private static final String TEST_CONFIG_DEFAULT = "perftests-config.json";
private static final String DISTRIBUTED_DEFAULT = "false";
private static final String OUTPUT_DIR_DEFAULT = ".";
private static final String WRITE_TO_DB_DEFAULT = "false";
private static final String REGISTRATION_TIMEOUT_DEFAULT = String.valueOf(60 * 1000);
private static final String COMMAND_RESPONSE_TIMEOUT_DEFAULT = String.valueOf(120 * 1000);
private static final String HILL_CLIMB_DEFAULT = "false";
private static final String HILL_CLIMBER_MAX_NUMBER_OF_RUNS_DEFAULT = "3";
private static final String HILL_CLIMBER_START_TARGET_RATE_DEFAULT = "1025";
private static final String HILL_CLIMBER_CONSUMPTION_TO_PRODUCTION_RATIO_SUCCESS_THRESHOLD_DEFAULT = "0.95";
private static final String HILL_CLIMBER_PRODUCTION_TO_TARGET_RATIO_SUCCESS_THRESHOLD_DEFAULT = "0.95";
private static final String HILL_CLIMBER_MINIMUM_DELTA_DEFAULT = "1";
private static final String HILL_CLIMBER_BIAS_DEFAULT = "-1";
private final Aggregator _aggregator = new Aggregator();
private final ConfigFileHelper _configFileHelper = new ConfigFileHelper();
private final CompositeResultsWriter _resultsWriter = new CompositeResultsWriter();
public ControllerRunner()
{
getCliOptions().put(TEST_CONFIG_PROP, TEST_CONFIG_DEFAULT);
getCliOptions().put(DISTRIBUTED_PROP, DISTRIBUTED_DEFAULT);
getCliOptions().put(OUTPUT_DIR_PROP, OUTPUT_DIR_DEFAULT);
getCliOptions().put(WRITE_TO_DB, WRITE_TO_DB_DEFAULT);
getCliOptions().put(RUN_ID, null);
getCliOptions().put(REGISTRATION_TIMEOUT, REGISTRATION_TIMEOUT_DEFAULT);
getCliOptions().put(COMMAND_RESPONSE_TIMEOUT, COMMAND_RESPONSE_TIMEOUT_DEFAULT);
getCliOptions().put(HILL_CLIMB, HILL_CLIMB_DEFAULT);
getCliOptions().put(HILL_CLIMBER_MAX_NUMBER_OF_RUNS,
HILL_CLIMBER_MAX_NUMBER_OF_RUNS_DEFAULT);
getCliOptions().put(HILL_CLIMBER_START_TARGET_RATE,
HILL_CLIMBER_START_TARGET_RATE_DEFAULT);
getCliOptions().put(HILL_CLIMBER_PRODUCTION_TO_TARGET_RATIO_SUCCESS_THRESHOLD,
HILL_CLIMBER_PRODUCTION_TO_TARGET_RATIO_SUCCESS_THRESHOLD_DEFAULT);
getCliOptions().put(HILL_CLIMBER_CONSUMPTION_TO_PRODUCTION_RATIO_SUCCESS_THRESHOLD,
HILL_CLIMBER_CONSUMPTION_TO_PRODUCTION_RATIO_SUCCESS_THRESHOLD_DEFAULT);
getCliOptions().put(HILL_CLIMBER_MINIMUM_DELTA,
HILL_CLIMBER_MINIMUM_DELTA_DEFAULT);
getCliOptions().put(HILL_CLIMBER_BIAS,
HILL_CLIMBER_BIAS_DEFAULT);
}
public static void main(String[] args) throws Exception
{
ControllerRunner runner = new ControllerRunner();
runner.parseArgumentsIntoConfig(args);
runner.runController();
}
public void runController() throws Exception
{
Context context = getContext();
setUpResultsWriters();
ControllerJmsDelegate jmsDelegate = new ControllerJmsDelegate(context);
try
{
Controller controller = new Controller(jmsDelegate, getCliOptions());
String testConfigPath = getCliOptions().get(ControllerRunner.TEST_CONFIG_PROP);
List<String> testConfigFiles = _configFileHelper.getTestConfigFiles(testConfigPath);
Collection<ClientRunner> clients = createClientsIfNotDistributed(testConfigFiles);
try
{
runTests(controller, testConfigFiles);
}
finally
{
controller.stopAllRegisteredClients();
awaitClientShutdown(clients);
}
}
finally
{
tearDownResultsWriters();
jmsDelegate.closeConnections();
}
}
private void setUpResultsWriters()
{
setUpResultFileWriters();
setUpResultsDbWriter();
_resultsWriter.begin();
}
private void setUpResultsDbWriter()
{
String writeToDbStr = getCliOptions().get(WRITE_TO_DB);
if(Boolean.valueOf(writeToDbStr))
{
String runId = getCliOptions().get(RUN_ID);
_resultsWriter.addWriter(new ResultsDbWriter(getContext(), runId));
}
}
void setUpResultFileWriters()
{
String outputDirString = getCliOptions().get(ControllerRunner.OUTPUT_DIR_PROP);
File outputDir = new File(outputDirString);
_resultsWriter.addWriter(new ResultsCsvWriter(outputDir));
_resultsWriter.addWriter(new ResultsXmlWriter(outputDir));
}
private void tearDownResultsWriters()
{
_resultsWriter.end();
}
private void runTests(Controller controller, List<String> testConfigFiles)
{
boolean testError = false;
try
{
List<ResultsForAllTests> results = new ArrayList<>();
for (String testConfigFile : testConfigFiles)
{
final Config testConfig = buildTestConfigFrom(testConfigFile);
controller.setConfig(testConfig);
controller.awaitClientRegistrations();
LOGGER.info("Running test : {} ", testConfigFile);
ResultsForAllTests testResult = runTest(controller, testConfigFile);
if (testResult.hasErrors())
{
testError = true;
}
results.add(testResult);
}
}
catch(Exception e)
{
LOGGER.error("Problem running test", e);
throw new DistributedTestException("Problem running tests", e);
}
if (testError)
{
throw new DistributedTestException("One or more tests ended in error");
}
}
private ResultsForAllTests runTest(Controller controller, String testConfigFile)
{
final Config testConfig = buildTestConfigFrom(testConfigFile);
controller.setConfig(testConfig);
ResultsForAllTests rawResultsForAllTests = controller.runAllTests();
ResultsForAllTests resultsForAllTests = _aggregator.aggregateResults(rawResultsForAllTests);
_resultsWriter.writeResults(resultsForAllTests, testConfigFile);
return resultsForAllTests;
}
private Collection<ClientRunner> createClientsIfNotDistributed(final List<String> testConfigFiles)
{
if(!isDistributed())
{
int maxNumberOfClients = 0;
for (String testConfigFile : testConfigFiles)
{
final Config testConfig = buildTestConfigFrom(testConfigFile);
final int numClients = testConfig.getTotalNumberOfClients();
maxNumberOfClients = Math.max(numClients, maxNumberOfClients);
}
//we must create the required test clients, running in single-jvm mode
Collection<ClientRunner> runners = new ArrayList<>(maxNumberOfClients);
for (int i = 1; i <= maxNumberOfClients; i++)
{
ClientRunner clientRunner = new ClientRunner();
clientRunner.setJndiPropertiesFileLocation(getJndiConfig());
clientRunner.runClients();
runners.add(clientRunner);
}
return runners;
}
return Collections.emptyList();
}
private void awaitClientShutdown(final Collection<ClientRunner> clients)
{
for(ClientRunner client: clients)
{
client.awaitShutdown();
}
}
private Config buildTestConfigFrom(String testConfigFile)
{
ConfigReader configReader = new ConfigReader();
Config testConfig;
try
{
testConfig = configReader.getConfigFromFile(testConfigFile);
}
catch (IOException e)
{
throw new DistributedTestException("Exception while loading test config from '" + testConfigFile + "'", e);
}
return testConfig;
}
private boolean isDistributed()
{
return Boolean.valueOf(getCliOptions().get(ControllerRunner.DISTRIBUTED_PROP));
}
}