@Override public void stop() { stopping = true; super.stop(); }
private JMeterThread makeThread(int groupCount, ListenerNotifier notifier, ListedHashTree threadGroupTree, StandardJMeterEngine engine, int i, JMeterContext context) { // N.B. Context needs to be fetched in the correct thread boolean onErrorStopTest = getOnErrorStopTest(); boolean onErrorStopTestNow = getOnErrorStopTestNow(); boolean onErrorStopThread = getOnErrorStopThread(); boolean onErrorStartNextLoop = getOnErrorStartNextLoop(); String groupName = getName(); final JMeterThread jmeterThread = new JMeterThread(cloneTree(threadGroupTree), this, notifier); jmeterThread.setThreadNum(i); jmeterThread.setThreadGroup(this); jmeterThread.setInitialContext(context); final String threadName = groupName + " " + (groupCount) + "-" + (i + 1); jmeterThread.setThreadName(threadName); jmeterThread.setEngine(engine); jmeterThread.setOnErrorStopTest(onErrorStopTest); jmeterThread.setOnErrorStopTestNow(onErrorStopTestNow); jmeterThread.setOnErrorStopThread(onErrorStopThread); jmeterThread.setOnErrorStartNextLoop(onErrorStartNextLoop); return jmeterThread; }
@Override public boolean stopThread(String threadName, boolean now) { for(Entry<JMeterThread, Thread> entry : allThreads.entrySet()){ JMeterThread thrd = entry.getKey(); if (thrd.getThreadName().equals(threadName)){ thrd.stop(); thrd.interrupt(); if (now) { Thread t = entry.getValue(); if (t != null) { t.interrupt(); } } return true; } } return false; }
/** * Hard Stop JMeterThread thrd and interrupt JVM Thread if interrupt is true * @param jmeterThread {@link JMeterThread} * @param jvmThread {@link Thread} * @param interrupt Interrupt thread or not */ private void stopThread(JMeterThread jmeterThread, Thread jvmThread, boolean interrupt) { jmeterThread.stop(); jmeterThread.interrupt(); // interrupt sampler if possible if (interrupt && jvmThread != null) { // Bug 49734 jvmThread.interrupt(); // also interrupt JVM thread } }
public synchronized void arrivalFact(JMeterThread thread, long arrivalID) { arrivalsCount.incrementAndGet(); notifyAll(); saveLogRecord("ARRIVAL", thread.getThreadName(), thread.getThreadNum() + "." + arrivalID); }
JMeterThread thread = new JMeterThread(hashTree, null, null); log.debug("Num Threads: " + numThreads); for (int n = 0; n < numThreads; n++) { thread.setThreadNum(n); thread.setThreadName(Integer.toString(n)); tg.scheduleThread(thread, now); row.add(thread.getStartTime() - 1, 0); row.add(thread.getStartTime(), 1); thread.setThreadNum(n); thread.setThreadName(Integer.toString(n)); tg.scheduleThread(thread, now); row.add(thread.getEndTime() - 1, 0); row.add(thread.getEndTime(), -1);
@Override protected void scheduleThread(JMeterThread thread, long tgStartTime) { log.debug("Scheduling thread: " + thread.getThreadName()); if (threadsToSchedule < 1) { if (!scheduleIT.hasNext()) { throw new RuntimeException("Not enough schedule records for thread #" + thread.getThreadName()); } currentRecord = (CollectionProperty) scheduleIT.next(); threadsToSchedule = currentRecord.get(0).getIntValue(); } int numThreads = currentRecord.get(START_THREADS_CNT_FIELD_NO).getIntValue(); int initialDelay = currentRecord.get(INIT_DELAY_FIELD_NO).getIntValue(); int startRampUp = currentRecord.get(STARTUP_TIME_FIELD_NO).getIntValue(); int flightTime = currentRecord.get(HOLD_LOAD_FOR_FIELD_NO).getIntValue(); int endRampUp = currentRecord.get(SHUTDOWN_TIME_FIELD_NO).getIntValue(); long ascentPoint = tgStartTime + 1000 * initialDelay; final int rampUpDelayForThread = (int) Math.floor(1000 * startRampUp * (double) threadsToSchedule / numThreads); long startTime = ascentPoint + rampUpDelayForThread; long descentPoint = startTime + 1000 * flightTime + 1000 * startRampUp - rampUpDelayForThread; thread.setStartTime(startTime); thread.setEndTime(descentPoint + (int) Math.floor(1000 * endRampUp * (double) threadsToSchedule / numThreads)); thread.setScheduled(true); threadsToSchedule--; }
int rampUpBucket = thread.getThreadNum() < inUserCountBurst ? 0 : 1 + (thread.getThreadNum() - inUserCountBurst) / inUserCount; int rampUpBucketThreadCount = thread.getThreadNum() < inUserCountBurst ? inUserCountBurst : inUserCount; int rampUpBucketThreadPosition = thread.getThreadNum() < inUserCountBurst ? thread.getThreadNum() : (thread.getThreadNum() - inUserCountBurst) % inUserCount; long endTime = descentPoint + outUserPeriod * (int) Math.floor((double) thread.getThreadNum() / outUserCount); thread.getThreadNum(), rampUpBucket, rampUpBucketThreadCount, rampUpBucketStartTime, rampUpBucketThreadPosition, rampUpDuration, iterationDuration, iterationCountTotal, ascentPoint, descentPoint, startTime, endTime)); thread.setStartTime(startTime); thread.setEndTime(endTime); thread.setScheduled(true);
/** * Called by JMeterThread when it finishes */ @Override public void threadFinished(JMeterThread thread) { if (log.isDebugEnabled()) { log.debug("Ending thread {}", thread.getThreadName()); } allThreads.remove(thread); }
reqText.append(ctl.getName()).append("\n"); JMeterThread jmThread = new JMeterThreadParallel(getTestTree(ctl), this, notifier, getGenerateParent()); jmThread.setThreadName("parallel " + this.getName()); jmThread.setThreadGroup(threadGroup); jmThread.setEngine(JMeterContextService.getContext().getEngine()); injectVariables(jmThread, this.getThreadContext()); jMeterThreads.add(jmThread);
/** * This will schedule the time for the JMeterThread. * * @param thread JMeterThread * @param now in milliseconds */ private void scheduleThread(JMeterThread thread, long now) { if (!getScheduler()) { // if the Scheduler is not enabled return; } if (getDelay() >= 0) { // Duration is in seconds thread.setStartTime(getDelay() * 1000 + now); } else { throw new JMeterStopTestException("Invalid delay " + getDelay() + " set in Thread Group:" + getName()); } // set the endtime for the Thread if (getDuration() > 0) {// Duration is in seconds thread.setEndTime(getDuration() * 1000 + (thread.getStartTime())); } else { throw new JMeterStopTestException("Invalid duration " + getDuration() + " set in Thread Group:" + getName()); } // Enables the scheduler thread.setScheduled(true); }
HashTree hashtree = new HashTree(); hashtree.add(new LoopController()); JMeterThread thread = new JMeterThread(hashtree, monitor, null); thread.setThreadName("test thread"); JMeterContextService.getContext().setThread(thread); ThreadGroup threadGroup = new org.apache.jmeter.threads.ThreadGroup();
jmThread.setInitialDelay(0); // Already waited if (usingScheduler) { jmThread.setScheduled(true); jmThread.setEndTime(endtime); Thread newThread = new Thread(jmThread, jmThread.getThreadName()); newThread.setDaemon(false); // ThreadStarter is daemon, but we don't want sampler threads to be so too registerStartedThread(jmThread, newThread);
iterationListener = initRun(threadContext); while (running) { Sampler sam = threadGroupLoopController.next(); while (running && sam != null) { processSampler(sam, null, threadContext); threadContext.cleanAfterSample(); triggerLoopLogicalActionOnParentControllers(sam, threadContext, JMeterThread::continueOnThreadLoop); } else { switch (threadContext.getTestLogicalAction()) { case BREAK_CURRENT_LOOP: triggerLoopLogicalActionOnParentControllers(sam, threadContext, JMeterThread::breakOnCurrentLoop); break; case START_NEXT_ITERATION_OF_THREAD: triggerLoopLogicalActionOnParentControllers(sam, threadContext, JMeterThread::continueOnThreadLoop); break; case START_NEXT_ITERATION_OF_CURRENT_LOOP: triggerLoopLogicalActionOnParentControllers(sam, threadContext, JMeterThread::continueOnCurrentLoop); break; default: shutdownTest(); stopTestNow(); } catch (JMeterStopThreadException e) { // NOSONAR if (log.isInfoEnabled()) { log.info("Stop Thread seen for thread {}, reason: {}", getThreadName(), e.toString()); threadFinished(iterationListener);
threadContext.setThreadNum(getThreadNum()); threadContext.getVariables().put(LAST_SAMPLE_OK, TRUE); threadContext.setThread(this); if (scheduler) { startScheduler(); rampUpDelay(); // TODO - how to handle thread stopped here if (log.isInfoEnabled()) { log.info("Thread started: {}", Thread.currentThread().getName()); threadGroupLoopController.addIterationListener(iterationListener); threadStarted(); return iterationListener;
/** * Start a new {@link JMeterThread} and registers it * @param notifier {@link ListenerNotifier} * @param threadGroupTree {@link ListedHashTree} * @param engine {@link StandardJMeterEngine} * @param threadNum Thread number * @param context {@link JMeterContext} * @param now Nom in milliseconds * @param delay int delay in milliseconds * @return {@link JMeterThread} newly created */ private JMeterThread startNewThread(ListenerNotifier notifier, ListedHashTree threadGroupTree, StandardJMeterEngine engine, int threadNum, final JMeterContext context, long now, int delay) { JMeterThread jmThread = makeThread(notifier, threadGroupTree, engine, threadNum, context); scheduleThread(jmThread, now); // set start and end time jmThread.setInitialDelay(delay); Thread newThread = new Thread(jmThread, jmThread.getThreadName()); registerStartedThread(jmThread, newThread); newThread.start(); return jmThread; }
@Override public long delay() { double nextEvent; EventProducer events = getEventProducer(); synchronized (events) { nextEvent = events.next(); } long delay = (long) (nextEvent * TimeUnit.SECONDS.toMillis(1) + testStarted - System.currentTimeMillis()); if (log.isDebugEnabled()) { log.debug("Calculated delay is {}", delay); } delay = Math.max(0, delay); long endTime = getThreadContext().getThread().getEndTime(); if (endTime > 0 && System.currentTimeMillis() + delay > endTime) { throw new JMeterStopThreadException("The thread is scheduled to stop in " + (System.currentTimeMillis() - endTime) + " ms" + " and the throughput timer generates a delay of " + delay + "." + " JMeter (as of 4.0) does not support interrupting of sleeping threads, thus terminating the thread manually." ); } return delay; }
JMeterThread thread = new JMeterThread(hashTree, null, null); log.debug("Num Threads: " + numThreads); for (int n = 0; n < numThreads; n++) { thread.setThreadNum(n); thread.setThreadName(Integer.toString(n)); tg.scheduleThread(thread, now); row.add(thread.getStartTime() - 1, 0); row.add(thread.getStartTime(), 1); thread.setThreadNum(n); thread.setThreadName(Integer.toString(n)); tg.scheduleThread(thread, now); row.add(thread.getEndTime() - 1, 0); row.add(thread.getEndTime(), -1);
@Override protected void scheduleThread(JMeterThread thread, long tgStartTime) { log.debug("Scheduling thread: " + thread.getThreadName()); if (threadsToSchedule < 1) { if (!scheduleIT.hasNext()) { throw new RuntimeException("Not enough schedule records for thread #" + thread.getThreadName()); } currentRecord = (CollectionProperty) scheduleIT.next(); threadsToSchedule = currentRecord.get(0).getIntValue(); } int numThreads = currentRecord.get(START_THREADS_CNT_FIELD_NO).getIntValue(); int initialDelay = currentRecord.get(INIT_DELAY_FIELD_NO).getIntValue(); int startRampUp = currentRecord.get(STARTUP_TIME_FIELD_NO).getIntValue(); int flightTime = currentRecord.get(HOLD_LOAD_FOR_FIELD_NO).getIntValue(); int endRampUp = currentRecord.get(SHUTDOWN_TIME_FIELD_NO).getIntValue(); long ascentPoint = tgStartTime + 1000 * initialDelay; final int rampUpDelayForThread = (int) Math.floor(1000 * startRampUp * (double) threadsToSchedule / numThreads); long startTime = ascentPoint + rampUpDelayForThread; long descentPoint = startTime + 1000 * flightTime + 1000 * startRampUp - rampUpDelayForThread; thread.setStartTime(startTime); thread.setEndTime(descentPoint + (int) Math.floor(1000 * endRampUp * (double) threadsToSchedule / numThreads)); thread.setScheduled(true); threadsToSchedule--; }