Skip to content

Conversation

AlexeyKuznetsov-DD
Copy link
Contributor

@AlexeyKuznetsov-DD AlexeyKuznetsov-DD commented Sep 22, 2025

What Does This Do

Refactors environment variables handling to make it testable.

Motivation

Relying directly on environment variables in tests is considered a bad practice.
@PerfectSlayer introduced a shared component, EnvironmentVariables, which is already used across the codebase.

This PR makes EnvironmentVariables testable by introducing a provider that allows configuring initial values for environment variables in tests.

Additional Notes

In one case, I had to initialize environment variables in a static block, because the test expected instrumentation to be auto-enabled by a special variable before instrumentation was loaded.

If class loading order cannot be avoided, I added support for a special environment variable:
TEST_ENV_PROPAGATE_VARS — a comma-separated list of variables that should be propagated from the real environment into the test environment.

This change also removed the need for the JUnit4 @Rule API and the legacy system-rules library.

@AlexeyKuznetsov-DD AlexeyKuznetsov-DD self-assigned this Sep 22, 2025
@AlexeyKuznetsov-DD AlexeyKuznetsov-DD added type: enhancement Enhancements and improvements comp: testing Testing tag: no release notes Changes to exclude from release notes labels Sep 22, 2025
@AlexeyKuznetsov-DD AlexeyKuznetsov-DD marked this pull request as ready for review September 22, 2025 19:47
@AlexeyKuznetsov-DD AlexeyKuznetsov-DD requested review from a team as code owners September 22, 2025 19:47
@AlexeyKuznetsov-DD AlexeyKuznetsov-DD changed the title Refactored ENV variables to be testable. Refactors environment variables handling to make it testable. Sep 22, 2025
@pr-commenter
Copy link

pr-commenter bot commented Sep 22, 2025

Benchmarks

Startup

Parameters

Baseline Candidate
baseline_or_candidate baseline candidate
git_branch master alexeyk/refactored-env-vars-to-be-testable
git_commit_date 1758813010 1758813563
git_commit_sha 050cad8 335f9f2
release_version 1.54.0-SNAPSHOT~050cad8b0e 1.54.0-SNAPSHOT~335f9f25a7
See matching parameters
Baseline Candidate
application insecure-bank insecure-bank
ci_job_date 1758815360 1758815360
ci_job_id 1147891490 1147891490
ci_pipeline_id 77542437 77542437
cpu_model Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz
kernel_version Linux runner-zfyrx7zua-project-304-concurrent-0-b8rmdk26 6.8.0-1031-aws #33~22.04.1-Ubuntu SMP Thu Jun 26 14:22:30 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux Linux runner-zfyrx7zua-project-304-concurrent-0-b8rmdk26 6.8.0-1031-aws #33~22.04.1-Ubuntu SMP Thu Jun 26 14:22:30 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
module Agent Agent
parent None None

Summary

Found 0 performance improvements and 0 performance regressions! Performance is the same for 52 metrics, 7 unstable metrics.

Startup time reports for petclinic
gantt
    title petclinic - global startup overhead: candidate=1.54.0-SNAPSHOT~335f9f25a7, baseline=1.54.0-SNAPSHOT~050cad8b0e

    dateFormat X
    axisFormat %s
section tracing
Agent [baseline] (1.019 s) : 0, 1019335
Total [baseline] (10.683 s) : 0, 10683080
Agent [candidate] (1.017 s) : 0, 1016569
Total [candidate] (10.679 s) : 0, 10678696
section appsec
Agent [baseline] (1.196 s) : 0, 1195986
Total [baseline] (11.026 s) : 0, 11026422
Agent [candidate] (1.189 s) : 0, 1188585
Total [candidate] (10.995 s) : 0, 10994778
section iast
Agent [baseline] (1.154 s) : 0, 1153572
Total [baseline] (10.939 s) : 0, 10939094
Agent [candidate] (1.153 s) : 0, 1152525
Total [candidate] (10.996 s) : 0, 10996178
section profiling
Agent [baseline] (1.159 s) : 0, 1159176
Total [baseline] (11.035 s) : 0, 11035020
Agent [candidate] (1.154 s) : 0, 1153554
Total [candidate] (11.063 s) : 0, 11062764
Loading
  • baseline results
Module Variant Duration Δ tracing
Agent tracing 1.019 s -
Agent appsec 1.196 s 176.651 ms (17.3%)
Agent iast 1.154 s 134.237 ms (13.2%)
Agent profiling 1.159 s 139.841 ms (13.7%)
Total tracing 10.683 s -
Total appsec 11.026 s 343.342 ms (3.2%)
Total iast 10.939 s 256.015 ms (2.4%)
Total profiling 11.035 s 351.94 ms (3.3%)
  • candidate results
