forked from JCMais/node-libcurl
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathstress-test.js
153 lines (119 loc) · 3.43 KB
/
stress-test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/**
* Copyright (c) Jonathan Cardoso Machado. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/*
* This script does a stress test on the given domain.
* Don't put a real domain here if you don't want to be blocked by some DDOS Protection.
*/
const path = require('path')
const Curl = require('../lib/Curl')
const url = 'http://127.0.0.1:8080'
const file = 'file:///' + path.join(__dirname, 'test.txt')
// 25 instances running at max per iteration
const instances = 25
// 10000 requests in total per iteration
const maxRequests = 1e4
// repeat n times to collect data
const iterations = 3
const precision = 3
const shouldTestFile = false
const shouldUseHeaderRequest = true
const requestData = []
const timeBetweenStdouWrite = 1000
let finishedRequests = 0
let runningRequests = 0
let currentIteration = 0
let lastTimeStdoutWrite = 0
function doRequest(data) {
const curl = new Curl()
curl.setOpt(Curl.option.URL, shouldTestFile ? file : url)
curl.setOpt(Curl.option.NOBODY, shouldUseHeaderRequest)
curl.setOpt(Curl.option.CONNECTTIMEOUT, 5)
curl.setOpt(Curl.option.TIMEOUT, 10)
curl.on('end', cb.bind(curl))
curl.on('error', cb.bind(curl))
curl.data = data
curl.perform()
++runningRequests
}
function cb(code) {
const { data } = this
const now = Date.now()
let shouldWrite = false
if (now - lastTimeStdoutWrite >= timeBetweenStdouWrite) {
shouldWrite = true
lastTimeStdoutWrite = now
}
this.close()
if (code instanceof Error) {
++data.errors
}
--runningRequests
++finishedRequests
if (finishedRequests + runningRequests < maxRequests) {
doRequest(data)
}
if (shouldWrite) {
console.info(
'Curl instances: ',
Curl.getCount(),
' -> Requests finished: ',
finishedRequests,
' -> Time: ',
process.hrtime(data.startTime)[0],
's',
)
}
if (runningRequests === 0) {
//nano to milli
data.endTime = process.hrtime(data.startTime)
console.info(
'Request time: ',
data.endTime[0] +
's, ' +
(data.endTime[1] / 1e9).toFixed(precision) +
'ms',
)
process.nextTick(startRequests)
}
}
function startRequests() {
if (currentIteration == iterations) {
return printCollectedData()
}
console.log('Iteration -> ', currentIteration + 1)
finishedRequests = 0
runningRequests = 0
if (requestData[currentIteration] === undefined) {
requestData[currentIteration] = {
errors: 0,
startTime: process.hrtime(),
endTime: 0,
}
}
for (let i = 0; i < instances; i++) {
doRequest(requestData[currentIteration])
}
return currentIteration++
}
function printCollectedData() {
//Sum all timings
const timingSumNs = requestData.reduce((prev, curr) => {
const currTimingNs = curr.endTime[0] * 1e9 + curr.endTime[1]
return prev + currTimingNs
}, 0)
const errors = requestData.reduce((prev, curr) => {
return prev + curr.errors
}, 0)
console.info('Iterations ------------ ', iterations)
console.info('Requests ------------ ', maxRequests)
console.info('Instances ------------ ', instances)
console.info('Total Time ------------ ', timingSumNs / 1e9 + 's')
console.info('Iteration Avg --------- ', timingSumNs / 1e9 / iterations + 's')
console.info('Errors Avg ------------ ', errors)
}
console.log('Starting...')
process.nextTick(startRequests)