Skip to content

Commit

Permalink
[Security Solution] Unskip related integrations Cypress tests in ESS (#…
Browse files Browse the repository at this point in the history
…166659)

**Related to: #165359
**Resolves: #165504

## Summary

This PR unskips skipped rule integrations ESS tests.

## Details

Besides just unskipping ESS tests this PR simplifies the test by fetching alert data from the ES directly instead of using multiple steps in UI to validate an expected field has an expected value.

## Flaky test runner

ESS [related_integrations.cy.ts 100 runs](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/3199) 🟢
  • Loading branch information
maximpn committed Sep 22, 2023
1 parent 884bcb2 commit f52ca02
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@

import { omit } from 'lodash';
import { PerformRuleInstallationResponseBody } from '@kbn/security-solution-plugin/common/api/detection_engine';
import { filterBy, openTable } from '../../../../tasks/rule_details_flyout';
import { generateEvent } from '../../../../objects/event';
import { createDocument, deleteDataStream } from '../../../../tasks/api_calls/elasticsearch';
import { createRuleAssetSavedObject } from '../../../../helpers/rules';
import { FIELD } from '../../../../screens/alerts_details';
import { INTEGRATION_LINK, INTEGRATION_STATUS } from '../../../../screens/rule_details';
import {
INTEGRATIONS_POPOVER,
Expand All @@ -34,7 +32,6 @@ import {
visitSecurityDetectionRulesPage,
visitWithoutDateRange,
} from '../../../../tasks/login';
import { expandFirstAlert } from '../../../../tasks/alerts';
import { waitForAlertsToPopulate } from '../../../../tasks/create_new_rule';
import {
installIntegrations,
Expand All @@ -46,6 +43,7 @@ import {
} from '../../../../tasks/alerts_detection_rules';
import { ruleDetailsUrl } from '../../../../urls/navigation';
import { enablesRule, waitForPageToBeLoaded } from '../../../../tasks/rule_details';
import { fetchRuleAlerts } from '../../../../tasks/api_calls/alerts';

// TODO: https://github.com/elastic/kibana/issues/161540
describe('Related integrations', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => {
Expand Down Expand Up @@ -190,12 +188,10 @@ describe('Related integrations', { tags: ['@ess', '@serverless', '@brokenInServe
});
});

// TODO: https://github.com/elastic/kibana/issues/161540
// Flaky in serverless tests
// @brokenInServerless tag is not working so a skip was needed
describe.skip('rule details', { tags: ['@brokenInServerless'] }, () => {
describe('rule details', () => {
beforeEach(() => {
visitFirstInstalledPrebuiltRuleDetailsPage();
waitForPageToBeLoaded(PREBUILT_RULE_NAME);
});

it('should display the integrations in the definition section', () => {
Expand All @@ -212,42 +208,26 @@ describe('Related integrations', { tags: ['@ess', '@serverless', '@brokenInServe
});
});

it('the alerts generated should have a "kibana.alert.rule.parameters.related_integrations" field containing the integrations', () => {
const RELATED_INTEGRATION_FIELD = 'kibana.alert.rule.parameters.related_integrations';
const RELATED_INTEGRATION_FIELD = 'kibana.alert.rule.parameters.related_integrations';

it(`the alerts generated should have a "${RELATED_INTEGRATION_FIELD}" field containing the integrations`, () => {
deleteDataStream(DATA_STREAM_NAME);
createDocument(DATA_STREAM_NAME, generateEvent());

waitForPageToBeLoaded(PREBUILT_RULE_NAME);
enablesRule();
waitForAlertsToPopulate();
expandFirstAlert();
openTable();
filterBy(RELATED_INTEGRATION_FIELD);

cy.get(FIELD(RELATED_INTEGRATION_FIELD))
.invoke('text')
.then((stringValue) => {
// Integrations are displayed in the flyout as a string with a format like so:
// '{"package":"aws","version":"1.17.0","integration":"unknown"}{"package":"mock","version":"1.1.0"}{"package":"system","version":"1.17.0"}'
// We need to parse it to an array of valid objects before we can compare it to the expected value
// Otherwise, the test might fail because of the order of the properties in the objects in the string
const jsonStringArray = stringValue.split('}{');

const validJsonStringArray = createValidJsonStringArray(jsonStringArray);

const parsedIntegrations = validJsonStringArray.map((jsonString) =>
JSON.parse(jsonString)
);

RULE_RELATED_INTEGRATIONS.forEach((integration) => {
expect(parsedIntegrations).to.deep.include({
package: integration.package,
version: integration.version,
...(integration.integration ? { integration: integration.integration } : {}),
});
});

fetchRuleAlerts({
ruleId: 'rule_1',
fields: [RELATED_INTEGRATION_FIELD],
size: 1,
}).then((alertsResponse) => {
expect(alertsResponse.body.hits.hits[0].fields).to.deep.equal({
[RELATED_INTEGRATION_FIELD]: RULE_RELATED_INTEGRATIONS.map((x) =>
omit(x, ['installed', 'enabled'])
),
});
});
});
});
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* 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 {
RuleObjectId,
RuleSignatureId,
} from '@kbn/security-solution-plugin/common/api/detection_engine';
import { rootRequest } from '../common';

export const DEFAULT_ALERTS_INDEX_PATTERN = '.alerts-security.alerts-*';

interface FetchRuleAlertsParams {
ruleId: RuleObjectId | RuleSignatureId;
fields: string[];
size?: number;
}

interface AlertFields {
fields: Record<string, unknown>;
}

interface AlertsResponse {
hits: {
total: {
value: number;
};
hits: AlertFields[];
};
}

/**
* Returns rule's generated alerts
*
* @param ruleId a rule id representing either RuleObjectId (Saved Object id) or RuleSignatureId (rule_id)
* @param fields fields to fetch (fetch only fields you need to do assertions on)
* @param size a number of alerts to fetch
*
* @returns rule's generated alerts
*/
export function fetchRuleAlerts({
ruleId,
fields,
size,
}: FetchRuleAlertsParams): Cypress.Chainable<Cypress.Response<AlertsResponse>> {
return rootRequest<AlertsResponse>({
method: 'GET',
url: `${Cypress.env('ELASTICSEARCH_URL')}/${DEFAULT_ALERTS_INDEX_PATTERN}/_search`,
body: {
query: {
bool: {
should: [
{
term: {
'kibana.alert.rule.rule_id': ruleId,
},
},
{
term: {
'kibana.alert.rule.uuid': ruleId,
},
},
],
},
},
fields,
sort: {
'@timestamp': 'desc',
},
size,
_source: false,
},
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common';
import { KIBANA_LOADING_ICON } from '../screens/security_header';
import { EUI_BASIC_TABLE_LOADING } from '../screens/common/controls';
import { deleteAllDocuments } from './api_calls/elasticsearch';
import { DEFAULT_ALERTS_INDEX_PATTERN } from './api_calls/alerts';

const primaryButton = 0;

Expand Down Expand Up @@ -135,7 +136,7 @@ export const deleteAlertsAndRules = () => {
},
});

deleteAllDocuments('.lists-*,.items-*,.alerts-security.alerts-*');
deleteAllDocuments(`.lists-*,.items-*,${DEFAULT_ALERTS_INDEX_PATTERN}`);
};

export const deleteTimelines = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,23 @@ export function installIntegrations({
packages,
force: true,
},
headers: { 'kbn-xsrf': 'cypress-creds', 'x-elastic-internal-origin': 'security-solution' },
headers: {
'kbn-xsrf': 'cypress-creds',
'x-elastic-internal-origin': 'security-solution',
'elastic-api-version': '2023-10-31',
},
});

// Install agent and package policies
rootRequest<CreateAgentPolicyResponse>({
method: 'POST',
url: `${AGENT_POLICY_API_ROUTES.CREATE_PATTERN}?sys_monitoring=true`,
body: agentPolicy,
headers: { 'kbn-xsrf': 'cypress-creds', 'x-elastic-internal-origin': 'security-solution' },
headers: {
'kbn-xsrf': 'cypress-creds',
'x-elastic-internal-origin': 'security-solution',
'elastic-api-version': '2023-10-31',
},
}).then((response) => {
const packagePolicyWithAgentPolicyId: PackagePolicy = {
...packagePolicy,
Expand All @@ -75,7 +83,11 @@ export function installIntegrations({
method: 'POST',
url: PACKAGE_POLICY_API_ROUTES.CREATE_PATTERN,
body: packagePolicyWithAgentPolicyId,
headers: { 'kbn-xsrf': 'cypress-creds', 'x-elastic-internal-origin': 'security-solution' },
headers: {
'kbn-xsrf': 'cypress-creds',
'x-elastic-internal-origin': 'security-solution',
'elastic-api-version': '2023-10-31',
},
});
});
}

0 comments on commit f52ca02

Please sign in to comment.