Module Variant Duration Δ tracing
Agent tracing 1.017 s -
Agent appsec 1.189 s 172.016 ms (16.9%)
Agent iast 1.153 s 135.955 ms (13.4%)
Agent profiling 1.154 s 136.985 ms (13.5%)
Total tracing 10.679 s -
Total appsec 10.995 s 316.082 ms (3.0%)
Total iast 10.996 s 317.482 ms (3.0%)
Total profiling 11.063 s 384.068 ms (3.6%)
gantt
    title petclinic - break down per module: candidate=1.54.0-SNAPSHOT~335f9f25a7, baseline=1.54.0-SNAPSHOT~050cad8b0e

    dateFormat X
    axisFormat %s
section tracing
crashtracking [baseline] (1.495 ms) : 0, 1495
crashtracking [candidate] (1.48 ms) : 0, 1480
BytebuddyAgent [baseline] (698.853 ms) : 0, 698853
BytebuddyAgent [candidate] (695.598 ms) : 0, 695598
GlobalTracer [baseline] (249.972 ms) : 0, 249972
GlobalTracer [candidate] (250.487 ms) : 0, 250487
AppSec [baseline] (31.324 ms) : 0, 31324
AppSec [candidate] (31.538 ms) : 0, 31538
Debugger [baseline] (6.472 ms) : 0, 6472
Debugger [candidate] (6.449 ms) : 0, 6449
Remote Config [baseline] (685.149 µs) : 0, 685
Remote Config [candidate] (722.458 µs) : 0, 722
Telemetry [baseline] (9.038 ms) : 0, 9038
Telemetry [candidate] (9.062 ms) : 0, 9062
section appsec
crashtracking [baseline] (1.474 ms) : 0, 1474
crashtracking [candidate] (1.458 ms) : 0, 1458
BytebuddyAgent [baseline] (717.479 ms) : 0, 717479
BytebuddyAgent [candidate] (712.241 ms) : 0, 712241
GlobalTracer [baseline] (241.554 ms) : 0, 241554
GlobalTracer [candidate] (239.961 ms) : 0, 239961
AppSec [baseline] (172.389 ms) : 0, 172389
AppSec [candidate] (171.575 ms) : 0, 171575
Debugger [baseline] (6.842 ms) : 0, 6842
Debugger [candidate] (6.794 ms) : 0, 6794
Remote Config [baseline] (657.777 µs) : 0, 658
Remote Config [candidate] (645.609 µs) : 0, 646
Telemetry [baseline] (9.261 ms) : 0, 9261
Telemetry [candidate] (10.107 ms) : 0, 10107
IAST [baseline] (25.01 ms) : 0, 25010
IAST [candidate] (24.678 ms) : 0, 24678
section iast
crashtracking [baseline] (1.489 ms) : 0, 1489
crashtracking [candidate] (1.473 ms) : 0, 1473
BytebuddyAgent [baseline] (815.948 ms) : 0, 815948
BytebuddyAgent [candidate] (815.89 ms) : 0, 815890
GlobalTracer [baseline] (238.757 ms) : 0, 238757
GlobalTracer [candidate] (238.26 ms) : 0, 238260
AppSec [baseline] (34.155 ms) : 0, 34155
AppSec [candidate] (34.123 ms) : 0, 34123
Debugger [baseline] (6.073 ms) : 0, 6073
Debugger [candidate] (6.09 ms) : 0, 6090
Remote Config [baseline] (607.72 µs) : 0, 608
Remote Config [candidate] (596.403 µs) : 0, 596
Telemetry [baseline] (8.417 ms) : 0, 8417
Telemetry [candidate] (8.492 ms) : 0, 8492
IAST [baseline] (26.641 ms) : 0, 26641
IAST [candidate] (26.303 ms) : 0, 26303
section profiling
crashtracking [baseline] (1.456 ms) : 0, 1456
crashtracking [candidate] (1.446 ms) : 0, 1446
BytebuddyAgent [baseline] (723.97 ms) : 0, 723970
BytebuddyAgent [candidate] (720.366 ms) : 0, 720366
GlobalTracer [baseline] (225.027 ms) : 0, 225027
GlobalTracer [candidate] (223.24 ms) : 0, 223240
AppSec [baseline] (31.428 ms) : 0, 31428
AppSec [candidate] (31.291 ms) : 0, 31291
Debugger [baseline] (7.338 ms) : 0, 7338
Debugger [candidate] (6.528 ms) : 0, 6528
Remote Config [baseline] (1.402 ms) : 0, 1402
Remote Config [candidate] (712.038 µs) : 0, 712
Telemetry [baseline] (14.76 ms) : 0, 14760
Telemetry [candidate] (15.501 ms) : 0, 15501
ProfilingAgent [baseline] (101.002 ms) : 0, 101002
ProfilingAgent [candidate] (101.837 ms) : 0, 101837
Profiling [baseline] (101.589 ms) : 0, 101589
Profiling [candidate] (102.45 ms) : 0, 102450
Loading
Startup time reports for insecure-bank
gantt
    title insecure-bank - global startup overhead: candidate=1.54.0-SNAPSHOT~335f9f25a7, baseline=1.54.0-SNAPSHOT~050cad8b0e

    dateFormat X
    axisFormat %s
