Comparing version 6.3.2 to 6.4.0
@@ -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); | ||
} | ||
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
104103
2375
955