mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[SearchProfiler] Handle scenario when user has no indices (#128066)
This commit is contained in:
parent
c55bb917fa
commit
d253355234
3 changed files with 89 additions and 14 deletions
|
@ -21,6 +21,16 @@ interface ReturnValue {
|
|||
error?: string;
|
||||
}
|
||||
|
||||
interface ProfileResponse {
|
||||
profile?: { shards: ShardSerialized[] };
|
||||
_shards: {
|
||||
failed: number;
|
||||
skipped: number;
|
||||
total: number;
|
||||
successful: number;
|
||||
};
|
||||
}
|
||||
|
||||
const extractProfilerErrorMessage = (e: any): string | undefined => {
|
||||
if (e.body?.attributes?.error?.reason) {
|
||||
const { reason, line, col } = e.body.attributes.error;
|
||||
|
@ -67,8 +77,7 @@ export const useRequestProfile = () => {
|
|||
|
||||
try {
|
||||
const resp = await http.post<
|
||||
| { ok: true; resp: { profile: { shards: ShardSerialized[] } } }
|
||||
| { ok: false; err: { msg: string } }
|
||||
{ ok: true; resp: ProfileResponse } | { ok: false; err: { msg: string } }
|
||||
>('../api/searchprofiler/profile', {
|
||||
body: JSON.stringify(payload),
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
|
@ -78,7 +87,23 @@ export const useRequestProfile = () => {
|
|||
return { data: null, error: resp.err.msg };
|
||||
}
|
||||
|
||||
return { data: resp.resp.profile.shards };
|
||||
// If a user attempts to run Search Profiler without any indices,
|
||||
// _shards=0 and a "profile" output will not be returned
|
||||
if (resp.resp._shards.total === 0) {
|
||||
notifications.addDanger({
|
||||
'data-test-subj': 'noShardsNotification',
|
||||
title: i18n.translate('xpack.searchProfiler.errorNoShardsTitle', {
|
||||
defaultMessage: 'Unable to profile',
|
||||
}),
|
||||
text: i18n.translate('xpack.searchProfiler.errorNoShardsDescription', {
|
||||
defaultMessage: 'Verify your index input matches a valid index',
|
||||
}),
|
||||
});
|
||||
|
||||
return { data: null };
|
||||
}
|
||||
|
||||
return { data: resp.resp.profile!.shards };
|
||||
} catch (e) {
|
||||
const profilerErrorMessage = extractProfilerErrorMessage(e);
|
||||
if (profilerErrorMessage) {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
import { asyncForEach } from '@kbn/std';
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
||||
|
@ -14,6 +15,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
const aceEditor = getService('aceEditor');
|
||||
const retry = getService('retry');
|
||||
const security = getService('security');
|
||||
const es = getService('es');
|
||||
const log = getService('log');
|
||||
|
||||
const editorTestSubjectSelector = 'searchProfilerEditor';
|
||||
|
||||
|
@ -34,23 +37,23 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
|
||||
const okInput = [
|
||||
`{
|
||||
"query": {
|
||||
"match_all": {}`,
|
||||
"query": {
|
||||
"match_all": {}`,
|
||||
`{
|
||||
"query": {
|
||||
"match_all": {
|
||||
"test": """{ "more": "json" }"""`,
|
||||
"query": {
|
||||
"match_all": {
|
||||
"test": """{ "more": "json" }"""`,
|
||||
];
|
||||
|
||||
const notOkInput = [
|
||||
`{
|
||||
"query": {
|
||||
"match_all": {
|
||||
"test": """{ "more": "json" }""`,
|
||||
"query": {
|
||||
"match_all": {
|
||||
"test": """{ "more": "json" }""`,
|
||||
`{
|
||||
"query": {
|
||||
"match_all": {
|
||||
"test": """{ "more": "json" }""'`,
|
||||
"query": {
|
||||
"match_all": {
|
||||
"test": """{ "more": "json" }""'`,
|
||||
];
|
||||
|
||||
const expectHasParseErrorsToBe = (expectation: boolean) => async (inputs: string[]) => {
|
||||
|
@ -70,5 +73,44 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
await expectHasParseErrorsToBe(false)(okInput);
|
||||
await expectHasParseErrorsToBe(true)(notOkInput);
|
||||
});
|
||||
|
||||
describe('No indices', () => {
|
||||
before(async () => {
|
||||
// Delete any existing indices that were not properly cleaned up
|
||||
try {
|
||||
const indices = await es.indices.get({
|
||||
index: '*',
|
||||
});
|
||||
const indexNames = Object.keys(indices);
|
||||
|
||||
if (indexNames.length > 0) {
|
||||
await asyncForEach(indexNames, async (indexName) => {
|
||||
await es.indices.delete({ index: indexName });
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
log.debug('[Setup error] Error deleting existing indices');
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('returns error if profile is executed with no valid indices', async () => {
|
||||
const input = {
|
||||
query: {
|
||||
match_all: {},
|
||||
},
|
||||
};
|
||||
|
||||
await aceEditor.setValue(editorTestSubjectSelector, JSON.stringify(input));
|
||||
|
||||
await testSubjects.click('profileButton');
|
||||
|
||||
await retry.waitFor('notification renders', async () => {
|
||||
const notification = await testSubjects.find('noShardsNotification');
|
||||
const notificationText = await notification.getVisibleText();
|
||||
return notificationText.includes('Unable to profile');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -425,6 +425,14 @@ export default async function ({ readConfigFile }) {
|
|||
},
|
||||
|
||||
global_devtools_read: {
|
||||
elasticsearch: {
|
||||
indices: [
|
||||
{
|
||||
names: ['*'],
|
||||
privileges: ['read', 'all'],
|
||||
},
|
||||
],
|
||||
},
|
||||
kibana: [
|
||||
{
|
||||
feature: {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue