mnaufaldillah

RandomDate Jmeter

Oct 23rd, 2021
593
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to you under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  * http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17.  
  18. package org.apache.jmeter.functions;
  19.  
  20. import java.time.LocalDate;
  21. import java.time.Year;
  22. import java.time.ZoneId;
  23. import java.time.format.DateTimeFormatter;
  24. import java.time.format.DateTimeFormatterBuilder;
  25. import java.time.format.DateTimeParseException;
  26. import java.time.temporal.ChronoField;
  27. import java.util.Arrays;
  28. import java.util.Collection;
  29. import java.util.List;
  30. import java.util.Locale;
  31. import java.util.concurrent.ThreadLocalRandom;
  32.  
  33. import org.apache.commons.lang3.LocaleUtils;
  34. import org.apache.commons.lang3.StringUtils;
  35. import org.apache.jmeter.engine.util.CompoundVariable;
  36. import org.apache.jmeter.samplers.SampleResult;
  37. import org.apache.jmeter.samplers.Sampler;
  38. import org.apache.jmeter.util.JMeterUtils;
  39. import org.slf4j.Logger;
  40. import org.slf4j.LoggerFactory;
  41.  
  42. import com.github.benmanes.caffeine.cache.Cache;
  43. import com.github.benmanes.caffeine.cache.Caffeine;
  44.  
  45. /**
  46.  * RandomDate Function generates a date in a specific range
  47.  *
  48.  * Parameters:
  49.  * <ul>
  50.  *  <li>Time format @see <a href="https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html">DateTimeFormatter</a>
  51.  *      (optional - defaults to yyyy-MM-dd)</li>
  52.  *  <li>Start date formated as first param (optional - defaults to now)</li>
  53.  *  <li>End date</li>
  54.  *  <li>Locale for the format (optional)</li>
  55.  *  <li>variable name (optional)</li>
  56.  * </ul>
  57.  * Returns a formatted date with the specified number of (days, month, year)
  58.  * Value is also saved in the variable for later re-use.
  59.  *
  60.  * @since 3.3
  61.  */
  62. public class RandomDate extends AbstractFunction {
  63.  
  64.     private static final Logger log = LoggerFactory.getLogger(RandomDate.class);
  65.  
  66.     private static final String KEY = "__RandomDate"; // $NON-NLS-1$
  67.  
  68.     private static final int MIN_PARAMETER_COUNT = 3;
  69.  
  70.     private static final int MAX_PARAMETER_COUNT = 5;
  71.  
  72.     private static final List<String> desc = Arrays.asList(JMeterUtils.getResString("time_format_random"),
  73.             JMeterUtils.getResString("date_start"), JMeterUtils.getResString("date_end"),
  74.             JMeterUtils.getResString("locale_format"), JMeterUtils.getResString("function_name_paropt"));
  75.  
  76.     // Ensure that these are set, even if no parameters are provided
  77.     private Locale locale = JMeterUtils.getLocale(); // $NON-NLS-1$
  78.     private ZoneId systemDefaultZoneID = ZoneId.systemDefault(); // $NON-NLS-1$
  79.     private CompoundVariable[] values;
  80.  
  81.     private static final class LocaleFormatObject {
  82.  
  83.         private String format;
  84.         private Locale locale;
  85.  
  86.         public LocaleFormatObject(String format, Locale locale) {
  87.             this.format = format;
  88.             this.locale = locale;
  89.         }
  90.  
  91.         public String getFormat() {
  92.             return format;
  93.         }
  94.  
  95.         public Locale getLocale() {
  96.             return locale;
  97.         }
  98.  
  99.         @Override
  100.         public int hashCode() {
  101.             return format.hashCode() + locale.hashCode();
  102.         }
  103.  
  104.         @Override
  105.         public boolean equals(Object other) {
  106.             if (!(other instanceof LocaleFormatObject)) {
  107.                 return false;
  108.             }
  109.  
  110.             LocaleFormatObject otherError = (LocaleFormatObject) other;
  111.             return format.equals(otherError.getFormat())
  112.                     && locale.getDisplayName().equals(otherError.getLocale().getDisplayName());
  113.         }
  114.  
  115.         /**
  116.          * @see java.lang.Object#toString()
  117.          */
  118.         @Override
  119.         public String toString() {
  120.             return "LocaleFormatObject [format=" + format + ", locale=" + locale + "]";
  121.         }
  122.  
  123.     }
  124.  
  125.     /** Date time format cache handler **/
  126.     private Cache<LocaleFormatObject, DateTimeFormatter> dateRandomFormatterCache;
  127.  
  128.     public RandomDate() {
  129.         super();
  130.     }
  131.  
  132.     /** {@inheritDoc} */
  133.     @Override
  134.     public String execute(SampleResult previousResult, Sampler currentSampler) throws InvalidVariableException {
  135.         DateTimeFormatter formatter;
  136.         if(values.length>3) {
  137.             String localeAsString = values[3].execute().trim();
  138.             if (!localeAsString.trim().isEmpty()) {
  139.                 locale = LocaleUtils.toLocale(localeAsString);
  140.             }
  141.         }
  142.  
  143.         String format = values[0].execute().trim();
  144.         if (!StringUtils.isEmpty(format)) {
  145.             try {
  146.                 LocaleFormatObject lfo = new LocaleFormatObject(format, locale);
  147.                 formatter = dateRandomFormatterCache.get(lfo, key -> createFormatter((LocaleFormatObject) key));
  148.             } catch (IllegalArgumentException ex) {
  149.                 log.error(
  150.                         "Format date pattern '{}' is invalid (see https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html)",
  151.                         format, ex); // $NON-NLS-1$
  152.                 return "";
  153.             }
  154.         } else {
  155.             try {
  156.                 LocaleFormatObject lfo = new LocaleFormatObject("yyyy-MM-dd", locale);
  157.                 formatter = dateRandomFormatterCache.get(lfo, key -> createFormatter((LocaleFormatObject) key));
  158.             } catch (IllegalArgumentException ex) {
  159.                 log.error(
  160.                         "Format date pattern '{}' is invalid (see https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html)",
  161.                         format, ex); // $NON-NLS-1$
  162.                 return "";
  163.             }
  164.         }
  165.  
  166.         String dateStart = values[1].execute().trim();
  167.         long localStartDate = 0;
  168.         if (!dateStart.isEmpty()) {
  169.             try {
  170.                 localStartDate = LocalDate.parse(dateStart, formatter).toEpochDay();
  171.             } catch (DateTimeParseException | NumberFormatException ex) {
  172.                 log.error("Failed to parse Start Date '{}'", dateStart, ex); // $NON-NLS-1$
  173.             }
  174.         } else {
  175.             try {
  176.                 localStartDate = LocalDate.now(systemDefaultZoneID).toEpochDay();
  177.             } catch (DateTimeParseException | NumberFormatException ex) {
  178.                 log.error("Failed to create current date '{}'", dateStart, ex); // $NON-NLS-1$
  179.             }
  180.         }
  181.         long localEndDate = 0;
  182.         String dateEnd = values[2].execute().trim();
  183.         try {
  184.             localEndDate = LocalDate.parse(dateEnd, formatter).toEpochDay();
  185.         } catch (DateTimeParseException | NumberFormatException ex) {
  186.             log.error("Failed to parse End date '{}'", dateEnd, ex); // $NON-NLS-1$
  187.         }
  188.  
  189.         // Generate the random date
  190.         String dateString = "";
  191.         if (localEndDate < localStartDate) {
  192.             log.error("End Date '{}' must be greater than Start Date '{}'", dateEnd, dateStart); // $NON-NLS-1$
  193.         } else {
  194.             long randomDay = ThreadLocalRandom.current().nextLong(localStartDate, localEndDate);
  195.             try {
  196.                 dateString = LocalDate.ofEpochDay(randomDay).format(formatter);
  197.             } catch (DateTimeParseException | NumberFormatException ex) {
  198.                 log.error("Failed to generate random date '{}'", randomDay, ex); // $NON-NLS-1$
  199.             }
  200.             addVariableValue(dateString, values, 4);
  201.         }
  202.         return dateString;
  203.     }
  204.  
  205.     @SuppressWarnings("JavaTimeDefaultTimeZone")
  206.     private DateTimeFormatter createFormatter(LocaleFormatObject format) {
  207.         log.debug("Create a new instance of DateTimeFormatter for format '{}' in the cache", format);
  208.         return new DateTimeFormatterBuilder().appendPattern(format.getFormat())
  209.                 // TODO: what if year changes? (e.g. the year changes as the test executes)
  210.                 .parseDefaulting(ChronoField.DAY_OF_MONTH, 1).parseDefaulting(ChronoField.MONTH_OF_YEAR, 1)
  211.                 .parseDefaulting(ChronoField.YEAR_OF_ERA, Year.now().getValue()).toFormatter(format.getLocale());
  212.  
  213.     }
  214.  
  215.     /** {@inheritDoc} */
  216.     @Override
  217.     public void setParameters(Collection<CompoundVariable> parameters) throws InvalidVariableException {
  218.  
  219.         checkParameterCount(parameters, MIN_PARAMETER_COUNT, MAX_PARAMETER_COUNT);
  220.         values = parameters.toArray(new CompoundVariable[parameters.size()]);
  221.         // Create the cache
  222.         if (dateRandomFormatterCache == null) {
  223.             dateRandomFormatterCache = Caffeine.newBuilder().maximumSize(100).build();
  224.         }
  225.     }
  226.  
  227.     /** {@inheritDoc} */
  228.     @Override
  229.     public String getReferenceKey() {
  230.         return KEY;
  231.     }
  232.  
  233.     /** {@inheritDoc} */
  234.     @Override
  235.     public List<String> getArgumentDesc() {
  236.         return desc;
  237.     }
  238.  
  239. }
RAW Paste Data