[8.x] [SLO/Test] add new slo definition api test (#216573) (#218160)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[SLO/Test] add new slo definition api test
(#216573)](https://github.com/elastic/kibana/pull/216573)

<!--- Backport version: 9.6.6 -->

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

<!--BACKPORT [{"author":{"name":"Bailey
Cash","email":"bailey.cash@elastic.co"},"sourceCommit":{"committedDate":"2025-04-01T22:12:04Z","message":"[SLO/Test]
add new slo definition api test (#216573)\n\nCloses #216236 \n\nadd
integration tests for the SLO Definition API, specifically to test\nthe
changes for the implementation of
this\n[issue](https://github.com/elastic/kibana/issues/214260)","sha":"0f402ca31c9fc49039e3ac7464e7d4c19d84d59f","branchLabelMapping":{"^v9.1.0$":"main","^v8.19.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","backport:skip","Team:SharedUX","Team:obs-ux-management","v9.1.0"],"title":"[SLO/Test]
add new slo definition api
test","number":216573,"url":"https://github.com/elastic/kibana/pull/216573","mergeCommit":{"message":"[SLO/Test]
add new slo definition api test (#216573)\n\nCloses #216236 \n\nadd
integration tests for the SLO Definition API, specifically to test\nthe
changes for the implementation of
this\n[issue](https://github.com/elastic/kibana/issues/214260)","sha":"0f402ca31c9fc49039e3ac7464e7d4c19d84d59f"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/216573","number":216573,"mergeCommit":{"message":"[SLO/Test]
add new slo definition api test (#216573)\n\nCloses #216236 \n\nadd
integration tests for the SLO Definition API, specifically to test\nthe
changes for the implementation of
this\n[issue](https://github.com/elastic/kibana/issues/214260)","sha":"0f402ca31c9fc49039e3ac7464e7d4c19d84d59f"}}]}]
BACKPORT-->

Co-authored-by: Shahzad <shahzad31comp@gmail.com>
This commit is contained in:
Bailey Cash 2025-04-15 11:04:31 -04:00 committed by GitHub
parent a6bd5642ba
commit 93b2fd62d9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 172 additions and 3 deletions

View file

@ -27,7 +27,7 @@ export default function ({ getService }: DeploymentAgnosticFtrProviderContext) {
let adminRoleAuthc: RoleCredentials;
let internalHeaders: InternalRequestHeader;
describe('Find SLOs', function () {
describe('Find SLOs using kql query', function () {
before(async () => {
adminRoleAuthc = await samlAuth.createM2mApiKeyWithRoleScope('admin');
internalHeaders = samlAuth.getInternalRequestHeader();
@ -51,7 +51,7 @@ export default function ({ getService }: DeploymentAgnosticFtrProviderContext) {
await samlAuth.invalidateM2mApiKeyWithRoleScope(adminRoleAuthc);
});
it('searches SLOs', async () => {
it('searches SLOs using kqlQuery', async () => {
const createResponse1 = await sloApi.create(DEFAULT_SLO, adminRoleAuthc);
const createResponse2 = await sloApi.create(
Object.assign({}, DEFAULT_SLO, { name: 'something irrelevant foo' }),

View file

@ -0,0 +1,123 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { cleanup, generate } from '@kbn/data-forge';
import expect from '@kbn/expect';
import { RoleCredentials } from '@kbn/ftr-common-functional-services';
import { DeploymentAgnosticFtrProviderContext } from '../../../ftr_provider_context';
import { DEFAULT_SLO } from './fixtures/slo';
import { DATA_FORGE_CONFIG } from './helpers/dataforge';
export default function ({ getService }: DeploymentAgnosticFtrProviderContext) {
const esClient = getService('es');
const sloApi = getService('sloApi');
const logger = getService('log');
const samlAuth = getService('samlAuth');
const dataViewApi = getService('dataViewApi');
const DATA_VIEW = 'kbn-data-forge-fake_hosts.fake_hosts-*';
const DATA_VIEW_ID = 'data-view-id';
let adminRoleAuthc: RoleCredentials;
describe('Find SLOs by outdated status and tags', function () {
before(async () => {
adminRoleAuthc = await samlAuth.createM2mApiKeyWithRoleScope('admin');
await generate({ client: esClient, config: DATA_FORGE_CONFIG, logger });
await dataViewApi.create({
roleAuthc: adminRoleAuthc,
name: DATA_VIEW,
id: DATA_VIEW_ID,
title: DATA_VIEW,
});
await sloApi.deleteAllSLOs(adminRoleAuthc);
});
after(async () => {
await dataViewApi.delete({ roleAuthc: adminRoleAuthc, id: DATA_VIEW_ID });
await cleanup({ client: esClient, config: DATA_FORGE_CONFIG, logger });
await sloApi.deleteAllSLOs(adminRoleAuthc);
await samlAuth.invalidateM2mApiKeyWithRoleScope(adminRoleAuthc);
});
it('finds SLOs by different tags', async () => {
const tags = ['test1', 'test2'];
const slo1 = {
...DEFAULT_SLO,
tags: [tags[0]],
name: 'Test SLO for api integration 1',
};
const slo2 = {
...DEFAULT_SLO,
tags: [tags[1]],
name: 'Test SLO for api integration 2',
};
await Promise.allSettled([
sloApi.create(slo1, adminRoleAuthc),
sloApi.create(slo2, adminRoleAuthc),
]);
const definitions = await sloApi.findDefinitions(adminRoleAuthc, {
tags: tags.join(','),
});
expect(definitions.total).eql(2);
const definitionsWithoutTag2 = await sloApi.findDefinitions(adminRoleAuthc, {
tags: tags[0],
});
expect(definitionsWithoutTag2.total).eql(1);
expect(definitionsWithoutTag2.results.find((def) => def.tags.includes('tag2'))).eql(
undefined
);
});
it('finds outdated SLOs', async () => {
const outdatedSLO = {
...DEFAULT_SLO,
name: 'outdated slo',
};
const recentSLO = {
...DEFAULT_SLO,
name: 'recent slo',
};
const outdatedResponse = await sloApi.create(outdatedSLO, adminRoleAuthc);
const recentResponse = await sloApi.create(recentSLO, adminRoleAuthc);
const { id: outdatedSloId } = outdatedResponse;
const SOResponse = await sloApi.getSavedObject(adminRoleAuthc, outdatedSloId);
const savedObject = SOResponse.saved_objects[0];
await sloApi.updateSavedObject(
adminRoleAuthc,
{ ...savedObject.attributes, version: 1 },
savedObject.id
);
const allDefinitions = await sloApi.findDefinitions(adminRoleAuthc, {
includeOutdatedOnly: 'false',
});
expect(allDefinitions.results.find((slo) => slo.id === recentResponse.id)?.id).to.be(
recentResponse.id
);
const definitions = await sloApi.findDefinitions(adminRoleAuthc, {
includeOutdatedOnly: 'true',
});
expect(definitions.results.find((slo) => slo.id === recentResponse.id)).to.be(undefined);
expect(definitions.results.find((slo) => slo.id === outdatedResponse.id)?.id).to.be(
outdatedSloId
);
});
});
}

View file

@ -13,6 +13,7 @@ export default function ({ loadTestFile }: DeploymentAgnosticFtrProviderContext)
loadTestFile(require.resolve('./delete_slo'));
loadTestFile(require.resolve('./get_slo'));
loadTestFile(require.resolve('./find_slo'));
loadTestFile(require.resolve('./find_slo_definition'));
loadTestFile(require.resolve('./reset_slo'));
loadTestFile(require.resolve('./update_slo'));
});

View file

@ -7,8 +7,23 @@
import { RoleCredentials } from '@kbn/ftr-common-functional-services';
import { CreateSLOInput, FindSLODefinitionsResponse, UpdateSLOInput } from '@kbn/slo-schema';
import { StoredSLODefinition } from '@kbn/slo-plugin/server/domain/models/slo';
import { DeploymentAgnosticFtrProviderContext } from '../ftr_provider_context';
interface SavedObject<Attributes extends Record<string, any>> {
attributes: Attributes;
id: string;
type: string;
updated_at?: string;
version?: string;
}
interface SavedObjectResponse {
page: number;
per_page: number;
total: number;
saved_objects: Array<SavedObject<StoredSLODefinition>>;
}
export function SloApiProvider({ getService }: DeploymentAgnosticFtrProviderContext) {
const supertestWithoutAuth = getService('supertestWithoutAuth');
const samlAuth = getService('samlAuth');
@ -69,9 +84,23 @@ export function SloApiProvider({ getService }: DeploymentAgnosticFtrProviderCont
return body;
},
async findDefinitions(roleAuthc: RoleCredentials): Promise<FindSLODefinitionsResponse> {
async findDefinitions(
roleAuthc: RoleCredentials,
params?: Record<string, string>
): Promise<FindSLODefinitionsResponse> {
const { body } = await supertestWithoutAuth
.get(`/api/observability/slos/_definitions`)
.query(params || {})
.set(roleAuthc.apiKeyHeader)
.set(samlAuth.getInternalRequestHeader())
.send();
return body;
},
async getSavedObject(roleAuthc: RoleCredentials, sloId: string): Promise<SavedObjectResponse> {
const { body } = await supertestWithoutAuth
.get(`/api/saved_objects/_find?type=slo&filter=slo.attributes.id:(${sloId})`)
.set(roleAuthc.apiKeyHeader)
.set(samlAuth.getInternalRequestHeader())
.send()
@ -80,6 +109,22 @@ export function SloApiProvider({ getService }: DeploymentAgnosticFtrProviderCont
return body;
},
async updateSavedObject(
roleAuthc: RoleCredentials,
slo: StoredSLODefinition,
id: string
): Promise<SavedObjectResponse> {
const { body } = await supertestWithoutAuth
.put(`/api/saved_objects/slo/${id}`)
.set(roleAuthc.apiKeyHeader)
.set(samlAuth.getInternalRequestHeader())
.send({
attributes: slo,
})
.expect(200);
return body;
},
async deleteAllSLOs(roleAuthc: RoleCredentials) {
const response = await supertestWithoutAuth
.get(`/api/observability/slos/_definitions`)