You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@jmeter.apache.org by max3163 <gi...@git.apache.org> on 2017/04/25 13:29:56 UTC

[GitHub] jmeter pull request #291: Add time shifting function

GitHub user max3163 opened a pull request:

    https://github.com/apache/jmeter/pull/291

    Add time shifting function

    Add a new function to shift date easily.

You can merge this pull request into a Git repository by running:

    $ git pull https://github.com/max3163/jmeter timeShiftingFunction

Alternatively you can review and apply these changes as the patch at:

    https://github.com/apache/jmeter/pull/291.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

    This closes #291
    
----
commit 16e9db26c3fb7c82c957934db01b732eba9a367b
Author: Chassagneux Maxime <41...@airfrance.fr>
Date:   2017-04-25T13:07:18Z

    Add time shifting function

----


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by pmouawad <gi...@git.apache.org>.
Github user pmouawad commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113294131
  
    --- Diff: src/functions/org/apache/jmeter/functions/TimeShiftingFunction.java ---
    @@ -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.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.Collection;
    +import java.util.LinkedList;
    +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;
    +
    +/**
    + * 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 / months ) to add (optional - default nothing is add )
    + * - variable name ( optional )
    + *
    + * Returns:
    + * - Returns a formated date with the specified number of (seconds / minutes / hours / days / months ) added.
    + * - value is also saved in the variable for later re-use.
    + *
    + * @since 3.3
    + */
    +public class TimeShiftingFunction extends AbstractFunction {
    +    private static final Logger log = LoggerFactory.getLogger(TimeShiftingFunction.class);
    +
    +    private static final String KEY = "__timeShifting"; // $NON-NLS-1$
    +
    +    private static final List<String> desc = new LinkedList<>();
    +    
    +    static {
    +        desc.add(JMeterUtils.getResString("time_format_shift")); //$NON-NLS-1$
    +        desc.add(JMeterUtils.getResString("date_to_shift")); //$NON-NLS-1$
    +        desc.add(JMeterUtils.getResString("value_to_shift")); //$NON-NLS-1$
    +        desc.add(JMeterUtils.getResString("function_name_paropt")); //$NON-NLS-1$
    +    }
    +
    +    // 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 shift = ""; //$NON-NLS-1$
    +    private String variable = ""; //$NON-NLS-1$
    +
    +    public TimeShiftingFunction() {
    +        super();
    +    }
    +
    +    /** {@inheritDoc} */
    +    @Override
    +    public String execute(SampleResult previousResult, Sampler currentSampler) throws InvalidVariableException {
    +        String dateString;
    +        LocalDateTime localDateTimeToShift = LocalDateTime.now( ZoneId.systemDefault() );
    +        DateTimeFormatter formatter = null; 
    +        if (!StringUtils.isEmpty(format)) {
    +            try {
    +                formatter = 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());
    +            } catch (IllegalArgumentException ex) {
    +                log.error("Pattern is invalid", ex); // $NON-NLS-1$
    +            }
    +        }
    +
    +        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 date to shift", ex); // $NON-NLS-1$
    +            }
    +        }
    +
    +        // Check amount value to shift
    +        if (!StringUtils.isEmpty(shift)) {
    +            int strLength = shift.length();
    +            Character lastChar = shift.charAt(strLength - 1);
    +            try {
    +                long amount = Long.parseLong(shift.substring(0, strLength - 1));
    +                switch (lastChar) {
    +                case 's':
    +                    localDateTimeToShift = localDateTimeToShift.plusSeconds(amount);
    +                    break;
    +                case 'm':
    +                    localDateTimeToShift = localDateTimeToShift.plusMinutes(amount);
    +                    break;
    +                case 'H':
    +                    localDateTimeToShift = localDateTimeToShift.plusHours(amount);
    +                    break;
    +                case 'd':
    +                    localDateTimeToShift = localDateTimeToShift.plusDays(amount);
    +                    break;
    +                case 'M':
    +                    localDateTimeToShift = localDateTimeToShift.plusMonths(amount);
    +                    break;
    +                }
    +            } catch (NumberFormatException nfe) {
    +                log.warn("Failed to parse amount of time to add", nfe); // $NON-NLS-1$
    --- End diff --
    
    Mention amount


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by pmouawad <gi...@git.apache.org>.
Github user pmouawad commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113292969
  
    --- Diff: src/core/org/apache/jmeter/resources/messages_fr.properties ---
    @@ -1169,6 +1170,7 @@ 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_shift=Chaine de formatage sur le mod\u00E8le DateTimeFormatter (optionnel) ( defaut unix timestamp en milliseconde )
    --- End diff --
    
    Cha�ne
    millisecondes


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter issue #291: Add time shifting function

Posted by pmouawad <gi...@git.apache.org>.
Github user pmouawad commented on the issue:

    https://github.com/apache/jmeter/pull/291
  
    Hello,
    Regarding format, for maintainability and documentation, using Java8 Duration is better IMO.
    
    Regards



---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by max3163 <gi...@git.apache.org>.
Github user max3163 commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113761987
  
    --- Diff: src/functions/org/apache/jmeter/functions/TimeShift.java ---
    @@ -0,0 +1,188 @@
    +/*
    + * 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.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 java.util.regex.Matcher;
    +import java.util.regex.Pattern;
    +
    +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;
    +
    +/**
    + * 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 or months ) 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 Pattern pattern = Pattern.compile("(?:((?:[+-])?\\d+)([MdHms]))");
    +    
    +    public TimeShift() {
    +        super();
    +    }
    +
    +    /** {@inheritDoc} */
    +    @Override
    +    public String execute(SampleResult previousResult, Sampler currentSampler) throws InvalidVariableException {
    +        String dateString;
    +        LocalDateTime localDateTimeToShift = LocalDateTime.now(ZoneId.systemDefault());
    +        DateTimeFormatter formatter = null;
    +        if (!StringUtils.isEmpty(format)) {
    +            try {
    +                formatter = new DateTimeFormatterBuilder().appendPattern(format)
    --- End diff --
    
    I had a caffeine cache but I don't know how to set it ( size / expiration ... ? )


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by max3163 <gi...@git.apache.org>.
Github user max3163 commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113871604
  
    --- Diff: src/functions/org/apache/jmeter/functions/TimeShift.java ---
    @@ -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 or months ) 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<Object, Object> 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<Object, Object> buildCache() {
    --- End diff --
    
    Thanks ! done


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by pmouawad <gi...@git.apache.org>.
Github user pmouawad commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113292880
  
    --- Diff: src/core/org/apache/jmeter/resources/messages_fr.properties ---
    @@ -238,6 +238,7 @@ database_sql_query_title=Requ\u00EAte SQL JDBC par d\u00E9faut
     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 laquel on applique le d\u00E9callage (optionnel) (defaut \: maintenant )
    --- End diff --
    
    laquelle, 
    d\u00E9faut


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by max3163 <gi...@git.apache.org>.
Github user max3163 commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113760549
  
    --- Diff: test/src/org/apache/jmeter/functions/TestTimeShiftFunction.java ---
    @@ -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", "1d", "");
    +        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", "1d", "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", "+1M+1d-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", "", "1d", "");
    +        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", "", "+1M+1d-1H-5m5s", "");
    +        function.setParameters(params);
    +        value = function.execute(result, null);
    +        LocalDateTime futureDate = LocalDateTime.now().plusMonths(1).plusDays(1).plusHours(-1).plusMinutes(-5).plusSeconds(5);
    +        LocalDateTime futureDateFromFunction = LocalDateTime.parse(value);
    --- End diff --
    
    the test use the default one.
    The string must represent a valid date-time and is parsed using DateTimeFormatter.ISO_LOCAL_DATE_TIME.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by FSchumacher <gi...@git.apache.org>.
Github user FSchumacher commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113534765
  
    --- Diff: xdocs/usermanual/functions.xml ---
    @@ -1499,6 +1502,36 @@ becomes:
     </properties>
     </component>
     
    +
    +<component index="&sect-num;.5.22" name="__timeShifting">
    +<description>
    +    <p>The timeShifting function returns a date in various formats with the specified amount of seconds/minutes/hours/days/months added</p>
    +    </description>
    +<properties>
    +        <property name="Format" required="No">
    +        The format to be passed to DateTimeFormatter.
    +        If omitted, the function use milliseconds since epoch format.
    +        </property>
    +        <property name="Date to shift" required="No">
    +        Indicate the date with the format from first paramater 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/days/mounths to add according to this usage :
    +        <ul>
    +        <li><code>5s</code> for Second value</li>
    +        <li><code>5m</code> for Minute value</li>
    +        <li><code>5H</code> for Hour value</li>
    +        <li><code>5d</code> for Day value</li>
    +        <li><code>5M</code> for Month value</li>
    +        </ul>
    +        To shift in the pass, you just have to indicate <code>-5d</code>  to remove 5 days.
    --- End diff --
    
    "into the past"? 
    "to subtract five days" or "to move five days backwards"?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by PascalSchumacher <gi...@git.apache.org>.
Github user PascalSchumacher commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113698827
  
    --- Diff: res/maven/ApacheJMeter_parent.pom ---
    @@ -427,6 +428,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>
    --- End diff --
    
    I guess this dependency should have test scope.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by vlsi <gi...@git.apache.org>.
Github user vlsi commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113695286
  
    --- Diff: build.xml ---
    @@ -400,6 +400,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}"/>
    --- End diff --
    
    This line seems to be using tabs while file is using spaces for indent. Can you please convert to spaces?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by vlsi <gi...@git.apache.org>.
Github user vlsi commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113696083
  
    --- Diff: licenses/bin/hamcrest-date-2.0.4.txt ---
    @@ -0,0 +1 @@
    +According to https://github.com/eXparity/hamcrest-date Hamcrest-date is under BSD License
    --- End diff --
    
    >According to https://github.com/eXparity/hamcrest-date
    
    I'm not sure https://github.com/eXparity/hamcrest-date would always represent licensing state for hamcrest-date-2.0.4
    
    Should some more specific link be used here? For instance, https://search.maven.org/#artifactdetails%7Corg.exparity%7Chamcrest-date%7C2.0.4%7Cjar or https://github.com/eXparity/hamcrest-date/blob/hamcrest-date-2.0.4/pom.xml#L18-L24 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by max3163 <gi...@git.apache.org>.
Github user max3163 closed the pull request at:

    https://github.com/apache/jmeter/pull/291


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by FSchumacher <gi...@git.apache.org>.
Github user FSchumacher commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113539786
  
    --- Diff: src/functions/org/apache/jmeter/functions/TimeShiftingFunction.java ---
    @@ -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.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.Collection;
    +import java.util.LinkedList;
    +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;
    +
    +/**
    + * 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 / months ) to add (optional - default nothing is add ) -
    + * variable name ( optional )
    + *
    + * Returns: - Returns a formated date with the specified number of (seconds /
    + * minutes / hours / days / months ) added. - value is also saved in the
    + * variable for later re-use.
    + *
    + * @since 3.3
    + */
    +public class TimeShiftingFunction extends AbstractFunction {
    +    private static final Logger log = LoggerFactory.getLogger(TimeShiftingFunction.class);
    +
    +    private static final String KEY = "__timeShifting"; // $NON-NLS-1$
    +
    +    private static final List<String> desc = new LinkedList<>();
    +
    +    static {
    +        desc.add(JMeterUtils.getResString("time_format_shift")); //$NON-NLS-1$
    +        desc.add(JMeterUtils.getResString("date_to_shift")); //$NON-NLS-1$
    +        desc.add(JMeterUtils.getResString("value_to_shift")); //$NON-NLS-1$
    +        desc.add(JMeterUtils.getResString("function_name_paropt")); //$NON-NLS-1$
    +    }
    +
    +    // 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 shift = ""; //$NON-NLS-1$
    --- End diff --
    
    I would name it `amountToShift`.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by max3163 <gi...@git.apache.org>.
Github user max3163 commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113705740
  
    --- Diff: src/functions/org/apache/jmeter/functions/TimeShift.java ---
    @@ -0,0 +1,188 @@
    +/*
    + * 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.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 java.util.regex.Matcher;
    +import java.util.regex.Pattern;
    +
    +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;
    +
    +/**
    + * 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 or months ) 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 Pattern pattern = Pattern.compile("(?:((?:[+-])?\\d+)([MdHms]))");
    --- End diff --
    
    Why not, if we use my implementation it's possible but not if we use the Duration native java one.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by FSchumacher <gi...@git.apache.org>.
Github user FSchumacher commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113539229
  
    --- Diff: test/src/org/apache/jmeter/functions/TestTimeShiftingFunction.java ---
    @@ -0,0 +1,161 @@
    +/*
    + * 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.junit.Assert.assertTrue;
    +
    +import java.time.Instant;
    +import java.util.Collection;
    +import java.util.LinkedList;
    +
    +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 TestTimeShiftingFunction extends JMeterTestCase {
    +        private Function function;
    +
    +        private SampleResult result;
    +
    +        private Collection<CompoundVariable> params;
    +
    +        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);
    +            params = new LinkedList<>();
    +            result = new SampleResult();
    +            function = new TimeShiftingFunction();
    +        }
    +
    +        @Test
    +        public void testDatePlusOneDay() throws Exception {
    +            Collection<CompoundVariable> params = makeParams("yyyy-dd-MM","2017-01-01","1d","");
    +            function.setParameters(params);
    +            value = function.execute(result, null);
    +            assertTrue(value.equalsIgnoreCase("2017-02-01"));
    +        }
    +        
    +        @Test
    +        public void testDatePlusOneDayInVariable() throws Exception {
    +            Collection<CompoundVariable> params = makeParams("yyyy-dd-MM","2017-01-01","1d","VAR");
    +            function.setParameters(params);
    +            function.execute(result, null);
    +            assertTrue(vars.get("VAR").equalsIgnoreCase("2017-02-01"));
    +        }
    +        
    +        @Test
    +        public void testDateLessOneDay() throws Exception {
    +            Collection<CompoundVariable> params = makeParams("yyyy-dd-MM","2017-01-01","-1d","");
    +            function.setParameters(params);
    +            value = function.execute(result, null);
    +            assertTrue(value.equalsIgnoreCase("2016-31-12"));
    +        }
    +        
    +        @Test
    +        public void testDatePlusOneHour() throws Exception {
    +            Collection<CompoundVariable> params = makeParams("HH:mm:ss","14:00:00","1H","");
    +            function.setParameters(params);
    +            value = function.execute(result, null);
    +            assertTrue(value.equalsIgnoreCase("15:00:00"));
    +        }
    +        
    +        @Test
    +        public void testDateLessOneMinute() throws Exception {
    +            Collection<CompoundVariable> params = makeParams("HH:mm:ss","14:00:00","-1m","");
    +            function.setParameters(params);
    +            value = function.execute(result, null);
    +            assertTrue(value.equalsIgnoreCase("13:59:00"));
    +        }
    +        
    +        @Test
    +        public void testDefault() throws Exception {
    +            Collection<CompoundVariable> params = makeParams("","","","");
    +            function.setParameters(params);
    +            long before = Instant.now().toEpochMilli();
    +            value = function.execute(result, null);
    +            long after = Instant.now().toEpochMilli();
    +            long now = Long.parseLong(value);
    +            assertTrue(now >= before && now <= after);
    --- End diff --
    
    If we use assertThat with CoreMatchers, we get the values, of the assertions in case of a failing test. It might be nice to use a compare method on Instant instead of converting everything to longs.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by FSchumacher <gi...@git.apache.org>.
Github user FSchumacher commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113536574
  
    --- Diff: xdocs/usermanual/functions.xml ---
    @@ -1499,6 +1502,36 @@ becomes:
     </properties>
     </component>
     
    +
    +<component index="&sect-num;.5.22" name="__timeShifting">
    +<description>
    +    <p>The timeShifting function returns a date in various formats with the specified amount of seconds/minutes/hours/days/months added</p>
    +    </description>
    +<properties>
    +        <property name="Format" required="No">
    +        The format to be passed to DateTimeFormatter.
    +        If omitted, the function use milliseconds since epoch format.
    +        </property>
    +        <property name="Date to shift" required="No">
    +        Indicate the date with the format from first paramater 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/days/mounths to add according to this usage :
    --- End diff --
    
    mounths => months
    seconds, minutes, ... or months
    
    As a side note, in english microtypography there is no space in front of a colon, as is in french microtypography.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by FSchumacher <gi...@git.apache.org>.
Github user FSchumacher commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113537122
  
    --- Diff: xdocs/usermanual/functions.xml ---
    @@ -1499,6 +1502,36 @@ becomes:
     </properties>
     </component>
     
    +
    +<component index="&sect-num;.5.22" name="__timeShifting">
    +<description>
    +    <p>The timeShifting function returns a date in various formats with the specified amount of seconds/minutes/hours/days/months added</p>
    +    </description>
    +<properties>
    +        <property name="Format" required="No">
    +        The format to be passed to DateTimeFormatter.
    +        If omitted, the function use milliseconds since epoch format.
    +        </property>
    +        <property name="Date to shift" required="No">
    +        Indicate the date with the format from first paramater to shift
    --- End diff --
    
    paramater => parameter
    "the date in the format set by the parameter 'Format'"


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by ben-manes <gi...@git.apache.org>.
Github user ben-manes commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113822733
  
    --- Diff: src/functions/org/apache/jmeter/functions/TimeShift.java ---
    @@ -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 or months ) 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<Object, Object> 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<Object, Object> buildCache() {
    --- End diff --
    
    You can make this typesafe by returning `Cache<String, DateTimeFormatter>`. The generics are inferred at the `build()` step rather than construction, which might have caused confusion.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter issue #291: Add time shifting function

Posted by max3163 <gi...@git.apache.org>.
Github user max3163 commented on the issue:

    https://github.com/apache/jmeter/pull/291
  
    I took into account all yours feedbacks, so please can you review new commits ?
    I add a new library ( hamcrest-date ) to easily check date.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by vlsi <gi...@git.apache.org>.
Github user vlsi commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113700339
  
    --- Diff: test/src/org/apache/jmeter/functions/TestTimeShiftFunction.java ---
    @@ -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", "1d", "");
    +        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", "1d", "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", "+1M+1d-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", "", "1d", "");
    +        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", "", "+1M+1d-1H-5m5s", "");
    +        function.setParameters(params);
    +        value = function.execute(result, null);
    +        LocalDateTime futureDate = LocalDateTime.now().plusMonths(1).plusDays(1).plusHours(-1).plusMinutes(-5).plusSeconds(5);
    +        LocalDateTime futureDateFromFunction = LocalDateTime.parse(value);
    --- End diff --
    
    Should format be added to `LocalDateTime.parse`?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by FSchumacher <gi...@git.apache.org>.
Github user FSchumacher commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113539596
  
    --- Diff: src/functions/org/apache/jmeter/functions/TimeShiftingFunction.java ---
    @@ -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.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.Collection;
    +import java.util.LinkedList;
    +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;
    +
    +/**
    + * 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 / months ) to add (optional - default nothing is add ) -
    + * variable name ( optional )
    + *
    + * Returns: - Returns a formated date with the specified number of (seconds /
    + * minutes / hours / days / months ) added. - value is also saved in the
    + * variable for later re-use.
    + *
    + * @since 3.3
    + */
    +public class TimeShiftingFunction extends AbstractFunction {
    +    private static final Logger log = LoggerFactory.getLogger(TimeShiftingFunction.class);
    +
    +    private static final String KEY = "__timeShifting"; // $NON-NLS-1$
    +
    +    private static final List<String> desc = new LinkedList<>();
    +
    +    static {
    +        desc.add(JMeterUtils.getResString("time_format_shift")); //$NON-NLS-1$
    +        desc.add(JMeterUtils.getResString("date_to_shift")); //$NON-NLS-1$
    +        desc.add(JMeterUtils.getResString("value_to_shift")); //$NON-NLS-1$
    +        desc.add(JMeterUtils.getResString("function_name_paropt")); //$NON-NLS-1$
    +    }
    +
    +    // 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 shift = ""; //$NON-NLS-1$
    +    private String variable = ""; //$NON-NLS-1$
    +
    +    public TimeShiftingFunction() {
    +        super();
    +    }
    +
    +    /** {@inheritDoc} */
    +    @Override
    +    public String execute(SampleResult previousResult, Sampler currentSampler) throws InvalidVariableException {
    +        String dateString;
    +        LocalDateTime localDateTimeToShift = LocalDateTime.now(ZoneId.systemDefault());
    +        DateTimeFormatter formatter = null;
    +        if (!StringUtils.isEmpty(format)) {
    +            try {
    +                formatter = 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());
    +            } catch (IllegalArgumentException ex) {
    +                log.error("Pattern '{}' is invalid", format, ex); // $NON-NLS-1$
    --- End diff --
    
    Do we really want to continue in case of an error?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter issue #291: Add time shifting function

Posted by pmouawad <gi...@git.apache.org>.
Github user pmouawad commented on the issue:

    https://github.com/apache/jmeter/pull/291
  
    Thanks for the changes. Looks good to me for commit.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by FSchumacher <gi...@git.apache.org>.
Github user FSchumacher commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113540403
  
    --- Diff: src/core/org/apache/jmeter/resources/messages.properties ---
    @@ -1179,6 +1180,7 @@ throughput_control_perthread_label=Per User
     throughput_control_title=Throughput Controller
     throughput_control_tplabel=Throughput
     time_format=Format string for SimpleDateFormat (optional)
    +time_format_shift=Format string for DateTimeFormatter (optional) ( defaut unix timestamp in millisecond )
    --- End diff --
    
    defaut => default


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by max3163 <gi...@git.apache.org>.
Github user max3163 commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113761186
  
    --- Diff: src/functions/org/apache/jmeter/functions/TimeShift.java ---
    @@ -0,0 +1,188 @@
    +/*
    + * 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.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 java.util.regex.Matcher;
    +import java.util.regex.Pattern;
    +
    +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;
    +
    +/**
    + * 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 or months ) 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 Pattern pattern = Pattern.compile("(?:((?:[+-])?\\d+)([MdHms]))");
    +    
    +    public TimeShift() {
    +        super();
    +    }
    +
    +    /** {@inheritDoc} */
    +    @Override
    +    public String execute(SampleResult previousResult, Sampler currentSampler) throws InvalidVariableException {
    +        String dateString;
    +        LocalDateTime localDateTimeToShift = LocalDateTime.now(ZoneId.systemDefault());
    +        DateTimeFormatter formatter = null;
    +        if (!StringUtils.isEmpty(format)) {
    +            try {
    +                formatter = 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());
    +            } catch (IllegalArgumentException ex) {
    +                log.error("Pattern '{}' is invalid", 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)) {
    +            Matcher m = pattern.matcher(amountToShift);
    +            while (m.find()) {
    +                long amount = Long.parseLong(m.group(1));
    +                String period = m.group(2);
    +                log.debug("Add '{}{}' period of time on '{}'", amount, period, localDateTimeToShift);
    +                switch (period) {
    +                    case "s":
    +                        localDateTimeToShift = localDateTimeToShift.plusSeconds(amount);
    +                        break;
    +                    case "m":
    +                        localDateTimeToShift = localDateTimeToShift.plusMinutes(amount);
    +                        break;
    +                    case "H":
    +                        localDateTimeToShift = localDateTimeToShift.plusHours(amount);
    +                        break;
    +                    case "d":
    +                        localDateTimeToShift = localDateTimeToShift.plusDays(amount);
    +                        break;
    +                    case "M":
    +                        localDateTimeToShift = localDateTimeToShift.plusMonths(amount);
    +                        break;
    +                }
    +            }
    +        }
    +
    +        if (formatter != null) {
    +            dateString = localDateTimeToShift.format(formatter);
    +        } else {
    +            ZoneOffset offset = ZoneOffset.systemDefault().getRules().getOffset(localDateTimeToShift);
    +            dateString = String.valueOf(localDateTimeToShift.toInstant(offset).toEpochMilli());
    +        }
    +
    +        if (variableName.length() > 0) {
    --- End diff --
    
    Fix, length()>0 was use on others functions ... damn copy / paste :)


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by FSchumacher <gi...@git.apache.org>.
Github user FSchumacher commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113540671
  
    --- Diff: src/functions/org/apache/jmeter/functions/TimeShiftingFunction.java ---
    @@ -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.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.Collection;
    +import java.util.LinkedList;
    +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;
    +
    +/**
    + * 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 / months ) to add (optional - default nothing is add ) -
    + * variable name ( optional )
    + *
    + * Returns: - Returns a formated date with the specified number of (seconds /
    --- End diff --
    
    formated => formatted


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by max3163 <gi...@git.apache.org>.
Github user max3163 commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113762145
  
    --- Diff: res/maven/ApacheJMeter_parent.pom ---
    @@ -427,6 +428,11 @@ under the License.
             <artifactId>hamcrest-core</artifactId>
             <version>${hamcrest-core.version}</version>
           </dependency>
    +      <dependency>
    +	    <groupId>org.exparity</groupId>
    --- End diff --
    
    Fix


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by vlsi <gi...@git.apache.org>.
Github user vlsi commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113700248
  
    --- Diff: test/src/org/apache/jmeter/functions/TestTimeShiftFunction.java ---
    @@ -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", "1d", "");
    +        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", "1d", "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", "+1M+1d-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", "", "1d", "");
    +        function.setParameters(params);
    +        value = function.execute(result, null);
    +        LocalDate tomorrow = LocalDate.now().plusDays(1);
    +        LocalDate tomorrowFromFunction = LocalDate.parse(value);
    --- End diff --
    
    Is this code locale-dependent? How does `LocalDate.parse` known which format to use?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by max3163 <gi...@git.apache.org>.
Github user max3163 commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113761611
  
    --- Diff: src/functions/org/apache/jmeter/functions/TimeShift.java ---
    @@ -0,0 +1,188 @@
    +/*
    + * 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.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 java.util.regex.Matcher;
    +import java.util.regex.Pattern;
    +
    +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;
    +
    +/**
    + * 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 or months ) 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 Pattern pattern = Pattern.compile("(?:((?:[+-])?\\d+)([MdHms]))");
    +    
    +    public TimeShift() {
    +        super();
    +    }
    +
    +    /** {@inheritDoc} */
    +    @Override
    +    public String execute(SampleResult previousResult, Sampler currentSampler) throws InvalidVariableException {
    +        String dateString;
    +        LocalDateTime localDateTimeToShift = LocalDateTime.now(ZoneId.systemDefault());
    +        DateTimeFormatter formatter = null;
    +        if (!StringUtils.isEmpty(format)) {
    +            try {
    +                formatter = 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());
    +            } catch (IllegalArgumentException ex) {
    +                log.error("Pattern '{}' is invalid", format, ex); // $NON-NLS-1$
    --- End diff --
    
    Done with url to javadoc


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by max3163 <gi...@git.apache.org>.
Github user max3163 commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113760326
  
    --- Diff: test/src/org/apache/jmeter/functions/TestTimeShiftFunction.java ---
    @@ -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", "1d", "");
    +        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", "1d", "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", "+1M+1d-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", "", "1d", "");
    +        function.setParameters(params);
    +        value = function.execute(result, null);
    +        LocalDate tomorrow = LocalDate.now().plusDays(1);
    +        LocalDate tomorrowFromFunction = LocalDate.parse(value);
    --- End diff --
    
    By default, parse use the format YYYY-MM-dd 
    Javadoc : The string must represent a valid date and is parsed using DateTimeFormatter.ISO_LOCAL_DATE.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by max3163 <gi...@git.apache.org>.
Github user max3163 commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113762187
  
    --- Diff: build.xml ---
    @@ -400,6 +400,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}"/>
    --- End diff --
    
    Fix


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by vlsi <gi...@git.apache.org>.
Github user vlsi commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113697973
  
    --- Diff: src/functions/org/apache/jmeter/functions/TimeShift.java ---
    @@ -0,0 +1,188 @@
    +/*
    + * 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.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 java.util.regex.Matcher;
    +import java.util.regex.Pattern;
    +
    +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;
    +
    +/**
    + * 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 or months ) 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 Pattern pattern = Pattern.compile("(?:((?:[+-])?\\d+)([MdHms]))");
    +    
    +    public TimeShift() {
    +        super();
    +    }
    +
    +    /** {@inheritDoc} */
    +    @Override
    +    public String execute(SampleResult previousResult, Sampler currentSampler) throws InvalidVariableException {
    +        String dateString;
    +        LocalDateTime localDateTimeToShift = LocalDateTime.now(ZoneId.systemDefault());
    +        DateTimeFormatter formatter = null;
    +        if (!StringUtils.isEmpty(format)) {
    +            try {
    +                formatter = 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());
    +            } catch (IllegalArgumentException ex) {
    +                log.error("Pattern '{}' is invalid", format, ex); // $NON-NLS-1$
    --- End diff --
    
    Could you please add "corrective action" to the log message? E.g. "supported formats are..."


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by vlsi <gi...@git.apache.org>.
Github user vlsi commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113696389
  
    --- Diff: src/functions/org/apache/jmeter/functions/TimeShift.java ---
    @@ -0,0 +1,188 @@
    +/*
    + * 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.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 java.util.regex.Matcher;
    +import java.util.regex.Pattern;
    +
    +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;
    +
    +/**
    + * 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 or months ) 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 Pattern pattern = Pattern.compile("(?:((?:[+-])?\\d+)([MdHms]))");
    --- End diff --
    
    `static final`?
    Could you please choose a more meaningful name rather than `pattern`?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter issue #291: Add time shifting function

Posted by FSchumacher <gi...@git.apache.org>.
Github user FSchumacher commented on the issue:

    https://github.com/apache/jmeter/pull/291
  
    You might want to look at `Duration#parse(CharSequence)`.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter issue #291: Add time shifting function

Posted by pmouawad <gi...@git.apache.org>.
Github user pmouawad commented on the issue:

    https://github.com/apache/jmeter/pull/291
  
    Hello,
    Looks good to me (see my comments), very good idea !
    
    Thanks


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by FSchumacher <gi...@git.apache.org>.
Github user FSchumacher commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113537173
  
    --- Diff: xdocs/usermanual/functions.xml ---
    @@ -1499,6 +1502,36 @@ becomes:
     </properties>
     </component>
     
    +
    +<component index="&sect-num;.5.22" name="__timeShifting">
    +<description>
    +    <p>The timeShifting function returns a date in various formats with the specified amount of seconds/minutes/hours/days/months added</p>
    +    </description>
    +<properties>
    +        <property name="Format" required="No">
    +        The format to be passed to DateTimeFormatter.
    +        If omitted, the function use milliseconds since epoch format.
    --- End diff --
    
    use => uses


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by FSchumacher <gi...@git.apache.org>.
Github user FSchumacher commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113541037
  
    --- Diff: xdocs/usermanual/functions.xml ---
    @@ -1499,6 +1502,36 @@ becomes:
     </properties>
     </component>
     
    +
    +<component index="&sect-num;.5.22" name="__timeShifting">
    +<description>
    +    <p>The timeShifting function returns a date in various formats with the specified amount of seconds/minutes/hours/days/months added</p>
    +    </description>
    +<properties>
    +        <property name="Format" required="No">
    +        The format to be passed to DateTimeFormatter.
    +        If omitted, the function use milliseconds since epoch format.
    +        </property>
    +        <property name="Date to shift" required="No">
    +        Indicate the date with the format from first paramater 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/days/mounths to add according to this usage :
    +        <ul>
    +        <li><code>5s</code> for Second value</li>
    +        <li><code>5m</code> for Minute value</li>
    +        <li><code>5H</code> for Hour value</li>
    +        <li><code>5d</code> for Day value</li>
    +        <li><code>5M</code> for Month value</li>
    +        </ul>
    +        To shift in the pass, you just have to indicate <code>-5d</code>  to remove 5 days.
    --- End diff --
    
    Would it be useful, to specify more complex amount of times like `5d7H` or `5 days 7 minutes`?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by vlsi <gi...@git.apache.org>.
Github user vlsi commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113697784
  
    --- Diff: src/functions/org/apache/jmeter/functions/TimeShift.java ---
    @@ -0,0 +1,188 @@
    +/*
    + * 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.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 java.util.regex.Matcher;
    +import java.util.regex.Pattern;
    +
    +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;
    +
    +/**
    + * 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 or months ) 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 Pattern pattern = Pattern.compile("(?:((?:[+-])?\\d+)([MdHms]))");
    +    
    +    public TimeShift() {
    +        super();
    +    }
    +
    +    /** {@inheritDoc} */
    +    @Override
    +    public String execute(SampleResult previousResult, Sampler currentSampler) throws InvalidVariableException {
    +        String dateString;
    +        LocalDateTime localDateTimeToShift = LocalDateTime.now(ZoneId.systemDefault());
    --- End diff --
    
    `ZoneId.systemDefault` is not a trivial method, so it makes sense to cache the outcome at least for the duration of the method


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by FSchumacher <gi...@git.apache.org>.
Github user FSchumacher commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113538522
  
    --- Diff: xdocs/usermanual/functions.xml ---
    @@ -1499,6 +1502,36 @@ becomes:
     </properties>
     </component>
     
    +
    +<component index="&sect-num;.5.22" name="__timeShifting">
    +<description>
    +    <p>The timeShifting function returns a date in various formats with the specified amount of seconds/minutes/hours/days/months added</p>
    --- End diff --
    
    "in various formats" => "in configured format" or "in the given format" as the function will return one value, only.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter issue #291: Add time shifting function

Posted by max3163 <gi...@git.apache.org>.
Github user max3163 commented on the issue:

    https://github.com/apache/jmeter/pull/291
  
    I found the format more complex and you can't add month. 
    But it's more java native like my implementation. 
    What do you prefer ? 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by max3163 <gi...@git.apache.org>.
Github user max3163 commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113762164
  
    --- Diff: licenses/bin/hamcrest-date-2.0.4.txt ---
    @@ -0,0 +1 @@
    +According to https://github.com/eXparity/hamcrest-date Hamcrest-date is under BSD License
    --- End diff --
    
    Fix


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by vlsi <gi...@git.apache.org>.
Github user vlsi commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113698846
  
    --- Diff: src/functions/org/apache/jmeter/functions/TimeShift.java ---
    @@ -0,0 +1,188 @@
    +/*
    + * 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.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 java.util.regex.Matcher;
    +import java.util.regex.Pattern;
    +
    +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;
    +
    +/**
    + * 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 or months ) 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 Pattern pattern = Pattern.compile("(?:((?:[+-])?\\d+)([MdHms]))");
    +    
    +    public TimeShift() {
    +        super();
    +    }
    +
    +    /** {@inheritDoc} */
    +    @Override
    +    public String execute(SampleResult previousResult, Sampler currentSampler) throws InvalidVariableException {
    +        String dateString;
    +        LocalDateTime localDateTimeToShift = LocalDateTime.now(ZoneId.systemDefault());
    +        DateTimeFormatter formatter = null;
    +        if (!StringUtils.isEmpty(format)) {
    +            try {
    +                formatter = 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());
    +            } catch (IllegalArgumentException ex) {
    +                log.error("Pattern '{}' is invalid", 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)) {
    +            Matcher m = pattern.matcher(amountToShift);
    +            while (m.find()) {
    +                long amount = Long.parseLong(m.group(1));
    +                String period = m.group(2);
    +                log.debug("Add '{}{}' period of time on '{}'", amount, period, localDateTimeToShift);
    +                switch (period) {
    +                    case "s":
    +                        localDateTimeToShift = localDateTimeToShift.plusSeconds(amount);
    +                        break;
    +                    case "m":
    +                        localDateTimeToShift = localDateTimeToShift.plusMinutes(amount);
    +                        break;
    +                    case "H":
    +                        localDateTimeToShift = localDateTimeToShift.plusHours(amount);
    +                        break;
    +                    case "d":
    +                        localDateTimeToShift = localDateTimeToShift.plusDays(amount);
    +                        break;
    +                    case "M":
    +                        localDateTimeToShift = localDateTimeToShift.plusMonths(amount);
    +                        break;
    +                }
    +            }
    +        }
    +
    +        if (formatter != null) {
    +            dateString = localDateTimeToShift.format(formatter);
    +        } else {
    +            ZoneOffset offset = ZoneOffset.systemDefault().getRules().getOffset(localDateTimeToShift);
    +            dateString = String.valueOf(localDateTimeToShift.toInstant(offset).toEpochMilli());
    +        }
    +
    +        if (variableName.length() > 0) {
    +            JMeterVariables vars = getVariables();
    +            if (vars != null) {// vars will be null on TestPlan
    +                vars.put(variableName, dateString);
    +            }
    +        }
    +        return dateString;
    +    }
    +
    +    /** {@inheritDoc} */
    +    @Override
    +    public void setParameters(Collection<CompoundVariable> parameters) throws InvalidVariableException {
    +
    +        checkParameterCount(parameters, 0, 4);
    +        Object[] values = parameters.toArray();
    +
    +        format = ((CompoundVariable) values[0]).execute();
    +        dateToShift = ((CompoundVariable) values[1]).execute();
    +        amountToShift = ((CompoundVariable) values[2]).execute();
    --- End diff --
    
    Should other fields be trimmed like `variableName`?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter issue #291: Add time shifting function

Posted by max3163 <gi...@git.apache.org>.
Github user max3163 commented on the issue:

    https://github.com/apache/jmeter/pull/291
  
    Close with commit r1794517 : http://svn.apache.org/viewvc?rev=1794517&view=rev


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by vlsi <gi...@git.apache.org>.
Github user vlsi commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113698496
  
    --- Diff: src/functions/org/apache/jmeter/functions/TimeShift.java ---
    @@ -0,0 +1,188 @@
    +/*
    + * 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.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 java.util.regex.Matcher;
    +import java.util.regex.Pattern;
    +
    +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;
    +
    +/**
    + * 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 or months ) 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 Pattern pattern = Pattern.compile("(?:((?:[+-])?\\d+)([MdHms]))");
    --- End diff --
    
    Should year and week be supported as well?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by pmouawad <gi...@git.apache.org>.
Github user pmouawad commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113294026
  
    --- Diff: src/functions/org/apache/jmeter/functions/TimeShiftingFunction.java ---
    @@ -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.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.Collection;
    +import java.util.LinkedList;
    +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;
    +
    +/**
    + * 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 / months ) to add (optional - default nothing is add )
    + * - variable name ( optional )
    + *
    + * Returns:
    + * - Returns a formated date with the specified number of (seconds / minutes / hours / days / months ) added.
    + * - value is also saved in the variable for later re-use.
    + *
    + * @since 3.3
    + */
    +public class TimeShiftingFunction extends AbstractFunction {
    +    private static final Logger log = LoggerFactory.getLogger(TimeShiftingFunction.class);
    +
    +    private static final String KEY = "__timeShifting"; // $NON-NLS-1$
    +
    +    private static final List<String> desc = new LinkedList<>();
    +    
    +    static {
    +        desc.add(JMeterUtils.getResString("time_format_shift")); //$NON-NLS-1$
    +        desc.add(JMeterUtils.getResString("date_to_shift")); //$NON-NLS-1$
    +        desc.add(JMeterUtils.getResString("value_to_shift")); //$NON-NLS-1$
    +        desc.add(JMeterUtils.getResString("function_name_paropt")); //$NON-NLS-1$
    +    }
    +
    +    // 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 shift = ""; //$NON-NLS-1$
    +    private String variable = ""; //$NON-NLS-1$
    +
    +    public TimeShiftingFunction() {
    +        super();
    +    }
    +
    +    /** {@inheritDoc} */
    +    @Override
    +    public String execute(SampleResult previousResult, Sampler currentSampler) throws InvalidVariableException {
    +        String dateString;
    +        LocalDateTime localDateTimeToShift = LocalDateTime.now( ZoneId.systemDefault() );
    +        DateTimeFormatter formatter = null; 
    +        if (!StringUtils.isEmpty(format)) {
    +            try {
    +                formatter = 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());
    +            } catch (IllegalArgumentException ex) {
    +                log.error("Pattern is invalid", ex); // $NON-NLS-1$
    --- End diff --
    
    Mention pattern in message


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by pmouawad <gi...@git.apache.org>.
Github user pmouawad commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113294069
  
    --- Diff: src/functions/org/apache/jmeter/functions/TimeShiftingFunction.java ---
    @@ -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.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.Collection;
    +import java.util.LinkedList;
    +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;
    +
    +/**
    + * 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 / months ) to add (optional - default nothing is add )
    + * - variable name ( optional )
    + *
    + * Returns:
    + * - Returns a formated date with the specified number of (seconds / minutes / hours / days / months ) added.
    + * - value is also saved in the variable for later re-use.
    + *
    + * @since 3.3
    + */
    +public class TimeShiftingFunction extends AbstractFunction {
    +    private static final Logger log = LoggerFactory.getLogger(TimeShiftingFunction.class);
    +
    +    private static final String KEY = "__timeShifting"; // $NON-NLS-1$
    +
    +    private static final List<String> desc = new LinkedList<>();
    +    
    +    static {
    +        desc.add(JMeterUtils.getResString("time_format_shift")); //$NON-NLS-1$
    +        desc.add(JMeterUtils.getResString("date_to_shift")); //$NON-NLS-1$
    +        desc.add(JMeterUtils.getResString("value_to_shift")); //$NON-NLS-1$
    +        desc.add(JMeterUtils.getResString("function_name_paropt")); //$NON-NLS-1$
    +    }
    +
    +    // 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 shift = ""; //$NON-NLS-1$
    +    private String variable = ""; //$NON-NLS-1$
    +
    +    public TimeShiftingFunction() {
    +        super();
    +    }
    +
    +    /** {@inheritDoc} */
    +    @Override
    +    public String execute(SampleResult previousResult, Sampler currentSampler) throws InvalidVariableException {
    +        String dateString;
    +        LocalDateTime localDateTimeToShift = LocalDateTime.now( ZoneId.systemDefault() );
    +        DateTimeFormatter formatter = null; 
    +        if (!StringUtils.isEmpty(format)) {
    +            try {
    +                formatter = 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());
    +            } catch (IllegalArgumentException ex) {
    +                log.error("Pattern is invalid", ex); // $NON-NLS-1$
    +            }
    +        }
    +
    +        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 date to shift", ex); // $NON-NLS-1$
    --- End diff --
    
    Mention dateToShift


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by vlsi <gi...@git.apache.org>.
Github user vlsi commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113698701
  
    --- Diff: src/functions/org/apache/jmeter/functions/TimeShift.java ---
    @@ -0,0 +1,188 @@
    +/*
    + * 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.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 java.util.regex.Matcher;
    +import java.util.regex.Pattern;
    +
    +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;
    +
    +/**
    + * 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 or months ) 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 Pattern pattern = Pattern.compile("(?:((?:[+-])?\\d+)([MdHms]))");
    +    
    +    public TimeShift() {
    +        super();
    +    }
    +
    +    /** {@inheritDoc} */
    +    @Override
    +    public String execute(SampleResult previousResult, Sampler currentSampler) throws InvalidVariableException {
    +        String dateString;
    +        LocalDateTime localDateTimeToShift = LocalDateTime.now(ZoneId.systemDefault());
    +        DateTimeFormatter formatter = null;
    +        if (!StringUtils.isEmpty(format)) {
    +            try {
    +                formatter = 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());
    +            } catch (IllegalArgumentException ex) {
    +                log.error("Pattern '{}' is invalid", 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)) {
    +            Matcher m = pattern.matcher(amountToShift);
    +            while (m.find()) {
    +                long amount = Long.parseLong(m.group(1));
    +                String period = m.group(2);
    +                log.debug("Add '{}{}' period of time on '{}'", amount, period, localDateTimeToShift);
    +                switch (period) {
    +                    case "s":
    +                        localDateTimeToShift = localDateTimeToShift.plusSeconds(amount);
    +                        break;
    +                    case "m":
    +                        localDateTimeToShift = localDateTimeToShift.plusMinutes(amount);
    +                        break;
    +                    case "H":
    +                        localDateTimeToShift = localDateTimeToShift.plusHours(amount);
    +                        break;
    +                    case "d":
    +                        localDateTimeToShift = localDateTimeToShift.plusDays(amount);
    +                        break;
    +                    case "M":
    +                        localDateTimeToShift = localDateTimeToShift.plusMonths(amount);
    +                        break;
    +                }
    +            }
    +        }
    +
    +        if (formatter != null) {
    +            dateString = localDateTimeToShift.format(formatter);
    +        } else {
    +            ZoneOffset offset = ZoneOffset.systemDefault().getRules().getOffset(localDateTimeToShift);
    +            dateString = String.valueOf(localDateTimeToShift.toInstant(offset).toEpochMilli());
    +        }
    +
    +        if (variableName.length() > 0) {
    --- End diff --
    
    Other checks seem to use `StringUtils.isEmpty` rather than `length()>0`


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by FSchumacher <gi...@git.apache.org>.
Github user FSchumacher commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113539922
  
    --- Diff: src/functions/org/apache/jmeter/functions/TimeShiftingFunction.java ---
    @@ -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.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.Collection;
    +import java.util.LinkedList;
    +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;
    +
    +/**
    + * 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 / months ) to add (optional - default nothing is add ) -
    + * variable name ( optional )
    + *
    + * Returns: - Returns a formated date with the specified number of (seconds /
    + * minutes / hours / days / months ) added. - value is also saved in the
    + * variable for later re-use.
    + *
    + * @since 3.3
    + */
    +public class TimeShiftingFunction extends AbstractFunction {
    +    private static final Logger log = LoggerFactory.getLogger(TimeShiftingFunction.class);
    +
    +    private static final String KEY = "__timeShifting"; // $NON-NLS-1$
    +
    +    private static final List<String> desc = new LinkedList<>();
    +
    +    static {
    +        desc.add(JMeterUtils.getResString("time_format_shift")); //$NON-NLS-1$
    +        desc.add(JMeterUtils.getResString("date_to_shift")); //$NON-NLS-1$
    +        desc.add(JMeterUtils.getResString("value_to_shift")); //$NON-NLS-1$
    +        desc.add(JMeterUtils.getResString("function_name_paropt")); //$NON-NLS-1$
    +    }
    +
    +    // 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 shift = ""; //$NON-NLS-1$
    +    private String variable = ""; //$NON-NLS-1$
    --- End diff --
    
    What do you think of `variableName`?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by vlsi <gi...@git.apache.org>.
Github user vlsi commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113696169
  
    --- Diff: res/maven/ApacheJMeter_parent.pom ---
    @@ -427,6 +428,11 @@ under the License.
             <artifactId>hamcrest-core</artifactId>
             <version>${hamcrest-core.version}</version>
           </dependency>
    +      <dependency>
    +	    <groupId>org.exparity</groupId>
    --- End diff --
    
    please, avoid using tabs when file is space indented


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by undera <gi...@git.apache.org>.
Github user undera commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113537870
  
    --- Diff: src/functions/org/apache/jmeter/functions/TimeShiftingFunction.java ---
    @@ -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.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.Collection;
    +import java.util.LinkedList;
    +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;
    +
    +/**
    + * 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 / months ) to add (optional - default nothing is add ) -
    + * variable name ( optional )
    + *
    + * Returns: - Returns a formated date with the specified number of (seconds /
    + * minutes / hours / days / months ) added. - value is also saved in the
    + * variable for later re-use.
    + *
    + * @since 3.3
    + */
    +public class TimeShiftingFunction extends AbstractFunction {
    +    private static final Logger log = LoggerFactory.getLogger(TimeShiftingFunction.class);
    +
    +    private static final String KEY = "__timeShifting"; // $NON-NLS-1$
    --- End diff --
    
    "timeShifting" is unusual style for function name. Usually functions are called like "__timeShift", without continuous tense


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by vlsi <gi...@git.apache.org>.
Github user vlsi commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113872248
  
    --- Diff: src/functions/org/apache/jmeter/functions/TimeShift.java ---
    @@ -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 or months ) 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;
    --- End diff --
    
    `DateTimeFormatter` is thread-safe. Does is make sense to make cache `static final` ?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by max3163 <gi...@git.apache.org>.
Github user max3163 commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113760749
  
    --- Diff: src/functions/org/apache/jmeter/functions/TimeShift.java ---
    @@ -0,0 +1,188 @@
    +/*
    + * 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.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 java.util.regex.Matcher;
    +import java.util.regex.Pattern;
    +
    +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;
    +
    +/**
    + * 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 or months ) 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 Pattern pattern = Pattern.compile("(?:((?:[+-])?\\d+)([MdHms]))");
    +    
    +    public TimeShift() {
    +        super();
    +    }
    +
    +    /** {@inheritDoc} */
    +    @Override
    +    public String execute(SampleResult previousResult, Sampler currentSampler) throws InvalidVariableException {
    +        String dateString;
    +        LocalDateTime localDateTimeToShift = LocalDateTime.now(ZoneId.systemDefault());
    +        DateTimeFormatter formatter = null;
    +        if (!StringUtils.isEmpty(format)) {
    +            try {
    +                formatter = 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());
    +            } catch (IllegalArgumentException ex) {
    +                log.error("Pattern '{}' is invalid", 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)) {
    +            Matcher m = pattern.matcher(amountToShift);
    +            while (m.find()) {
    +                long amount = Long.parseLong(m.group(1));
    +                String period = m.group(2);
    +                log.debug("Add '{}{}' period of time on '{}'", amount, period, localDateTimeToShift);
    +                switch (period) {
    +                    case "s":
    +                        localDateTimeToShift = localDateTimeToShift.plusSeconds(amount);
    +                        break;
    +                    case "m":
    +                        localDateTimeToShift = localDateTimeToShift.plusMinutes(amount);
    +                        break;
    +                    case "H":
    +                        localDateTimeToShift = localDateTimeToShift.plusHours(amount);
    +                        break;
    +                    case "d":
    +                        localDateTimeToShift = localDateTimeToShift.plusDays(amount);
    +                        break;
    +                    case "M":
    +                        localDateTimeToShift = localDateTimeToShift.plusMonths(amount);
    +                        break;
    +                }
    +            }
    +        }
    +
    +        if (formatter != null) {
    +            dateString = localDateTimeToShift.format(formatter);
    +        } else {
    +            ZoneOffset offset = ZoneOffset.systemDefault().getRules().getOffset(localDateTimeToShift);
    +            dateString = String.valueOf(localDateTimeToShift.toInstant(offset).toEpochMilli());
    +        }
    +
    +        if (variableName.length() > 0) {
    +            JMeterVariables vars = getVariables();
    +            if (vars != null) {// vars will be null on TestPlan
    +                vars.put(variableName, dateString);
    +            }
    +        }
    +        return dateString;
    +    }
    +
    +    /** {@inheritDoc} */
    +    @Override
    +    public void setParameters(Collection<CompoundVariable> parameters) throws InvalidVariableException {
    +
    +        checkParameterCount(parameters, 0, 4);
    +        Object[] values = parameters.toArray();
    +
    +        format = ((CompoundVariable) values[0]).execute();
    +        dateToShift = ((CompoundVariable) values[1]).execute();
    +        amountToShift = ((CompoundVariable) values[2]).execute();
    --- End diff --
    
    Change to all fields done


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by FSchumacher <gi...@git.apache.org>.
Github user FSchumacher commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113540245
  
    --- Diff: src/functions/org/apache/jmeter/functions/TimeShiftingFunction.java ---
    @@ -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.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.Collection;
    +import java.util.LinkedList;
    +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;
    +
    +/**
    + * 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 / months ) to add (optional - default nothing is add ) -
    + * variable name ( optional )
    + *
    + * Returns: - Returns a formated date with the specified number of (seconds /
    + * minutes / hours / days / months ) added. - value is also saved in the
    + * variable for later re-use.
    + *
    + * @since 3.3
    + */
    +public class TimeShiftingFunction extends AbstractFunction {
    +    private static final Logger log = LoggerFactory.getLogger(TimeShiftingFunction.class);
    +
    +    private static final String KEY = "__timeShifting"; // $NON-NLS-1$
    +
    +    private static final List<String> desc = new LinkedList<>();
    --- End diff --
    
    Would it be possible to use `Arrays.asList(JMeterUtils.getResString(...), ...)`?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by vlsi <gi...@git.apache.org>.
Github user vlsi commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113696887
  
    --- Diff: src/functions/org/apache/jmeter/functions/TimeShift.java ---
    @@ -0,0 +1,188 @@
    +/*
    + * 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.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 java.util.regex.Matcher;
    +import java.util.regex.Pattern;
    +
    +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;
    +
    +/**
    + * 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 or months ) 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 Pattern pattern = Pattern.compile("(?:((?:[+-])?\\d+)([MdHms]))");
    +    
    +    public TimeShift() {
    +        super();
    +    }
    +
    +    /** {@inheritDoc} */
    +    @Override
    +    public String execute(SampleResult previousResult, Sampler currentSampler) throws InvalidVariableException {
    +        String dateString;
    +        LocalDateTime localDateTimeToShift = LocalDateTime.now(ZoneId.systemDefault());
    +        DateTimeFormatter formatter = null;
    +        if (!StringUtils.isEmpty(format)) {
    +            try {
    +                formatter = new DateTimeFormatterBuilder().appendPattern(format)
    --- End diff --
    
    I wonder how much does it cost to build this formatter thing. Is it something that should be cached?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] jmeter pull request #291: Add time shifting function

Posted by pmouawad <gi...@git.apache.org>.
Github user pmouawad commented on a diff in the pull request:

    https://github.com/apache/jmeter/pull/291#discussion_r113294213
  
    --- Diff: src/functions/org/apache/jmeter/functions/TimeShiftingFunction.java ---
    @@ -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.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.Collection;
    +import java.util.LinkedList;
    +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;
    +
    +/**
    + * 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 / months ) to add (optional - default nothing is add )
    + * - variable name ( optional )
    + *
    + * Returns:
    + * - Returns a formated date with the specified number of (seconds / minutes / hours / days / months ) added.
    + * - value is also saved in the variable for later re-use.
    + *
    + * @since 3.3
    + */
    +public class TimeShiftingFunction extends AbstractFunction {
    +    private static final Logger log = LoggerFactory.getLogger(TimeShiftingFunction.class);
    +
    +    private static final String KEY = "__timeShifting"; // $NON-NLS-1$
    +
    +    private static final List<String> desc = new LinkedList<>();
    +    
    +    static {
    +        desc.add(JMeterUtils.getResString("time_format_shift")); //$NON-NLS-1$
    +        desc.add(JMeterUtils.getResString("date_to_shift")); //$NON-NLS-1$
    +        desc.add(JMeterUtils.getResString("value_to_shift")); //$NON-NLS-1$
    +        desc.add(JMeterUtils.getResString("function_name_paropt")); //$NON-NLS-1$
    +    }
    +
    +    // 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 shift = ""; //$NON-NLS-1$
    +    private String variable = ""; //$NON-NLS-1$
    +
    +    public TimeShiftingFunction() {
    +        super();
    +    }
    +
    +    /** {@inheritDoc} */
    +    @Override
    +    public String execute(SampleResult previousResult, Sampler currentSampler) throws InvalidVariableException {
    +        String dateString;
    +        LocalDateTime localDateTimeToShift = LocalDateTime.now( ZoneId.systemDefault() );
    +        DateTimeFormatter formatter = null; 
    +        if (!StringUtils.isEmpty(format)) {
    +            try {
    +                formatter = 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());
    +            } catch (IllegalArgumentException ex) {
    +                log.error("Pattern is invalid", ex); // $NON-NLS-1$
    +            }
    +        }
    +
    +        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 date to shift", ex); // $NON-NLS-1$
    +            }
    +        }
    +
    +        // Check amount value to shift
    +        if (!StringUtils.isEmpty(shift)) {
    +            int strLength = shift.length();
    +            Character lastChar = shift.charAt(strLength - 1);
    +            try {
    +                long amount = Long.parseLong(shift.substring(0, strLength - 1));
    +                switch (lastChar) {
    +                case 's':
    +                    localDateTimeToShift = localDateTimeToShift.plusSeconds(amount);
    +                    break;
    +                case 'm':
    +                    localDateTimeToShift = localDateTimeToShift.plusMinutes(amount);
    +                    break;
    +                case 'H':
    +                    localDateTimeToShift = localDateTimeToShift.plusHours(amount);
    +                    break;
    +                case 'd':
    +                    localDateTimeToShift = localDateTimeToShift.plusDays(amount);
    +                    break;
    +                case 'M':
    +                    localDateTimeToShift = localDateTimeToShift.plusMonths(amount);
    +                    break;
    +                }
    +            } catch (NumberFormatException nfe) {
    +                log.warn("Failed to parse amount of time to add", nfe); // $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 (variable.length() > 0) {
    +            JMeterVariables vars = getVariables();
    +            if (vars != null) {// vars will be null on TestPlan
    --- End diff --
    
    Add some debug ?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---