jmeter icon indicating copy to clipboard operation
jmeter copied to clipboard

RandomDate ignores inclusive end date and throws when start == end

Open weillercarvalho opened this issue 1 month ago • 3 comments

Expected behavior

The __RandomDate function should treat the provided end date as inclusive. When the start and end dates are the same, the function should simply return that single date (and store it in the target variable) instead of failing.

Actual behavior

  • When startDate < endDate, the function never returns the configured end date. It behaves as if the interval were [start, end) (exclusive upper bound).

  • When startDate == endDate, the call to ThreadLocalRandom.nextLong(start, end) raises IllegalArgumentException: bound must be greater than origin, so the function errors out instead of returning the only valid date.

Steps to reproduce the problem

  1. Create a test plan with a Debug Sampler and a Simple Data Writer (or just watch the Debug Sampler output).
  2. Add a User Parameters or a JSR223 Sampler to evaluate ${__RandomDate(yyyy-MM-dd,2111-03-29,2111-03-30,,MY_VAR)}.
  3. Run the plan multiple times. Observe that the logged value is always 2111-03-29 and MY_VAR never contains 2111-03-30.
  4. Change the call to ${__RandomDate(yyyy-MM-dd,2111-03-29,2111-03-29,,MY_VAR)} and run again. The sampler now fails with the IllegalArgumentException mentioned above.

JMeter Version

6.0.0-SNAPSHOT

Java Version

OpenJDK Runtime Environment 21.0.8 (2025-07-16)

OS Version

Linux 6.6.87.2-microsoft-standard-WSL2 (running under Windows 11 / WSL2)

weillercarvalho avatar Nov 17 '25 19:11 weillercarvalho

I think it makes sense mirroring Java behavior: Random#nextInt(min, max) has inclusive min.

At the same time, __Random uses min, max+1: https://github.com/apache/jmeter/blob/47bd32e0aa2d804a196570c05b52e88aabdc7e4f/src/functions/src/main/java/org/apache/jmeter/functions/Random.java#L69

Frankly I would like to align __RandomDate and __Random. At the same time, I do not quite like to have different semantics for max in JMeter and in Java

vlsi avatar Nov 19 '25 13:11 vlsi

You're right @vlsi , makes more sense, quick explanation of the new changes:

I ditched the inclusive “max” change and went back to Java‑style semantics: start date is inclusive, end date is exclusive. To keep single‑day ranges working I still handle start == end as a special case so you get that exact day without blowing up. The helper is just ThreadLocalRandom.nextLong(start,end) again, no max+1. Tests were rolled back to expect the start date in those locale examples and they now assert result < max. Docs got tweaked to call out that end is exclusive and the changes log mentions the behavior shift.

weillercarvalho avatar Nov 19 '25 14:11 weillercarvalho

Hi there, I would like to work on this issue.

I have analyzed the problem and reproduced both behaviors: the IllegalArgumentException when dates are equal, and the exclusion of the end date in normal ranges.

Root Cause Analysis: The underlying method ThreadLocalRandom.current().nextLong(origin, bound) treats the upper bound as exclusive.

The Logic Error: When passing (start, end), the function picks a value in [start, end). The configured end date is never reached.

The Crash: When start == end, the bounds are invalid because nextLong requires bound > origin.

Proposed Solution: I propose shifting the upper bound by adding 1 day (in milliseconds) before generating the random number. This single change elegantly resolves both issues.

Fixes the Logic: By making the range [start, end + 1day), the original end date becomes a valid candidate.

Fixes the Crash: Even if start == end, the range becomes [start, start + 1day). This satisfies the bound > origin requirement and correctly returns the single start date.

Implementation Plan:

Modify RandomDate.java to add 86400000L (24 hours in ms) to the end parameter.

hitashuu avatar Dec 01 '25 06:12 hitashuu