From 0a4e81b59391298ef4cc3fecad1d1fe5d31f37ca Mon Sep 17 00:00:00 2001 From: Felix Schumacher Date: Mon, 20 Aug 2018 16:16:34 +0200 Subject: [PATCH] Use endTime of JMeterThread for SyncTimer --- .../org/apache/jmeter/timers/SyncTimer.java | 11 ++- .../apache/jmeter/timers/SyncTimerSpec.groovy | 95 +++++++++++++++++++ 2 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 test/src/org/apache/jmeter/timers/SyncTimerSpec.groovy diff --git a/src/components/org/apache/jmeter/timers/SyncTimer.java b/src/components/org/apache/jmeter/timers/SyncTimer.java index d80ba2f7a..62b727545 100644 --- a/src/components/org/apache/jmeter/timers/SyncTimer.java +++ b/src/components/org/apache/jmeter/timers/SyncTimer.java @@ -171,14 +171,19 @@ public class SyncTimer extends AbstractTestElement implements Timer, Serializabl if(getGroupSize()>=0) { int arrival = 0; try { + long endTime = getThreadContext().getThread().getEndTime(); + long maxWaitInMS = endTime > 0 ? Math.max(0, endTime - System.currentTimeMillis()) : Long.MAX_VALUE; if(timeoutInMs==0) { - arrival = this.barrier.await(); + arrival = this.barrier.await(maxWaitInMS, TimeUnit.MILLISECONDS); } else if(timeoutInMs > 0){ - arrival = this.barrier.await(timeoutInMs, TimeUnit.MILLISECONDS); + arrival = this.barrier.await(Math.min(timeoutInMs, maxWaitInMS), TimeUnit.MILLISECONDS); } else { throw new IllegalArgumentException("Negative value for timeout:"+timeoutInMs+" in Synchronizing Timer "+getName()); } - } catch (InterruptedException | BrokenBarrierException e) { + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return 0; + } catch (BrokenBarrierException e) { return 0; } catch (TimeoutException e) { if (log.isWarnEnabled()) { diff --git a/test/src/org/apache/jmeter/timers/SyncTimerSpec.groovy b/test/src/org/apache/jmeter/timers/SyncTimerSpec.groovy new file mode 100644 index 000000000..e4731150b --- /dev/null +++ b/test/src/org/apache/jmeter/timers/SyncTimerSpec.groovy @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.jmeter.timers + +import org.apache.jmeter.threads.JMeterContext +import org.apache.jmeter.threads.JMeterContextService +import org.apache.jmeter.threads.JMeterThread + +import spock.lang.Specification + +class SyncTimerSpec extends Specification { + + + def "timer with scheduled end point"() { + setup: + def timer = new SyncTimer() + def ctx = Stub(JMeterContext) + def thread = Stub(JMeterThread) + + thread.getEndTime() >> System.currentTimeMillis() + 100L + ctx.getThread() >> thread + + timer.threadContext = ctx + timer.groupSize = 2 + timer.testStarted() + when: + def start = System.currentTimeMillis(); + def delay = timer.delay() + def elapsed = System.currentTimeMillis() - start + then: + delay == 0 + elapsed < 10 * 100L + } + + def "timer with scheduled end point and shorter max timeout in ms"() { + setup: + def timer = new SyncTimer() + timer.setTimeoutInMs(100L) + def ctx = Stub(JMeterContext) + def thread = Stub(JMeterThread) + + thread.getEndTime() >> System.currentTimeMillis() + 2000L + ctx.getThread() >> thread + + timer.threadContext = ctx + timer.groupSize = 2 + timer.testStarted() + when: + def start = System.currentTimeMillis(); + def delay = timer.delay() + def elapsed = System.currentTimeMillis() - start + then: + delay == 0 + elapsed < 10 * 100L + } + + def "timer with scheduled end point and longer max timeout in ms"() { + setup: + def timer = new SyncTimer() + timer.setTimeoutInMs(2000L) + def ctx = Stub(JMeterContext) + def thread = Stub(JMeterThread) + + thread.getEndTime() >> System.currentTimeMillis() + 100L + ctx.getThread() >> thread + + timer.threadContext = ctx + timer.groupSize = 2 + timer.testStarted() + when: + def start = System.currentTimeMillis(); + def delay = timer.delay() + def elapsed = System.currentTimeMillis() - start + then: + delay == 0 + elapsed < 10 * 100L + } + +} \ No newline at end of file -- 2.17.1