SkillAgentSearch skills...

Hulken

Hulken is a stress testing tool for everything speaking HTTP. Hulken supports multiple urls, GETs and POSTs, static and dynamic payloads, multiple agents and more. Hulken is highly configurable but defaults to some reasonable settings. Hulken works both as a library and a stand-alone command line tool. Hulken is swedish for The Hulk.

Install / Use

/learn @hellgrenj/Hulken
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

hulken

Hulken is a stress testing tool for everything speaking HTTP. Hulken supports multiple urls, GETs and POSTs, static and dynamic payloads, multiple agents and more. Hulken is highly configurable but defaults to some reasonable settings. Hulken works both as a library and a stand-alone command line tool. Hulken is swedish for The Hulk.

.. smash and nothing else

Hulken is in no way a proper load test tool like LoadRunner, JMeter and such (e.g it does not try to simulate realistic user behaviours), but that's usually not what I need. I need something quick and lightweight to run early and often that helps me catch the biggest boo boo's before they see the light of day. If you have the same need I hope that Hulken can be useful to you too.

Quick Examples

as a library:

npm install hulken --save

var hulken = require('hulken');

var myArrayOfRequests = [{
    method: 'get',
    path: '/',
    expectedTextToExist: 'Welcome to the landing page'
}];

var hulken_options = {  
  targetUrl: 'http://localhost:8888',  
  requestsArray: JSON.stringify(myArrayOfRequests),
};  

hulken.run(function(stats){  
  console.log('error ... perhaps i should look closer at the stats');  
  },function(stats){  
    console.log('success! ... auto tweet my stats to the world!');  
    },hulken_options);

(you can override a lot of default settings, see documentation)

instead of passing in the requests in requestsArray you can also set the requestsFilePath (the value is the path) that points to a json file like this:

[{
  "method":"get",
  "path":"/index",
  "expectedTextToExist":"Start"
 },
 {
    "method":"get",
    "path":"/about",
    "expectedTextToExist":"About us"
 },
 {
    "method": "post",
    "path": "/",
    "expectedTextToExist": "thank you for your POST",
    "expectedStatusCode": 201,
    "payload": {
      "foo": "bar"
     }
}]

(you can also send dynamic payloads, see documentation )
checkout ./tests/integrations.js for more examples!

as a command line tool

npm install hulken -g

Create a 'options.json' file with the following content. the requestsFilePath points to the same hulkenRequests.json as in the example above (as a library). If you wish you can also pass in the list of requests inline (as a valid json string, escaping your double quotes) with requestsArray.

{
  "targetUrl" : "http://yourapp.com",
  "requestsFilePath": "./path/to/my/hulkenRequests.json"
}

(you can have hulken generate an example options for you, see documentation)

and then you can use the hulken command to run a stress test:

hulken options.json

option files makes it easy to reuse requests files when targeting different environments (dev, test, staging etc..)

Documentation

1.) Settings you can override through options
2.) Dynamic payloads
3.) The stats
4.) Command line tricks
5.) Automatically generate requests files with Informants
6.) Smash responsibly - It is your foot!
7.) Release notes
8.) Tests
9.) License

<a name="settings"></a>

Settings

When you use hulken as a library you override these settings in the options object you pass in. When you use hulken as a command line tool you override these settings in the options file.

