com.mnxfst.testing.handler.exec.client.PTestPlanExecutorClient.java Source code

Java tutorial

Introduction

Here is the source code for com.mnxfst.testing.handler.exec.client.PTestPlanExecutorClient.java

Source

/*
 *  The ptest framework provides you with a performance test utility
 *  Copyright (C) 2012  Christian Kreutzfeldt <mnxfst@googlemail.com>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

package com.mnxfst.testing.handler.exec.client;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.apache.commons.io.IOUtils;
import org.apache.http.NameValuePair;

import com.mnxfst.testing.handler.exec.exception.InvalidConfigurationException;
import com.mnxfst.testing.server.cli.CommandLineOption;
import com.mnxfst.testing.server.cli.CommandLineProcessor;

/**
 * @author mnxfst
 * @since 08.05.2012
 */
public class PTestPlanExecutorClient {

    public static final String CMD_OPT_MODE_EXECUTE = "execute";
    public static final String CMD_OPT_MODE_EXECUTE_SHORT = "exec";
    public static final String CMD_OPT_THREADS = "threads";
    public static final String CMD_OPT_THREADS_SHORT = "t";
    public static final String CMD_OPT_RECURRENCES = "recurrences";
    public static final String CMD_OPT_RECURRENCES_SHORT = "r";
    public static final String CMD_OPT_RECURRENCE_TYPE = "recurrenceType";
    public static final String CMD_OPT_RECURRENCE_TYPE_SHORT = "rt";
    public static final String CMD_OPT_TESTPLAN = "testPlan";
    public static final String CMD_OPT_TESTPLAN_SHORT = "tp";
    public static final String CMD_OPT_PTEST_SERVER_HOSTS = "ptestHosts";
    public static final String CMD_OPT_PTEST_SERVER_HOSTS_SHORT = "h";
    public static final String CMD_OPT_PTEST_SERVER_PORT = "ptestPort";
    public static final String CMD_OPT_PTEST_SERVER_PORT_SHORT = "p";

    public static final String CLI_VALUE_MAP_KEY_EXECUTE = "executeMode";
    public static final String CLI_VALUE_MAP_KEY_THREADS = "threads";
    public static final String CLI_VALUE_MAP_KEY_RECURRENCES = "recurrences";
    public static final String CLI_VALUE_MAP_KEY_RECURRENCE_TYPE = "recurrenceType";
    public static final String CLI_VALUE_MAP_KEY_TESTPLAN = "testplan";
    public static final String CLI_VALUE_MAP_KEY_SERVER_HOSTS = "serverHosts";
    public static final String CLI_VALUE_MAP_KEY_SERVER_PORT = "serverPort";

    public static final String REQUEST_PARAMETER_EXECUTE = "execute";
    public static final String REQUEST_PARAMETER_THREADS = "threads";
    public static final String REQUEST_PARAMETER_RECURRENCES = "recurrences";
    public static final String REQUEST_PARAMETER_RECURRENCE_TYPE = "recurrencetype";
    public static final String REQUEST_PARAMETER_TESTPLAN = "testplan";

    /** 
     * @param args
     */
    public static void main(String[] args) {
        PTestPlanExecutorClient client = new PTestPlanExecutorClient();
        client.executeClient(args);
        System.exit(0);
    }

