Skip to content

Commit

Permalink
[8.x] Observability AI Assistant Tests Deployment Agnostic (#205194) (#…
Browse files Browse the repository at this point in the history
…206516)

# Backport

This will backport the following commits from `main` to `8.x`:
- [Observability AI Assistant Tests Deployment Agnostic
(#205194)](#205194)

<!--- Backport version: 8.9.8 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Arturo
Lidueña","email":"[email protected]"},"sourceCommit":{"committedDate":"2025-01-13T15:03:51Z","message":"Observability
AI Assistant Tests Deployment Agnostic (#205194)\n\nCloses
#192718\r\n\r\n## Summary\r\n\r\nThis PR add a deployment-agnostic
testing environment for Observability\r\nAI Assistant tests by unifying
the duplicated tests for stateful and\r\nserverless environments. It
create the ObservabilityAIAssistantApiClient\r\nto work seamlessly in
both environments, enabling a single test to run\r\nacross stateful, CI,
and MKI.\r\n\r\nInitial efforts focus on deduplicating the
`conversations.spec.ts` and\r\n`connectors.spec.ts` files, as these
already run in all environments.\r\n\r\nMove / dedup the tests that
exist in stateful and serverless. They run\r\nin serverless CI but not
MKI and add the skipMki
tag.\r\n`chat.spec.ts`\r\n`complete.spec.ts`\r\n`elasticsearch.spec.ts`\r\n`public_complete.spec.ts`\r\n`alerts.spec.ts`\r\n`knowledge_base_setup.spec.ts`
\r\n`knowledge_base_status.spec.ts` \r\n`knowledge_base.spec.ts`
\r\n`summarize.ts`
\r\n`knowledge_base_user_instructions.spec.ts`","sha":"ee6c5bde34b984e14889eb136cfa1a9baa9991c0","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","Team:Obs
AI
Assistant","ci:project-deploy-observability","backport:version","v8.18.0"],"number":205194,"url":"https://github.com/elastic/kibana/pull/205194","mergeCommit":{"message":"Observability
AI Assistant Tests Deployment Agnostic (#205194)\n\nCloses
#192718\r\n\r\n## Summary\r\n\r\nThis PR add a deployment-agnostic
testing environment for Observability\r\nAI Assistant tests by unifying
the duplicated tests for stateful and\r\nserverless environments. It
create the ObservabilityAIAssistantApiClient\r\nto work seamlessly in
both environments, enabling a single test to run\r\nacross stateful, CI,
and MKI.\r\n\r\nInitial efforts focus on deduplicating the
`conversations.spec.ts` and\r\n`connectors.spec.ts` files, as these
already run in all environments.\r\n\r\nMove / dedup the tests that
exist in stateful and serverless. They run\r\nin serverless CI but not
MKI and add the skipMki
tag.\r\n`chat.spec.ts`\r\n`complete.spec.ts`\r\n`elasticsearch.spec.ts`\r\n`public_complete.spec.ts`\r\n`alerts.spec.ts`\r\n`knowledge_base_setup.spec.ts`
\r\n`knowledge_base_status.spec.ts` \r\n`knowledge_base.spec.ts`
\r\n`summarize.ts`
\r\n`knowledge_base_user_instructions.spec.ts`","sha":"ee6c5bde34b984e14889eb136cfa1a9baa9991c0"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","labelRegex":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/205194","number":205194,"mergeCommit":{"message":"Observability
AI Assistant Tests Deployment Agnostic (#205194)\n\nCloses
#192718\r\n\r\n## Summary\r\n\r\nThis PR add a deployment-agnostic
testing environment for Observability\r\nAI Assistant tests by unifying
the duplicated tests for stateful and\r\nserverless environments. It
create the ObservabilityAIAssistantApiClient\r\nto work seamlessly in
both environments, enabling a single test to run\r\nacross stateful, CI,
and MKI.\r\n\r\nInitial efforts focus on deduplicating the
`conversations.spec.ts` and\r\n`connectors.spec.ts` files, as these
already run in all environments.\r\n\r\nMove / dedup the tests that
exist in stateful and serverless. They run\r\nin serverless CI but not
MKI and add the skipMki
tag.\r\n`chat.spec.ts`\r\n`complete.spec.ts`\r\n`elasticsearch.spec.ts`\r\n`public_complete.spec.ts`\r\n`alerts.spec.ts`\r\n`knowledge_base_setup.spec.ts`
\r\n`knowledge_base_status.spec.ts` \r\n`knowledge_base.spec.ts`
\r\n`summarize.ts`
\r\n`knowledge_base_user_instructions.spec.ts`","sha":"ee6c5bde34b984e14889eb136cfa1a9baa9991c0"}},{"branch":"8.x","label":"v8.18.0","labelRegex":"^v8.18.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

---------

Co-authored-by: kibanamachine <[email protected]>
  • Loading branch information
arturoliduena and kibanamachine authored Jan 13, 2025
1 parent 41208f4 commit d7b26dc
Show file tree
Hide file tree
Showing 43 changed files with 1,190 additions and 4,140 deletions.
14 changes: 8 additions & 6 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -1164,13 +1164,15 @@ packages/kbn-monaco/src/esql @elastic/kibana-esql

### Observability Plugins


# Observability AI Assistant
x-pack/test/observability_ai_assistant_api_integration @elastic/obs-ai-assistant
x-pack/test/observability_ai_assistant_functional @elastic/obs-ai-assistant
x-pack/test_serverless/**/test_suites/observability/ai_assistant @elastic/obs-ai-assistant

# Infra Monitoring
/x-pack/test_serverless/api_integration/test_suites/common/data_usage @elastic/obs-ai-assistant @elastic/security-solution
/x-pack/test_serverless/functional/test_suites/common/data_usage @elastic/obs-ai-assistant @elastic/security-solution
/x-pack/test/observability_ai_assistant_api_integration @elastic/obs-ai-assistant
/x-pack/test/observability_ai_assistant_functional @elastic/obs-ai-assistant
/x-pack/test_serverless/**/test_suites/observability/ai_assistant @elastic/obs-ai-assistant
/x-pack/test/functional/es_archives/observability/ai_assistant @elastic/obs-ai-assistant
/x-pack/test/api_integration/deployment_agnostic/apis/observability/ai_assistant @elastic/obs-ai-assistant
# Infra Obs
## This plugin mostly contains the codebase for the infra services, but also includes some code for the Logs UI app.
## To keep @elastic/obs-ux-logs-team as codeowner of the plugin manifest without requiring a review for all the other code changes
## the priority on codeownership will be as follow:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,16 @@
import expect from '@kbn/expect';
import { MessageRole, type Message } from '@kbn/observability-ai-assistant-plugin/common';
import { PassThrough } from 'stream';
import { createLlmProxy, LlmProxy } from '../../common/create_llm_proxy';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import { createProxyActionConnector, deleteActionConnector } from '../../common/action_connectors';
import { ForbiddenApiError } from '../../common/config';

export default function ApiTest({ getService }: FtrProviderContext) {
const supertest = getService('supertest');
import {
LlmProxy,
createLlmProxy,
} from '../../../../../../observability_ai_assistant_api_integration/common/create_llm_proxy';
import { SupertestWithRoleScope } from '../../../../services/role_scoped_supertest';
import type { DeploymentAgnosticFtrProviderContext } from '../../../../ftr_provider_context';

export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderContext) {
const log = getService('log');
const observabilityAIAssistantAPIClient = getService('observabilityAIAssistantAPIClient');

const CHAT_API_URL = `/internal/observability_ai_assistant/chat`;
const observabilityAIAssistantAPIClient = getService('observabilityAIAssistantApi');

const messages: Message[] = [
{
Expand All @@ -37,37 +36,50 @@ export default function ApiTest({ getService }: FtrProviderContext) {
},
];

describe('/internal/observability_ai_assistant/chat', () => {
describe('/internal/observability_ai_assistant/chat', function () {
// Fails on MKI: https://github.com/elastic/kibana/issues/205581
this.tags(['failsOnMKI']);
let proxy: LlmProxy;

let connectorId: string;

before(async () => {
proxy = await createLlmProxy(log);
connectorId = await createProxyActionConnector({ supertest, log, port: proxy.getPort() });
connectorId = await observabilityAIAssistantAPIClient.createProxyActionConnector({
port: proxy.getPort(),
});
});

after(async () => {
proxy.close();
await deleteActionConnector({ supertest, connectorId, log });
await observabilityAIAssistantAPIClient.deleteActionConnector({
actionId: connectorId,
});
});

it("returns a 4xx if the connector doesn't exist", async () => {
await supertest
.post(CHAT_API_URL)
.set('kbn-xsrf', 'foo')
.send({
name: 'my_api_call',
messages,
connectorId: 'does not exist',
functions: [],
scopes: ['all'],
})
.expect(404);
const { status } = await observabilityAIAssistantAPIClient.editor({
endpoint: 'POST /internal/observability_ai_assistant/chat',
params: {
body: {
name: 'my_api_call',
messages,
connectorId: 'does not exist',
functions: [],
scopes: ['all'],
},
},
});
expect(status).to.be(404);
});

it('returns a streaming response from the server', async () => {
const NUM_RESPONSES = 5;
const roleScopedSupertest = getService('roleScopedSupertest');
const supertestEditorWithCookieCredentials: SupertestWithRoleScope =
await roleScopedSupertest.getSupertestWithRoleScope('editor', {
useCookieHeader: true,
withInternalHeaders: true,
});

await Promise.race([
new Promise((resolve, reject) => {
Expand All @@ -81,9 +93,8 @@ export default function ApiTest({ getService }: FtrProviderContext) {
const receivedChunks: Array<Record<string, any>> = [];

const passThrough = new PassThrough();
supertest
.post(CHAT_API_URL)
.set('kbn-xsrf', 'foo')
supertestEditorWithCookieCredentials
.post('/internal/observability_ai_assistant/chat')
.on('error', reject)
.send({
name: 'my_api_call',
Expand Down Expand Up @@ -136,26 +147,21 @@ export default function ApiTest({ getService }: FtrProviderContext) {
}),
]);
});

describe('security roles and access privileges', () => {
it('should deny access for users without the ai_assistant privilege', async () => {
try {
await observabilityAIAssistantAPIClient.unauthorizedUser({
endpoint: `POST ${CHAT_API_URL}`,
params: {
body: {
name: 'my_api_call',
messages,
connectorId,
functions: [],
scopes: ['all'],
},
const { status } = await observabilityAIAssistantAPIClient.viewer({
endpoint: 'POST /internal/observability_ai_assistant/chat',
params: {
body: {
name: 'my_api_call',
messages,
connectorId,
functions: [],
scopes: ['all'],
},
});
throw new ForbiddenApiError('Expected unauthorizedUser() to throw a 403 Forbidden error');
} catch (e) {
expect(e.status).to.be(403);
}
},
});
expect(status).to.be(403);
});
});
});
Expand Down
Loading

0 comments on commit d7b26dc

Please sign in to comment.