Monday, March 17, 2014

Part 2: Advanced Apache JMeter Stress Testing OAM and LDAP

In “Part 1: How To Load Test OAM11g using Apache JMeter” I talked about an example plan that could be used to load test OAM11g, which included some common configuration elements, some samplers for login, authorization, logout, and some listeners that provided result analysis.   In Part 2, I wanted to expand on an option to make JMeter send random logins and I will explain why, and then cover how to leverage JMeter to load test an LDAP server like OUD, OID, ODSE, or OVD.

How to get JMeter to do Random Logins

As I mentioned before in Part 1 the load test was simply going through a list of users and each would login.  As the test plan is run a second time OAM would have cached authorization for the purpose of improved performance, but each time you would run the load test it would be skewed a bit and the test results may be inconsistent and therefore harder to determine if tuning or other changes have improved results.  I want to note that OAM does not cache login data like passwords or usernames, the caching is more about policies for authorizations.

So why care about randomizing login requests in a load test?  Randomizing in my opinion provides a way to try and simulate a little more realistic load test since in real life you would not expect Brian to login just before Pardha every single time.  So one option to avoid this dilemma is to restart the environment after each load test, and this is often a common practice, but that can cost a lot of time.  The approach I am proposing generates random logins in a little more realistic anyway, so why not do it?

It would be really nice if the CSV Data Set Config element had an option to randomly select users from the list in the file, but unfortunately it doesn’t.  So I spent a little time trying to come up with a good way to accomplish random logins and it was not as easy as I had hoped.   I finally came up with an approach that works pretty well, though I would love to get feedback if there is another way to do it.  The approach I came up with has some additional benefits, more on that later. So to get started please download the Test Plan and follow through the remaining sections.

Split the User List

The first step is to take the CSV file that holds all the list of users JMeter uses to iterate through logins and split it into chunks.   Each split list of users would be tied to a sampler, but more on this later.  So to get started complete the following steps.

  1. Download the example LDIF, which contains a sample list of 5,000 users with random populated data.  I generated this using a Perl script.  If you have you own LDIF of users from the OAM Identity Store use that.  Keep in mind for the CSV you really only need the elements needed to login, for example uid and password.  Though if all of the User passwords are the same you can just include the usernames in the CSV file and hard code the password in JMeter User Defined Variables elements.
  2. Run the following command against the LDIF to generate a single flat file of just usernames.  For your convenience you can also download the flat file Users.csv.tar.gz that basically contains a single column of all 5,000 usernames.

    Comments:  This command extracts only the uid: and outputs just uids.
    Command:  grep "uid:" import_users_list.ldif | awk '{print $2}' >> Users.csv
    Output:  Users.csv file will be a file with only a list of all “uid” values.
  3. Split the Users.csv file into 10 parts using the following commands.  The reason I selected 10 was it evenly divided the 5,000 users into 500 in each file.  Feel free to break the list up as you feel needed, but I think this is a reasonable division of users.

    Comments: This command lets you know the total number of lines in the file.
    Command: wc –l Users.csv
    Output:  5000 Users.csv

    Comment:  This command splits the single large file into a group of files.
    Command:  split –d –l 500 Users.csv Users_
    Output:  10 separate files will be created Users_00, Users_01, Users_02, etc.

    Comment:  This command adds an extension to the files that were created.
    Command:  find . -name "Users_*" -exec mv "{}" "{}".txt \;
    Output:  Same list of files created earlier except with *.txt extensions.
For your convenience I have included all the split files in the same Users.tar.gz file.  If you have your own custom list of users feel free to follow the same steps.

Setup the Login Sampler

Download the advanced file.  It is simpler to explain how the Login Sampler is setup by using an example you can modify it for your own use cases.

Refer to the following graphic; you can see there are 10 Login samplers in my example, but you are welcome to adjust that for your own needs.  Each Login Sampler is made up of a Simple Controller, and underneath each there is one CSV Data Set Config (One of the CSV flat files we split earlier.), two HTTP Requests, and one Regular Expression Extractor found under the Portal Request.  The only difference in each Simple Controller like Login 00, Login 01, Login 02, etc. is the User flat file used for the CSV Data Set Config.  So for example “Login 00” uses the CSV flat file Users_00.txt, then in the next Login 001 sampler users Filename Users_01.txt and so forth.  Go ahead and open each one and compare.  Basically this is the only difference.

Now if you select the top element named “Login”, you will see that this is a Random Controller.The Random Controller will randomly select one of the samplers at a time for each thread like Login 00, or Login 03, or Login 06, etc.

For example when the Load Test starts, it will go to “Login” and then randomly pick one of the ten Login (nn) samplers and execute it, then go the AuhZ sampler to go through those samplers to request the Portal, submit the login, and finally finish with the Logout sampler to logout all the requests.  What is interesting is each time the Login Random Controller (Parent Login element) picks a random Login 00 or Login 05, etc., it not only picks a single user to login from the respective CSV flat file, but each time the same Login sampler is selected again, it keeps track of which User logged in and makes sure it picks the next User in the list.  

Random Login Summary

As you can see the test plan is similar to Part 1, but enhanced to provide a way to make logins more random that simulates a more real life login load.   So to summarize, each thread that is open by JMeter to execute a process to login, the Login Random Controller will make sure to run one login from one of the Login (nn) samplers and each new thread that the Random Controller picks that is the same sampler, JMeter makes sure the next user in the Sampler’s CSV file is used.  This way it makes sure each login is unique and we get a random selection of logins.  Brilliant!

