Page tree

This guide will explain some interesting elements and functionality from a Jmeter plan. Supposing you have it already installed we will move to the principal elements of a JMX plan (if not, check Richard Gange post: JMeter Load Testing).

1. Common config elements

There is some common configuration that must be used on every element in the test plan that can be extracted to a shared level so no duplication of definitions are done. For example, the ip of the server, the application context, port number, URL params... those are variables that can be defined once and used by all.

1.1. Variables

1.1.1. User defined variables

On this group we will define general settings like server IP address, port and the web context. For creating this group, just right click on your Test Plan → Add → Config Element → User Defined Variables. Once you have this, just click on the add button on the bottom of the main section and set a var name and a value (also a description will be useful for people who reuse your plan)

1.1.2. Magnolia specific variables

On this group we will define variables that are needed only because the JMeter plan is being launched against Magnolia app. For example, root user account, URL params for login (mgnlUserId, mgnlUserId) ...

1.2. Shared HTTP petitions

As far as there are several common elements that all our petitions will need to share, we will create some HTTP config elements that will be used for all the HTTP request executed by the Jmeter plan:

1.2.1. HTTP Request Defaults

Right click on the plan → Add → Config Element → HTTP Request Default. Here we will define the default protocol (http), the default server address (we will use the value of the var ${server} defined in the User Defined Variables section) and the default port (${port} value).

1.2.2. HTTP Cookie Manager

Right click on the plan → Add → Config Element → HTTP Cookie Manager. This config element will help us to manage the cookies provided by Magnolia (just set the Cookie Policy to Compatibility)

1.2.3. HTTP Header Manager

Right click on the plan → Add → Config Element → HTTP Header Manager. This will set the content-type (application/json) for our Http requests

Now we can move to create the elements that will conform the Jmeter plan.

2. Threads

First element we would probably want to use are the Threads that, basically, they are a group of actions. Mostly every element (HTTP petitions, controllers...) must be under a thread group. For simulating concurrent actions on the system, multiple Thread groups must be created. There are three types of threads regarding its purpose:

  • The setUp thread gets executed always at first place, no matter in which position you created it within the test plan: it will be always executed the first. It's useful for performing initial actions before the real test plan starts (e.g, creating users, folders or any configuration that will be needed for executing successfully the test plan).
  • The tearDown thread will always be executed at last place. As you imagine it's useful to perform clean up actions (e.g, deleting directories or users that were used in the plan)
  • The thread group itself simulates a user, anyhow, you can create a thread group that gets executed several times and each time with a different user. So the proper definition of the thread group would really be a group of actions that will be executed one or more times.

Within the thread groups we can define some properties like:

  • Number of threads:  which is the number of users that will execute the thread (e.g, if you set Number of threads to 5, all the elements in the Thread group will be executed 5 times).
  • Ramp-up period: this value tells jMeter how long to take to go through all the Threads (e.g, if there are 30 threads and a ramp-up period of 120 seconds, then each successive thread will be delayed by 4 seconds).
  • Loop count: number of times the thread is going to be executed

2.1. setUp Thread Group

We will create a setUp thread group that will perform several actions that will be needed for the successful execution of the rest of the plan, these will be:

  • Login as superuser
  • Create the root path in the pages app where the full plan will be executed (to isolate the Jmeter testing from the rest of the already existing pages)
  • Publish that parent page
  • Logout

So, just right click on the plan → Add → Threads (users) → setUp Thread Group and add the following configuration:

  • Number of threads: 1
  • Ramp-up period: 1
  • Loop count: 1

Now we will create the HTTP request that will perform the needed actions in Magnolia via Rest. We will reuse all the elements created in the Variables and Shared HTTP request sections. For further information regarding which method (POST / PUT / DELETE / GET ) you need to use or which body data you need, just check the documentation.

2.1.1. HTTP Request [LOGIN - superuser]

Right click on the setUp Thread Group → Sampler → HTTP Request

