Simperf is a simple performance test framework for java. It provides a multithread test framework.
Example:
- Use simperf in java:
Simperf perf = new Simperf(50, 2000, 1000, new SimperfThreadFactory() { public SimperfThread newThread() { return new SimperfThread(); } }); // setting output file path,simperf-result.log by default. perf.getMonitorThread().setLogFile("simperf.log"); // begin performance testing perf.start();
- Use simperf in command line
public class SimperfCommandTest { public static void main(String[] args) { SimperfCommand simCommand = new SimperfCommand(args); Simperf perf = simCommand.create(); if (perf == null) { // fail to parse the args System.exit(-1); } perf.start(new SimperfThreadFactory() { public SimperfThread newThread() { return new SimperfThread(); } }); } }
execute command:
java SimperfCommandTest -t 10 -c 10 -i 1000 DESCRIPTION : usage: SimperfCommand options -c,--count [*] number of each thread requests count -i,--interval [ ] interval of print messages, default 1000 -j [ ] generate jtl report -l,--log [ ] log filename -m,--maxtps [ ] max tps -o,--timeout [ ] timeout, in millis -t,--thread [*] number of thread count
- Use simperf in JUnit4
public class SimperfTestCaseTest extends SimperfTestCase { private Random rand; @Test @Simperf(thread = 2, count = 5, interval = 1000) public void testXxx() { try { Thread.sleep(1000); } catch (Exception e) { } boolean result = rand.nextInt(10) > 1; Assert.assertTrue("random result", result); } }
Download: simperf-1.0.4.jar
- The Number Of Concurrent Threads
int thread = 10; // the number of threads int count = 20; // the number of times to execute the test for each thread, -1 means to run forever Simperf perf = new Simperf(thread, count); // start simperf
- Interval (default:1000)
Simperf perf = new Simperf(thread, count); int interval = 1000; // 1000ms perf.setInterval(interval); // Sampling calculation once every 1000 ms // start simperf
- Timeout (default:-1)
Simperf perf = new Simperf(thread, count); int timeout = 10000; // 10000ms perf.timeout(timeout); // the threads will exit after 10s // start simperf
- The Maximum TPS (optional)
Simperf perf = new Simperf(thread, count); int maxTps = 10; // the maximum TPS for each thread perf.setMaxTps(maxTps); // start simperf
Use simperf in command line has given the supported options by Simperf. You could add your own options if you need.
SimperfCommand simCommand = new SimperfCommand(args); simCommand.getOptions().addOption("a", "argument", true, "a custom argument"); Simperf perf = simCommand.create(); if (simCommand.getCmd().hasOption("a")) { System.out.println(simCommand.getCmd().getOptionValue("a")); }
- log results by log4j
- write the results into a file (It will flush the cache after complete)
- jtl file, which analyzed by jmeter
- SQL
- custom types Simperf registers log4j and file writer by default, and it will take JSON as the default format.
Simperf perf = new Simperf(10, 10); perf.getMonitorThread().clearCallback(); //clear all callback perf.getMonitorThread().registerCallback(new DefaultConsolePrinter()); //register DefaultConsolePrinter, which uses log4j perf.getMonitorThread().registerCallback( new DefaultLogFileWriter(Constant.DEFAULT_RESULT_LOG)); //register DefaultLogFileWriter to write file ,default file name:simperf-result.log perf.getMonitorThread().registerCallback(new DefaultSqlFileWriter("xxx.sql"));//register DefaultSqlFileWriter, write Sql to file // start simperf
There are some different to use JTL.
Simperf perf = new Simperf(10, 10); // print JTL record JTLResult jtl = new JTLResult(perf.getMonitorThread()); //default file: Constant.DEFAULT_JTL_FILE SimperfConfig.setConfig(SimperfConfig.JTL_RESULT, jtl); // start simperf
- Set the filename for writer
Simperf perf = new Simperf(10, 10); perf.getMonitorThread().setLogFile("simperf.log"); //FileWriter will write data into simperf.log
- Register callbacks by yourself
Simperf perf = new Simperf(10, 10); perf.getMonitorThread().clearCallback(); //clear all callbacks perf.getMonitorThread().registerCallback(new DefaultLogFileWriter("simperf.log"));
Create a class extends DefaultCallback,and then call method perf.getMonitorThread().registerCallback() to register callback objects.
public void onStart(MonitorThread monitorThread); // call on start test public void onMonitor(MonitorThread monitorThread, StatInfo statInfo); // call on calculate the output public void onExit(MonitorThread monitorThread); //call on simperf exit
Constant.DEFAULT_NA = "NaA"; //output when NA,0 as a divisor for example Constant.DEFAULT_DIVIDE_FORMAT = "%.3f"; //round number to three decimal places // output format which use to log or write results,Json by default,the format contains %s,%s,%d,%d,%d,%s,%d,%d,%d Constant.DEFAULT_MSG_FORMAT = ">>>\ntime:%s\navgTps:%s\ncount:%d\nduration:%d\nfail:%d\ntTps:%s\ntCount:%d\ntDuration:%d\ntFail:%d\n"; Constant.DEFAULT_DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd-HH:mm:ss"); // default data format
- Change the number of concurrent threads when testing
public static void main(String[] args) { Simperf perf = new Simperf(10, 100); perf.start(new SimperfThreadFactory() { public SimperfThread newThread() { return new SendMessageThread(); } }); thread(perf, 7); thread(perf, 10); thread(perf, 15); thread(perf, 20); thread(perf, 15); thread(perf, 25); thread(perf, 10); thread(perf, 5); } // Change the number of concurrent threads every 5s public static void thread(Simperf perf, int size) { try { Thread.sleep(5000); } catch (InterruptedException e) { } perf.thread(size); // dynamic adjustment }
- Change the number of times to execute for each thread when testing
Simperf perf = new Simperf(10, 100); // start simperf perf.count(200); // dynamic adjustment
- Change the interval of print results when testing
Simperf perf = new Simperf(10, 100); // start simperf perf.interval(2000); // dynamic adjustment
- Stepping change the number of concurrent thread
Simperf perf = new Simperf(10, 20); TimeSteppingThreadTrigger trigger = new TimeSteppingThreadTrigger(3000, 3); //add three new threads every 3s trigger.setMaxThreads(18); //the maximum number of threads is 18 trigger.startWork(perf); // start work // start simpef
SimperfThread is the most important class in Simperf,which implements the specific tasks. You must extend and implement SimperfThread in Simperf for your transactions.
public class DemoSimperfThread extends SimperfThread { // Required public boolean runTask() { // implement a transaction operate doSleep(); // return the result, true if success otherwise false return true; } /** * Sample task, sleep 20ms */ public void doSleep() { try { Thread.sleep(20); } catch (Exception e) { } } // Optional public void warmUp() { } // Optional public void beforeRunTask() { } // Optional public void afterRunTask() { } // Optional protected Object beforeInvoke() { return System.currentTimeMillis(); } // Optional protected void afterInvoke(boolean result, Object beforeInvokeResult) { long begin = (Long) beforeInvokeResult; long end = (Long) System.currentTimeMillis(); System.out.println("result:" + result + ",duration:" + (end - begin)); } }
All of the futures are available in Junit 4
public class SimperfTestCaseTest extends SimperfTestCase { private static final Logger logger = LoggerFactory.getLogger(SimperfTestCaseTest.class); private Random rand; @Before public void before() { TimeSteppingThreadTrigger t = new TimeSteppingThreadTrigger(2000, 2); // set a stepping thread concurent trigger t.startWork(simperf); rand = new Random(); logger.debug(Thread.currentThread().getId() + "SimperfTestCaseTest.before()"); } @After public void after() { logger.debug(Thread.currentThread().getId() + "SimperfTestCaseTest.after()"); } @BeforeInvoke public void beforeInvoke() { logger.debug(Thread.currentThread().getId() + "SimperfTestCaseTest.beforeInvoke()"); } @AfterInvoke public void afterInvoke() { logger.debug(Thread.currentThread().getId() + "SimperfTestCaseTest.afterInvoke()"); } @BeforeRunTask public void beforeRunTask() { logger.debug(Thread.currentThread().getId() + "SimperfTestCaseTest.beforeRunTask()"); } @AfterRunTask public void afterRunTask() { logger.debug(Thread.currentThread().getId() + "SimperfTestCaseTest.afterRunTask()"); } @WarmUp public void warmUp() { logger.debug(Thread.currentThread().getId() + "SimperfTestCaseTest.warmUp()"); } @Test @Simperf(thread = 2, count = 5, interval = 1000) public void testXxx() { try { Thread.sleep(1000); } catch (Exception e) { } boolean result = rand.nextInt(10) > 1; // 10% failed Assert.assertTrue("xxxx", result); } }