From 9b9473f8ea7fed510bdccd93789cfc9bd8dd6a3f Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Wed, 30 Jun 2021 22:38:23 -0400 Subject: [PATCH] Fixes the unHandledPromise rejections happening from unit tests (#104017) (#104034) ## Summary We had `unHandledPromise` rejections within some of our unit tests which still pass on CI but technically those tests are not running correctly and will not catch bugs. We were seeing them showing up like so: ```ts PASS x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.test.ts (10.502 s) (node:21059) UnhandledPromiseRejectionWarning: [object Object] at emitUnhandledRejectionWarning (internal/process/promises.js:170:15) at processPromiseRejections (internal/process/promises.js:247:11) at processTicksAndRejections (internal/process/task_queues.js:96:32) (node:21059) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 3) (node:21059) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. at emitDeprecationWarning (internal/process/promises.js:180:11) at processPromiseRejections (internal/process/promises.js:249:13) at processTicksAndRejections (internal/process/task_queues.js:96:32) PASS x-pack/plugins/security_solution/server/lib/detection_engine/signals/signal_rule_alert_type.test.ts PASS x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.test.ts PASS x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_route.test.ts (node:21059) UnhandledPromiseRejectionWarning: Error: bulk failed at emitUnhandledRejectionWarning (internal/process/promises.js:170:15) at processPromiseRejections (internal/process/promises.js:247:11) at processTicksAndRejections (internal/process/task_queues.js:96:32) (node:21059) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 7) ```` You can narrow down `unHandledPromise` rejections and fix tests one by one by running the following command: ```ts node --trace-warnings --unhandled-rejections=strict scripts/jest.js --runInBand x-pack/plugins/security_solution ``` You can manually test if I fixed them by running that command and ensuring all tests run without errors and that the process exits with a 0 for detections only by running: ```ts node --trace-warnings --unhandled-rejections=strict scripts/jest.js --runInBand x-pack/plugins/security_solution/public/detections ``` and ```ts node --trace-warnings --unhandled-rejections=strict scripts/jest.js --runInBand x-pack/plugins/security_solution/server/lib/detection_engine ``` ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or Co-authored-by: Frank Hassanabad --- .../components/rules/query_bar/index.test.tsx | 33 ++++++++++++++++--- .../rule_actions_overflow/index.test.tsx | 15 ++++++--- .../signals/search_after_bulk_create.test.ts | 14 ++++++-- .../signals/signal_rule_alert_type.test.ts | 12 +++++-- 4 files changed, 60 insertions(+), 14 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/query_bar/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/query_bar/index.test.tsx index 8c6f74a01e49a7..12923609db2668 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/query_bar/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/query_bar/index.test.tsx @@ -6,7 +6,7 @@ */ import React from 'react'; -import { mount, shallow } from 'enzyme'; +import { mount } from 'enzyme'; import { QueryBarDefineRule } from './index'; import { @@ -17,7 +17,26 @@ import { import { useGetAllTimeline, getAllTimeline } from '../../../../timelines/containers/all'; import { mockHistory, Router } from '../../../../common/mock/router'; -jest.mock('../../../../common/lib/kibana'); +jest.mock('../../../../common/lib/kibana', () => { + const actual = jest.requireActual('../../../../common/lib/kibana'); + return { + ...actual, + KibanaServices: { + get: jest.fn(() => ({ + http: { + post: jest.fn().mockReturnValue({ + success: true, + success_count: 0, + timelines_installed: 0, + timelines_updated: 0, + errors: [], + }), + fetch: jest.fn(), + }, + })), + }, + }; +}); jest.mock('../../../../timelines/containers/all', () => { const originalModule = jest.requireActual('../../../../timelines/containers/all'); @@ -55,8 +74,14 @@ describe('QueryBarDefineRule', () => { /> ); }; - const wrapper = shallow(); - expect(wrapper.dive().find('[data-test-subj="query-bar-define-rule"]')).toHaveLength(1); + const wrapper = mount( + + + + + + ); + expect(wrapper.find('[data-test-subj="query-bar-define-rule"]').exists()).toBeTruthy(); }); it('renders import query from saved timeline modal actions hidden correctly', () => { diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.test.tsx index c545de7fd8d7d4..6a62b05c2e3194 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.test.tsx @@ -36,11 +36,16 @@ jest.mock('react-router-dom', () => ({ }), })); -jest.mock('../../../pages/detection_engine/rules/all/actions', () => ({ - deleteRulesAction: jest.fn(), - duplicateRulesAction: jest.fn(), - editRuleAction: jest.fn(), -})); +jest.mock('../../../pages/detection_engine/rules/all/actions', () => { + const actual = jest.requireActual('../../../../common/lib/kibana'); + return { + ...actual, + exportRulesAction: jest.fn(), + deleteRulesAction: jest.fn(), + duplicateRulesAction: jest.fn(), + editRuleAction: jest.fn(), + }; +}); const duplicateRulesActionMock = duplicateRulesAction as jest.Mock; const flushPromises = () => new Promise(setImmediate); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.test.ts index dc03f1bc964f23..711db931e9072f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.test.ts @@ -31,6 +31,7 @@ import { getQueryRuleParams } from '../schemas/rule_schemas.mock'; import { bulkCreateFactory } from './bulk_create_factory'; import { wrapHitsFactory } from './wrap_hits_factory'; import { mockBuildRuleMessage } from './__mocks__/build_rule_message.mock'; +import { ResponseError } from '@elastic/elasticsearch/lib/errors'; const buildRuleMessage = mockBuildRuleMessage; @@ -739,9 +740,16 @@ describe('searchAfterAndBulkCreate', () => { repeatedSearchResultsWithSortId(4, 1, someGuids.slice(0, 3)) ) ); - mockService.scopedClusterClient.asCurrentUser.bulk.mockRejectedValue( - elasticsearchClientMock.createErrorTransportRequestPromise(new Error('bulk failed')) - ); // Added this recently + mockService.scopedClusterClient.asCurrentUser.bulk.mockReturnValue( + elasticsearchClientMock.createErrorTransportRequestPromise( + new ResponseError( + elasticsearchClientMock.createApiResponse({ + statusCode: 400, + body: { error: { type: 'bulk_error_type' } }, + }) + ) + ) + ); const { success, createdSignalsCount, lastLookBackDate } = await searchAfterAndBulkCreate({ listClient, exceptionsList: [exceptionItem], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/signal_rule_alert_type.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/signal_rule_alert_type.test.ts index 39aebb4aa45550..aec8b6c552b1da 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/signal_rule_alert_type.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/signal_rule_alert_type.test.ts @@ -32,6 +32,7 @@ import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mo import { queryExecutor } from './executors/query'; import { mlExecutor } from './executors/ml'; import { getMlRuleParams, getQueryRuleParams } from '../schemas/rule_schemas.mock'; +import { ResponseError } from '@elastic/elasticsearch/lib/errors'; jest.mock('./rule_status_saved_objects_client'); jest.mock('./rule_status_service'); @@ -455,8 +456,15 @@ describe('signal_rule_alert_type', () => { }); it('and call ruleStatusService with the default message', async () => { - (queryExecutor as jest.Mock).mockRejectedValue( - elasticsearchClientMock.createErrorTransportRequestPromise({}) + (queryExecutor as jest.Mock).mockReturnValue( + elasticsearchClientMock.createErrorTransportRequestPromise( + new ResponseError( + elasticsearchClientMock.createApiResponse({ + statusCode: 400, + body: { error: { type: 'some_error_type' } }, + }) + ) + ) ); await alert.executor(payload); expect(logger.error).toHaveBeenCalled();