section tracing
Agent [baseline] (1.02 s) : 0, 1020180
Total [baseline] (8.712 s) : 0, 8711925
Agent [candidate] (1.006 s) : 0, 1006037
Total [candidate] (8.663 s) : 0, 8662762
section iast
Agent [baseline] (1.153 s) : 0, 1153209
Total [baseline] (9.306 s) : 0, 9306338
Agent [candidate] (1.149 s) : 0, 1148727
Total [candidate] (9.287 s) : 0, 9286911
Loading
  • baseline results
Module Variant Duration Δ tracing
Agent tracing 1.02 s -
Agent iast 1.153 s 133.03 ms (13.0%)
Total tracing 8.712 s -
Total iast 9.306 s 594.414 ms (6.8%)
  • candidate results
Module Variant Duration Δ tracing
Agent tracing 1.006 s -
Agent iast 1.149 s 142.69 ms (14.2%)
Total tracing 8.663 s -
Total iast 9.287 s 624.149 ms (7.2%)
gantt
    title insecure-bank - break down per module: candidate=1.54.0-SNAPSHOT~335f9f25a7, baseline=1.54.0-SNAPSHOT~050cad8b0e

    dateFormat X
    axisFormat %s
section tracing
crashtracking [baseline] (1.485 ms) : 0, 1485
crashtracking [candidate] (1.46 ms) : 0, 1460
BytebuddyAgent [baseline] (698.541 ms) : 0, 698541
BytebuddyAgent [candidate] (688.505 ms) : 0, 688505
GlobalTracer [baseline] (250.812 ms) : 0, 250812
GlobalTracer [candidate] (248.245 ms) : 0, 248245
AppSec [baseline] (31.605 ms) : 0, 31605
AppSec [candidate] (30.882 ms) : 0, 30882
Debugger [baseline] (6.47 ms) : 0, 6470
Debugger [candidate] (6.349 ms) : 0, 6349
Remote Config [baseline] (716.391 µs) : 0, 716
Remote Config [candidate] (675.563 µs) : 0, 676
Telemetry [baseline] (9.18 ms) : 0, 9180
Telemetry [candidate] (8.871 ms) : 0, 8871
section iast
crashtracking [baseline] (1.474 ms) : 0, 1474
crashtracking [candidate] (1.473 ms) : 0, 1473
BytebuddyAgent [baseline] (816.378 ms) : 0, 816378
BytebuddyAgent [candidate] (814.125 ms) : 0, 814125
GlobalTracer [baseline] (238.773 ms) : 0, 238773
GlobalTracer [candidate] (237.155 ms) : 0, 237155
AppSec [baseline] (33.985 ms) : 0, 33985
AppSec [candidate] (33.836 ms) : 0, 33836
Debugger [baseline] (6.085 ms) : 0, 6085
Debugger [candidate] (6.07 ms) : 0, 6070
Remote Config [baseline] (602.636 µs) : 0, 603
Remote Config [candidate] (592.328 µs) : 0, 592
Telemetry [baseline] (8.3 ms) : 0, 8300
Telemetry [candidate] (8.423 ms) : 0, 8423
IAST [baseline] (26.325 ms) : 0, 26325
IAST [candidate] (25.893 ms) : 0, 25893
Loading

Load

Parameters

Baseline Candidate
baseline_or_candidate baseline candidate
git_branch master alexeyk/refactored-env-vars-to-be-testable
git_commit_date 1758813010 1758813563
git_commit_sha 050cad8 335f9f2
release_version 1.54.0-SNAPSHOT~050cad8b0e 1.54.0-SNAPSHOT~335f9f25a7
See matching parameters
Baseline Candidate
application insecure-bank insecure-bank
ci_job_date 1758815028 1758815028
ci_job_id 1147891491 1147891491
ci_pipeline_id 77542437 77542437
cpu_model Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz
kernel_version Linux runner-zfyrx7zua-project-304-concurrent-1-fh7z3ojp 6.8.0-1031-aws #33~22.04.1-Ubuntu SMP Thu Jun 26 14:22:30 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux Linux runner-zfyrx7zua-project-304-concurrent-1-fh7z3ojp 6.8.0-1031-aws #33~22.04.1-Ubuntu SMP Thu Jun 26 14:22:30 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux

Summary

Found 3 performance improvements and 1 performance regressions! Performance is the same for 8 metrics, 12 unstable metrics.

