// entery point for each thread/client public void run() { if (debug) { Console.WriteLine("Thread-" + Thread.CurrentThread.Name + " started"); } // instance the test runner and call its init() Interfaces.ITestRun runner = Activator.CreateInstance(this.testAssemblyType) as Interfaces.ITestRun; runner.init(this.config); // prepare local logs to avoid conflictions between threads // prepare logs ResultLog[] localLogs = new ResultLog[this.numLogs]; for (int i = 0; i < globalLogs.Length; i++) { string logName = logInfo[i].name; double disUnit = Double.Parse(DataUtility.getPropertyValueByName(logInfo[i], "disUnit", "10")); localLogs[i] = new ResultLog(logName, disUnit, 0, 5000, 500); } // prepare timers: one for performance measurement // one for test control HighResolutionTimer timer = new HighResolutionTimer(); com.csiro.cs.util.TestTimer alarm = new com.csiro.cs.util.TestTimer(this.testTime, this.warmupRate, this.cooldownRate); // prepare temp varibles ulong latency; // to test performance int numTx = 0; // to test fairness int index; // to identify which log int localNumExceptions = 0; // to record exceptions bool _isPreRun = this.isPreRun; bool _isPostRun = this.isPostRun; for (alarm.start(); !alarm.isTime(); numTx++) { try { if (_isPreRun) { runner.preRun(); } timer.start(); index = runner.run(); latency = timer.stop(); if (alarm.isTesting()) { localLogs[0].add(latency); // only log test period } if (_isPostRun) { runner.postRun(); } } catch (Exception e) { Console.WriteLine("LoadTester.Tester.run(): " + e.Message); localNumExceptions++; } } try { this.globalNumExceptions += localNumExceptions; if (debug) { Console.WriteLine("numTx = " + numTx); } runner.done(); // add to global lock (this.globalLogs) { for (int i = 0; i < localLogs.Length; i++) { this.globalLogs[i].add(localLogs[i]); } } } catch (Exception e) { Console.WriteLine("LoadTester.Tester.run(): " + e.Message); } }