setting name (default value) | explanation

  • targetUrl ("http://localhost") | url to application under test
  • numberOfHulkenAgents (1) | number of agents sending requests
  • timesToRunEachRequest (1) | number of times to execute each request per agent
  • requestsFilePath ("./hulkenRequests.json") | path to requestsFile (including file name)
  • requestsArray (undefined) | an array of hulken requests as a json string (see Quick Examples - as a library). Overrides requestsFilePath if both are present.
  • tokensSkippingRequest ([':']) | requests with urls containing one or more of these chars gets ignored
  • requestsToSkip (['/logout', 'signoff']) | requests with urls matching one of the provided urls gets ignored
  • loginRequired (false) | is a login required to execute the requests?
  • username ("") | mandatory if loginRequired is true ... the username
  • password ("") | mandatory if loginRequired is true ... the password
  • usernamePostName ("username") | the username post name
  • passwordPostName ("password") | the password post name
  • loginUrl ("/login") | the url to post to when logging in
  • loginResponseExpectedText ("") | a text which hulken searches for in the response to the login post (if non is provided hulken will consider http 200 OK good enough)
  • happyTimeLimit (10) | max test suite duration (in seconds). If the whole test takes longer than this value hulken gets angry.
  • slowRequestsTimeLimit (3) | response times (in seconds) over this value are considered slow
  • angryOnFailedRequest (false) | Hulken gets angry (calls error callback) if a single request fails
  • chatty (true) | set to false to make Hulken less chatty
  • happyMessage ("HULKEN PLEASED WITH RESULT, NO ONE NEEDS TO GET HURT TODAY!") | pass in what you want Hulken to say when Hulken is happy with a result
  • angryMessage (".... BAD RESULT... HULKEN ANGRY!") | pass in what you want Hulken to say when Hulken is angry with a result
  • minWaitTime (1000) | minimum wait time in milliseconds (every request waits for a random time before executing)
  • maxWaitTime (6000) | maximum wait time in milliseconds (every request waits for a random time before executing)
  • returnAllRequests (false) | If true the stats object will contain all executed requests (stats.allRequests)
  • headers ({}) | set HTTP headers in a simple object: { "key1": "value1", "key2": "value2", "accept-encoding": "Overriden" }. These headers will be set for every request in the test.
  • requestValueLists ({}) | insert value lists in a simple object: { usernames: ['john', 'jessica','admin'], cities: ['Stockholm', 'London', 'Berlin', 'New York'] }
  • printLoadDistribution (false) | prints how the load was randomly distributed (see minWaitTime and maxWaitTime) during the test with timestamps: hh:mm:ss number of requests sent
    example:
    12:10:37 18
    12:10:38 28
    12:10:39 17 (at 12:10:39 17 requests were sent)

<a name="dynamicPayloads"></a>

Dynamic payloads

POSTs require a payload.

Besides hard coded values you can let hulken generate random post values consisting of letters, numbers or letters and numbers. The syntax is as follows:

::random <valuetype> <numberOfChars>

available value types are numbers [0-9], letters [A-Za-z] and lettersandnumbers [A-Za-z0-9].

For example, the request below will send a POST to the url /random with a payload consisting of 3 generated property values. random will be a 10 characters long string of letters and numbers. random2 will be a 15 characters long string of numbers. random3 will be a 20 characters long string of letters.

{
  "method": "post",
  "path": "/random",
  "expectedTextToExist": "thank you for the random value",
  "payload": {
    "random": "::random lettersandnumbers 10",
    "random2": "::random numbers 15",
    "random3": "::random letters 20"
  }
}

You can also pass in value lists with your options file/object and have hulken pick randomly from these when executing the requests.

The syntax in your request is as follows:
::randomList <nameOfList>

in options pass in:

requestValueLists : {
  usernames: ['john', 'jessica','admin'],
  cities: ['Stockholm', 'London', 'Berlin', 'New York']
}

and then in your requests file have a post that looks like this:

{
  "method": "post",
  "path": "/RandomList",
  "expectedTextToExist": "you have sent /RandomList a POST request",
  "payload": {
    "username": "::randomList usernames",
    "city" : "::randomList cities"
  }
}

<a name="theStats"></a>

The stats

When you use hulken as a library you get callbacks with stats. This is what this stats object looks like. This object can also contain allRequests see Settings

{ numberOfHulkenAgents: 50,
  numberOfConcurrentRequests: 150,
  numberOfUniqueRequests: 3,
  totalSecondsElapsed: 6.001,
  avgReqResponseTime: 0.001806666666666668,
  reqsPerSecond: 24.995834027662056,
  randomRequestWaitTime: '1-6 seconds',
  slowRequests: [],
  failedRequests: [] }

<a name="commandLineTricks"></a>

Command line tricks

Hulken can generate an example options file for you, all you have to do is provide the target url.

hulken make_options http://localhost:8080

<a name="informants"></a>

Automatically generate requests files with Informants

an hulken_informant offers a quick and simple way to create a stress test suite by inspecting your application routes and auto generating the requests file for you!

hulken_informant_express3 (works with express3)
hulken_informant_hapi (works with hapi.js 7)
hulken_informant_hapi8 (works with hapi.js 8)
missing your framework?
feel free to create a hulken_informant_x and send me the link

<a name="smashResponsibly"></a>

Smash responsibly!

Hulken knows no limits! Be it number of agents, times to execute each request or the length of a randomly generated post value. IT IS YOUR FOOT! =) Seriously though - how could hulken enforce any reasonable limits? What is reasonable depends on the application under test and the machine executing the test.

<a name="releaseNotes"></a>

Release notes

1.2.3

  • add property expectedStatusCode: (int value) to a request to override the def
View on GitHub
GitHub Stars294
CategoryDevelopment
Updated27d ago
Forks8

Languages

JavaScript

Security Score

80/100

Audited on Mar 3, 2026

No findings