Repository: mcollina/autocannon
Pull request #368 (2021-05-05 14:29:54)

fix(multi workers and input file): working with multiple workers and…
… input file

Closes https://github.com/mcollina/autocannon/issues/356


Patch:
diff --git a/autocannon.js b/autocannon.js
index e3ed8e3..91db9a3 100755
--- a/autocannon.js
+++ b/autocannon.js
@@ -154,7 +154,7 @@ function parseArguments (argvs) {
   })
 
   if (argv.input) {
-    argv.body = fs.readFileSync(argv.input)
+    argv.body = fs.readFileSync(argv.input, 'utf8')
   }
 
   if (argv.headers) {
diff --git a/lib/requestIterator.js b/lib/requestIterator.js
index 0a1c4eb..1402dbd 100644
--- a/lib/requestIterator.js
+++ b/lib/requestIterator.js
@@ -88,7 +88,7 @@ RequestIterator.prototype.rebuildRequest = function () {
   let data
   this.resetted = false
   if (this.currentRequest) {
-    this.currentRequest.headers = this.headers
+    this.currentRequest.headers = this.currentRequest.headers || this.headers
     data = this.requestBuilder(this.currentRequest, this.context)
     if (data) {
       this.currentRequest.requestBuffer = this.reqDefaults.idReplacement


Test patch:
diff --git a/test/argumentParsing.test.js b/test/argumentParsing.test.js
index 9131f2a..4ed1b13 100644
--- a/test/argumentParsing.test.js
+++ b/test/argumentParsing.test.js
@@ -2,6 +2,7 @@
 
 const test = require('tap').test
 const Autocannon = require('../autocannon')
+const fs = require('fs')
 
 test('parse argument', (t) => {
   t.plan(4)
@@ -158,3 +159,21 @@ test('parse argument with multiple url', (t) => {
   t.equal(args.url[0], 'http://localhost/foo/bar')
   t.equal(args.url[1], 'http://localhost/baz/qux')
 })
+
+test('parse argument with input file and multiple workers', (t) => {
+  t.plan(3)
+
+  const inputPath = 'help.txt'
+  const args = Autocannon.parseArguments([
+    '-m', 'POST',
+    '-w', '2',
+    '-a', 10,
+    '-i', inputPath,
+    '-H', 'Content-Type=application/json',
+    'http://localhost/foo/bar'
+  ])
+
+  t.equal(args.url, 'http://localhost/foo/bar')
+  t.equal(args.method, 'POST')
+  t.equal(args.body, fs.readFileSync(inputPath, 'utf8'))
+})
diff --git a/test/httpClient.test.js b/test/httpClient.test.js
index 5f33eac..e1d663f 100644
--- a/test/httpClient.test.js
+++ b/test/httpClient.test.js
@@ -287,6 +287,34 @@ test('client supports custom headers', (t) => {
   })
 })
 
+test('client supports custom headers in requests', (t) => {
+  t.plan(2)
+
+  const opts = server.address()
+  opts.requests = [
+    {
+      path: '/',
+      method: 'POST',
+      headers: {
+        'content-type': 'application/json'
+      },
+      body: JSON.stringify({
+        foo: 'example'
+      })
+    }
+  ]
+  const client = new Client(opts)
+
+  server.once('request', (req, res) => {
+    t.equal(req.headers['content-type'], 'application/json', 'custom header matches')
+  })
+
+  client.on('response', (statusCode, length) => {
+    t.equal(statusCode, 200, 'status code matches')
+    client.destroy()
+  })
+})
+
 test('client supports host custom header', (t) => {
   t.plan(2)
 
diff --git a/test/requestIterator.test.js b/test/requestIterator.test.js
index fac1860..e35e04f 100644
--- a/test/requestIterator.test.js
+++ b/test/requestIterator.test.js
@@ -44,6 +44,35 @@ test('request iterator should create requests with overwritten defaults', (t) =>
     'request is okay')
 })
 
+test('request iterator should use headers from requests', (t) => {
+  t.plan(2)
+
+  const opts = server.address()
+  opts.requests = [
+    {
+      path: '/',
+      method: 'POST',
+      headers: {
+        'content-type': 'application/json'
+      },
+      body: JSON.stringify({ foo: 'bar' })
+    },
+    {
+      path: '/2',
+      method: 'POST',
+      headers: {
+        'content-type': 'text/html'
+      },
+      body: JSON.stringify({ foo: 'bar' })
+    }
+  ]
+  const iterator = new RequestIterator(opts)
+
+  t.same(iterator.currentRequest.headers['content-type'], 'application/json')
+  iterator.nextRequest()
+  t.same(iterator.currentRequest.headers['content-type'], 'text/html')
+})
+
 test('request iterator should create requests with overwritten defaults', (t) => {
   t.plan(3)