13 Replies Latest reply on Aug 7, 2009 1:48 PM by Coral Featherstone

    JMeter Seam cid problem

    Danny Bollaert Newbie

      I have bean trying to load test a seam application. But I am having troubles configuring my jmeter.


      I have tried extracting cid , jsessionid and javax.faces.ViewState. The cid is configured inside my url.


      The webapplication  failles after I load the first page and try to post it to the second page. The problem is, I can't get a new session. I already have added a cookie manager and it deletes my cookies each iteratation.


      Some code or a small example would come in handy.


      Thanks in advance.

        • 1. Re: JMeter Seam cid problem
          Keith Naas Novice

          Can you post your JMeter Test Plan?  I've never used it, but it would be a big help if we could look at how you are using it.

          • 2. Re: JMeter Seam cid problem
            Denis Forveille Novice

            It works perfectly for us.
            We dont extract cid, instead we configure JMeter ro follow redirect as the cid are always used during redirections
            For jsessionid, our websphere store teh session id in a cookie so we just added a acookie handler in our jmeter test
            And indeed we had to extract/forward the ViewStates parameters
            With all of that, everything works well

            • 3. Re: JMeter Seam cid problem
              Danny Bollaert Newbie

              could you please provide an example how exactly you extract your viewstates parms.


              Thanks in advance

              • 4. Re: JMeter Seam cid problem
                Marcell Newbie

                I am also running in problems to load test. I am not being able to extract the cid in a redirect.


                Which configurations did you use?


                Tnx

                • 5. Re: JMeter Seam cid problem
                  Peter Johnson Master

                  With JMeter, there does not appear to be a cid problem. Here is what I did.


                  My config:



                  • JBossAS 4.2.2.GA

                  • Seam 2.0.0.GA

                  • JMeter 2.3.1

                  • JDK 1.5

                  • SeamBay example from Seam



                  Here is how I created my Script:



                  In JMeter, I added a Thread Group and Recording Controller to the Test Plan. I configured an HTTP Proxy Server: Port = 8888; Grouping = Put each group in a new controller; defaults for everything else.
                  I set my browser to use the proxy. Then I went to the home page, clicked on the register link, provided registration info, and back on the home page logged out.
                  Back in JMeter, I made these changes:



                  • In the third Simple Controller, named /seam-bay/register.seam, the first HTTP Request contains a javax.faces.ViewState parameter. I set its value to “${VIEWSTATE}”. (This request was a POST.)

                  • In the same HTTP Request, changed the values for the parameters j_id7:username, j_id7:password, and j_id7:confirm.

                  • For the immediately prior HTTP Request, which is a GET request, I added a Regular Expression Extractor: Reference Name = VIEWSTATE; Regular Expression =



                  id="javax.faces.ViewState" value="([^"]*)"



                  ; Template = $1$; Match No: 1



                  • Added an HTTP Cookie Manager to the Recording Controller

                  • Added a View Results Tree to the Recording Controller. Change the configuration  to also capture: Save Response Headers, Save Request Header, Save Response Data. (Did this mainly so that I could examine the results of the test.)



                  Some observations



                  I did not have to do anything with cids. One of my HTTP requests in the script looks like http://xxx:8080/seam-bay/home.seam?cid=118, but when I run the script I see that this request is submitted as http://xxx:8080/seam-bay/home.seam?cid=130. Apparently, JMeter is smart enough to grab the Location response header returned the prior request and use that in place of the recorder URL, thereby forwarding the correct cid.


                  Caveat: So far I have run this script with a single thread only. My next task is to try multiple threads. Hopefully I will be more successful that I was with Grinder. When I have a multipel thread script running, I will post my results.

                  • 6. Re: JMeter Seam cid problem
                    Marcell Newbie

                    Well, we did it already, and look what we found:


                    http://jira.jboss.com/jira/browse/JBSEAM-2864


                    If you had better lucky please tell me what I am doing wrong.

                    • 7. Re: JMeter Seam cid problem
                      Peter Johnson Master

                      I was wrong - you have to capture the cid and forward it.


                      Here is what my recorded script looked like:



                      1. POST that provides the new user's id and password

                      2. GET for the response page (happens to be home page)



                      And here is what I got when I ran the recorded script:



                      1. POST that provides the new user's id and password

                      2. GET for the response page, with correct cid

                      3. GET for the response page, with recorded cid



                      In my script, the POST request had Follow Redirects checked, so the first GET, with the correct cid, during the run was the automatic redirect. Apparently the second GET is being ignored or an error is being generated but was ignored, perhaps because was of no consequence.


                      My script worked only because I have only one GET request that required the cid. I now have another script with a longer running conversation (half dozen POST/GET combos), and when I ran the script I got new cids for each one (when I should have had the same cid).


                      The solution? After the first POST, the response message will contain a Location value that contains the URL with the cid. So I applied a Regular Expression Extractor to the HTTP Request that did the POST. I gave these properties:



                      • Reference name - CID

                      • Regular expression -



                      cid=(\d+)




                      • Template - $1$

                      • Match No. - 1

                      • Default Value - 99999



                      Then for each GET that needs this cid I provide a parameter whose value is ${CID}. Now the cid gets properly propagated to the requests. Of course, if I notice that the cid changes during the recording (I have 2 or more conversations), I just recapture the cid each time I expect it to change. Alternately, I could capture the cid after every POST.


                      That's all for now. I'll post more as I learn more.

                      • 8. Re: JMeter Seam cid problem
                        Peter Johnson Master

                        I forgot to mention that I also had to turn off Follow Redirects for each POST. This prevents the GET of the response from being invoked twice. I guess I could have instead removed the GET request from my script.

                        • 9. Re: JMeter Seam cid problem
                          Peter Johnson Master

                          As I mentioned earlier, when I recorded my script, each POST was responded to with a 302 result with a Location that was used for the following GET. I found out that either disabling the recorded GET request and leaving the Follow Redirect set on the POST, or turning off the Follow Redirect on the POST and leaving the recorded GET enabled worked. For the latter, I had to use a regex post processor to extract the cid from the Location in the response to the POST, and use that as the cid for the GET.


                          Did you follow that? If not, here is a pseudo-excerpt from my script for registering an item to sell (using the latter scenario from the previous paragraph):



                          • POST sell.seam, parameters include VIEWSTATE extracted from prior request

                          • RegEx Extractor to get CID out of Location in header of 302 result

                          • GET sell.seam, parameter is cid equals ${CID}

                          • RegEx Extractor to get VIEWSTATE out of result body



                          This pattern is pretty much repeated for every page of the 'sell an item' wizard.


                          Runs great with one user. Fails miserably with multiple users. And I figured out why. For some reason, most of the POST requests are not responding with HTTP 302 responses. Instead, they are responding with HTTP 200. But the 200 doesn't have a redirect location, and therefore the script cannot extract the cid which it desperately requires for the following GET. And on the next request I get a NPE, probably the same one reported in JBSEAM-2864.


                          Of course, disabling the GET and setting Follow Redirect also doesn't work, but for different reasons. In that case, the GET never takes place, because the POST responded with a 200, not a 302, and thus the VIEWSTATE is not captured and forwarded to the next POST. And this situation leads to an invalid string index exception.


                          So now I have to figure out why most of the POST requests are not responding with 302s.

                          • 10. Re: JMeter Seam cid problem
                            Marcell Newbie

                            Hi Peter,


                            I am not the person who is doing loading testing here however, from what I am seeing, we are having same problems and some different ones.


                            The bug I reported does not have anything to do with extracting viewstates or cids because it only do get requests in the same conversation. The JBSEAM-2864 is all about the injection not working with simultaneous clients. It is a very simple application that explores the seam core and does not work. I am really concerned with this! Unfortunately, for me, it is easy to drop Seam then try to fix what he proposes to do (it is the core that is not working).


                            Tomorrow I will ask our tester to post here.

                            • 11. Re: JMeter Seam cid problem
                              Peter Johnson Master

                              What a long, strange trip it's been...


                              I added logging code to pinpoint where things were fgoing wrong. I added the thread info to the log so I could differentiate between requests. I logged the request url and all the parameters. I added an extra parameter whose value was the JMeter thread so that I could match jbossas threads to jmeter users.


                              I also added logging for the response so I would know when and who changed the response value to 302.


                              I verified a lot of data between the jmeter reports and the jbossas log to make sure that jmeter was supplying the correct information. All this was done doing single user runs.


                              Once I was satisfied that things were in order, I did a 4 user run. And of course, the problem moved. So let me digress a little.


                              As I mentioned before, I am scripting the SeamBay app that comes with Seam. My JMeter script signs in a random user, and then registers an item to sell, and then logs back out. Earlier (before adding the extra logging), the problem occurred during registering an item to sell phase of the script. With the extra logging, a problem showed up during used signin. Being a firm believer in tackling the initial problem first, I decided to added yet more logging to track that down.


                              At one point I added too much logging, and suddenly signin was working again. This lead me to suspect a timing issue. So I backed off on some of the logging and finally narrowed the problem down. It is a timing issue.


                              Assume that two users attempt to sign in at exactly the same time, and this is the first time any user has signed in. Each user's request is handled by a separate jbossas thread. What follows is an excerpt of the code that is processed (I abbreviate org.jboss.seam as simply seam, and all line numbers are from the Seam 2.0.1.GA source):



                              1. seam.security.Configuration.instance() is called to get the security config instance (line 73)

                              2. seam.Component.getInstance(org.jboss.seam.security.configuration) calls the next getInstance (line 1834)

                              3. seam.Component.getInstance(...), in line 1839 the call to Contexts.lookupInStatefulContexts(name) returns null because the security config instance has not yet been created, then line 1840 calls the next getInstance(...)

                              4. seam.Component.getInstance(...), in line 1861, create is true and result is null, so getInstanceFromFactory() is called at line 1863

                              5. seam.Component.getInstanceFromFactory(..), eventually gets to line 1927, where handleFactoryMethodResult() is called



                              Now, the first thread to handleFactoryMethodResult(), when it gets to line 1939, the call to Contexts.lookupInStatefulContexts() returns null because the security config instance is not yet created. Which is fine because the 'create' flag is set to true so the security config gets created (back in getInstance, at line 1873)and placed into the APPLICATION context.


                              Then the second htread gets to handleFactoryMethodResult() line 1939, but its call to Contexts.lookupInStatefulContexts() returns the object created by the first thread. This causes the code to branch to the else statement at line 1949, and because the scope is not UNSPECIFIED, the excpetion that I was seeing gets thrown.


                              The problem is that after the Contexts.lookupInStatefulContexts(name) at line 1839, the APPLICATION context (at least) should be locked until that getInstance method exists, or the code in handleFactoryMethod needs to be a little more understanding of unexpected objects suddenly show up. I image that the former is the correct mechanism.


                              Q.E.D.


                              I could not find a JIRA issue for this, so I will create one.


                              Unfortunately, I suspect that once I code around this timing hole I will just end up finding the next one. And I am now out of time . I have spent a week playing around with this and it is preventing me from getting my work done. So if my patch doesn't work, I will probably have to drop Seam and look elsewhere. What a pity.

                              • 12. Re: JMeter Seam cid problem
                                Peter Johnson Master

                                The problem (timing issue when accessing global components from multiple threads) turns out to be due to running in debug mode. Changing components.xml to contain:


                                <core:init . . . debug="false">



                                fixed this issue.


                                Now I am back to the POSTs returning a status of 200 instead of 302.


                                And just fyi, here is he JIRA, which is now closed: http://jira.jboss.com/jira/browse/JBSEAM-2910

                                • 13. Re: JMeter Seam cid problem
                                  Coral Featherstone Newbie

                                  The regular expression extractor works but is painful.


                                  I got this working by adding 2 Http Url Re-writing Modifiers to the thread group.


                                  Name=CID
                                  Session Argument Name = cid
                                  cache session id=true
                                  


                                  and


                                  Name=VS
                                  Session Argument Name=javax.faces.ViewState
                                  cache session id=true
                                  


                                  And then as per regular expression extractor replacing request parameters with


                                  cid | ${CID}
                                  javax.faces.ViewState | ${VS}