Giter VIP home page Giter VIP logo

load-test-tool's Introduction

Load test tool

Simple but powerful command line tool for load testing your Java modules. It has a simple API that allows you to define testing tasks. It has a concept similar to JUnit/TestNG tests but with concentration on performance measurements in concurrent environment.

Installing

If you use a Debian based OS (Ubuntu, for example), you could simply download a .deb package from: http://github.com/bazhenov/load-test-tool/downloads

Then you should execute:

# dpkg -i load-test-tool-1.0-3.deb

Building

You need nothing more but maven for building load test tool.

$ mvn package

After building you will have .tar.gz artifact in ldt-assembly/target directory. You should unpack it in some directory where ldt will be installed:

$ tar xvf ldt-assembly-1.0-SNAPSHOT.tar.gz
x ldt-assembly-1.0-SNAPSHOT/bin/ldt.sh
x ldt-assembly-1.0-SNAPSHOT/bin/install.sh
x ldt-assembly-1.0-SNAPSHOT/lib/ldt-core-1.0-SNAPSHOT.jar
x ldt-assembly-1.0-SNAPSHOT/lib/commons-beanutils-1.7.0.jar
x ldt-assembly-1.0-SNAPSHOT/lib/commons-logging-1.0.3.jar
x ldt-assembly-1.0-SNAPSHOT/lib/commons-cli-1.1.jar
x ldt-assembly-1.0-SNAPSHOT/lib/log4j-1.2.14.jar
x ldt-assembly-1.0-SNAPSHOT/lib/ldt-assembly-1.0-SNAPSHOT.jar
$ alias ldt="~/Developer/ldt-assembly-1.0-SNAPSHOT/bin/ldt.sh"
$ ldt
usage: ltd
 -c,--concurrency-level <arg>   concurrency level
 -n,--count <arg>               sample count
 -p,--parameters <arg>          task parameters
 -r,--result-printer <arg>      result printer type (plain, log)
 -t,--timeframe <arg>           timeframe testing range (in milliseconds)
 -w,--warmup-threshold <arg>    warmup test execution count
 -z,--clazz <arg>               full qualified test class name
$ ldt -z com.farpost.ldt.Sleep -c 2 -n 10
                     RESULTS                      
--------------------------------------------------
 Concurrency level             : 2
 Samples count (per thread)    : 10
 Total time                    : 3.5s
 Min. time                     : 300ms
 Max. time                     : 304ms
 Std. dev.                     : ~349mcs
 Throughput                    : 6.7 tps

You could use alias or some other way to publish ldt.sh script in your shell environment (ln -s is a good way to start).

Task running

ldt can run tests written as a simple pojo objects. Let's see a sample:

public class MathTest {

	public void execute() {
		Math.sin(30);
	}
}

Method execute() called when you pass MathTest as a class name.

$ ldt -z org.mypackage.MathTest

This command will run tests and display execution statistic. It's worth to mention that ldt automatically adds current directory to classpath.

You could adjust concurrency level and thread sample count (task repeat count)

$ ldt -z full.quialified.ClassName -c 2 -n 100

In this example test defined in a class will be run in two separate threads 100 times in each thread.

If test class contains several tests (cases) you could choose which to run with following syntax:

$ ldt -z full.quialified.ClassName#test1

Strictly speaking test address full.quialified.ClassName equals to full.quialified.ClassName#execute.

ldt distribution contains several standard tasks. For example HttpTask for testing throughput of http services:

$ ldt -z com.farpost.ldt.HttpTask#get -p "url=http://google.com/" -n 10 -r log
1448
1011
997
987
989
2349
1229
990
983
1948

As you see I have not a very good link to google.com. I'm inclined to think that my physical location is reason to that ;) Anyhow, this example shows how you can use standard task in conjunction with different result printer (-r log) to get raw elapsed time log for several http requests.

Fixture

If you have some bootstraping code which must be executed before tests run you could define prepare() method. This method will be executed before any test in suite. All methods are called at one object instance, so prepare() method could communicate with test method using class properties:

public class SomeTest {
	
	private int[] numbers;

	public void prepare() {
		numbers = new int[1000];
	}

	public void test() {
		for ( int i : numbers ) {
			// ...
		}
	}
}

You could also define cleanup() method which will be executed only once after all test measurements are finished.

Warm up threshold

There are some reasons why in complex environments such as JVM you could want to skip first several test executions statistic (do not include it in resulting statistic). At the moment when JVM is started and run yor code, there are a lot activity going on. Some of them can influence your code hot paths (for example HotSpot JIT compiler). So ldt allows you to execute test several times before starting real measurements:

$ ldt -z full.qualified.test.name -w 10 -n 100 -c 4

In this example we run test 110 times in each thread, but ten first executions of each thread will be droped out and do not influence history.

Timeframe based testing

Instead of configuring test execution samples count you could just specifiy how long test should be executed (eg. 2 seconds). This is very convinient way of testing code especially when you do not know code throughtput in first place.

$ ldt -z com.farpost.ldt.HttpTask#get -p "url=http://baza.farpost.ru/" -t 2000
                     RESULTS                      
