Sample workflows

Here’s some sample workflows to show you the power of Rungutan:

LANDING PAGE

{
  "test_name": "Blog post test",
  "num_clients": 250,
  "hatch_rate": 250,
  "run_time": 60,
  "threads_per_region": 1,
  "domain_name": "my-landing-page.com",
  "protocol": "https",
  "test_region": [ "us-east-1" ],
  "workflow": [
    {
      "path": "/",
      "method": "GET"
    },
    {
      "path": "/blog",
      "method": "GET"
    },
    {
      "path": "/blog/post-1",
      "method": "GET"
    },
  ]
}

BASIC AUTH

{
  "test_name": "Blog post behind nginx HTTP access basic auth",
  "num_clients": 250,
  "hatch_rate": 250,
  "run_time": 60,
  "threads_per_region": 1,
  "domain_name": "my-basic-site.com",
  "protocol": "https",
  "test_region": [ "us-east-1" ],
  "workflow": [
    {
      "path": "/",
      "method": "GET",
      "headers": {
         "Authorization": "Basic some-token-here"
      }
    },
    {
      "path": "/blog",
      "method": "GET",
      "headers": {
         "Authorization": "Basic some-token-here"
      }
    },
    {
      "path": "/blog/post-1",
      "method": "GET",
      "headers": {
         "Authorization": "Basic some-token-here"
      }
    },
  ]
}

BASIC AUTH WITH FILE UPLOAD

{
  "test_name": "Upload file to site with basic auth",
  "num_clients": 250,
  "hatch_rate": 250,
  "run_time": 60,
  "threads_per_region": 1,
  "domain_name": "my-basic-site.com",
  "protocol": "https",
  "test_region": [ "us-east-1" ],
  "workflow": [
    {
      "path": "/",
      "method": "GET",
      "files": [
         "file1", "file2"
      ]
      "headers": {
         "Authorization": "Basic some-token-here"
      }
    },
    {
      "path": "/blog",
      "method": "GET",
      "headers": {
         "Authorization": "Basic some-token-here"
      }
    },
    {
      "path": "/blog/post-1",
      "method": "GET",
      "files": [
         "file3"
      ]
      "headers": {
         "Authorization": "Basic some-token-here"
      }
    },
  ]
}

JSON RESPONSE WITH PATH EXPRESSION

{
    "num_clients": 30,
    "hatch_rate": 1,
    "run_time": 30,
    "threads_per_region": 1,
    "workflow": [
        {
            "path": "/v1/api/tests/list",
            "method": "POST",
            "headers": {
                "Content-Type": "application/json",
                "X-Api-Key": "${vault.api_key}"
            },
            "extract": [
                {
                    "parameter_name": "test_id",
                    "location": "body",
                    "json_path_expression": "Tests[*].test_id",
                    "default_value": "some_id_here_in_case_not_found"
                }
            ],
            "data": "{\"team_id\":\"rungutan\"}",
            "files": []
        },
        {
            "path": "/v1/api/tests/get",
            "method": "POST",
            "headers": {
                "Content-Type": "application/json",
                "X-Api-Key": "${vault.api_key}"
            },
            "data": "{\"team_id\":\"rungutan\", \"test_id\":\"${test_id}\"}",
            "extract": [],
            "files": []
        }
    ],
    "domain_name": "app.rungutan.com",
    "protocol": "https",
    "test_region": [
        "eu-west-1",
        "eu-west-2"
    ],
    "min_wait": 1000,
    "max_wait": 1000,
    "file_name_certificate": "",
    "test_name": "List all tests, extract a random test_id using path expression and fetches its details"
}

First workflow step:

  • Hit the /v1/api/tests/list path with POST

  • Inject the X-Api-Key header with the relevant Vault key

  • Extract a random “test_id” key from the “Tests” array in the JSON response and STORE it in the variable named “test_id”

Second workflow step:

  • Hit the /v1/api/tests/get path with POST

  • Inject the X-Api-Key header with the relevant Vault key

  • Set the payload as “{“team_id”:”rungutan”, “test_id”:”${test_id}”}” by referencing the value of the variable that we extracted in the previous step

JWT LOGIN PLATFORM

{
  "test_name": "Platform with JWT based auth",
  "num_clients": 250,
  "hatch_rate": 250,
  "run_time": 60,
  "threads_per_region": 1,
  "domain_name": "my-jwt-platform.com",
  "protocol": "https",
  "test_region": [ "us-east-1" ],
  "workflow": [
       {
           "path": "/login",
           "method": "POST",
           "headers": {
               "Content-Type": "application/x-www-form-urlencoded"
           },
           "data": "user=${vault.username}&password=${vault.password}",
           "extract": [
               {
                   "parameter_name": "authtoken",
                   "location": "body",
                   "key": "access_token"
               }
           ]
       },
       {
           "path": "/results",
           "method": "POST",
           "data": "{\"result_id\": \"1\"}"
           "headers": {
               "Authorization": "Bearer ${authtoken}"
           }
       }
   ]
}