scenario Δ mean http_req_duration Δ mean throughput candidate mean http_req_duration candidate mean throughput baseline mean http_req_duration baseline mean throughput
scenario:load:insecure-bank:tracing:high_load better
[-820.546µs; -581.814µs] or [-10.034%; -7.115%]
unstable
[-17.698op/s; +122.698op/s] or [-3.123%; +21.651%]
7.476ms 619.219op/s 8.177ms 566.719op/s
scenario:load:insecure-bank:iast_GLOBAL:high_load worse
[+309.408µs; +732.588µs] or [+2.900%; +6.867%]
unstable
[-66.468op/s; +26.343op/s] or [-15.254%; +6.046%]
11.190ms 415.688op/s 10.669ms 435.750op/s
scenario:load:petclinic:appsec:high_load better
[-3.050ms; -2.124ms] or [-6.112%; -4.256%]
unstable
[-2.309op/s; +12.484op/s] or [-2.461%; +13.304%]
47.310ms 98.925op/s 49.896ms 93.838op/s
scenario:load:petclinic:no_agent:high_load better
[-1.573ms; -0.917ms] or [-4.091%; -2.387%]
unstable
[-4.779op/s; +13.029op/s] or [-3.929%; +10.710%]
37.191ms 125.775op/s 38.436ms 121.650op/s
Request duration reports for petclinic
gantt
    title petclinic - request duration [CI 0.99] : candidate=1.54.0-SNAPSHOT~335f9f25a7, baseline=1.54.0-SNAPSHOT~050cad8b0e
    dateFormat X
    axisFormat %s
section baseline
no_agent (38.436 ms) : 38121, 38751
.   : milestone, 38436,
appsec (49.896 ms) : 49448, 50345
.   : milestone, 49896,
code_origins (44.428 ms) : 44028, 44828
.   : milestone, 44428,
iast (44.465 ms) : 44087, 44843
.   : milestone, 44465,
profiling (47.19 ms) : 46756, 47625
.   : milestone, 47190,
tracing (44.682 ms) : 44293, 45072
.   : milestone, 44682,
section candidate
no_agent (37.191 ms) : 36898, 37484
.   : milestone, 37191,
appsec (47.31 ms) : 46898, 47721
.   : milestone, 47310,
code_origins (44.018 ms) : 43633, 44402
.   : milestone, 44018,
iast (44.727 ms) : 44343, 45111
.   : milestone, 44727,
profiling (48.585 ms) : 48130, 49040
.   : milestone, 48585,
tracing (43.828 ms) : 43469, 44187
.   : milestone, 43828,
Loading
  • baseline results
Variant Request duration [CI 0.99] Δ no_agent
no_agent 38.436 ms [38.121 ms, 38.751 ms] -
appsec 49.896 ms [49.448 ms, 50.345 ms] 11.46 ms (29.8%)
code_origins 44.428 ms [44.028 ms, 44.828 ms] 5.992 ms (15.6%)
iast 44.465 ms [44.087 ms, 44.843 ms] 6.029 ms (15.7%)
profiling 47.19 ms [46.756 ms, 47.625 ms] 8.754 ms (22.8%)
tracing 44.682 ms [44.293 ms, 45.072 ms] 6.246 ms (16.3%)
  • candidate results
Variant Request duration [CI 0.99] Δ no_agent
no_agent 37.191 ms [36.898 ms, 37.484 ms] -
appsec 47.31 ms [46.898 ms, 47.721 ms] 10.118 ms (27.2%)
code_origins 44.018 ms [43.633 ms, 44.402 ms] 6.827 ms (18.4%)
iast 44.727 ms [44.343 ms, 45.111 ms] 7.536 ms (20.3%)
profiling 48.585 ms [48.13 ms, 49.04 ms] 11.394 ms (30.6%)
tracing 43.828 ms [43.469 ms, 44.187 ms] 6.637 ms (17.8%)
Request duration reports for insecure-bank
gantt
    title insecure-bank - request duration [CI 0.99] : candidate=1.54.0-SNAPSHOT~335f9f25a7, baseline=1.54.0-SNAPSHOT~050cad8b0e
    dateFormat X
    axisFormat %s
section baseline
no_agent (4.305 ms) : 4257, 4353
.   : milestone, 4305,
iast (9.654 ms) : 9494, 9814
.   : milestone, 9654,
iast_FULL (14.224 ms) : 13944, 14504
.   : milestone, 14224,
iast_GLOBAL (10.669 ms) : 10477, 10860
.   : milestone, 10669,
profiling (8.749 ms) : 8615, 8882
.   : milestone, 8749,
tracing (8.177 ms) : 8060, 8295
.   : milestone, 8177,
section candidate
no_agent (4.36 ms) : 4311, 4409
.   : milestone, 4360,
iast (9.876 ms) : 9712, 10041
.   : milestone, 9876,
iast_FULL (13.887 ms) : 13615, 14160
.   : milestone, 13887,
iast_GLOBAL (11.19 ms) : 10988, 11391
.   : milestone, 11190,
profiling (8.798 ms) : 8653, 8942
.   : milestone, 8798,
tracing (7.476 ms) : 7372, 7580
.   : milestone, 7476,
Loading
  • baseline results
