/* * The contents of this file are subject to the Mozilla Public License * Version 1.1 (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.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is the Kowari Metadata Store. * * The Initial Developer of the Original Code is Plugged In Software Pty * Ltd (http://www.pisoftware.com, mailto:info@pisoftware.com). Portions * created by Plugged In Software Pty Ltd are Copyright (C) 2001,2002 * Plugged In Software Pty Ltd. All Rights Reserved. * * Contributor(s): N/A. * * [NOTE: The text of this Exhibit A may differ slightly from the text * of the notices in the Source Code files of the Original Code. You * should use the text of this Exhibit A rather than the text found in the * Original Code Source Code for Your Modifications.] * */ package org.mulgara.itql; import org.mulgara.query.Answer; // Java 2 standard packages // third party packages // third party packages import java.io.*; import java.util.Random; import java.util.Vector; /** * Stress test the system by creating robot itql beans and * randomly execute tql queries and record the results * * Unit test for {@link ItqlInterpreterBean}. * * @created 2002-06-03 * * @author Tate Jones * * @version $Revision: 1.8 $ * * @modified $Date: 2005/01/05 04:58:15 $ by $Author: newmana $ * * @company <a href="mailto:info@PIsoftware.com">Plugged In Software</a> * * @copyright ©2001 <a href="http://www.pisoftware.com/">Plugged In * Software Pty Ltd</a> * * @licence <a href="{@docRoot}/../../LICENCE">Mozilla Public License v1.1</a> */ public class ItqlInterpreterStressTest { /** * Description of the Field */ @SuppressWarnings("unused") private boolean verbose = false; /** * Number of repetiions each robot executes the set of tql queries. */ private int repetitions = 1000; /** * The number of itql bean robots to be created */ private int stress = 50; /** * The maximum delay between tql executions */ private int delay = 7000; /** * The minimum delay between tql executions */ private int minDelay = 2000; /** * Period to wait until another robot is added */ private int rampTime = 250; /** * The current number of robots active */ private int robots = 100; /** * The file location of the tql commands */ private String itqlLog = "itqlcmd.log"; /** * The file location of the outputed results for queries */ private String queryOutputFile = "query.csv"; /** * The total time of the stress test */ private long totalTime = 0; /** * The total number of tql executions across all robots */ private long executions = 0; /** * Start time of the stress test */ @SuppressWarnings("unused") private long startTime = 0; /** * Used to create random delay between tql executions */ private Random rand = new Random(); /** * Contains the list of queries to be executed */ private Vector<String> queries = new Vector<String>(); /** * Stream to read tql commands */ private PrintWriter queryLog = null; /** * Stress test the system by creating robot itql beans and * randomly execute tql queries and record the results */ public ItqlInterpreterStressTest() { } /** * METHOD TO DO * * @param args PARAMETER TO DO */ public static void main(String[] args) { if ( args.length > 0 && (args[0].equals("-?") || args[0].equalsIgnoreCase("-h"))) { String lineSeparator = System.getProperty("line.separator"); String usuage = "Stress test " + lineSeparator + "Usage: "+ lineSeparator + " [-s <number>] [-r <number>] [-w <milliseconds>] "+ " [-wm <milliseconds>] [-ra <milliseconds>] [-i <file>] "+ " [-o <file>]" + lineSeparator + lineSeparator + " -h display this help screen "+lineSeparator+ " -s number of robots to ramp up to (stress level) (default 100)"+lineSeparator+ " -r number of query repetitions for each robot to execute (default 1000)"+lineSeparator+ " -w the maximum wait time between query executions per robot (default 7000 millisec)"+lineSeparator+ " -wm the minimum wait time between query executions per robot (default 2000 millisec)"+lineSeparator+ " -ra the ramp time for each new robot to be created (default 250 millisec)"+lineSeparator+ " -i the input file containing the itql commands (default itqlcmd.log)"+lineSeparator+ " -o output file containing the query performance results (default query.csv)"+lineSeparator; System.out.println( usuage ); } else { try { new ItqlInterpreterStressTest().start(args); System.exit(0); } catch (Exception e) { System.out.println(e.getMessage()); System.exit(1); } } } /** * METHOD TO DO * * @param args PARAMETER TO DO * @throws Exception EXCEPTION TO DO */ protected void start(String[] args) throws Exception { for (int i = 0; i < args.length; i++) { if (args[i].equals("-v")) { verbose = true; } else if (args[i].equals("-r")) { repetitions = Integer.parseInt(args[i + 1]); } else if (args[i].equals("-s")) { stress = Integer.parseInt(args[i + 1]); } else if (args[i].equals("-w")) { delay = Integer.parseInt(args[i + 1]); } else if (args[i].equals("-wm")) { minDelay = Integer.parseInt(args[i + 1]); } else if (args[i].equals("-i")) { itqlLog = args[i + 1]; } else if (args[i].equals("-ra")) { rampTime = Integer.parseInt(args[i + 1]); } else if (args[i].equals("-o")) { queryOutputFile = args[i + 1]; } } // open the itql command log LineNumberReader itqlCommands = new LineNumberReader(new FileReader(itqlLog)); // read the contents String query = itqlCommands.readLine(); while (query != null) { queries.add(query); query = itqlCommands.readLine(); } System.out.println("Settings"); System.out.println("\tRepetitions :" + repetitions); System.out.println("\tStress (number of robots) :" + stress); System.out.println("\tRandom Delay up-to :" + delay); System.out.println("\tMin. Delay up-to :" + minDelay); System.out.println("\tNumber of queries :" + queries.size()); System.out.println("\tRamp robot every :" + rampTime); System.out.println("\tQuery OutputFile :" + queryOutputFile); if (queries.size() == 0) { System.out.println("No queries to be tested - exiting"); } if (queryOutputFile == null) { System.out.println("The output file has been supplied. Use -o"); } queryLog = new PrintWriter(new FileWriter(queryOutputFile), true); queryLog.println("Time\tRobot\tQuery Number\tQuery Time\tAverage Query Time ms" ); ItqlRobot[] threads = new ItqlRobot[stress]; for (int i = 0; i < stress; i++) { String name = "Robot" + String.valueOf(i); threads[i] = new ItqlRobot(name, queries, repetitions, delay, minDelay); } startTime = System.currentTimeMillis(); for (int i = 0; i < stress; i++) { // start a robot System.out.println("Starting " + threads[i].getRobotName()); threads[i].start(); synchronized (queryLog) { robots++; } // wait a period time before adding a new robot try { Thread.sleep(rampTime); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("All robots have started...."); for (int i = 0; i < stress; i++) { threads[i].join(); } queryLog.close(); } private class ItqlRobot extends Thread { private ItqlInterpreterBean itql = null; private String name = null; private Vector<String> queries = null; private int repetitions = 0; private int delay = 0; private int minDelay = 0; private int noOfQueries = 0; /** * TQL bean robot that will execute a collection of TQL queries * * @param name robot name identifier * @param queries a list of queries to execute * @param repetitions number of repeatitions * @param delay the maximum delay between executes * @param minDelay the minimum delay between executes */ public ItqlRobot(String name, Vector<String> queries, int repetitions, int delay, int minDelay) { this.itql = new ItqlInterpreterBean(); this.name = name; this.queries = queries; this.repetitions = repetitions; this.delay = delay; this.minDelay = minDelay; this.noOfQueries = queries.size(); } /** * Obtain the current robot name * * @return String Current robot name */ public String getRobotName() { return this.name; } private void executeQuery() { Answer answer = null; try { long start = System.currentTimeMillis(); int queryNumber = rand.nextInt(noOfQueries); String query = queries.elementAt(queryNumber); answer = itql.executeQuery(query); if ( answer != null ) { System.out.print("."); } else { System.out.println(); System.out.println(query ); } long queryTime = (System.currentTimeMillis() - start); totalTime = totalTime + queryTime; executions++; synchronized (queryLog) { queryLog.println(System.currentTimeMillis()+"\t"+ this.getRobotName()+"\t"+ queryNumber + "\t" + queryTime + "\t"+ (totalTime / executions) ); } } catch (Exception ex) { ex.printStackTrace(); } finally { try { answer.close(); } catch (Exception ex) { // do nothing } } } public void run() { try { for (int calls = 0; calls < repetitions; calls++) { try { sleep(rand.nextInt(delay - minDelay) + minDelay); } catch (InterruptedException e) { e.printStackTrace(); } try { this.executeQuery(); } catch (Exception ex) { ex.printStackTrace(); } } System.out.println(this.name + " has completed"); } finally { synchronized (queryLog) { robots--; } itql.close(); } } } }