First workflow step:

  • Hit the /login path with POST

  • Inject the username and password values from the relevant Vault keys into the payload

  • Extract the “access_token” key from the JSON response and STORE it in the variable named “authtoken”

Second workflow step:

  • Hit the /results path witht POST

  • Include a payload in the request

  • Set the header as “Bearer ${authtoken}” by referencing the value of the variable that we extracted in the previous step

LOGIN E-COMMERCE, PUSH COOKIES AND UPDATE SHIPPING ADDRESS

{
    "num_clients": 1,
    "hatch_rate": 1,
    "run_time": 300,
    "threads_per_region": 1,
    "workflow": [
        {
            "path": "/login",
            "method": "GET",
            "files": [],
            "data": "",
            "headers": {
                "authority": "${vault.domain_name}",
                "sec-ch-ua": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"96\", \"Google Chrome\";v=\"96\"",
                "sec-ch-ua-mobile": "?0",
                "sec-ch-ua-platform": "macOS",
                "upgrade-insecure-requests": "1",
                "dnt": "1",
                "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36",
                "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
                "sec-fetch-site": "same-origin",
                "sec-fetch-mode": "navigate",
                "sec-fetch-user": "?1",
                "sec-fetch-dest": "document",
                "referer": "https://${vault.domain_name}/"
            },
            "extract": [
                {
                    "parameter_name": "csrftoken",
                    "location": "body",
                    "element_with_regex": "type=\"hidden\" name=\"ci_csrf_token\" value=\"(.+?)\""
                }
            ],
            "extract_cookies": "yes"
        },
        {
            "path": "/login",
            "method": "POST",
            "files": [],
            "data": "ci_csrf_token=${csrftoken}&login-email=${vault.login_email}&login-password=${vault.login_password}&form-login-submit=1",
            "headers": {
                "authority": "${vault.domain_name}",
                "sec-ch-ua": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"96\", \"Google Chrome\";v=\"96\"",
                "sec-ch-ua-mobile": "?0",
                "sec-ch-ua-platform": "macOS",
                "upgrade-insecure-requests": "1",
                "dnt": "1",
                "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36",
                "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
                "sec-fetch-site": "same-origin",
                "sec-fetch-mode": "navigate",
                "sec-fetch-user": "?1",
                "sec-fetch-dest": "document",
                "referer": "https://${vault.domain_name}/login",
                "origin": "https://${vault.domain_name}",
                "content-type": "application/x-www-form-urlencoded"
            },
            "extract": [],
            "extract_cookies": "no"
        },
        {
            "path": "/dashboard/address_book/shipping",
            "method": "GET",
            "files": [],
            "data": "",
            "headers": {
                "authority": "${vault.domain_name}",
                "sec-ch-ua": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"96\", \"Google Chrome\";v=\"96\"",
                "sec-ch-ua-mobile": "?0",
                "sec-ch-ua-platform": "macOS",
                "upgrade-insecure-requests": "1",
                "dnt": "1",
                "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36",
                "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
                "sec-fetch-site": "same-origin",
                "sec-fetch-mode": "navigate",
                "sec-fetch-user": "?1",
                "sec-fetch-dest": "document",
                "referer": "https://${vault.domain_name}/dashboard",
                "origin": "https://${vault.domain_name}"
            },
            "extract": [
                {
                    "parameter_name": "shipping_address_id",
                    "location": "body",
                    "element_with_regex": "/dashboard/address_book/edit_shipping/(.+?)"
                }
            ],
            "extract_cookies": "no"
        },
        {
            "path": "/dashboard/address_book/edit_shipping/${shipping_address_id}",
            "method": "GET",
            "files": [],
            "data": "",
            "headers": {
                "authority": "${vault.domain_name}",
                "sec-ch-ua": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"96\", \"Google Chrome\";v=\"96\"",
                "sec-ch-ua-mobile": "?0",
                "sec-ch-ua-platform": "macOS",
                "upgrade-insecure-requests": "1",
                "dnt": "1",
                "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36",
                "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
                "sec-fetch-site": "same-origin",
                "sec-fetch-mode": "navigate",
                "sec-fetch-user": "?1",
                "sec-fetch-dest": "document",
                "referer": "https://${vault.domain_name}/dashboard/address_book/shipping",
                "origin": "https://${vault.domain_name}"
            },
            "extract": [],
            "extract_cookies": "no"
        },
        {
            "path": "/dashboard/address_book/edit_shipping/${shipping_address_id}/ajax-save-address",
            "method": "POST",
            "files": [],
            "data": "action=ajax_save_address&validate_data=ci_csrf_token%3D${csrftoken}%26address_book_id%3D${shipping_address_id}%26zipcode%3D${vault.zip_code}&address_book_id=${shipping_address_id}&ci_csrf_token=${csrftoken}",
            "headers": {
                "authority": "${vault.domain_name}",
                "sec-ch-ua": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"96\", \"Google Chrome\";v=\"96\"",
                "sec-ch-ua-mobile": "?0",
                "sec-ch-ua-platform": "macOS",
                "upgrade-insecure-requests": "1",
                "dnt": "1",
                "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36",
                "accept": "*/*",
                "sec-fetch-site": "same-origin",
                "sec-fetch-mode": "cors",
                "sec-fetch-user": "?1",
                "sec-fetch-dest": "empty",
                "referer": "https://${vault.domain_name}/dashboard/address_book/edit_shipping/${shipping_address_id}",
                "origin": "https://${vault.domain_name}",
                "x-requested-with": "XMLHttpRequest",
                "content-type": "application/x-www-form-urlencoded; charset=UTF-8"
            },
            "extract": [],
            "extract_cookies": "no"
        },
        {
            "path": "/logout",
            "method": "POST",
            "files": [],
            "data": "",
            "headers": {
                "authority": "${vault.domain_name}",
                "sec-ch-ua": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"96\", \"Google Chrome\";v=\"96\"",
                "sec-ch-ua-mobile": "?0",
                "sec-ch-ua-platform": "macOS",
                "upgrade-insecure-requests": "1",
                "dnt": "1",
                "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36",
                "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
                "sec-fetch-site": "same-origin",
                "sec-fetch-mode": "navigate",
                "sec-fetch-user": "?1",
                "sec-fetch-dest": "document",
                "referer": "https://${vault.domain_name}/dashboard/address_book/shipping",
                "origin": "https://${vault.domain_name}"
            },
            "extract": [],
            "extract_cookies": "no"
        }
    ],
    "domain_name": "${vault.domain_name}",
    "protocol": "https",
    "test_region": [
        "eu-central-1"
    ],
    "min_wait": 1000,
    "max_wait": 1000,
    "file_name_certificate": "",
    "test_name": "Login GET + Login POST + View shipping addresses GET + Update address with ajax POST + Logout GET"
}

First workflow step:

  • Hit the login URL with the METHOD GET

  • EXTRACT the CSRF token value by scanning the page for the actual value of csrf-token and STORE IT with variable name csrftoken

Second workflow step:

  • Use the value of the PREVIOUSLY STORED variable csrftoken and construct the LOGIN credentials by fetching the username and password from vault

  • Hit that URL with the METHOD POST

  • EXTRACT COOKIES and push them towards future workflow steps

Third workflow step:

  • Access the Shipping page

  • EXTRACT the ID of the shipping address stored in database and STORE IT with variable name shipping_address_id

Forth workflow step: * Update the shipping address by simulating an AJAX post call with sec-fetch-mode header as CORS and XMLHttpRequest as the “x-requested-with” header

Fifth workflow step

  • Simply log out the user

CSV UPDATE USER DETAILS

{
    "test_name": "Update email + phone number - 1000 users csv",
    "num_clients": 60,
    "hatch_rate": 60,
    "run_time": 60,
    "threads_per_region": 5,
    "workflow": [
        {
            "path": "/user/${csv.testprod.3}/profile",
            "method": "GET",
            "data": "",
            "headers": {
                "Content-Type": "application/json",
                "Authorization": "${vault.api_key}"
            },
            "extract": [
                {
                    "parameter_name": "profile_id",
                    "location": "body",
                    "key": "profile_id_extracted"
                }
            ]
        },
        {
            "path": "/user/${profile_id_extracted}/profile-details",
            "method": "POST",
            "data": "{\"phone_number\": \"+14041234567\"}",
            "headers": {
                "Content-Type": "application/json",
                "Authorization": "${vault.api_key}"
            }
        },
        {
            "path": "/user/${profile_id_extracted}/profile-details",
            "method": "POST",
            "data": "{\"email\": \"[email protected]"}",
            "headers": {
                "Content-Type": "application/json",
                "Authorization": "${vault.api_key}"
            }
        }
    ],
    "domain_name": "domain.com",
    "protocol": "https",
    "test_region": [
        "us-east-1",
        "us-east-2"
    ]
}

Here’s the step by step long explanation:

First workflow step:

  • Extract a random ROW from file testprod

  • From that ROW, get the value of the COLUMN with index 3

  • With that value, construct the URL -> /user/${csv.testprod.3}/profile

  • Hit that URL with the METHOD GET

  • Authenticate the API request using a VAULT key with the name api_key by placing it in the header key called “Authorization”

  • EXTRACT the parameter profile_id from the received JSON response and STORE IT with variable name profile_id_extracted

Second workflow step:

  • Use the value of the PREVIOUSLY STORED variable profile_id_extracted and construct the URL -> /user/${profile_id_extracted}/profile-details

  • Hit that URL with the METHOD POST

  • Authenticate the API request using a VAULT key with the name api_key by placing it in the header key called “Authorization”

  • Push the appropriate PAYLOAD using the json-escaped data field in order to update the phone number

Third workflow step:

  • Use the SAME value of the PREVIOUSLY STORED variable profile_id_extracted and construct the URL -> /user/${profile_id_extracted}/profile-details

  • Hit that URL with the METHOD POST

  • Authenticate the API request using a VAULT key with the name api_key by placing it in the header key called “Authorization”

  • Push the appropriate PAYLOAD using the json-escaped data field in order to update the email address