From f51f8cae82631ca914b36ab6cf03161c40ff8390 Mon Sep 17 00:00:00 2001 From: arbulu89 Date: Wed, 28 Feb 2024 14:17:01 +0100 Subject: [PATCH 1/4] Update the used new api versions for checks endpoint --- assets/js/lib/api/checks.js | 6 +++--- assets/js/state/sagas/catalog.test.js | 2 +- assets/js/state/sagas/lastExecutions.test.js | 2 +- test/e2e/cypress/e2e/checks_catalog.cy.js | 2 +- test/e2e/cypress/e2e/hana_cluster_details.cy.js | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/js/lib/api/checks.js b/assets/js/lib/api/checks.js index c3b89afd8a..d7de0281f7 100644 --- a/assets/js/lib/api/checks.js +++ b/assets/js/lib/api/checks.js @@ -6,16 +6,16 @@ const baseURL = config.checksServiceBaseUrl; const defaultConfig = { baseURL }; export const getExecutionResult = (executionID) => - networkClient.get(`/api/v1/checks/executions/${executionID}`, defaultConfig); + networkClient.get(`/api/v2/checks/executions/${executionID}`, defaultConfig); export const getLastExecutionByGroupID = (groupID) => networkClient.get( - `/api/v1/checks/groups/${groupID}/executions/last`, + `/api/v2/checks/groups/${groupID}/executions/last`, defaultConfig ); export const getCatalog = (env) => - networkClient.get(`/api/v2/checks/catalog`, { + networkClient.get(`/api/v3/checks/catalog`, { ...defaultConfig, params: env, }); diff --git a/assets/js/state/sagas/catalog.test.js b/assets/js/state/sagas/catalog.test.js index 8f2b3063f7..add07619d4 100644 --- a/assets/js/state/sagas/catalog.test.js +++ b/assets/js/state/sagas/catalog.test.js @@ -7,7 +7,7 @@ import { updateCatalog } from './catalog'; import { setCatalogLoading, setCatalogData, setCatalogError } from '../catalog'; -const getCatalogUrl = '/api/v2/checks/catalog'; +const getCatalogUrl = '/api/v3/checks/catalog'; const axiosMock = new MockAdapter(networkClient); describe('Catalog saga', () => { diff --git a/assets/js/state/sagas/lastExecutions.test.js b/assets/js/state/sagas/lastExecutions.test.js index 6a14c4fd56..7dfa99a1e2 100644 --- a/assets/js/state/sagas/lastExecutions.test.js +++ b/assets/js/state/sagas/lastExecutions.test.js @@ -23,7 +23,7 @@ import { const axiosMock = new MockAdapter(networkClient); const lastExecutionURL = (groupID) => - `/api/v1/checks/groups/${groupID}/executions/last`; + `/api/v2/checks/groups/${groupID}/executions/last`; const triggerClusterChecksExecutionURL = (clusterId) => `/clusters/${clusterId}/checks/request_execution`; diff --git a/test/e2e/cypress/e2e/checks_catalog.cy.js b/test/e2e/cypress/e2e/checks_catalog.cy.js index 78e192a15e..4f22a75e95 100644 --- a/test/e2e/cypress/e2e/checks_catalog.cy.js +++ b/test/e2e/cypress/e2e/checks_catalog.cy.js @@ -2,7 +2,7 @@ import { catalogCheckFactory } from '@lib/test-utils/factories'; import { groupBy } from 'lodash'; context('Checks catalog', () => { - const checksCatalogURL = `**/api/v2/checks/catalog`; + const checksCatalogURL = `**/api/v3/checks/catalog`; const clusterChecksGroup = 'Group 1'; const group1Checks = 2; diff --git a/test/e2e/cypress/e2e/hana_cluster_details.cy.js b/test/e2e/cypress/e2e/hana_cluster_details.cy.js index 4f6f8c0b21..c31ad01db1 100644 --- a/test/e2e/cypress/e2e/hana_cluster_details.cy.js +++ b/test/e2e/cypress/e2e/hana_cluster_details.cy.js @@ -6,14 +6,14 @@ import { capitalize } from 'lodash'; import { availableHanaCluster } from '../fixtures/hana-cluster-details/available_hana_cluster'; context('HANA cluster details', () => { - const lastExecutionURL = `**/api/v1/checks/groups/**/executions/last`; + const lastExecutionURL = `**/api/v2/checks/groups/**/executions/last`; const lastExecution = checksExecutionCompletedFactory.build({ group_id: availableHanaCluster.id, passing_count: 5, warning_count: 3, critical_count: 1, }); - const catalogURL = `**/api/v2/checks/catalog*`; + const catalogURL = `**/api/v3/checks/catalog*`; const catalog = catalogFactory.build(); before(() => { From cdf94b47159868c7907efc127f04d241846315ab Mon Sep 17 00:00:00 2001 From: arbulu89 Date: Wed, 28 Feb 2024 14:59:06 +0100 Subject: [PATCH 2/4] Update check utils function to use expect_enum --- assets/js/lib/model/index.js | 8 ++ assets/js/lib/test-utils/factories/index.js | 14 ++- .../js/pages/ExecutionResults/checksUtils.js | 34 ++++-- .../ExecutionResults/checksUtils.test.js | 108 +++++++++++++----- 4 files changed, 126 insertions(+), 38 deletions(-) diff --git a/assets/js/lib/model/index.js b/assets/js/lib/model/index.js index d2b9a68856..c252ecd2c8 100644 --- a/assets/js/lib/model/index.js +++ b/assets/js/lib/model/index.js @@ -1,6 +1,10 @@ export const EXPECT = 'expect'; +export const EXPECT_ENUM = 'expect_enum'; export const EXPECT_SAME = 'expect_same'; +const hostExepectations = [EXPECT, EXPECT_ENUM]; +export const isHostExpectation = ({ type }) => hostExepectations.includes(type); + export const TARGET_HOST = 'host'; export const TARGET_CLUSTER = 'cluster'; @@ -8,6 +12,10 @@ export const targetTypes = [TARGET_HOST, TARGET_CLUSTER]; export const isValidTargetType = (targetType) => targetTypes.includes(targetType); +export const PASSING = 'passing'; +export const WARNING = 'warning'; +export const CRITICAL = 'critical'; + export const AWS_PROVIDER = 'aws'; export const AZURE_PROVIDER = 'azure'; export const GCP_PROVIDER = 'gcp'; diff --git a/assets/js/lib/test-utils/factories/index.js b/assets/js/lib/test-utils/factories/index.js index 56b759504f..645a126acc 100644 --- a/assets/js/lib/test-utils/factories/index.js +++ b/assets/js/lib/test-utils/factories/index.js @@ -2,6 +2,8 @@ import { faker } from '@faker-js/faker'; import { Factory } from 'fishery'; +import { EXPECT, EXPECT_ENUM, EXPECT_SAME } from '@lib/model'; + export * from './executions'; export * from './hosts'; export * from './sapSystems'; @@ -67,7 +69,7 @@ export const healthSummaryFactory = Factory.define(() => ({ export const catalogExpectExpectationFactory = Factory.define( ({ sequence }) => ({ name: `${faker.lorem.word()}_${sequence}`, - type: 'expect', + type: EXPECT, expression: faker.lorem.sentence(), }) ); @@ -75,7 +77,15 @@ export const catalogExpectExpectationFactory = Factory.define( export const catalogExpectSameExpectationFactory = Factory.define( ({ sequence }) => ({ name: `${faker.lorem.word()}_${sequence}`, - type: 'expect_same', + type: EXPECT_SAME, + expression: faker.lorem.sentence(), + }) +); + +export const catalogExpectEnumExpectationFactory = Factory.define( + ({ sequence }) => ({ + name: `${faker.lorem.word()}_${sequence}`, + type: EXPECT_ENUM, expression: faker.lorem.sentence(), }) ); diff --git a/assets/js/pages/ExecutionResults/checksUtils.js b/assets/js/pages/ExecutionResults/checksUtils.js index cdb1aee8ae..0e99e87bbb 100644 --- a/assets/js/pages/ExecutionResults/checksUtils.js +++ b/assets/js/pages/ExecutionResults/checksUtils.js @@ -1,9 +1,14 @@ -import { EXPECT, EXPECT_SAME, TARGET_CLUSTER, TARGET_HOST } from '@lib/model'; +import { + EXPECT_SAME, + TARGET_CLUSTER, + TARGET_HOST, + PASSING, + isHostExpectation, +} from '@lib/model'; export const isTargetHost = (targetType) => targetType === TARGET_HOST; export const isTargetCluster = (targetType) => targetType === TARGET_CLUSTER; -export const isExpect = ({ type }) => type === EXPECT; export const isExpectSame = ({ type }) => type === EXPECT_SAME; export const isAgentCheckError = ({ type }) => !!type; @@ -84,8 +89,8 @@ export const getCheckExpectations = (catalog, checkID) => { return []; }; -export const getExpectStatements = (expectationList) => - expectationList.filter(isExpect); +export const getHostExpectationStatements = (expectationList) => + expectationList.filter(isHostExpectation); export const getExpectSameStatements = (expectationList) => expectationList.filter(isExpectSame); @@ -95,11 +100,11 @@ const expectationByName = ({ name }) => name === expectationName; -export const getExpectStatementsResults = ( +export const getHostExpectationStatementsResults = ( expectations, expectationEvaluations ) => - getExpectStatements(expectations).map( + getHostExpectationStatements(expectations).map( ({ name }) => expectationEvaluations.find(expectationByName(name)) || {} ); @@ -148,9 +153,9 @@ export const getAgentCheckResultByAgentID = ( ); }; -export const getExpectStatementsMet = (expectationEvaluations) => - getExpectStatements(expectationEvaluations).filter( - ({ return_value }) => return_value +export const getHostExpectationStatementsMet = (expectationEvaluations) => + getHostExpectationStatements(expectationEvaluations).filter( + ({ return_value }) => return_value === true || return_value === PASSING ).length; export const getExpectSameFacts = (expectations, agentsCheckResults) => @@ -180,3 +185,14 @@ export const getTargetName = (target, targetType) => { return null; } }; + +export const normalizeExpectationResult = (result, severity) => { + switch (result) { + case true: + return PASSING; + case false: + return severity; + default: + return result; + } +}; diff --git a/assets/js/pages/ExecutionResults/checksUtils.test.js b/assets/js/pages/ExecutionResults/checksUtils.test.js index 4c97dd2826..cec777a60b 100644 --- a/assets/js/pages/ExecutionResults/checksUtils.test.js +++ b/assets/js/pages/ExecutionResults/checksUtils.test.js @@ -5,6 +5,7 @@ import { catalogCheckFactory, catalogExpectExpectationFactory, catalogExpectSameExpectationFactory, + catalogExpectEnumExpectationFactory, checksExecutionCompletedFactory, checksExecutionRunningFactory, executionExpectationEvaluationFactory, @@ -15,7 +16,15 @@ import { executionExpectationEvaluationErrorFactory, failingExpectEvaluationFactory, } from '@lib/test-utils/factories'; -import { EXPECT, EXPECT_SAME } from '@lib/model'; + +import { + EXPECT, + EXPECT_ENUM, + EXPECT_SAME, + PASSING, + WARNING, + CRITICAL, +} from '@lib/model'; import { getCatalogCategoryList, @@ -25,17 +34,18 @@ import { getCheckResults, getCheckExpectations, isAgentCheckError, - getExpectStatements, + getHostExpectationStatements, + getHostExpectationStatementsResults, + getHostExpectationStatementsMet, getExpectSameStatements, getExpectSameStatementResult, getAgentCheckResultByAgentID, - getExpectStatementsMet, isPremium, getClusterCheckResults, getExpectSameStatementsResults, getExpectSameFacts, - getExpectStatementsResults, getTargetName, + normalizeExpectationResult, } from './checksUtils'; describe('checksUtils', () => { @@ -129,41 +139,50 @@ describe('checksUtils', () => { }); it('should get expectation statements from a list', () => { - const evaluationList = [ - ...executionExpectationEvaluationFactory.buildList(3, { + const evaluationList = [].concat( + executionExpectationEvaluationFactory.buildList(3, { type: EXPECT, }), - ...executionExpectationEvaluationFactory.buildList(4, { + executionExpectationEvaluationFactory.buildList(4, { type: EXPECT_SAME, }), - ]; - const resultList = [ - ...expectationResultFactory.buildList(2, { + executionExpectationEvaluationFactory.buildList(2, { + type: EXPECT_ENUM, + }) + ); + + const resultList = [].concat( + expectationResultFactory.buildList(2, { type: EXPECT, }), - expectationResultFactory.build({ + expectationResultFactory.buildList(1, { type: EXPECT_SAME, }), - ]; + expectationResultFactory.buildList(3, { + type: EXPECT_ENUM, + }) + ); - expect(getExpectStatements(evaluationList)).toHaveLength(3); + expect(getHostExpectationStatements(evaluationList)).toHaveLength(5); expect(getExpectSameStatements(evaluationList)).toHaveLength(4); - expect(getExpectStatements(resultList)).toHaveLength(2); + expect(getHostExpectationStatements(resultList)).toHaveLength(5); expect(getExpectSameStatements(resultList)).toHaveLength(1); }); - it('should get expect statements results', () => { - const expectations = [ - ...catalogExpectExpectationFactory.buildList(3), - catalogExpectSameExpectationFactory.build(), - ]; + it('should get host expectation statements results', () => { + const expectations = [].concat( + catalogExpectExpectationFactory.buildList(3), + catalogExpectSameExpectationFactory.buildList(1), + catalogExpectEnumExpectationFactory.buildList(1) + ); const [ { name: expectation1 }, { name: expectation2 }, { name: expectation3 }, { name: expectation4 }, + { name: expectation5 }, ] = expectations; const evaluationsList = [ @@ -181,15 +200,23 @@ describe('checksUtils', () => { name: expectation4, type: EXPECT_SAME, }), + executionExpectationEvaluationFactory.build({ + name: expectation5, + type: EXPECT_ENUM, + }), ]; const [ { return_value: returnValue1 }, { message, type }, { failure_message, return_value: returnValue3 }, + _, + { return_value: returnValue5 }, ] = evaluationsList; - expect(getExpectStatementsResults(expectations, evaluationsList)).toEqual([ + expect( + getHostExpectationStatementsResults(expectations, evaluationsList) + ).toEqual([ { name: expectation1, return_value: returnValue1, @@ -206,6 +233,11 @@ describe('checksUtils', () => { failure_message, return_value: returnValue3, }, + { + name: expectation5, + type: 'expect_enum', + return_value: returnValue5, + }, ]); }); @@ -475,22 +507,30 @@ describe('checksUtils', () => { ).toEqual({}); }); - it('should count the expect statements met', () => { - const expectationEvaluations = [ - executionExpectationEvaluationFactory.build({ + it('should count the host expectations statements met', () => { + const expectationEvaluations = [].concat( + executionExpectationEvaluationFactory.buildList(1, { type: EXPECT_SAME, }), - ...executionExpectationEvaluationFactory.buildList(2, { + executionExpectationEvaluationFactory.buildList(2, { return_value: false, type: EXPECT, }), - ...executionExpectationEvaluationFactory.buildList(3, { + executionExpectationEvaluationFactory.buildList(3, { return_value: true, type: EXPECT, }), - ]; + executionExpectationEvaluationFactory.buildList(1, { + return_value: PASSING, + type: EXPECT_ENUM, + }), + executionExpectationEvaluationFactory.buildList(1, { + return_value: CRITICAL, + type: EXPECT_ENUM, + }) + ); - expect(getExpectStatementsMet(expectationEvaluations)).toBe(3); + expect(getHostExpectationStatementsMet(expectationEvaluations)).toBe(4); }); it('should return true or false if a check is premium or not', () => { @@ -512,6 +552,20 @@ describe('checksUtils', () => { }); }); + it.each([ + { result: true, severity: CRITICAL, normalizedResult: PASSING }, + { result: false, severity: CRITICAL, normalizedResult: CRITICAL }, + { result: false, severity: WARNING, normalizedResult: WARNING }, + { result: PASSING, severity: CRITICAL, normalizedResult: PASSING }, + ])( + 'should normalize the expectation result', + ({ result, severity, normalizedResult }) => { + expect(normalizeExpectationResult(result, severity)).toBe( + normalizedResult + ); + } + ); + describe('target name detection', () => { it('should detect a cluster target name', () => { const targetName = faker.lorem.word(); From f00ef68bf41233b6bd691e94f08ac58c82927d5d Mon Sep 17 00:00:00 2001 From: arbulu89 Date: Wed, 28 Feb 2024 17:33:32 +0100 Subject: [PATCH 3/4] Display in result details view warning messages --- .../js/lib/test-utils/factories/executions.js | 15 ++-- .../CheckResultDetail/CheckResultDetail.jsx | 6 +- .../CheckResultDetail.test.jsx | 8 +- .../CheckResultDetailPage.jsx | 10 +-- .../CheckResultDetail/ExpectationsResults.jsx | 22 ++++-- .../ExpectationsResults.test.jsx | 76 +++++++++++++++---- .../ExecutionResults/CheckResultOutline.jsx | 11 ++- .../CheckResultOutline.test.jsx | 58 +++++++++++--- .../ExecutionResults/checksUtils.test.js | 12 +-- 9 files changed, 159 insertions(+), 59 deletions(-) diff --git a/assets/js/lib/test-utils/factories/executions.js b/assets/js/lib/test-utils/factories/executions.js index 71591247da..95c785dc3a 100644 --- a/assets/js/lib/test-utils/factories/executions.js +++ b/assets/js/lib/test-utils/factories/executions.js @@ -216,15 +216,20 @@ const addExpectation = (checkResult, name, expectation, result) => { }; }; -export const addPassingExpectation = (checkResult, type, expectationName) => { +export const addExpectationWithResult = ( + checkResult, + type, + expectationName, + result +) => { const name = expectationName || faker.company.name(); const expectation = executionExpectationEvaluationFactory.build({ name, type, - return_value: true, + return_value: result, }); - return addExpectation(checkResult, name, expectation, true); + return addExpectation(checkResult, name, expectation, result); }; export const addExpectationWithError = (checkResult, expectationName) => { @@ -237,7 +242,7 @@ export const addExpectationWithError = (checkResult, expectationName) => { }; export const addPassingExpectExpectation = (checkResult, expectationName) => - addPassingExpectation(checkResult, 'expect', expectationName); + addExpectationWithResult(checkResult, 'expect', expectationName, true); export const addCriticalExpectExpectation = (checkResult, expectationName) => { const name = expectationName || faker.company.name(); @@ -248,7 +253,7 @@ export const addCriticalExpectExpectation = (checkResult, expectationName) => { return addExpectation(checkResult, name, expectation, false); }; export const addPassingExpectSameExpectation = (checkResult, expectationName) => - addPassingExpectation(checkResult, 'expect_same', expectationName); + addExpectationWithResult(checkResult, 'expect_same', expectationName, true); export const agentsCheckResultsWithHostname = ( agentsCheckResults, diff --git a/assets/js/pages/ExecutionResults/CheckResultDetail/CheckResultDetail.jsx b/assets/js/pages/ExecutionResults/CheckResultDetail/CheckResultDetail.jsx index e41d30fe0d..0791f3bf98 100644 --- a/assets/js/pages/ExecutionResults/CheckResultDetail/CheckResultDetail.jsx +++ b/assets/js/pages/ExecutionResults/CheckResultDetail/CheckResultDetail.jsx @@ -2,7 +2,7 @@ import React from 'react'; import { getAgentCheckResultByAgentID, - getExpectStatementsResults, + getHostExpectationStatementsResults, getExpectSameStatementsResults, getClusterCheckResults, isAgentCheckError, @@ -18,6 +18,7 @@ function CheckResultDetail({ expectations = [], targetID, targetType, + severity, executionData, }) { const targetHost = isTargetHost(targetType); @@ -38,7 +39,7 @@ function CheckResultDetail({ const isError = isAgentCheckError(targetResult); const targetExpectationsResults = targetHost - ? getExpectStatementsResults(expectations, expectation_evaluations) + ? getHostExpectationStatementsResults(expectations, expectation_evaluations) : getExpectSameStatementsResults(expectations, expectation_results); const gatheredFacts = targetHost @@ -49,6 +50,7 @@ function CheckResultDetail({ <> { ); expect(screen.getAllByText('Passing')).toHaveLength(2); - expect(screen.getAllByText('Failing')).toHaveLength(3); + expect(screen.getAllByText('Critical')).toHaveLength(3); values.forEach(({ name, value }) => { expect(screen.getByText(name)).toBeVisible(); @@ -175,7 +175,7 @@ describe('CheckResultDetail Component', () => { ); expect(screen.getAllByText('Passing')).toHaveLength(2); - expect(screen.queryAllByText('Failing')).toHaveLength(0); + expect(screen.queryAllByText('Critical')).toHaveLength(0); expect(screen.queryByText('Values')).toBeNull(); expect(screen.getAllByLabelText('property tree')).toHaveLength(2); }); @@ -221,7 +221,7 @@ describe('CheckResultDetail Component', () => { ); expect(screen.queryAllByText('Passing')).toHaveLength(0); - expect(screen.queryAllByText('Failing')).toHaveLength(0); + expect(screen.queryAllByText('Critical')).toHaveLength(0); expect(screen.getByText(factGatheringErrorMessage)).toBeVisible(); expect(screen.getByText('Expected Values unavailable')).toBeVisible(); @@ -273,7 +273,7 @@ describe('CheckResultDetail Component', () => { ); expect(screen.queryAllByText('Passing')).toHaveLength(0); - expect(screen.queryAllByText('Failing')).toHaveLength(0); + expect(screen.queryAllByText('Critical')).toHaveLength(0); expect(screen.getByText(timeoutMessage)).toBeVisible(); expect(values).toBeUndefined(); diff --git a/assets/js/pages/ExecutionResults/CheckResultDetail/CheckResultDetailPage.jsx b/assets/js/pages/ExecutionResults/CheckResultDetail/CheckResultDetailPage.jsx index 172c09ac49..beb2c8cf67 100644 --- a/assets/js/pages/ExecutionResults/CheckResultDetail/CheckResultDetailPage.jsx +++ b/assets/js/pages/ExecutionResults/CheckResultDetail/CheckResultDetailPage.jsx @@ -24,8 +24,7 @@ import ResultsContainer from '@pages/ExecutionResults/ResultsContainer'; import CheckResultDetail from './CheckResultDetail'; import { - getCheckDescription, - getCheckExpectations, + findCheck, isTargetHost, isTargetCluster, getClusterCheckResults, @@ -163,7 +162,7 @@ function CheckResultDetailPage({ targetType }) { ); } - const checkDescription = getCheckDescription(catalog, checkID); + const { description, severity, expectations } = findCheck(catalog, checkID); const resultTargetID = getResultTargetID( targetID, @@ -181,7 +180,7 @@ function CheckResultDetailPage({ targetType }) { > ({ name, - passing: !!return_value, + result: normalizeExpectationResult(return_value, severity), failureMessage: failure_message, evaluationErrorMessage: message, })) : results.map(({ name, result, failure_message, message }) => ({ name, - passing: !!result, + result: normalizeExpectationResult(result, severity), failureMessage: failure_message, evaluationErrorMessage: message, })); const expectationsEvaluations = renderedResults.map( - ({ name, passing, failureMessage, evaluationErrorMessage }) => ({ + ({ name, result, failureMessage, evaluationErrorMessage }) => ({ title: name, - content: passing, - render: (isPassing) => ( + content: result || CRITICAL, + render: (content) => (
- {isPassing ? 'Passing' : 'Failing'} + {capitalize(content)} {failureMessage && {failureMessage}} {evaluationErrorMessage && ( {evaluationErrorMessage} diff --git a/assets/js/pages/ExecutionResults/CheckResultDetail/ExpectationsResults.test.jsx b/assets/js/pages/ExecutionResults/CheckResultDetail/ExpectationsResults.test.jsx index 366e069ac3..2e9802a09a 100644 --- a/assets/js/pages/ExecutionResults/CheckResultDetail/ExpectationsResults.test.jsx +++ b/assets/js/pages/ExecutionResults/CheckResultDetail/ExpectationsResults.test.jsx @@ -3,6 +3,8 @@ import { render, screen } from '@testing-library/react'; import { faker } from '@faker-js/faker'; +import { PASSING, WARNING, CRITICAL } from '@lib/model'; + import { executionExpectationEvaluationFactory, executionExpectationEvaluationErrorFactory, @@ -15,46 +17,83 @@ import '@testing-library/jest-dom'; import ExpectationsResults from './ExpectationsResults'; describe('ExpectationsResults Component', () => { - it('should render expect statements results', () => { + it('should render host expectation statements results', () => { const failureMessage = faker.lorem.sentence(); + const warningMessage = faker.lorem.sentence(); const evaluationErrorMessage = faker.lorem.sentence(); - const results = [ - ...executionExpectationEvaluationFactory.buildList(3, { + const results = [].concat( + executionExpectationEvaluationFactory.buildList(3, { return_value: true, }), - ...failingExpectEvaluationFactory.buildList(2, { + executionExpectationEvaluationFactory.build({ + return_value: PASSING, + }), + executionExpectationEvaluationFactory.build({ + return_value: WARNING, + failure_message: warningMessage, + }), + executionExpectationEvaluationFactory.build({ + return_value: CRITICAL, + }), + failingExpectEvaluationFactory.buildList(2, { failure_message: failureMessage, }), executionExpectationEvaluationErrorFactory.build({ name: 'erroring_evaluation', message: evaluationErrorMessage, - }), - ]; + }) + ); const [{ name: expectationName1 }, _, { name: expectationName3 }] = results; - render(); + render(); - expect(screen.getAllByText('Passing')).toHaveLength(3); - expect(screen.getAllByText('Failing')).toHaveLength(3); + expect(screen.getAllByText('Passing')).toHaveLength(4); + expect(screen.getAllByText('Warning')).toHaveLength(1); + expect(screen.getAllByText('Critical')).toHaveLength(4); expect(screen.getAllByText(failureMessage)).toHaveLength(2); + expect(screen.getAllByText(warningMessage)).toHaveLength(1); expect(screen.getAllByText(evaluationErrorMessage)).toHaveLength(1); expect(screen.getByText(expectationName1)).toBeVisible(); expect(screen.getByText(expectationName3)).toBeVisible(); }); + it('should render host expectation statements with provided seveirty', () => { + const failureMessage = faker.lorem.sentence(); + + const results = executionExpectationEvaluationFactory.buildList(1, { + return_value: false, + failure_message: failureMessage, + }); + + const [{ name: expectationName }] = results; + + render(); + + expect(screen.getAllByText('Warning')).toHaveLength(1); + expect(screen.getAllByText(failureMessage)).toHaveLength(1); + expect(screen.getByText(expectationName)).toBeVisible(); + }); + it('should render expect_same statements results', () => { const failureMessage = faker.lorem.sentence(); - const results = [ - ...failingExpectationResultFactory.buildList(7, { + const evaluationErrorMessage = faker.lorem.sentence(); + + const results = [].concat( + failingExpectationResultFactory.buildList(7, { type: 'expect_same', failure_message: failureMessage, }), - ...expectationResultFactory.buildList(2, { + expectationResultFactory.buildList(2, { result: true, type: 'expect_same', }), - ]; + executionExpectationEvaluationErrorFactory.build({ + name: 'erroring_evaluation', + type: 'expect_same', + message: evaluationErrorMessage, + }) + ); const [ { name: expectationName1 }, @@ -62,11 +101,18 @@ describe('ExpectationsResults Component', () => { { name: expectationName3 }, ] = results; - render(); + render( + + ); expect(screen.getAllByText('Passing')).toHaveLength(2); - expect(screen.getAllByText('Failing')).toHaveLength(7); + expect(screen.getAllByText('Critical')).toHaveLength(8); expect(screen.getAllByText(failureMessage)).toHaveLength(7); + expect(screen.getAllByText(evaluationErrorMessage)).toHaveLength(1); expect(screen.getByText(expectationName1)).toBeVisible(); expect(screen.getByText(expectationName2)).toBeVisible(); expect(screen.getByText(expectationName3)).toBeVisible(); diff --git a/assets/js/pages/ExecutionResults/CheckResultOutline.jsx b/assets/js/pages/ExecutionResults/CheckResultOutline.jsx index 0e6f7f075c..8667804cc8 100644 --- a/assets/js/pages/ExecutionResults/CheckResultOutline.jsx +++ b/assets/js/pages/ExecutionResults/CheckResultOutline.jsx @@ -3,15 +3,16 @@ import { useNavigate } from 'react-router-dom'; import { TARGET_CLUSTER, TARGET_HOST } from '@lib/model'; import TargetResult from './TargetResult'; import { - getExpectStatements, + getHostExpectationStatements, isAgentCheckError, - getExpectStatementsMet, + getHostExpectationStatementsMet, isTargetCluster, getExpectSameStatementsResults, } from './checksUtils'; const extractExpectResults = (expectations, agentsCheckResults) => { - const expectStatementsCount = getExpectStatements(expectations).length; + const expectStatementsCount = + getHostExpectationStatements(expectations).length; if (expectStatementsCount === 0) { return []; @@ -24,7 +25,9 @@ const extractExpectResults = (expectations, agentsCheckResults) => { message, } = agentCheckResult; const isCheckError = isAgentCheckError(agentCheckResult); - const metExpectations = getExpectStatementsMet(expectation_evaluations); + const metExpectations = getHostExpectationStatementsMet( + expectation_evaluations + ); const expectationsSummary = isCheckError ? message : `${metExpectations}/${expectStatementsCount} Expectations met.`; diff --git a/assets/js/pages/ExecutionResults/CheckResultOutline.test.jsx b/assets/js/pages/ExecutionResults/CheckResultOutline.test.jsx index eacc668c3c..94beb2645e 100644 --- a/assets/js/pages/ExecutionResults/CheckResultOutline.test.jsx +++ b/assets/js/pages/ExecutionResults/CheckResultOutline.test.jsx @@ -6,6 +6,15 @@ import { act } from 'react-dom/test-utils'; import { faker } from '@faker-js/faker'; import { + EXPECT, + EXPECT_SAME, + EXPECT_ENUM, + PASSING, + CRITICAL, +} from '@lib/model'; + +import { + addExpectationWithResult, addPassingExpectExpectation, addPassingExpectSameExpectation, emptyCheckResultFactory, @@ -14,6 +23,7 @@ import { expectationResultFactory, catalogExpectExpectationFactory, catalogExpectSameExpectationFactory, + catalogExpectEnumExpectationFactory, } from '@lib/test-utils/factories'; import { renderWithRouter } from '@lib/test-utils'; @@ -24,14 +34,21 @@ import CheckResultOutline from './CheckResultOutline'; const expectStatementResult = (expectationName, result) => expectationResultFactory.build({ name: expectationName, - type: 'expect', + type: EXPECT, result, }); const expectSameStatementResult = (expectationName, result) => expectationResultFactory.build({ name: expectationName, - type: 'expect_same', + type: EXPECT_SAME, + result, + }); + +const expectEnumStatementResult = (expectationName, result) => + expectationResultFactory.build({ + name: expectationName, + type: EXPECT_ENUM, result, }); @@ -135,27 +152,48 @@ describe('CheckResultOutline Component', () => { const hostName = faker.lorem.word(); const checkID = faker.string.uuid(); - const expectationName = faker.string.uuid(); - const expectations = [ - catalogExpectExpectationFactory.build({ - name: expectationName, - }), + catalogExpectExpectationFactory.build(), + catalogExpectEnumExpectationFactory.build(), + catalogExpectEnumExpectationFactory.build(), ]; + const [ + { name: expectationName1 }, + { name: expectationName2 }, + { name: expectationName3 }, + ] = expectations; + let checkResult = emptyCheckResultFactory.build({ checkID, targets: [hostID], result: 'passing', }); - checkResult = addPassingExpectExpectation(checkResult, expectationName); + + checkResult = addPassingExpectExpectation(checkResult, expectationName1); + checkResult = addExpectationWithResult( + checkResult, + EXPECT_ENUM, + expectationName2, + PASSING + ); + checkResult = addExpectationWithResult( + checkResult, + EXPECT_ENUM, + expectationName3, + CRITICAL + ); const agentsCheckResults = agentsCheckResultsWithHostname( checkResult.agents_check_results, [{ id: hostID, hostname: hostName }] ); - const expectationResults = [expectStatementResult(expectationName, true)]; + const expectationResults = [ + expectStatementResult(expectationName1, true), + expectEnumStatementResult(expectationName2, PASSING), + expectEnumStatementResult(expectationName3, CRITICAL), + ]; renderWithRouter( { ); expect(screen.getAllByText(hostName)).toHaveLength(1); - expect(screen.getAllByText('1/1 Expectations met.')).toHaveLength(1); + expect(screen.getAllByText('2/3 Expectations met.')).toHaveLength(1); await act(async () => user.click(screen.getAllByText(hostName)[0])); diff --git a/assets/js/pages/ExecutionResults/checksUtils.test.js b/assets/js/pages/ExecutionResults/checksUtils.test.js index cec777a60b..d256b25d2e 100644 --- a/assets/js/pages/ExecutionResults/checksUtils.test.js +++ b/assets/js/pages/ExecutionResults/checksUtils.test.js @@ -155,7 +155,7 @@ describe('checksUtils', () => { expectationResultFactory.buildList(2, { type: EXPECT, }), - expectationResultFactory.buildList(1, { + expectationResultFactory.build({ type: EXPECT_SAME, }), expectationResultFactory.buildList(3, { @@ -173,8 +173,8 @@ describe('checksUtils', () => { it('should get host expectation statements results', () => { const expectations = [].concat( catalogExpectExpectationFactory.buildList(3), - catalogExpectSameExpectationFactory.buildList(1), - catalogExpectEnumExpectationFactory.buildList(1) + catalogExpectSameExpectationFactory.build(), + catalogExpectEnumExpectationFactory.build() ); const [ @@ -509,7 +509,7 @@ describe('checksUtils', () => { it('should count the host expectations statements met', () => { const expectationEvaluations = [].concat( - executionExpectationEvaluationFactory.buildList(1, { + executionExpectationEvaluationFactory.build({ type: EXPECT_SAME, }), executionExpectationEvaluationFactory.buildList(2, { @@ -520,11 +520,11 @@ describe('checksUtils', () => { return_value: true, type: EXPECT, }), - executionExpectationEvaluationFactory.buildList(1, { + executionExpectationEvaluationFactory.build({ return_value: PASSING, type: EXPECT_ENUM, }), - executionExpectationEvaluationFactory.buildList(1, { + executionExpectationEvaluationFactory.build({ return_value: CRITICAL, type: EXPECT_ENUM, }) From dee425668cb45670bdbd39d8d63c7478b57bebce Mon Sep 17 00:00:00 2001 From: arbulu89 Date: Thu, 29 Feb 2024 08:48:08 +0100 Subject: [PATCH 4/4] Add examples in storybook --- .../CheckResultDetail/CheckResultDetail.stories.jsx | 12 ++++++++++++ .../ExpectationsResults.stories.jsx | 9 +++++++++ 2 files changed, 21 insertions(+) diff --git a/assets/js/pages/ExecutionResults/CheckResultDetail/CheckResultDetail.stories.jsx b/assets/js/pages/ExecutionResults/CheckResultDetail/CheckResultDetail.stories.jsx index 91588a90d6..91f964a789 100644 --- a/assets/js/pages/ExecutionResults/CheckResultDetail/CheckResultDetail.stories.jsx +++ b/assets/js/pages/ExecutionResults/CheckResultDetail/CheckResultDetail.stories.jsx @@ -1,6 +1,7 @@ import { addPassingExpectExpectation, addPassingExpectSameExpectation, + addExpectationWithResult, emptyCheckResultFactory, hostFactory, checksExecutionCompletedFactory, @@ -9,8 +10,11 @@ import { withOverriddenValues, catalogExpectExpectationFactory, catalogExpectSameExpectationFactory, + catalogExpectEnumExpectationFactory, } from '@lib/test-utils/factories'; +import { EXPECT_ENUM, WARNING } from '@lib/model'; + import CheckResultDetail from './CheckResultDetail'; const clusterHosts = hostFactory.buildList(2); @@ -20,6 +24,7 @@ const targetType = 'host'; const catalogExpectations = [ ...catalogExpectExpectationFactory.buildList(5), catalogExpectSameExpectationFactory.build(), + catalogExpectEnumExpectationFactory.build(), ]; const [ @@ -29,6 +34,7 @@ const [ { name: expectationName4 }, { name: expectationName5 }, { name: expectationName6 }, + { name: expectationName7 }, ] = catalogExpectations; let checkResult = emptyCheckResultFactory.build({ @@ -43,6 +49,12 @@ checkResult = addCriticalExpectExpectation(checkResult, expectationName3); checkResult = addCriticalExpectExpectation(checkResult, expectationName4); checkResult = addCriticalExpectExpectation(checkResult, expectationName5); checkResult = addPassingExpectSameExpectation(checkResult, expectationName6); +checkResult = addExpectationWithResult( + checkResult, + EXPECT_ENUM, + expectationName7, + WARNING +); const checkResultWithoutValues = withOverriddenValues(checkResult, target1, []); diff --git a/assets/js/pages/ExecutionResults/CheckResultDetail/ExpectationsResults.stories.jsx b/assets/js/pages/ExecutionResults/CheckResultDetail/ExpectationsResults.stories.jsx index a85f30e290..e9d43a69f8 100644 --- a/assets/js/pages/ExecutionResults/CheckResultDetail/ExpectationsResults.stories.jsx +++ b/assets/js/pages/ExecutionResults/CheckResultDetail/ExpectationsResults.stories.jsx @@ -4,6 +4,8 @@ import { failingExpectEvaluationFactory, } from '@lib/test-utils/factories'; +import { WARNING } from '@lib/model'; + import ExpectationsResults from './ExpectationsResults'; export default { @@ -30,6 +32,13 @@ export const WithFailureMessage = { }, }; +export const WithWarning = { + args: { + ...WithFailureMessage.args, + severity: WARNING, + }, +}; + export const WithEvaluationError = { args: { ...Default.args,