makiwara 2.0.6 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,10 +1,10 @@
1
- # makiwara ([npm](https://www.npmjs.com/package/makiwara))
1
+ # makiwara
2
2
 
3
3
  [![npm version](https://badge.fury.io/js/makiwara.svg)](https://badge.fury.io/js/makiwara)
4
4
  [![downloads count](https://img.shields.io/npm/dt/makiwara.svg)](https://www.npmjs.com/~piecioshka)
5
5
  [![travis](https://img.shields.io/travis/piecioshka/makiwara.svg)](https://travis-ci.org/piecioshka/makiwara)
6
6
  [![dependencies](https://david-dm.org/piecioshka/makiwara.svg)](https://github.com/piecioshka/makiwara)
7
- [![codecov](https://codecov.io/gh/piecioshka/makiwara/branch/master/graph/badge.svg)](https://codecov.io/gh/piecioshka/makiwara)
7
+ [![coveralls](https://coveralls.io/repos/github/piecioshka/makiwara/badge.svg?branch=master)](https://coveralls.io/github/piecioshka/makiwara?branch=master)
8
8
 
9
9
  :hammer: Benchmark URL to gain HTTP requests limits
10
10
 
@@ -19,7 +19,7 @@ npm install -g makiwara
19
19
  ```javascript
20
20
  const { attack } = require('makiwara');
21
21
 
22
- attack('http;//example.org', [1, 5, 10])
22
+ attack('http://example.org', [1, 5, 10], 'sequence')
23
23
  .then((result) => {
24
24
  console.log(result);
25
25
  })
@@ -30,63 +30,61 @@ attack('http;//example.org', [1, 5, 10])
30
30
 
31
31
  ## CLI
32
32
 
33
- ```bash
33
+ ```text
34
34
  makiwara --help
35
35
 
36
- Usage: cli [options]
36
+ Usage: cli [options]
37
37
 
38
+ Example:
39
+ makiwara -u http://localhost:3000 -t 10 -s sequence
38
40
 
39
- Options:
41
+ Options:
42
+ -V, --version output the version number
43
+ -u, --url <url> Define URL to attack. Ex. http://example.org/
44
+ -t, --timelimit [numbers] Define list of time thresholds (in seconds). Ex. 10,100,1000
45
+ -s, --strategy <concurrent|sequence> Define strategy for making requests
46
+ -h, --help output usage information
47
+ ```
40
48
 
41
- -V, --version output the version number
42
- -u, --url <url> Define URL to attack
43
- -t, --times [times] Define list of time thresholds (in seconds)
44
- -h, --help output usage information
49
+ ## Example
50
+
51
+ ```bash
52
+ makiwara -u https://example.org -t 1,5 -s sequence
45
53
  ```
46
54
 
55
+ Result:
56
+
47
57
  ```text
48
- Requests summary of 1 second(s):
49
- ╔══════════════════════╤═══════════════════════════╗
50
- ║ HTTP Status Code │ Quantity ║
51
- ╟──────────────────────┼───────────────────────────╢
52
- ║ 200 OK │ 3 ║
53
- ╚══════════════════════╧═══════════════════════════╝
54
-
55
- Attack summary of 1 second(s):
56
- ╔══════════════════════╤═══════════════════════════╗
57
- ║ Start time │ 2017-12-18T11:48:37.152Z ║
58
- ╟──────────────────────┼───────────────────────────╢
59
- ║ End time │ 2017-12-18T11:48:38.296Z ║
60
- ╟──────────────────────┼───────────────────────────╢
61
- ║ Duration │ 1144 ms ║
62
- ╟──────────────────────┼───────────────────────────╢
63
- ║ Time limit │ 1000 ms ║
64
- ╟──────────────────────┼───────────────────────────╢
65
- ║ Avg. request time │ 333.333 ms/req. ║
66
- ╚══════════════════════╧═══════════════════════════╝
67
58
 
68
- ----------------------------------------------------
59
+ ╔════════════════════════╤════════════════════════════════╗
60
+ ║ HTTP Status Code │ Requests quantity ║
61
+ ╟────────────────────────┼────────────────────────────────╢
62
+ ║ 200 OK │ 3 ║
63
+ ╚════════════════════════╧════════════════════════════════╝
69
64
 
70
- Requests summary of 5 second(s):
71
- ╔══════════════════════╤═══════════════════════════╗
72
- ║ HTTP Status Code │ Quantity ║
73
- ╟──────────────────────┼───────────────────────────╢
74
- ║ 200 OK │ 21 ║
75
- ╚══════════════════════╧═══════════════════════════╝
76
-
77
- Attack summary of 5 second(s):
78
- ╔══════════════════════╤═══════════════════════════╗
79
- ║ Start time │ 2017-12-18T11:48:37.153Z ║
80
- ╟──────────────────────┼───────────────────────────╢
81
- ║ End time │ 2017-12-18T11:48:42.265Z ║
82
- ╟──────────────────────┼───────────────────────────╢
83
- ║ Duration │ 5112 ms ║
84
- ╟──────────────────────┼───────────────────────────╢
85
- ║ Time limit │ 5000 ms ║
86
- ╟──────────────────────┼───────────────────────────╢
87
- ║ Avg. request time │ 238.095 ms/req. ║
88
- ╚══════════════════════╧═══════════════════════════╝
65
+ ╔════════════════════════╤════════════════════════════════╗
66
+ ║ Type │ Sequence ║
67
+ ╟────────────────────────┼────────────────────────────────╢
68
+ ║ Effective Duration │ 1.456 seconds ║
69
+ ╟────────────────────────┼────────────────────────────────╢
70
+ ║ Times │ 3 ║
71
+ ╚════════════════════════╧════════════════════════════════╝
72
+
73
+ ----------------------------------------------------
89
74
 
75
+ ╔════════════════════════╤════════════════════════════════╗
76
+ ║ HTTP Status Code │ Requests quantity ║
77
+ ╟────────────────────────┼────────────────────────────────╢
78
+ ║ 200 OK │ 10 ║
79
+ ╚════════════════════════╧════════════════════════════════╝
80
+
81
+ ╔════════════════════════╤════════════════════════════════╗
82
+ ║ Type │ Sequence ║
83
+ ╟────────────────────────┼────────────────────────────────╢
84
+ ║ Effective Duration │ 5.399 seconds ║
85
+ ╟────────────────────────┼────────────────────────────────╢
86
+ ║ Times │ 10 ║
87
+ ╚════════════════════════╧════════════════════════════════╝
90
88
  ```
91
89
 
92
90
  ## Unit tests
@@ -103,4 +101,4 @@ npm run coverage
103
101
 
104
102
  ## License
105
103
 
106
- [The MIT License](http://piecioshka.mit-license.org) @ 2017
104
+ [The MIT License](http://piecioshka.mit-license.org) @ 2017-2019
package/bin/cli.js CHANGED
@@ -1,31 +1,44 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- 'use strict';
4
-
5
3
  const fs = require('fs');
4
+ const path = require('path');
5
+
6
+ const http = require('http');
7
+ const https = require('https');
8
+ http.globalAgent.maxSockets = https.globalAgent.maxSockets = 512;
9
+ // http.globalAgent.maxFreeSockets = https.globalAgent.maxFreeSockets = 512;
10
+
6
11
  const program = require('commander');
7
12
  const ora = require('ora');
8
13
  const isUrl = require('is-url');
9
14
  const bold = require('ansi-bold');
10
15
 
11
- // eslint-disable-next-line no-sync
12
- const pkg = fs.readFileSync('../package.json').toJSON();
13
16
  const { attack } = require('../index');
17
+ const HTTP_STATUS = require('../src/http-status-codes');
14
18
  const { displaySummary, displayError } = require('../src/display');
19
+ const { makeRequest } = require('../src/make-requests');
20
+
21
+ // eslint-disable-next-line no-sync
22
+ const pkg = JSON.parse(fs.readFileSync(
23
+ path.join(__dirname, '..', 'package.json')
24
+ ).toString());
25
+ const STRATEGY_REGEXP = /^(concurrent|sequence)$/;
15
26
 
16
27
  program
17
28
  .version(pkg.version)
18
29
  .option('-u, --url <url>', 'Define URL to attack. Ex. http://example.org/')
19
30
  .option('-t, --timelimit [numbers]', 'Define list of time thresholds (in seconds). Ex. 10,100,1000')
31
+ .option('-s, --strategy <concurrent|sequence>', 'Define strategy for making requests')
32
+ .description('Example:\n\tmakiwara -u http://localhost:3000 -t 10 -s sequence')
20
33
  .parse(process.argv);
21
34
 
22
35
  if (typeof program.url !== 'string') {
23
- console.red('ERROR: url is not a string');
36
+ console.red('Error: url is not a string');
24
37
  program.help();
25
38
  }
26
39
 
27
40
  if (!isUrl(program.url)) {
28
- console.red(`ERROR: url is not correct format`);
41
+ console.red('Error: url is not correct format');
29
42
  program.help();
30
43
  }
31
44
 
@@ -35,8 +48,16 @@ if (!program.timelimit) {
35
48
  console.yellow(`Thresholds are sets to: ${bold(program.timelimit)} (seconds)\n`);
36
49
  }
37
50
 
51
+ if (!(STRATEGY_REGEXP).test(program.strategy)) {
52
+ program.strategy = 'concurrent';
53
+ console.yellow('Ups... you did not put "strategy"');
54
+ console.yellow(`Default strategy is: ${program.strategy}\n`);
55
+ }
56
+
38
57
  const url = program.url;
39
58
  const timeLimit = program.timelimit.split(',').map(Number);
59
+ const strategy = program.strategy;
60
+ let spinner = null;
40
61
 
41
62
  function displayDelimiter() {
42
63
  console.gray('----------------------------------------------------\n');
@@ -44,26 +65,49 @@ function displayDelimiter() {
44
65
 
45
66
  function displayHeader() {
46
67
  console.log(`${pkg.name}, Version ${pkg.version}`);
47
- console.log(`Copyright 2017 ${pkg.author.name} <${pkg.author.email}> ${pkg.author.url}`);
68
+ const currentYear = new Date().getFullYear();
69
+ console.log(`Copyright 2017-${currentYear} ${pkg.author.name} <${pkg.author.email}> ${pkg.author.url}`);
48
70
  console.log(`The ${pkg.license} License, https://piecioshka.mit-license.org/\n`);
49
71
  console.log(`> ${pkg.description}\n`);
50
72
  }
51
73
 
52
- displayHeader();
74
+ async function sendTestRequest(testUrl) {
75
+ spinner.succeed(`Start testing... ${bold(testUrl)}`);
76
+ const response = await makeRequest(testUrl, { agent: false });
77
+ if (response.status !== HTTP_STATUS.OK) {
78
+ console.red(`HTTP Status Code: ${bold(response.status)}`);
79
+ console.yellow(`Response Body: ${bold(response.text)}`);
80
+ }
81
+ spinner.succeed(`Testing completed (response: ${bold(response.text.length)} Bytes)`);
82
+ }
83
+
84
+ async function main() {
85
+ displayHeader();
53
86
 
54
- const spinner = ora('Loading').start();
87
+ spinner = ora('Loading').start();
55
88
 
56
- attack(url, timeLimit)
57
- .then((results) => {
89
+ try {
90
+ await sendTestRequest(url);
91
+
92
+ spinner.succeed('Start attacking...');
93
+ const results = await attack(url, timeLimit, strategy);
58
94
  spinner.stop();
95
+ spinner.succeed('Attacking completed\n');
96
+
59
97
  results.forEach((result, index) => {
60
98
  displaySummary(result);
99
+
61
100
  if (index < results.length - 1) {
62
101
  displayDelimiter();
63
102
  }
64
103
  });
65
- })
66
- .catch((err) => {
104
+ } catch (err) {
67
105
  spinner.stop();
68
106
  displayError(err);
69
- });
107
+ }
108
+
109
+ // eslint-disable-next-line no-process-exit
110
+ process.exit(0);
111
+ }
112
+
113
+ main();
package/index.js CHANGED
@@ -1,15 +1,19 @@
1
- 'use strict';
2
-
3
- const { makeRequests } = require('./src/make-requests');
1
+ const { makeRequestsInConcurrentMode, makeRequestsInSequenceMode } = require('./src/make-requests');
4
2
 
5
3
  require('./src/color-logs');
6
4
 
7
- function attack(url, timeLimits) {
8
- // Remove zeros timeLimits
5
+ const strategies = new Map();
6
+ strategies.set('sequence', makeRequestsInSequenceMode);
7
+ strategies.set('concurrent', makeRequestsInConcurrentMode);
8
+
9
+ function attack(url, timeLimits, strategy) {
10
+ const method = strategies.get(strategy);
11
+
9
12
  return Promise.all(
10
13
  timeLimits
14
+ // Remove zeros timeLimits
11
15
  .filter((k) => k)
12
- .map((duration) => makeRequests(url, duration))
16
+ .map((duration) => method(url, duration))
13
17
  );
14
18
  }
15
19
 
package/package.json CHANGED
@@ -1,71 +1,77 @@
1
1
  {
2
- "name": "makiwara",
3
- "description": "Benchmark URL to gain HTTP requests limits",
4
- "version": "2.0.6",
5
- "license": "MIT",
6
- "author": {
7
- "name": "Piotr Kowalski",
8
- "email": "piecioshka@gmail.com",
9
- "url": "https://piecioshka.pl/"
10
- },
11
- "scripts": {
12
- "clear": "rm -rf dist/ coverage/ .nyc_output/",
13
- "clear:all": "rm -rf node_modules/ && npm run clear",
14
- "test": "jasmine test/**",
15
- "coverage": "nyc npm run test && nyc report --reporter=html",
16
- "report-coverage": "nyc report --reporter=text-lcov > coverage.lcov && codecov",
17
- "lint": "eslint ."
18
- },
19
- "dependencies": {
20
- "@types/node": "^11.13.8",
21
- "ansi-bold": "^0.1.1",
22
- "ansi-cyan": "^0.1.1",
23
- "ansi-gray": "^0.1.1",
24
- "ansi-red": "^0.1.1",
25
- "ansi-yellow": "^0.1.1",
26
- "axios": "^0.18.0",
27
- "commander": "^2.20.0",
28
- "http-status-codes": "^1.3.2",
29
- "is-url": "^1.2.4",
30
- "ora": "^3.4.0",
31
- "table": "^5.2.3"
32
- },
33
- "devDependencies": {
34
- "codecov": "^3.3.0",
35
- "eslint": "^5.16.0",
36
- "eslint-config-piecioshka": "^2.0.1",
37
- "jasmine": "^3.4.0",
38
- "nyc": "^14.0.0"
39
- },
40
- "repository": {
41
- "type": "git",
42
- "url": "https://github.com/piecioshka/makiwara.git"
43
- },
44
- "bugs": {
45
- "url": "https://github.com/piecioshka/makiwara/issues"
46
- },
47
- "files": [
48
- "bin",
49
- "src",
50
- "index.js",
51
- "package.json",
52
- "README.md"
53
- ],
54
- "keywords": [
55
- "app",
56
- "test",
57
- "attack",
58
- "multi",
59
- "statistics",
60
- "summary",
61
- "metrics",
62
- "verify",
63
- "request",
64
- "time",
65
- "analyze",
66
- "cli",
67
- "commonjs"
68
- ],
69
- "main": "./index.js",
70
- "bin": "./bin/cli.js"
2
+ "name": "makiwara",
3
+ "description": "Benchmark URL to gain HTTP requests limits",
4
+ "version": "2.1.1",
5
+ "license": "MIT",
6
+ "author": {
7
+ "name": "Piotr Kowalski",
8
+ "email": "piecioshka@gmail.com",
9
+ "url": "https://piecioshka.pl/"
10
+ },
11
+ "scripts": {
12
+ "clear": "rm -rf dist/ coverage/ .nyc_output/",
13
+ "clear:all": "rm -rf node_modules/ && npm run clear",
14
+ "test": "jasmine test/specs/*.js",
15
+ "coverage": "nyc npm run test && nyc report --reporter=text-lcov | coveralls -v",
16
+ "lint": "eslint .",
17
+ "snyk-protect": "snyk protect",
18
+ "prepare": "npm run snyk-protect"
19
+ },
20
+ "dependencies": {
21
+ "@types/node": "^17.0.0",
22
+ "ansi-bold": "^0.1.1",
23
+ "ansi-cyan": "^0.1.1",
24
+ "ansi-gray": "^0.1.1",
25
+ "ansi-red": "^0.1.1",
26
+ "ansi-yellow": "^0.1.1",
27
+ "axios": "^0.24.0",
28
+ "commander": "^8.3.0",
29
+ "http-status-codes": "^2.1.4",
30
+ "is-url": "^1.2.4",
31
+ "node-fetch": "^3.1.0",
32
+ "ora": "^6.0.1",
33
+ "snyk": "^1.797.0",
34
+ "table": "^6.7.5"
35
+ },
36
+ "devDependencies": {
37
+ "@types/jasmine": "^3.10.2",
38
+ "coveralls": "^3.1.1",
39
+ "eslint": "^8.5.0",
40
+ "eslint-config-piecioshka": "^2.0.4",
41
+ "jasmine": "^3.10.0",
42
+ "nock": "^13.2.1",
43
+ "nyc": "^15.1.0"
44
+ },
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "https://github.com/piecioshka/makiwara.git"
48
+ },
49
+ "bugs": {
50
+ "url": "https://github.com/piecioshka/makiwara/issues"
51
+ },
52
+ "files": [
53
+ "bin",
54
+ "src",
55
+ "index.js",
56
+ "package.json",
57
+ "README.md"
58
+ ],
59
+ "keywords": [
60
+ "app",
61
+ "test",
62
+ "attack",
63
+ "multi",
64
+ "statistics",
65
+ "summary",
66
+ "metrics",
67
+ "verify",
68
+ "request",
69
+ "time",
70
+ "analyze",
71
+ "cli",
72
+ "commonjs"
73
+ ],
74
+ "main": "./index.js",
75
+ "bin": "./bin/cli.js",
76
+ "snyk": true
71
77
  }
package/src/color-logs.js CHANGED
@@ -1,5 +1,3 @@
1
- 'use strict';
2
-
3
1
  function setupColorLogFunction(name) {
4
2
  const fn = require(`ansi-${name}`);
5
3
  console[name] = (...args) => console.log(...args.map(fn));
package/src/display.js CHANGED
@@ -1,14 +1,14 @@
1
- 'use strict';
2
-
3
1
  const { table } = require('table');
4
2
  const HTTPStatusCodes = require('http-status-codes');
5
3
  const bold = require('ansi-bold');
6
4
 
7
5
  const { collapseArray } = require('./object-util');
8
6
 
7
+ const SECOND_IN_MILLISECONDS = 1000;
8
+
9
9
  const tableOptions = {
10
10
  columns: {
11
- 0: { width: 20 },
11
+ 0: { width: 22 },
12
12
  1: { width: 30 }
13
13
  }
14
14
  };
@@ -29,26 +29,28 @@ function appendHttpStatusCodeLabel(statusCodeEntries) {
29
29
 
30
30
  function displayRequestsSummary(attackResults) {
31
31
  const statusCodes = collapseArray(
32
- attackResults.requests.map((r) => r.statusCode)
32
+ attackResults.requests.map((r) => r.status)
33
33
  );
34
34
  const isEmptyResults = (statusCodes.length === 0);
35
35
 
36
36
  if (isEmptyResults) {
37
- console.log(' No request were sent\n');
37
+ statusCodes['-'] = -1;
38
38
  } else {
39
39
  appendHttpStatusCodeLabel(statusCodes);
40
- const data = [['HTTP Status Code', 'Requests quantity'].map(bold)]
41
- .concat(statusCodes);
42
- console.log(table(data, tableOptions));
43
40
  }
41
+
42
+ const data = [['HTTP Status Code', 'Requests quantity']
43
+ .map(bold)]
44
+ .concat(statusCodes);
45
+ console.log(table(data, tableOptions));
44
46
  }
45
47
 
46
- function displayAttackSummary(attackResults) {
48
+ function displayAttackSummary(results) {
47
49
  const meta = [];
48
- meta.push(['Concurrency Level', 1]);
49
- meta.push(['Time taken for tests', `${(attackResults.duration / 1000).toLocaleString()} seconds`]);
50
- const rps = (attackResults.requests.length / attackResults.duration * 1000);
51
- meta.push(['Requests per second', `${rps.toFixed(3)} [#/sec] (mean)`]);
50
+ meta.push(['Type', results.type]);
51
+ const durationInSeconds = (results.duration / SECOND_IN_MILLISECONDS);
52
+ meta.push(['Effective Duration', `${durationInSeconds.toLocaleString()} seconds`]);
53
+ meta.push(['Times', `${results.times}`]);
52
54
  console.log(table(meta, tableOptions));
53
55
  }
54
56
 
@@ -0,0 +1,6 @@
1
+ module.exports = {
2
+ OK: 200,
3
+ NO_CONTENT: 204,
4
+ PERMISSION_DENIED: 403,
5
+ NOT_FOUND: 404,
6
+ };
@@ -0,0 +1,36 @@
1
+ const http = require('http');
2
+ const https = require('https');
3
+
4
+ const IS_HTTP = (/^https/);
5
+
6
+ function getProtocol(url) {
7
+ if (IS_HTTP.test(url)) {
8
+ return https;
9
+ }
10
+ return http;
11
+ }
12
+
13
+ async function makeRequest(url, options = {}) {
14
+ const response = {
15
+ status: null,
16
+ text: '',
17
+ };
18
+ const protocol = getProtocol(url);
19
+ return new Promise((resolve, reject) => {
20
+ protocol.get(url, options, (res) => {
21
+ res.addListener('data', (data) => {
22
+ response.text += data.toString();
23
+ });
24
+ res.addListener('error', (err) => {
25
+ reject(err);
26
+ });
27
+ res.addListener('end', () => {
28
+ response.status = res.statusCode;
29
+ resolve(response);
30
+ });
31
+ });
32
+ });
33
+ }
34
+
35
+ module.exports = makeRequest;
36
+ module.exports.makeRequest = makeRequest;
@@ -1,70 +1,111 @@
1
- 'use strict';
2
-
3
- const request = require('axios');
4
-
5
- /**
6
- * @param {string} url
7
- * @returns {Promise}
8
- */
9
- async function fetchStatusCode(url) {
10
- try {
11
- const response = await request.get(url);
12
- return response.status;
13
- } catch (err) {
14
- if (err.response) {
15
- return err.response.status;
16
- }
17
- return 0;
18
- }
1
+ const http = require('http');
2
+
3
+ // const makeRequest = require('node-fetch');
4
+ const makeRequest = require('./local-fetch');
5
+
6
+ const SECOND_IN_MILLISECONDS = 1000;
7
+
8
+ function pause(timeoutInSeconds) {
9
+ return new Promise((resolve) => {
10
+ setTimeout(resolve, timeoutInSeconds * SECOND_IN_MILLISECONDS);
11
+ });
19
12
  }
20
13
 
21
- /**
22
- * @param {string} url
23
- * @param {number} durationLimit - In seconds
24
- * @returns {Promise}
25
- */
26
- async function makeRequests(url, durationLimit) {
27
- durationLimit = Number(durationLimit);
14
+ function status(i) {
15
+ if (global.spinner) {
16
+ global.spinner.text = `Loading: ${i} time(s)`;
17
+ global.spinner.render();
18
+ }
19
+ }
28
20
 
29
- if (Number.isNaN(durationLimit)) {
30
- throw new TypeError('Put numer of durationLimit time of making requests (ex. 1,3,5)');
21
+ async function makeRequestsInConcurrentMode(url, durationInSeconds) {
22
+ if (isNaN(durationInSeconds)) {
23
+ throw new TypeError('duration should be a number (ex. 1,3,5)');
31
24
  }
32
25
 
33
- const millisecondTimeLimit = durationLimit * 1000;
34
26
  const requests = [];
35
27
  const startTime = Date.now();
28
+ const durationInMilliseconds = durationInSeconds * SECOND_IN_MILLISECONDS;
29
+ let i = 0;
36
30
 
31
+ // eslint-disable-next-line no-constant-condition
37
32
  while (true) {
38
- const startRequestTime = Date.now();
39
- const statusCode = await fetchStatusCode(url);
40
- const endRequestTime = Date.now();
41
- const requestDuration = (endRequestTime - startRequestTime);
33
+ const currentTime = Date.now();
42
34
 
43
- const diffTime = (endRequestTime - startTime);
44
- const offset = (diffTime - millisecondTimeLimit);
35
+ if (i >= http.globalAgent.maxSockets) {
36
+ break;
37
+ }
45
38
 
46
- if (offset > 0) {
39
+ if (currentTime > startTime + durationInMilliseconds) {
47
40
  break;
48
41
  }
49
42
 
50
- requests.push({
51
- statusCode,
52
- duration: requestDuration
53
- });
43
+ i++;
44
+
45
+ status(i);
46
+
47
+ await makeRequest(url, { agent: false })
48
+ .then((response) => {
49
+ requests.push(response);
50
+ });
51
+ }
52
+
53
+ const endTime = Date.now();
54
+ const wholeProcessDuration = endTime - startTime;
55
+
56
+ await pause(durationInSeconds);
57
+
58
+ return {
59
+ type: 'Concurrent',
60
+ startTime,
61
+ endTime,
62
+ duration: wholeProcessDuration,
63
+ times: i,
64
+ requests
65
+ };
66
+ }
67
+
68
+ async function makeRequestsInSequenceMode(url, durationInSeconds) {
69
+ if (isNaN(durationInSeconds)) {
70
+ throw new TypeError('duration should be a number (ex. 1,3,5)');
71
+ }
72
+
73
+ const requests = [];
74
+ const startTime = Date.now();
75
+ const durationInMilliseconds = durationInSeconds * SECOND_IN_MILLISECONDS;
76
+ let i = 0;
77
+
78
+ // eslint-disable-next-line no-constant-condition
79
+ while (true) {
80
+ const currentTime = Date.now();
81
+
82
+ if (currentTime > startTime + durationInMilliseconds) {
83
+ break;
84
+ }
85
+
86
+ i++;
87
+
88
+ status(i);
89
+
90
+ const response = await makeRequest(url, { agent: false });
91
+ requests.push(response);
54
92
  }
55
93
 
56
94
  const endTime = Date.now();
57
- const duration = endTime - startTime;
95
+ const wholeProcessDuration = endTime - startTime;
58
96
 
59
97
  return {
98
+ type: 'Sequence',
60
99
  startTime,
61
100
  endTime,
62
- durationLimit,
63
- duration,
101
+ duration: wholeProcessDuration,
102
+ times: i,
64
103
  requests
65
104
  };
66
105
  }
67
106
 
68
107
  module.exports = {
69
- makeRequests
108
+ makeRequest,
109
+ makeRequestsInSequenceMode,
110
+ makeRequestsInConcurrentMode
70
111
  };
@@ -1,5 +1,3 @@
1
- 'use strict';
2
-
3
1
  function collapseArray(array) {
4
2
  const hashMap = array.reduce((mem, item) => {
5
3
  if (!mem[item]) {