mirror of https://github.com/apache/jmeter.git
Merge branch 'master' into bug_64553
This commit is contained in:
commit
459efe1bee
|
|
@ -22,10 +22,12 @@ jobs:
|
|||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 14
|
||||
- name: 'Test'
|
||||
shell: bash
|
||||
run: |
|
||||
./gradlew --no-parallel build -x distTar -x distTarSource
|
||||
- uses: burrunan/gradle-cache-action@v1
|
||||
name: Test
|
||||
with:
|
||||
job-id: jdk14
|
||||
multi-cache-enabled: false
|
||||
arguments: --scan --no-parallel build -x distTar -x distTarSource
|
||||
|
||||
mac:
|
||||
name: 'macOS (JDK 14)'
|
||||
|
|
@ -38,6 +40,9 @@ jobs:
|
|||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 14
|
||||
- name: 'Test'
|
||||
run: |
|
||||
./gradlew --no-parallel build -x distTar -x distTarSource -Dskip.test_TestDNSCacheManager.testWithCustomResolverAnd1Server=true
|
||||
- uses: burrunan/gradle-cache-action@v1
|
||||
name: Test
|
||||
with:
|
||||
job-id: jdk14
|
||||
multi-cache-enabled: false
|
||||
arguments: --scan --no-parallel build -x distTar -x distTarSource -Dskip.test_TestDNSCacheManager.testWithCustomResolverAnd1Server=true
|
||||
|
|
|
|||
14
README.md
14
README.md
|
|
@ -107,7 +107,7 @@ The following requirements exist for running Apache JMeter:
|
|||
|
||||
- Java Compiler (*OPTIONAL*):
|
||||
|
||||
A Java compiler is not needed since the distribution cludes a
|
||||
A Java compiler is not needed since the distribution includes a
|
||||
precompiled Java binary archive.
|
||||
> **Note** that a compiler is required to build plugins for Apache JMeter.
|
||||
|
||||
|
|
@ -126,7 +126,7 @@ The following requirements exist for running Apache JMeter:
|
|||
|
||||
### Windows
|
||||
|
||||
For Windows there are also some other scripts which you can drag-and-drop
|
||||
For Windows, there are also some other scripts which you can drag-and-drop
|
||||
a JMX file onto:
|
||||
|
||||
- `jmeter-n.cmd` - runs the file as a non-GUI test
|
||||
|
|
@ -160,7 +160,7 @@ _This is useful for testing what happens if the optional jars are not
|
|||
downloaded by other JMeter users._
|
||||
|
||||
If you are behind a proxy, you can set a few build properties in
|
||||
`~/.gradle/gradle.properties` for gradle to use the proxy:
|
||||
`~/.gradle/gradle.properties` for Gradle to use the proxy:
|
||||
|
||||
```properties
|
||||
systemProp.http.proxyHost=proxy.example.invalid
|
||||
|
|
@ -193,14 +193,16 @@ The output artifacts (jars, reports) are placed in the `build` folder.
|
|||
For instance, binary artifacts can be found under `src/dist/build/distributions`.
|
||||
|
||||
The following command would compile the application and enable you to run `jmeter`
|
||||
from the `bin` directory. Note: it completely refreshes `lib/` contents,
|
||||
so it would remove clustom plugins should you have them installed.
|
||||
from the `bin` directory.
|
||||
|
||||
> **Note** that it completely refreshes `lib/` contents,
|
||||
so it would remove custom plugins should you have them installed.
|
||||
|
||||
```sh
|
||||
./gradlew createDist
|
||||
```
|
||||
|
||||
Alternatively you could get Gradle to start the GUI:
|
||||
Alternatively, you could get Gradle to start the GUI:
|
||||
|
||||
```sh
|
||||
./gradlew runGui
|
||||
|
|
|
|||
|
|
@ -140,6 +140,14 @@
|
|||
# See https://bz.apache.org/bugzilla/show_bug.cgi?id=52026 for details
|
||||
# N.B. the LAF can be defined in user.properties.
|
||||
|
||||
# Enable custom window chrome for Darklaf Look and Feels.
|
||||
# defaults to false
|
||||
# darklaf.decorations=false
|
||||
|
||||
# Enables the unified menubar for Darklaf Look and Feels.
|
||||
# defaults to true
|
||||
# darklaf.unifiedMenuBar=true
|
||||
|
||||
# LoggerPanel display
|
||||
# default to false
|
||||
#jmeter.loggerpanel.display=false
|
||||
|
|
|
|||
|
|
@ -15,8 +15,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import com.github.spotbugs.SpotBugsPlugin
|
||||
import com.github.spotbugs.SpotBugsTask
|
||||
import com.github.spotbugs.snom.SpotBugsTask
|
||||
import com.github.vlsi.gradle.crlf.CrLfSpec
|
||||
import com.github.vlsi.gradle.crlf.LineEndings
|
||||
import com.github.vlsi.gradle.crlf.filter
|
||||
|
|
@ -188,11 +187,15 @@ sonarqube {
|
|||
}
|
||||
}
|
||||
|
||||
fun SonarQubeProperties.add(name: String, value: String) {
|
||||
properties.getOrPut(name) { mutableSetOf<String>() }
|
||||
fun SonarQubeProperties.add(name: String, valueProvider: () -> String) {
|
||||
properties.getOrPut(name) { mutableSetOf<Any>() }
|
||||
.also {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
(it as MutableCollection<String>).add(value)
|
||||
(it as MutableCollection<Any>).add(object {
|
||||
// SonarQube calls toString when converting properties to values
|
||||
// (see SonarQubeProperties), so we use that to emulate "lazy properties"
|
||||
override fun toString() = valueProvider()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -239,7 +242,11 @@ if (enableSpotBugs) {
|
|||
sonarqube {
|
||||
properties {
|
||||
spotBugTasks.configureEach {
|
||||
add("sonar.java.spotbugs.reportPaths", reports.xml.destination.toString())
|
||||
add("sonar.java.spotbugs.reportPaths") {
|
||||
// Note: report is created with lower-case xml, and then
|
||||
// the created entry MUST be retrieved as upper-case XML
|
||||
reports.named("XML").get().destination.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -321,8 +328,14 @@ allprojects {
|
|||
}
|
||||
val sourceSets: SourceSetContainer by project
|
||||
if (sourceSets.isNotEmpty()) {
|
||||
val checkstyleTasks = tasks.withType<Checkstyle>()
|
||||
checkstyleTasks.configureEach {
|
||||
// Checkstyle 8.26 does not need classpath, see https://github.com/gradle/gradle/issues/14227
|
||||
classpath = files()
|
||||
}
|
||||
|
||||
tasks.register("checkstyleAll") {
|
||||
dependsOn(tasks.withType<Checkstyle>())
|
||||
dependsOn(checkstyleTasks)
|
||||
}
|
||||
tasks.register("checkstyle") {
|
||||
group = LifecycleBasePlugin.VERIFICATION_GROUP
|
||||
|
|
@ -341,11 +354,11 @@ allprojects {
|
|||
}
|
||||
}
|
||||
}
|
||||
apply<SpotBugsPlugin>()
|
||||
apply(plugin = "com.github.spotbugs")
|
||||
|
||||
spotbugs {
|
||||
toolVersion = "spotbugs".v
|
||||
isIgnoreFailures = ignoreSpotBugsFailures
|
||||
toolVersion.set("spotbugs".v)
|
||||
ignoreFailures.set(ignoreSpotBugsFailures)
|
||||
}
|
||||
|
||||
if (!skipAutostyle) {
|
||||
|
|
@ -457,21 +470,17 @@ allprojects {
|
|||
options.encoding = "UTF-8"
|
||||
}
|
||||
withType<ProcessResources>().configureEach {
|
||||
from(source) {
|
||||
include("**/*.properties")
|
||||
filteringCharset = "UTF-8"
|
||||
// apply native2ascii conversion since Java 8 expects properties to have ascii symbols only
|
||||
filter(org.apache.tools.ant.filters.EscapeUnicode::class)
|
||||
filter(LineEndings.LF)
|
||||
}
|
||||
// Text-like resources are normalized to LF (just for consistency purposes)
|
||||
// This makes to produce exactly the same jar files no matter which OS is used for the build
|
||||
from(source) {
|
||||
include("**/*.dtd")
|
||||
include("**/*.svg")
|
||||
include("**/*.txt")
|
||||
filteringCharset = "UTF-8"
|
||||
filter(LineEndings.LF)
|
||||
filteringCharset = "UTF-8"
|
||||
eachFile {
|
||||
if (name.endsWith(".properties")) {
|
||||
filteringCharset = "UTF-8"
|
||||
// apply native2ascii conversion since Java 8 expects properties to have ascii symbols only
|
||||
filter(org.apache.tools.ant.filters.EscapeUnicode::class)
|
||||
filter(LineEndings.LF)
|
||||
} else if (name.endsWith(".dtd") || name.endsWith(".svg") ||
|
||||
name.endsWith(".txt")) {
|
||||
filter(LineEndings.LF)
|
||||
}
|
||||
}
|
||||
}
|
||||
afterEvaluate {
|
||||
|
|
@ -506,6 +515,11 @@ allprojects {
|
|||
exceptionFormat = TestExceptionFormat.FULL
|
||||
showStandardStreams = true
|
||||
}
|
||||
|
||||
outputs.cacheIf("test outcomes sometimes depends on third-party systems, so we should not cache it for now") {
|
||||
false
|
||||
}
|
||||
|
||||
// Pass the property to tests
|
||||
fun passProperty(name: String, default: String? = null) {
|
||||
val value = System.getProperty(name) ?: default
|
||||
|
|
@ -522,10 +536,11 @@ allprojects {
|
|||
description = "$description (skipped by default, to enable it add -Dspotbugs)"
|
||||
}
|
||||
reports {
|
||||
html.isEnabled = reportsForHumans()
|
||||
xml.isEnabled = !reportsForHumans()
|
||||
// This is for Sonar
|
||||
xml.isWithMessages = true
|
||||
// xml goes for SonarQube, so we always create it just in case
|
||||
create("xml")
|
||||
if (reportsForHumans()) {
|
||||
create("html")
|
||||
}
|
||||
}
|
||||
enabled = enableSpotBugs
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,9 @@
|
|||
<dependency group='org.gradle.kotlin' module='plugins' version='1.3.4'>
|
||||
<sha512>B6F05B16B1826C3FD50D80AFD14965566B27313691A111EC8589867678D6B92AF827E5E098BECCE8F911D8B479AF5303322A6B2ECA971D1A2D985F42BD1AAA87</sha512>
|
||||
</dependency>
|
||||
<dependency group='org.gradle.kotlin' module='plugins' version='1.3.6'>
|
||||
<sha512>FFC641492549525D06D6788A3D708C7108AFA06C35796EF0B3A71541672162A7BAFDE6DC8F90F63D524BA33D1447C172C589491C16CF3B91C2C3E150AAB71B46</sha512>
|
||||
</dependency>
|
||||
<dependency group='org.slf4j' module='jcl-over-slf4j' version='1.6.2'>
|
||||
<sha512>3BA508C96EE0985865C9E86EBE803D1903835F7C198EB15723CDC86B028D6C82DBB7E96ECB01CEFAD7CC6EC7023155676D034B6B730A911D0FFE9F91FE532592</sha512>
|
||||
</dependency>
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
|
||||
dependencies {
|
||||
compile("org.ajoberstar.grgit:grgit-gradle:3.1.1")
|
||||
implementation("org.ajoberstar.grgit:grgit-gradle:3.1.1")
|
||||
}
|
||||
|
||||
gradlePlugin {
|
||||
|
|
|
|||
12
checksum.xml
12
checksum.xml
|
|
@ -14,11 +14,13 @@
|
|||
<trusted-key id='8ea48d105232855d' group='com.github.jknack' />
|
||||
<trusted-key id='461a804f2609fd89' group='com.github.shyiko.klob' />
|
||||
<trusted-key id='1756b920eecf0e90' group='com.github.spotbugs' />
|
||||
<trusted-key id='a5def5a76f94a471' group='com.github.spotbugs' />
|
||||
<trusted-key id='78fcd238c26ea995' group='com.github.tomakehurst' />
|
||||
<trusted-key id='105cb91cac2aee0e' group='com.github.vlsi.gradle' />
|
||||
<trusted-key id='254e9c64c264c176' group='com.github.weisj' />
|
||||
<trusted-key id='59a252fb1199d873' group='com.google.code.findbugs' />
|
||||
<trusted-key id='7a01b0f236e5430f' group='com.google.code.gson' />
|
||||
<trusted-key id='1669c4bb543e0445' group='com.google.errorprone' />
|
||||
<trusted-key id='912d2c0eccda55c0' group='com.google.errorprone' />
|
||||
<trusted-key id='9a259c7ee636c5ed' group='com.google.errorprone' />
|
||||
<trusted-key id='bf935c771a8474f8' group='com.google.errorprone' />
|
||||
|
|
@ -39,6 +41,7 @@
|
|||
<trusted-key id='6425559c47cc79c4' group='com.sun.activation' />
|
||||
<trusted-key id='602ec18d20c4661c' group='com.thoughtworks.xstream' />
|
||||
<trusted-key id='1861c322c56014b2' group='commons-beanutils' />
|
||||
<trusted-key id='3faad2cd5ecbb314' group='commons-beanutils' />
|
||||
<trusted-key id='411063a3a0ffd119' group='commons-beanutils' />
|
||||
<trusted-key id='9daadc1c9fcc82d0' group='commons-cli' />
|
||||
<trusted-key id='86fdc7e2a11262cb' group='commons-codec' />
|
||||
|
|
@ -77,8 +80,8 @@
|
|||
<trusted-key id='411063a3a0ffd119' group='org.apache-extras.beanshell' />
|
||||
<trusted-key id='87a7f75a6a8ba5fc' group='org.apache.activemq' />
|
||||
<trusted-key id='bff2ee42c8282e76' group='org.apache.activemq' />
|
||||
<trusted-key id='ddbcc1270a29d081' group='org.apache.ant' />
|
||||
<trusted-key id='a2115ae15f6b8b72' group='org.apache.ant' />
|
||||
<trusted-key id='ddbcc1270a29d081' group='org.apache.ant' />
|
||||
<trusted-key id='86fdc7e2a11262cb' group='org.apache.bcel' />
|
||||
<trusted-key id='3faad2cd5ecbb314' group='org.apache.commons' />
|
||||
<trusted-key id='64a16faaec16a4be' group='org.apache.commons' />
|
||||
|
|
@ -130,6 +133,7 @@
|
|||
<trusted-key id='98fe03a974ce0a0b' group='org.jetbrains.kotlin' />
|
||||
<trusted-key id='379ce192d401ab61' group='org.jetbrains.kotlinx' />
|
||||
<trusted-key id='91ae1504568ec4dd' group='org.jodd' />
|
||||
<trusted-key id='145d819475314d97' group='org.json' />
|
||||
<trusted-key id='f42e87f9665015c9' group='org.jsoup' />
|
||||
<trusted-key id='85911f425ec61b51' group='org.junit.jupiter' />
|
||||
<trusted-key id='85911f425ec61b51' group='org.junit.platform' />
|
||||
|
|
@ -169,6 +173,9 @@
|
|||
<dependency group='de.marcphilipp.gradle' module='nexus-publish-plugin' version='0.4.0'>
|
||||
<sha512>37EC6DFBDDD0458A2A341E371D038B3B0A25AB2F9006B295EBCF3BDE873A8D02C8CDAA6C69D875500F67593C618E8EF62C0269FB2F7F527A1367A7D6B8EA3CBE</sha512>
|
||||
</dependency>
|
||||
<dependency group='gradle.plugin.com.github.spotbugs.snom' module='spotbugs-gradle-plugin' version='4.5.0'>
|
||||
<sha512>36557C04B8FC7DC446B5FBDD6383A1B7281708B424C3039E7EC11807F3BB9A5E2764BE4BEC1D717C38595B12D8B291CB2A002D85B5E79DC9A9A4CBD27C58C7BB</sha512>
|
||||
</dependency>
|
||||
<dependency group='gradle.plugin.com.github.spotbugs' module='spotbugs-gradle-plugin' version='1.6.10'>
|
||||
<sha512>E7486B32EF6C9C14FE879814DA5F06CA6ECABF47195063A93E6FC8CD10119244C5A7BC3C71A4760CCE3AFFA9E9736336D345D8ED84EB65153C15683FA6529D92</sha512>
|
||||
</dependency>
|
||||
|
|
@ -238,6 +245,9 @@
|
|||
<dependency group='org.slf4j' module='slf4j-nop' version='1.6.2'>
|
||||
<sha512>89F8559C281F6BCEA4EB193C49AA8C960A5FE6762DCA0198A7BB04B9D8A846AC52231F77EC16B2E9C0B48D0F6011517B641B5B93279B24EEF65EE22E2C1167F3</sha512>
|
||||
</dependency>
|
||||
<dependency group='org.sonarsource.scanner.gradle' module='sonarqube-gradle-plugin' version='3.0'>
|
||||
<sha512>AFC41AFD611214C500CACA4D826652E38D5DDD1BCF182D935AFFD2B5B8DF26650DFEB76E4C06C2D46593E1FB86BB4D093438E8E862666E64AB32FB4B6EFEA30D</sha512>
|
||||
</dependency>
|
||||
<dependency group='oro' module='oro' version='2.0.8'>
|
||||
<sha512>9A98E493C4D771322B1331EC05AB0E363A83D8AC2AF8018D96A44DF2BF5BFC97D33EBE6F6F93E46AB10BF1536F0C29E9D9569318ED49BC18B4E96B1A8B476D37</sha512>
|
||||
</dependency>
|
||||
|
|
|
|||
|
|
@ -68,6 +68,12 @@
|
|||
<property name="fileExtensions" value="java, kt, kts, groovy"/>
|
||||
</module>
|
||||
|
||||
<module name="LineLength">
|
||||
<!-- TODO: reduce this to 120 -->
|
||||
<property name="max" value="160"/>
|
||||
<property name="fileExtensions" value="java, kt, kts, groovy"/>
|
||||
</module>
|
||||
|
||||
<module name="TreeWalker">
|
||||
|
||||
<!-- Annotations -->
|
||||
|
|
@ -178,10 +184,6 @@
|
|||
<module name="AnonInnerLength">
|
||||
<property name="max" value="45"/>
|
||||
</module>
|
||||
<module name="LineLength">
|
||||
<!-- TODO: reduce this to 120 -->
|
||||
<property name="max" value="160"/>
|
||||
</module>
|
||||
|
||||
<!-- whitespace -->
|
||||
<module name="EmptyForInitializerPad"/>
|
||||
|
|
|
|||
|
|
@ -16,6 +16,10 @@
|
|||
#
|
||||
|
||||
org.gradle.parallel=true
|
||||
# Build cache can be disabled with --no-build-cache option
|
||||
org.gradle.caching=true
|
||||
#org.gradle.caching.debug=true
|
||||
|
||||
# See https://github.com/gradle/gradle/pull/11358 , https://issues.apache.org/jira/browse/INFRA-14923
|
||||
# repository.apache.org does not yet support .sha256 and .sha512 checksums
|
||||
systemProp.org.gradle.internal.publish.checksums.insecure=true
|
||||
|
|
@ -28,28 +32,28 @@ kotlin.parallel.tasks.in.project=true
|
|||
jmeter.version=5.3.1
|
||||
|
||||
# Tools
|
||||
checkstyle.version=8.22
|
||||
checkstyle.version=8.35
|
||||
jacoco.version=0.8.5
|
||||
spotbugs.version=3.1.12
|
||||
spotbugs.version=4.1.2
|
||||
velocity.version=1.7
|
||||
|
||||
# Plugins
|
||||
com.github.autostyle.version=3.0
|
||||
com.github.spotbugs.version=2.0.0
|
||||
com.github.spotbugs.version=4.5.0
|
||||
com.github.vlsi.checksum-dependency.sha512=4D1A76F38F327CEA0C723D9BDD9ABFE16933769052F47BCECD555DDD1A6CD0A9C21E3CC8F9E1B92780F9B443070D4844889EE9ECB0690D30E50AAB085096D8E1
|
||||
com.github.vlsi.checksum-dependency.version=1.70
|
||||
com.github.vlsi.vlsi-release-plugins.version=1.70
|
||||
org.jetbrains.gradle.plugin.idea-ext.version=0.5
|
||||
org.nosphere.apache.rat.version=0.5.3
|
||||
org.sonarqube.version=2.7.1
|
||||
org.sonarqube.version=3.0
|
||||
|
||||
# Dependencies
|
||||
accessors-smart.version=1.2
|
||||
activemq.version=5.15.11
|
||||
activemq.version=5.16.0
|
||||
apache-rat.version=0.13
|
||||
apiguardian-api.version=1.1.0
|
||||
asm.version=7.3.1
|
||||
bouncycastle.version=1.64
|
||||
bouncycastle.version=1.66
|
||||
bsf.version=2.4.0
|
||||
bsh.version=2.0b6
|
||||
caffeine.version=2.8.0
|
||||
|
|
@ -58,20 +62,19 @@ commons-codec.version=1.14
|
|||
commons-collections.version=3.2.2
|
||||
commons-collections4.version=4.4
|
||||
commons-dbcp2.version=2.7.0
|
||||
commons-io.version=2.6
|
||||
commons-io.version=2.7
|
||||
commons-jexl.version=2.1.1
|
||||
commons-jexl3.version=3.1
|
||||
commons-lang.version=2.6
|
||||
commons-lang3.version=3.10
|
||||
commons-lang3.version=3.11
|
||||
commons-math3.version=3.6.1
|
||||
commons-net.version=3.6
|
||||
commons-pool2.version=2.8.0
|
||||
commons-text.version=1.8
|
||||
darklaf.version=2.4.2
|
||||
#darklaf.version=latest.integration
|
||||
commons-net.version=3.7
|
||||
commons-pool2.version=2.8.1
|
||||
commons-text.version=1.9
|
||||
darklaf.version=2.4.5
|
||||
dec.version=0.1.2
|
||||
dnsjava.version=2.1.9
|
||||
equalsverifier.version=3.1.13
|
||||
equalsverifier.version=3.4.2
|
||||
freemarker.version=2.3.30
|
||||
ftplet-api.version=1.1.1
|
||||
ftpserver-core.version=1.1.1
|
||||
|
|
@ -98,8 +101,8 @@ json-smart.version=2.3
|
|||
jsoup.version=1.13.1
|
||||
jtidy.version=r938
|
||||
junit4.version=4.13
|
||||
junit5.version=5.6.0
|
||||
log4j.version=2.13.1
|
||||
junit5.version=5.6.2
|
||||
log4j.version=2.13.3
|
||||
mail.version=1.5.0-b01
|
||||
miglayout.version=5.2
|
||||
mina-core.version=2.0.19
|
||||
|
|
@ -110,7 +113,7 @@ oro.version=2.0.8
|
|||
ph-commons.version=9.4.1
|
||||
ph-css.version=6.2.2
|
||||
rhino.version=1.7.12
|
||||
rsyntaxtextarea.version=3.1.0
|
||||
rsyntaxtextarea.version=3.1.1
|
||||
Saxon-HE.version=9.9.1-7
|
||||
slf4j.version=1.7.30
|
||||
spock-core.version=2.0-M2-groovy-3.0
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionSha256Sum=0f316a67b971b7b571dac7215dcf2591a30994b3450e0629925ffcfe2c68cc5c
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
|
||||
distributionSha256Sum=e6f83508f0970452f56197f610d13c5f593baaf43c0e3c6a571e5967be754025
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ esac
|
|||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
|
|
@ -129,6 +130,7 @@ fi
|
|||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
|||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
|
@ -54,7 +54,7 @@ goto fail
|
|||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
|
|
@ -64,28 +64,14 @@ echo location of your Java installation.
|
|||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@ pluginManagement {
|
|||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
`gradle-enterprise`
|
||||
}
|
||||
|
||||
// This is the name of a current project
|
||||
// Note: it cannot be inferred from the directory name as developer might clone JMeter to jmeter_tmp folder
|
||||
rootProject.name = "jmeter"
|
||||
|
|
@ -92,6 +96,18 @@ if (property("localReleasePlugins").toBool(nullAs = false, blankAs = true, defau
|
|||
includeBuild("../vlsi-release-plugins")
|
||||
}
|
||||
|
||||
val isCiServer = System.getenv().containsKey("CI")
|
||||
|
||||
if (isCiServer) {
|
||||
gradleEnterprise {
|
||||
buildScan {
|
||||
termsOfServiceUrl = "https://gradle.com/terms-of-service"
|
||||
termsOfServiceAgree = "yes"
|
||||
tag("CI")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Checksum plugin sources can be validated at https://github.com/vlsi/vlsi-release-plugins
|
||||
buildscript {
|
||||
dependencies {
|
||||
|
|
@ -107,6 +123,8 @@ buildscript {
|
|||
|
||||
// Note: we need to verify the checksum for checksum-dependency-plugin itself
|
||||
val expectedSha512 = mapOf(
|
||||
"F7040C571C2A2727F2EED4EA772F5A7C5D9CB393828B7A2331F7167E467429486F5F3E9423883FE9A6D652FFB0484EAE722CDFB46D97180209BCBEEBF9C25DE3"
|
||||
to "gradle-enterprise-gradle-plugin-3.4.jar",
|
||||
"43BC9061DFDECA0C421EDF4A76E380413920E788EF01751C81BDC004BD28761FBD4A3F23EA9146ECEDF10C0F85B7BE9A857E9D489A95476525565152E0314B5B"
|
||||
to "bcpg-jdk15on-1.62.jar",
|
||||
"2BA6A5DEC9C8DAC2EB427A65815EB3A9ADAF4D42D476B136F37CD57E6D013BF4E9140394ABEEA81E42FBDB8FC59228C7B85C549ED294123BF898A7D048B3BD95"
|
||||
|
|
@ -137,7 +155,7 @@ val violations =
|
|||
.joinToString("\n ") { (file, sha512) -> "SHA-512(${file.name}) = $sha512 ($file)" }
|
||||
|
||||
if (violations.isNotBlank()) {
|
||||
throw GradleException("Buildscript classpath has permitted files that were not explicitly permitted:\n $violations")
|
||||
throw GradleException("Buildscript classpath has files that were not explicitly permitted:\n $violations")
|
||||
}
|
||||
|
||||
apply(plugin = "com.github.vlsi.checksum-dependency")
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
dependencies {
|
||||
api(project(":src:core"))
|
||||
testCompile(project(":src:core", "testClasses"))
|
||||
testImplementation(project(":src:core", "testClasses"))
|
||||
|
||||
api("org.apache-extras.beanshell:bsh") {
|
||||
because("""
|
||||
|
|
|
|||
|
|
@ -121,9 +121,9 @@ public class HTMLAssertion extends AbstractTestElement implements Serializable,
|
|||
|| (!isErrorsOnly() && warningsAboveThreshold)) {
|
||||
log.debug("Errors/warnings detected while parsing with tidy: {}", errbuf);
|
||||
result.setFailure(true);
|
||||
result.setFailureMessage(MessageFormat.format("Tidy Parser errors: " + tidy.getParseErrors()
|
||||
+ " (allowed " + getErrorThreshold() + ") " + "Tidy Parser warnings: "
|
||||
+ tidy.getParseWarnings() + " (allowed " + getWarningThreshold() + ")", new Object[0]));
|
||||
result.setFailureMessage(MessageFormat.format(
|
||||
"Tidy Parser errors: {} (allowed {}) Tidy Parser warnings: {} (allowed {})",
|
||||
tidy.getParseErrors(), getErrorThreshold(), tidy.getParseWarnings(), getWarningThreshold()));
|
||||
// return with an error
|
||||
|
||||
} else if (tidy.getParseErrors() > 0 || tidy.getParseWarnings() > 0) {
|
||||
|
|
|
|||
|
|
@ -203,19 +203,36 @@ public class BoundaryExtractor extends AbstractScopedTestElement implements Post
|
|||
}
|
||||
|
||||
private String getInputString(SampleResult result) {
|
||||
String inputString = useUrl() ? result.getUrlAsString() // Bug 39707
|
||||
: useHeaders() ? result.getResponseHeaders()
|
||||
: useRequestHeaders() ? result.getRequestHeaders()
|
||||
: useCode() ? result.getResponseCode() // Bug 43451
|
||||
: useMessage() ? result.getResponseMessage() // Bug 43451
|
||||
: useUnescapedBody() ? StringEscapeUtils.unescapeHtml4(result.getResponseDataAsString())
|
||||
: useBodyAsDocument() ? Document.getTextFromDocument(result.getResponseData())
|
||||
: result.getResponseDataAsString() // Bug 36898
|
||||
;
|
||||
String inputString = chosenInput(result);
|
||||
log.debug("Input = '{}'", inputString);
|
||||
return inputString;
|
||||
}
|
||||
|
||||
private String chosenInput(SampleResult result) {
|
||||
if (useUrl()) {
|
||||
return result.getUrlAsString(); // Bug 39707;
|
||||
}
|
||||
if (useHeaders()) {
|
||||
return result.getResponseHeaders();
|
||||
}
|
||||
if (useRequestHeaders()) {
|
||||
return result.getRequestHeaders();
|
||||
}
|
||||
if (useCode()) {
|
||||
return result.getResponseCode(); // Bug 43451
|
||||
}
|
||||
if (useMessage()) {
|
||||
return result.getResponseMessage(); // Bug 43451
|
||||
}
|
||||
if (useUnescapedBody()) {
|
||||
return StringEscapeUtils.unescapeHtml4(result.getResponseDataAsString());
|
||||
}
|
||||
if (useBodyAsDocument()) {
|
||||
return Document.getTextFromDocument(result.getResponseData());
|
||||
}
|
||||
return result.getResponseDataAsString(); // Bug 36898
|
||||
}
|
||||
|
||||
private List<String> extract(
|
||||
String leftBoundary, String rightBoundary, int matchNumber, Stream<String> previousResults) {
|
||||
boolean allItems = matchNumber <= 0;
|
||||
|
|
|
|||
|
|
@ -53,13 +53,7 @@ public class JSONManager {
|
|||
private final Map<String, JsonPath> expressionToJsonPath = new HashMap<>(2);
|
||||
|
||||
private JsonPath getJsonPath(String jsonPathExpression) {
|
||||
JsonPath jsonPath = expressionToJsonPath.get(jsonPathExpression);
|
||||
if (jsonPath == null) {
|
||||
jsonPath = JsonPath.compile(jsonPathExpression);
|
||||
expressionToJsonPath.put(jsonPathExpression, jsonPath);
|
||||
}
|
||||
|
||||
return jsonPath;
|
||||
return expressionToJsonPath.computeIfAbsent(jsonPathExpression, JsonPath::compile);
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ plugins {
|
|||
dependencies {
|
||||
api(project(":src:launcher"))
|
||||
api(project(":src:jorphan"))
|
||||
testCompile(project(":src:jorphan", "testClasses"))
|
||||
testImplementation(project(":src:jorphan", "testClasses"))
|
||||
|
||||
api("bsf:bsf") {
|
||||
because("protected BSFManager BSFTestElement#getManager()")
|
||||
|
|
|
|||
|
|
@ -385,18 +385,26 @@ public class JMeter implements JMeterPlugin {
|
|||
SplashScreen splash = new SplashScreen();
|
||||
splash.showScreen();
|
||||
splash.setProgress(10);
|
||||
log.debug("Apply HiDPI on fonts");
|
||||
JMeterUtils.applyHiDPIOnFonts();
|
||||
splash.setProgress(20);
|
||||
log.debug("Configure PluginManager");
|
||||
PluginManager.install(this, true);
|
||||
|
||||
JMeterTreeModel treeModel = new JMeterTreeModel();
|
||||
splash.setProgress(30);
|
||||
log.debug("Setup tree");
|
||||
JMeterTreeModel treeModel = new JMeterTreeModel();
|
||||
JMeterTreeListener treeLis = new JMeterTreeListener(treeModel);
|
||||
final ActionRouter instance = ActionRouter.getInstance();
|
||||
splash.setProgress(40);
|
||||
log.debug("populate command map");
|
||||
instance.populateCommandMap();
|
||||
splash.setProgress(60);
|
||||
treeLis.setActionHandler(instance);
|
||||
log.debug("init instance");
|
||||
splash.setProgress(70);
|
||||
GuiPackage.initInstance(treeLis, treeModel);
|
||||
splash.setProgress(80);
|
||||
log.debug("constructing main frame");
|
||||
MainFrame main = new MainFrame(treeModel, treeLis);
|
||||
splash.setProgress(100);
|
||||
ComponentUtil.centerComponentInWindow(main, 80);
|
||||
|
|
|
|||
|
|
@ -24,9 +24,9 @@ import java.net.URL;
|
|||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JProgressBar;
|
||||
import javax.swing.JWindow;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
|
||||
|
|
@ -40,7 +40,7 @@ import com.github.weisj.darklaf.icons.ThemedSVGIcon;
|
|||
* Splash Screen
|
||||
* @since 3.2
|
||||
*/
|
||||
public class SplashScreen extends JWindow {
|
||||
public class SplashScreen extends JDialog {
|
||||
private static final Logger log = LoggerFactory.getLogger(SplashScreen.class);
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
|
@ -53,6 +53,9 @@ public class SplashScreen extends JWindow {
|
|||
setLayout(new BorderLayout());
|
||||
add(loadLogo(), BorderLayout.CENTER);
|
||||
add(progressBar, BorderLayout.SOUTH);
|
||||
setModalityType(ModalityType.APPLICATION_MODAL);
|
||||
setAutoRequestFocus(true);
|
||||
setUndecorated(true);
|
||||
pack();
|
||||
setLocationRelativeTo(null);
|
||||
}
|
||||
|
|
@ -89,10 +92,7 @@ public class SplashScreen extends JWindow {
|
|||
* Show screen
|
||||
*/
|
||||
public void showScreen() {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
setVisible(true);
|
||||
setAlwaysOnTop(true);
|
||||
});
|
||||
SwingUtilities.invokeLater(() -> setVisible(true));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -89,13 +89,13 @@ public class HtmlReportGenerator {
|
|||
}
|
||||
} catch (TimeoutException e) {
|
||||
errorMessageList.add(MessageFormat.format(JMeterUtils.getResString("generate_report_ui.html_report_timeout_error"),
|
||||
COMMAND_TIMEOUT, e.getMessage(), commandExecutionOutput.toString()));
|
||||
LOGGER.error("Report generation took more time than configured timeout(Property {}={})",
|
||||
"generate_report_ui.generation_timeout", COMMAND_TIMEOUT, commandExecutionOutput.toString(), e);
|
||||
COMMAND_TIMEOUT, e.getMessage(), commandExecutionOutput));
|
||||
LOGGER.error("Report generation took more time than configured timeout (Property {}={}, command output=[{}])",
|
||||
"generate_report_ui.generation_timeout", COMMAND_TIMEOUT, commandExecutionOutput, e);
|
||||
} catch (InterruptedException | IOException e) {
|
||||
errorMessageList.add(MessageFormat.format(JMeterUtils.getResString("generate_report_ui.html_report_unknown_error"),
|
||||
e.getMessage(), commandExecutionOutput.toString()));
|
||||
LOGGER.error("Error during HTML report generation, executing {}", commandExecutionOutput.toString(), e);
|
||||
e.getMessage(), commandExecutionOutput));
|
||||
LOGGER.error("Error during HTML report generation, executing {}", commandExecutionOutput, e);
|
||||
if (e instanceof InterruptedException) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
package org.apache.jmeter.gui.action;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
|
@ -41,12 +40,6 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import com.github.weisj.darklaf.LafManager;
|
||||
import com.github.weisj.darklaf.theme.DarculaTheme;
|
||||
import com.github.weisj.darklaf.theme.HighContrastDarkTheme;
|
||||
import com.github.weisj.darklaf.theme.HighContrastLightTheme;
|
||||
import com.github.weisj.darklaf.theme.IntelliJTheme;
|
||||
import com.github.weisj.darklaf.theme.OneDarkTheme;
|
||||
import com.github.weisj.darklaf.theme.SolarizedDarkTheme;
|
||||
import com.github.weisj.darklaf.theme.SolarizedLightTheme;
|
||||
import com.github.weisj.darklaf.theme.Theme;
|
||||
|
||||
/**
|
||||
|
|
@ -70,9 +63,9 @@ public class LookAndFeelCommand extends AbstractAction {
|
|||
final String title;
|
||||
final String command;
|
||||
final String lafClassName;
|
||||
final Class<? extends Theme> lafTheme;
|
||||
final Theme lafTheme;
|
||||
|
||||
private MenuItem(String title, String command, String lafClassName, Class<? extends Theme> lafTheme) {
|
||||
private MenuItem(String title, String command, String lafClassName, Theme lafTheme) {
|
||||
this.title = title;
|
||||
this.command = command;
|
||||
this.lafClassName = lafClassName;
|
||||
|
|
@ -88,39 +81,41 @@ public class LookAndFeelCommand extends AbstractAction {
|
|||
}
|
||||
|
||||
private static MenuItem of(String title, String lafClass) {
|
||||
return new MenuItem(title,ActionNames.LAF_PREFIX + lafClass, lafClass, null);
|
||||
return new MenuItem(title, ActionNames.LAF_PREFIX + lafClass, lafClass, null);
|
||||
}
|
||||
|
||||
private static MenuItem ofDarklafTheme(Class<? extends Theme> lafTheme) {
|
||||
return new MenuItem("Darklaf - " + lafTheme.getSimpleName().replace("Theme", ""),
|
||||
JMeterMenuBar.DARKLAF_LAF_CLASS + ":" + lafTheme.getName(),
|
||||
private static MenuItem ofDarklafTheme(Theme theme) {
|
||||
return new MenuItem("Darklaf - " + theme.getName(),
|
||||
JMeterMenuBar.DARKLAF_LAF_CLASS + ":" + theme.getThemeClass().getName(),
|
||||
JMeterMenuBar.DARKLAF_LAF_CLASS,
|
||||
lafTheme);
|
||||
theme);
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
if (System.getProperty("darklaf.decorations") == null) {
|
||||
System.setProperty("darklaf.decorations", "false");
|
||||
} else if (Boolean.getBoolean("darklaf.allowNativeCode")) {
|
||||
// darklaf.allowNativeCode=true is required for darklaf.decorations=true to work.
|
||||
System.setProperty("darklaf.decorations", "true");
|
||||
}
|
||||
if (System.getProperty("darklaf.allowNativeCode") == null) {
|
||||
System.setProperty("darklaf.allowNativeCode", "false");
|
||||
}
|
||||
UIManager.installLookAndFeel(JMeterMenuBar.DARKLAF_LAF, JMeterMenuBar.DARKLAF_LAF_CLASS);
|
||||
if (System.getProperty("darklaf.unifiedMenuBar") == null) {
|
||||
System.setProperty("darklaf.unifiedMenuBar", "true");
|
||||
}
|
||||
UIManager.installLookAndFeel(JMeterMenuBar.DARCULA_LAF, JMeterMenuBar.DARCULA_LAF_CLASS);
|
||||
|
||||
List<MenuItem> items = new ArrayList<>();
|
||||
for (UIManager.LookAndFeelInfo laf : JMeterMenuBar.getAllLAFs()) {
|
||||
if (!laf.getClassName().equals(JMeterMenuBar.DARKLAF_LAF_CLASS)) {
|
||||
if (!laf.getClassName().equals(JMeterMenuBar.DARCULA_LAF_CLASS)) {
|
||||
items.add(MenuItem.of(laf.getName(), laf.getClassName()));
|
||||
continue;
|
||||
} else {
|
||||
for (Theme theme : LafManager.getRegisteredThemes()) {
|
||||
items.add(MenuItem.ofDarklafTheme(theme));
|
||||
}
|
||||
}
|
||||
items.add(MenuItem.ofDarklafTheme(DarculaTheme.class));
|
||||
items.add(MenuItem.ofDarklafTheme(IntelliJTheme.class));
|
||||
items.add(MenuItem.ofDarklafTheme(OneDarkTheme.class));
|
||||
items.add(MenuItem.ofDarklafTheme(SolarizedDarkTheme.class));
|
||||
items.add(MenuItem.ofDarklafTheme(SolarizedLightTheme.class));
|
||||
items.add(MenuItem.ofDarklafTheme(HighContrastDarkTheme.class));
|
||||
items.add(MenuItem.ofDarklafTheme(HighContrastLightTheme.class));
|
||||
}
|
||||
items.sort(Comparator.comparing(MenuItem::getTitle));
|
||||
for (MenuItem item : items) {
|
||||
|
|
@ -184,7 +179,7 @@ public class LookAndFeelCommand extends AbstractAction {
|
|||
String jMeterLaf = getJMeterLaf();
|
||||
if (jMeterLaf.equals(JMeterMenuBar.DARCULA_LAF_CLASS)) {
|
||||
// Convert old Darcula to new Darklaf-Darcula LaF
|
||||
return MenuItem.ofDarklafTheme(DarculaTheme.class).command;
|
||||
return MenuItem.ofDarklafTheme(new DarculaTheme()).command;
|
||||
}
|
||||
|
||||
return MenuItem.of("default", jMeterLaf).command; // $NON-NLS-1$
|
||||
|
|
@ -208,12 +203,7 @@ public class LookAndFeelCommand extends AbstractAction {
|
|||
public static boolean isDark() {
|
||||
String lookAndFeelID = UIManager.getLookAndFeel().getID();
|
||||
if (lookAndFeelID.equals("Darklaf")) { // $NON-NLS-1$
|
||||
Theme lafTheme = LafManager.getTheme();
|
||||
if (lafTheme == null) {
|
||||
return false;
|
||||
}
|
||||
String name = lafTheme.getName();
|
||||
return name.equals("darcula") || name.equals("solarized_dark"); // $NON-NLS-1$
|
||||
return Theme.isDark(LafManager.getTheme());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -221,24 +211,15 @@ public class LookAndFeelCommand extends AbstractAction {
|
|||
public static void activateLookAndFeel(String command) {
|
||||
MenuItem item = items.get(command);
|
||||
String className = item.lafClassName;
|
||||
try {
|
||||
if (item.lafTheme != null) {
|
||||
LafManager.setTheme(item.lafTheme.getConstructor().newInstance());
|
||||
}
|
||||
GuiPackage instance = GuiPackage.getInstance();
|
||||
if (instance != null) {
|
||||
instance.updateUIForHiddenComponents();
|
||||
}
|
||||
JFactory.refreshUI(className);
|
||||
PREFS.put(USER_PREFS_KEY, item.command);
|
||||
} catch ( InstantiationException
|
||||
| NoSuchMethodException
|
||||
| IllegalAccessException e) {
|
||||
throw new IllegalArgumentException("Look and Feel unavailable:" + e.toString(), e);
|
||||
} catch (InvocationTargetException e) {
|
||||
Throwable c = e.getCause();
|
||||
throw new IllegalArgumentException("Look and Feel unavailable:" + c.toString(), c);
|
||||
if (item.lafTheme != null) {
|
||||
LafManager.setTheme(item.lafTheme);
|
||||
}
|
||||
GuiPackage instance = GuiPackage.getInstance();
|
||||
if (instance != null) {
|
||||
instance.updateUIForHiddenComponents();
|
||||
}
|
||||
JFactory.refreshUI(className);
|
||||
PREFS.put(USER_PREFS_KEY, item.command);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ import org.apache.jmeter.processor.gui.AbstractPreProcessorGui;
|
|||
import org.apache.jmeter.samplers.Sampler;
|
||||
import org.apache.jmeter.samplers.gui.AbstractSamplerGui;
|
||||
import org.apache.jmeter.testelement.TestElement;
|
||||
import org.apache.jmeter.threads.ThreadGroup;
|
||||
import org.apache.jmeter.threads.gui.AbstractThreadGroupGui;
|
||||
import org.apache.jmeter.timers.Timer;
|
||||
import org.apache.jmeter.timers.gui.AbstractTimerGui;
|
||||
|
|
@ -100,7 +101,7 @@ public class StaticJMeterGUIComponent implements JMeterGUIComponent {
|
|||
group = MenuFactory.SAMPLERS;
|
||||
} else if (Timer.class.isAssignableFrom(c) || AbstractTimerGui.class.isAssignableFrom(c)) {
|
||||
group = MenuFactory.TIMERS;
|
||||
} else if (AbstractThreadGroupGui.class.isAssignableFrom(c) || AbstractThreadGroupGui.class.isAssignableFrom(c)) {
|
||||
} else if (ThreadGroup.class.isAssignableFrom(c) || AbstractThreadGroupGui.class.isAssignableFrom(c)) {
|
||||
group = MenuFactory.THREADS;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown group for class " + c);
|
||||
|
|
|
|||
|
|
@ -20,13 +20,14 @@ package org.apache.jmeter.report.dashboard;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.text.StringEscapeUtils;
|
||||
import org.apache.jmeter.report.core.JsonUtil;
|
||||
import org.apache.jmeter.report.processor.ListResultData;
|
||||
import org.apache.jmeter.report.processor.MapResultData;
|
||||
import org.apache.jmeter.report.processor.ResultData;
|
||||
import org.apache.jmeter.report.processor.ResultDataVisitor;
|
||||
import org.apache.jmeter.report.processor.ValueResultData;
|
||||
|
||||
import com.fasterxml.jackson.core.io.JsonStringEncoder;
|
||||
/**
|
||||
* The class JsonizerVisitor provides a visitor that can get json-like string
|
||||
* from ResultData.
|
||||
|
|
@ -96,7 +97,7 @@ public class JsonizerVisitor implements ResultDataVisitor<String> {
|
|||
Object value = valueResult.getValue();
|
||||
result = String.valueOf(value);
|
||||
if (value instanceof String) {
|
||||
result = '"' + StringEscapeUtils.escapeEcmaScript(result.replace('\"', '\'')) + '"';
|
||||
result = '"' + new String(JsonStringEncoder.getInstance().quoteAsString(result)) + '"';
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ import org.apache.jmeter.report.utils.MetricUtils;
|
|||
import org.apache.jmeter.samplers.SampleSaveConfiguration;
|
||||
import org.apache.jmeter.util.JMeterUtils;
|
||||
|
||||
import com.fasterxml.jackson.core.io.JsonStringEncoder;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* The class ErrorSummaryConsumer provides a consumer that calculates error
|
||||
|
|
@ -89,7 +91,7 @@ public class ErrorsSummaryConsumer extends AbstractSummaryConsumer<Long> {
|
|||
String responseCode = sample.getResponseCode();
|
||||
String responseMessage = sample.getResponseMessage();
|
||||
String key = responseCode + (!StringUtils.isEmpty(responseMessage) ?
|
||||
"/" + StringEscapeUtils.escapeJson(StringEscapeUtils.escapeHtml4(responseMessage)) : "");
|
||||
"/" + escapeJson(responseMessage) : "");
|
||||
if (MetricUtils.isSuccessCode(responseCode) ||
|
||||
(StringUtils.isEmpty(responseCode) &&
|
||||
!StringUtils.isEmpty(sample.getFailureMessage()))) {
|
||||
|
|
@ -97,12 +99,17 @@ public class ErrorsSummaryConsumer extends AbstractSummaryConsumer<Long> {
|
|||
if (ASSERTION_RESULTS_FAILURE_MESSAGE) {
|
||||
String msg = sample.getFailureMessage();
|
||||
if (!StringUtils.isEmpty(msg)) {
|
||||
key = StringEscapeUtils.escapeJson(StringEscapeUtils.escapeHtml4(msg));
|
||||
key = escapeJson(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
private static String escapeJson(String responseMessage) {
|
||||
return new String(JsonStringEncoder.getInstance().quoteAsString(StringEscapeUtils.escapeHtml4(responseMessage)));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ public class JsseSSLManager extends SSLManager {
|
|||
public void resetContext() {
|
||||
if (!SHARED_SESSION_CONTEXT) {
|
||||
log.debug("Clearing session context for current thread");
|
||||
this.threadlocal.set(null);
|
||||
this.threadlocal.remove();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1016,8 +1016,14 @@ run_threadgroup_no_timers=Start no pauses
|
|||
running_test=Running test
|
||||
runtime_controller_title=Runtime Controller
|
||||
runtime_seconds=Runtime (seconds)
|
||||
sample_creator_counter_value=Counter start value
|
||||
sample_creator_set_counter=Set counter
|
||||
sample_name_formatter=Use format string
|
||||
sample_name_prefix=Prefix
|
||||
sample_name_suffix=Suffix
|
||||
sample_naming_scheme=Naming scheme
|
||||
sample_name_transaction=Transaction name
|
||||
sample_naming_format_help=<html>Format for the names of the samplers.<br> The counter, path and transaction names can be given with the placeholders <tt>#{counter}</tt>, <tt>#{path}</tt> and <tt>#{name}</tt>.</html>
|
||||
salt_string=Salt to be used for hashing (optional)
|
||||
sample_result_save_configuration=Sample Result Save Configuration
|
||||
sample_scope=Apply to:
|
||||
|
|
@ -1459,6 +1465,7 @@ web_testing_basic=Basic
|
|||
web_testing_advanced=Advanced
|
||||
web_testing_concurrent_download=Parallel downloads. Number:
|
||||
web_testing_embedded_url_pattern=URLs must match\:
|
||||
web_testing_embedded_url_exclude_pattern=URLs must not match\:
|
||||
web_testing_retrieve_images=Retrieve All Embedded Resources
|
||||
web_testing_retrieve_title=Embedded Resources from HTML Files
|
||||
web_testing_source_ip=Source address
|
||||
|
|
|
|||
|
|
@ -1006,8 +1006,14 @@ running_test=Lancer test
|
|||
runtime_controller_title=Contrôleur Durée d'exécution
|
||||
runtime_seconds=Temps d'exécution (secondes) \:
|
||||
salt_string=Sel à utiliser pour le hash
|
||||
sample_creator_counter_value=Valeur de départ du compteur
|
||||
sample_creator_set_counter=Définir le compteur
|
||||
sample_name_formatter=Utiliser le format
|
||||
sample_name_prefix=Préfixe
|
||||
sample_name_suffix=Suffixe
|
||||
sample_naming_scheme=Schéma de dénomination
|
||||
sample_name_transaction=Nom de la transaction
|
||||
sample_naming_format_help=<html>Format des noms des échantillonneurs.<br>Les noms de compteur, chemin et transaction peuvent être donnés avec <tt>#{counter}</tt>, <tt>#{path}</tt> et <tt>#{name}</tt>.</html>
|
||||
sample_result_save_configuration=Sauvegarder la configuration de la sauvegarde des échantillons
|
||||
sample_scope=Appliquer sur
|
||||
sample_scope_all=L'échantillon et ses ressources liées
|
||||
|
|
@ -1448,6 +1454,7 @@ web_testing_advanced=Avancée
|
|||
web_testing_basic=Basique
|
||||
web_testing_concurrent_download=Téléchargements en parallèle. Nombre \:
|
||||
web_testing_embedded_url_pattern=Les URL à inclure doivent correspondre à \:
|
||||
web_testing_embedded_url_exclude_pattern=Les URL à exclure doivent correspondre à \:
|
||||
web_testing_retrieve_images=Récupérer les ressources incluses
|
||||
web_testing_retrieve_title=Ressources incluses dans les pages HTML
|
||||
web_testing_source_ip=Adresse source
|
||||
|
|
|
|||
|
|
@ -40,12 +40,12 @@ public class ErrorsSummaryConsumerTest {
|
|||
|
||||
sample = new Sample(0, metadata, new String[] { "false", "200", "",
|
||||
"Test failed: text expected to contain /<title>Some html text</title>/" });
|
||||
assertEquals("Test failed: text expected to contain \\/<title>Some html text<\\/title>\\/",
|
||||
assertEquals("Test failed: text expected to contain /<title>Some html text</title>/",
|
||||
ErrorsSummaryConsumer.getErrorKey(sample));
|
||||
|
||||
sample = new Sample(0, metadata, new String[] { "false", "200", "",
|
||||
"Test failed: text expected to contain /{\"glossary\": { \"title\": \"example glossary\"}}/" });
|
||||
assertEquals("Test failed: text expected to contain \\/{"glossary": { "title": "example glossary"}}\\/",
|
||||
assertEquals("Test failed: text expected to contain /{"glossary": { "title": "example glossary"}}/",
|
||||
ErrorsSummaryConsumer.getErrorKey(sample));
|
||||
|
||||
sample = new Sample(0, metadata, new String[] { "true", "200", "", "" });
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ val loggingClasspath by configurations.creating
|
|||
|
||||
dependencies {
|
||||
api(project(":src:dist"))
|
||||
testCompile(project(":src:dist", "testClasses"))
|
||||
testImplementation(project(":src:dist", "allTestClasses"))
|
||||
testImplementation("org.apache.commons:commons-lang3") {
|
||||
because("StringUtils")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,12 +64,17 @@ val srcLicense by configurations.creating {
|
|||
isCanBeConsumed = false
|
||||
}
|
||||
|
||||
val allTestClasses by configurations.creating {
|
||||
isCanBeConsumed = true
|
||||
isCanBeResolved = false
|
||||
}
|
||||
|
||||
// Note: you can inspect final classpath (list of jars in the binary distribution) via
|
||||
// gw dependencies --configuration runtimeClasspath
|
||||
dependencies {
|
||||
for (p in jars) {
|
||||
api(project(p))
|
||||
testCompile(project(p, "testClasses"))
|
||||
allTestClasses(project(p, "testClasses"))
|
||||
}
|
||||
|
||||
binLicense(project(":src:licenses", "binLicense"))
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
dependencies {
|
||||
api(project(":src:components"))
|
||||
testCompile(project(":src:components", "testClasses"))
|
||||
testImplementation(project(":src:core", "testClasses"))
|
||||
|
||||
implementation("org.mozilla:rhino")
|
||||
implementation("commons-codec:commons-codec")
|
||||
|
|
|
|||
|
|
@ -79,12 +79,15 @@ public final class NewDriver {
|
|||
tmpDir = null;
|
||||
}
|
||||
} else {// e.g. started from IDE with full classpath
|
||||
tmpDir = System.getProperty("jmeter.home","");// Allow override $NON-NLS-1$ $NON-NLS-2$
|
||||
if (tmpDir.length() == 0) {
|
||||
tmpDir = System.getProperty("jmeter.home", System.getenv("JMETER_HOME"));// Allow override $NON-NLS-1$ $NON-NLS-2$
|
||||
if (tmpDir == null || tmpDir.length() == 0) {
|
||||
File userDir = new File(System.getProperty("user.dir"));// $NON-NLS-1$
|
||||
tmpDir = userDir.getAbsoluteFile().getParent();
|
||||
}
|
||||
}
|
||||
if (tmpDir == null) {
|
||||
tmpDir = System.getenv("JMETER_HOME");
|
||||
}
|
||||
JMETER_INSTALLATION_DIRECTORY=tmpDir;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
subprojects {
|
||||
dependencies {
|
||||
api(project(":src:core"))
|
||||
testCompile(project(":src:core", "testClasses"))
|
||||
testImplementation(project(":src:core", "testClasses"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ project("http") {
|
|||
dependencies {
|
||||
// for SearchTextExtension
|
||||
api(project(":src:components"))
|
||||
testCompile(project(":src:components", "testClasses"))
|
||||
testImplementation(project(":src:components", "testClasses"))
|
||||
|
||||
api("com.thoughtworks.xstream:xstream") {
|
||||
because("HTTPResultConverter uses XStream in public API")
|
||||
|
|
@ -84,6 +84,7 @@ project("http") {
|
|||
implementation("org.apache.httpcomponents:httpmime")
|
||||
implementation("org.apache.httpcomponents:httpcore")
|
||||
implementation("org.brotli:dec")
|
||||
implementation("com.miglayout:miglayout-swing")
|
||||
testImplementation(testFixtures(project(":src:testkit-wiremock")))
|
||||
testImplementation("com.github.tomakehurst:wiremock-jre8")
|
||||
}
|
||||
|
|
@ -114,7 +115,7 @@ project("jdbc") {
|
|||
|
||||
project("jms") {
|
||||
dependencies {
|
||||
testCompile(project(":src:core", "testClasses"))
|
||||
testImplementation(project(":src:core", "testClasses"))
|
||||
api("com.github.ben-manes.caffeine:caffeine") {
|
||||
because("MessageRenderer#getValueFromFile(..., caffeine.cache.Cache)")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,8 @@ import org.apache.jmeter.testelement.property.IntegerProperty;
|
|||
import org.apache.jmeter.testelement.property.StringProperty;
|
||||
import org.apache.jmeter.util.JMeterUtils;
|
||||
import org.apache.jorphan.gui.JFactory;
|
||||
import org.apache.jorphan.gui.JLabeledTextField;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
/**
|
||||
* GUI for Http Request defaults
|
||||
|
|
@ -55,14 +56,15 @@ import org.apache.jorphan.gui.JLabeledTextField;
|
|||
@TestElementMetadata(labelResource = "url_config_title")
|
||||
public class HttpDefaultsGui extends AbstractConfigGui {
|
||||
|
||||
private static final long serialVersionUID = 241L;
|
||||
private static final long serialVersionUID = 242L;
|
||||
|
||||
private UrlConfigGui urlConfigGui;
|
||||
private JCheckBox retrieveEmbeddedResources;
|
||||
private JCheckBox concurrentDwn;
|
||||
private JTextField concurrentPool;
|
||||
private JCheckBox useMD5;
|
||||
private JLabeledTextField embeddedRE; // regular expression used to match against embedded resource URLs
|
||||
private JTextField embeddedAllowRE; // regular expression used to match against embedded resource URLs to allow
|
||||
private JTextField embeddedExcludeRE; // regular expression used to match against embedded resource URLs to discard
|
||||
private JTextField sourceIpAddr; // does not apply to Java implementation
|
||||
private JComboBox<String> sourceIpType = new JComboBox<>(HTTPSamplerBase.getSourceTypeList());
|
||||
private JTextField proxyScheme;
|
||||
|
|
@ -131,12 +133,18 @@ public class HttpDefaultsGui extends AbstractConfigGui {
|
|||
} else {
|
||||
config.removeProperty(HTTPSamplerBase.MD5);
|
||||
}
|
||||
if (!StringUtils.isEmpty(embeddedRE.getText())) {
|
||||
if (!StringUtils.isEmpty(embeddedAllowRE.getText())) {
|
||||
config.setProperty(new StringProperty(HTTPSamplerBase.EMBEDDED_URL_RE,
|
||||
embeddedRE.getText()));
|
||||
embeddedAllowRE.getText()));
|
||||
} else {
|
||||
config.removeProperty(HTTPSamplerBase.EMBEDDED_URL_RE);
|
||||
}
|
||||
if (!StringUtils.isEmpty(embeddedExcludeRE.getText())) {
|
||||
config.setProperty(new StringProperty(HTTPSamplerBase.EMBEDDED_URL_EXCLUDE_RE,
|
||||
embeddedExcludeRE.getText()));
|
||||
} else {
|
||||
config.removeProperty(HTTPSamplerBase.EMBEDDED_URL_EXCLUDE_RE);
|
||||
}
|
||||
|
||||
if(!StringUtils.isEmpty(sourceIpAddr.getText())) {
|
||||
config.setProperty(new StringProperty(HTTPSamplerBase.IP_SOURCE,
|
||||
|
|
@ -170,7 +178,8 @@ public class HttpDefaultsGui extends AbstractConfigGui {
|
|||
enableConcurrentDwn(false);
|
||||
useMD5.setSelected(false);
|
||||
urlConfigGui.clear();
|
||||
embeddedRE.setText(""); // $NON-NLS-1$
|
||||
embeddedAllowRE.setText(""); // $NON-NLS-1$
|
||||
embeddedExcludeRE.setText(""); // $NON-NLS-1$
|
||||
sourceIpAddr.setText(""); // $NON-NLS-1$
|
||||
sourceIpType.setSelectedIndex(HTTPSamplerBase.SourceType.HOSTNAME.ordinal()); //default: IP/Hostname
|
||||
proxyScheme.setText(""); // $NON-NLS-1$
|
||||
|
|
@ -192,7 +201,8 @@ public class HttpDefaultsGui extends AbstractConfigGui {
|
|||
concurrentDwn.setSelected(samplerBase.getPropertyAsBoolean(HTTPSamplerBase.CONCURRENT_DWN));
|
||||
concurrentPool.setText(samplerBase.getPropertyAsString(HTTPSamplerBase.CONCURRENT_POOL));
|
||||
useMD5.setSelected(samplerBase.getPropertyAsBoolean(HTTPSamplerBase.MD5, false));
|
||||
embeddedRE.setText(samplerBase.getPropertyAsString(HTTPSamplerBase.EMBEDDED_URL_RE, ""));//$NON-NLS-1$
|
||||
embeddedAllowRE.setText(samplerBase.getPropertyAsString(HTTPSamplerBase.EMBEDDED_URL_RE, ""));//$NON-NLS-1$
|
||||
embeddedExcludeRE.setText(samplerBase.getPropertyAsString(HTTPSamplerBase.EMBEDDED_URL_EXCLUDE_RE, ""));//$NON-NLS-1$
|
||||
sourceIpAddr.setText(samplerBase.getPropertyAsString(HTTPSamplerBase.IP_SOURCE)); //$NON-NLS-1$
|
||||
sourceIpType.setSelectedIndex(
|
||||
samplerBase.getPropertyAsInt(HTTPSamplerBase.IP_SOURCE_TYPE,
|
||||
|
|
@ -294,22 +304,33 @@ public class HttpDefaultsGui extends AbstractConfigGui {
|
|||
});
|
||||
concurrentPool = new JTextField(2); // 2 columns size
|
||||
concurrentPool.setMinimumSize(new Dimension(10, (int) concurrentPool.getPreferredSize().getHeight()));
|
||||
concurrentPool.setMaximumSize(new Dimension(30, (int) concurrentPool.getPreferredSize().getHeight()));
|
||||
concurrentPool.setMaximumSize(new Dimension(60, (int) concurrentPool.getPreferredSize().getHeight()));
|
||||
|
||||
final JPanel embeddedRsrcPanel = new HorizontalPanel();
|
||||
final JPanel embeddedRsrcPanel = new JPanel(new MigLayout());
|
||||
embeddedRsrcPanel.setBorder(BorderFactory.createTitledBorder(
|
||||
JMeterUtils.getResString("web_testing_retrieve_title"))); // $NON-NLS-1$
|
||||
embeddedRsrcPanel.add(retrieveEmbeddedResources);
|
||||
embeddedRsrcPanel.add(concurrentDwn);
|
||||
embeddedRsrcPanel.add(concurrentPool);
|
||||
embeddedRsrcPanel.add(concurrentPool, "wrap");
|
||||
|
||||
// Embedded URL match regex
|
||||
embeddedRE = new JLabeledTextField(JMeterUtils.getResString("web_testing_embedded_url_pattern"),20); // $NON-NLS-1$
|
||||
embeddedRsrcPanel.add(embeddedRE);
|
||||
// Embedded URL match regex to allow
|
||||
embeddedAllowRE = addTextFieldWithLabel(embeddedRsrcPanel, JMeterUtils.getResString("web_testing_embedded_url_pattern")); // $NON-NLS-1$
|
||||
|
||||
// Embedded URL match regex to exclude
|
||||
embeddedExcludeRE = addTextFieldWithLabel(embeddedRsrcPanel, JMeterUtils.getResString("web_testing_embedded_url_exclude_pattern")); // $NON-NLS-1$
|
||||
|
||||
return embeddedRsrcPanel;
|
||||
}
|
||||
|
||||
private JTextField addTextFieldWithLabel(JPanel panel, String labelText) {
|
||||
JLabel label = new JLabel(labelText); // $NON-NLS-1$
|
||||
JTextField field = new JTextField(100);
|
||||
label.setLabelFor(field);
|
||||
panel.add(label);
|
||||
panel.add(field, "span");
|
||||
return field;
|
||||
}
|
||||
|
||||
protected JPanel createSourceAddrPanel() {
|
||||
final JPanel sourceAddrPanel = new HorizontalPanel();
|
||||
sourceAddrPanel.setBorder(BorderFactory.createTitledBorder(
|
||||
|
|
@ -343,17 +364,10 @@ public class HttpDefaultsGui extends AbstractConfigGui {
|
|||
}
|
||||
|
||||
private void enableConcurrentDwn(final boolean enable) {
|
||||
if (enable) {
|
||||
concurrentDwn.setEnabled(true);
|
||||
embeddedRE.setEnabled(true);
|
||||
if (concurrentDwn.isSelected()) {
|
||||
concurrentPool.setEnabled(true);
|
||||
}
|
||||
} else {
|
||||
concurrentDwn.setEnabled(false);
|
||||
concurrentPool.setEnabled(false);
|
||||
embeddedRE.setEnabled(false);
|
||||
}
|
||||
concurrentDwn.setEnabled(enable);
|
||||
embeddedAllowRE.setEnabled(enable);
|
||||
embeddedExcludeRE.setEnabled(enable);
|
||||
concurrentPool.setEnabled(concurrentDwn.isSelected() && enable);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -43,7 +43,8 @@ import org.apache.jmeter.samplers.gui.AbstractSamplerGui;
|
|||
import org.apache.jmeter.testelement.TestElement;
|
||||
import org.apache.jmeter.util.JMeterUtils;
|
||||
import org.apache.jorphan.gui.JFactory;
|
||||
import org.apache.jorphan.gui.JLabeledTextField;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
/**
|
||||
* HTTP Sampler GUI
|
||||
|
|
@ -52,14 +53,15 @@ import org.apache.jorphan.gui.JLabeledTextField;
|
|||
@TestElementMetadata(labelResource = "web_testing_title")
|
||||
public class HttpTestSampleGui extends AbstractSamplerGui {
|
||||
|
||||
private static final long serialVersionUID = 241L;
|
||||
private static final long serialVersionUID = 242L;
|
||||
|
||||
private UrlConfigGui urlConfigGui;
|
||||
private JCheckBox retrieveEmbeddedResources;
|
||||
private JCheckBox concurrentDwn;
|
||||
private JTextField concurrentPool;
|
||||
private JCheckBox useMD5;
|
||||
private JLabeledTextField embeddedRE; // regular expression used to match against embedded resource URLs
|
||||
private JTextField embeddedAllowRE; // regular expression used to match against embedded resource URLs to allow
|
||||
private JTextField embeddedExcludeRE; // regular expression used to match against embedded resource URLs to exclude
|
||||
private JTextField sourceIpAddr; // does not apply to Java implementation
|
||||
private JComboBox<String> sourceIpType = new JComboBox<>(HTTPSamplerBase.getSourceTypeList());
|
||||
private JTextField proxyScheme;
|
||||
|
|
@ -96,7 +98,8 @@ public class HttpTestSampleGui extends AbstractSamplerGui {
|
|||
concurrentDwn.setSelected(samplerBase.isConcurrentDwn());
|
||||
concurrentPool.setText(samplerBase.getConcurrentPool());
|
||||
useMD5.setSelected(samplerBase.useMD5());
|
||||
embeddedRE.setText(samplerBase.getEmbeddedUrlRE());
|
||||
embeddedAllowRE.setText(samplerBase.getEmbeddedUrlRE());
|
||||
embeddedExcludeRE.setText(samplerBase.getEmbededUrlExcludeRE());
|
||||
if (!isAJP) {
|
||||
sourceIpAddr.setText(samplerBase.getIpSource());
|
||||
sourceIpType.setSelectedIndex(samplerBase.getIpSourceType());
|
||||
|
|
@ -136,7 +139,8 @@ public class HttpTestSampleGui extends AbstractSamplerGui {
|
|||
samplerBase.setConcurrentDwn(concurrentDwn.isSelected());
|
||||
samplerBase.setConcurrentPool(concurrentPool.getText());
|
||||
samplerBase.setMD5(useMD5.isSelected());
|
||||
samplerBase.setEmbeddedUrlRE(embeddedRE.getText());
|
||||
samplerBase.setEmbeddedUrlRE(embeddedAllowRE.getText());
|
||||
samplerBase.setEmbeddedUrlExcludeRE(embeddedExcludeRE.getText());
|
||||
if (!isAJP) {
|
||||
samplerBase.setIpSource(sourceIpAddr.getText());
|
||||
samplerBase.setIpSourceType(sourceIpType.getSelectedIndex());
|
||||
|
|
@ -256,22 +260,33 @@ public class HttpTestSampleGui extends AbstractSamplerGui {
|
|||
});
|
||||
concurrentPool = new JTextField(2); // 2 column size
|
||||
concurrentPool.setMinimumSize(new Dimension(10, (int) concurrentPool.getPreferredSize().getHeight()));
|
||||
concurrentPool.setMaximumSize(new Dimension(30, (int) concurrentPool.getPreferredSize().getHeight()));
|
||||
concurrentPool.setMaximumSize(new Dimension(60, (int) concurrentPool.getPreferredSize().getHeight()));
|
||||
|
||||
final JPanel embeddedRsrcPanel = new HorizontalPanel();
|
||||
final JPanel embeddedRsrcPanel = new JPanel(new MigLayout());
|
||||
embeddedRsrcPanel.setBorder(BorderFactory.createTitledBorder(
|
||||
JMeterUtils.getResString("web_testing_retrieve_title"))); // $NON-NLS-1$
|
||||
embeddedRsrcPanel.add(retrieveEmbeddedResources);
|
||||
embeddedRsrcPanel.add(concurrentDwn);
|
||||
embeddedRsrcPanel.add(concurrentPool);
|
||||
embeddedRsrcPanel.add(concurrentPool, "wrap");
|
||||
|
||||
// Embedded URL match regex
|
||||
embeddedRE = new JLabeledTextField(JMeterUtils.getResString("web_testing_embedded_url_pattern"),20); // $NON-NLS-1$
|
||||
embeddedRsrcPanel.add(embeddedRE);
|
||||
embeddedAllowRE = addTextFieldWithLabel(embeddedRsrcPanel, JMeterUtils.getResString("web_testing_embedded_url_pattern")); // $NON-NLS-1$
|
||||
|
||||
// Embedded URL to not match regex
|
||||
embeddedExcludeRE = addTextFieldWithLabel(embeddedRsrcPanel, JMeterUtils.getResString("web_testing_embedded_url_exclude_pattern")); // $NON-NLS-1$
|
||||
|
||||
return embeddedRsrcPanel;
|
||||
}
|
||||
|
||||
private JTextField addTextFieldWithLabel(JPanel panel, String labelText) {
|
||||
JLabel label = new JLabel(labelText); // $NON-NLS-1$
|
||||
JTextField field = new JTextField(100);
|
||||
label.setLabelFor(field);
|
||||
panel.add(label);
|
||||
panel.add(field, "span");
|
||||
return field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a panel containing the implementation details
|
||||
*
|
||||
|
|
@ -334,7 +349,7 @@ public class HttpTestSampleGui extends AbstractSamplerGui {
|
|||
enableConcurrentDwn(false);
|
||||
useMD5.setSelected(false);
|
||||
urlConfigGui.clear();
|
||||
embeddedRE.setText(""); // $NON-NLS-1$
|
||||
embeddedAllowRE.setText(""); // $NON-NLS-1$
|
||||
if (!isAJP) {
|
||||
sourceIpAddr.setText(""); // $NON-NLS-1$
|
||||
sourceIpType.setSelectedIndex(HTTPSamplerBase.SourceType.HOSTNAME.ordinal()); //default: IP/Hostname
|
||||
|
|
@ -350,17 +365,10 @@ public class HttpTestSampleGui extends AbstractSamplerGui {
|
|||
}
|
||||
|
||||
private void enableConcurrentDwn(boolean enable) {
|
||||
if (enable) {
|
||||
concurrentDwn.setEnabled(true);
|
||||
embeddedRE.setEnabled(true);
|
||||
if (concurrentDwn.isSelected()) {
|
||||
concurrentPool.setEnabled(true);
|
||||
}
|
||||
} else {
|
||||
concurrentDwn.setEnabled(false);
|
||||
concurrentPool.setEnabled(false);
|
||||
embeddedRE.setEnabled(false);
|
||||
}
|
||||
concurrentDwn.setEnabled(enable);
|
||||
embeddedAllowRE.setEnabled(enable);
|
||||
embeddedExcludeRE.setEnabled(enable);
|
||||
concurrentPool.setEnabled(concurrentDwn.isSelected() && enable);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -73,12 +73,6 @@ public abstract class AbstractSamplerCreator implements SamplerCreator {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public AbstractSamplerCreator() {
|
||||
super();
|
||||
}
|
||||
|
|
@ -97,6 +91,11 @@ public abstract class AbstractSamplerCreator implements SamplerCreator {
|
|||
incrementRequestNumberAndGet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCounter(int value) {
|
||||
REQUEST_NUMBER.set(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment request number
|
||||
* @return int number for created sampler
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import java.io.IOException;
|
|||
import java.io.StringReader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.XMLConstants;
|
||||
|
|
@ -60,6 +61,8 @@ public class DefaultSamplerCreator extends AbstractSamplerCreator {
|
|||
*/
|
||||
private static final int SAMPLER_NAME_NAMING_MODE_PREFIX = 0; // $NON-NLS-1$
|
||||
private static final int SAMPLER_NAME_NAMING_MODE_COMPLETE = 1; // $NON-NLS-1$
|
||||
private static final int SAMPLER_NAME_NAMING_MODE_SUFFIX = 2; // $NON-NLS-1$
|
||||
private static final int SAMPLER_NAME_NAMING_MODE_FORMATTER = 3; // $NON_NLS-1$
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -285,35 +288,50 @@ public class DefaultSamplerCreator extends AbstractSamplerCreator {
|
|||
*/
|
||||
protected void computeSamplerName(HTTPSamplerBase sampler,
|
||||
HttpRequestHdr request) {
|
||||
String prefix = request.getPrefix();
|
||||
String prefix = StringUtils.defaultString(request.getPrefix(), "");
|
||||
int httpSampleNameMode = request.getHttpSampleNameMode();
|
||||
String format = getFormat(httpSampleNameMode, request.getHttpSampleNameFormat());
|
||||
if (!HTTPConstants.CONNECT.equals(request.getMethod()) && isNumberRequests()) {
|
||||
if(StringUtils.isNotEmpty(prefix)) {
|
||||
if (httpSampleNameMode == SAMPLER_NAME_NAMING_MODE_PREFIX) {
|
||||
sampler.setName(prefix + sampler.getPath()+ "-" + incrementRequestNumberAndGet());
|
||||
} else if (httpSampleNameMode == SAMPLER_NAME_NAMING_MODE_COMPLETE) {
|
||||
sampler.setName(prefix + "-" + incrementRequestNumberAndGet());
|
||||
} else {
|
||||
log.debug("Sampler name naming mode not recognized");
|
||||
}
|
||||
} else {
|
||||
sampler.setName(sampler.getPath()+"-"+incrementRequestNumberAndGet());
|
||||
}
|
||||
sampler.setName(MessageFormat.format(format, prefix, sampler.getPath(), incrementRequestNumberAndGet()));
|
||||
} else {
|
||||
if(StringUtils.isNotEmpty(prefix)) {
|
||||
if (httpSampleNameMode == SAMPLER_NAME_NAMING_MODE_PREFIX) {
|
||||
sampler.setName(prefix + sampler.getPath());
|
||||
} else if (httpSampleNameMode == SAMPLER_NAME_NAMING_MODE_COMPLETE) {
|
||||
sampler.setName(prefix);
|
||||
} else {
|
||||
log.debug("Sampler name naming mode not recognized");
|
||||
}
|
||||
} else {
|
||||
sampler.setName(sampler.getPath());
|
||||
}
|
||||
sampler.setName(MessageFormat.format(format, prefix, sampler.getPath()));
|
||||
}
|
||||
}
|
||||
|
||||
private String getFormat(int httpSampleNameMode, String format) {
|
||||
if (httpSampleNameMode == SAMPLER_NAME_NAMING_MODE_FORMATTER) {
|
||||
return format.replaceAll("#\\{name([,}])", "{0$1")
|
||||
.replaceAll("#\\{path([,}])", "{1$1")
|
||||
.replaceAll("#\\{counter([,}])", "{2$1");
|
||||
}
|
||||
if (isNumberRequests()) {
|
||||
return getNumberedFormat(httpSampleNameMode, format);
|
||||
}
|
||||
if (httpSampleNameMode == SAMPLER_NAME_NAMING_MODE_PREFIX) {
|
||||
return "{0}{1}";
|
||||
}
|
||||
if (httpSampleNameMode == SAMPLER_NAME_NAMING_MODE_COMPLETE) {
|
||||
return "{0}";
|
||||
}
|
||||
if (httpSampleNameMode == SAMPLER_NAME_NAMING_MODE_SUFFIX) {
|
||||
return "{0} {1}";
|
||||
}
|
||||
return "{1}";
|
||||
}
|
||||
|
||||
private String getNumberedFormat(int httpSampleNameMode, String format) {
|
||||
if (httpSampleNameMode == SAMPLER_NAME_NAMING_MODE_PREFIX) {
|
||||
return "{0}{1}-{2}";
|
||||
}
|
||||
if (httpSampleNameMode == SAMPLER_NAME_NAMING_MODE_COMPLETE) {
|
||||
return "{0}-{2}";
|
||||
}
|
||||
if (httpSampleNameMode == SAMPLER_NAME_NAMING_MODE_SUFFIX) {
|
||||
return "{0}-{2} {1}";
|
||||
}
|
||||
return "{1}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Set path on sampler
|
||||
* @param sampler {@link HTTPSamplerBase}
|
||||
|
|
|
|||
|
|
@ -84,6 +84,8 @@ public class HttpRequestHdr {
|
|||
|
||||
private int httpSampleNameMode;
|
||||
|
||||
private String httpSampleNameFormat;
|
||||
|
||||
public HttpRequestHdr() {
|
||||
this("", "");
|
||||
}
|
||||
|
|
@ -100,19 +102,21 @@ public class HttpRequestHdr {
|
|||
* @param httpSamplerName the http sampler name
|
||||
*/
|
||||
public HttpRequestHdr(String prefix, String httpSamplerName) {
|
||||
this(prefix, httpSamplerName,0);
|
||||
this(prefix, httpSamplerName, 0, "{0}{1}");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param prefix Sampler prefix
|
||||
* @param httpSamplerName the http sampler name
|
||||
* @param httpSampleNameMode the naming mode of sampler name
|
||||
* @param format format to use when mode is 3
|
||||
*/
|
||||
public HttpRequestHdr(String prefix, String httpSamplerName, int httpSampleNameMode) {
|
||||
public HttpRequestHdr(String prefix, String httpSamplerName, int httpSampleNameMode, String format) {
|
||||
this.prefix = prefix;
|
||||
this.httpSamplerName = httpSamplerName;
|
||||
this.firstLine = "" ; // $NON-NLS-1$
|
||||
this.httpSampleNameMode = httpSampleNameMode;
|
||||
this.httpSampleNameFormat = format;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -463,4 +467,8 @@ public class HttpRequestHdr {
|
|||
public int getHttpSampleNameMode() {
|
||||
return httpSampleNameMode;
|
||||
}
|
||||
|
||||
public String getHttpSampleNameFormat() {
|
||||
return httpSampleNameFormat;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import java.security.GeneralSecurityException;
|
|||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -63,6 +64,9 @@ import org.slf4j.LoggerFactory;
|
|||
* JMeter test plan.
|
||||
*/
|
||||
public class Proxy extends Thread {
|
||||
// Mime-types of resources, that are not HTML and not binary that should be skipped on form parsing in JSoup
|
||||
private static final List<String> NOT_HTML_TEXT_TYPES = Arrays.asList("application/javascript", "application/json", "text/javascript");
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(Proxy.class);
|
||||
|
||||
private static final byte[] CRLF_BYTES = { 0x0d, 0x0a };
|
||||
|
|
@ -157,7 +161,8 @@ public class Proxy extends Thread {
|
|||
// Check which HTTPSampler class we should use
|
||||
String httpSamplerName = target.getSamplerTypeName();
|
||||
|
||||
HttpRequestHdr request = new HttpRequestHdr(target.getPrefixHTTPSampleName(), httpSamplerName,target.getHTTPSampleNamingMode());
|
||||
HttpRequestHdr request = new HttpRequestHdr(target.getPrefixHTTPSampleName(), httpSamplerName,
|
||||
target.getHTTPSampleNamingMode(), target.getHttpSampleNameFormat());
|
||||
SampleResult result = null;
|
||||
HeaderManager headers = null;
|
||||
HTTPSamplerBase sampler = null;
|
||||
|
|
@ -300,6 +305,15 @@ public class Proxy extends Thread {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the counter for all registered {@link SamplerCreatorFactory}s
|
||||
*
|
||||
* @param value to be initialized
|
||||
*/
|
||||
public static void setCounter(int value) {
|
||||
SAMPLERFACTORY.setCounter(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SSL connection from hashmap, creating it if necessary.
|
||||
*
|
||||
|
|
@ -595,10 +609,16 @@ public class Proxy extends Thread {
|
|||
FormCharSetFinder finder = new FormCharSetFinder();
|
||||
if (SampleResult.isBinaryType(result.getContentType())) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Will not guess encoding of url:{} as it's binary", result.getUrlAsString());
|
||||
log.debug("Will not guess encoding of URL: {} as it's binary", result.getUrlAsString());
|
||||
}
|
||||
return; // no point parsing anything else, e.g. GIF ...
|
||||
}
|
||||
if (isNotHtmlType(result.getContentType())) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Will not guess encoding of URL: {} as it's not HTML", result.getUrlAsString());
|
||||
}
|
||||
return; // None HTML types have been crashing JSoup parser, so return here early
|
||||
}
|
||||
try {
|
||||
finder.addFormActionsAndCharSet(result.getResponseDataAsString(), formEncodings, pageEncoding);
|
||||
}
|
||||
|
|
@ -609,6 +629,15 @@ public class Proxy extends Thread {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean isNotHtmlType(String contentType) {
|
||||
for (String mimeType: NOT_HTML_TEXT_TYPES) {
|
||||
if (contentType.startsWith(mimeType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String getUrlWithoutQuery(URL url) {
|
||||
String fullUrl = url.toString();
|
||||
String urlWithoutQuery = fullUrl;
|
||||
|
|
|
|||
|
|
@ -288,6 +288,8 @@ public class ProxyControl extends GenericController implements NonTestElement {
|
|||
|
||||
private transient javax.swing.Timer sampleWorkerTimer;
|
||||
|
||||
private String httpSampleNameFormat;
|
||||
|
||||
public ProxyControl() {
|
||||
setPort(DEFAULT_PORT);
|
||||
setExcludeList(new HashSet<>());
|
||||
|
|
@ -1658,8 +1660,7 @@ public class ProxyControl extends GenericController implements NonTestElement {
|
|||
private int groupingMode;
|
||||
private long recordedAt;
|
||||
|
||||
public SamplerInfo(HTTPSamplerBase sampler, TestElement[] testElements, JMeterTreeNode target, String prefix,
|
||||
int groupingMode) {
|
||||
public SamplerInfo(HTTPSamplerBase sampler, TestElement[] testElements, JMeterTreeNode target, String prefix, int groupingMode) {
|
||||
this.sampler = sampler;
|
||||
this.testElements = testElements;
|
||||
this.target = target;
|
||||
|
|
@ -1668,4 +1669,12 @@ public class ProxyControl extends GenericController implements NonTestElement {
|
|||
this.recordedAt = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
|
||||
public void setHttpSampleNameFormat(String text) {
|
||||
this.httpSampleNameFormat = text;
|
||||
}
|
||||
|
||||
public String getHttpSampleNameFormat() {
|
||||
return httpSampleNameFormat;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,4 +93,12 @@ public interface SamplerCreator {
|
|||
* @return List
|
||||
*/
|
||||
List<TestElement> createChildren(HTTPSamplerBase sampler, SampleResult result);
|
||||
|
||||
/**
|
||||
* Set the counter for this implementation. The counter should be incremented
|
||||
* before creating a new sampler by the implementation.
|
||||
*
|
||||
* @param value to be used
|
||||
*/
|
||||
default void setCounter(int value) {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,19 @@ public class SamplerCreatorFactory {
|
|||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the counter for all available {@link SamplerCreator}s.
|
||||
* <p>
|
||||
* <em>The only implementation that is currently available, increments the counter before it is used!</em>
|
||||
* @param value to initialize the creators
|
||||
*/
|
||||
public void setCounter(int value) {
|
||||
DEFAULT_SAMPLER_CREATOR.setCounter(value);
|
||||
for (SamplerCreator samplerCreator: samplerCreatorMap.values()) {
|
||||
samplerCreator.setCounter(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize factory from classpath
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ import org.apache.jmeter.gui.util.MenuFactory;
|
|||
import org.apache.jmeter.gui.util.PowerTableModel;
|
||||
import org.apache.jmeter.gui.util.VerticalPanel;
|
||||
import org.apache.jmeter.protocol.http.control.RecordingController;
|
||||
import org.apache.jmeter.protocol.http.proxy.Proxy;
|
||||
import org.apache.jmeter.protocol.http.proxy.ProxyControl;
|
||||
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerFactory;
|
||||
import org.apache.jmeter.testelement.TestElement;
|
||||
|
|
@ -91,6 +92,8 @@ import org.apache.jorphan.gui.JLabeledTextField;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
/**
|
||||
* GUI of HTTP(s) Test Script Recorder
|
||||
*
|
||||
|
|
@ -229,7 +232,7 @@ public class ProxyControlGui extends LogicControllerGui implements JMeterGUIComp
|
|||
|
||||
private transient RecorderDialog recorderDialog;
|
||||
|
||||
private Component labelDefaultEncoding;
|
||||
private JTextField httpSampleNameFormat;
|
||||
|
||||
//+ action names
|
||||
private static final String ACTION_STOP = "stop"; // $NON-NLS-1$
|
||||
|
|
@ -270,6 +273,9 @@ public class ProxyControlGui extends LogicControllerGui implements JMeterGUIComp
|
|||
// Used by itemListener
|
||||
private static final String PORT_FIELD_NAME = "portField"; // $NON-NLS-1$
|
||||
|
||||
static final String HTTP_SAMPLER_NAME_FORMAT = "proxy_http_sampler_name_format";
|
||||
|
||||
|
||||
public ProxyControlGui() {
|
||||
super();
|
||||
log.debug("Creating ProxyControlGui");
|
||||
|
|
@ -416,12 +422,12 @@ public class ProxyControlGui extends LogicControllerGui implements JMeterGUIComp
|
|||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
if (e.getSource() instanceof JComboBox) {
|
||||
JComboBox combo = (JComboBox) e.getSource();
|
||||
if(HTTP_SAMPLER_NAMING_MODE.equals(combo.getName())){
|
||||
JComboBox<?> combo = (JComboBox<?>) e.getSource();
|
||||
if (HTTP_SAMPLER_NAMING_MODE.equals(combo.getName())) {
|
||||
model.setHTTPSampleNamingMode(httpSampleNamingMode.getSelectedIndex());
|
||||
}
|
||||
httpSampleNameFormat.setEnabled(httpSampleNamingMode.getSelectedIndex() == 3);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
enableRestart();
|
||||
}
|
||||
}
|
||||
|
|
@ -710,6 +716,8 @@ public class ProxyControlGui extends LogicControllerGui implements JMeterGUIComp
|
|||
enableRestart();
|
||||
} else if(fieldName.equals(PREFIX_HTTP_SAMPLER_NAME)) {
|
||||
model.setPrefixHTTPSampleName(prefixHTTPSampleName.getText());
|
||||
} else if (fieldName.equals(HTTP_SAMPLER_NAME_FORMAT)) {
|
||||
model.setHttpSampleNameFormat(httpSampleNameFormat.getText());
|
||||
} else if(fieldName.equals(PROXY_PAUSE_HTTP_SAMPLER)) {
|
||||
try {
|
||||
Long.parseLong(proxyPauseHTTPSample.getText());
|
||||
|
|
@ -868,22 +876,16 @@ public class ProxyControlGui extends LogicControllerGui implements JMeterGUIComp
|
|||
regexMatch.addActionListener(this);
|
||||
regexMatch.setActionCommand(ENABLE_RESTART);
|
||||
|
||||
VerticalPanel mainPanel = new VerticalPanel();
|
||||
mainPanel.setBorder(BorderFactory.createTitledBorder(
|
||||
JPanel contentPanel = new JPanel(new MigLayout("fillx, wrap 3"));
|
||||
contentPanel.setBorder(BorderFactory.createTitledBorder(
|
||||
JMeterUtils.getResString("proxy_test_plan_content"))); // $NON-NLS-1$
|
||||
addTargetToPanel(contentPanel);
|
||||
addGroupingToPanel(contentPanel);
|
||||
contentPanel.add(httpHeaders);
|
||||
contentPanel.add(addAssertions);
|
||||
contentPanel.add(regexMatch);
|
||||
|
||||
HorizontalPanel nodeCreationPanel = new HorizontalPanel();
|
||||
nodeCreationPanel.add(createGroupingPanel());
|
||||
nodeCreationPanel.add(httpHeaders);
|
||||
nodeCreationPanel.add(addAssertions);
|
||||
nodeCreationPanel.add(regexMatch);
|
||||
|
||||
HorizontalPanel targetPanel = new HorizontalPanel();
|
||||
targetPanel.add(createTargetPanel());
|
||||
mainPanel.add(targetPanel);
|
||||
mainPanel.add(nodeCreationPanel);
|
||||
|
||||
return mainPanel;
|
||||
return contentPanel;
|
||||
}
|
||||
|
||||
private JPanel createHTTPSamplerPanel() {
|
||||
|
|
@ -922,6 +924,8 @@ public class ProxyControlGui extends LogicControllerGui implements JMeterGUIComp
|
|||
DefaultComboBoxModel<String> choice = new DefaultComboBoxModel<>();
|
||||
choice.addElement(JMeterUtils.getResString("sample_name_prefix")); // $NON-NLS-1$
|
||||
choice.addElement(JMeterUtils.getResString("sample_name_transaction")); // $NON-NLS-1$
|
||||
choice.addElement(JMeterUtils.getResString("sample_name_suffix")); // $NON-NLS-1$
|
||||
choice.addElement(JMeterUtils.getResString("sample_name_formatter")); // $NON-NLS-1$
|
||||
httpSampleNamingMode = new JComboBox<>(choice);
|
||||
httpSampleNamingMode.setName(HTTP_SAMPLER_NAMING_MODE);
|
||||
httpSampleNamingMode.addItemListener(this);
|
||||
|
|
@ -932,6 +936,10 @@ public class ProxyControlGui extends LogicControllerGui implements JMeterGUIComp
|
|||
prefixHTTPSampleName.addKeyListener(this);
|
||||
prefixHTTPSampleName.setName(PREFIX_HTTP_SAMPLER_NAME);
|
||||
|
||||
httpSampleNameFormat = new JTextField(20);
|
||||
httpSampleNameFormat.addKeyListener(this);
|
||||
httpSampleNameFormat.setName(HTTP_SAMPLER_NAME_FORMAT);
|
||||
|
||||
proxyPauseHTTPSample = new JTextField(10);
|
||||
proxyPauseHTTPSample.addKeyListener(this);
|
||||
proxyPauseHTTPSample.setName(PROXY_PAUSE_HTTP_SAMPLER);
|
||||
|
|
@ -942,71 +950,50 @@ public class ProxyControlGui extends LogicControllerGui implements JMeterGUIComp
|
|||
JLabel labelDefaultEncoding = new JLabel(JMeterUtils.getResString("proxy_default_encoding")); // $NON-NLS-1$
|
||||
labelDefaultEncoding.setLabelFor(defaultEncoding);
|
||||
|
||||
GridBagLayout gridBagLayout = new GridBagLayout();
|
||||
GridBagConstraints gbc = new GridBagConstraints();
|
||||
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
|
||||
gbc.fill = GridBagConstraints.NONE;
|
||||
gbc.gridheight = 1;
|
||||
gbc.gridwidth = 1;
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 0;
|
||||
gbc.weightx = 1;
|
||||
gbc.weighty = 1;
|
||||
JPanel panel = new JPanel(gridBagLayout);
|
||||
JPanel panel = new JPanel(new MigLayout("fillx, wrap 3"));
|
||||
panel.setBorder(BorderFactory.createTitledBorder(
|
||||
JMeterUtils.getResString("proxy_sampler_settings"))); // $NON-NLS-1$
|
||||
panel.add(httpSampleNamingMode, gbc.clone());
|
||||
gbc.gridx++;
|
||||
gbc.weightx = 3;
|
||||
gbc.fill=GridBagConstraints.HORIZONTAL;
|
||||
panel.add(prefixHTTPSampleName, gbc.clone());
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy++;
|
||||
panel.add(labelProxyPause, gbc.clone());
|
||||
gbc.gridx++;
|
||||
gbc.weightx = 3;
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||
panel.add(proxyPauseHTTPSample, gbc.clone());
|
||||
gbc.weightx = 1;
|
||||
JLabel labelSampleTransactionName = new JLabel(JMeterUtils.getResString("sample_name_transaction"));
|
||||
labelSampleTransactionName.setLabelFor(prefixHTTPSampleName);
|
||||
panel.add(labelSampleTransactionName);
|
||||
panel.add(prefixHTTPSampleName, "growx, span");
|
||||
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy++;
|
||||
panel.add(labelDefaultEncoding, gbc.clone());
|
||||
gbc.gridx++;
|
||||
gbc.weightx = 3;
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||
panel.add(defaultEncoding, gbc.clone());
|
||||
gbc.weightx = 1;
|
||||
JLabel labelNamingScheme = new JLabel(JMeterUtils.getResString("sample_naming_scheme"));
|
||||
labelNamingScheme.setLabelFor(httpSampleNamingMode);
|
||||
panel.add(labelNamingScheme, "split 2");
|
||||
panel.add(httpSampleNamingMode);
|
||||
panel.add(httpSampleNameFormat, "growx, span");
|
||||
httpSampleNameFormat.setToolTipText(JMeterUtils.getResString("sample_naming_format_help"));
|
||||
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy++;
|
||||
gbc.fill=GridBagConstraints.VERTICAL;
|
||||
panel.add(samplerDownloadImages, gbc.clone());
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy++;
|
||||
gbc.fill=GridBagConstraints.VERTICAL;
|
||||
panel.add(samplerRedirectAutomatically, gbc.clone());
|
||||
gbc.gridx++;
|
||||
gbc.fill=GridBagConstraints.HORIZONTAL;
|
||||
panel.add(samplerFollowRedirects, gbc.clone());
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy++;
|
||||
gbc.fill=GridBagConstraints.VERTICAL;
|
||||
panel.add(useKeepAlive, gbc.clone());
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy++;
|
||||
gbc.fill=GridBagConstraints.VERTICAL;
|
||||
panel.add(labelSamplerType, gbc.clone());
|
||||
gbc.gridx++;
|
||||
gbc.fill=GridBagConstraints.HORIZONTAL;
|
||||
panel.add(samplerTypeName, gbc.clone());
|
||||
JLabel labelSetCounter = new JLabel(JMeterUtils.getResString("sample_creator_counter_value"));
|
||||
JTextField counterValue = new JTextField(10);
|
||||
labelSetCounter.setLabelFor(counterValue);
|
||||
JButton buttonSetCounter = new JButton(JMeterUtils.getResString("sample_creator_set_counter"));
|
||||
buttonSetCounter.addActionListener(e -> Proxy.setCounter(Integer.valueOf(counterValue.getText())));
|
||||
panel.add(labelSetCounter);
|
||||
panel.add(counterValue);
|
||||
panel.add(buttonSetCounter);
|
||||
|
||||
panel.add(labelProxyPause);
|
||||
panel.add(proxyPauseHTTPSample, "growx, span");
|
||||
|
||||
panel.add(labelDefaultEncoding);
|
||||
panel.add(defaultEncoding, "growx, span");
|
||||
|
||||
panel.add(samplerDownloadImages);
|
||||
panel.add(samplerRedirectAutomatically);
|
||||
panel.add(samplerFollowRedirects);
|
||||
panel.add(useKeepAlive, "wrap");
|
||||
|
||||
panel.add(labelSamplerType);
|
||||
panel.add(samplerTypeName, "growx, span");
|
||||
return panel;
|
||||
}
|
||||
|
||||
private JPanel createTargetPanel() {
|
||||
private void addTargetToPanel(JPanel destPanel) {
|
||||
targetNodesModel = new DefaultComboBoxModel<>();
|
||||
targetNodes = new JComboBox<>(targetNodesModel);
|
||||
targetNodes.setPrototypeDisplayValue(""); // $NON-NLS-1$ // Bug 56303 fixed the width of combo list
|
||||
// Bug 56303 fixed the width of combo list
|
||||
JPopupMenu popup = (JPopupMenu) targetNodes.getUI().getAccessibleChild(targetNodes, 0); // get popup element
|
||||
JScrollPane scrollPane = findScrollPane(popup);
|
||||
if(scrollPane != null) {
|
||||
|
|
@ -1019,11 +1006,8 @@ public class ProxyControlGui extends LogicControllerGui implements JMeterGUIComp
|
|||
JLabel label = new JLabel(JMeterUtils.getResString("proxy_target")); // $NON-NLS-1$
|
||||
label.setLabelFor(targetNodes);
|
||||
|
||||
HorizontalPanel panel = new HorizontalPanel();
|
||||
panel.add(label);
|
||||
panel.add(targetNodes);
|
||||
|
||||
return panel;
|
||||
destPanel.add(label);
|
||||
destPanel.add(targetNodes, "growx, span");
|
||||
}
|
||||
|
||||
private JScrollPane findScrollPane(JPopupMenu popup) {
|
||||
|
|
@ -1036,7 +1020,7 @@ public class ProxyControlGui extends LogicControllerGui implements JMeterGUIComp
|
|||
return null;
|
||||
}
|
||||
|
||||
private JPanel createGroupingPanel() {
|
||||
private void addGroupingToPanel(JPanel destPanel) {
|
||||
DefaultComboBoxModel<String> m = new DefaultComboBoxModel<>();
|
||||
// Note: position of these elements in the menu *must* match the
|
||||
// corresponding ProxyControl.GROUPING_* values.
|
||||
|
|
@ -1046,18 +1030,14 @@ public class ProxyControlGui extends LogicControllerGui implements JMeterGUIComp
|
|||
m.addElement(JMeterUtils.getResString("grouping_store_first_only")); // $NON-NLS-1$
|
||||
m.addElement(JMeterUtils.getResString("grouping_in_transaction_controllers")); // $NON-NLS-1$
|
||||
groupingMode = new JComboBox<>(m);
|
||||
groupingMode.setPreferredSize(new Dimension(150, 20));
|
||||
groupingMode.setSelectedIndex(0);
|
||||
groupingMode.addItemListener(this);
|
||||
|
||||
JLabel label2 = new JLabel(JMeterUtils.getResString("grouping_mode")); // $NON-NLS-1$
|
||||
label2.setLabelFor(groupingMode);
|
||||
|
||||
HorizontalPanel panel = new HorizontalPanel();
|
||||
panel.add(label2);
|
||||
panel.add(groupingMode);
|
||||
|
||||
return panel;
|
||||
destPanel.add(label2);
|
||||
destPanel.add(groupingMode, "growx, span");
|
||||
}
|
||||
|
||||
private JPanel createContentTypePanel() {
|
||||
|
|
@ -1266,4 +1246,9 @@ public class ProxyControlGui extends LogicControllerGui implements JMeterGUIComp
|
|||
prefixHTTPSampleName.setText(text);
|
||||
model.setPrefixHTTPSampleName(text);
|
||||
}
|
||||
|
||||
void setSampleNameFormat(String text) {
|
||||
httpSampleNameFormat.setText(text);
|
||||
model.setHttpSampleNameFormat(text);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,8 +18,6 @@
|
|||
package org.apache.jmeter.protocol.http.proxy.gui;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
|
@ -47,8 +45,11 @@ import javax.swing.JTextField;
|
|||
|
||||
import org.apache.jmeter.gui.action.KeyStrokes;
|
||||
import org.apache.jmeter.gui.util.JMeterToolBar;
|
||||
import org.apache.jmeter.protocol.http.proxy.Proxy;
|
||||
import org.apache.jmeter.util.JMeterUtils;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
/**
|
||||
* Dialog for Recorder
|
||||
* @since 5.0
|
||||
|
|
@ -66,6 +67,8 @@ public class RecorderDialog extends JDialog implements ItemListener, KeyListener
|
|||
*/
|
||||
private JTextField prefixHTTPSampleName;
|
||||
|
||||
private JTextField sampleNameFormat;
|
||||
|
||||
private JTextField proxyPauseHTTPSample;
|
||||
|
||||
/**
|
||||
|
|
@ -120,6 +123,8 @@ public class RecorderDialog extends JDialog implements ItemListener, KeyListener
|
|||
DefaultComboBoxModel<String> choice = new DefaultComboBoxModel<>();
|
||||
choice.addElement(JMeterUtils.getResString("sample_name_prefix")); // $NON-NLS-1$
|
||||
choice.addElement(JMeterUtils.getResString("sample_name_transaction")); // $NON-NLS-1$
|
||||
choice.addElement(JMeterUtils.getResString("sample_name_suffix")); // $NON-NLS-1$
|
||||
choice.addElement(JMeterUtils.getResString("sample_name_formatter")); // $NON-NLS-1$
|
||||
httpSampleNamingMode = new JComboBox<>(choice);
|
||||
httpSampleNamingMode.setName(ProxyControlGui.HTTP_SAMPLER_NAMING_MODE);
|
||||
httpSampleNamingMode.addItemListener(this);
|
||||
|
|
@ -136,31 +141,35 @@ public class RecorderDialog extends JDialog implements ItemListener, KeyListener
|
|||
JLabel labelProxyPause = new JLabel(JMeterUtils.getResString("proxy_pause_http_sampler")); // $NON-NLS-1$
|
||||
labelProxyPause.setLabelFor(proxyPauseHTTPSample);
|
||||
|
||||
GridBagLayout gridBagLayout = new GridBagLayout();
|
||||
GridBagConstraints gbc = new GridBagConstraints();
|
||||
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
|
||||
gbc.fill = GridBagConstraints.NONE;
|
||||
gbc.gridheight = 1;
|
||||
gbc.gridwidth = 1;
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 0;
|
||||
gbc.weightx = 1;
|
||||
gbc.weighty = 1;
|
||||
JPanel panel = new JPanel(gridBagLayout);
|
||||
JPanel panel = new JPanel(new MigLayout("fillx, wrap 3"));
|
||||
panel.setBorder(BorderFactory.createTitledBorder(
|
||||
JMeterUtils.getResString("proxy_sampler_settings"))); // $NON-NLS-1$
|
||||
panel.add(httpSampleNamingMode, gbc.clone());
|
||||
gbc.gridx++;
|
||||
gbc.weightx = 3;
|
||||
gbc.fill=GridBagConstraints.HORIZONTAL;
|
||||
panel.add(prefixHTTPSampleName, gbc.clone());
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy++;
|
||||
panel.add(labelProxyPause, gbc.clone());
|
||||
gbc.gridx++;
|
||||
gbc.weightx = 3;
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||
panel.add(proxyPauseHTTPSample, gbc.clone());
|
||||
JLabel labelTransactionName = new JLabel(JMeterUtils.getResString("sample_name_transaction"));
|
||||
labelTransactionName.setLabelFor(prefixHTTPSampleName);
|
||||
panel.add(labelTransactionName);
|
||||
panel.add(prefixHTTPSampleName, "span");
|
||||
|
||||
JLabel labelNamingScheme = new JLabel(JMeterUtils.getResString("sample_naming_scheme"));
|
||||
labelNamingScheme.setLabelFor(httpSampleNamingMode);
|
||||
panel.add(labelNamingScheme, "split 2");
|
||||
panel.add(httpSampleNamingMode);
|
||||
sampleNameFormat = new JTextField(20);
|
||||
sampleNameFormat.addKeyListener(this);
|
||||
sampleNameFormat.setName(ProxyControlGui.HTTP_SAMPLER_NAME_FORMAT);
|
||||
sampleNameFormat.setEnabled(httpSampleNamingMode.getSelectedIndex() == 3);
|
||||
sampleNameFormat.setToolTipText(JMeterUtils.getResString("sample_naming_format_help"));
|
||||
panel.add(sampleNameFormat, "span");
|
||||
|
||||
JLabel labelSetCounter = new JLabel(JMeterUtils.getResString("sample_creator_counter_value"));
|
||||
JTextField counterValue = new JTextField(10);
|
||||
labelSetCounter.setLabelFor(counterValue);
|
||||
JButton buttonSetCounter = new JButton(JMeterUtils.getResString("sample_creator_set_counter"));
|
||||
buttonSetCounter.addActionListener(e -> Proxy.setCounter(Integer.valueOf(counterValue.getText())));
|
||||
panel.add(labelSetCounter);
|
||||
panel.add(counterValue);
|
||||
panel.add(buttonSetCounter);
|
||||
panel.add(labelProxyPause);
|
||||
panel.add(proxyPauseHTTPSample, "span");
|
||||
|
||||
this.getContentPane().add(panel, BorderLayout.CENTER);
|
||||
|
||||
|
|
@ -194,9 +203,10 @@ public class RecorderDialog extends JDialog implements ItemListener, KeyListener
|
|||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
if (e.getSource() instanceof JComboBox) {
|
||||
JComboBox combo = (JComboBox) e.getSource();
|
||||
JComboBox<?> combo = (JComboBox<?>) e.getSource();
|
||||
if(ProxyControlGui.HTTP_SAMPLER_NAMING_MODE.equals(combo.getName())){
|
||||
recorderGui.setHTTPSampleNamingMode(httpSampleNamingMode.getSelectedIndex());
|
||||
sampleNameFormat.setEnabled(httpSampleNamingMode.getSelectedIndex() == 3);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -220,9 +230,11 @@ public class RecorderDialog extends JDialog implements ItemListener, KeyListener
|
|||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
String fieldName = e.getComponent().getName();
|
||||
if(fieldName.equals(ProxyControlGui.PREFIX_HTTP_SAMPLER_NAME)) {
|
||||
if (fieldName.equals(ProxyControlGui.PREFIX_HTTP_SAMPLER_NAME)) {
|
||||
recorderGui.setPrefixHTTPSampleName(prefixHTTPSampleName.getText());
|
||||
} else if(fieldName.equals(ProxyControlGui.PROXY_PAUSE_HTTP_SAMPLER)) {
|
||||
} else if (fieldName.equals(ProxyControlGui.HTTP_SAMPLER_NAME_FORMAT)) {
|
||||
recorderGui.setSampleNameFormat(sampleNameFormat.getText());
|
||||
} else if (fieldName.equals(ProxyControlGui.PROXY_PAUSE_HTTP_SAMPLER)) {
|
||||
try {
|
||||
Long.parseLong(proxyPauseHTTPSample.getText());
|
||||
} catch (NumberFormatException nfe) {
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ public abstract class HTTPSamplerBase extends AbstractSampler
|
|||
implements TestStateListener, TestIterationListener, ThreadListener, HTTPConstantsInterface,
|
||||
Replaceable {
|
||||
|
||||
private static final long serialVersionUID = 242L;
|
||||
private static final long serialVersionUID = 243L;
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(HTTPSamplerBase.class);
|
||||
|
||||
|
|
@ -266,6 +266,9 @@ public abstract class HTTPSamplerBase extends AbstractSampler
|
|||
// Embedded URLs must match this RE (if provided)
|
||||
public static final String EMBEDDED_URL_RE = "HTTPSampler.embedded_url_re"; // $NON-NLS-1$
|
||||
|
||||
// Embedded URLs must not match this RE (if provided)
|
||||
public static final String EMBEDDED_URL_EXCLUDE_RE = "HTTPSampler.embedded_url_exclude_re"; // $NON-NLS-1$
|
||||
|
||||
public static final String MONITOR = "HTTPSampler.monitor"; // $NON-NLS-1$
|
||||
|
||||
// Store MD5 hash instead of storing response
|
||||
|
|
@ -1026,6 +1029,17 @@ public abstract class HTTPSamplerBase extends AbstractSampler
|
|||
setProperty(new StringProperty(EMBEDDED_URL_RE, regex));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the regular (as String) expression that embedded URLs must not match
|
||||
*/
|
||||
public String getEmbededUrlExcludeRE() {
|
||||
return getPropertyAsString(EMBEDDED_URL_EXCLUDE_RE, "");
|
||||
}
|
||||
|
||||
public void setEmbeddedUrlExcludeRE(String regex) {
|
||||
setProperty(new StringProperty(EMBEDDED_URL_EXCLUDE_RE, regex));
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the provided HTTPSampleResult with details from the Exception.
|
||||
* Does not create a new instance, so should not be used directly to add a subsample.
|
||||
|
|
@ -1349,17 +1363,29 @@ public abstract class HTTPSamplerBase extends AbstractSampler
|
|||
res = lContainer;
|
||||
|
||||
// Get the URL matcher
|
||||
String re = getEmbeddedUrlRE();
|
||||
String allowRegex = getEmbeddedUrlRE();
|
||||
Perl5Matcher localMatcher = null;
|
||||
Pattern pattern = null;
|
||||
if (re.length() > 0) {
|
||||
Pattern allowPattern = null;
|
||||
if (allowRegex.length() > 0) {
|
||||
try {
|
||||
pattern = JMeterUtils.getPattern(re);
|
||||
allowPattern = JMeterUtils.getPattern(allowRegex);
|
||||
localMatcher = JMeterUtils.getMatcher();// don't fetch unless pattern compiles
|
||||
} catch (MalformedCachePatternException e) { // NOSONAR
|
||||
log.warn("Ignoring embedded URL match string: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
Pattern excludePattern = null;
|
||||
String excludeRegex = getEmbededUrlExcludeRE();
|
||||
if (excludeRegex.length() > 0) {
|
||||
try {
|
||||
excludePattern = JMeterUtils.getPattern(excludeRegex);
|
||||
if (localMatcher == null) {
|
||||
localMatcher = JMeterUtils.getMatcher();// don't fetch unless pattern compiles
|
||||
}
|
||||
} catch (MalformedCachePatternException e) { // NOSONAR
|
||||
log.warn("Ignoring embedded URL exclude string: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// For concurrent get resources
|
||||
final List<Callable<AsynSamplerResultHolder>> list = new ArrayList<>();
|
||||
|
|
@ -1396,8 +1422,12 @@ public abstract class HTTPSamplerBase extends AbstractSampler
|
|||
setParentSampleSuccess(res, false);
|
||||
continue;
|
||||
}
|
||||
log.debug("allowPattern: {}, excludePattern: {}, localMatcher: {}, url: {}", allowPattern, excludePattern, localMatcher, url);
|
||||
// I don't think localMatcher can be null here, but check just in case
|
||||
if (pattern != null && localMatcher != null && !localMatcher.matches(url.toString(), pattern)) {
|
||||
if (allowPattern != null && localMatcher != null && !localMatcher.matches(url.toString(), allowPattern)) {
|
||||
continue; // we have a pattern and the URL does not match, so skip it
|
||||
}
|
||||
if (excludePattern != null && localMatcher != null && localMatcher.matches(url.toString(), excludePattern)) {
|
||||
continue; // we have a pattern and the URL does not match, so skip it
|
||||
}
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import java.util.Map;
|
|||
import java.util.TimeZone;
|
||||
|
||||
import org.apache.jmeter.junit.JMeterTestCase;
|
||||
import org.apache.jmeter.protocol.http.control.CacheManager.CacheEntry;
|
||||
import org.apache.jmeter.protocol.http.sampler.HTTPSampleResult;
|
||||
import org.apache.jmeter.protocol.http.util.HTTPConstants;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
|
@ -281,8 +282,9 @@ public abstract class TestCacheManagerBase extends JMeterTestCase {
|
|||
assertNotNull(getThreadCacheEntry(LOCAL_HOST), "Should find entry");
|
||||
assertTrue(this.cacheManager.inCache(url), "Should find valid entry");
|
||||
sleepTill(start + age / 10 + 10);
|
||||
assertNotNull(getThreadCacheEntry(LOCAL_HOST), "Should find entry");
|
||||
assertFalse(this.cacheManager.inCache(url), "Should not find valid entry");
|
||||
CacheEntry cachedEntry = getThreadCacheEntry(LOCAL_HOST);
|
||||
assertNotNull(cachedEntry, "Should find entry");
|
||||
assertFalse(this.cacheManager.inCache(url), "Should not find valid entry. Found " + cachedEntry);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -631,7 +631,7 @@ public abstract class AbstractJDBCTestElement extends AbstractTestElement implem
|
|||
s.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
log.warn("Error closing Statement {}", s.toString(), e);
|
||||
log.warn("Error closing Statement {}", s, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ public class SynchronousTransportListener extends TransportAdapter {
|
|||
* Synchronized-method
|
||||
* <p>
|
||||
* Waits until {@link #finish()} was called and thus the end of the mail
|
||||
* sending was signalled.
|
||||
* sending was signaled.
|
||||
*
|
||||
* @throws InterruptedException
|
||||
* when interrupted while waiting with the lock
|
||||
|
|
@ -93,7 +93,7 @@ public class SynchronousTransportListener extends TransportAdapter {
|
|||
public void finish() {
|
||||
finished = true;
|
||||
synchronized(LOCK) {
|
||||
LOCK.notify();
|
||||
LOCK.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,9 +63,13 @@ Summary
|
|||
<ch_title>Core improvements</ch_title>
|
||||
<ch_title>Test Plan</ch_title>
|
||||
<ch_title>Scripting / Debugging enhancements</ch_title>
|
||||
<ch_title>UX improvements</ch_title>
|
||||
<ch_title>Functions</ch_title>
|
||||
-->
|
||||
<ch_title>UX improvements</ch_title>
|
||||
|
||||
<p>The splash screen is now application-modal rather than system-modal, so it does not block other
|
||||
applications when JMeter is starting up.</p>
|
||||
|
||||
<!-- =================== Incompatible changes =================== -->
|
||||
|
||||
<ch_section>Incompatible changes</ch_section>
|
||||
|
|
@ -77,6 +81,8 @@ Summary
|
|||
|
||||
<h3>HTTP Samplers and Test Script Recorder</h3>
|
||||
<ul>
|
||||
<li><bug>63527</bug>Implement a new setting to allow the exclusion of embedded URLs</li>
|
||||
<li><bug>64696</bug><pr>571</pr><pr>595</pr>Freestyle format for names in (Default)SamplerCreater. Based on a patch by Vincent Daburon (vdaburon at gmail.com)</li>
|
||||
</ul>
|
||||
|
||||
<h3>Other samplers</h3>
|
||||
|
|
@ -113,6 +119,7 @@ Summary
|
|||
<li><bug>64446</bug>Better parse curl commands with backslash at line endings and support <code>PUT</code> method with data arguments</li>
|
||||
<li><pr>599</pr>Ensure all buttons added to the toolbar behave/look consistently. Contributed by Jannis Weis</li>
|
||||
<li><bug>64581</bug>Allow SampleResult#setIgnore to influence behaviour on Sampler Error</li>
|
||||
<li><bug>64680</bug>Fall back to <code>JMETER_HOME</code> on startup to detect JMeter's installation directory</li>
|
||||
</ul>
|
||||
|
||||
<ch_section>Non-functional changes</ch_section>
|
||||
|
|
@ -121,11 +128,27 @@ Summary
|
|||
<li><bug>64454</bug>More precise error message, when no datasource value can be found in JDBC sampler</li>
|
||||
<li><bug>64440</bug>Log exeptions reported via <code>JMeterUtils#reportToUser</code> even when in GUI mode</li>
|
||||
<li><pr>591</pr>Remove deprecated sudo flag from travis file. Deng Liming (liming.d.pro at gmail.com)</li>
|
||||
<li>Updated Darklaf to 2.4.2 (from 2.1.1)</li>
|
||||
<li>Updated Darklaf to 2.4.5 (from 2.1.1)</li>
|
||||
<li>Updated Groovy to 3.0.5 (from 3.0.3)</li>
|
||||
<li><pr>596</pr>Use neutral words in documentation</li>
|
||||
<li><bug>63809</bug><pr>557</pr>Updated commons-collections to 4.4 (from 3.2.2) while keeping the jars for the old commons-collections 3.x for compatibility</li>
|
||||
<li><pr>598</pr>Add another option for creating diffs to the building page. Contributed by jmetertea (github.com/jmetertea)</li>
|
||||
<li><pr>609</pr>Make use of newer API for darklaf installation. Jannis Weis</li>
|
||||
<li><pr>612</pr>Correct typos in <code>README.me</code>. Based on patches by Pooja Chandak (poojachandak002 at gmail.com)</li>
|
||||
<li><pr>613</pr>Add documentation for Darklaf properties. Jannis Weis</li>
|
||||
<li>Update SpotBugs to 4.1.2 (from 4.1.1), upgrade spotbugs-gradle-plugin to 4.5.0 (from 2.0.0)</li>
|
||||
<li>Update org.sonarqube Gradle plugin to 3.0 (from 2.7.1)</li>
|
||||
<li>Update Apache ActiveMQ to 5.16.0 (from 5.15.11)</li>
|
||||
<li>Update Bouncycastle to 1.66 (from 1.64)</li>
|
||||
<li>Update Apache commons-io to 2.7 (from 2.6)</li>
|
||||
<li>Update Apache commons-lang3 to 3.11 (from 3.10)</li>
|
||||
<li>Update Apache commons-net to 3.7 (from 3.6)</li>
|
||||
<li>Update Apache commons-pool2 to 2.8.1 (from 2.8.0)</li>
|
||||
<li>Update Apache commons-text to 1.9 (from 1.8)</li>
|
||||
<li>Update equalsverifier to 3.4.2 (from 3.1.13)</li>
|
||||
<li>Update junit5 to 5.6.2 (from 5.6.0)</li>
|
||||
<li>Update Apache log4j2 to 2.13.3 (from 2.13.1)</li>
|
||||
<li>Update rsyntaxtextarea to 3.1.1 (from 3.1.0)</li>
|
||||
</ul>
|
||||
|
||||
<!-- =================== Bug fixes =================== -->
|
||||
|
|
@ -135,6 +158,7 @@ Summary
|
|||
<h3>HTTP Samplers and Test Script Recorder</h3>
|
||||
<ul>
|
||||
<li><bug>64479</bug>Regression: HTTP(s) Script Recorder prevents proper shutdown in non-GUI mode</li>
|
||||
<li><bug>64653</bug>Exclude Javascript and JSON from parsing for charsets from forms by proxy</li>
|
||||
</ul>
|
||||
|
||||
<h3>Other Samplers</h3>
|
||||
|
|
@ -172,6 +196,7 @@ Summary
|
|||
|
||||
<h3>Documentation</h3>
|
||||
<ul>
|
||||
<li><pr>571</pr>Correct documented name of generated CA when using proxy script recorder. Part of a bigger PR. Vincent Daburon (vdaburon at gmail.com)</li>
|
||||
</ul>
|
||||
|
||||
<h3>General</h3>
|
||||
|
|
@ -204,6 +229,8 @@ Summary
|
|||
<li><a href="https://github.com/topicus-pw-dvdouden">Daniel van den Ouden</a></li>
|
||||
<li><a href="https://ubikloadpack.com" >Ubik Load Pack</a></li>
|
||||
<li>Till Neunast (https://github.com/tilln)</li>
|
||||
<li>Pooja Chandak (poojachandak002 at gmail.com)</li>
|
||||
<li>Vincent Daburon (vdaburon at gmail.com)</li>
|
||||
</ul>
|
||||
<p>We also thank bug reporters who helped us improve JMeter.</p>
|
||||
<ul>
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 19 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 18 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 20 KiB |
|
|
@ -36,7 +36,7 @@
|
|||
<note><b>These builds should not be used in production.</b></note>
|
||||
|
||||
<h2>Last Build status on Jenkins</h2>
|
||||
<a href='https://builds.apache.org/job/JMeter-trunk/'><img src='https://builds.apache.org/buildStatus/icon?job=JMeter-trunk' /></a>
|
||||
<a href='https://ci-builds.apache.org/job/JMeter/job/JMeter-trunk/'><img src='https://ci-builds.apache.org/buildStatus/icon?job=JMeter%2FJMeter-trunk'/></a>
|
||||
|
||||
<h2>Last Quality Report on Sonar</h2>
|
||||
<a href="https://sonarcloud.io/dashboard?id=JMeter">Apache JMeter quality report</a>
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
<p>JMeter CI builds are currently run by Jenkins and Buildbot</p>
|
||||
<p>These are located at:
|
||||
<ul>
|
||||
<li><a href="https://builds.apache.org/job/JMeter-trunk/lastSuccessfulBuild/artifact/src/dist/build/distributions/">Last Successful Jenkins build for JMeter-trunk</a></li>
|
||||
<li><a href="https://ci-builds.apache.org/job/JMeter/job/JMeter-trunk/lastSuccessfulBuild/artifact/src/dist/build/distributions/">Last Successful Jenkins build for JMeter-trunk</a></li>
|
||||
<li><a href="http://ci.apache.org/projects/jmeter/nightlies/">Buildbot nightly builds for JMeter-trunk</a></li>
|
||||
<li><a href="https://repository.apache.org/content/repositories/snapshots/org/apache/jmeter/">Maven Snapshots (Buildbot nightly builds)</a></li>
|
||||
</ul>
|
||||
|
|
@ -55,10 +55,10 @@
|
|||
JMeter is distributed as a set of zip (or tar-gz) archive files as are the released versions.
|
||||
You can find the bundles:
|
||||
<ul>
|
||||
<li>apache-jmeter-{SVN revision}.zip - Bundle in ZIP format</li>
|
||||
<li>apache-jmeter-{SVN revision}.tgz - Bundle in TAR GZIP format</li>
|
||||
<li>apache-jmeter-{SVN revision}_src.zip - Sources in ZIP format</li>
|
||||
<li>apache-jmeter-{SVN revision}_src.tgz - Sources in TAR GZIP format</li>
|
||||
<li>{git revision}/apache-jmeter-{version}.zip - Bundle in ZIP format</li>
|
||||
<li>{git revision}/apache-jmeter-{version}.tgz - Bundle in TAR GZIP format</li>
|
||||
<li>{git revision}/apache-jmeter-{version}_src.zip - Sources in ZIP format</li>
|
||||
<li>{git revision}/apache-jmeter-{version}_src.tgz - Sources in TAR GZIP format</li>
|
||||
</ul>
|
||||
For each file you will also find a hash (MD5, SHA) that allows you to test its integrity.
|
||||
</p>
|
||||
|
|
|
|||
|
|
@ -331,10 +331,15 @@ and send HTTP/HTTPS requests for all images, Java applets, JavaScript files, CSS
|
|||
Instead, the 32 character MD5 hash of the data is calculated and stored instead.
|
||||
This is intended for testing large amounts of data.
|
||||
</property>
|
||||
<property name="Embedded URLs must match:" required="No">
|
||||
<property name="URLs must match:" required="No">
|
||||
If present, this must be a regular expression that is used to match against any embedded URLs found.
|
||||
So if you only want to download embedded resources from <code>http://example.com/</code>, use the expression:
|
||||
<code>http://example\.com/.*</code>
|
||||
So if you only want to download embedded resources from <code>http://example.invalid/</code>, use the expression:
|
||||
<code>http://example\.invalid/.*</code>
|
||||
</property>
|
||||
<property name="URLs must not match:" required="No">
|
||||
If present, this must be a regular expression that is used to filter out any embedded URLs found.
|
||||
So if you don't want to download PNG or SVG files from any source, use the expression:
|
||||
<code>.*\.(?i:svg|png)</code>
|
||||
</property>
|
||||
<property name="Use concurrent pool" required="No">Use a pool of concurrent connections to get embedded resources.</property>
|
||||
<property name="Size" required="No">Pool size for concurrent connections used to get embedded resources.</property>
|
||||
|
|
@ -3898,10 +3903,15 @@ and send HTTP/HTTPS requests for all images, Java applets, JavaScript files, CSS
|
|||
</property>
|
||||
<property name="Use concurrent pool" required="No">Use a pool of concurrent connections to get embedded resources.</property>
|
||||
<property name="Size" required="No">Pool size for concurrent connections used to get embedded resources.</property>
|
||||
<property name="Embedded URLs must match:" required="No">
|
||||
<property name="URLs must match:" required="No">
|
||||
If present, this must be a regular expression that is used to match against any embedded URLs found.
|
||||
So if you only want to download embedded resources from <code>http://example.com/</code>, use the expression:
|
||||
<code>http://example\.com/.*</code>
|
||||
So if you only want to download embedded resources from <code>http://example.invalid/</code>, use the expression:
|
||||
<code>http://example\.invalid/.*</code>
|
||||
</property>
|
||||
<property name="URLs must not match:" required="No">
|
||||
If present, this must be a regular expression that is used to filter out any embedded URLs found.
|
||||
So if you don't want to download PNG or SVG files from any source, use the expression:
|
||||
<code>.*\.(?i:svg|png)</code>
|
||||
</property>
|
||||
</properties>
|
||||
<note>
|
||||
|
|
@ -6531,7 +6541,7 @@ Behaviour can be modified with some properties by setting in <code>user.properti
|
|||
</p>
|
||||
</component>
|
||||
|
||||
<component name="HTTP(S) Test Script Recorder" was="HTTP Proxy Server" index="§-num;.9.5" width="1052" height="694" screenshot="proxy_control.png">
|
||||
<component name="HTTP(S) Test Script Recorder" was="HTTP Proxy Server" index="§-num;.9.5" width="983" height="702" screenshot="proxy_control.png">
|
||||
<description><p>The HTTP(S) Test Script Recorder allows JMeter to intercept and record your actions while you browse your web application
|
||||
with your normal browser. JMeter will create test sample objects and store them
|
||||
directly into your test plan as you go (so you can view samples interactively while you make them).<br/>
|
||||
|
|
@ -6607,9 +6617,9 @@ As a consequence:
|
|||
<li>The browser should display a dialogue asking if you want to accept the certificate or not. For example:
|
||||
<source>
|
||||
1) The server's name "<code>www.example.com</code>" does not match the certificate's name
|
||||
"<code>JMeter Proxy (DO NOT TRUST)</code>". Somebody may be trying to eavesdrop on you.
|
||||
2) The certificate for "<code>JMeter Proxy (DO NOT TRUST)</code>" is signed by the unknown Certificate Authority
|
||||
"<code>JMeter Proxy (DO NOT TRUST)</code>". It is not possible to verify that this is a valid certificate.
|
||||
"<code>_ JMeter Root CA for recording (INSTALL ONLY IF IT S YOURS)</code>". Somebody may be trying to eavesdrop on you.
|
||||
2) The certificate for "<code>_ JMeter Root CA for recording (INSTALL ONLY IF IT S YOURS)</code>" is signed by the unknown Certificate Authority
|
||||
"<code>_ JMeter Root CA for recording (INSTALL ONLY IF IT S YOURS)</code>". It is not possible to verify that this is a valid certificate.
|
||||
</source>
|
||||
You will need to accept the certificate in order to allow the JMeter Proxy to intercept the SSL traffic in order to
|
||||
record it.
|
||||
|
|
@ -6735,6 +6745,9 @@ Both Chrome and Internet Explorer use the same trust store for certificates.
|
|||
<property name="Add Assertions" required="Yes">Add a blank assertion to each sampler?</property>
|
||||
<property name="Regex Matching" required="Yes">Use Regex Matching when replacing variables? If checked replacement will use word boundaries, i.e. it will only replace word matching values of variable, not part of a word. A word boundary follows Perl5 definition and is equivalent to <code>\b</code>. More information below in the paragraph about "<code>User Defined Variable replacement</code>".</property>
|
||||
<property name="Prefix/Transaction name" required="No">Add a prefix to sampler name during recording (Prefix mode). Or replace sampler name by user chosen name (Transaction name)</property>
|
||||
<property name="Naming scheme" required="No">Select the naming scheme for sampler names during recording. Default is <code>Transaction name</code></property>
|
||||
<property name="Naming format" required="No">If <code>Use format string</code> is selected as naming scheme, a freestyle format can be given. Placeholders for the transaction name, path and counter can be given by <code>#{name}</code>, <code>#{path}</code> and <code>#{counter}</code>. A simple format could be "<code>#{name}-#{counter}</code>", which would be equivalent to the numbered default naming scheme. For more complex formatting Java formatting for MessageFormat can be used, as in "<code>#{counter,number,000}: #{name}-#{path}</code>", which would print the counter filled with up to three zeroes. Default is an empty string.</property>
|
||||
<property name="Counter start value" required="No">Can be used to reset the counter to a given value. Note, that the next sample will first increment and then use the value. If the first sampler should start with <code>1</code>, reset the counter to <code>0</code>.</property>
|
||||
<property name="Create new transaction after request (ms)">Inactivity time between two requests needed to consider them in two separate groups.</property>
|
||||
<property name="Type" required="Yes">Which type of sampler to generate (the HTTPClient default or Java)</property>
|
||||
<property name="Redirect Automatically" required="Yes">Set Redirect Automatically in the generated samplers?</property>
|
||||
|
|
|
|||
|
|
@ -196,6 +196,17 @@ Defaults to: <code>true</code>
|
|||
Defaults to: <code>500</code></property>
|
||||
</properties>
|
||||
</section>
|
||||
<section name="§-num;.4.1 Darklaf configuration" anchor="darklaf_config">
|
||||
<properties>
|
||||
<property name="darklaf.decorations">
|
||||
Enables custom window chrome when using a Darklaf Look And Feel.
|
||||
Defaults to: <code>false</code></property>
|
||||
<property name="darklaf.unifiedMenuBar">
|
||||
Enables the unified menubar on Windows when using a Darklaf Look and Feel.<br/>
|
||||
This property only has an effect if <code>darklaf.native</code> is <code>true</code>.
|
||||
Defaults to: <code>true</code></property>
|
||||
</properties>
|
||||
</section>
|
||||
<section name="§-num;.5 Toolbar display" anchor="toolbar_display">
|
||||
<properties>
|
||||
<property name="jmeter.toolbar.icons">
|
||||
|
|
|
|||
Loading…
Reference in New Issue