Skip to content

Commit

Permalink
Fix computation of min in Summary report
Browse files Browse the repository at this point in the history
  • Loading branch information
vlsi committed Jul 12, 2023
1 parent 8e612ec commit ce1f32a
Show file tree
Hide file tree
Showing 5 changed files with 290 additions and 6 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ kotlin.code.style=official
# This is version for Apache JMeter itself
# Note: it should not include "-SNAPSHOT" as it is automatically added by build.gradle.kts
# Release version can be generated by using -Prelease or -Prc=<int> arguments
jmeter.version=5.6.2
jmeter.version=5.6.3

# Plugins
com.github.vlsi.checksum-dependency.sha512=FAC41BF54A7C833BEAE9AB64083F6BEB3E1935BD6866C1B2F1D48FF926ABA4AECA53600FC3E41BE6ECBC87B73CE12F59C59836FB2E1DECC9408288060D66E988
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public class Calculator {

private final String label;

private final AtomicLong startTime = new AtomicLong(Long.MAX_VALUE);
private final AtomicLong startTime = new AtomicLong();

private final LongAccumulator elapsedTime = new LongAccumulator(Math::max, Long.MIN_VALUE);

Expand All @@ -63,6 +63,7 @@ public Calculator() {

public Calculator(String label) {
this.label = label;
clear();
}

public void clear() {
Expand Down
149 changes: 149 additions & 0 deletions src/core/src/test/kotlin/org/apache/jmeter/util/CalculatorTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/*
* 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.util

import org.apache.jmeter.samplers.SampleResult
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import kotlin.math.pow
import kotlin.math.sqrt

class CalculatorTest {
val calculator = Calculator()

@Test
fun min() {
assertEquals(Long.MAX_VALUE, calculator.min, "min()")
calculator.addSample(SampleResult(10, 42))
assertEquals(42, calculator.min, "min(42)")
calculator.addSample(SampleResult(10, 40))
assertEquals(40, calculator.min, "min(42, 40)")
calculator.addSample(SampleResult(10, 50))
assertEquals(40, calculator.min, "min(42, 40, 50)")
calculator.addSample(SampleResult(10, 50).apply { sampleCount = 2 })
assertEquals(25, calculator.min, "min(42, 40, 50, 50/2)")
}

@Test
fun max() {
assertEquals(Long.MIN_VALUE, calculator.max, "max()")
calculator.addSample(SampleResult(10, 40))
assertEquals(40, calculator.max, "max(40)")
calculator.addSample(SampleResult(10, 42))
assertEquals(42, calculator.max, "max(40, 42)")
calculator.addSample(SampleResult(10, 30))
assertEquals(42, calculator.max, "max(40, 42, 30)")
calculator.addSample(SampleResult(10, 90).apply { sampleCount = 2 })
assertEquals(45, calculator.max, "max(40, 42, 30, 90/2)")
}

@Test
fun countLong() {
assertEquals(0, calculator.countLong, "countLong()")
calculator.addSample(SampleResult(10, 40))
assertEquals(1, calculator.countLong, "countLong(40)")
calculator.addSample(SampleResult(10, 42))
assertEquals(2, calculator.countLong, "countLong(40, 42)")
calculator.addSample(SampleResult(10, 42).apply { sampleCount = 2 })
assertEquals(4, calculator.countLong, "countLong(40, 42, 42/2)")
}

@Test
fun mean() {
assertEquals(0.0, calculator.mean, "mean()")
calculator.addSample(SampleResult(10, 40))
assertEquals(40.0, calculator.mean, 0.001, "mean(40)")
calculator.addSample(SampleResult(10, 42))
assertEquals((40.0 + 42.0) / 2, calculator.mean, 0.001, "mean(40, 42)")
calculator.addSample(SampleResult(10, 48).apply { sampleCount = 2 })
assertEquals((40.0 + 42.0 + 48) / 4, calculator.mean, 0.001, "mean(40, 42, 48/2)")
}

@Test
fun standardDeviation() {
assertEquals(0.0, calculator.standardDeviation, "standardDeviation()")
calculator.addSample(SampleResult(10, 40))
assertEquals(0.0, calculator.standardDeviation, "standardDeviation(40)")
calculator.addSample(SampleResult(10, 42))
assertEquals(1.0, calculator.standardDeviation, "standardDeviation(40, 42)")
calculator.addSample(SampleResult(10, 43))
// Math.sqrt((sumOfSquares / count) - (mean * mean))
assertEquals(
sqrt((40 * 40 + 42 * 42 + 43 * 43) / 3.0 - ((40.0 + 42 + 43) / 3).pow(2)),
calculator.standardDeviation,
0.001,
"standardDeviation(40, 42, 43)"
)
calculator.addSample(SampleResult(10, 48).apply { sampleCount = 2 })
assertEquals(
sqrt((40 * 40 + 42 * 42 + 43 * 43 + 24 * 24 + 24 * 24) / 5.0 - ((40.0 + 42 + 43 + 24 + 24) / 5.0).pow(2)),
calculator.standardDeviation,
0.001,
"standardDeviation(40, 42, 43, 48/2)"
)
}

@Test
fun errorPercentage() {
assertEquals(0.0, calculator.errorPercentage, 0.001, "errorPercentage()")
calculator.addSample(SampleResult(10, 40).apply { isSuccessful = false })
assertEquals(1.0, calculator.errorPercentage, 0.001, "errorPercentage(KO)")
calculator.addSample(SampleResult(10, 42).apply { isSuccessful = false })
assertEquals(1.0, calculator.errorPercentage, 0.001, "errorPercentage(KO, KO)")
calculator.addSample(SampleResult(10, 42).apply { isSuccessful = true })
assertEquals(0.666, calculator.errorPercentage, 0.001, "errorPercentage(KO, KO, OK)")
}

@Test
fun bytesPerSecond() {
assertEquals(0.0, calculator.bytesPerSecond, "bytesPerSecond()")
calculator.addSample(SampleResult(40, 30).apply { setBodySize(50L) })
assertEquals(
50.0 * 1000 / (40 - 10.0),
calculator.bytesPerSecond,
0.001,
"bytesPerSecond({50bytes, 10ms..40ms})"
)
calculator.addSample(SampleResult(60, 20).apply { setBodySize(70L) })
assertEquals(
(50 + 70.0) * 1000 / (60 - 10.0),
calculator.bytesPerSecond,
0.001,
"bytesPerSecond({50bytes, 10ms..40ms}, {70bytes, 40ms..60ms})"
)
}

@Test
fun sentBytesPerSecond() {
assertEquals(0.0, calculator.sentBytesPerSecond, "sentBytesPerSecond()")
calculator.addSample(SampleResult(40, 30).apply { sentBytes = 50L })
assertEquals(
50.0 * 1000 / (40 - 10.0),
calculator.sentBytesPerSecond,
0.001,
"sentBytesPerSecond({sent=50bytes, 10ms..40ms})"
)
calculator.addSample(SampleResult(60, 20).apply { sentBytes = 70L })
assertEquals(
(50 + 70.0) * 1000 / (60 - 10.0),
calculator.sentBytesPerSecond,
0.001,
"sentBytesPerSecond({sent=50bytes, 10ms..40ms}, {sent=70bytes, 40ms..60ms})"
)
}
}
7 changes: 3 additions & 4 deletions xdocs/changes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ JMeter 5.6.x requires Java 8 or later for execution (Java 17 or later recommende
<b>The next major release would require Java 11 or later.</b>
</note>

<!-- =================== 5.6.2 =================== -->
<!-- =================== 5.6.3 =================== -->

<h1>Version 5.6.2 </h1>
<h1>Version 5.6.3 </h1>
<p>
Summary
</p>
Expand All @@ -68,8 +68,7 @@ Summary

<h3>General</h3>
<ul>
<li><pr>6042</pr><issue>6041</issue>Fix compatibility with Maven's pom.xml parser by adding explicit versions for
<code>com.google.auto.service:auto-service-annotations</code> (regression since 5.6)</li>
<li><pr></pr><issue>6043</issue>Fix computation of <code>min</code> in <code>Summary report</code> (regression since 5.6.0)</li>
</ul>

<!-- =================== Thanks =================== -->
Expand Down
135 changes: 135 additions & 0 deletions xdocs/changes_history.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,137 @@ Current changes are detailed in <a href="changes.html">Changes</a>.
<p><b>Changes sections are chronologically ordered from top (most recent) to bottom
(least recent)</b></p>

<!-- =================== 5.6.2 =================== -->

<h1>Version 5.6.2 </h1>
<p>
Summary
</p>
<ul>
<li><a href="#Bug fixes">Bug fixes</a></li>
</ul>

<!-- =================== Bug fixes =================== -->

<ch_section>Bug fixes</ch_section>

<h3>General</h3>
<ul>
<li><pr>6042</pr><issue>6041</issue>Fix compatibility with Maven's pom.xml parser by adding explicit versions for
<code>com.google.auto.service:auto-service-annotations</code> (regression since 5.6)</li>
</ul>

<!-- =================== Thanks =================== -->

<ch_section>Thanks</ch_section>
<p>We thank all contributors mentioned in bug and improvement sections above:
</p>
<ul>
</ul>
<p>We also thank bug reporters who helped us improve JMeter.</p>
<ul>
</ul>
<p>
Apologies if we have omitted anyone else.
</p>
<!-- =================== Known bugs or issues related to JAVA Bugs =================== -->

<ch_section>Known problems and workarounds</ch_section>
<ul>
<li><issue>6043</issue> <code>Min</code> is always <code>0</code> in <code>Summary Report</code> (fixed in 5.6.3)</li>

<li>The Once Only controller behaves correctly under a Thread Group or Loop Controller,
but otherwise its behaviour is not consistent (or clearly specified).</li>

<li>
The numbers that appear to the left of the green box are the number of active threads / total number of threads,
the total number of threads only applies to a locally run test, otherwise it will show <code>0</code> (see <bugzilla>55510</bugzilla>).
</li>

<li>
Note that under some windows systems you may have this WARNING:
<source>
java.util.prefs.WindowsPreferences
WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0
x80000002. Windows RegCreateKeyEx(&hellip;) returned error code 5.
</source>
The fix is to run JMeter as Administrator, it will create the registry key for you, then you can restart JMeter as a normal user and you won't have the warning anymore.
</li>

<li>
You may encounter the following error:
<source>java.security.cert.CertificateException: Certificates does not conform to algorithm constraints</source>
if you run a HTTPS request on a web site with a SSL certificate (itself or one of SSL certificates in its chain of trust) with a signature
algorithm using MD2 (like <code>md2WithRSAEncryption</code>) or with a SSL certificate with a size lower than 1024 bits.
This error is related to increased security in Java 8+.
<br></br>
To allow you to perform your HTTPS request, you can downgrade the security of your Java installation by editing
the Java <code>jdk.certpath.disabledAlgorithms</code> property. Remove the MD2 value or the constraint on size, depending on your case.
<br></br>
This property is in this file:
<source>JAVA_HOME/jre/lib/security/java.security</source>
See <bugzilla>56357</bugzilla> for details.
</li>

<li>
Under Mac OSX Aggregate Graph will show wrong values due to mirroring effect on numbers.
This is due to a known Java bug, see Bug <a href="https://bugs.openjdk.java.net/browse/JDK-8065373" >JDK-8065373</a>
The fix is to use JDK8_u45 or later.
</li>

<li>
View Results Tree may fail to display some HTML code under HTML renderer, see <bugzilla>54586</bugzilla>.
This is due to a known Java bug which fails to parse "<code>px</code>" units in row/col attributes.
See Bug <a href="https://bugs.openjdk.java.net/browse/JDK-8031109" >JDK-8031109</a>
The fix is to use JDK9 b65 or later.
</li>

<li>
JTable selection with keyboard (<keycombo><keysym>SHIFT</keysym><keysym>up/down</keysym></keycombo>) is totally unusable with Java 7 on Mac OSX.
This is due to a known Java bug <a href="https://bugs.openjdk.java.net/browse/JDK-8025126" >JDK-8025126</a>
The fix is to use JDK 8 b132 or later.
</li>

<li>
Since Java 11 the JavaScript implementation <a href="https://openjdk.java.net/jeps/335">Nashorn has been deprecated</a>.
Java will emit the following deprecation warnings, if you are using JavaScript based on Nashorn.
<source>
Warning: Nashorn engine is planned to be removed from a future JDK release
</source>
To silence these warnings, add <code>-Dnashorn.args=--no-deprecation-warning</code> to your Java arguments.
That can be achieved by setting the enviroment variable <code>JVM_ARGS</code>
<source>
export JVM_ARGS="-Dnashorn.args=--no-deprecation-warning"
</source>
</li>

<li>
With Java 15 the JavaScript implementation <a href="https://openjdk.java.net/jeps/372">Nashorn has been removed</a>. To add back a JSR-223 compatible JavaScript engine you have two options:
<dl>
<dt>Use Mozilla Rhino</dt>
<dd>Copy <a href="https://github.com/mozilla/rhino/releases/download/Rhino1_7_14_Release/rhino-engine-1.7.14.jar">rhino-engine-1.7.14.jar</a> into <code>$JMETER_HOME/lib/ext</code>.</dd>
<dt>Use OpenJDK Nashorn</dt>
<dd>
The OpenJDK Nashorn implementation comes as a module. To use it, you will have to download it and add it to the module path. A hacky way to download the version 15.0 (or later) and its dependencies and set the module path is outlined below:
<source>
mkdir lib/modules
pushd lib/modules
wget https://repo1.maven.org/maven2/org/openjdk/nashorn/nashorn-core/15.3/nashorn-core-15.3.jar
wget https://repo1.maven.org/maven2/org/ow2/asm/asm/9.5/asm-9.5.jar
wget https://repo1.maven.org/maven2/org/ow2/asm/asm-commons/9.5/asm-commons-9.5.jar
wget https://repo1.maven.org/maven2/org/ow2/asm/asm-util/9.5/asm-util-9.5.jar
wget https://repo1.maven.org/maven2/org/ow2/asm/asm-tree/9.5/asm-tree-9.5.jar
wget https://repo1.maven.org/maven2/org/ow2/asm/asm-analysis/9.5/asm-analysis-9.5.jar
popd
export JVM_ARGS="--module-path $PWD/lib/modules"
./bin/jmeter
</source>
</dd>
</dl>
</li>

</ul>

<!-- =================== 5.6.1 =================== -->

<h1>Version 5.6.1</h1>
Expand Down Expand Up @@ -122,6 +253,8 @@ Apologies if we have omitted anyone else.
<ul>
<li><code>pom.xml</code> misses <code>&lt;version&gt;</code> tags for <code>auto-service-annotations</code>, so Maven can't infer transitive dependencies. The issue is resolved in 5.6.2</li>

<li><issue>6043</issue> <code>Min</code> is always <code>0</code> in <code>Summary Report</code> (fixed in 5.6.3)</li>

<li>The Once Only controller behaves correctly under a Thread Group or Loop Controller,
but otherwise its behaviour is not consistent (or clearly specified).</li>

Expand Down Expand Up @@ -410,6 +543,8 @@ Apologies if we have omitted anyone else.
<ul>
<li><issue>6008</issue> ThreadGroups are running endlessly in non-gui mode (fixed in 5.6.1, see <pr>6011</pr>)</li>

<li><issue>6043</issue> <code>Min</code> is always <code>0</code> in <code>Summary Report</code> (fixed in 5.6.3)</li>

<li><pr>5987</pr>HTTP sampler sends filenames with percent-encoded UTF-8, however it is not aligned with the browsers. The workaround is to refrain non-ASCII filenames</li>

<li><issue>6004</issue>Java Request sampler cannot be enabled again after disabling in UI (fixed in 5.6.1, <pr>6012</pr>)</li>
Expand Down

0 comments on commit ce1f32a

Please sign in to comment.