Variant Request duration [CI 0.99] Δ no_agent
no_agent 4.305 ms [4.257 ms, 4.353 ms] -
iast 9.654 ms [9.494 ms, 9.814 ms] 5.349 ms (124.3%)
iast_FULL 14.224 ms [13.944 ms, 14.504 ms] 9.919 ms (230.4%)
iast_GLOBAL 10.669 ms [10.477 ms, 10.86 ms] 6.364 ms (147.8%)
profiling 8.749 ms [8.615 ms, 8.882 ms] 4.444 ms (103.2%)
tracing 8.177 ms [8.06 ms, 8.295 ms] 3.873 ms (90.0%)
  • candidate results
Variant Request duration [CI 0.99] Δ no_agent
no_agent 4.36 ms [4.311 ms, 4.409 ms] -
iast 9.876 ms [9.712 ms, 10.041 ms] 5.516 ms (126.5%)
iast_FULL 13.887 ms [13.615 ms, 14.16 ms] 9.527 ms (218.5%)
iast_GLOBAL 11.19 ms [10.988 ms, 11.391 ms] 6.83 ms (156.6%)
profiling 8.798 ms [8.653 ms, 8.942 ms] 4.437 ms (101.8%)
tracing 7.476 ms [7.372 ms, 7.58 ms] 3.116 ms (71.5%)

Dacapo

Parameters

Baseline Candidate
baseline_or_candidate baseline candidate
git_branch master alexeyk/refactored-env-vars-to-be-testable
git_commit_date 1758813010 1758813563
git_commit_sha 050cad8 335f9f2
release_version 1.54.0-SNAPSHOT~050cad8b0e 1.54.0-SNAPSHOT~335f9f25a7
See matching parameters
Baseline Candidate
application biojava biojava
ci_job_date 1758815523 1758815523
ci_job_id 1147891494 1147891494
ci_pipeline_id 77542437 77542437
cpu_model Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz
kernel_version Linux runner-zfyrx7zua-project-304-concurrent-2-t3kqjkoz 6.8.0-1031-aws #33~22.04.1-Ubuntu SMP Thu Jun 26 14:22:30 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux Linux runner-zfyrx7zua-project-304-concurrent-2-t3kqjkoz 6.8.0-1031-aws #33~22.04.1-Ubuntu SMP Thu Jun 26 14:22:30 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux

Summary

Found 0 performance improvements and 0 performance regressions! Performance is the same for 11 metrics, 1 unstable metrics.

Execution time for tomcat
gantt
    title tomcat - execution time [CI 0.99] : candidate=1.54.0-SNAPSHOT~335f9f25a7, baseline=1.54.0-SNAPSHOT~050cad8b0e
    dateFormat X
    axisFormat %s
section baseline
no_agent (1.489 ms) : 1477, 1501
.   : milestone, 1489,
appsec (3.75 ms) : 3532, 3969
.   : milestone, 3750,
iast (2.223 ms) : 2159, 2287
.   : milestone, 2223,
iast_GLOBAL (2.265 ms) : 2201, 2330
.   : milestone, 2265,
profiling (2.088 ms) : 2035, 2140
.   : milestone, 2088,
tracing (2.051 ms) : 2001, 2101
.   : milestone, 2051,
section candidate
no_agent (1.488 ms) : 1477, 1500
.   : milestone, 1488,
appsec (3.747 ms) : 3528, 3965
.   : milestone, 3747,
iast (2.23 ms) : 2166, 2294
.   : milestone, 2230,
iast_GLOBAL (2.263 ms) : 2199, 2327
.   : milestone, 2263,
profiling (2.093 ms) : 2040, 2146
.   : milestone, 2093,
tracing (2.03 ms) : 1981, 2079
.   : milestone, 2030,
Loading
  • baseline results
Variant Execution Time [CI 0.99] Δ no_agent
no_agent 1.489 ms [1.477 ms, 1.501 ms] -
appsec 3.75 ms [3.532 ms, 3.969 ms] 2.261 ms (151.9%)
iast 2.223 ms [2.159 ms, 2.287 ms] 734.436 µs (49.3%)
iast_GLOBAL 2.265 ms [2.201 ms, 2.33 ms] 776.133 µs (52.1%)
profiling 2.088 ms [2.035 ms, 2.14 ms] 598.682 µs (40.2%)
tracing 2.051 ms [2.001 ms, 2.101 ms] 561.87 µs (37.7%)
  • candidate results
Variant Execution Time [CI 0.99] Δ no_agent
no_agent 1.488 ms [1.477 ms, 1.5 ms] -
appsec 3.747 ms [3.528 ms, 3.965 ms] 2.258 ms (151.7%)
iast 2.23 ms [2.166 ms, 2.294 ms] 741.481 µs (49.8%)
iast_GLOBAL 2.263 ms [2.199 ms, 2.327 ms] 774.508 µs (52.0%)
profiling 2.093 ms [2.04 ms, 2.146 ms] 604.334 µs (40.6%)
tracing 2.03 ms [1.981 ms, 2.079 ms] 541.637 µs (36.4%)
Execution time for biojava
gantt
    title biojava - execution time [CI 0.99] : candidate=1.54.0-SNAPSHOT~335f9f25a7, baseline=1.54.0-SNAPSHOT~050cad8b0e
    dateFormat X
    axisFormat %s
