jmeter - second post request is not using the JSESSIONID created on my log in post request

marlon brillantes picture marlon brillantes · Feb 18, 2014 · Viewed 17.2k times · Source

I was successfully able to send a POST request for my log in end point and a JSESSIONID was created. I know the JSESSIONID is kept by the HTTP Cookie Manager that I have at the top of my thread because I see it being used on several GET requests I have in my thread.

But when I attempt a POST request it does not use the JSESSIONID and creates its own ID. Below are my settings:

Protocol: https Method: POST -Use KeppAlive {"json":"params"}

Sampler Result: Thread Name: sim test 1-1 Sample Start: 2014-02-18 15:42:42 EST Load time: 95 Latency: 95 Size in bytes: 239 Headers size in bytes: 239 Body size in bytes: 0 Sample Count: 1 Error Count: 0 Response code: 302 Response message: Found

Response headers: HTTP/1.1 302 Found Server: Apache-Coyote/1.1 Set-Cookie: JSESSIONID=F16BF82FD28A84F6E28DDE30DECDC48C; Path=/; Secure; HttpOnly Location: https : //api.zzzz com/site/needsAuth Content-Length: 0 Date: Tue, 18 Feb 2014 20:42:42 GMT

HTTPSampleResult fields: ContentType: DataEncoding: null

Request: POST https : //api.zzz com/rest/members/347/passengers

POST data: {"relationshipToMember":null,"authorizedToBook":false,"authorizedToFly":true,"authorizedToGetInfo":false,"passenger":{"firstName":"Mighty","middleName":null,"lastName":"Max","dateOfBirth": 1380857200000}}

[no cookies]

Request Headers: Connection: keep-alive Content-Type: application/json Content-Length: 204 Host: api.zzz.com User-Agent: Apache-HttpClient/4.2.6 (java 1.5)

-Note: I don't know if I am doing my GET requests correctly but they are working. They have Follow Redirects on and it first goes to http : //api.zzz... - 302 Found, then goes https : //api.zzz...

edit: I found this which is exactly my problem: Cookie Manager of Apache JMeter doesn't add the cookie to POST request, but I do not understand his solution if anyone can elaborate on the steps.

UPDATE Solved: I had to keep the same Server Name as my Log in POST and change my Path

Answer

Dmitri T picture Dmitri T · Feb 19, 2014

UPDATE!!!

Haven't noticed your https protocol.

All you need is to set either CookieManager.save.cookies=true property in your jmeter.properties file or add it as an argument to JMeter command line as

jmeter -JCookieManager.save.cookies=true -n -t path_to_jmx_script.jmx -l path_to_log_file.jtl

Leaving the rest of my response just in case anyone else will need it as a guide on how to share JMeter Cookies across different Thread Groups.

I'm not able to reproduce your use case in my environment using following scenarios:

  • HTTP Cookie Manager lives under Test Plan (same level as Thread Group(s))
  • HTTP Cookie Manager lives under Thread Group (same level as Samplers)

It's only reproducible if HTTP Cookie Manager added as a child of Login request. If it's your case - move it up 1 level to broaden it's scope.

If for some reason it doesn't help - see below for possible workaround details.

Your response code 204 doesn't sound like an error to me. I guess that the server would rather respond with something like 401 or 403 if there were problems with cookie-based authentication.

If you explicitly need to set cookie it still can be done via i.e. Beanshell

You need to do the following:

  1. If you're going to share cookies between different thread groups or need them as JMeter variables for any other reason set CookieManager.save.cookies=true property either in jmeter.properties file or specify it during JMeter startup as jmeter -JCookieManager.save.cookies=true
  2. Add Beanshell Post Processor to your Login Request with following code:

    import org.apache.jmeter.protocol.http.control.CookieManager;
    
    CookieManager manager = ctx.getCurrentSampler().getProperty("HTTPSampler.cookie_manager").getObjectValue();
    
    props.put("cookiecount", String.valueOf(manager.getCookieCount()));
    
    for (int i = 0; i < manager.getCookieCount(); i++) {
        props.put("cookie_name" + i, manager.get(i).getName());
        props.put("cookie_value" + i, manager.get(i).getValue());
        props.put("cookie_domain" + i, manager.get(i).getDomain());
        props.put("cookie_path" + i, manager.get(i).getPath());
        props.put("cookie_expires" + i, String.valueOf(manager.get(i).getExpires()));
        props.put("cookie_secure" + i, String.valueOf(manager.get(i).getSecure()));
    }
    
  3. Add Beanshell Pre Processor to your POST request with following code:

    import org.apache.jmeter.protocol.http.control.CookieManager;
    import org.apache.jmeter.protocol.http.control.Cookie;
    import org.apache.jmeter.testelement.property.JMeterProperty;
    
    
    CookieManager manager = ctx.getCurrentSampler().getProperty("HTTPSampler.cookie_manager").getObjectValue();
    
    int count = Integer.parseInt(props.getProperty("cookiecount"));
    
    for (int i = 0; i < count; i++) {
        Cookie cookie = new Cookie(props.getProperty("cookie_name" + i), props.getProperty("cookie_value" + i),
                props.getProperty("cookie_domain" + i), props.getProperty("cookie_path" + i),
                Boolean.parseBoolean(props.getProperty("cookie_secure" + i)),
                Long.parseLong(props.getProperty("cookie_expires" + i)));
        manager.add(cookie);
    }
    
    JMeterProperty cookieprop = ctx.getCurrentSampler().getProperty("HTTPSampler.cookie_manager");
    
    cookieprop.setObjectValue(manager);
    
    ctx.getCurrentSampler().setProperty(cookieprop);
    

Explanation:

The code at point 2 fetches all available cookies from HTTP Cookie Manager and stores them to JMeter Properties prefixed with cookie_

The code at point 3 reads all properties prefixed with cookie_, constructs JMeter Cookies from them and adds them to HTTP Cookie Manager.

See How to use BeanShell guide for more information on extending JMeter via scripting.