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

logiload

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

logiload - npm Package Compare versions

Comparing version 0.0.5 to 0.4.0

9

bin/run.js

@@ -18,6 +18,6 @@ #!/usr/bin/env node

, o = require('o-core')
, runner = require('../lib/runner')
, log = logger.getLogger('run')
, macro = path.join( process.cwd(), args.macro )
, starttime
, runner
;

@@ -43,3 +43,3 @@

starttime = Date.now();
runner(macro, function(e, macro) {
runner = require('../lib/runner')(macro, function(e, macro) {
//TODO final stats

@@ -49,2 +49,5 @@ log[ e ? "error" : "info" ]("Complete in [%ss], with ", (Date.now() - starttime ) / 1000, e || "SUCCESS");

if (macro.stats.errored) log.warn("Counted total of [%s] errors", macro.stats.errored);
})
});
process.on('SIGINT' , runner.stop );
process.on('SIGTERM', runner.stop );

@@ -19,3 +19,3 @@ var fs = require('fs')

csv = fs.createWriteStream(filename, {'flags': 'a'});
csv = fs.createWriteStream(filename, { flags: 'a' });
if (!exists)

@@ -37,12 +37,12 @@ csv.write( fields.map(function(c) { return options.columns[c] }).join(",") + "\n" );

csv.write(",");
};
}
csv.write(String(rslt[ fields[i] ] || ""));
csv.write("\n",cb);
csv.write("\n",cb)
}
, end:
function csv_end(m,f) {
function csv_end(msg,cb) {
log.info("[%s] - closing" , filename);
csv.end(m,f)
csv.end(msg,cb)
}
}
}

@@ -0,0 +0,0 @@ var log = require('log4js').getLogger('logiload')

@@ -26,11 +26,7 @@ var async = require('async')

, sid = 0 //sid = step id
, lastRPS = 0 //Request Per Second
, csvStats
, csvReq
, secIntrv
, statsIntrv
;
ctx.agents = [];
ctx.byUrl = {};
//prepare stats bag per step