--------------------------------------------------
 Concurrency level             : 1
 Samples count                 : 6
 Total time                    : 2.139s
 Min. time                     : 289ms
 Max. time                     : 499ms
 Throughput                    : 2.8 tps

In this example ldt repeat test execution until cummulative execution time overgrown 2 seconds.

Test parameters

Sometimes there is need to pass some parameters to a test. Suppose following test example:

public class HttpRequestTest {

	private String url;
	private long timeout;

	public void setUrl(String url) {
		this.url = url;
	}

	public void setReadTimeout(long timeout) {
		this.timeout = timeout;
	}

	public void execute() {
		// reading url contents
	}
}

For passing url value in test we could use following command (parameters should be separated with comma):

$ ldt -z org.mypackage.HttpRequestTest -p "url=http://host.com, timeout=3000"

JVM startup options

In some cases you want to pass additional parameters to JVM when starting test (eg. heap size):

$ JAVA_OPTS="Xmx512M" ldt -z path.to.Test

Maven integration

ldt have full maven integration via maven plugin. At the moment you should build maven plugin by itself. Using maven this is as simply as:

$ mvn install

ldt have no heavy dependency list, so you shouldn't have any problems.

Then you should configure plugin in your pom.xml:

<project>

	<build>
		<plugins>
			<plugin>
				<groupId>com.farpost.maven.plugins</groupId>
				<artifactId>maven-ldt-plugin</artifactId>
				<configuration>
					<testName>com.farpost.test.ExampleTest</testName>
					<concurrencyLevel>3</concurrencyLevel>
					<callCount>1000</callCount>
				</configuration>
			</plugin>
		</plugins>
</project>

In order to use timeframe based testing you should set testTime parameter: com.farpost.test.ExampleTest 3 2000

At this point you should be able to run:

$ mvn ldt:test

and view test results

You also can pass ldt parameters from console line instead of pom.xml:

$ mvn ldt:test -Dldt.testName=com.farpost.test.ExampleTest -Dldt.concurrencyLevel=10 -Dldt.callCount=1000

License

Copyright (c) 2010 Denis Bazhenov

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

load-test-tool's People

Contributors

bazhenov avatar erkan-yilmaz avatar orthographic-pedant avatar zolotov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

load-test-tool's Issues

fixture support

There is need for fixture support in test runner. There should be no arg setUp()/tearDown() methods which is used to prepare and cleanup environment respectively.

annotation based test runner

There should be way to configure tests without extending ldt classes directly. I think annotation could help here:

import com.farpost.loadTestTool.Before;
import com.farpost.loadTestTool.After;
import com.farpost.loadTestTool.Test;

class FooTest {

  @Before
  public void beforeTest() {
    // initialize
  }

  @Test
  public void someTest() {
    // test
  }

  @After
  public void afterTest() {
    // clean up
  }
}

maven support

It should be cool if ldt will support maven natively. The most easy way to do it is to bootstrap maven compile path to java classpath (in bash script). More advanced way to do the same is to integrate in maven as a maven plugin (execution goal). In such case all client need to do is "mvn lst:test", which is nice, I think.

Standart deviation measurements

It will be useful to measure standard deviance for elapsed execution time, as it's measure of code latency predictability

Mark samples in test results

Some of the test samples can fail with the exception. The fail count should be published by ldt on a result screen.

Warm up threading policy change

There is no need to perform test warm up in several threads. It would be more predictable to user if ldt performs given number of warm up samples in one thread.

more accurate elapsed time measurement

At the moment ldt use elapsed time measurement with accuracy to 10e-3 second. This method fair enough for most IO based tasks, but simply too loose for tasks with execution time less than 1 ms (for example, primitive CPU tasks like sin()/sqrt() and so on).

So it'll be good to use ns. based measurement with resolution 10e-6 second.

Warm up period

ldt should be able to warm up code execution path by executing test some time before starting measurements.

Timeframe testing

I think it'll be useful to test code not by running N times, but measuring how much times code will be executed in up to second for example. So I choose some timeframe (1 second) and system runs test until elapsed time sum will overgrown that given timeframe.

Isolate test case factory

While using ldt it's becomes obvious that code creating test must been isolated and test covered.

Thread naming

I think it'll be usefull if all testing threads will have describing names, so than I can quickly identify them among other JVM threads.

Maven plugin

It will be cool if we have maven plugin which can resolve all dependencies for testing environment.

create assembly for ldt

Assembly should be created for ldt in first place. Assembly should contain all required jar for ldt to work with some bootstrapping shell scripts for easy using

log based reporter

There is should be some sort of log based ResultReporter which is intended to use with metric analysis when you need to plot a graph of execution times of test.

Simple dependency injection mechanism

It would be nice idea to have some sort of configuring test before running. Suppose we have task:

class SomeTask {

  private String url;

  public void setUrl(String url) {
    this.url = url;
  }

  @Test
  public void test() {
    // reading data from url
  }
}

So we can run this task as:
ldt -c 10 -z org.test.SomeTask -p "url=http://host/path"

Batch tests

Add batch tests. It is very convenient for testing several features at the same time

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.