Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ describe('plugins/elasticsearch', () => {

cluster = { callWithInternalUser: sinon.stub() };
cluster.callWithInternalUser.withArgs('index', sinon.match.any).returns(Promise.resolve());
cluster.callWithInternalUser.withArgs('create', sinon.match.any).returns(Promise.resolve({ _id: 1, _version: 1 }));
cluster.callWithInternalUser.withArgs('create', sinon.match.any).returns(Promise.resolve({ _id: '1', _version: 1 }));
cluster.callWithInternalUser.withArgs('mget', sinon.match.any).returns(Promise.resolve({ ok: true }));
cluster.callWithInternalUser.withArgs('get', sinon.match.any).returns(Promise.resolve({ found: false }));
cluster.callWithInternalUser.withArgs('search', sinon.match.any).returns(Promise.resolve({ hits: { hits: [] } }));
Expand Down
116 changes: 75 additions & 41 deletions src/server/saved_objects/client/__tests__/saved_objects_client.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import expect from 'expect.js';
import sinon from 'sinon';
import { SavedObjectsClient } from '../saved_objects_client';
import { createIdQuery } from '../lib/create_id_query';

describe('SavedObjectsClient', () => {
let callAdminCluster;
Expand Down Expand Up @@ -167,16 +168,16 @@ describe('SavedObjectsClient', () => {
errors: false,
items: [{
create: {
_type: 'foo',
_type: 'config',
_id: 'one',
error: {
reason: 'type[config] missing'
}
}
}, {
create: {
_type: 'config',
_id: 'one',
_type: 'index-pattern',
_id: 'two',
_version: 2
}
}]
Expand All @@ -190,13 +191,13 @@ describe('SavedObjectsClient', () => {
expect(response).to.eql([
{
id: 'one',
type: 'foo',
type: 'config',
version: undefined,
attributes: { title: 'Test One' },
error: { message: 'type[config] missing' }
}, {
id: 'one',
type: 'config',
id: 'two',
type: 'index-pattern',
version: 2,
attributes: { title: 'Test Two' },
error: undefined
Expand All @@ -215,8 +216,8 @@ describe('SavedObjectsClient', () => {
}
}, {
create: {
_type: 'config',
_id: 'one',
_type: 'index-pattern',
_id: 'two',
_version: 2
}
}]
Expand All @@ -235,8 +236,8 @@ describe('SavedObjectsClient', () => {
attributes: { title: 'Test One' },
error: undefined
}, {
id: 'one',
type: 'config',
id: 'two',
type: 'index-pattern',
version: 2,
attributes: { title: 'Test Two' },
error: undefined
Expand All @@ -247,7 +248,9 @@ describe('SavedObjectsClient', () => {

describe('#delete', () => {
it('throws notFound when ES is unable to find the document', (done) => {
callAdminCluster.returns(Promise.resolve({ found: false }));
callAdminCluster.returns(Promise.resolve({
deleted: 0
}));

savedObjectsClient.delete('index-pattern', 'logstash-*').then(() => {
done('failed');
Expand All @@ -263,10 +266,9 @@ describe('SavedObjectsClient', () => {
expect(callAdminCluster.calledOnce).to.be(true);

const args = callAdminCluster.getCall(0).args;
expect(args[0]).to.be('delete');
expect(args[0]).to.be('deleteByQuery');
expect(args[1]).to.eql({
type: 'index-pattern',
id: 'logstash-*',
body: createIdQuery({ type: 'index-pattern', id: 'logstash-*' }),
refresh: 'wait_for',
index: '.kibana-test'
});
Expand Down Expand Up @@ -311,7 +313,23 @@ describe('SavedObjectsClient', () => {
const expectedQuery = {
bool: {
must: [{ match_all: {} }],
filter: [{ term: { _type: 'index-pattern' } }]
filter: [
{
bool: {
should: [
{
term: {
_type: 'index-pattern'
}
}, {
term: {
type: 'index-pattern'
}
}
]
}
}
]
}
};

Expand Down Expand Up @@ -364,18 +382,26 @@ describe('SavedObjectsClient', () => {
expect(callAdminCluster.calledOnce).to.be(true);

const options = callAdminCluster.getCall(0).args[1];
expect(options._source).to.eql('title');
expect(options._source).to.eql([
'*.title', 'type', 'title'
]);
});
});

describe('#get', () => {
it('formats Elasticsearch response', async () => {
callAdminCluster.returns(Promise.resolve({
_id: 'logstash-*',
_type: 'index-pattern',
_version: 2,
_source: {
title: 'Testing'
hits: {
hits: [
{
_id: 'logstash-*',
_type: 'index-pattern',
_version: 2,
_source: {
title: 'Testing'
}
}
]
}
}));

Expand All @@ -392,20 +418,20 @@ describe('SavedObjectsClient', () => {
});

describe('#bulkGet', () => {
it('accepts a array of mixed type and ids', async () => {
it('accepts an array of mixed type and ids', async () => {
await savedObjectsClient.bulkGet([
{ id: 'one', type: 'config' },
{ id: 'two', type: 'index-pattern' },
{ id: 'three' }
{ id: 'two', type: 'index-pattern' }
]);

expect(callAdminCluster.calledOnce).to.be(true);

const options = callAdminCluster.getCall(0).args[1];
expect(options.body.docs).to.eql([
{ _type: 'config', _id: 'one' },
{ _type: 'index-pattern', _id: 'two' },
{ _type: undefined, _id: 'three' }
expect(options.body).to.eql([
{},
createIdQuery({ type: 'config', id: 'one' }),
{},
createIdQuery({ type: 'index-pattern', id: 'two' })
]);
});

Expand All @@ -416,23 +442,31 @@ describe('SavedObjectsClient', () => {
expect(callAdminCluster.notCalled).to.be(true);
});

it('omits missed objects', async () => {
it('reports error on missed objects', async () => {
callAdminCluster.returns(Promise.resolve({
docs:[{
_type: 'config',
_id: 'bad',
found: false
}, {
_type: 'config',
_id: 'good',
found: true,
_version: 2,
_source: { title: 'Test' }
}]
responses: [
{
hits: {
hits: [
{
_id: 'good',
_type: 'doc',
_version: 2,
_source: {
type: 'config',
config: {
title: 'Test'
}
}
}
]
}
}
]
}));

const { saved_objects: savedObjects } = await savedObjectsClient.bulkGet(
['good', 'bad', 'config']
[{ id: 'good', type: 'config' }, { id: 'bad', type: 'config' }]
);

expect(savedObjects).to.have.length(1);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import elasticsearch from 'elasticsearch';
import expect from 'expect.js';
import sinon from 'sinon';

import { SavedObjectsClient } from '../saved_objects_client';
const { BadRequest } = elasticsearch.errors;

describe('SavedObjectsClient', () => {
let callAdminCluster;
let savedObjectsClient;
const illegalArgumentException = {
type: 'illegal_argument_exception',
reason: 'Rejecting mapping update to [.kibana-v6] as the final mapping would have more than 1 type: [doc, foo]'
};

describe('mapping', () => {
beforeEach(() => {
callAdminCluster = sinon.stub();
savedObjectsClient = new SavedObjectsClient('.kibana-test', {}, callAdminCluster);
});

afterEach(() => {
callAdminCluster.reset();
});


describe('#create', () => {
it('falls back to v6 mapping', async () => {
const error = new BadRequest('[illegal_argument_exception] Rejecting mapping update to [.kibana-v6]', {
body: {
error: illegalArgumentException
}
});

callAdminCluster
.onFirstCall().throws(error)
.onSecondCall().returns(Promise.resolve({ _type: 'index-pattern', _id: 'logstash-*', _version: 2 }));

const response = await savedObjectsClient.create('index-pattern', {
title: 'Logstash'
});

expect(response).to.eql({
type: 'index-pattern',
id: 'logstash-*',
version: 2,
attributes: {
title: 'Logstash',
}
});
});
});

describe('#bulkCreate', () => {
it('falls back to v6 mappings', async () => {
const firstResponse = {
errors: true,
items: [{
create: {
_type: 'config',
_id: 'one',
_version: 2,
status: 400,
error: illegalArgumentException
}
}, {
create: {
_type: 'index-pattern',
_id: 'two',
_version: 2,
status: 400,
error: illegalArgumentException
}
}]
};

const secondResponse = {
errors: false,
items: [{
create: {
_type: 'config',
_id: 'one',
_version: 2
}
}, {
create: {
_type: 'index-pattern',
_id: 'two',
_version: 2
}
}]
};

callAdminCluster
.onFirstCall().returns(Promise.resolve(firstResponse))
.onSecondCall().returns(Promise.resolve(secondResponse));

const response = await savedObjectsClient.bulkCreate([
{ type: 'config', id: 'one', attributes: { title: 'Test One' } },
{ type: 'index-pattern', id: 'two', attributes: { title: 'Test Two' } }
]);

expect(response).to.eql([
{
id: 'one',
type: 'config',
version: 2,
attributes: { title: 'Test One' },
error: undefined
}, {
id: 'two',
type: 'index-pattern',
version: 2,
attributes: { title: 'Test Two' },
error: undefined
}
]);
});
});

describe('update', () => {
it('falls back to v6 mappings', async () => {
const id = 'logstash-*';
const type = 'index-pattern';
const version = 2;
const attributes = { title: 'Testing' };

const error = new BadRequest('[document_missing_exception] [config][logstash-*]: document missing', {
body: {
error: {
type: 'document_missing_exception'
}
}
});

callAdminCluster
.onFirstCall().throws(error)
.onSecondCall().returns(Promise.resolve({
_id: id,
_type: type,
_version: version,
result: 'updated'
}));

const response = await savedObjectsClient.update('index-pattern', 'logstash-*', attributes);
expect(response).to.eql({
id,
type,
version,
attributes
});
});
});
});
});
Loading