Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

loadtest

Package Overview
Dependencies
Maintainers
1
Versions
122
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

loadtest - npm Package Compare versions

Comparing version 6.3.2 to 6.4.0

104

lib/httpClient.js

@@ -12,2 +12,4 @@ import * as urlLib from 'url'

let uniqueIndex = 1
/**

@@ -94,2 +96,15 @@ * Create a new HTTP client.

}
// adding proxy configuration
if (this.params.proxy) {
const proxy = this.params.proxy;
const agent = new HttpsProxyAgent(proxy);
this.options.agent = agent;
}
if (this.params.indexParam) {
this.options.indexParamFinder = new RegExp(this.params.indexParam, 'g');
}
// Disable certificate checking
if (this.params.insecure === true) {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
}
}

@@ -134,39 +149,6 @@

const id = this.operation.latency.start();
const options = {...this.options, headers: {...this.options.headers}}
const requestFinished = this.getRequestFinisher(id);
let lib = http;
if (this.options.protocol == 'https:') {
lib = https;
}
if (this.options.protocol == 'ws:') {
lib = websocket;
}
// adding proxy configuration
if (this.params.proxy) {
const proxy = this.params.proxy;
const agent = new HttpsProxyAgent(proxy);
this.options.agent = agent;
}
// Disable certificate checking
if (this.params.insecure === true) {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
}
let request, message;
if (this.generateMessage) {
message = this.generateMessage(id);
if (typeof message === 'object') {
message = JSON.stringify(message);
}
this.options.headers['Content-Length'] = Buffer.byteLength(message);
} else {
delete this.options.headers['Content-Length'];
}
if (typeof this.params.requestGenerator == 'function') {
const connect = this.getConnect(id, requestFinished, this.params.contentInspector)
request = this.params.requestGenerator(this.params, this.options, lib.request, connect);
} else {
request = lib.request(this.options, this.getConnect(id, requestFinished, this.params.contentInspector));
}
this.customizeIndex(options)
const request = this.getRequest(id, options, requestFinished)
if (this.params.timeout) {

@@ -181,4 +163,6 @@ const timeout = parseInt(this.params.timeout);

}
const message = this.getMessage(id, options)
if (message) {
request.write(message);
options.headers['Content-Length'] = Buffer.byteLength(message);
}

@@ -191,2 +175,50 @@ request.on('error', error => {

customizeIndex(options) {
if (!this.options.indexParamFinder) {
return
}
options.customIndex = this.getCustomIndex()
options.path = this.options.path.replace(this.options.indexParamFinder, options.customIndex);
}
getCustomIndex() {
if (this.options.indexParamCallback instanceof Function) {
return this.options.indexParamCallback();
}
const customIndex = uniqueIndex
uniqueIndex += 1
return customIndex
}
getLib() {
if (this.options.protocol == 'https:') {
return https;
}
if (this.options.protocol == 'ws:') {
return websocket;
}
return http;
}
getMessage(id, options) {
if (!this.generateMessage) {
return
}
const candidate = this.generateMessage(id);
const message = typeof candidate === 'object' ? JSON.stringify(candidate) : candidate
if (this.options.indexParamFinder) {
return message.replace(this.options.indexParamFinder, options.customIndex);
}
return message
}
getRequest(id, options, requestFinished) {
const lib = this.getLib()
if (typeof this.params.requestGenerator == 'function') {
const connect = this.getConnect(id, requestFinished, this.params.contentInspector)
return this.params.requestGenerator(this.params, options, lib.request, connect);
}
return lib.request(options, this.getConnect(id, requestFinished, this.params.contentInspector));
}
/**

@@ -193,0 +225,0 @@ * Get a function that finishes one request and goes for the next.

@@ -26,3 +26,3 @@ import * as http from 'http'

* - method [string]: the method to use: POST, PUT. Default: GET, what else.
* - body [string]: the contents to send along a POST or PUT request.
* - data [string]: the contents to send along a POST or PUT request.
* - contentType [string]: the MIME type to use for the body, default text/plain.

@@ -37,2 +37,3 @@ * - requestsPerSecond [number]: how many requests per second to send.

* - debug: show debug messages (deprecated).
* - requestGenerator [function]: use a custom function to generate requests.
* - `callback`: optional `function(result, error)` called if/when the test finishes;

@@ -122,29 +123,5 @@ * if not present a promise is returned.

startClients() {
const url = this.options.url;
const strBody = JSON.stringify(this.options.body);
for (let index = 0; index < this.options.concurrency; index++) {
if (this.options.indexParam) {
let oldToken = new RegExp(this.options.indexParam, 'g');
if(this.options.indexParamCallback instanceof Function) {
let customIndex = this.options.indexParamCallback();
this.options.url = url.replace(oldToken, customIndex);
if(this.options.body) {
let body = strBody.replace(oldToken, customIndex);
this.options.body = JSON.parse(body);
}
}
else {
this.options.url = url.replace(oldToken, index);
if(this.options.body) {
let body = strBody.replace(oldToken, index);
this.options.body = JSON.parse(body);
}
}
}
let constructor = httpClient.create;
// TODO: || this.options.url.startsWith('wss:'))
if (this.options.url.startsWith('ws:')) {
constructor = websocket.create;
}
const client = constructor(this, this.options);
const createClient = this.getClientCreator()
const client = createClient(this, this.options);
this.clients[index] = client;

@@ -161,2 +138,10 @@ if (!this.options.requestsPerSecond) {

getClientCreator() {
// TODO: || this.options.url.startsWith('wss:'))
if (this.options.url.startsWith('ws:')) {
return websocket.create;
}
return httpClient.create;
}
/**

@@ -163,0 +148,0 @@ * Stop clients.

@@ -19,2 +19,3 @@ import * as http from 'http'

* - error: set an HTTP error code, default is 500.
* - logger: function to log all incoming requests.
* - `callback`: optional callback, called after the server has started.

@@ -122,6 +123,6 @@ * If not present will return a promise.

if (!this.options.delay) {
return this.end(response, id);
return this.end(request, response, id);
}
setTimeout(() => {
this.end(response, id);
this.end(request, response, id);
}, this.options.delay).unref();

@@ -172,3 +173,3 @@ });

*/
end(response, id) {
end(request, response, id) {
if (this.shouldError()) {

@@ -182,2 +183,5 @@ const code = this.options.error || 500;

this.latency.end(id);
if (this.options.logger) {
this.options.logger(request, response)
}
}

@@ -184,0 +188,0 @@

{
"name": "loadtest",
"version": "6.3.2",
"version": "6.4.0",
"type": "module",

@@ -5,0 +5,0 @@ "description": "Run load tests for your web application. Mostly ab-compatible interface, with an option to force requests per second. Includes an API for automated load testing.",

@@ -514,3 +514,2 @@ [![run on repl.it](http://repl.it/badge/github/alexfernandez/loadtest)](https://repl.it/github/alexfernandez/loadtest)

console.log('Tests run successfully')
})
```

@@ -888,2 +887,7 @@

#### `logger`
A function to be called as `logger(request, response)` after every request served by the test server.
Where `request` and `response` are the usual HTTP objects.
### Configuration file

@@ -890,0 +894,0 @@

@@ -162,2 +162,30 @@ import * as testing from 'testing'

async function testIndexParam() {
const urls = new Map()
const bodies = new Map()
function logger(request) {
if (urls.has(request.url)) {
throw new Error(`Duplicated url ${request.url}`)
}
urls.set(request.url, true)
if (bodies.has(request.body)) {
throw new Error(`Duplicated body ${request.body}`)
}
bodies.set(request.body, true)
}
const server = await startServer({logger, ...serverOptions})
const options = {
url: `http://localhost:${PORT}/?param=index`,
maxRequests: 100,
concurrency: 10,
postBody: {
hi: 'my_index',
},
indexParam: 'index',
quiet: true,
};
await loadTest(options)
await server.close()
}
/**

@@ -168,5 +196,6 @@ * Run all tests.

testing.run([
testIntegration, testIntegrationFile, testDelay, testWSIntegration, testPromise,
testIntegration, testIntegrationFile, testDelay, testWSIntegration,
testPromise, testIndexParam,
], 4000, callback);
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc