How To
ForgeRock Identity Platform
Does not apply to Identity Cloud

How do I generate sample user data for performance testing in DS (All versions)?

Last updated Jun 15, 2021

The purpose of this article is to provide information on generating sample user data for performance testing in DS. It is generally recommended that you use sample data for performance testing rather than actual data. This ensures that you do not expose any sensitive data, such as passwords, and also gives you more consistent data for testing purposes.

1 reader recommends this article

Generating sample user data

You can generate sample user data using makeldif; this command uses a template file and data files to create sample data that you can then import into DS. A sample template file (example.template located in the /path/to/ds/config/MakeLDIF/ directory) is included in DS, which generates 10,000 LDAP entries. This sample template file points to other data files (located in the same directory) from which makeldif derives the data to populate the LDAP entries. 

You should create your own template and data files based on these sample files to ensure the test data you create is similar to your actual data. The example template file is detailed below to help you create your own template and data files. See makeldif-template for further information.


Before generating a very large LDIF file, make sure you have enough space on disk.

Template file

The example.template file looks like this:

define suffix=dc=example,dc=com define define numusers=10000 branch: [suffix] objectClass: top objectClass: domain branch: ou=People,[suffix] objectClass: top objectClass: organizationalUnit subordinateTemplate: person:[numusers] template: person rdnAttr: uid objectClass: top objectClass: person objectClass: organizationalPerson objectClass: inetOrgPerson givenName: <first> sn: <last> cn: {givenName} {sn} initials: {givenName:1}<random:chars:ABCDEFGHIJKLMNOPQRSTUVWXYZ:1>{sn:1} employeeNumber: <sequential:0> uid: user.{employeeNumber} mail: {uid}@[maildomain] userPassword: password telephoneNumber: <random:telephone> homePhone: <random:telephone> pager: <random:telephone> mobile: <random:telephone> street: <random:numeric:5> <file:streets> Street l: <file:cities> st: <file:states> postalCode: <random:numeric:5> postalAddress: {cn}${street}${l}, {st} {postalCode} description: This is the description for {cn}.

This file breaks down into the following components with descriptions:

Component Description
define suffix=dc=example,dc=com define  define numusers=10000 Defines global variables that are used throughout the makeldif process to build up LDAP entries. The suffix and maildomain are self-explanatory; the numusers is the total number of LDAP entries that should be created.
branch: [suffix] objectClass: top objectClass: domain Creates a domain branch under dc=example,dc=com (the suffix variable). This branch should not already exist in your directory server, otherwise you will get an error when you attempt the import. The branch created in the ldif output file looks like this: dn: dc=example,dc=com objectClass: top objectClass: domain dc: example { [various aci settings] } 
branch: ou=People,[suffix] objectClass: top objectClass: organizationalUnit Creates another branch under dc=example,dc=com. This branch is an organizational unit called People. The branch created in the ldif output file looks like this: dn: ou=People,dc=example,dc=com objectClass: top objectClass: organizationalunit ou: People { [various aci settings] } 
subordinateTemplate: person:[numusers] Tells the makeldif process to run the person subordinate template 10001 times (the numusers variable).
template: person Defines the type of subordinate template to use as makeldif can create multiple object class types. In this case it is person.
rdnAttr: uid objectClass: top  objectClass: person  objectClass: organizationalPerson  objectClass: inetOrgPerson Gives the object class definition section for a person; this is repeated for each LDAP entry. The first entry created in the ldif output file looks like this: dn: uid=user.0,ou=People,dc=example,dc=com objectClass: top objectClass: person objectClass: organizationalperson objectClass: inetorgperson 
givenName: <first> Populates the givenName value from a randomly selected line in the sample first.names file.
sn: <last> Populates the sn value from a randomly selected line in the sample last.names file.
cn: {givenName} {sn} Assigns the cn value based on the populated givenName and sn values; makeldif is sequential so values must be assigned before being used to assign another attribute.
initials: {givenName:1}<random:chars:ABCDEFGHIJKLMNOPQRSTUVWXYZ:1>{sn:1} Derives the three letter initials value. The initials are derived as follows in this template: the first letter of the givenName value is taken, followed by a randomly selected character from the string, followed by the first letter of the sn value.
employeeNumber: <sequential:0> Assigns a sequential integer to the employeeNumber value starting with 0.
uid: user.{employeeNumber} Creates a uid value by appending a sequential integer to user. starting with 0, for example, user.0, user.1 etc.
mail: {uid}@[maildomain] Creates an email address from the derived uid value and the maildomain variable, for example,
userPassword: password Creates the userPassword value, which in this case equals password for all users. You could alternatively set this to something like P@ssw0rd! to capture a variety of characters if you plan on enforcing stronger passwords or you could use something like <random:alphanumeric:8> to generate a random 8 character password for each user.
telephoneNumber: <random:telephone> homePhone: <random:telephone>  pager: <random:telephone>  mobile: <random:telephone> Generates random numbers for the telephoneNumber, homePhone, pager and mobile values using USA style telephone numbers. You could change this to suit other countries, for example, you could use +44 <random:numeric:4> <random:numeric:6> for UK based numbers.
street: <random:numeric:5> <file:streets> Street Populates the street value by generating a 5 digit number followed by a random line from the sample streets file. 
l: <file:cities> st: <file:states> Populates the l and st values from randomly selected lines in the sample cities and states files respectively. 
postalCode: <random:numeric:5> postalAddress: {cn}${street}${l}, {st}  {postalCode}  description: This is the description for {cn}. Populates the postalCode value by generating a 5 digit number. The postalAddress value is derived by concatenating the derived cn value, followed by $, the derived street value, followed by $ and then the derived l value. This is followed by the derived state value and the derived postalCode value. Finally, plain text (This is a description for) is displayed followed by the cn value.

See Also

FAQ: AM performance and tuning

Performance Tuning

Related Training

ForgeRock Directory Services Core Concepts (DS-400) 

Related Issue Tracker IDs


Copyright and Trademarks Copyright © 2021 ForgeRock, all rights reserved.