@@ -52,3 +48,3 @@ ctx.scenario.forEach(function(step) {

macro.samples = [];
macro.samples = 1;
nextSample();

@@ -63,3 +59,3 @@

macro.sid = 0;
macro.starttime = new Date();
macro.starttime = Date.now();

@@ -132,6 +128,5 @@ //init CSV output

}
}
secIntrv = setInterval(
statsIntrv = setInterval(
function() {

@@ -144,8 +139,14 @@ dumpStatsRow();

macro.terminate = 0;
async.whilst(
function() {
if (total)
if (macro.terminate) return false;
if (total >= 0) {
log.debug("%s more agent(s) to go", total);
return total--;
return total--
}
log.debug("agent #%s done", - --total);
return true;
}

@@ -159,22 +160,39 @@ , agent_start

);
return {
stop: function() {
switch(++macro.terminate) {
case 1:
log.warn("Term signal: No more agents will be created. Expecting %s agents to finish. Last agent: ", macro.stats.expected, agentId - 1);
return;
case 2:
log.warn("2nd Term signal: No more requests will be fired")
return;
case 3:
log.fatal("3rd Term signal: Hard abort");
cleanup(done)
case 4:
log.fatal("4th Term signal: force-exitting");
process.exit();
}
}
}
//called when whilst signals true
function agent_start(next) {
var agent = run_user(ctx
, function agent_finished(e) {
//TODO - check if to restart the user
//if (testDur && ) {
//}
if (--macro.stats.expected)
return log.info("[a#%s] - finished. expecting %s more agents to finish", agent.id );
cleanup(done);
}
);
var agentId =
run_user(ctx
, function agent_finished(e) {
//TODO - implement mode of test-duration, as opposed to total users
//if (testDur && ) {}
macro.stats.dur = Date.now() - macro.starttime;
if (--macro.stats.expected)
return log.info("[a#%s] - finished. Current stats:", agentId, macro.stats );
cleanup(done);
}
).id;
setTimeout(next, arrivIntr)
}
//called upon interval

@@ -212,3 +230,3 @@ function dumpStatsRow(f) {

//clear interval
clearInterval(secIntrv);
clearInterval(statsIntrv);

@@ -241,6 +259,3 @@ //dump & close csvs

//TODO - skip keeping samples for very big tests
macro.samples.push(macro.sample);
macro.sample.sid = macro.samples.length;
macro.sample.sid = macro.samples++;
}

@@ -263,7 +278,8 @@ }

log.debug("[%s] - constructed", agent.id);5/7/2015
log.debug("[%s] - constructed", agent.id);
async.eachSeries( macro.scenario
, function(step, next) {
step.starttime = Date.now();
, function(step, next) {
if (macro.terminate >= 2) return next({ message: "ABORTED" });
stepTypes[ step.type ](

@@ -299,5 +315,6 @@ { agent: agent

//TODO: count the brutally errored users
log[e?"error":"info"]( "[a#%s] - finished with %s, stats: ", agent.id, e ? e.message : "SUCCESS", stats);
log[e && e.message != "ABORTED" ?"error":"info"]( "[a#%s] - finished with %s, stats: ", agent.id, e ? e.message : "SUCCESS", stats);
if (e && "ABORTED" == e.message) e = null;
fFinished(e);

@@ -304,0 +321,0 @@ }

@@ -8,7 +8,7 @@ var format = require('util').format

function Stats() {
this.min = 999999;
this.max = 0;
this.sum = 0;
this.count= 0;
this.avg = null
this.min = 999999;
this.max = 0;
this.sum = 0;
this.count = 0;
this.avg = null
}

@@ -15,0 +15,0 @@

@@ -25,3 +25,2 @@ var LOG = require('log4js').getLogger('lib/steps/req')

, function(reqInfo, next) {
//TODO: let the user provide req object, ready to fire with request
//TODO: add event hooks to measures

@@ -33,5 +32,5 @@ // - connect time - until connected

var reqStats = reqInfo.stats
, req = reqOf(reqInfo, agent)
, rid = reqInfo.id
, url = parameterize(agent.params, reqInfo.get).replace(/,/g,"%2C")
, rslt =
, rslt =
{ aid : aid

@@ -41,3 +40,4 @@ , step : step.name

, starttime : Date.now()
, url : url
, req : req
, url : req.url
}

@@ -47,12 +47,6 @@ , sec

log.info("[a#%s/r#%s] - firing: ", aid, rid, url );
log.info("[a#%s/r#%s] - firing %s: ", aid, rid, req.method || "GET", req.url );
request(
{ url : url
, jar : agent.jar
, headers:
//TODO - let user-code pass headers
{ "user-agent" : "logiload stress tester"
}
}
req.jar = agent.jar;
request( req
, function(e,r) {

@@ -107,3 +101,3 @@ var dur =

if (e) {
e.reqUrl = url;
e.req = req;
e.responseBody = (r || e).body;

@@ -126,2 +120,3 @@ e.httpCode = (r || e).statusCode;

);
delete req.jar;

@@ -137,6 +132,29 @@ macro.onRequest()

function parameterize(params, url) {
return url.replace(/\%\%_([^%]+)\%\%/g, function(_,p) {
return params[p];
})
function reqOf(reqInfo, agent) {
if ('string' == typeof reqInfo) reqInfo = { req: { url: reqInfo } };
var req = reqInfo.req /* backward compatibility: */|| { url: reqInfo.get };
if (!req.headers) req.headers = {};
if (!req.headers["user-agent"]) req.headers["user-agent"] = "logiload stress tester";
req = parameterize( req, agent.params );
if (!req.timeout) req.timeout = agent.params.reqTimeout;
return req;
}
function parameterize(v, params) {
var k, o;
switch(typeof v) {
case 'string' :
return v.replace(/\%\%_([^%]+)\%\%/g, function(_,p) {
return params[p];
});
case 'object' :
o = {};
for (k in v) o[k] = parameterize(v[k], params);
return o
default:
return v
}
}
{
"name": "logiload",
"version": "0.0.5",
"version": "0.4.0",
"description": "",

@@ -5,0 +5,0 @@ "main": "lib",

@@ -6,17 +6,60 @@ logiload

Features overview
=================
*) url parameterization
*) any setting can be overriden usign CLI switches
*) patterned file-names
*) output request stat info into req.csv
*) output overview stats into stats.csv
- describe your test as a data-structure simply exported by a node-module
- use request parameterization to express your logic
- override any setting given in the scenario usign CLI switches
- writes it's output to patterned file-names
- output request stat info into req.csv
- output overview stats into stats.csv
- run modes:
- to a given number of times to run the scenario (by providing -n <num-of-times>)
- until SIGTERM/SIGINT (by prviding -n-1)
- Command types:
- req - to fire one or more requests in parallel
- wait - thinktime between simulated page-views
- uses a bell curve to spread think times for more humanlike behavior
url parameterization
Request parameterization
---
TBD
Parameterizing of parts in request descriptors are done using the tsung placeholders style,
i.e using placeholders wrapped with `%%_` and `%%`, example: `%%_param1%%` will replace this expression with the value in `agent.params.param1`.
`agent.params` collection starts as a clone of the `macro.options.params` provided by the user.
User may manipulate the `agent.params` using `onResponse(err, response)` hook,
which is called on a context with reference to `agent`.
Note in the following example how the 2nd request adds to the cart the product-id returned by the 1st request.
```
module.exports =
{ options:
{ params:
{ env: "stage"
}
, scenario:
[ { type: "req"
req :
[ "http://%%_env%%.mydomain.com/promo-data"
]
, onResponse: function(e, r) {
if (e) throw e;
this.agent.params.product = JSON.parse(r.body).product
}
}
, { type: "wait", wait: 1500 }
, { type: "req"
req:
[ { method: "POST"
, url: "http://%%_env%%.mydomain.com/addToChart"
, body: {
pid: "%%_product%%"
}
}
]
}
]
}
}
```
any setting can be overriden usign CLI switches

@@ -23,0 +66,0 @@ ---

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