Author: mchassagneux
Date: Tue May 9 09:49:35 2017
New Revision: 1794517
URL: http://svn.apache.org/viewvc?rev=1794517&view=rev
Log:
Add a time shifting function
Bugzilla Id: 61040
Added:
jmeter/trunk/licenses/bin/hamcrest-date-2.0.4.txt
jmeter/trunk/src/functions/org/apache/jmeter/functions/TimeShift.java
jmeter/trunk/test/src/org/apache/jmeter/functions/TestTimeShiftFunction.java
Modified:
jmeter/trunk/LICENSE
jmeter/trunk/build.properties
jmeter/trunk/build.xml
jmeter/trunk/eclipse.classpath
jmeter/trunk/res/maven/ApacheJMeter_parent.pom
jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
jmeter/trunk/test/src/org/apache/jmeter/functions/FunctionTestHelper.java
jmeter/trunk/xdocs/changes.xml
jmeter/trunk/xdocs/usermanual/functions.xml
Modified: jmeter/trunk/LICENSE
URL:
http://svn.apache.org/viewvc/jmeter/trunk/LICENSE?rev=1794517&r1=1794516&r2=1794517&view=diff
==============================================================================
--- jmeter/trunk/LICENSE [utf-8] (original)
+++ jmeter/trunk/LICENSE [utf-8] Tue May 9 09:49:35 2017
@@ -277,3 +277,4 @@ For details, please see the files under:
* xmlpull-1.1.3.1.jar (Public Domain)
* xpp3-1.1.4c.jar (Indiana University Extreme! Lab Software License 1.1.1)
* xstream-1.4.9.jar (BSD)
+* hamcrest-date-2.0.4.jar (BSD)
Modified: jmeter/trunk/build.properties
URL:
http://svn.apache.org/viewvc/jmeter/trunk/build.properties?rev=1794517&r1=1794516&r2=1794517&view=diff
==============================================================================
--- jmeter/trunk/build.properties (original)
+++ jmeter/trunk/build.properties Tue May 9 09:49:35 2017
@@ -164,6 +164,12 @@ hamcrest-core.loc = ${maven2.
hamcrest-core.jar = hamcrest-core-${hamcrest-core.version}.jar
hamcrest-core.md5 = 6393363b47ddcbba82321110c3e07519
+# hamcrest-date
+hamcrest-date.version = 2.0.4
+hamcrest-date.loc =
${maven2.repo}/org/exparity/hamcrest-date/${hamcrest-date.version}
+hamcrest-date.jar = hamcrest-date-${hamcrest-date.version}.jar
+hamcrest-date.md5 = e37d0c3e0a578f4da48d0e8fee6e4c44
+
# Apache HttpASyncClient 4.x
httpasyncclient.version = 4.1.3
httpasyncclient.jar =
httpasyncclient-${httpasyncclient.version}.jar
Modified: jmeter/trunk/build.xml
URL:
http://svn.apache.org/viewvc/jmeter/trunk/build.xml?rev=1794517&r1=1794516&r2=1794517&view=diff
==============================================================================
--- jmeter/trunk/build.xml (original)
+++ jmeter/trunk/build.xml Tue May 9 09:49:35 2017
@@ -402,6 +402,7 @@
<include name="${lib.dir}/${freemarker.jar}"/>
<include name="${lib.dir}/${groovy-all.jar}"/>
<include name="${lib.dir}/${hamcrest-core.jar}"/>
+ <include name="${lib.dir}/${hamcrest-date.jar}"/>
<include name="${lib.dir}/${httpclient.jar}"/>
<include name="${lib.dir}/${httpasyncclient.jar}"/>
<include name="${lib.dir}/${httpcore.jar}"/>
@@ -483,6 +484,7 @@
<pathelement location="${lib.dir}/${freemarker.jar}"/>
<pathelement location="${lib.dir}/${groovy-all.jar}"/>
<pathelement location="${lib.dir}/${hamcrest-core.jar}"/>
+ <pathelement location="${lib.dir}/${hamcrest-date.jar}"/>
<pathelement location="${lib.dir}/${httpclient.jar}"/>
<pathelement location="${lib.dir}/${httpasyncclient.jar}"/>
<pathelement location="${lib.dir}/${httpcore.jar}"/>
Modified: jmeter/trunk/eclipse.classpath
URL:
http://svn.apache.org/viewvc/jmeter/trunk/eclipse.classpath?rev=1794517&r1=1794516&r2=1794517&view=diff
==============================================================================
--- jmeter/trunk/eclipse.classpath (original)
+++ jmeter/trunk/eclipse.classpath Tue May 9 09:49:35 2017
@@ -65,6 +65,7 @@
<classpathentry kind="lib" path="lib/freemarker-2.3.23.jar"/>
<classpathentry kind="lib" path="lib/groovy-all-2.4.11.jar"/>
<classpathentry kind="lib" path="lib/hamcrest-core-1.3.jar"/>
+ <classpathentry kind="lib" path="lib/hamcrest-date-2.0.4.jar"/>
<classpathentry kind="lib" path="lib/geronimo-jms_1.1_spec-1.1.1.jar"/>
<classpathentry kind="lib" path="lib/httpasyncclient-4.1.3.jar"/>
<classpathentry kind="lib" path="lib/httpclient-4.5.3.jar"/>
Added: jmeter/trunk/licenses/bin/hamcrest-date-2.0.4.txt
URL:
http://svn.apache.org/viewvc/jmeter/trunk/licenses/bin/hamcrest-date-2.0.4.txt?rev=1794517&view=auto
==============================================================================
--- jmeter/trunk/licenses/bin/hamcrest-date-2.0.4.txt (added)
+++ jmeter/trunk/licenses/bin/hamcrest-date-2.0.4.txt Tue May 9 09:49:35 2017
@@ -0,0 +1 @@
+According to
https://github.com/eXparity/hamcrest-date/blob/hamcrest-date-2.0.4/pom.xml#L18-L24
Hamcrest-date is under BSD License
\ No newline at end of file
Modified: jmeter/trunk/res/maven/ApacheJMeter_parent.pom
URL:
http://svn.apache.org/viewvc/jmeter/trunk/res/maven/ApacheJMeter_parent.pom?rev=1794517&r1=1794516&r2=1794517&view=diff
==============================================================================
--- jmeter/trunk/res/maven/ApacheJMeter_parent.pom (original)
+++ jmeter/trunk/res/maven/ApacheJMeter_parent.pom Tue May 9 09:49:35 2017
@@ -75,6 +75,7 @@ under the License.
<freemarker.version>2.3.23</freemarker.version>
<groovy-all.version>2.4.11</groovy-all.version>
<hamcrest-core.version>1.3</hamcrest-core.version>
+ <hamcrest-date.version>2.0.4</hamcrest-date.version>
<httpasyncclient.version>4.1.3</httpasyncclient.version>
<httpclient.version>4.5.3</httpclient.version>
<httpcore.version>4.4.6</httpcore.version>
@@ -433,6 +434,11 @@ under the License.
<artifactId>hamcrest-core</artifactId>
<version>${hamcrest-core.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.exparity</groupId>
+ <artifactId>hamcrest-date</artifactId>
+ <version>${hamcrest-date.version}</version>
+ </dependency>
</dependencies>
<repositories>
Modified: jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
URL:
http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties?rev=1794517&r1=1794516&r2=1794517&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
(original)
+++ jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties Tue
May 9 09:49:35 2017
@@ -243,6 +243,7 @@ database_sql_query_title=JDBC SQL Query
database_testing_title=JDBC Request
database_url=JDBC URL\:
database_url_jdbc_props=Database URL and JDBC Driver
+date_to_shift=Date to shift (optional) (default \: now )
ddn=DN
de=German
debug_off=Disable debug
@@ -1179,6 +1180,7 @@ throughput_control_perthread_label=Per U
throughput_control_title=Throughput Controller
throughput_control_tplabel=Throughput
time_format=Format string for SimpleDateFormat (optional)
+time_format_shift=Format string for DateTimeFormatter (optional) ( default
unix timestamp in millisecond )
timelim=Time limit
timeout_config_box_title=Timeout configuration
timeout_title=Timeout (ms)
@@ -1233,6 +1235,7 @@ userpw=Password
validate_threadgroup=Validate
value=Value
value_to_quote_meta=Value to escape from ORO Regexp meta chars
+value_to_shift=Amount of seconds/minutes/hours/days to add ( example P2D \:
plus one day ) (optional)
var_name=Reference Name
variable_name_param=Name of variable (may include variable and function
references)
view_graph_tree_title=View Graph Tree
Modified:
jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
URL:
http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties?rev=1794517&r1=1794516&r2=1794517&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
(original)
+++ jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
Tue May 9 09:49:35 2017
@@ -238,6 +238,7 @@ database_sql_query_title=Requ\u00EAte SQ
database_testing_title=Requ\u221A\u2122te JDBC
database_url=URL JDBC\:
database_url_jdbc_props=URL et driver JDBC de la base de donn\u221A\u00A9es
+date_to_shift=Date sur laquelle on applique le d\u00E9callage (optionnel)
(d\u00E9faut \: maintenant )
ddn=DN \:
de=Allemand
debug_off=D\u00E9sactiver le d\u00E9bogage
@@ -1168,7 +1169,8 @@ throughput_control_bypercent_label=Pourc
throughput_control_perthread_label=Par utilisateur
throughput_control_title=Contr\u00F4leur D\u00E9bit
throughput_control_tplabel=D\u00E9bit \:
-time_format=Chaine de formatage sur le mod\u00E8le SimpleDateFormat (optionnel)
+time_format=Cha00EEne de formatage sur le mod\u00E8le SimpleDateFormat
(optionnel)
+time_format_shift=Cha\u00EEne de formatage sur le mod\u00E8le
DateTimeFormatter (optionnel) ( d\u00E9faut \: unix timestamp en millisecondes )
timelim=Limiter le temps de r\u00E9ponses \u00E0 (ms)
timeout_config_box_title=Configuration du d\u00E9lai d'expiration
timeout_title=D\u00E9lai expiration (ms)
@@ -1223,6 +1225,7 @@ userpw=Mot de passe
validate_threadgroup=Valider
value=Valeur \:
value_to_quote_meta=Valeur \u00E0 \u00E9chapper des caract\u00E8res
sp\u00E9ciaux utilis\u00E8s par ORO Regexp
+value_to_shift=Valeur \u00E0 ajouter ( example P2D \: plus deux jour )
(optionnel)
var_name=Nom de r\u00E9f\u00E9rence \:
variable_name_param=Nom de variable (peut inclure une r\u00E9f\u00E9rence de
variable ou fonction)
view_graph_tree_title=Voir le graphique en arbre
Added: jmeter/trunk/src/functions/org/apache/jmeter/functions/TimeShift.java
URL:
http://svn.apache.org/viewvc/jmeter/trunk/src/functions/org/apache/jmeter/functions/TimeShift.java?rev=1794517&view=auto
==============================================================================
--- jmeter/trunk/src/functions/org/apache/jmeter/functions/TimeShift.java
(added)
+++ jmeter/trunk/src/functions/org/apache/jmeter/functions/TimeShift.java Tue
May 9 09:49:35 2017
@@ -0,0 +1,186 @@
+/*
+ * 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.functions;
+
+import java.time.Duration;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.Year;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.DateTimeParseException;
+import java.time.temporal.ChronoField;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.jmeter.engine.util.CompoundVariable;
+import org.apache.jmeter.samplers.SampleResult;
+import org.apache.jmeter.samplers.Sampler;
+import org.apache.jmeter.threads.JMeterVariables;
+import org.apache.jmeter.util.JMeterUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.github.benmanes.caffeine.cache.Cache;
+import com.github.benmanes.caffeine.cache.Caffeine;
+
+/**
+ * timeShifting Function permit to shift a date
+ *
+ * Parameters: - format date @see
+ *
https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html
+ * (optional - defaults to epoch time in millisecond) - date to shift formated
+ * as first param (optional - defaults now) - amount of (seconds, minutes,
+ * hours, days ) to add (optional - default nothing is add ) -
+ * variable name ( optional )
+ *
+ * Returns: a formatted date with the specified number of (seconds, minutes,
+ * hours, days or months ) added. - value is also saved in the variable for
+ * later re-use.
+ *
+ * @since 3.3
+ */
+public class TimeShift extends AbstractFunction {
+ private static final Logger log = LoggerFactory.getLogger(TimeShift.class);
+
+ private static final String KEY = "__timeShift"; // $NON-NLS-1$
+
+ private static final List<String> desc =
Arrays.asList(JMeterUtils.getResString("time_format_shift"),
+ JMeterUtils.getResString("date_to_shift"),
JMeterUtils.getResString("value_to_shift"),
+ JMeterUtils.getResString("function_name_paropt"));
+
+ // Ensure that these are set, even if no paramters are provided
+ private String format = ""; //$NON-NLS-1$
+ private String dateToShift = ""; //$NON-NLS-1$
+ private String amountToShift = ""; //$NON-NLS-1$
+ private String variableName = ""; //$NON-NLS-1$
+ private ZoneId systemDefaultZoneID = ZoneId.systemDefault();
+
+ /** Date time format cache handler **/
+ private Cache<String, DateTimeFormatter> dateTimeFormatterCache = null;
+
+ public TimeShift() {
+ super();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String execute(SampleResult previousResult, Sampler currentSampler)
throws InvalidVariableException {
+ String dateString;
+ LocalDateTime localDateTimeToShift =
LocalDateTime.now(systemDefaultZoneID);
+ DateTimeFormatter formatter = null;
+ if (!StringUtils.isEmpty(format)) {
+ try {
+ formatter = (DateTimeFormatter)
dateTimeFormatterCache.get(format, key -> createFormatter((String)key));
+ } catch (IllegalArgumentException ex) {
+ log.error("Format date pattern '{}' is invalid (see
https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html)",
format, ex); // $NON-NLS-1$
+ return "";
+ }
+ }
+
+ if (!dateToShift.isEmpty()) {
+ try {
+ if (formatter != null) {
+ localDateTimeToShift = LocalDateTime.parse(dateToShift,
formatter);
+ } else {
+ localDateTimeToShift =
LocalDateTime.ofInstant(Instant.ofEpochMilli(Long.parseLong(dateToShift)),
+ ZoneId.systemDefault());
+ }
+ } catch (DateTimeParseException | NumberFormatException ex) {
+ log.error("Failed to parse the date '{}' to shift",
dateToShift, ex); // $NON-NLS-1$
+ }
+ }
+
+ // Check amount value to shift
+ if (!StringUtils.isEmpty(amountToShift)) {
+ try {
+ Duration duration = Duration.parse(amountToShift);
+ localDateTimeToShift = localDateTimeToShift.plus(duration);
+ } catch (DateTimeParseException ex) {
+ log.error("Failed to parse the amount duration '{}' to shift
(see
https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html#parse-java.lang.CharSequence-)
", amountToShift, ex); // $NON-NLS-1$
+ }
+ }
+
+ if (formatter != null) {
+ dateString = localDateTimeToShift.format(formatter);
+ } else {
+ ZoneOffset offset =
ZoneOffset.systemDefault().getRules().getOffset(localDateTimeToShift);
+ dateString =
String.valueOf(localDateTimeToShift.toInstant(offset).toEpochMilli());
+ }
+
+ if (!StringUtils.isEmpty(variableName)) {
+ JMeterVariables vars = getVariables();
+ if (vars != null) {// vars will be null on TestPlan
+ vars.put(variableName, dateString);
+ }
+ }
+ return dateString;
+ }
+
+ private DateTimeFormatter createFormatter(String format) throws
IllegalArgumentException {
+
+ log.debug("Create a new instance of DateTimeFormatter for format '{}'
in the cache", format);
+ return new
DateTimeFormatterBuilder().appendPattern(format).parseDefaulting(ChronoField.NANO_OF_SECOND,
0)
+ .parseDefaulting(ChronoField.MILLI_OF_SECOND,
0).parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
+ .parseDefaulting(ChronoField.MINUTE_OF_HOUR,
0).parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
+ .parseDefaulting(ChronoField.DAY_OF_MONTH,
1).parseDefaulting(ChronoField.MONTH_OF_YEAR, 1)
+ .parseDefaulting(ChronoField.YEAR_OF_ERA,
Year.now().getValue()).toFormatter(JMeterUtils.getLocale());
+ }
+
+ protected static Cache<String, DateTimeFormatter> buildCache() {
+ Caffeine<Object, Object> cacheBuilder = Caffeine.newBuilder();
+ cacheBuilder.maximumSize(100);
+ return cacheBuilder.build();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setParameters(Collection<CompoundVariable> parameters) throws
InvalidVariableException {
+
+ checkParameterCount(parameters, 0, 4);
+ Object[] values = parameters.toArray();
+
+ format = ((CompoundVariable) values[0]).execute().trim();
+ dateToShift = ((CompoundVariable) values[1]).execute().trim();
+ amountToShift = ((CompoundVariable) values[2]).execute().trim();
+ variableName = ((CompoundVariable) values[3]).execute().trim();
+
+ // Create the cache
+ if (dateTimeFormatterCache == null) {
+ dateTimeFormatterCache = buildCache();
+ }
+
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String getReferenceKey() {
+ return KEY;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public List<String> getArgumentDesc() {
+ return desc;
+ }
+}
Modified:
jmeter/trunk/test/src/org/apache/jmeter/functions/FunctionTestHelper.java
URL:
http://svn.apache.org/viewvc/jmeter/trunk/test/src/org/apache/jmeter/functions/FunctionTestHelper.java?rev=1794517&r1=1794516&r2=1794517&view=diff
==============================================================================
--- jmeter/trunk/test/src/org/apache/jmeter/functions/FunctionTestHelper.java
(original)
+++ jmeter/trunk/test/src/org/apache/jmeter/functions/FunctionTestHelper.java
Tue May 9 09:49:35 2017
@@ -25,16 +25,12 @@ import org.apache.jmeter.engine.util.Com
public class FunctionTestHelper {
- public static Collection<CompoundVariable> makeParams(String p1, String
p2, String p3) {
+ public static Collection<CompoundVariable> makeParams(String... params) {
Collection<CompoundVariable> parms = new LinkedList<>();
- if (p1 != null) {
- parms.add(new CompoundVariable(p1));
- }
- if (p2 != null) {
- parms.add(new CompoundVariable(p2));
- }
- if (p3 != null) {
- parms.add(new CompoundVariable(p3));
+ for (String p : params) {
+ if (p != null) {
+ parms.add(new CompoundVariable(p));
+ }
}
return parms;
}
Added:
jmeter/trunk/test/src/org/apache/jmeter/functions/TestTimeShiftFunction.java
URL:
http://svn.apache.org/viewvc/jmeter/trunk/test/src/org/apache/jmeter/functions/TestTimeShiftFunction.java?rev=1794517&view=auto
==============================================================================
---
jmeter/trunk/test/src/org/apache/jmeter/functions/TestTimeShiftFunction.java
(added)
+++
jmeter/trunk/test/src/org/apache/jmeter/functions/TestTimeShiftFunction.java
Tue May 9 09:49:35 2017
@@ -0,0 +1,140 @@
+/*
+ * 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.functions;
+
+import static org.apache.jmeter.functions.FunctionTestHelper.makeParams;
+import static org.exparity.hamcrest.date.LocalDateMatchers.sameDay;
+import static org.exparity.hamcrest.date.LocalDateTimeMatchers.within;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
+import java.util.Collection;
+import java.util.TimeZone;
+
+import org.apache.jmeter.engine.util.CompoundVariable;
+import org.apache.jmeter.junit.JMeterTestCase;
+import org.apache.jmeter.samplers.SampleResult;
+import org.apache.jmeter.threads.JMeterContext;
+import org.apache.jmeter.threads.JMeterContextService;
+import org.apache.jmeter.threads.JMeterVariables;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestTimeShiftFunction extends JMeterTestCase {
+ private Function function;
+
+ private SampleResult result;
+
+ private JMeterVariables vars;
+
+ private JMeterContext jmctx = null;
+
+ private String value;
+
+ @Before
+ public void setUp() {
+ jmctx = JMeterContextService.getContext();
+ vars = new JMeterVariables();
+ jmctx.setVariables(vars);
+ jmctx.setPreviousResult(result);
+ result = new SampleResult();
+ function = new TimeShift();
+ }
+
+ @Test
+ public void testDatePlusOneDay() throws Exception {
+ Collection<CompoundVariable> params = makeParams("yyyy-dd-MM",
"2017-01-01", "P1D", "");
+ function.setParameters(params);
+ value = function.execute(result, null);
+ assertThat(value, is(equalTo("2017-02-01")));
+ }
+
+ @Test
+ public void testDatePlusOneDayInVariable() throws Exception {
+ Collection<CompoundVariable> params = makeParams("yyyy-dd-MM",
"2017-01-01", "P1d", "VAR");
+ function.setParameters(params);
+ function.execute(result, null);
+ assertThat(vars.get("VAR"), is(equalTo("2017-02-01")));
+ }
+
+ @Test
+ public void testDatePlusComplexPeriod() throws Exception {
+ Collection<CompoundVariable> params = makeParams("yyyy-dd-MM HH:m",
"2017-01-01 12:00", "P+32dT-1H-5m", "VAR");
+ function.setParameters(params);
+ String value = function.execute(result, null);
+ assertThat(value, is(equalTo("2017-02-02 10:55")));
+ }
+
+ @Test
+ public void testDefault() throws Exception {
+ Collection<CompoundVariable> params = makeParams("", "", "", "");
+ function.setParameters(params);
+ value = function.execute(result, null);
+ long resultat = Long.parseLong(value);
+ LocalDateTime nowFromFunction =
LocalDateTime.ofInstant(Instant.ofEpochMilli(resultat), TimeZone
+ .getDefault().toZoneId());
+ assertThat(nowFromFunction, within(5, ChronoUnit.SECONDS,
LocalDateTime.now()));
+ }
+
+ @Test
+ public void testNowPlusOneDay() throws Exception {
+ Collection<CompoundVariable> params = makeParams("YYYY-MM-dd", "",
"P1d", "");
+ function.setParameters(params);
+ value = function.execute(result, null);
+ LocalDate tomorrow = LocalDate.now().plusDays(1);
+ LocalDate tomorrowFromFunction = LocalDate.parse(value);
+ assertThat(tomorrowFromFunction, sameDay(tomorrow));
+ }
+
+ @Test
+ public void testNowWithComplexPeriod() throws Exception {
+ Collection<CompoundVariable> params =
makeParams("YYYY-MM-dd'T'HH:mm:ss", "", "P10DT-1H-5M5S", "");
+ function.setParameters(params);
+ value = function.execute(result, null);
+ LocalDateTime futureDate =
LocalDateTime.now().plusDays(10).plusHours(-1).plusMinutes(-5).plusSeconds(5);
+ LocalDateTime futureDateFromFunction = LocalDateTime.parse(value);
+ assertThat(futureDateFromFunction, within(1, ChronoUnit.SECONDS,
futureDate));
+ }
+
+ @Test
+ public void testWrongAmountToAdd() throws Exception {
+ // Nothing is add with wrong value, so check if return is now
+ Collection<CompoundVariable> params = makeParams("", "", "qefv1Psd",
"");
+ function.setParameters(params);
+ value = function.execute(result, null);
+ long resultat = Long.parseLong(value);
+ LocalDateTime nowFromFunction =
LocalDateTime.ofInstant(Instant.ofEpochMilli(resultat), TimeZone
+ .getDefault().toZoneId());
+ assertThat(nowFromFunction, within(5, ChronoUnit.SECONDS,
LocalDateTime.now()));
+ }
+
+ @Test
+ public void testWrongFormatDate() throws Exception {
+ Collection<CompoundVariable> params = makeParams("hjfdjyra:fd", "",
"P1D", "");
+ function.setParameters(params);
+ value = function.execute(result, null);
+ assertThat(value, is(equalTo("")));
+ }
+
+}
Modified: jmeter/trunk/xdocs/changes.xml
URL:
http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1794517&r1=1794516&r2=1794517&view=diff
==============================================================================
--- jmeter/trunk/xdocs/changes.xml [utf-8] (original)
+++ jmeter/trunk/xdocs/changes.xml [utf-8] Tue May 9 09:49:35 2017
@@ -107,6 +107,7 @@ Summary
<h3>Functions</h3>
<ul>
+ <li><bug>61040</bug>Add a time shifting function</li>
</ul>
<h3>I18N</h3>
Modified: jmeter/trunk/xdocs/usermanual/functions.xml
URL:
http://svn.apache.org/viewvc/jmeter/trunk/xdocs/usermanual/functions.xml?rev=1794517&r1=1794516&r2=1794517&view=diff
==============================================================================
--- jmeter/trunk/xdocs/usermanual/functions.xml (original)
+++ jmeter/trunk/xdocs/usermanual/functions.xml Tue May 9 09:49:35 2017
@@ -112,6 +112,7 @@ Alternatively, just use <code>/</code> i
<tr><td>Information</td><td> <a
href="#__machineIP">machineIP</a></td><td>get the local machine IP
address</td><td>2.6</td></tr>
<tr><td>Information</td><td> <a
href="#__machineName">machineName</a></td><td>get the local machine
name</td><td>1.X</td></tr>
<tr><td>Information</td><td> <a href="#__time">time</a></td><td>return
current time in various formats</td><td>2.2</td></tr>
+ <tr><td>Information</td><td> <a
href="#__timeShift">timeShift</a></td><td>return a date in various formats with
the specified amount of seconds/minutes/hours/days added</td><td>3.3</td></tr>
<tr><td>Information</td><td> <a href="#__log">log</a></td><td>log (or
display) a message (and return the value)</td><td>2.2</td></tr>
<tr><td>Information</td><td> <a href="#__logn">logn</a></td><td>log
(or display) a message (empty return value)</td><td>2.2</td></tr>
<tr><td>Input</td><td> <a
href="#__StringFromFile">StringFromFile</a></td><td>read a line from a
file</td><td>1.9</td></tr>
@@ -1499,6 +1500,34 @@ becomes:
</properties>
</component>
+
+<component index="§-num;.5.22" name="__timeShift">
+<description>
+ <p>The timeShift function returns a date in the given format with the
specified amount of seconds, minutes, hours, days or months added</p>
+ </description>
+<properties>
+ <property name="Format" required="No">
+ The format to be passed to DateTimeFormatter.
+ If omitted, the function uses milliseconds since epoch format.
+ </property>
+ <property name="Date to shift" required="No">
+ Indicate the date in the format set by the parameter 'Format' to shift
+ If omitted, the date is set to now
+ </property>
+ <property name="value to shift" required="No">
+ Indicate the specified amount of seconds, minutes, hours or days to
shift according to a textual representation of a duration such as PnDTnHnMn.nS.
See
https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html#parse-java.lang.CharSequence-
+ <ul>
+ <li><code>PT20.345S</code> parses as 20.345 seconds</li>
+ <li><code>PT15M</code> parses as 15 minutes</li>
+ <li><code>PT10H</code> parses as 10 hours</li>
+ <li><code>P2D</code> parses as 2 days</li>
+ <li><code>-P6H3M</code> parses as -6 hours and -3 minutes</li>
+ </ul>
+ </property>
+ <property name="Name of variable" required="No">The name of the
variable to set.</property>
+</properties>
+</component>
+
</subsection>
<subsection name="§-num;.6 Pre-defined Variables" anchor="predefinedvars">