section baseline
no_agent (14.949 s) : 14949000, 14949000
.   : milestone, 14949000,
appsec (15.253 s) : 15253000, 15253000
.   : milestone, 15253000,
iast (18.763 s) : 18763000, 18763000
.   : milestone, 18763000,
iast_GLOBAL (18.078 s) : 18078000, 18078000
.   : milestone, 18078000,
profiling (15.635 s) : 15635000, 15635000
.   : milestone, 15635000,
tracing (15.254 s) : 15254000, 15254000
.   : milestone, 15254000,
section candidate
no_agent (15.317 s) : 15317000, 15317000
.   : milestone, 15317000,
appsec (15.145 s) : 15145000, 15145000
.   : milestone, 15145000,
iast (18.377 s) : 18377000, 18377000
.   : milestone, 18377000,
iast_GLOBAL (18.218 s) : 18218000, 18218000
.   : milestone, 18218000,
profiling (15.904 s) : 15904000, 15904000
.   : milestone, 15904000,
tracing (15.463 s) : 15463000, 15463000
.   : milestone, 15463000,
Loading
  • baseline results
Variant Execution Time [CI 0.99] Δ no_agent
no_agent 14.949 s [14.949 s, 14.949 s] -
appsec 15.253 s [15.253 s, 15.253 s] 304.0 ms (2.0%)
iast 18.763 s [18.763 s, 18.763 s] 3.814 s (25.5%)
iast_GLOBAL 18.078 s [18.078 s, 18.078 s] 3.129 s (20.9%)
profiling 15.635 s [15.635 s, 15.635 s] 686.0 ms (4.6%)
tracing 15.254 s [15.254 s, 15.254 s] 305.0 ms (2.0%)
  • candidate results
Variant Execution Time [CI 0.99] Δ no_agent
no_agent 15.317 s [15.317 s, 15.317 s] -
appsec 15.145 s [15.145 s, 15.145 s] -172.0 ms (-1.1%)
iast 18.377 s [18.377 s, 18.377 s] 3.06 s (20.0%)
iast_GLOBAL 18.218 s [18.218 s, 18.218 s] 2.901 s (18.9%)
profiling 15.904 s [15.904 s, 15.904 s] 587.0 ms (3.8%)
tracing 15.463 s [15.463 s, 15.463 s] 146.0 ms (1.0%)

Copy link
Contributor

@daniel-mohedano daniel-mohedano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, some small feedback regarding changes to CIVis tests

def additionalIgnoredTags = CiVisibilityTestUtils.IGNORED_TAGS + ignoredTags

if (System.getenv().get("GENERATE_TEST_FIXTURES") != null) {
if (EnvironmentVariables.get("GENERATE_TEST_FIXTURES") != null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tested locally and after the changes the env var doesn't seem to be picked up. We use it locally to generate new test fixtures when they need to be updated, so it's not actually part of the testing process itself. I think it's safe to keep as it was

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While it might be safe to keep the old way, using EnvironmentVariables can help share example of how to access environment variable.

In my opinion if the env var is not used, then maybe the while check has to go ? But this is another PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is used, but only manually by us when developing locally. We just use as quality of life. Instead of, for example, commenting out the generation code and uncommenting it when we need to generate new test fixtures, we just do so through the environment variable, which is much more convenient

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@daniel-mohedano Actually there is a workaround for such use case, just set TEST_ENV_PROPAGATE_VARS= GENERATE_TEST_FIXTURES and it will be propagated to test. Would this work? I can document it as comment or some readme file. WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That totally works too, yeah! If you could add a comment to document the behavior, that would be helpful too. Small sidenote also, while testing I've found that we probably also want to populate the vars on datadog.trace.test.util.DDSpecification#setup. In parameterized tests the cleanup method is called after each configuration is run, so the propagated vars are only available on the first run

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While it might be safe to keep the old way, using EnvironmentVariables can help share example of how to access environment variable.

The environment component was designed to be used in the agent / client lib, not for general purpose or testing. It's expected to use the default env var and JVM checks when using tests, not the environment component. For example, you're supposed to use the JUnit @EnabledOnJre() annotation rather than using the JavaVirtualMachine for testing conditions.

I might later evolve the component in a way that is not testing friendly but tailored for agent bootstrap for example. So please keep using the default testing framework capabilities and System for testing. That is why I did not port testing code in the first place.

Comment on lines +71 to 76
if (EnvironmentVariables.get("DD_CIVISIBILITY_SMOKETEST_DEBUG_PARENT") != null) {
arguments += "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005"
}
if (System.getenv("DD_CIVISIBILITY_SMOKETEST_DEBUG_CHILD") != null) {
if (EnvironmentVariables.get("DD_CIVISIBILITY_SMOKETEST_DEBUG_CHILD") != null) {
argMap.put(CiVisibilityConfig.CIVISIBILITY_DEBUG_PORT, "5055")
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same rationale as above, not actually part of the testing process so probably safe to keep as is.

def additionalReplacements = ["content.meta.['test.toolchain']": "$toolchain:$toolchainVersion"]

if (System.getenv().get("GENERATE_TEST_FIXTURES") != null) {
if (EnvironmentVariables.get("GENERATE_TEST_FIXTURES") != null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

Copy link
Member

@jpbempel jpbempel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@PerfectSlayer PerfectSlayer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 suggestion: ‏I saw the component usage pushed to the testing code while it was mainly designed for the tracer.
How do you expect to reconcile this usage with framework like JUnit who won’t leverage it?

}

// Make it accessible from tests.
public static volatile EnvironmentVariablesProvider provider = new EnvironmentVariablesProvider();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❔ question: ‏Would there be a performance impact introducing volatile field access before env var access?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

considering the number of calls, I don't think you will see a measurable effect on this (particularly on x86).
From JDK9 you could workaround the usage of volatile qualifier by using VarHandles

public static Map<String, String> getAll() {
try {
return unmodifiableMap(new HashMap<>(System.getenv()));
return unmodifiableMap(new HashMap<>(provider.getAll()));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❔ question: ‏I wonder if I still should make a snapshot if its fine returning the original map 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I, personally, love the unmodifiableMap to make sure that map would not be modified later.
No strong opinion here...

@AlexeyKuznetsov-DD
Copy link
Contributor Author

AlexeyKuznetsov-DD commented Sep 23, 2025

🎯 suggestion: ‏I saw the component usage pushed to the testing code while it was mainly designed for the tracer. How do you expect to reconcile this usage with framework like JUnit who won’t leverage it?

After some thoughts I think that better not to mix testing code and library... I will revert some changes.

Comment on lines +43 to +47
System.getenv("TEST_ENV_PROPAGATE_VARS")
?.split(',')
?.each { envVar ->
provider[envVar] = System.getenv(envVar)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓ For my understanding, if there are actual env vars that needed to be accessed along with "fake" ones, I would need to set the env vars in the value of TEST_ENV_PROPAGATE_VARS?

Copy link
Contributor Author

@AlexeyKuznetsov-DD AlexeyKuznetsov-DD Sep 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mhlidd Yes, if you really need some variables from system level, just put TEST_ENV_PROPAGATE_VARS=var1,var2,...,varN as SYSTEM env var.
But I believe that this should be very rare corner case, our tests should be isolated from real env as much as possible.

@PerfectSlayer
Copy link
Contributor

After some thoughts I think that better not to mix testing code and library... I will revert some changes.

The main question is what are you trying to make "testable"?

All environment variables that are used as a way to control the "Java Client Library" behavior should never be accessing directly the System.getenv() nor the EnvironmentVariable.get(). All access will be guarded by @mhlidd ConfigHelper, which will have a way to setup test values -- you should discuss with him about his plans for config. There will be rules in ForbiddenApi gradle checks to prevent it.

The remaining access to environment variables should be to control tests, usually related to environment or CI setup. I'm not sure about the need a programmatic way to set them as we are controlling their value through our test setup.

Is there any other environment variable access I miss that must be testable?

@AlexeyKuznetsov-DD
Copy link
Contributor Author

After some thoughts I think that better not to mix testing code and library... I will revert some changes.

The main question is what are you trying to make "testable"?

All environment variables that are used as a way to control the "Java Client Library" behavior should never be accessing directly the System.getenv() nor the EnvironmentVariable.get(). All access will be guarded by @mhlidd ConfigHelper, which will have a way to setup test values -- you should discuss with him about his plans for config. There will be rules in ForbiddenApi gradle checks to prevent it.

The remaining access to environment variables should be to control tests, usually related to environment or CI setup. I'm not sure about the need a programmatic way to set them as we are controlling their value through our test setup.

Is there any other environment variable access I miss that must be testable?

@PerfectSlayer That make sense, I will chat with @mhlidd and rework my PR.
My main idea was to replace system-rules library which used to override access to System.getenv with reflection hack (that actually generates a lot of warnings under lates JDKs) and make sure that test can setup env vars without hacking System.getenv().

@mhlidd
Copy link
Contributor

mhlidd commented Sep 24, 2025

All environment variables that are used as a way to control the "Java Client Library" behavior should never be accessing directly the System.getenv() nor the EnvironmentVariable.get(). All access will be guarded by @mhlidd ConfigHelper, which will have a way to setup test values -- you should discuss with him about his plans for config. There will be rules in ForbiddenApi gradle checks to prevent it.

Adding on, but Config Inversion will only restrict the usages of EnvironmentVariables and System.getenv for src/main. Everything is allowed for testing. I don't think @AlexeyKuznetsov-DD and I will have any conflicting work (if anything I want to use the ControllableEnvironmentVariables util for my own Config Inversion tests. As discussed offline, Alexey will take a second look at my PRs to make sure that there is no conflict between our work. :)

@mhlidd mhlidd requested review from a team as code owners September 24, 2025 22:15
@mhlidd mhlidd requested review from smola, manuel-alvarez-alvarez and mtoffl01 and removed request for a team September 24, 2025 22:15
@mhlidd mhlidd force-pushed the alexeyk/refactored-env-vars-to-be-testable branch from 54f2e28 to 348f975 Compare September 24, 2025 22:24
@pr-commenter
Copy link

pr-commenter bot commented Sep 24, 2025

Debugger benchmarks

Parameters

Baseline Candidate
baseline_or_candidate baseline candidate
ci_job_date 1758814093 1758814439
end_time 2025-09-25T15:29:34 2025-09-25T15:35:19
git_branch master alexeyk/refactored-env-vars-to-be-testable
git_commit_sha 050cad8 335f9f2
start_time 2025-09-25T15:28:14 2025-09-25T15:34:00
See matching parameters
Baseline Candidate
ci_job_id 1147891511 1147891511
ci_pipeline_id 77542437 77542437
cpu_model Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz
git_commit_date 1758813563 1758813563

Summary

Found 0 performance improvements and 0 performance regressions! Performance is the same for 9 metrics, 6 unstable metrics.

See unchanged results
scenario Δ mean agg_http_req_duration_min Δ mean agg_http_req_duration_p50 Δ mean agg_http_req_duration_p75 Δ mean agg_http_req_duration_p99 Δ mean throughput
scenario:noprobe unstable
[-54.876µs; +21.604µs] or [-18.833%; +7.414%]
unstable
[-66.673µs; +32.875µs] or [-20.012%; +9.868%]
unstable
[-82.516µs; +40.982µs] or [-23.513%; +11.678%]
unstable
[-559.152µs; +127.875µs] or [-49.690%; +11.364%]
same
scenario:basic same same same unstable
[-104.135µs; +90.960µs] or [-13.989%; +12.219%]
unstable
[-105.629op/s; +247.876op/s] or [-4.014%; +9.419%]
scenario:loop same same same same same
Request duration reports for reports
gantt
    title reports - request duration [CI 0.99] : candidate=None, baseline=None
    dateFormat X
    axisFormat %s
section baseline
noprobe (333.161 µs) : 273, 393
.   : milestone, 333,
basic (277.913 µs) : 271, 285
.   : milestone, 278,
loop (8.965 ms) : 8959, 8971
.   : milestone, 8965,
section candidate
noprobe (316.262 µs) : 287, 346
.   : milestone, 316,
basic (275.673 µs) : 269, 282
.   : milestone, 276,
loop (8.965 ms) : 8961, 8970
.   : milestone, 8965,
Loading
  • baseline results
Scenario Request median duration [CI 0.99]
noprobe 333.161 µs [272.888 µs, 393.433 µs]
basic 277.913 µs [271.073 µs, 284.754 µs]
loop 8.965 ms [8.959 ms, 8.971 ms]
  • candidate results
Scenario Request median duration [CI 0.99]
noprobe 316.262 µs [286.966 µs, 345.558 µs]
basic 275.673 µs [269.327 µs, 282.02 µs]
loop 8.965 ms [8.961 ms, 8.97 ms]

Copy link

datadog-official bot commented Sep 24, 2025

🎯 Code Coverage
Patch Coverage: 85.71%
Total Coverage: 57.39% (-0.44%)

View detailed report

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 335f9f2 | Docs | Was this helpful? Give us feedback!

def additionalIgnoredTags = CiVisibilityTestUtils.IGNORED_TAGS + ignoredTags

if (System.getenv().get("GENERATE_TEST_FIXTURES") != null) {
if (EnvironmentVariables.get("GENERATE_TEST_FIXTURES") != null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While it might be safe to keep the old way, using EnvironmentVariables can help share example of how to access environment variable.

The environment component was designed to be used in the agent / client lib, not for general purpose or testing. It's expected to use the default env var and JVM checks when using tests, not the environment component. For example, you're supposed to use the JUnit @EnabledOnJre() annotation rather than using the JavaVirtualMachine for testing conditions.

I might later evolve the component in a way that is not testing friendly but tailored for agent bootstrap for example. So please keep using the default testing framework capabilities and System for testing. That is why I did not port testing code in the first place.

Comment on lines +181 to +182
env.set("DD_GIT_COMMIT_SHA", "sha1");
env.set("DD_GIT_REPOSITORY_URL", "http://github.com");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 suggestion: ‏This is typically the kind of test that should be migrated to be tested using config mocked value, not environment variables.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
comp: testing Testing tag: no release notes Changes to exclude from release notes type: enhancement Enhancements and improvements
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants