Repository: mcollina/autocannon
Pull request #501 (2023-11-22 17:47:54)

doc: adjust alignement
As titled


Patch:
diff --git a/README.md b/README.md
index e1ca406..e75e447 100644
--- a/README.md
+++ b/README.md
@@ -98,12 +98,13 @@ Available options:
   -R/--overallRate NUM
         The max number of requests to make per second from all connections.
         connection rate will take precedence if both are set.
-        NOTE: if using rate limiting and a very large rate is entered which cannot be met,
-              Autocannon will do as many requests as possible per second. Also, latency data will be corrected to compensate for the effects of the coordinated omission issue. If you are not familiar with the coordinated omission issue, you should probably read [this article](http://highscalability.com/blog/2015/10/5/your-load-generator-is-probably-lying-to-you-take-the-red-pi.html) or watch this [Gil Tene's talk](https://www.youtube.com/watch?v=lJ8ydIuPFeU) on the topic.
+        NOTE: if using rate limiting and a very large rate is entered which cannot be met, Autocannon will do as many requests as possible per second.
+        Also, latency data will be corrected to compensate for the effects of the coordinated omission issue.
+        If you are not familiar with the coordinated omission issue, you should probably read [this article](http://highscalability.com/blog/2015/10/5/your-load-generator-is-probably-lying-to-you-take-the-red-pi.html) or watch this [Gil Tene's talk](https://www.youtube.com/watch?v=lJ8ydIuPFeU) on the topic.
   -C/--ignoreCoordinatedOmission
         Ignore the coordinated omission issue when requests should be sent at a fixed rate using 'connectionRate' or 'overallRate'.
         NOTE: it is not recommended to enable this option.
-              When the request rate cannot be met because the server is too slow, many request latencies might be missing and Autocannon might report a misleading latency distribution.
+        When the request rate cannot be met because the server is too slow, many request latencies might be missing and Autocannon might report a misleading latency distribution.
   -D/--reconnectRate NUM
         The number of requests to make before resetting a connections connection to the
         server.
@@ -136,6 +137,8 @@ Available options:
         Print connection errors to stderr.
   -v/--version
         Print the version number.
+  -V/--verbose
+        Print the table with results. default: true.
   -h/--help
         Print this menu.
 ```
diff --git a/autocannon.js b/autocannon.js
index a4fb91e..5d885c8 100755
--- a/autocannon.js
+++ b/autocannon.js
@@ -71,6 +71,7 @@ const alias = {
   renderProgressBar: 'progress',
   renderStatusCodes: 'statusCodes',
   title: 'T',
+  verbose: 'V',
   version: 'v',
   forever: 'f',
   idReplacement: 'I',
@@ -98,12 +99,13 @@ const defaults = {
   idReplacement: false,
   excludeErrorStats: false,
   debug: false,
-  workers: 0
+  workers: 0,
+  verbose: true
 }
 
 function parseArguments (argvs) {
   let argv = subarg(argvs, {
-    boolean: ['json', 'n', 'help', 'renderLatencyTable', 'renderProgressBar', 'renderStatusCodes', 'forever', 'idReplacement', 'excludeErrorStats', 'onPort', 'debug', 'ignoreCoordinatedOmission'],
+    boolean: ['json', 'n', 'help', 'renderLatencyTable', 'renderProgressBar', 'renderStatusCodes', 'forever', 'idReplacement', 'excludeErrorStats', 'onPort', 'debug', 'ignoreCoordinatedOmission', 'verbose'],
     alias,
     default: defaults,
     '--': true
diff --git a/lib/printResult.js b/lib/printResult.js
index 0563190..5b3b096 100644
--- a/lib/printResult.js
+++ b/lib/printResult.js
@@ -11,65 +11,67 @@ const defaults = {
   // use stderr as its progressBar's default
   outputStream: process.stderr,
   renderResultsTable: true,
-  renderLatencyTable: false
+  renderLatencyTable: false,
+  verbose: true
 }
 
 const printResult = (result, opts) => {
   opts = Object.assign({}, defaults, opts)
   let strResult = ''
 
-  const chalk = new Chalk.Instance(testColorSupport({ stream: opts.outputStream, alwaysReturn: true }))
+  if (opts.verbose) {
+    const chalk = new Chalk.Instance(testColorSupport({ stream: opts.outputStream, alwaysReturn: true }))
 
-  const shortLatency = new Table({
-    head: asColor(chalk.cyan, ['Stat', '2.5%', '50%', '97.5%', '99%', 'Avg', 'Stdev', 'Max'])
-  })
-  shortLatency.push(asLowRow(chalk.bold('Latency'), asMs(result.latency)))
-  logToLocalStr('\n' + shortLatency.toString())
-
-  const requests = new Table({
-    head: asColor(chalk.cyan, ['Stat', '1%', '2.5%', '50%', '97.5%', 'Avg', 'Stdev', 'Min'])
-  })
-
-  requests.push(asHighRow(chalk.bold('Req/Sec'), asNumber(result.requests)))
-  requests.push(asHighRow(chalk.bold('Bytes/Sec'), asBytes(result.throughput)))
-  logToLocalStr(requests.toString())
-
-  if (opts.renderStatusCodes === true) {
-    const statusCodeStats = new Table({
-      head: asColor(chalk.cyan, ['Code', 'Count'])
+    const shortLatency = new Table({
+      head: asColor(chalk.cyan, ['Stat', '2.5%', '50%', '97.5%', '99%', 'Avg', 'Stdev', 'Max'])
     })
-    Object.keys(result.statusCodeStats).forEach(statusCode => {
-      const stats = result.statusCodeStats[statusCode]
-      const colorize = colorizeByStatusCode(chalk, statusCode)
-      statusCodeStats.push([colorize(statusCode), stats.count])
-    })
-    logToLocalStr(statusCodeStats.toString())
-  }
+    shortLatency.push(asLowRow(chalk.bold('Latency'), asMs(result.latency)))
+    logToLocalStr('\n' + shortLatency.toString())
 
-  logToLocalStr('')
-  if (result.sampleInt === 1000) {
-    logToLocalStr('Req/Bytes counts sampled once per second.')
-  } else {
-    logToLocalStr('Req/Bytes counts sampled every ' + result.sampleInt / 1000 + ' seconds.')
-  }
-  logToLocalStr('# of samples: ' + result.samples)
-  logToLocalStr('')
-
-  if (opts.renderLatencyTable) {
-    const latencies = new Table({
-      head: asColor(chalk.cyan, ['Percentile', 'Latency (ms)'])
-    })
-    percentiles.map((perc) => {
-      const key = `p${perc}`.replace('.', '_')
-      return [
-        chalk.bold('' + perc),
-        result.latency[key]
-      ]
-    }).forEach(row => {
-      latencies.push(row)
+    const requests = new Table({
+      head: asColor(chalk.cyan, ['Stat', '1%', '2.5%', '50%', '97.5%', 'Avg', 'Stdev', 'Min'])
     })
-    logToLocalStr(latencies.toString())
+
+    requests.push(asHighRow(chalk.bold('Req/Sec'), asNumber(result.requests)))
+    requests.push(asHighRow(chalk.bold('Bytes/Sec'), asBytes(result.throughput)))
+    logToLocalStr(requests.toString())
+
+    if (opts.renderStatusCodes === true) {
+      const statusCodeStats = new Table({
+        head: asColor(chalk.cyan, ['Code', 'Count'])
+      })
+      Object.keys(result.statusCodeStats).forEach(statusCode => {
+        const stats = result.statusCodeStats[statusCode]
+        const colorize = colorizeByStatusCode(chalk, statusCode)
+        statusCodeStats.push([colorize(statusCode), stats.count])
+      })
+      logToLocalStr(statusCodeStats.toString())
+    }
     logToLocalStr('')
+    if (result.sampleInt === 1000) {
+      logToLocalStr('Req/Bytes counts sampled once per second.')
+    } else {
+      logToLocalStr('Req/Bytes counts sampled every ' + result.sampleInt / 1000 + ' seconds.')
+    }
+    logToLocalStr('# of samples: ' + result.samples)
+    logToLocalStr('')
+
+    if (opts.renderLatencyTable) {
+      const latencies = new Table({
+        head: asColor(chalk.cyan, ['Percentile', 'Latency (ms)'])
+      })
+      percentiles.map((perc) => {
+        const key = `p${perc}`.replace('.', '_')
+        return [
+          chalk.bold('' + perc),
+          result.latency[key]
+        ]
+      }).forEach(row => {
+        latencies.push(row)
+      })
+      logToLocalStr(latencies.toString())
+      logToLocalStr('')
+    }
   }
 
   if (result.non2xx) {
diff --git a/package.json b/package.json
index f88597e..db5ef25 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "autocannon",
-  "version": "7.13.0",
+  "version": "7.14.0",
   "description": "Fast HTTP benchmarking tool written in Node.js",
   "main": "autocannon.js",
   "bin": {


Test patch:
diff --git a/test/printResult.test.js b/test/printResult.test.js
index 1341643..b2c3007 100644
--- a/test/printResult.test.js
+++ b/test/printResult.test.js
@@ -97,3 +97,45 @@ test('verify amount of total requests', (t) => {
   const expectedRequests = connections * pipelining
   t.match(output.includes(`${expectedRequests} requests in`), true)
 })
+
+test('should not print when verbose(V=0) is false', (t) => {
+  t.plan(1)
+
+  const connections = 10
+  const pipelining = 2
+  const result = {
+    connections,
+    pipelining,
+    latency: {},
+    requests: {
+      sent: connections * pipelining
+    },
+    throughput: {
+      average: 3319,
+      mean: 3319,
+      stddev: 0,
+      min: 3318,
+      max: 3318,
+      total: 3318,
+      p0_001: 3319,
+      p0_01: 3319,
+      p0_1: 3319,
+      p1: 3319,
+      p2_5: 3319,
+      p10: 3319,
+      p25: 3319,
+      p50: 3319,
+      p75: 3319,
+      p90: 3319,
+      p97_5: 3319,
+      p99: 3319,
+      p99_9: 3319,
+      p99_99: 3319,
+      p99_999: 3319
+    }
+  }
+
+  // act
+  const output = printResult(result, { verbose: false })
+  t.ok(output.split('\n').length === 2)
+})