@elastic/elasticsearch 7.14.0 → 7.17.0

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/lib/Transport.js CHANGED
@@ -36,13 +36,15 @@ const {
36
36
 
37
37
  const noop = () => {}
38
38
 
39
- const productCheckEmitter = new EventEmitter()
40
39
  const clientVersion = require('../package.json').version
41
40
  const userAgent = `elasticsearch-js/${clientVersion} (${os.platform()} ${os.release()}-${os.arch()}; Node.js ${process.version})`
42
41
  const MAX_BUFFER_LENGTH = buffer.constants.MAX_LENGTH
43
42
  const MAX_STRING_LENGTH = buffer.constants.MAX_STRING_LENGTH
44
43
  const kProductCheck = Symbol('product check')
45
44
  const kApiVersioning = Symbol('api versioning')
45
+ const kEventEmitter = Symbol('event emitter')
46
+ const kMaxResponseSize = Symbol('max response size')
47
+ const kMaxCompressedResponseSize = Symbol('max compressed response size')
46
48
 
47
49
  class Transport {
48
50
  constructor (opts) {
@@ -71,6 +73,9 @@ class Transport {
71
73
  this.opaqueIdPrefix = opts.opaqueIdPrefix
72
74
  this[kProductCheck] = 0 // 0 = to be checked, 1 = checking, 2 = checked-ok, 3 checked-notok, 4 checked-nodefault
73
75
  this[kApiVersioning] = process.env.ELASTIC_CLIENT_APIVERSIONING === 'true'
76
+ this[kEventEmitter] = new EventEmitter()
77
+ this[kMaxResponseSize] = opts.maxResponseSize || MAX_STRING_LENGTH
78
+ this[kMaxCompressedResponseSize] = opts.maxCompressedResponseSize || MAX_BUFFER_LENGTH
74
79
 
75
80
  this.nodeFilter = opts.nodeFilter || defaultNodeFilter
76
81
  if (typeof opts.nodeSelector === 'function') {
@@ -161,13 +166,19 @@ class Transport {
161
166
  ? 0
162
167
  : (typeof options.maxRetries === 'number' ? options.maxRetries : this.maxRetries)
163
168
  const compression = options.compression !== undefined ? options.compression : this.compression
169
+ const maxResponseSize = options.maxResponseSize || this[kMaxResponseSize]
170
+ const maxCompressedResponseSize = options.maxCompressedResponseSize || this[kMaxCompressedResponseSize]
164
171
  let request = { abort: noop }
165
172
  const transportReturn = {
166
173
  then (onFulfilled, onRejected) {
167
- return p.then(onFulfilled, onRejected)
174
+ if (p != null) {
175
+ return p.then(onFulfilled, onRejected)
176
+ }
168
177
  },
169
178
  catch (onRejected) {
170
- return p.catch(onRejected)
179
+ if (p != null) {
180
+ return p.catch(onRejected)
181
+ }
171
182
  },
172
183
  abort () {
173
184
  meta.aborted = true
@@ -176,12 +187,15 @@ class Transport {
176
187
  return this
177
188
  },
178
189
  finally (onFinally) {
179
- return p.finally(onFinally)
190
+ if (p != null) {
191
+ return p.finally(onFinally)
192
+ }
180
193
  }
181
194
  }
182
195
 
183
196
  const makeRequest = () => {
184
197
  if (meta.aborted === true) {
198
+ this.emit('request', new RequestAbortedError(), result)
185
199
  return process.nextTick(callback, new RequestAbortedError(), result)
186
200
  }
187
201
  meta.connection = this.getConnection({ requestId: meta.request.id })
@@ -237,26 +251,28 @@ class Transport {
237
251
 
238
252
  const contentEncoding = (result.headers['content-encoding'] || '').toLowerCase()
239
253
  const isCompressed = contentEncoding.indexOf('gzip') > -1 || contentEncoding.indexOf('deflate') > -1
254
+ const isVectorTile = (result.headers['content-type'] || '').indexOf('application/vnd.mapbox-vector-tile') > -1
240
255
 
241
256
  /* istanbul ignore else */
242
257
  if (result.headers['content-length'] !== undefined) {
243
258
  const contentLength = Number(result.headers['content-length'])
244
- if (isCompressed && contentLength > MAX_BUFFER_LENGTH) {
259
+ if (isCompressed && contentLength > maxCompressedResponseSize) {
245
260
  response.destroy()
246
261
  return onConnectionError(
247
- new RequestAbortedError(`The content length (${contentLength}) is bigger than the maximum allowed buffer (${MAX_BUFFER_LENGTH})`, result)
262
+ new RequestAbortedError(`The content length (${contentLength}) is bigger than the maximum allowed buffer (${maxCompressedResponseSize})`, result)
248
263
  )
249
- } else if (contentLength > MAX_STRING_LENGTH) {
264
+ } else if (contentLength > maxResponseSize) {
250
265
  response.destroy()
251
266
  return onConnectionError(
252
- new RequestAbortedError(`The content length (${contentLength}) is bigger than the maximum allowed string (${MAX_STRING_LENGTH})`, result)
267
+ new RequestAbortedError(`The content length (${contentLength}) is bigger than the maximum allowed string (${maxResponseSize})`, result)
253
268
  )
254
269
  }
255
270
  }
256
271
  // if the response is compressed, we must handle it
257
272
  // as buffer for allowing decompression later
258
- let payload = isCompressed ? [] : ''
259
- const onData = isCompressed
273
+ // while if it's a vector tile, we should return it as buffer
274
+ let payload = isCompressed || isVectorTile ? [] : ''
275
+ const onData = isCompressed || isVectorTile
260
276
  ? chunk => { payload.push(chunk) }
261
277
  : chunk => { payload += chunk }
262
278
  const onEnd = err => {
@@ -272,7 +288,7 @@ class Transport {
272
288
  if (isCompressed) {
273
289
  unzip(Buffer.concat(payload), onBody)
274
290
  } else {
275
- onBody(null, payload)
291
+ onBody(null, isVectorTile ? Buffer.concat(payload) : payload)
276
292
  }
277
293
  }
278
294
 
@@ -281,7 +297,7 @@ class Transport {
281
297
  onEnd(new Error('Response aborted while reading the body'))
282
298
  }
283
299
 
284
- if (!isCompressed) {
300
+ if (!isCompressed && !isVectorTile) {
285
301
  response.setEncoding('utf8')
286
302
  }
287
303
 
@@ -297,7 +313,9 @@ class Transport {
297
313
  this.emit('response', err, result)
298
314
  return callback(err, result)
299
315
  }
300
- if (Buffer.isBuffer(payload)) {
316
+
317
+ const isVectorTile = (result.headers['content-type'] || '').indexOf('application/vnd.mapbox-vector-tile') > -1
318
+ if (Buffer.isBuffer(payload) && !isVectorTile) {
301
319
  payload = payload.toString()
302
320
  }
303
321
  const isHead = params.method === 'HEAD'
@@ -416,8 +434,6 @@ class Transport {
416
434
  // handles request timeout
417
435
  params.timeout = toMs(options.requestTimeout || this.requestTimeout)
418
436
  if (options.asStream === true) params.asStream = true
419
- meta.request.params = params
420
- meta.request.options = options
421
437
 
422
438
  // handle compression
423
439
  if (params.body !== '' && params.body != null) {
@@ -448,6 +464,8 @@ class Transport {
448
464
  }
449
465
  }
450
466
 
467
+ meta.request.params = params
468
+ meta.request.options = options
451
469
  // still need to check the product or waiting for the check to finish
452
470
  if (this[kProductCheck] === 0 || this[kProductCheck] === 1) {
453
471
  // let pass info requests
@@ -455,7 +473,7 @@ class Transport {
455
473
  prepareRequest()
456
474
  } else {
457
475
  // wait for product check to finish
458
- productCheckEmitter.once('product-check', (error, status) => {
476
+ this[kEventEmitter].once('product-check', (error, status) => {
459
477
  if (status === false) {
460
478
  const err = error || new ProductNotSupportedError(result)
461
479
  if (this[kProductCheck] === 4) {
@@ -555,49 +573,52 @@ class Transport {
555
573
  debug('Product check failed', err)
556
574
  if (err.statusCode === 401 || err.statusCode === 403) {
557
575
  this[kProductCheck] = 2
558
- process.emitWarning('The client is unable to verify that the server is Elasticsearch due to security privileges on the server side. Some functionality may not be compatible if the server is running an unsupported product.')
559
- productCheckEmitter.emit('product-check', null, true)
576
+ process.emitWarning(
577
+ 'The client is unable to verify that the server is Elasticsearch due to security privileges on the server side. Some functionality may not be compatible if the server is running an unsupported product.',
578
+ 'ProductNotSupportedSecurityError'
579
+ )
580
+ this[kEventEmitter].emit('product-check', null, true)
560
581
  } else {
561
582
  this[kProductCheck] = 0
562
- productCheckEmitter.emit('product-check', err, false)
583
+ this[kEventEmitter].emit('product-check', err, false)
563
584
  }
564
585
  } else {
565
586
  debug('Checking elasticsearch version', result.body, result.headers)
566
587
  if (result.body.version == null || typeof result.body.version.number !== 'string') {
567
588
  debug('Can\'t access Elasticsearch version')
568
- return productCheckEmitter.emit('product-check', null, false)
589
+ return this[kEventEmitter].emit('product-check', null, false)
569
590
  }
570
591
  const tagline = result.body.tagline
571
592
  const version = result.body.version.number.split('.')
572
593
  const major = Number(version[0])
573
594
  const minor = Number(version[1])
574
595
  if (major < 6) {
575
- return productCheckEmitter.emit('product-check', null, false)
596
+ return this[kEventEmitter].emit('product-check', null, false)
576
597
  } else if (major >= 6 && major < 7) {
577
598
  if (tagline !== 'You Know, for Search') {
578
599
  debug('Bad tagline')
579
- return productCheckEmitter.emit('product-check', null, false)
600
+ return this[kEventEmitter].emit('product-check', null, false)
580
601
  }
581
602
  } else if (major === 7 && minor < 14) {
582
603
  if (tagline !== 'You Know, for Search') {
583
604
  debug('Bad tagline')
584
- return productCheckEmitter.emit('product-check', null, false)
605
+ return this[kEventEmitter].emit('product-check', null, false)
585
606
  }
586
607
 
587
608
  if (result.body.version.build_flavor !== 'default') {
588
609
  debug('Bad build_flavor')
589
610
  this[kProductCheck] = 4
590
- return productCheckEmitter.emit('product-check', null, false)
611
+ return this[kEventEmitter].emit('product-check', null, false)
591
612
  }
592
613
  } else {
593
614
  if (result.headers['x-elastic-product'] !== 'Elasticsearch') {
594
615
  debug('x-elastic-product not recognized')
595
- return productCheckEmitter.emit('product-check', null, false)
616
+ return this[kEventEmitter].emit('product-check', null, false)
596
617
  }
597
618
  }
598
619
  debug('Valid Elasticsearch distribution')
599
620
  this[kProductCheck] = 2
600
- productCheckEmitter.emit('product-check', null, true)
621
+ this[kEventEmitter].emit('product-check', null, true)
601
622
  }
602
623
  })
603
624
  }
package/lib/errors.js CHANGED
@@ -97,8 +97,10 @@ class ResponseError extends ElasticsearchClientError {
97
97
  } else {
98
98
  this.message = meta.body.error.type
99
99
  }
100
+ } else if (typeof meta.body === 'object' && meta.body != null) {
101
+ this.message = JSON.stringify(meta.body)
100
102
  } else {
101
- this.message = 'Response Error'
103
+ this.message = meta.body || 'Response Error'
102
104
  }
103
105
  this.meta = meta
104
106
  }
@@ -36,6 +36,7 @@ class BaseConnectionPool {
36
36
  this._ssl = opts.ssl
37
37
  this._agent = opts.agent
38
38
  this._proxy = opts.proxy || null
39
+ this._caFingerprint = opts.caFingerprint || null
39
40
  }
40
41
 
41
42
  getConnection () {
@@ -72,6 +73,8 @@ class BaseConnectionPool {
72
73
  if (opts.agent == null) opts.agent = this._agent
73
74
  /* istanbul ignore else */
74
75
  if (opts.proxy == null) opts.proxy = this._proxy
76
+ /* istanbul ignore else */
77
+ if (opts.caFingerprint == null) opts.caFingerprint = this._caFingerprint
75
78
 
76
79
  const connection = new this.Connection(opts)
77
80
 
@@ -31,6 +31,7 @@ interface BaseConnectionPoolOptions {
31
31
  auth?: BasicAuth | ApiKeyAuth;
32
32
  emit: (event: string | symbol, ...args: any[]) => boolean;
33
33
  Connection: typeof Connection;
34
+ caFingerprint?: string;
34
35
  }
35
36
 
36
37
  interface ConnectionPoolOptions extends BaseConnectionPoolOptions {
package/package.json CHANGED
@@ -8,11 +8,11 @@
8
8
  "require": "./index.js",
9
9
  "import": "./index.mjs"
10
10
  },
11
- "./": "./"
11
+ "./*": "./*.js"
12
12
  },
13
13
  "homepage": "http://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/index.html",
14
- "version": "7.14.0",
15
- "versionCanary": "7.14.0-canary.7",
14
+ "version": "7.17.0",
15
+ "versionCanary": "7.16.0-canary.7",
16
16
  "keywords": [
17
17
  "elasticsearch",
18
18
  "elastic",
@@ -100,6 +100,7 @@
100
100
  "jsx": false,
101
101
  "flow": false,
102
102
  "coverage": false,
103
- "jobs-auto": true
103
+ "jobs-auto": true,
104
+ "check-coverage": false
104
105
  }
105
106
  }
@@ -1,123 +0,0 @@
1
- <?xml version="1.0"?>
2
- <testsuites id="2021-04-02T14:09:24.358Z" name="Integration test for Free api" time="13" tests="35" failures="1" skipped="7">
3
- <testsuite id="2021-04-02T14:09:24.431Z" name="free/bulk - /free/bulk/10_basic.yml" time="4" tests="7" failures="0" skipped="0">
4
- <testcase id="2021-04-02T14:09:24.431Z" name="Array of objects" time="1"/>
5
- <testcase id="2021-04-02T14:09:25.235Z" name="Empty _id" time="0"/>
6
- <testcase id="2021-04-02T14:09:25.622Z" name="Empty _id with op_type create" time="0"/>
7
- <testcase id="2021-04-02T14:09:26.027Z" name="empty action" time="0"/>
8
- <testcase id="2021-04-02T14:09:26.218Z" name="When setting require_alias flag per request" time="1"/>
9
- <testcase id="2021-04-02T14:09:26.850Z" name="When setting require_alias flag" time="1"/>
10
- <testcase id="2021-04-02T14:09:27.424Z" name="Return item-level error when no write index defined for an alias" time="1"/>
11
- </testsuite>
12
- <testsuite id="2021-04-02T14:09:27.976Z" name="free/bulk - /free/bulk/20_list_of_strings.yml" time="1" tests="1" failures="0" skipped="0">
13
- <testcase id="2021-04-02T14:09:27.976Z" name="List of strings" time="1"/>
14
- </testsuite>
15
- <testsuite id="2021-04-02T14:09:28.725Z" name="free/bulk - /free/bulk/30_big_string.yml" time="0" tests="1" failures="0" skipped="0">
16
- <testcase id="2021-04-02T14:09:28.725Z" name="One big string" time="0"/>
17
- </testsuite>
18
- <testsuite id="2021-04-02T14:09:29.217Z" name="free/bulk - /free/bulk/40_source.yml" time="1" tests="1" failures="0" skipped="0">
19
- <testcase id="2021-04-02T14:09:29.217Z" name="Source filtering" time="1"/>
20
- </testsuite>
21
- <testsuite id="2021-04-02T14:09:30.150Z" name="free/bulk - /free/bulk/50_refresh.yml" time="2" tests="3" failures="0" skipped="0">
22
- <testcase id="2021-04-02T14:09:30.150Z" name="refresh=true immediately makes changes are visible in search" time="0"/>
23
- <testcase id="2021-04-02T14:09:30.399Z" name="refresh=empty string immediately makes changes are visible in search" time="0"/>
24
- <testcase id="2021-04-02T14:09:30.692Z" name="refresh=wait_for waits until changes are visible in search" time="1"/>
25
- </testsuite>
26
- <testsuite id="2021-04-02T14:09:31.890Z" name="free/bulk - /free/bulk/60_deprecated.yml" time="0" tests="1" failures="0" skipped="0">
27
- <testcase id="2021-04-02T14:09:31.890Z" name="Deprecated parameters should fail in Bulk query" time="0"/>
28
- </testsuite>
29
- <testsuite id="2021-04-02T14:09:32.018Z" name="free/bulk - /free/bulk/80_cas.yml" time="0" tests="1" failures="0" skipped="0">
30
- <testcase id="2021-04-02T14:09:32.018Z" name="Compare And Swap Sequence Numbers" time="0"/>
31
- </testsuite>
32
- <testsuite id="2021-04-02T14:09:32.344Z" name="free/bulk - /free/bulk/90_pipeline.yml" time="1" tests="1" failures="0" skipped="0">
33
- <testcase id="2021-04-02T14:09:32.344Z" name="One request has pipeline and another not" time="1"/>
34
- </testsuite>
35
- <testsuite id="2021-04-02T14:09:32.958Z" name="free/cat.aliases - /free/cat.aliases/10_basic.yml" time="3" tests="15" failures="0" skipped="6">
36
- <testcase id="2021-04-02T14:09:32.958Z" name="Help" time="0"/>
37
- <testcase id="2021-04-02T14:09:33.172Z" name="Help (pre 7.4.0)" time="0">
38
- <skipped>{
39
- "version": "7.4.0 - ",
40
- "features": "node_selector",
41
- "reason": "is_write_index is shown in cat.aliases starting version 7.4.0"
42
- }</skipped>
43
- </testcase>
44
- <testcase id="2021-04-02T14:09:33.301Z" name="Empty cluster" time="0"/>
45
- <testcase id="2021-04-02T14:09:33.434Z" name="Simple alias" time="0"/>
46
- <testcase id="2021-04-02T14:09:33.710Z" name="Simple alias (pre 7.4.0)" time="0">
47
- <skipped>{
48
- "version": "7.4.0 - ",
49
- "features": "node_selector",
50
- "reason": "is_write_index is shown in cat.aliases starting version 7.4.0"
51
- }</skipped>
52
- </testcase>
53
- <testcase id="2021-04-02T14:09:33.848Z" name="Complex alias" time="0"/>
54
- <testcase id="2021-04-02T14:09:34.172Z" name="Complex alias (pre 7.4.0)" time="0">
55
- <skipped>{
56
- "version": "7.4.0 - ",
57
- "features": "node_selector",
58
- "reason": "is_write_index is shown in cat.aliases starting version 7.4.0"
59
- }</skipped>
60
- </testcase>
61
- <testcase id="2021-04-02T14:09:34.303Z" name="Alias name" time="0"/>
62
- <testcase id="2021-04-02T14:09:34.573Z" name="Multiple alias names" time="1"/>
63
- <testcase id="2021-04-02T14:09:35.169Z" name="Column headers" time="0"/>
64
- <testcase id="2021-04-02T14:09:35.450Z" name="Column headers (pre 7.4.0)" time="0">
65
- <skipped>{
66
- "version": "7.4.0 - ",
67
- "features": "node_selector",
68
- "reason": "is_write_index is shown in cat.aliases starting version 7.4.0"
69
- }</skipped>
70
- </testcase>
71
- <testcase id="2021-04-02T14:09:35.577Z" name="Select columns" time="0"/>
72
- <testcase id="2021-04-02T14:09:35.814Z" name="Alias against closed index" time="0">
73
- <skipped>{
74
- "version": " - 7.3.99",
75
- "reason": "is_write_index is shown in cat.aliases starting version 7.4.0",
76
- "features": [
77
- "allowed_warnings"
78
- ]
79
- }</skipped>
80
- </testcase>
81
- <testcase id="2021-04-02T14:09:35.941Z" name="Alias against closed index (pre 7.4.0)" time="0">
82
- <skipped>{
83
- "version": "7.4.0 - ",
84
- "features": [
85
- "node_selector",
86
- "allowed_warnings"
87
- ],
88
- "reason": "is_write_index is shown in cat.aliases starting version 7.4.0"
89
- }</skipped>
90
- </testcase>
91
- <testcase id="2021-04-02T14:09:36.058Z" name="Alias sorting" time="0"/>
92
- </testsuite>
93
- <testsuite id="2021-04-02T14:09:36.361Z" name="free/cat.aliases - /free/cat.aliases/20_headers.yml" time="0" tests="1" failures="0" skipped="1">
94
- <testcase id="2021-04-02T14:09:36.361Z" name="Simple alias with yaml body through Accept header" time="0">
95
- <skipped>{
96
- "features": [
97
- "headers",
98
- "yaml"
99
- ]
100
- }</skipped>
101
- </testcase>
102
- </testsuite>
103
- <testsuite id="2021-04-02T14:09:36.487Z" name="free/cat.aliases - /free/cat.aliases/30_json.yml" time="0" tests="1" failures="0" skipped="0">
104
- <testcase id="2021-04-02T14:09:36.487Z" name="Simple alias with json body through format argument" time="0"/>
105
- </testsuite>
106
- <testsuite id="2021-04-02T14:09:36.725Z" name="free/cat.aliases - /free/cat.aliases/40_hidden.yml" time="0" tests="2" failures="1" skipped="0">
107
- <testcase id="2021-04-02T14:09:36.725Z" name="Test cat aliases output with a hidden index with a hidden alias" time="0"/>
108
- <testcase id="2021-04-02T14:09:36.909Z" name="Test cat aliases output with a hidden index with a visible alias" time="0">
109
- <failure message="ifError got unwanted exception: resource_already_exists_exception" type="ERR_ASSERTION">AssertionError [ERR_ASSERTION]: ifError got unwanted exception: resource_already_exists_exception
110
- at doAction (/Users/delvedor/Development/elastic/elasticsearch-js/test/integration/test-runner.js:425:14)
111
- at runMicrotasks (&lt;anonymous&gt;)
112
- at processTicksAndRejections (internal/process/task_queues.js:93:5)
113
- at async exec (/Users/delvedor/Development/elastic/elasticsearch-js/test/integration/test-runner.js:448:9)
114
- at async Object.run (/Users/delvedor/Development/elastic/elasticsearch-js/test/integration/test-runner.js:220:5)
115
- at async start (/Users/delvedor/Development/elastic/elasticsearch-js/test/integration/index.js:262:11)
116
- at onBody (/Users/delvedor/Development/elastic/elasticsearch-js/lib/Transport.js:337:23)
117
- at IncomingMessage.onEnd (/Users/delvedor/Development/elastic/elasticsearch-js/lib/Transport.js:264:11)
118
- at IncomingMessage.emit (events.js:327:22)
119
- at endReadableNT (_stream_readable.js:1327:12)
120
- at processTicksAndRejections (internal/process/task_queues.js:80:21)</failure>
121
- </testcase>
122
- </testsuite>
123
- </testsuites>
@@ -1,18 +0,0 @@
1
- <?xml version="1.0"?>
2
- <testsuites id="2021-02-08T18:24:44.902Z" name="Integration test for Platinum api" time="7" tests="1" failures="1" skipped="0">
3
- <testsuite id="2021-02-08T18:24:44.958Z" name="text_structure - /text_structure/find_structure.yml" time="7" tests="1" failures="1" skipped="0">
4
- <testcase id="2021-02-08T18:24:44.959Z" name="Test NDJSON file structure analysis without overrides" time="7">
5
- <failure message="ifError got unwanted exception: illegal_argument_exception" type="ERR_ASSERTION">AssertionError [ERR_ASSERTION]: ifError got unwanted exception: illegal_argument_exception
6
- at doAction (/Users/delvedor/Development/elastic/elasticsearch-js/test/integration/test-runner.js:428:14)
7
- at processTicksAndRejections (internal/process/task_queues.js:93:5)
8
- at async exec (/Users/delvedor/Development/elastic/elasticsearch-js/test/integration/test-runner.js:451:9)
9
- at async Object.run (/Users/delvedor/Development/elastic/elasticsearch-js/test/integration/test-runner.js:225:5)
10
- at async start (/Users/delvedor/Development/elastic/elasticsearch-js/test/integration/index.js:252:11)
11
- at onBody (/Users/delvedor/Development/elastic/elasticsearch-js/lib/Transport.js:333:23)
12
- at IncomingMessage.onEnd (/Users/delvedor/Development/elastic/elasticsearch-js/lib/Transport.js:260:11)
13
- at IncomingMessage.emit (events.js:327:22)
14
- at endReadableNT (_stream_readable.js:1327:12)
15
- at processTicksAndRejections (internal/process/task_queues.js:80:21)</failure>
16
- </testcase>
17
- </testsuite>
18
- </testsuites>