0

I have two HTTP GET requests in Jmeter. The first one calls to a server and gets a CSV that holds some user data. Using a JSR223 Post processor, I am , mapping that data onto a JSON and assigning the values to three variables to be passed onto the second request. The script for doing that is below.

import org.apache.commons.io.IOUtils
import java.nio.charset.StandardCharsets
import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
import groovy.json.JsonOutput

def response = prev.getResponseDataAsString()
def lines = response.split('\n')

def userData = []
for (int i = 1; i < lines.length; i++) {
    def line = lines[i]
    def tokens = line.split(',')
    userData << [login_type: tokens[0], username: tokens[1], password: tokens[2]]
}

def jsonString = JsonOutput.toJson(userData)
def jsonSlurper = new JsonSlurper()
def jsonMap = jsonSlurper.parseText(jsonString)

for (int i = 1; i <= Math.min(jsonMap.size(), Integer.parseInt("${__P(threads)}")); i++) {
    if(i < jsonMap.size()){
        vars.put("login_type" , jsonMap[Integer.parseInt("${__threadNum}")-1].login_type)
        vars.put("username" , jsonMap[Integer.parseInt("${__threadNum}")-1].username)
        vars.put("password" , jsonMap[Integer.parseInt("${__threadNum}")-1].password)
    }
}

I pass these three variables in the next request body as {"login_type":"${login_type}","username":"${username}","password":"${password}"}

When running the script i'm getting the response as 400 for second request even though i can see the data is getting passed.

POST data:
{"login_type":"data","username":"data","password":"data"}

I tried the second request by manually giving the login data instead of the variables and it works. {"login_type":"EMAIL","username":"username","password":"pass"}

The only difference i see on both attempts is in the request header where the Content-Length: 83 is shown for when manually sending data and Content-Length: 84 is shown for when passing the data from the groovy script. Though i don't think that's what causing the issue. Can anyone explain as to why this is happening and how to fix this.

I looked into the requests and the POST request body coming from the groovy script has a line break at the end.

{"login_type":"login_type","username":"username","password":"password
"}

Hence causing the request to throw a 400. How can i send the body data in one line?

coder
  • 3
  • 3

1 Answers1

0

Maybe there is some invisible character like whitespace or line break which is expected by your system under test and which you're not sending when you're populating variables in Groovy.

Use a sniffer tool like Wireshark or Fiddler to compare both requests byte by byte and amend your JMeter configuration or Groovy code to 100% match the "manual" request.

Also regarding your usage of JMeter Functions in the script, according to JSR223 Sampler documentation:

The JSR223 test elements have a feature (compilation) that can significantly increase performance. To benefit from this feature:

  • Use Script files instead of inlining them. This will make JMeter compile them if this feature is available on ScriptEngine and cache them.
  • Or Use Script Text and check Cache compiled script if available property.

When using this feature, ensure your script code does not use JMeter variables or JMeter function calls directly in script code as caching would only cache first replacement. Instead use script parameters.

So replace:

  • ${__P(threads)} with props.get('threads')
  • ${__threadNum} with ctx.getThreadNum()

See Top 8 JMeter Java Classes You Should Be Using with Groovy for more information on what do these props and ctx guys mean.

Dmitri T
  • 159,985
  • 5
  • 83
  • 133
  • There is a difference on the request body. The problem is a line break. Any idea how to fix this? – coder Jan 27 '23 at 12:08