Elasticsearch v8 (#1558)

This commit is contained in:
Tomas Della Vedova
2021-09-30 09:45:04 +02:00
committed by GitHub
parent 4c72b981cd
commit 1a227459f0
255 changed files with 36905 additions and 42018 deletions

View File

@ -17,19 +17,23 @@
* under the License.
*/
'use strict'
import * as http from 'http'
import { createReadStream } from 'fs'
import { join } from 'path'
import split from 'split2'
import FakeTimers from '@sinonjs/fake-timers'
import { test } from 'tap'
import { Client, errors } from '../../../'
import { buildServer, connection } from '../../utils'
const { createReadStream } = require('fs')
const { join } = require('path')
const split = require('split2')
const FakeTimers = require('@sinonjs/fake-timers')
const { test } = require('tap')
const { errors } = require('../../../')
const { Client, buildServer, connection } = require('../../utils')
let clientVersion = require('../../../package.json').version
let clientVersion: string = require('../../../package.json').version // eslint-disable-line
if (clientVersion.includes('-')) {
clientVersion = clientVersion.slice(0, clientVersion.indexOf('-')) + 'p'
}
let transportVersion: string = require('@elastic/transport/package.json').version // eslint-disable-line
if (transportVersion.includes('-')) {
transportVersion = transportVersion.slice(0, transportVersion.indexOf('-')) + 'p'
}
const nodeVersion = process.versions.node
const dataset = [
@ -46,9 +50,10 @@ test('bulk index', t => {
onRequest (params) {
t.equal(params.path, '/_bulk')
t.match(params.headers, {
'content-type': 'application/x-ndjson',
'x-elastic-client-meta': `es=${clientVersion},js=${nodeVersion},t=${clientVersion},hc=${nodeVersion},h=bp`
'content-type': 'application/vnd.elasticsearch+x-ndjson; compatible-with=8',
'x-elastic-client-meta': `es=${clientVersion},js=${nodeVersion},t=${transportVersion},hc=${nodeVersion},h=bp`
})
// @ts-expect-error
const [action, payload] = params.body.split('\n')
t.same(JSON.parse(action), { index: { _index: 'test' } })
t.same(JSON.parse(payload), dataset[count++])
@ -90,10 +95,11 @@ test('bulk index', t => {
const MockConnection = connection.buildMockConnection({
onRequest (params) {
t.equal(params.path, '/_bulk')
t.match(params.headers, { 'content-type': 'application/x-ndjson' })
t.match(params.headers, { 'content-type': 'application/vnd.elasticsearch+x-ndjson; compatible-with=8' })
t.notMatch(params.headers, {
'x-elastic-client-meta': `es=${clientVersion},js=${nodeVersion},t=${clientVersion},hc=${nodeVersion},h=bp`
'x-elastic-client-meta': `es=${clientVersion},js=${nodeVersion},t=${transportVersion},hc=${nodeVersion},h=bp`
})
// @ts-expect-error
const [action, payload] = params.body.split('\n')
t.same(JSON.parse(action), { index: { _index: 'test' } })
t.same(JSON.parse(payload), dataset[count++])
@ -135,7 +141,8 @@ test('bulk index', t => {
const MockConnection = connection.buildMockConnection({
onRequest (params) {
t.equal(params.path, '/_bulk')
t.match(params.headers, { 'content-type': 'application/x-ndjson' })
t.match(params.headers, { 'content-type': 'application/vnd.elasticsearch+x-ndjson; compatible-with=8' })
// @ts-expect-error
t.equal(params.body.split('\n').filter(Boolean).length, 6)
return { body: { errors: false, items: new Array(3).fill({}) } }
}
@ -179,7 +186,8 @@ test('bulk index', t => {
return { body: { acknowledged: true } }
} else {
t.equal(params.path, '/_bulk')
t.match(params.headers, { 'content-type': 'application/x-ndjson' })
t.match(params.headers, { 'content-type': 'application/vnd.elasticsearch+x-ndjson; compatible-with=8' })
// @ts-expect-error
const [action, payload] = params.body.split('\n')
t.same(JSON.parse(action), { index: { _index: 'test' } })
t.same(JSON.parse(payload), dataset[count++])
@ -224,7 +232,8 @@ test('bulk index', t => {
return { body: { acknowledged: true } }
} else {
t.equal(params.path, '/_bulk')
t.match(params.headers, { 'content-type': 'application/x-ndjson' })
t.match(params.headers, { 'content-type': 'application/vnd.elasticsearch+x-ndjson; compatible-with=8' })
// @ts-expect-error
const [action, payload] = params.body.split('\n')
t.same(JSON.parse(action), { index: { _index: 'test' } })
t.same(JSON.parse(payload), dataset[count++])
@ -265,7 +274,8 @@ test('bulk index', t => {
const MockConnection = connection.buildMockConnection({
onRequest (params) {
t.equal(params.path, '/_bulk')
t.match(params.headers, { 'content-type': 'application/x-ndjson' })
t.match(params.headers, { 'content-type': 'application/vnd.elasticsearch+x-ndjson; compatible-with=8' })
// @ts-expect-error
const [action, payload] = params.body.split('\n')
t.same(JSON.parse(action), { index: { _index: 'test', _id: count } })
t.same(JSON.parse(payload), dataset[count++])
@ -286,7 +296,7 @@ test('bulk index', t => {
return {
index: {
_index: 'test',
_id: id++
_id: String(id++)
}
}
},
@ -307,9 +317,9 @@ test('bulk index', t => {
})
t.test('Should perform a bulk request (retry)', async t => {
async function handler (req, res) {
async function handler (req: http.IncomingMessage, res: http.ServerResponse) {
t.equal(req.url, '/_bulk')
t.match(req.headers, { 'content-type': 'application/x-ndjson' })
t.match(req.headers, { 'content-type': 'application/vnd.elasticsearch+x-ndjson; compatible-with=8' })
let body = ''
req.setEncoding('utf8')
@ -376,7 +386,7 @@ test('bulk index', t => {
})
t.test('Should perform a bulk request (retry a single document from batch)', async t => {
function handler (req, res) {
function handler (req: http.IncomingMessage, res: http.ServerResponse) {
res.setHeader('content-type', 'application/json')
res.end(JSON.stringify({
took: 0,
@ -425,9 +435,9 @@ test('bulk index', t => {
})
t.test('Should perform a bulk request (failure)', async t => {
async function handler (req, res) {
async function handler (req: http.IncomingMessage, res: http.ServerResponse) {
t.equal(req.url, '/_bulk')
t.match(req.headers, { 'content-type': 'application/x-ndjson' })
t.match(req.headers, { 'content-type': 'application/vnd.elasticsearch+x-ndjson; compatible-with=8' })
let body = ''
req.setEncoding('utf8')
@ -524,7 +534,7 @@ test('bulk index', t => {
try {
await b
t.fail('Should throw')
} catch (err) {
} catch (err: any) {
t.ok(err instanceof errors.ResponseError)
}
})
@ -560,15 +570,15 @@ test('bulk index', t => {
try {
await b
t.fail('Should throw')
} catch (err) {
} catch (err: any) {
t.ok(err instanceof errors.ResponseError)
}
})
t.test('Should abort a bulk request', async t => {
async function handler (req, res) {
async function handler (req: http.IncomingMessage, res: http.ServerResponse) {
t.equal(req.url, '/_bulk')
t.match(req.headers, { 'content-type': 'application/x-ndjson' })
t.match(req.headers, { 'content-type': 'application/vnd.elasticsearch+x-ndjson; compatible-with=8' })
let body = ''
req.setEncoding('utf8')
@ -646,6 +656,7 @@ test('bulk index', t => {
datasource: dataset.slice(),
flushBytes: 1,
concurrency: 1,
// @ts-expect-error
onDocument (doc) {
return {
foo: { _index: 'test' }
@ -667,7 +678,8 @@ test('bulk index', t => {
const MockConnection = connection.buildMockConnection({
onRequest (params) {
t.equal(params.path, '/_bulk')
t.match(params.headers, { 'content-type': 'application/x-ndjson' })
t.match(params.headers, { 'content-type': 'application/vnd.elasticsearch+x-ndjson; compatible-with=8' })
// @ts-expect-error
const [action, payload] = params.body.split('\n')
t.same(JSON.parse(action), { index: { _index: 'test', _id: count } })
t.same(JSON.parse(payload), dataset[count++])
@ -690,7 +702,7 @@ test('bulk index', t => {
return {
index: {
_index: 'test',
_id: id++
_id: String(id++)
}
}
},
@ -719,7 +731,8 @@ test('bulk index', t => {
const MockConnection = connection.buildMockConnection({
onRequest (params) {
t.equal(params.path, '/_bulk')
t.match(params.headers, { 'content-type': 'application/x-ndjson' })
t.match(params.headers, { 'content-type': 'application/vnd.elasticsearch+x-ndjson; compatible-with=8' })
// @ts-expect-error
const [action, payload] = params.body.split('\n')
t.same(JSON.parse(action), { index: { _index: 'test' } })
t.same(JSON.parse(payload), dataset[count++])
@ -775,7 +788,8 @@ test('bulk create', t => {
const MockConnection = connection.buildMockConnection({
onRequest (params) {
t.equal(params.path, '/_bulk')
t.match(params.headers, { 'content-type': 'application/x-ndjson' })
t.match(params.headers, { 'content-type': 'application/vnd.elasticsearch+x-ndjson; compatible-with=8' })
// @ts-expect-error
const [action, payload] = params.body.split('\n')
t.same(JSON.parse(action), { create: { _index: 'test', _id: count } })
t.same(JSON.parse(payload), dataset[count++])
@ -796,7 +810,7 @@ test('bulk create', t => {
return {
create: {
_index: 'test',
_id: id++
_id: String(id++)
}
}
},
@ -824,7 +838,8 @@ test('bulk update', t => {
const MockConnection = connection.buildMockConnection({
onRequest (params) {
t.equal(params.path, '/_bulk')
t.match(params.headers, { 'content-type': 'application/x-ndjson' })
t.match(params.headers, { 'content-type': 'application/vnd.elasticsearch+x-ndjson; compatible-with=8' })
// @ts-expect-error
const [action, payload] = params.body.split('\n')
t.same(JSON.parse(action), { update: { _index: 'test', _id: count } })
t.same(JSON.parse(payload), { doc: dataset[count++], doc_as_upsert: true })
@ -845,7 +860,7 @@ test('bulk update', t => {
return [{
update: {
_index: 'test',
_id: id++
_id: String(id++)
}
}, {
doc_as_upsert: true
@ -872,7 +887,8 @@ test('bulk update', t => {
const MockConnection = connection.buildMockConnection({
onRequest (params) {
t.equal(params.path, '/_bulk')
t.match(params.headers, { 'content-type': 'application/x-ndjson' })
t.match(params.headers, { 'content-type': 'application/vnd.elasticsearch+x-ndjson; compatible-with=8' })
// @ts-expect-error
const [action, payload] = params.body.split('\n')
t.same(JSON.parse(action), { update: { _index: 'test', _id: count } })
t.same(JSON.parse(payload), { doc: dataset[count++] })
@ -893,9 +909,9 @@ test('bulk update', t => {
return [{
update: {
_index: 'test',
_id: id++
_id: String(id++)
}
}]
}, {}]
},
onDrop (doc) {
t.fail('This should never be called')
@ -917,11 +933,12 @@ test('bulk update', t => {
let count = 0
const MockConnection = connection.buildMockConnection({
onRequest (params) {
t.strictEqual(params.path, '/_bulk')
t.match(params.headers, { 'content-type': 'application/x-ndjson' })
t.equal(params.path, '/_bulk')
t.match(params.headers, { 'content-type': 'application/vnd.elasticsearch+x-ndjson; compatible-with=8' })
// @ts-expect-error
const [action, payload] = params.body.split('\n')
t.deepEqual(JSON.parse(action), { update: { _index: 'test', _id: count } })
t.deepEqual(JSON.parse(payload), { doc: dataset[count++], doc_as_upsert: true })
t.same(JSON.parse(action), { update: { _index: 'test', _id: count } })
t.same(JSON.parse(payload), { doc: dataset[count++], doc_as_upsert: true })
return { body: { errors: false, items: [{ update: { result: 'noop' } }] } }
}
})
@ -939,7 +956,7 @@ test('bulk update', t => {
return [{
update: {
_index: 'test',
_id: id++
_id: String(id++)
}
}, {
doc_as_upsert: true
@ -971,7 +988,8 @@ test('bulk delete', t => {
const MockConnection = connection.buildMockConnection({
onRequest (params) {
t.equal(params.path, '/_bulk')
t.match(params.headers, { 'content-type': 'application/x-ndjson' })
t.match(params.headers, { 'content-type': 'application/vnd.elasticsearch+x-ndjson; compatible-with=8' })
// @ts-expect-error
t.same(JSON.parse(params.body), { delete: { _index: 'test', _id: count++ } })
return { body: { errors: false, items: [{}] } }
}
@ -990,7 +1008,7 @@ test('bulk delete', t => {
return {
delete: {
_index: 'test',
_id: id++
_id: String(id++)
}
}
},
@ -1011,9 +1029,9 @@ test('bulk delete', t => {
})
t.test('Should perform a bulk request (failure)', async t => {
async function handler (req, res) {
async function handler (req: http.IncomingMessage, res: http.ServerResponse) {
t.equal(req.url, '/_bulk')
t.match(req.headers, { 'content-type': 'application/x-ndjson' })
t.match(req.headers, { 'content-type': 'application/vnd.elasticsearch+x-ndjson; compatible-with=8' })
let body = ''
req.setEncoding('utf8')
@ -1023,7 +1041,7 @@ test('bulk delete', t => {
res.setHeader('content-type', 'application/json')
if (JSON.parse(body).delete._id === 1) {
if (JSON.parse(body).delete._id === '1') {
res.end(JSON.stringify({
took: 0,
errors: true,
@ -1055,7 +1073,7 @@ test('bulk delete', t => {
return {
delete: {
_index: 'test',
_id: id++
_id: String(id++)
}
}
},
@ -1094,7 +1112,7 @@ test('transport options', t => {
if (params.path === '/_bulk') {
t.match(params.headers, {
'content-type': 'application/x-ndjson',
'content-type': 'application/vnd.elasticsearch+x-ndjson; compatible-with=8',
foo: 'bar'
})
return { body: { errors: false, items: [{}] } }
@ -1152,6 +1170,7 @@ test('errors', t => {
})
try {
await client.helpers.bulk({
// @ts-expect-error
datasource: 'hello',
onDocument (doc) {
return {
@ -1159,7 +1178,7 @@ test('errors', t => {
}
}
})
} catch (err) {
} catch (err: any) {
t.ok(err instanceof errors.ConfigurationError)
t.equal(err.message, 'bulk helper: the datasource must be an array or a buffer or a readable stream or an async generator')
}
@ -1170,6 +1189,7 @@ test('errors', t => {
node: 'http://localhost:9200'
})
try {
// @ts-expect-error
await client.helpers.bulk({
onDocument (doc) {
return {
@ -1177,7 +1197,7 @@ test('errors', t => {
}
}
})
} catch (err) {
} catch (err: any) {
t.ok(err instanceof errors.ConfigurationError)
t.equal(err.message, 'bulk helper: the datasource is required')
}
@ -1188,10 +1208,11 @@ test('errors', t => {
node: 'http://localhost:9200'
})
try {
// @ts-expect-error
await client.helpers.bulk({
datasource: dataset.slice()
})
} catch (err) {
} catch (err: any) {
t.ok(err instanceof errors.ConfigurationError)
t.equal(err.message, 'bulk helper: the onDocument callback is required')
}
@ -1209,7 +1230,8 @@ test('Flush interval', t => {
const MockConnection = connection.buildMockConnection({
onRequest (params) {
t.equal(params.path, '/_bulk')
t.match(params.headers, { 'content-type': 'application/x-ndjson' })
t.match(params.headers, { 'content-type': 'application/vnd.elasticsearch+x-ndjson; compatible-with=8' })
// @ts-expect-error
const [action, payload] = params.body.split('\n')
t.same(JSON.parse(action), { index: { _index: 'test' } })
t.same(JSON.parse(payload), dataset[count++])
@ -1261,7 +1283,8 @@ test('Flush interval', t => {
onRequest (params) {
t.ok(count < 2)
t.equal(params.path, '/_bulk')
t.match(params.headers, { 'content-type': 'application/x-ndjson' })
t.match(params.headers, { 'content-type': 'application/vnd.elasticsearch+x-ndjson; compatible-with=8' })
// @ts-expect-error
const [action, payload] = params.body.split('\n')
t.same(JSON.parse(action), { index: { _index: 'test' } })
t.same(JSON.parse(payload), dataset[count++])
@ -1282,6 +1305,7 @@ test('Flush interval', t => {
// Needed otherwise in Node.js 10
// the second request will never be sent
await Promise.resolve()
// @ts-ignore
b.abort()
}
yield chunk
@ -1316,14 +1340,15 @@ test('Flush interval', t => {
let count = 0
const MockConnection = connection.buildMockConnection({
onRequest (params) {
t.strictEqual(params.path, '/_bulk')
t.equal(params.path, '/_bulk')
t.match(params.headers, {
'content-type': 'application/x-ndjson',
'x-elastic-client-meta': `es=${clientVersion},js=${nodeVersion},t=${clientVersion},hc=${nodeVersion},h=bp`
'content-type': 'application/vnd.elasticsearch+x-ndjson; compatible-with=8',
'x-elastic-client-meta': `es=${clientVersion},js=${nodeVersion},t=${transportVersion},hc=${nodeVersion},h=bp`
})
// @ts-expect-error
const [action, payload] = params.body.split('\n')
t.deepEqual(JSON.parse(action), { index: { _index: 'test' } })
t.deepEqual(JSON.parse(payload), dataset[count++])
t.same(JSON.parse(action), { index: { _index: 'test' } })
t.same(JSON.parse(payload), dataset[count++])
return { body: { errors: false, items: [{}] } }
}
})

View File

@ -17,12 +17,10 @@
* under the License.
*/
'use strict'
const { test } = require('tap')
const { errors } = require('../../../')
const { Client, connection } = require('../../utils')
const FakeTimers = require('@sinonjs/fake-timers')
import { test } from 'tap'
import { Client, errors } from '../../../'
import { connection } from '../../utils'
import FakeTimers from '@sinonjs/fake-timers'
test('Basic', async t => {
const MockConnection = connection.buildMockConnection({
@ -77,7 +75,7 @@ test('Basic', async t => {
})
test('Multiple searches (inside async iterator)', t => {
t.plan(6)
t.plan(4)
const MockConnection = connection.buildMockConnection({
onRequest (params) {
@ -114,51 +112,53 @@ test('Multiple searches (inside async iterator)', t => {
const m = client.helpers.msearch({ operations: 2 })
m.search({ index: 'test' }, { query: { match: { foo: 'bar' } } }, (err, result) => {
t.error(err)
t.same(result.body, {
status: 200,
hits: {
hits: [
{ _source: { one: 'one' } },
{ _source: { two: 'two' } },
{ _source: { three: 'three' } }
]
}
m.search({ index: 'test' }, { query: { match: { foo: 'bar' } } })
.then(result => {
t.same(result.body, {
status: 200,
hits: {
hits: [
{ _source: { one: 'one' } },
{ _source: { two: 'two' } },
{ _source: { three: 'three' } }
]
}
})
t.same(result.documents, [
{ one: 'one' },
{ two: 'two' },
{ three: 'three' }
])
})
.catch(t.error)
t.same(result.documents, [
{ one: 'one' },
{ two: 'two' },
{ three: 'three' }
])
})
m.search({ index: 'test' }, { query: { match: { foo: 'bar' } } })
.then(result => {
t.same(result.body, {
status: 200,
hits: {
hits: [
{ _source: { four: 'four' } },
{ _source: { five: 'five' } },
{ _source: { six: 'six' } }
]
}
})
m.search({ index: 'test' }, { query: { match: { foo: 'bar' } } }, (err, result) => {
t.error(err)
t.same(result.body, {
status: 200,
hits: {
hits: [
{ _source: { four: 'four' } },
{ _source: { five: 'five' } },
{ _source: { six: 'six' } }
]
}
t.same(result.documents, [
{ four: 'four' },
{ five: 'five' },
{ six: 'six' }
])
})
t.same(result.documents, [
{ four: 'four' },
{ five: 'five' },
{ six: 'six' }
])
})
.catch(t.error)
t.teardown(() => m.stop())
})
test('Multiple searches (async iterator exits)', t => {
t.plan(6)
t.plan(4)
const MockConnection = connection.buildMockConnection({
onRequest (params) {
@ -195,45 +195,47 @@ test('Multiple searches (async iterator exits)', t => {
const m = client.helpers.msearch()
m.search({ index: 'test' }, { query: {} }, (err, result) => {
t.error(err)
t.same(result.body, {
status: 200,
hits: {
hits: [
{ _source: { one: 'one' } },
{ _source: { two: 'two' } },
{ _source: { three: 'three' } }
]
}
m.search({ index: 'test' }, { query: {} })
.then(result => {
t.same(result.body, {
status: 200,
hits: {
hits: [
{ _source: { one: 'one' } },
{ _source: { two: 'two' } },
{ _source: { three: 'three' } }
]
}
})
t.same(result.documents, [
{ one: 'one' },
{ two: 'two' },
{ three: 'three' }
])
})
.catch(t.error)
t.same(result.documents, [
{ one: 'one' },
{ two: 'two' },
{ three: 'three' }
])
})
m.search({ index: 'test' }, { query: {} })
.then(result => {
t.same(result.body, {
status: 200,
hits: {
hits: [
{ _source: { four: 'four' } },
{ _source: { five: 'five' } },
{ _source: { six: 'six' } }
]
}
})
m.search({ index: 'test' }, { query: { match: { foo: 'bar' } } }, (err, result) => {
t.error(err)
t.same(result.body, {
status: 200,
hits: {
hits: [
{ _source: { four: 'four' } },
{ _source: { five: 'five' } },
{ _source: { six: 'six' } }
]
}
t.same(result.documents, [
{ four: 'four' },
{ five: 'five' },
{ six: 'six' }
])
})
t.same(result.documents, [
{ four: 'four' },
{ five: 'five' },
{ six: 'six' }
])
})
.catch(t.error)
setImmediate(() => m.stop())
})
@ -241,7 +243,7 @@ test('Multiple searches (async iterator exits)', t => {
test('Stop a msearch processor (promises)', async t => {
const MockConnection = connection.buildMockConnection({
onRequest (params) {
return {}
return { body: {} }
}
})
@ -259,19 +261,19 @@ test('Stop a msearch processor (promises)', async t => {
{ index: 'test' },
{ query: { match: { foo: 'bar' } } }
)
} catch (err) {
} catch (err: any) {
t.equal(err.message, 'The msearch processor has been stopped')
}
t.teardown(() => m.stop())
})
test('Stop a msearch processor (callbacks)', t => {
test('Bad header', t => {
t.plan(1)
const MockConnection = connection.buildMockConnection({
onRequest (params) {
return {}
return { body: {} }
}
})
@ -282,33 +284,7 @@ test('Stop a msearch processor (callbacks)', t => {
const m = client.helpers.msearch()
m.stop()
m.search({ index: 'test' }, { query: { match: { foo: 'bar' } } }, (err, result) => {
t.equal(err.message, 'The msearch processor has been stopped')
})
})
test('Bad header', t => {
t.plan(2)
const MockConnection = connection.buildMockConnection({
onRequest (params) {
return {}
}
})
const client = new Client({
node: 'http://localhost:9200',
Connection: MockConnection
})
const m = client.helpers.msearch()
m.search(null, { query: { match: { foo: 'bar' } } }, (err, result) => {
t.equal(err.message, 'The header should be an object')
})
// @ts-expect-error
m.search(null, { query: { match: { foo: 'bar' } } })
.catch(err => {
t.equal(err.message, 'The header should be an object')
@ -318,11 +294,11 @@ test('Bad header', t => {
})
test('Bad body', t => {
t.plan(2)
t.plan(1)
const MockConnection = connection.buildMockConnection({
onRequest (params) {
return {}
return { body: {} }
}
})
@ -333,10 +309,7 @@ test('Bad body', t => {
const m = client.helpers.msearch()
m.search({ index: 'test' }, null, (err, result) => {
t.equal(err.message, 'The body should be an object')
})
// @ts-expect-error
m.search({ index: 'test' }, null)
.catch(err => {
t.equal(err.message, 'The body should be an object')
@ -435,7 +408,7 @@ test('Single search errors', async t => {
{ index: 'test' },
{ query: { match: { foo: 'bar' } } }
)
} catch (err) {
} catch (err: any) {
t.ok(err instanceof errors.ResponseError)
}
@ -443,7 +416,7 @@ test('Single search errors', async t => {
})
test('Entire msearch fails', t => {
t.plan(4)
t.plan(2)
const MockConnection = connection.buildMockConnection({
onRequest (params) {
@ -464,15 +437,15 @@ test('Entire msearch fails', t => {
const m = client.helpers.msearch({ operations: 1 })
m.search({ index: 'test' }, { query: {} }, (err, result) => {
t.ok(err instanceof errors.ResponseError)
t.same(result.documents, [])
})
m.search({ index: 'test' }, { query: {} })
.catch(err => {
t.ok(err instanceof errors.ResponseError)
})
m.search({ index: 'test' }, { query: {} }, (err, result) => {
t.ok(err instanceof errors.ResponseError)
t.same(result.documents, [])
})
m.search({ index: 'test' }, { query: {} })
.catch(err => {
t.ok(err instanceof errors.ResponseError)
})
t.teardown(() => m.stop())
})
@ -482,7 +455,7 @@ test('Resolves the msearch helper', t => {
const MockConnection = connection.buildMockConnection({
onRequest (params) {
return {}
return { body: {} }
}
})
@ -508,7 +481,7 @@ test('Stop the msearch helper with an error', t => {
const MockConnection = connection.buildMockConnection({
onRequest (params) {
return {}
return { body: {} }
}
})
@ -528,13 +501,14 @@ test('Stop the msearch helper with an error', t => {
m.catch(err => t.equal(err.message, 'kaboom'))
m.search({ index: 'test' }, { query: {} }, (err, result) => {
t.equal(err.message, 'kaboom')
})
m.search({ index: 'test' }, { query: {} })
.catch(err => {
t.equal(err.message, 'kaboom')
})
})
test('Multiple searches (concurrency = 1)', t => {
t.plan(6)
t.plan(4)
const MockConnection = connection.buildMockConnection({
onRequest (params) {
@ -562,51 +536,53 @@ test('Multiple searches (concurrency = 1)', t => {
const m = client.helpers.msearch({ operations: 1, concurrency: 1 })
m.search({ index: 'test' }, { query: {} }, (err, result) => {
t.error(err)
t.same(result.body, {
status: 200,
hits: {
hits: [
{ _source: { one: 'one' } },
{ _source: { two: 'two' } },
{ _source: { three: 'three' } }
]
}
m.search({ index: 'test' }, { query: { match: { foo: 'bar' } } })
.then(result => {
t.same(result.body, {
status: 200,
hits: {
hits: [
{ _source: { one: 'one' } },
{ _source: { two: 'two' } },
{ _source: { three: 'three' } }
]
}
})
t.same(result.documents, [
{ one: 'one' },
{ two: 'two' },
{ three: 'three' }
])
})
.catch(t.error)
t.same(result.documents, [
{ one: 'one' },
{ two: 'two' },
{ three: 'three' }
])
})
m.search({ index: 'test' }, { query: { match: { foo: 'bar' } } })
.then(result => {
t.same(result.body, {
status: 200,
hits: {
hits: [
{ _source: { one: 'one' } },
{ _source: { two: 'two' } },
{ _source: { three: 'three' } }
]
}
})
m.search({ index: 'test' }, { query: {} }, (err, result) => {
t.error(err)
t.same(result.body, {
status: 200,
hits: {
hits: [
{ _source: { one: 'one' } },
{ _source: { two: 'two' } },
{ _source: { three: 'three' } }
]
}
t.same(result.documents, [
{ one: 'one' },
{ two: 'two' },
{ three: 'three' }
])
})
t.same(result.documents, [
{ one: 'one' },
{ two: 'two' },
{ three: 'three' }
])
})
.catch(t.error)
t.teardown(() => m.stop())
})
test('Flush interval', t => {
t.plan(4)
t.plan(2)
const clock = FakeTimers.install({ toFake: ['setTimeout', 'clearTimeout'] })
t.teardown(() => clock.uninstall())
@ -645,15 +621,15 @@ test('Flush interval', t => {
const m = client.helpers.msearch()
m.search({ index: 'test' }, { query: { match: { foo: 'bar' } } }, (err, result) => {
t.error(err)
t.equal(result.documents.length, 3)
})
m.search({ index: 'test' }, { query: { match: { foo: 'bar' } } })
.then(result => {
t.equal(result.documents.length, 3)
})
m.search({ index: 'test' }, { query: { match: { foo: 'bar' } } }, (err, result) => {
t.error(err)
t.equal(result.documents.length, 3)
})
m.search({ index: 'test' }, { query: { match: { foo: 'bar' } } })
.then(result => {
t.equal(result.documents.length, 3)
})
setImmediate(clock.next)
@ -661,7 +637,7 @@ test('Flush interval', t => {
})
test('Flush interval - early stop', t => {
t.plan(3)
t.plan(2)
const MockConnection = connection.buildMockConnection({
onRequest (params) {
@ -689,15 +665,16 @@ test('Flush interval - early stop', t => {
const m = client.helpers.msearch()
m.search({ index: 'test' }, { query: { match: { foo: 'bar' } } }, (err, result) => {
t.error(err)
t.equal(result.documents.length, 3)
})
m.search({ index: 'test' }, { query: { match: { foo: 'bar' } } })
.then(result => {
t.equal(result.documents.length, 3)
})
setImmediate(() => {
m.search({ index: 'test' }, { query: { match: { foo: 'bar' } } }, (err, result) => {
t.ok(err instanceof errors.ConfigurationError)
})
m.search({ index: 'test' }, { query: { match: { foo: 'bar' } } })
.catch(err => {
t.ok(err instanceof errors.ConfigurationError)
})
})
m.stop()

View File

@ -17,15 +17,18 @@
* under the License.
*/
'use strict'
import { test } from 'tap'
import { Client, errors } from '../../../'
import { connection } from '../../utils'
const { test } = require('tap')
const { errors } = require('../../../')
const { Client, connection } = require('../../utils')
let clientVersion = require('../../../package.json').version
let clientVersion: string = require('../../../package.json').version // eslint-disable-line
if (clientVersion.includes('-')) {
clientVersion = clientVersion.slice(0, clientVersion.indexOf('-')) + 'p'
}
let transportVersion: string = require('@elastic/transport/package.json').version // eslint-disable-line
if (transportVersion.includes('-')) {
transportVersion = transportVersion.slice(0, transportVersion.indexOf('-')) + 'p'
}
const nodeVersion = process.versions.node
test('Scroll search', async t => {
@ -33,12 +36,17 @@ test('Scroll search', async t => {
const MockConnection = connection.buildMockConnection({
onRequest (params) {
t.match(params.headers, {
'x-elastic-client-meta': `es=${clientVersion},js=${nodeVersion},t=${clientVersion},hc=${nodeVersion},h=s`
'x-elastic-client-meta': `es=${clientVersion},js=${nodeVersion},t=${transportVersion},hc=${nodeVersion},h=s`
})
count += 1
if (params.method === 'POST') {
t.equal(params.querystring, 'scroll=1m')
if (params.path === '/test/_search') {
t.equal(params.querystring, 'scroll=1m')
} else {
// @ts-expect-error
t.equal(JSON.parse(params.body).scroll, '1m')
}
}
if (count === 4) {
// final automated clear
@ -69,10 +77,11 @@ test('Scroll search', async t => {
const scrollSearch = client.helpers.scrollSearch({
index: 'test',
body: { foo: 'bar' }
query: { match_all: {} }
})
for await (const result of scrollSearch) {
// @ts-expect-error
t.equal(result.body.count, count)
t.equal(result.body._scroll_id, 'id')
}
@ -83,9 +92,10 @@ test('Clear a scroll search', async t => {
const MockConnection = connection.buildMockConnection({
onRequest (params) {
t.notMatch(params.headers, {
'x-elastic-client-meta': `es=${clientVersion},js=${nodeVersion},t=${clientVersion},hc=${nodeVersion},h=s`
'x-elastic-client-meta': `es=${clientVersion},js=${nodeVersion},t=${transportVersion},hc=${nodeVersion},h=s`
})
if (params.method === 'DELETE') {
// @ts-expect-error
const body = JSON.parse(params.body)
t.equal(body.scroll_id, 'id')
}
@ -113,13 +123,14 @@ test('Clear a scroll search', async t => {
const scrollSearch = client.helpers.scrollSearch({
index: 'test',
body: { foo: 'bar' }
query: { match_all: {} }
})
for await (const result of scrollSearch) {
if (count === 2) {
t.fail('The scroll search should be cleared')
}
// @ts-expect-error
t.equal(result.body.count, count)
if (count === 1) {
await result.clear()
@ -166,13 +177,15 @@ test('Scroll search (retry)', async t => {
const scrollSearch = client.helpers.scrollSearch({
index: 'test',
body: { foo: 'bar' }
query: { match_all: {} }
}, {
wait: 10
})
for await (const result of scrollSearch) {
// @ts-expect-error
t.equal(result.body.count, count)
// @ts-expect-error
t.not(result.body.count, 1)
t.equal(result.body._scroll_id, 'id')
}
@ -197,17 +210,18 @@ test('Scroll search (retry throws and maxRetries)', async t => {
const scrollSearch = client.helpers.scrollSearch({
index: 'test',
body: { foo: 'bar' }
query: { match_all: {} }
}, {
wait: 10,
ignore: [404]
})
try {
// @ts-expect-error
for await (const result of scrollSearch) { // eslint-disable-line
t.fail('we should not be here')
}
} catch (err) {
} catch (err: any) {
t.ok(err instanceof errors.ResponseError)
t.equal(err.statusCode, 429)
t.equal(count, expectedAttempts)
@ -222,7 +236,14 @@ test('Scroll search (retry throws later)', async t => {
onRequest (params) {
count += 1
// filter_path should not be added if is not already present
t.equal(params.querystring, 'scroll=1m')
if (params.method === 'POST') {
if (params.path === '/test/_search') {
t.equal(params.querystring, 'scroll=1m')
} else {
// @ts-expect-error
t.equal(JSON.parse(params.body).scroll, '1m')
}
}
if (count > 1) {
return { body: {}, statusCode: 429 }
}
@ -251,16 +272,17 @@ test('Scroll search (retry throws later)', async t => {
const scrollSearch = client.helpers.scrollSearch({
index: 'test',
body: { foo: 'bar' }
query: { match_all: {} }
}, {
wait: 10
})
try {
for await (const result of scrollSearch) { // eslint-disable-line
// @ts-expect-error
t.equal(result.body.count, count)
}
} catch (err) {
} catch (err: any) {
t.ok(err instanceof errors.ResponseError)
t.equal(err.statusCode, 429)
t.equal(count, expectedAttempts)
@ -275,8 +297,7 @@ test('Scroll search documents', async t => {
t.equal(params.querystring, 'filter_path=hits.hits._source%2C_scroll_id&scroll=1m')
} else {
if (params.method !== 'DELETE') {
t.equal(params.querystring, 'scroll=1m')
t.equal(params.body, '{"scroll_id":"id"}')
t.equal(params.body, '{"scroll":"1m","scroll_id":"id"}')
}
}
return {
@ -304,7 +325,7 @@ test('Scroll search documents', async t => {
const scrollSearch = client.helpers.scrollDocuments({
index: 'test',
body: { foo: 'bar' }
query: { match_all: {} }
})
let n = 1
@ -337,17 +358,18 @@ test('Should not retry if maxRetries = 0', async t => {
const scrollSearch = client.helpers.scrollSearch({
index: 'test',
body: { foo: 'bar' }
query: { match_all: {} }
}, {
wait: 10,
ignore: [404]
})
try {
// @ts-expect-error
for await (const result of scrollSearch) { // eslint-disable-line
t.fail('we should not be here')
}
} catch (err) {
} catch (err: any) {
t.ok(err instanceof errors.ResponseError)
t.equal(err.statusCode, 429)
t.equal(count, expectedAttempts)
@ -359,10 +381,17 @@ test('Fix querystring for scroll search', async t => {
const MockConnection = connection.buildMockConnection({
onRequest (params) {
if (count === 0) {
t.equal(params.querystring, 'size=1&scroll=1m')
t.equal(params.querystring, 'scroll=1m')
} else {
if (params.method !== 'DELETE') {
t.equal(params.querystring, 'scroll=1m')
if (params.method === 'POST') {
if (params.path === '/test/_search') {
t.equal(params.querystring, 'scroll=1m')
} else {
// @ts-expect-error
t.equal(JSON.parse(params.body).scroll, '1m')
}
}
}
}
return {
@ -388,7 +417,7 @@ test('Fix querystring for scroll search', async t => {
const scrollSearch = client.helpers.scrollSearch({
index: 'test',
size: 1,
body: { foo: 'bar' }
query: { match_all: {} }
})
for await (const response of scrollSearch) {

View File

@ -17,10 +17,9 @@
* under the License.
*/
'use strict'
const { test } = require('tap')
const { Client, connection } = require('../../utils')
import { test } from 'tap'
import { Client } from '../../../'
import { connection } from '../../utils'
test('Search should have an additional documents property', async t => {
const MockConnection = connection.buildMockConnection({
@ -47,7 +46,7 @@ test('Search should have an additional documents property', async t => {
const result = await client.helpers.search({
index: 'test',
body: { foo: 'bar' }
query: { match_all: {} }
})
t.same(result, [
{ one: 'one' },
@ -71,7 +70,7 @@ test('kGetHits fallback', async t => {
const result = await client.helpers.search({
index: 'test',
body: { foo: 'bar' }
query: { match_all: {} }
})
t.same(result, [])
})
@ -102,46 +101,11 @@ test('Merge filter paths (snake_case)', async t => {
const result = await client.helpers.search({
index: 'test',
filter_path: 'foo',
body: { foo: 'bar' }
query: { match_all: {} }
})
t.same(result, [
{ one: 'one' },
{ two: 'two' },
{ three: 'three' }
])
})
test('Merge filter paths (camelCase)', async t => {
const MockConnection = connection.buildMockConnection({
onRequest (params) {
t.equal(params.querystring, 'filter_path=foo%2Chits.hits._source')
return {
body: {
hits: {
hits: [
{ _source: { one: 'one' } },
{ _source: { two: 'two' } },
{ _source: { three: 'three' } }
]
}
}
}
}
})
const client = new Client({
node: 'http://localhost:9200',
Connection: MockConnection
})
const result = await client.helpers.search({
index: 'test',
filterPath: 'foo',
body: { foo: 'bar' }
})
t.same(result, [
{ one: 'one' },
{ two: 'two' },
{ three: 'three' }
])
})
})