Test the new client wrapper.
Signed-off-by: Eric Peterson <ericpeterson@spotify.com>
This commit is contained in:
@@ -38,7 +38,8 @@
|
||||
"devDependencies": {
|
||||
"@backstage/backend-common": "^0.14.1-next.0",
|
||||
"@backstage/cli": "^0.17.3-next.0",
|
||||
"@elastic/elasticsearch-mock": "^1.0.0"
|
||||
"@elastic/elasticsearch-mock": "^1.0.0",
|
||||
"@short.io/opensearch-mock": "^0.3.1"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
|
||||
+337
@@ -0,0 +1,337 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { Client as ElasticSearchClient } from '@elastic/elasticsearch';
|
||||
import { Client as OpenSearchClient } from '@opensearch-project/opensearch';
|
||||
import Mock from '@short.io/opensearch-mock';
|
||||
import { Readable } from 'stream';
|
||||
|
||||
import { ElasticSearchClientWrapper } from './ElasticSearchClientWrapper';
|
||||
import {
|
||||
createElasticSearchClientOptions,
|
||||
ElasticSearchClientOptions,
|
||||
} from './ElasticSearchSearchEngine';
|
||||
|
||||
jest.mock('@elastic/elasticsearch', () => ({
|
||||
...jest.requireActual('@elastic/elasticsearch'),
|
||||
Client: jest.fn().mockReturnValue({
|
||||
search: jest
|
||||
.fn()
|
||||
.mockImplementation(async args => ({ client: 'es', args })),
|
||||
cat: {
|
||||
aliases: jest
|
||||
.fn()
|
||||
.mockImplementation(async args => ({ client: 'es', args })),
|
||||
},
|
||||
helpers: {
|
||||
bulk: jest
|
||||
.fn()
|
||||
.mockImplementation(async args => ({ client: 'es', args })),
|
||||
},
|
||||
indices: {
|
||||
create: jest
|
||||
.fn()
|
||||
.mockImplementation(async args => ({ client: 'es', args })),
|
||||
delete: jest
|
||||
.fn()
|
||||
.mockImplementation(async args => ({ client: 'es', args })),
|
||||
exists: jest
|
||||
.fn()
|
||||
.mockImplementation(async args => ({ client: 'es', args })),
|
||||
putIndexTemplate: jest
|
||||
.fn()
|
||||
.mockImplementation(async args => ({ client: 'es', args })),
|
||||
updateAliases: jest
|
||||
.fn()
|
||||
.mockImplementation(async args => ({ client: 'es', args })),
|
||||
},
|
||||
}),
|
||||
}));
|
||||
|
||||
jest.mock('@opensearch-project/opensearch', () => ({
|
||||
...jest.requireActual('@opensearch-project/opensearch'),
|
||||
Client: jest.fn().mockReturnValue({
|
||||
search: jest
|
||||
.fn()
|
||||
.mockImplementation(async args => ({ client: 'os', args })),
|
||||
cat: {
|
||||
aliases: jest
|
||||
.fn()
|
||||
.mockImplementation(async args => ({ client: 'os', args })),
|
||||
},
|
||||
helpers: {
|
||||
bulk: jest
|
||||
.fn()
|
||||
.mockImplementation(async args => ({ client: 'os', args })),
|
||||
},
|
||||
indices: {
|
||||
create: jest
|
||||
.fn()
|
||||
.mockImplementation(async args => ({ client: 'os', args })),
|
||||
delete: jest
|
||||
.fn()
|
||||
.mockImplementation(async args => ({ client: 'os', args })),
|
||||
exists: jest
|
||||
.fn()
|
||||
.mockImplementation(async args => ({ client: 'os', args })),
|
||||
putIndexTemplate: jest
|
||||
.fn()
|
||||
.mockImplementation(async args => ({ client: 'os', args })),
|
||||
updateAliases: jest
|
||||
.fn()
|
||||
.mockImplementation(async args => ({ client: 'os', args })),
|
||||
},
|
||||
}),
|
||||
}));
|
||||
|
||||
describe('ElasticSearchClientWrapper', () => {
|
||||
describe('elasticSearchClient', () => {
|
||||
let esOptions: ElasticSearchClientOptions;
|
||||
|
||||
beforeEach(async () => {
|
||||
esOptions = await createElasticSearchClientOptions(
|
||||
new ConfigReader({
|
||||
node: 'http://localhost:9200',
|
||||
}),
|
||||
);
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('instantiation', () => {
|
||||
ElasticSearchClientWrapper.fromClientOptions(esOptions);
|
||||
expect(ElasticSearchClient).toHaveBeenCalledWith(esOptions);
|
||||
});
|
||||
|
||||
it('search', async () => {
|
||||
const wrapper = ElasticSearchClientWrapper.fromClientOptions(esOptions);
|
||||
|
||||
const searchInput = { index: 'xyz', body: { eg: 'etc' } };
|
||||
const result = (await wrapper.search(searchInput)) as any;
|
||||
|
||||
// Should call the ElasticSearch client's search with expected input.
|
||||
expect(result.client).toBe('es');
|
||||
expect(result.args).toStrictEqual(searchInput);
|
||||
});
|
||||
|
||||
it('bulk', async () => {
|
||||
const wrapper = ElasticSearchClientWrapper.fromClientOptions(esOptions);
|
||||
|
||||
const bulkInput = {
|
||||
datasource: Readable.from([{}]),
|
||||
onDocument() {
|
||||
return { index: { _index: 'xyz' } };
|
||||
},
|
||||
refreshCompletion: 'xyz',
|
||||
};
|
||||
const result = (await wrapper.bulk(bulkInput)) as any;
|
||||
|
||||
// Should call the ElasticSearch client's bulk helper with expected input
|
||||
expect(result.client).toBe('es');
|
||||
expect(result.args).toStrictEqual(bulkInput);
|
||||
});
|
||||
|
||||
it('putIndexTemplate', async () => {
|
||||
const wrapper = ElasticSearchClientWrapper.fromClientOptions(esOptions);
|
||||
|
||||
const indexTemplate = { name: 'xyz', body: { index_patterns: ['*'] } };
|
||||
const result = (await wrapper.putIndexTemplate(indexTemplate)) as any;
|
||||
|
||||
// Should call the ElasticSearch client with expected input.
|
||||
expect(result.client).toBe('es');
|
||||
expect(result.args).toStrictEqual(indexTemplate);
|
||||
});
|
||||
|
||||
it('indexExists', async () => {
|
||||
const wrapper = ElasticSearchClientWrapper.fromClientOptions(esOptions);
|
||||
|
||||
const input = { index: 'xyz' };
|
||||
const result = (await wrapper.indexExists(input)) as any;
|
||||
|
||||
// Should call the ElasticSearch client with expected input.
|
||||
expect(result.client).toBe('es');
|
||||
expect(result.args).toStrictEqual(input);
|
||||
});
|
||||
|
||||
it('deleteIndex', async () => {
|
||||
const wrapper = ElasticSearchClientWrapper.fromClientOptions(esOptions);
|
||||
|
||||
const input = { index: 'xyz' };
|
||||
const result = (await wrapper.deleteIndex(input)) as any;
|
||||
|
||||
// Should call the OpenSearch client with expected input.
|
||||
expect(result.client).toBe('es');
|
||||
expect(result.args).toStrictEqual(input);
|
||||
});
|
||||
|
||||
it('createIndex', async () => {
|
||||
const wrapper = ElasticSearchClientWrapper.fromClientOptions(esOptions);
|
||||
|
||||
const input = { index: 'xyz' };
|
||||
const result = (await wrapper.createIndex(input)) as any;
|
||||
|
||||
// Should call the OpenSearch client with expected input.
|
||||
expect(result.client).toBe('es');
|
||||
expect(result.args).toStrictEqual(input);
|
||||
});
|
||||
|
||||
it('getAliases', async () => {
|
||||
const wrapper = ElasticSearchClientWrapper.fromClientOptions(esOptions);
|
||||
|
||||
const input = { aliases: ['xyz'] };
|
||||
const result = (await wrapper.getAliases(input)) as any;
|
||||
|
||||
// Should call the OpenSearch client with expected input.
|
||||
expect(result.client).toBe('es');
|
||||
expect(result.args).toStrictEqual({
|
||||
format: 'json',
|
||||
name: input.aliases,
|
||||
});
|
||||
});
|
||||
|
||||
it('updateAliases', async () => {
|
||||
const wrapper = ElasticSearchClientWrapper.fromClientOptions(esOptions);
|
||||
|
||||
const input = { actions: [{ remove: { index: 'xyz', alias: 'abc' } }] };
|
||||
const result = (await wrapper.updateAliases(input)) as any;
|
||||
|
||||
// Should call the OpenSearch client with expected input.
|
||||
expect(result.client).toBe('es');
|
||||
expect(result.args).toStrictEqual({
|
||||
body: { actions: input.actions },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('openSearchClient', () => {
|
||||
const mock = new Mock();
|
||||
let osOptions: ElasticSearchClientOptions;
|
||||
|
||||
beforeEach(() => {
|
||||
osOptions = {
|
||||
provider: 'aws',
|
||||
node: 'https://my-es-cluster.eu-west-1.es.amazonaws.com',
|
||||
connection: mock.getConnection(),
|
||||
};
|
||||
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('instantiation', () => {
|
||||
ElasticSearchClientWrapper.fromClientOptions(osOptions);
|
||||
expect(OpenSearchClient).toHaveBeenCalledWith(osOptions);
|
||||
});
|
||||
|
||||
it('search', async () => {
|
||||
const wrapper = ElasticSearchClientWrapper.fromClientOptions(osOptions);
|
||||
|
||||
const searchInput = { index: 'xyz', body: { eg: 'etc' } };
|
||||
const result = (await wrapper.search(searchInput)) as any;
|
||||
|
||||
// Should call the OpenSearch client's search with expected input.
|
||||
expect(result.client).toBe('os');
|
||||
expect(result.args).toStrictEqual(searchInput);
|
||||
});
|
||||
|
||||
it('bulk', async () => {
|
||||
const wrapper = ElasticSearchClientWrapper.fromClientOptions(osOptions);
|
||||
|
||||
const bulkInput = {
|
||||
datasource: Readable.from([{}]),
|
||||
onDocument() {
|
||||
return { index: { _index: 'xyz' } };
|
||||
},
|
||||
refreshCompletion: 'xyz',
|
||||
};
|
||||
const result = (await wrapper.bulk(bulkInput)) as any;
|
||||
|
||||
// Should call the OpenSearch client's bulk helper with expected input.
|
||||
expect(result.client).toBe('os');
|
||||
expect(result.args).toStrictEqual(bulkInput);
|
||||
});
|
||||
|
||||
it('putIndexTemplate', async () => {
|
||||
const wrapper = ElasticSearchClientWrapper.fromClientOptions(osOptions);
|
||||
|
||||
const indexTemplate = { name: 'xyz', body: { index_patterns: ['*'] } };
|
||||
const result = (await wrapper.putIndexTemplate(indexTemplate)) as any;
|
||||
|
||||
// Should call the OpenSearch client with expected input.
|
||||
expect(result.client).toBe('os');
|
||||
expect(result.args).toStrictEqual(indexTemplate);
|
||||
});
|
||||
|
||||
it('indexExists', async () => {
|
||||
const wrapper = ElasticSearchClientWrapper.fromClientOptions(osOptions);
|
||||
|
||||
const input = { index: 'xyz' };
|
||||
const result = (await wrapper.indexExists(input)) as any;
|
||||
|
||||
// Should call the OpenSearch client with expected input.
|
||||
expect(result.client).toBe('os');
|
||||
expect(result.args).toStrictEqual(input);
|
||||
});
|
||||
|
||||
it('deleteIndex', async () => {
|
||||
const wrapper = ElasticSearchClientWrapper.fromClientOptions(osOptions);
|
||||
|
||||
const input = { index: 'xyz' };
|
||||
const result = (await wrapper.deleteIndex(input)) as any;
|
||||
|
||||
// Should call the OpenSearch client with expected input.
|
||||
expect(result.client).toBe('os');
|
||||
expect(result.args).toStrictEqual(input);
|
||||
});
|
||||
|
||||
it('createIndex', async () => {
|
||||
const wrapper = ElasticSearchClientWrapper.fromClientOptions(osOptions);
|
||||
|
||||
const input = { index: 'xyz' };
|
||||
const result = (await wrapper.createIndex(input)) as any;
|
||||
|
||||
// Should call the OpenSearch client with expected input.
|
||||
expect(result.client).toBe('os');
|
||||
expect(result.args).toStrictEqual(input);
|
||||
});
|
||||
|
||||
it('getAliases', async () => {
|
||||
const wrapper = ElasticSearchClientWrapper.fromClientOptions(osOptions);
|
||||
|
||||
const input = { aliases: ['xyz'] };
|
||||
const result = (await wrapper.getAliases(input)) as any;
|
||||
|
||||
// Should call the OpenSearch client with expected input.
|
||||
expect(result.client).toBe('os');
|
||||
expect(result.args).toStrictEqual({
|
||||
format: 'json',
|
||||
name: input.aliases,
|
||||
});
|
||||
});
|
||||
|
||||
it('updateAliases', async () => {
|
||||
const wrapper = ElasticSearchClientWrapper.fromClientOptions(osOptions);
|
||||
|
||||
const input = { actions: [{ remove: { index: 'xyz', alias: 'abc' } }] };
|
||||
const result = (await wrapper.updateAliases(input)) as any;
|
||||
|
||||
// Should call the OpenSearch client with expected input.
|
||||
expect(result.client).toBe('os');
|
||||
expect(result.args).toStrictEqual({
|
||||
body: { actions: input.actions },
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
+1
-1
@@ -366,7 +366,7 @@ export function encodePageCursor({ page }: { page: number }): string {
|
||||
return Buffer.from(`${page}`, 'utf-8').toString('base64');
|
||||
}
|
||||
|
||||
async function createElasticSearchClientOptions(
|
||||
export async function createElasticSearchClientOptions(
|
||||
config?: Config,
|
||||
): Promise<ElasticSearchClientOptions> {
|
||||
if (!config) {
|
||||
|
||||
@@ -5423,6 +5423,15 @@
|
||||
dependencies:
|
||||
any-observable "^0.3.0"
|
||||
|
||||
"@short.io/opensearch-mock@^0.3.1":
|
||||
version "0.3.1"
|
||||
resolved "https://registry.npmjs.org/@short.io/opensearch-mock/-/opensearch-mock-0.3.1.tgz#41678404b94342ac60263a8df590f9b1efa80622"
|
||||
integrity sha512-gwLTzxJrZNGVQNn+FHLhpw7at3jHb6tNczq2hvFPJ3C3nLaCBRkbP2IQHrIDzklLBVFV83Ug0Xgs73A5o9eLtg==
|
||||
dependencies:
|
||||
fast-deep-equal "^3.1.3"
|
||||
find-my-way "^4.3.3"
|
||||
into-stream "^6.0.0"
|
||||
|
||||
"@sideway/address@^4.1.0":
|
||||
version "4.1.1"
|
||||
resolved "https://registry.npmjs.org/@sideway/address/-/address-4.1.1.tgz#9e321e74310963fdf8eebfbee09c7bd69972de4d"
|
||||
|
||||
Reference in New Issue
Block a user