Updated the answer to fix a bug in the code and to improve the logging
This could be another solution.

- Initialize the properties.
Add a SetUp Thread Group. Add a JSR223 Sampler to the SetUp Thread Group.
Then add the following code to initialize the properties.
props.put("total_requests","0")
props.put("total_requests_exceeding_limit","0")
- Add a JSR223 Post Processor at the top level.
This will ensure the element is applied to all the samplers in the test plan
- Add the following parameters to the JSR223 Post Processor
${__P(stop_test_exceeding_percentile_error,true)} ${__P(percentage_limit,95)} ${__P(response_time_limit_in_seconds,1)}
- Add the following script to the JSR223 Postprocessor.
long rampupTime=60000
long requestCountToStartChecking=50
long startTimeInMillis=vars.get("TESTSTART.MS").toLong()
long currentTimeInMillis = new Date().getTime()
long currentTestDurationInMillis=currentTimeInMillis-startTimeInMillis
log.info("currentTestDurationInMillis ${currentTestDurationInMillis}")
if(args[0].toBoolean() && currentTestDurationInMillis> rampupTime ){
def total_requests_exceeding_limit=0
def percentageOfRequestExceedingLimit=0
int percentile_limit=args[1].toInteger()
int response_time_limit_in_seconds=args[2].toInteger()
long response_time_limit_in_milliseconds=response_time_limit_in_seconds*1000
def totalRequests = props.get("total_requests").toInteger() + 1
props.put("total_requests",totalRequests.toString())
if(prev.getTime() > response_time_limit_in_milliseconds){
total_requests_exceeding_limit= props.get("total_requests_exceeding_limit").toInteger() + 1
percentageOfRequestExceedingLimit = ((total_requests_exceeding_limit/totalRequests)* 100).round()
if (percentageOfRequestExceedingLimit> percentile_limit && totalRequests>requestCountToStartChecking) {
log.info("Requests execeeding ${response_time_limit_in_milliseconds} has reached ${percentageOfRequestExceedingLimit}")
log.info("Stopping the test")
prev.setStopTest(true)
log.info("Stopped the test")
}
props.put("total_requests_exceeding_limit",total_requests_exceeding_limit.toString())
} else {
total_requests_exceeding_limit= props.get("total_requests_exceeding_limit").toInteger()
percentageOfRequestExceedingLimit = ( (total_requests_exceeding_limit/totalRequests)* 100).round()
}
log.info("totalRequests ${totalRequests} total_requests_exceeding_limit ${total_requests_exceeding_limit} percentageOfRequestExceedingLimit ${percentageOfRequestExceedingLimit} ")
} else {
prev.setIgnore()
}
- The script will ignore the samplers during the ramp-up time. Rampup period should be set in the script at the moment
- The response time threshold, response percentage limit, etc can be configured through the properties/parameters
- The percentage will be checked after a predefined number of requests from the ramp-up time to avoid test stopping immediately when the first response time is greater than the configured value.
- The script can be improved further to wait for a pre-defined period with a response percentage exceeding the limit.
- Need to handle the synchronization issues. You can use Inter-Thread communication plugin to ensure the same values are not read by different threads.