Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport 2.10] Fixed bucket monitor groupBy/aggregation display bug. #833

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 16 additions & 7 deletions cypress/integration/alerts_dashboard_flyout_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import { INDEX, PLUGIN_NAME } from '../support/constants';
import sampleAlertsFlyoutBucketMonitor from '../fixtures/sample_alerts_flyout_bucket_level_monitor.json';
import sampleAlertsFlyoutQueryMonitor from '../fixtures/sample_alerts_flyout_query_level_monitor.json';
Expand All @@ -23,12 +22,19 @@ describe('Alerts by trigger flyout', () => {
// Load sample data
cy.loadSampleEcommerceData();

// Ensure monitors have been deleted
cy.visit(`${Cypress.env('opensearch_dashboards')}/app/${PLUGIN_NAME}#/monitors`);
cy.contains('There are no existing monitors. Create a monitor to add triggers and actions.', {
timeout: TWENTY_SECONDS,
});

// Create the test monitors
cy.createMonitor(sampleAlertsFlyoutBucketMonitor);
cy.createMonitor(sampleAlertsFlyoutQueryMonitor);

// Visit Alerting OpenSearch Dashboards
cy.visit(`${Cypress.env('opensearch_dashboards')}/app/${PLUGIN_NAME}#/monitors`);
cy.reload();

// Confirm test monitors were created successfully
cy.contains(BUCKET_MONITOR, { timeout: TWENTY_SECONDS });
Expand All @@ -41,6 +47,7 @@ describe('Alerts by trigger flyout', () => {
beforeEach(() => {
// Reloading the page to close any flyouts that were not closed by other tests that had failures.
cy.visit(`${Cypress.env('opensearch_dashboards')}/app/${PLUGIN_NAME}#/dashboard`);
cy.contains('Alerts by triggers', { timeout: TWENTY_SECONDS });

// Waiting 5 seconds for alerts to finish loading.
// This short wait period alleviates flakiness observed during these tests.
Expand All @@ -60,9 +67,10 @@ describe('Alerts by trigger flyout', () => {
timeout: TWENTY_SECONDS,
}).within(() => {
// Confirm flyout header contains expected text.
cy.get(
`[data-test-subj="alertsDashboardFlyout_header_${BUCKET_TRIGGER}"]`
).contains(`Alerts by ${BUCKET_TRIGGER}`, { timeout: TWENTY_SECONDS });
cy.get(`[data-test-subj="alertsDashboardFlyout_header_${BUCKET_TRIGGER}"]`).contains(
`Alerts by ${BUCKET_TRIGGER}`,
{ timeout: TWENTY_SECONDS }
);

// Confirm 'Trigger name' sections renders as expected.
cy.get(`[data-test-subj="alertsDashboardFlyout_triggerName_${BUCKET_TRIGGER}"]`).as(
Expand Down Expand Up @@ -154,9 +162,10 @@ describe('Alerts by trigger flyout', () => {
timeout: TWENTY_SECONDS,
}).within(() => {
// Confirm flyout header contains expected text.
cy.get(
`[data-test-subj="alertsDashboardFlyout_header_${QUERY_TRIGGER}"]`
).contains(`Alerts by ${QUERY_TRIGGER}`, { timeout: TWENTY_SECONDS });
cy.get(`[data-test-subj="alertsDashboardFlyout_header_${QUERY_TRIGGER}"]`).contains(
`Alerts by ${QUERY_TRIGGER}`,
{ timeout: TWENTY_SECONDS }
);

// Confirm 'Trigger name' sections renders as expected.
cy.get(`[data-test-subj="alertsDashboardFlyout_triggerName_${QUERY_TRIGGER}"]`).as(
Expand Down
17 changes: 11 additions & 6 deletions cypress/integration/bucket_level_monitor_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,23 +225,28 @@ describe('Bucket-Level Monitors', () => {
cy.get('[data-test-subj="addMetricButton"]').click({ force: true });

cy.get('[data-test-subj="metrics.0.aggregationTypeSelect"]').select('count', { force: true });
cy.wait(1000);

cy.get('[data-test-subj="metrics.0.ofFieldComboBox"]').type(
`${COUNT_METRIC_FIELD}{downArrow}{enter}`
);
cy.get('[data-test-subj="metrics.0.ofFieldComboBox"] input')
.focus()
.type(`${COUNT_METRIC_FIELD}{downArrow}{enter}`);

cy.get('button').contains('Save').click({ force: true });
cy.wait(1000);

// Add a second metric for the query
cy.get('[data-test-subj="addMetricButton"]').click({ force: true });

cy.get('[data-test-subj="metrics.1.aggregationTypeSelect"]').select('avg', { force: true });
cy.wait(1000);

cy.get('[data-test-subj="metrics.1.ofFieldComboBox"]').type(
`${AVERAGE_METRIC_FIELD}{downArrow}{enter}`
);
cy.get('[data-test-subj="metrics.1.ofFieldComboBox"] input')
.focus()
.type(`${AVERAGE_METRIC_FIELD}{downArrow}{enter}`);
cy.wait(1000);

cy.get('button').contains('Save').click({ force: true });
cy.wait(1000);

// Add data filters for the query
const filters = [
Expand Down
7 changes: 6 additions & 1 deletion cypress/integration/monitors_dashboard_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const clusterHealthMonitor = {
severity: '1',
condition: {
script: {
source: 'ctx.results[0].status != "green"',
source: 'ctx.results[0].status != "blue"',
lang: 'painless',
},
},
Expand Down Expand Up @@ -101,6 +101,11 @@ describe('Monitors dashboard page', () => {
});

it('Displays expected number of alerts', () => {
// Wait for table to finish loading
cy.get('tbody > tr', { timeout: 20000 }).should(($tr) =>
expect($tr).to.have.length.greaterThan(1)
);

// Ensure the 'Monitor name' column is sorted in ascending order by sorting another column first
cy.contains('Last updated by').click({ force: true });
cy.contains('Monitor name').click({ force: true });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,8 @@ Object {
"aggregations": Array [],
"bucketUnitOfTime": "h",
"bucketValue": 1,
"cleanedGroupBy": Array [],
"filters": Array [],
"groupBy": Array [],
"searchType": "graph",
"timeField": "",
},
Expand Down Expand Up @@ -322,8 +322,8 @@ Object {
"aggregations": Array [],
"bucketUnitOfTime": "h",
"bucketValue": 1,
"cleanedGroupBy": Array [],
"filters": Array [],
"groupBy": Array [],
"searchType": "graph",
"timeField": "@timestamp",
}
Expand All @@ -334,8 +334,8 @@ Object {
"aggregations": Array [],
"bucketUnitOfTime": "h",
"bucketValue": 1,
"cleanedGroupBy": Array [],
"filters": Array [],
"groupBy": Array [],
"searchType": "graph",
"timeField": "@timestamp",
}
Expand All @@ -346,8 +346,8 @@ Object {
"aggregations": Array [],
"bucketUnitOfTime": "h",
"bucketValue": 1,
"cleanedGroupBy": Array [],
"filters": Array [],
"groupBy": Array [],
"searchType": "graph",
"timeField": "@timestamp",
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ export function formikToUiSearch(values) {
searchType,
timeField,
aggregations,
cleanedGroupBy,
groupBy: cleanedGroupBy,
bucketValue,
bucketUnitOfTime,
filters,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import React from 'react';
import _ from 'lodash';
import { EuiPanel, EuiText, EuiSpacer, EuiLoadingSpinner } from '@elastic/eui';
import { EuiPanel, EuiText, EuiSpacer } from '@elastic/eui';
import Action from '../../components/Action';
import ActionEmptyPrompt from '../../components/ActionEmptyPrompt';
import AddActionButton from '../../components/AddActionButton';
Expand All @@ -27,12 +27,27 @@ import { formikToTrigger } from '../CreateTrigger/utils/formikToTrigger';
import { getChannelOptions, toChannelType } from '../../utils/helper';
import { getInitialActionValues } from '../../components/AddActionButton/utils';

const createActionContext = (context, action) => ({
ctx: {
...context,
action,
},
});
const createActionContext = (context, action) => {
let trigger = context.trigger;
const triggerType = Object.keys(trigger)[0];
if (
Object.keys(trigger).length === 1 &&
!_.isEmpty(triggerType) &&
Object.values(TRIGGER_TYPE).includes(triggerType)
) {
// If the trigger values is wrapped in the trigger type, unwrap it
trigger = trigger[triggerType];
} else {
console.warn(`Unknown trigger type "${triggerType}".`, context);
}
return {
ctx: {
...context,
trigger: { ...trigger },
action,
},
};
};

export const checkForError = (response, error) => {
for (const trigger_name in response.resp.trigger_results) {
Expand Down
4 changes: 2 additions & 2 deletions public/pages/Dashboard/utils/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ export const renderEmptyValue = (value) => {
export function insertGroupByColumn(groupBy = []) {
let result = _.cloneDeep(bucketColumns);
groupBy.map((fieldName) =>
result.splice(0, 0, {
result.push({
field: `agg_alert_content.bucket.key.${fieldName}`,
name: fieldName,
name: _.capitalize(fieldName),
render: renderEmptyValue,
sortable: false,
truncateText: false,
Expand Down
12 changes: 6 additions & 6 deletions public/pages/Dashboard/utils/helpers.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -575,24 +575,24 @@ describe('Dashboard/utils/helpers', () => {
test('with valid groupBy list', () => {
const groupBy = ['keyword1', 'keyword2', 'keyword3'];
const expectedOutput = _.cloneDeep(bucketColumns);
expectedOutput.unshift(
expectedOutput.push(
{
field: 'agg_alert_content.bucket.key.keyword3',
name: 'keyword3',
field: 'agg_alert_content.bucket.key.keyword1',
name: 'Keyword1',
render: renderEmptyValue,
sortable: false,
truncateText: false,
},
{
field: 'agg_alert_content.bucket.key.keyword2',
name: 'keyword2',
name: 'Keyword2',
render: renderEmptyValue,
sortable: false,
truncateText: false,
},
{
field: 'agg_alert_content.bucket.key.keyword1',
name: 'keyword1',
field: 'agg_alert_content.bucket.key.keyword3',
name: 'Keyword3',
render: renderEmptyValue,
sortable: false,
truncateText: false,
Expand Down
Loading