    /**
     * Executes the client
     * @param args
     */
    protected void executeClient(String[] args) {

        try {
            CommandLineProcessor commandLineProcessor = new CommandLineProcessor();
            Map<String, Serializable> commandLineValues = commandLineProcessor
                    .parseCommandLine(PTestPlanExecutorClient.class.getName(), args, getCommandLineOptions());
            if (commandLineValues != null && !commandLineValues.isEmpty()) {

                Long threads = (Long) commandLineValues.get(CLI_VALUE_MAP_KEY_THREADS);
                Long recurrences = (Long) commandLineValues.get(CLI_VALUE_MAP_KEY_RECURRENCES);
                String recurrenceType = (String) commandLineValues.get(CLI_VALUE_MAP_KEY_RECURRENCE_TYPE);
                String testplanFile = (String) commandLineValues.get(CLI_VALUE_MAP_KEY_TESTPLAN);
                String hosts = (String) commandLineValues.get(CLI_VALUE_MAP_KEY_SERVER_HOSTS);
                Long port = (Long) commandLineValues.get(CLI_VALUE_MAP_KEY_SERVER_PORT);

                byte[] testplan = loadTestplan(testplanFile);

                System.out.println(threads + "-" + recurrences + "-" + hosts);
                executeTestplan(threads.intValue(), recurrences.intValue(), recurrenceType, testplan,
                        hosts.split(","), port.intValue());
            }
        } catch (Exception e) {
            System.out.println("Error while executing client: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * Executes the referenced test plan on all given hosts  
     * @param threads
     * @param recurrences
     * @param recurrenceType
     * @param testplan
     * @param hosts
     * @param port
     * @return
     */
    protected Map<String, String> executeTestplan(int threads, int recurrences, String recurrenceType,
            byte[] testplan, String[] hosts, int port) {

        StringBuffer buf = new StringBuffer("/planexec?action=execute");
        buf.append("&threads=").append(threads);
        buf.append("&recurrences=").append(recurrences);
        buf.append("&recurrenceType=").append(recurrenceType);

        StringBuffer hn = new StringBuffer();
        for (int i = 0; i < hosts.length; i++) {
            hn.append(hosts[i]);
            if (i < hosts.length - 1)
                hn.append(", ");
        }

        System.out.println("Execute testplan:");
        System.out.println("\thostNames: " + hn.toString());
        System.out.println("\tport: " + port);
        System.out.println("\tthreads: " + threads);
        System.out.println("\trecurrences: " + recurrences);
        System.out.println("\trecurrenceType: " + recurrenceType);
        System.out.println("\n\turi: " + buf.toString());

        PTestPlanExecutorClientCallable callables[] = new PTestPlanExecutorClientCallable[hosts.length];
        for (int i = 0; i < hosts.length; i++) {
            callables[i] = new PTestPlanExecutorClientCallable(hosts[i], port, buf.toString(), testplan);
        }

        ExecutorService executorService = Executors.newFixedThreadPool(hosts.length);
        List<Future<NameValuePair>> executionResults = new ArrayList<Future<NameValuePair>>();
        try {
            executionResults = executorService.invokeAll(Arrays.asList(callables));
        } catch (InterruptedException e) {
            System.out.println("Test execution interrupted: " + e.getMessage());
        }

        // collect results from callables
        Map<String, String> result = new HashMap<String, String>();
        for (Future<NameValuePair> r : executionResults) {
            try {
                NameValuePair nvp = r.get();
                result.put(nvp.getName(), nvp.getValue());
            } catch (InterruptedException e) {
                System.out.println("Interrupted while waiting for results. Error: " + e.getMessage());
                e.printStackTrace();
            } catch (ExecutionException e) {
                System.out.println("Interrupted while waiting for results. Error: " + e.getMessage());
                e.printStackTrace();
            }
        }

        return result;
    }

    /**
     * Returns the available command-line options 
     * @return
     */
    protected static List<CommandLineOption> getCommandLineOptions() {

        List<CommandLineOption> options = new ArrayList<CommandLineOption>();
        options.add(new CommandLineOption(CMD_OPT_MODE_EXECUTE, CMD_OPT_MODE_EXECUTE_SHORT, false, false,
                String.class, "Executes a test plan on the ptest-server instance(s)", CLI_VALUE_MAP_KEY_EXECUTE,
                "Required mode 'execute' missing"));
        options.add(new CommandLineOption(CMD_OPT_THREADS, CMD_OPT_THREADS_SHORT, true, true, Long.class,
                "Number of threads to be used for executing the test plan", CLI_VALUE_MAP_KEY_THREADS,
                "Required number of threads missing"));
        options.add(new CommandLineOption(CMD_OPT_RECURRENCES, CMD_OPT_RECURRENCES_SHORT, true, true, Long.class,
                "Number of times to execute the test plan", CLI_VALUE_MAP_KEY_RECURRENCES,
                "Required number of test plan execution recurrences missing"));
        options.add(new CommandLineOption(CMD_OPT_TESTPLAN, CMD_OPT_TESTPLAN_SHORT, true, true, String.class,
                "Name of the testplan file", CLI_VALUE_MAP_KEY_TESTPLAN, "Required test plan file"));
        options.add(new CommandLineOption(CMD_OPT_PTEST_SERVER_HOSTS, CMD_OPT_PTEST_SERVER_HOSTS_SHORT, true, true,
                String.class,
                "Comma-separated list of hosts running the ptest-server being provided the testplan setup",
                CLI_VALUE_MAP_KEY_SERVER_HOSTS, "Required server host missing"));
        options.add(new CommandLineOption(CMD_OPT_PTEST_SERVER_PORT, CMD_OPT_PTEST_SERVER_PORT_SHORT, true, true,
                Long.class, "Port the ptest-server instances listen to", CLI_VALUE_MAP_KEY_SERVER_PORT,
                "Required ptest-server port missing"));
        options.add(new CommandLineOption(CMD_OPT_RECURRENCE_TYPE, CMD_OPT_RECURRENCE_TYPE_SHORT, true, true,
                String.class,
                "Recurrence type specifying the number recurrences (TIMES, MILLIS, SECONDS, MINUTES, HOURS ...)",
                CLI_VALUE_MAP_KEY_RECURRENCE_TYPE, "Required recurrence type missing"));

        return options;
    }

    /**
     * Reads in a test plan
     * @param fileName
     * @return
     * @throws TSClientConfigurationException
     */
    protected byte[] loadTestplan(String fileName) throws InvalidConfigurationException {
        FileInputStream fin = null;
        try {
            fin = new FileInputStream(fileName);
            return IOUtils.toByteArray(fin);
        } catch (IOException e) {
            throw new InvalidConfigurationException(
                    "Failed to read test plan file '" + fileName + "'. Error: " + e.getMessage());
        } finally {
            if (fin != null) {
                try {
                    fin.close();
                } catch (IOException e) {
                    System.out
                            .println("Failed to close test plan file '" + fileName + "'. Error: " + e.getMessage());
                }
            }
        }

    }

}