Load Testing LDAP servers using JMeter

Now moving on to using JMeter to load test an LDAP server.  In any Identity and Access Management deployment there is a LDAP server deployed supporting all Internal and External user data among other things.  The LDAP server is a very critical part of the Identity and Access Management architecture.  In Part 1 the blog talked about Load Testing OAM, which is very important.  At the heart of the OAM authentication is the backend LDAP server.  Typically many other applications are using the LDAP Identity data for other reasons.   So load testing OAM alone is not going to fully load test the LDAP server.  Therefore it is a very good idea to stress test against the LDAP server directly to reflect the load you are expecting it to handle and then some.   With this in mind, JMeter is here to help again.  JMeter provides a free load testing software to solve this dilemma.

Defining a LDAP Load Test

A lot of people don’t realize that JMeter can send search, add, modify, and delete operations to an LDAP server like OUD, OID, ODSEE, or OVD, or any other LDAP server.  To keep things simple, I incorporated my LDAP Load Test sample in the same OAM11g_AdvLoadTest.jmx JMeter load test file.   This sample is in the “LDAP Thread Group” thread group, but feel free to copy the configuration into a stand-alone JMeter file.  You can easily do this by making a copy of the OAM11g_AdvLoadTest.jmx file, open it up, delete the OAM11g Thread Group and modify the remaining LDAP Thread Group.  Another approach is to disable the OAM11g Thread Group and make sure the LDAP Thread Group is enabled before using it.

Elements of the LDAP Thread Group

So to get started, using the example I included in the download follow the next sections to understand how to implement each type of LDAP operation.  I think this keeps things simple and then you can then take the examples and build your own test plan.   So here we go…

CSV Data Set Config

The first element called CSV Data Set Config basically sets up the CSV file that would contain all the user data values for all the respective attributes like uid, cn, givenname, sn, mail, and userpassword.  Note that attribute names are not in this CSV file, only the attribute values.  Also note that some values are duplicated depending on what you are doing.  For example in my JMeter example there is a mail_new and a mail_orig.  Both are mail values, but mail_new holds a new email address while the mail_orig holds the old or original value.  This is a simple trick to make the test plan add a new email address and then modify it using the mail_new value in the CSV file.  Please be creative as needed to making the test plan per your needs.


The next few elements uses the LDAP Extended Request, but each one is configured slightly differently depending on how it is used.  For this element we use the LDAP Bind option. This provides a way to BIND to LDAP and opens a connection to the LDAP server.  Simply modify the fields as needed per your environment.


This element is used to Add an entry to LDAP.  The key here is to include the proper object class.  For example for a User in OUD, inetOrgPerson is the required object class to create a User.  For example a User in OUD is required to have the object class inetOrgPerson to create a User.  The specific object classes can vary between types of Directory Servers.  For example if using Active Directory the User object class would be person, a group would require the group object class.  Just modify this per your requirements. 

LDAP Search

This element obviously searches for an entry.  The key to this element is to include the sub branch for the Search Base and not the entire namespace.  For example in the LDAP Bind element there is a field DN, and in my example I put “dc=oracle,dc=com”.  So within this element you only use ou=People, and the translation becomes ou=People,dc=oracle,dc=com for the entire search DN.

LDAP Modify New

This element will modify an entry.  You can include as many attributes as you want, though the key is to make sure to use the correct opCode.  The opCode determines the LDAP change type.  The opCode options are replace, add, or delete.  You can mix and match various operations for each attribute being modified. 

LDAP Modify Orig

This element is basically the same as the LDAP Modify New element, but instead it switches back the old mail address attribute value.  This is just a simple trick to stress the LDAP server to modify an entry and put the original value back.  In my example I replace the old mail attribute value with a new one, which ties back to my comment earlier on why in my CSV flat file I had a mail_new and mail_orig values.

LDAP Delete

This element is a little different than the LDAP Modify elements previously mentioned.  The previous elements use the opCode delete.  However that delete operation is to delete an attribute.  This element will delete the entire entry.  As previously mentioned about the namespace, it is key to only use the sub branch ou=People and not the entire namespace like ou=People,dc=oracle,dc=com.

LDAP Unbind

This element is important because it executes a LDAP Unbind to close the connection to the LDAP server.  If this element were left out of the test plan JMeter would have hundreds or thousands of open connections and none of them closed, thereby overwhelming the Operating System and the Directory Server pushing it to its limits.

LDAP Load Test Summary

I really only wanted to go over the building blocks of the JMeter LDAP Operation elements so that you would have the tools to build your own load test plan.  There are certainly other tools to load test LDAP, but I feel JMeter provides a very easy way to accomplish this and provides a fair one size fits all tool to do HTTP and LDAP testing.   Not a bad tool to keep in your bag.

Summarizing the Advanced Apache JMeter Stress Testing  OAM and LDAP

Hopefully combining a couple important advanced features of JMeter add more help in load testing projects that have deployments of Oracle’s IAM suite.  JMeter can certainly do many other things,;though my goal was to cover more of the essentials of developing load test plans for projects that lack load test tools.  I like to say this is the 80/20 rule where I hoped to cover 80% of what you need in regard to load testing from a tool perspective.  Happy load testing!

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.