This request will reuse server IP address and port, so we will just need to define the path for the REST petition, in this case, we will login against the AdminCentral as follows:

HTTP method → GET

Path: ${author}/.magnolia/admincentral

We will include the requested params for the login, which are mgnlUserId and mgnlUserPSWD (defined in Magnolia specific section) with the values superuser and superuser (defined in the User Defined Variables section)

2.1.2. HTTP Request [Creation of the Jmeter-testing parent page]

This request will create the parent page (in the root of website workspace, a parent page called jmeter-testing of which the rest of pages will be created and activated. Right click on the setUp Thread Group → Sampler → HTTP Request

Switch to "Body data" and copy the following snippet:

{
  "name": "jmeter-testing",
  "type": "mgnl:page",
  "path": "/jmeter-testing",
  "properties": [
    {
      "name": "title",
      "type": "String",
      "multiple": false,
      "values": [
        "This is parent page for Jmeter testing"
      ]
    },
    {
      "name": "mgnl:template",
      "type": "String",
      "multiple": false,
      "values": [
        "mtk:pages/basic"
      ]
    }
   ]
}

For the rest of elements, just configure them like the image below:

2.1.3. HTTP Request [Publish the parent page]

This request will publish jmeter-testing parent page created in the previous step.

Right click on the setUp Thread Group → Sampler → HTTP Request

Switch to "Body data" and copy the following snippet:

{
  "repository": "website",
  "path": "/jmeter-testing/",
  "recursive": "false"
}

For the rest of elements, just configure them like the image below:

2.1.4. HTTP Request [LOGOUT - superuser]

This request will finish the superuser session and will be the last action of the setUp Thread Group.

Right click on the setUp Thread Group → Sampler → HTTP Request

In the "Parameters" section add the following:

2.2. Thread Group

We will create a Thread group that will perform the actions oriented to stress the system. 

First of all, right click on the plan → Add → Threads (users) → Thread Group and add the following configuration:

As far as all users on this demo can create and publish pages, the option "Same user each iteration" is no mandatory but you can check it to keep the workflow coherence: the user of iteration 1 (user-1) creates and publish the page-1, otherwise, user-1 can create the page-1 but it could be published by the user of the iteration 5. It's up to you.

As explained above, the objective of the stress plan is to simulate several users login, creating and publishing pages at the same time. Instead of creating different HTTP Request with different users and password, JMeter has a fancy behavior that allows us to use for each thread a user defined in a CSV file. This config element (called CSV Data set Config) just need you to specify the location of the file which contains the accounts, how the variables must be named and the delimiter between these vars (for this example I used comma as delimiter and USERNAME and PASSWORD as the variables names for the pairs of values that will be read for each line)

2.2.1. CSV Data set Config

So, firstly lets create a users.csv file with the usernames and password of the publishers that we are going to play a role in the plan. Below you have an example you can use:

publisher-1,1234
publisher-2,1234
publisher-3,1234
publisher-4,1234
publisher-5,1234
publisher-6,1234
publisher-7,1234
publisher-8,1234
publisher-9,1234

Just remember that those accounts must exists and have the create and publish page privileges on the website workspace or the test will fail. You can download an example file from here

Now we just need to right click on the Thread → Add → Config Element → CSV Data Set Config and set the config as the image below:

Now, once this config Element is executed we will have available the vars ${USERNAME} and ${PASSWORD} for the rest of the Thread execution.

Next step will be login into Magnolia with the account loaded from the users.csv file. Similar as we did on the setUp Thread with the superuser login, we will create a HTTP Request Sampler and we will use the value of the vars USERNAME and PASSWORD:

2.2.2. Loop Controller

Once we have the user logged in, we will define a set of activities we want him to perform. For this tasks we will use a Loop Controller which will be executed 5 times per user. Right click on the Thread Group → Add → Logic Controller → Loop Controller and set the value of Loop Count to 5.

2.2.3 Counters

For managing the page's names (path) and other properties such as titles, we will define two counters. Counters can be created by right clicking on the Loop Controller → Add → Config Element → Counter.

The first counter (Page counter) will have the following configuration:

  • Starting value: 1
  • Increment: 1
  • Exported Variable Name: page-counter
  • Track counter independently for each user: false

The second counter (Child counter) will have a similar configuration but we will switch the Track counter independently for each user to true 

  • Starting value: 1
  • Increment: 1
  • Exported Variable Name: child-counter
  • Track counter independently for each user: true

Within this Loop counter we will define 5 activities that must be performed 5 times each by every user before loging out:

  1. Create a test page
  2. Publish the previous page
  3. Create a main node
  4. Create an HTML component with some value
  5. Create a Text and Image component with some value

Once the Loop is done, the user will logout from the system.

2.2.4. HTTP Request [Creates a test page]

Each user will create and edit 5 pages under the meter-testing parent page created in the HTTP Request [Creation of the Jmeter-testing parent page] step.

Right click on the Loop Controller → Add → Sampler → HTTP Request

Switch to "Body data" and copy the following snippet:

{
  "name": "test-page-${page-counter}",
  "type": "mgnl:page",
  "path": "/jmeter-testing/test-page-${page-counter}",
  "properties": [
    {
      "name": "title",
      "type": "String",
      "multiple": false,
      "values": [
        "Thread-${__threadNum}: child-${child-counter} by ${USERNAME}"
      ]
    },
    {
      "name": "mgnl:template",
      "type": "String",
      "multiple": false,
      "values": [
        "mtk:pages/basic"
      ]
    }
   ]
}

As you can see in the code, this will create a page in /jmeter-testing called test-page followed by the value of the page-counter for that iteration. It will also set the title of the page depending on the threadNumber and the value of the child-counter.

2.2.5. HTTP Request [Publishes the previous page]

This request will publish the page created in the step before, for achieving that, we will use the following snippet in the body data section:

{
  "repository": "website",
  "path": "/jmeter-testing/test-page-${page-counter}",
  "recursive": "false"
}

Copy the rest of elements as described in the image below:

2.2.6. HTTP Request [Creates a main node]

For creating some components (like HTML or Text and Image) we need to create first the element in which the component will be pending (header, main or footer). For this example we will create the components under the main area. We will use use the .rest/nodes API call as far as the area is truly a node.

Create a new HTTP Request and set in the body data section the following code:

{
  "name": "main",
  "type": "mgnl:area",
  "path": "/jmeter-testing/test-page-${page-counter}/main"
}

Now just set the remaining configuration as shown in the image below:

2.2.7. HTTP Request [Creates an HTML component]

This request will create an HTML component in the main area and will set a value to it. This HTTP Request will need the following code in the body data:

{
  "name": "0",
  "type": "mgnl:component",
  "path": "/jmeter-testing/test-page-${page-counter}/main/0",
  "properties": [
    {
      "name": "editHTML",
      "type": "String",
      "multiple": false,
      "values": [ 				"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Cursus sit amet dictum sit amet. Eu augue ut lectus arcu. Id venenatis a condimentum vitae sapien pellentesque. Ridiculus mus mauris vitae ultricies leo integer. Consequat id porta nibh venenatis cras sed felis. At ultrices mi tempus imperdiet nulla malesuada. Vitae congue mauris rhoncus aenean vel. Maecenas volutpat blandit aliquam etiam erat velit scelerisque. Eget nunc scelerisque viverra mauris in aliquam sem fringilla ut. Massa vitae tortor condimentum lacinia quis vel. Elementum curabitur vitae nunc sed velit. Aliquet risus feugiat in ante. Consectetur a erat nam at lectus urna duis convallis. Gravida neque convallis a cras semper auctor. Tristique magna sit amet purus gravida. Iaculis nunc sed augue lacus viverra. Interdum consectetur libero id faucibus nisl tincidunt eget nullam non."
      ]
    },
    {
      "name": "mgnl:template",
      "type": "String",
      "multiple": false,
      "values": [
        "mtk:components/html"
      ]
    }
   ]
}

Copy the rest of elements as described in the image below:

2.2.8. HTTP Request [Creates a Text and Image component]

The last component that the publisher will create its a Text and Image component. For this, we will create a second node (00) pending the main area and set some text to the text property:

{
  "name": "00",
  "type": "mgnl:component",
  "path": "/jmeter-testing/test-page-${page-counter}/main/00",
  "properties": [
    {
      "name": "text",
      "type": "String",
      "multiple": false,
      "values": [ 					"Erat nam at lectus urna duis convallis convallis tellus. Feugiat in fermentum posuere urna nec. Interdum velit laoreet id donec ultrices tincidunt. Mattis pellentesque id nibh tortor id. Sed elementum tempus egestas sed sed risus pretium. Sed id semper risus in hendrerit gravida. Libero justo laoreet sit amet cursus sit amet dictum sit. Malesuada nunc vel risus commodo viverra maecenas accumsan lacus. Aliquet eget sit amet tellus cras adipiscing. Blandit aliquam etiam erat velit scelerisque in. Lorem sed risus ultricies tristique nulla aliquet enim tortor at. Non diam phasellus vestibulum lorem sed risus ultricies tristique nulla. Quam id leo in vitae turpis massa sed. Viverra nam libero justo laoreet sit amet cursus sit amet. Consectetur libero id faucibus nisl tincidunt eget nullam non nisi. Ac tortor vitae purus faucibus. Risus in hendrerit gravida rutrum quisque non tellus orci ac. Tristique et egestas quis ipsum suspendisse ultrices gravida dictum."
      ]
    },
    {
      "name": "mgnl:template",
      "type": "String",
      "multiple": false,
      "values": [
        "mtk:components/textImage"
      ]
    }
   ]
}

Rest of elements can be set as described below:

2.2.9. HTTP Request [LOGOUT - publisher]

Finally, the user will logout from the system. It's important that you create this HTTP Request outside the Activity Loop otherwise it will try to logout the user 5 times and probably this will make Magnolia to explode everywhere. So set the HTTP Request as follows:

3. Plan Results

There are several ways of analyze the Jmeter plan results, but the easier way it's to use a Result Tree. This will provide information about the final state of each request in a very visual way: green → OK , red → Failure, quite easy. then you can get further information clicking on one specific request and checking the headers, response from server... etc.

For adding a Result Tree to your plan, just right click on the Test Plan → Add → Listener → View Results Tree. This element do not need any further information as far as it's internally linked to the plan, so once you execute it (through the "Play" button) it will start to provide a real-time feedback information.

Just down right here you have the Result Tree of the stress plan execution:

When any step returns an error status, it's useful to check the HTTP URL that has been build (sometimes the use of variables can throw unexpected results). Once the plan is executed, if we go to the Pages app, we will see the result of the test plan:

And the JCR view:

4. Download the JMX plan

If you feel lazy to create a JMX plan from scratch, you can simply download it from here (smile)

5. Final thoughts

As you may noticed, this plan misses some elements that probably came to your mind. E.g, the HTML and Text and Image component are created and some properties are filled but they are never published. We also talked about the utility of the tearDown Thread but we didn't use it to clean the test results (e.g, we could have deleted the root /jmeter-testing parent page so once the test is finished the pages apps structure would remain as it was originally). This lack of config elements are intentionally and it's up to you to customize or not the given plan.

Jmeter provides a powerful tool to simulate users activity on a web application. Tho there is a bunch more of config elements that the ones described here, this guide provides basic concepts to step in the Jmeter world. 


  • No labels

1 Comment

  1. Carlos Cantalapiedra Thank you for sharing this guide. Please check the links to "JMeter Load Testing" (Introduction) and to the JMX plan (4. Download the JMX plan), which are not accessible to me.