Skip to content

Commit e32ff8e

Browse files
authored
[Obs AI Assistant] Add knowledge base migration test to the serverless test suite (#205631)
Closes #205537 ## Summary The knowledge base migration test suite is missing in serverless. This PR adds it to the serverless test suite. - This has a dependancy to #205194 since we are removing all serverless tests and adding them to DA tests. - If the DA tests PR gets merged first, I'll refactor this PR to add it there. ### Checklist - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [x] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
1 parent 9f4e851 commit e32ff8e

File tree

1 file changed

+162
-0
lines changed

1 file changed

+162
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
import expect from '@kbn/expect';
9+
import {
10+
deleteInferenceEndpoint,
11+
createKnowledgeBaseModel,
12+
TINY_ELSER,
13+
deleteKnowledgeBaseModel,
14+
clearKnowledgeBase,
15+
} from '@kbn/test-suites-xpack/observability_ai_assistant_api_integration/tests/knowledge_base/helpers';
16+
import { AI_ASSISTANT_KB_INFERENCE_ID } from '@kbn/observability-ai-assistant-plugin/server/service/inference_endpoint';
17+
import { SearchResponse } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
18+
import { KnowledgeBaseEntry } from '@kbn/observability-ai-assistant-plugin/common';
19+
import { orderBy } from 'lodash';
20+
import { FtrProviderContext } from '../../common/ftr_provider_context';
21+
22+
export default function ApiTest({ getService }: FtrProviderContext) {
23+
const ml = getService('ml');
24+
const es = getService('es');
25+
const esArchiver = getService('esArchiver');
26+
const observabilityAIAssistantAPIClient = getService('observabilityAIAssistantAPIClient');
27+
28+
const archive =
29+
'x-pack/test/functional/es_archives/observability/ai_assistant/knowledge_base_8_15';
30+
31+
async function getKnowledgeBaseEntries() {
32+
const res = (await es.search({
33+
index: '.kibana-observability-ai-assistant-kb*',
34+
body: {
35+
query: {
36+
match_all: {},
37+
},
38+
},
39+
})) as SearchResponse<
40+
KnowledgeBaseEntry & {
41+
semantic_text: {
42+
text: string;
43+
inference: { inference_id: string; chunks: Array<{ text: string; embeddings: any }> };
44+
};
45+
}
46+
>;
47+
48+
return res.hits.hits;
49+
}
50+
51+
describe('When there are knowledge base entries (from 8.15 or earlier) that does not contain semantic_text embeddings', function () {
52+
this.tags(['skipMKI']);
53+
54+
before(async () => {
55+
await clearKnowledgeBase(es);
56+
await esArchiver.load(archive);
57+
await createKnowledgeBaseModel(ml);
58+
await observabilityAIAssistantAPIClient
59+
.slsAdmin({
60+
endpoint: 'POST /internal/observability_ai_assistant/kb/setup',
61+
params: {
62+
query: {
63+
model_id: TINY_ELSER.id,
64+
},
65+
},
66+
})
67+
.expect(200);
68+
});
69+
70+
after(async () => {
71+
await clearKnowledgeBase(es);
72+
await esArchiver.unload(archive);
73+
await deleteKnowledgeBaseModel(ml);
74+
await deleteInferenceEndpoint({ es });
75+
});
76+
77+
describe('before migrating', () => {
78+
it('the docs do not have semantic_text embeddings', async () => {
79+
const hits = await getKnowledgeBaseEntries();
80+
const hasSemanticTextEmbeddings = hits.some((hit) => hit._source?.semantic_text);
81+
expect(hasSemanticTextEmbeddings).to.be(false);
82+
});
83+
});
84+
85+
describe('after migrating', () => {
86+
before(async () => {
87+
await observabilityAIAssistantAPIClient
88+
.slsEditor({
89+
endpoint: 'POST /internal/observability_ai_assistant/kb/semantic_text_migration',
90+
})
91+
.expect(200);
92+
});
93+
94+
it('the docs have semantic_text embeddings', async () => {
95+
const hits = await getKnowledgeBaseEntries();
96+
const hasSemanticTextEmbeddings = hits.every((hit) => hit._source?.semantic_text);
97+
expect(hasSemanticTextEmbeddings).to.be(true);
98+
99+
expect(
100+
orderBy(hits, '_source.title').map(({ _source }) => {
101+
const { text, inference } = _source?.semantic_text!;
102+
103+
return {
104+
text,
105+
inferenceId: inference.inference_id,
106+
chunkCount: inference.chunks.length,
107+
};
108+
})
109+
).to.eql([
110+
{
111+
text: 'To infinity and beyond!',
112+
inferenceId: AI_ASSISTANT_KB_INFERENCE_ID,
113+
chunkCount: 1,
114+
},
115+
{
116+
text: "The user's favourite color is blue.",
117+
inferenceId: AI_ASSISTANT_KB_INFERENCE_ID,
118+
chunkCount: 1,
119+
},
120+
]);
121+
});
122+
123+
it('returns entries correctly via API', async () => {
124+
await observabilityAIAssistantAPIClient
125+
.slsEditor({
126+
endpoint: 'POST /internal/observability_ai_assistant/kb/semantic_text_migration',
127+
})
128+
.expect(200);
129+
130+
const res = await observabilityAIAssistantAPIClient
131+
.slsEditor({
132+
endpoint: 'GET /internal/observability_ai_assistant/kb/entries',
133+
params: {
134+
query: {
135+
query: '',
136+
sortBy: 'title',
137+
sortDirection: 'asc',
138+
},
139+
},
140+
})
141+
.expect(200);
142+
143+
expect(
144+
res.body.entries.map(({ title, text, role, type }) => ({ title, text, role, type }))
145+
).to.eql([
146+
{
147+
role: 'user_entry',
148+
title: 'Toy Story quote',
149+
type: 'contextual',
150+
text: 'To infinity and beyond!',
151+
},
152+
{
153+
role: 'assistant_summarization',
154+
title: "User's favourite color",
155+
type: 'contextual',
156+
text: "The user's favourite color is blue.",
157+
},
158+
]);
159+
});
160+
});
161+
});
162+
}

0 commit comments

Comments
 (0)