top of page

MIDSHIPS

  • Debasis Dwivedy

Performance Testing ForgeRock with K6 (for beginners :-))

Updated: Apr 14


Introduction:

k6 is a modern, developer-friendly load testing tool built with Go programming language. It offers a simple and efficient way to create, execute, and analyse load tests. k6 provides a JavaScript-based scripting approach, making it accessible to both developers and non-technical users.


Testing ForgeRock installation can be tricky as there are several components to ForgeRock, and testing each component and optimising it for the production environment can be time-consuming.

The technical test is composed of 3 parts:

  • Load testing is a crucial aspect of ensuring the performance and reliability of web applications. It involves simulating realistic user traffic to determine how an application behaves under different load conditions.

  • Soak testing ensures that the system can operate under high demand for a longer period.

  • Stress testing allows you to find the breaking point of the system.


k6 is a powerful open-source load-testing tool that simplifies the process of testing and provides actionable insights. This guide will explore the key concepts and steps involved in load testing with k6 for ForgeRock setup.

 

About the Author

Debasis is a Senior ForgeRock Subject Matter Expert at Midships leading ForgeRock implementations at customers across South East Asia. For further details about this blog, please reach out on debasis.dwivedy@midships.io

 

Installation and Setup:

To get started with k6, you need to install it on your local machine or a dedicated load testing environment. k6 supports major operating systems like Windows, macOS, and Linux. The installation process is straightforward and well-documented in the official k6 documentation. The details of the installation can be found in the link below:


Writing a k6 Test Script:

k6 test scripts are written in JavaScript, allowing you to define realistic user scenarios, specify HTTP requests, and add assertions to verify the application's response. You can utilize the k6 API to simulate complex user interactions, handle dynamic data, and control test flow.


I found this better than jmeter as sometimes the plugins in jmeter can be overwhelming and hard to understand. k6 allows programmers to write the test scripts as normal JavaScript using the request/response syntax and scale it up if and when required.


It also provides fine granularity as the response from a previous request can be used to determine the next request. All these requests can be clubbed together to form a long/short test script which can be loaded independently to test specific scenarios.

Below is a sample:

import http from 'k6/http';
import { group } from "k6";
import { Counter } from 'k6/metrics';
let CounterErrors = new Counter("Errors");
let CounterDuration1 = new Counter("Login1");
let CounterDuration2 = new Counter("Login2");
let CounterDuration3 = new Counter("Login3");
const url ="https://am.example.com";
export function login1(token) {
  let params = {
    headers: {
       "accept-api-version": "protocol=1.0,resource=2.1",
         "Accept": "application/json",
         "Content-Type": "application/json",
         "X-OpenAM-Username": "testuser",
         "X-OpenAM-Password": "Password12345",
    },
  }; 
  let res =   http.post(`${url}/am/json/realms/root/realms/test/authenticate`, {}, params);
   CounterDuration1.add(res.timings.duration);
  return tokenId;
}

export function login2(token) {
  let params = {
    headers: {
       "accept-api-version": "protocol=1.0,resource=2.1",
         "Accept": "application/json",
         "Content-Type":   "application/x-www-form-urlencoded",
         "Cookie": token,
    },
    redirects: 0,
  };
  let payload ={
    "scope":   "openid",
     "response_type": "code",
    "client_id":   "testClient",
     "redirect_uri": "http://example.com",
    "decision":   "allow",
     "code_challenge":   "j3wKnK2Fa_mc2tgdqa6GtUfCYjdWSA5S23JKTTtPF8Y",
    "code_challenge_method":   "S256",
    "csrf":   token,
    "state":   "abc123",
  }; 
  let res =   http.post(`${url}/am/oauth2/test/authorize`, payload, params);
  CounterDuration2.add(res.timings.duration);
  let   code=res.headers.Location.split('&')[0].split('?')[1].split('=')[1];
  return code;
}
export function login3(code) {
  let params = {
    headers: {
         "Content-Type":   "application/x-www-form-urlencoded",
    },
  };

  let payload ={
    "code":   code,
     "grant_type": "authorization_code",
    "client_id":   "testClient",
     "code_verifier":   "ZpJiIM_G0SE9WlxzS69Cq0mQh8uyFaeEbILlW8tHs62SmEE6n7Nke0XJGx_F4OduTI4",
     "redirect_uri": "http://example.com",
  }; 
  let res =   http.post(`${url}/am/oauth2/test/access_token`, payload, params);
  CounterDuration3.add(res.timings.duration);
  let   access_token=res.json()["access_token"];
  return access_token
}
export default function() {
  let token=login1();
  let code=login2(token);
  let   access_token=login3(code);
  if(!access_token)
  {
    CounterErrors.add(1);
  }
}

The above script name sample.js could be run by using the command below, which will run it once for one user:

k6 run sample.js

For more sample on how to write the scripts can be found from the link below:


Configuring Load Scenarios:

k6 provides various configuration options to simulate different types of load scenarios. You can define the number of virtual users (VUs), duration of the test, and ramp-up periods. Additionally, k6 allows for specifying thresholds and tolerances to determine the test's success criteria.

The above script could be ramped up for multiple used by multiple users for a longer period of time using the command below:


k6 run –vus 6 –duration 180m sample.js


This will run the scripts for 6 users for 3 hours.


For more sample on how to write the scripts can be found from the link below:


Executing Load Tests:

Once you have written your test script and configured the load scenario, you can execute the load test using the k6 command-line interface (CLI). k6 provides real-time test execution metrics and progress updates, enabling you to monitor the test's progress and identify any issues. We have integrated k6 run with a Grafana dashboard to visualize the progress of each test and send alerts if required. Below the dashboard for the run above.


We have used Grafana+influxdb for our test example, but there are multiple ways to integrate. Please follow the link below for k6 and Grafana integration:


It is important to note that we are using our own standalone k6 installation. There is a k6 cloud offering that operates similarly but without the need of adding your own infrastructure.

For more details visit the link below:


Analysing Test Results:

After the load test execution, k6 generates comprehensive test reports and result summaries. These reports include key performance indicators like response times, throughput, error rates, and more. You can leverage these insights to identify performance bottlenecks, evaluate system capacity, and make data-driven optimizations.

The response to the above run was as below:

k6 run --vus 6 --duration 180m sample.js
     data_received..................: 78 MB          16 kB/s
     data_sent......................: 25 MB          5.0 kB/s
     http_req_blocked...............: avg=155.07µs min=0s       med=3.23µs   max=110.01ms p(90)=4.47µs   p(95)=4.96µs  
     http_req_connecting............: avg=7.69µs   min=0s       med=0s       max=3.83ms   p(90)=0s       p(95)=0s      
     http_req_duration..............: avg=397.61ms min=0s       med=300.28ms max=7.63s    p(90)=896.04ms p(95)=1.38s   
       { expected_response:true }...: avg=412.65ms min=12.1ms   med=313.19ms max=7.63s    p(90)=951.83ms p(95)=1.4s    
     http_req_failed................: 3.67%          ✓ 1326        ✗ 34741
     http_req_receiving.............: avg=92.1µs   min=0s       med=91.76µs  max=2ms      p(90)=129.22µs p(95)=139.91µs
     http_req_sending...............: avg=32.58µs  min=0s       med=28.54µs  max=10.42ms  p(90)=43.86µs  p(95)=49.93µs 
     http_req_tls_handshaking.......: avg=139.17µs min=0s       med=0s       max=78.23ms  p(90)=0s       p(95)=0s      
     http_req_waiting...............: avg=397.48ms min=0s       med=300.12ms max=7.63s    p(90)=895.95ms p(95)=1.38s   
     http_reqs......................: 36067          7.255703/s
     iteration_duration.............: avg=1.15s    min=514.67µs med=823.96ms max=30s      p(90)=2.4s     p(95)=2.8s    
     iterations.....................: 12905          2.596136/s
     Login1.........................: 5617456.782563 1130.080107/s
     Login2.........................: 3079675.395106 619.54725/s
     Login3.........................: 5643533.119942 1135.32596/s
     vus............................: 3              min=3         max=3  
     vus_max........................: 3              min=3         max=3

If there is no visualization tool integration, then this output can be saved to a file for future analysis.


Integrations and Extensibility:

k6 integrates with popular tools and platforms like Grafana, InfluxDB, and New Relic, allowing you to visualize and analyse load test results in a more advanced manner. k6 also supports custom metrics, thresholds, and result exports, providing flexibility and extensibility to suit different testing requirements.

There are several ways to generate the script automatically without writing them:

Best practice would be to generate the scripts based on any of the method above and then modify it according to the requirement.


More details about these integration tools can be found below:


Advanced Features and Best Practices:

As you gain proficiency with k6, you can explore advanced features like test setup and teardown functions, custom performance profiles, distributed load testing, and more. Additionally, it is crucial to follow best practices like realistic test scenarios, data parameterization, and proper resource management to ensure accurate and reliable load testing results.


Conclusion:

Load testing with k6 empowers developers and testers to identify and address performance issues early in the development lifecycle. With its ease of use, flexibility, and powerful reporting capabilities, k6 proves to be an excellent tool for load testing web applications. By following this beginner's guide, you can get started with k6 and effectively conduct load tests to optimize your application's performance and user experience.



 

I hope you enjoyed this blog. Please reach out if you have any queries, Debasis.



33 views0 comments
bottom of page