-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
## Summary Breaks apart the e2e FTR utils from one large file to individual files with an index.ts ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios
- Loading branch information
1 parent
ef7f28e
commit 874bfb3
Showing
84 changed files
with
3,045 additions
and
2,179 deletions.
There are no files selected for viewing
2,179 changes: 0 additions & 2,179 deletions
2,179
x-pack/test/detection_engine_api_integration/utils.ts
This file was deleted.
Oops, something went wrong.
22 changes: 22 additions & 0 deletions
22
x-pack/test/detection_engine_api_integration/utils/binary_to_string.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/* | ||
* 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. | ||
*/ | ||
|
||
/** | ||
* Useful for export_api testing to convert from a multi-part binary back to a string | ||
* @param res Response | ||
* @param callback Callback | ||
*/ | ||
export const binaryToString = (res: any, callback: any): void => { | ||
res.setEncoding('binary'); | ||
res.data = ''; | ||
res.on('data', (chunk: any) => { | ||
res.data += chunk; | ||
}); | ||
res.on('end', () => { | ||
callback(null, Buffer.from(res.data)); | ||
}); | ||
}; |
46 changes: 46 additions & 0 deletions
46
x-pack/test/detection_engine_api_integration/utils/count_down_es.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/* | ||
* 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 type { TransportResult } from '@elastic/elasticsearch'; | ||
import type { ToolingLog } from '@kbn/dev-utils'; | ||
import { countDownTest } from './count_down_test'; | ||
|
||
/** | ||
* Does a plain countdown and checks against es queries for either conflicts in the error | ||
* or for any over the wire issues such as timeouts or temp 404's to make the tests more | ||
* reliant. | ||
* @param esFunction The function to test against | ||
* @param esFunctionName The name of the function to print if we encounter errors | ||
* @param log The tooling logger | ||
* @param retryCount The number of times to retry before giving up (has default) | ||
* @param timeoutWait Time to wait before trying again (has default) | ||
*/ | ||
export const countDownES = async ( | ||
esFunction: () => Promise<TransportResult<Record<string, any>, unknown>>, | ||
esFunctionName: string, | ||
log: ToolingLog, | ||
retryCount: number = 50, | ||
timeoutWait = 250 | ||
): Promise<void> => { | ||
await countDownTest( | ||
async () => { | ||
const result = await esFunction(); | ||
if (result.body.version_conflicts !== 0) { | ||
return { | ||
passed: false, | ||
errorMessage: 'Version conflicts for ${result.body.version_conflicts}', | ||
}; | ||
} else { | ||
return { passed: true }; | ||
} | ||
}, | ||
esFunctionName, | ||
log, | ||
retryCount, | ||
timeoutWait | ||
); | ||
}; |
78 changes: 78 additions & 0 deletions
78
x-pack/test/detection_engine_api_integration/utils/count_down_test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/* | ||
* 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 type { ToolingLog } from '@kbn/dev-utils'; | ||
|
||
/** | ||
* Does a plain countdown and checks against a boolean to determine if to wait and try again. | ||
* This is useful for over the wire things that can cause issues such as conflict or timeouts | ||
* for testing resiliency. | ||
* @param functionToTest The function to test against | ||
* @param name The name of the function to print if we encounter errors | ||
* @param log The tooling logger | ||
* @param retryCount The number of times to retry before giving up (has default) | ||
* @param timeoutWait Time to wait before trying again (has default) | ||
*/ | ||
export const countDownTest = async <T>( | ||
functionToTest: () => Promise<{ | ||
passed: boolean; | ||
returnValue?: T | undefined; | ||
errorMessage?: string; | ||
}>, | ||
name: string, | ||
log: ToolingLog, | ||
retryCount: number = 50, | ||
timeoutWait = 250, | ||
ignoreThrow: boolean = false | ||
): Promise<T | undefined> => { | ||
if (retryCount > 0) { | ||
try { | ||
const testReturn = await functionToTest(); | ||
if (!testReturn.passed) { | ||
const error = testReturn.errorMessage != null ? ` error: ${testReturn.errorMessage},` : ''; | ||
log.error(`Failure trying to ${name},${error} retries left are: ${retryCount - 1}`); | ||
// retry, counting down, and delay a bit before | ||
await new Promise((resolve) => setTimeout(resolve, timeoutWait)); | ||
const returnValue = await countDownTest( | ||
functionToTest, | ||
name, | ||
log, | ||
retryCount - 1, | ||
timeoutWait, | ||
ignoreThrow | ||
); | ||
return returnValue; | ||
} else { | ||
return testReturn.returnValue; | ||
} | ||
} catch (err) { | ||
if (ignoreThrow) { | ||
throw err; | ||
} else { | ||
log.error( | ||
`Failure trying to ${name}, with exception message of: ${ | ||
err.message | ||
}, retries left are: ${retryCount - 1}` | ||
); | ||
// retry, counting down, and delay a bit before | ||
await new Promise((resolve) => setTimeout(resolve, timeoutWait)); | ||
const returnValue = await countDownTest( | ||
functionToTest, | ||
name, | ||
log, | ||
retryCount - 1, | ||
timeoutWait, | ||
ignoreThrow | ||
); | ||
return returnValue; | ||
} | ||
} | ||
} else { | ||
log.error(`Could not ${name}, no retries are left`); | ||
return undefined; | ||
} | ||
}; |
85 changes: 85 additions & 0 deletions
85
x-pack/test/detection_engine_api_integration/utils/create_container_with_endpoint_entries.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
/* | ||
* 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 type { ToolingLog } from '@kbn/dev-utils'; | ||
import type SuperTest from 'supertest'; | ||
import type { | ||
CreateExceptionListItemSchema, | ||
ListArray, | ||
NonEmptyEntriesArray, | ||
OsTypeArray, | ||
} from '@kbn/securitysolution-io-ts-list-types'; | ||
|
||
import { EXCEPTION_LIST_ITEM_URL } from '@kbn/securitysolution-list-constants'; | ||
import { createExceptionListItem } from './create_exception_list_item'; | ||
import { waitFor } from './wait_for'; | ||
import { createExceptionList } from './create_exception_list'; | ||
|
||
/** | ||
* Convenience testing function where you can pass in just the endpoint entries and you will | ||
* get a container created with the entries. | ||
* @param supertest super test agent | ||
* @param endpointEntries The endpoint entries to create the rule and exception list from | ||
* @param osTypes The os types to optionally add or not to add to the container | ||
*/ | ||
export const createContainerWithEndpointEntries = async ( | ||
supertest: SuperTest.SuperTest<SuperTest.Test>, | ||
log: ToolingLog, | ||
endpointEntries: Array<{ | ||
entries: NonEmptyEntriesArray; | ||
osTypes: OsTypeArray | undefined; | ||
}> | ||
): Promise<ListArray> => { | ||
// If not given any endpoint entries, return without any | ||
if (endpointEntries.length === 0) { | ||
return []; | ||
} | ||
|
||
// create the endpoint exception list container | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
const { id, list_id, namespace_type, type } = await createExceptionList(supertest, log, { | ||
description: 'endpoint description', | ||
list_id: 'endpoint_list', | ||
name: 'endpoint_list', | ||
type: 'endpoint', | ||
}); | ||
|
||
// Add the endpoint exception list container to the backend | ||
await Promise.all( | ||
endpointEntries.map((endpointEntry) => { | ||
const exceptionListItem: CreateExceptionListItemSchema = { | ||
description: 'endpoint description', | ||
entries: endpointEntry.entries, | ||
list_id: 'endpoint_list', | ||
name: 'endpoint_list', | ||
os_types: endpointEntry.osTypes, | ||
type: 'simple', | ||
}; | ||
return createExceptionListItem(supertest, log, exceptionListItem); | ||
}) | ||
); | ||
|
||
// To reduce the odds of in-determinism and/or bugs we ensure we have | ||
// the same length of entries before continuing. | ||
await waitFor( | ||
async () => { | ||
const { body } = await supertest.get(`${EXCEPTION_LIST_ITEM_URL}/_find?list_id=${list_id}`); | ||
return body.data.length === endpointEntries.length; | ||
}, | ||
`within createContainerWithEndpointEntries ${EXCEPTION_LIST_ITEM_URL}/_find?list_id=${list_id}`, | ||
log | ||
); | ||
|
||
return [ | ||
{ | ||
id, | ||
list_id, | ||
namespace_type, | ||
type, | ||
}, | ||
]; | ||
}; |
76 changes: 76 additions & 0 deletions
76
x-pack/test/detection_engine_api_integration/utils/create_container_with_entries.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/* | ||
* 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 type { ToolingLog } from '@kbn/dev-utils'; | ||
import type SuperTest from 'supertest'; | ||
import type { CreateExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; | ||
import type { ListArray, NonEmptyEntriesArray } from '@kbn/securitysolution-io-ts-list-types'; | ||
|
||
import { EXCEPTION_LIST_ITEM_URL } from '@kbn/securitysolution-list-constants'; | ||
import { createExceptionList } from './create_exception_list'; | ||
import { createExceptionListItem } from './create_exception_list_item'; | ||
import { waitFor } from './wait_for'; | ||
|
||
/** | ||
* Convenience testing function where you can pass in just the endpoint entries and you will | ||
* get a container created with the entries. | ||
* @param supertest super test agent | ||
* @param entries The entries to create the rule and exception list from | ||
* @param osTypes The os types to optionally add or not to add to the container | ||
*/ | ||
export const createContainerWithEntries = async ( | ||
supertest: SuperTest.SuperTest<SuperTest.Test>, | ||
log: ToolingLog, | ||
entries: NonEmptyEntriesArray[] | ||
): Promise<ListArray> => { | ||
// If not given any endpoint entries, return without any | ||
if (entries.length === 0) { | ||
return []; | ||
} | ||
// Create the rule exception list container | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
const { id, list_id, namespace_type, type } = await createExceptionList(supertest, log, { | ||
description: 'some description', | ||
list_id: 'some-list-id', | ||
name: 'some name', | ||
type: 'detection', | ||
}); | ||
|
||
// Add the rule exception list container to the backend | ||
await Promise.all( | ||
entries.map((entry) => { | ||
const exceptionListItem: CreateExceptionListItemSchema = { | ||
description: 'some description', | ||
list_id: 'some-list-id', | ||
name: 'some name', | ||
type: 'simple', | ||
entries: entry, | ||
}; | ||
return createExceptionListItem(supertest, log, exceptionListItem); | ||
}) | ||
); | ||
|
||
// To reduce the odds of in-determinism and/or bugs we ensure we have | ||
// the same length of entries before continuing. | ||
await waitFor( | ||
async () => { | ||
const { body } = await supertest.get(`${EXCEPTION_LIST_ITEM_URL}/_find?list_id=${list_id}`); | ||
return body.data.length === entries.length; | ||
}, | ||
`within createContainerWithEntries ${EXCEPTION_LIST_ITEM_URL}/_find?list_id=${list_id}`, | ||
log | ||
); | ||
|
||
return [ | ||
{ | ||
id, | ||
list_id, | ||
namespace_type, | ||
type, | ||
}, | ||
]; | ||
}; |
68 changes: 68 additions & 0 deletions
68
x-pack/test/detection_engine_api_integration/utils/create_exception_list.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/* | ||
* 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 type { ToolingLog } from '@kbn/dev-utils'; | ||
import type SuperTest from 'supertest'; | ||
import type { | ||
CreateExceptionListSchema, | ||
ExceptionListSchema, | ||
} from '@kbn/securitysolution-io-ts-list-types'; | ||
|
||
import { EXCEPTION_LIST_URL } from '@kbn/securitysolution-list-constants'; | ||
import { deleteExceptionList } from './delete_exception_list'; | ||
|
||
/** | ||
* Helper to cut down on the noise in some of the tests. This checks for | ||
* an expected 200 still and does not try to any retries. Creates exception lists | ||
* @param supertest The supertest deps | ||
* @param exceptionList The exception list to create | ||
* @param log The tooling logger | ||
*/ | ||
export const createExceptionList = async ( | ||
supertest: SuperTest.SuperTest<SuperTest.Test>, | ||
log: ToolingLog, | ||
exceptionList: CreateExceptionListSchema | ||
): Promise<ExceptionListSchema> => { | ||
const response = await supertest | ||
.post(EXCEPTION_LIST_URL) | ||
.set('kbn-xsrf', 'true') | ||
.send(exceptionList); | ||
|
||
if (response.status === 409) { | ||
if (exceptionList.list_id != null) { | ||
log.error( | ||
`When creating an exception list found an unexpected conflict (409) creating an exception list (createExceptionList), will attempt a cleanup and one time re-try. This usually indicates a bad cleanup or race condition within the tests: ${JSON.stringify( | ||
response.body | ||
)}, status: ${JSON.stringify(response.status)}` | ||
); | ||
await deleteExceptionList(supertest, log, exceptionList.list_id); | ||
const secondResponseTry = await supertest | ||
.post(EXCEPTION_LIST_URL) | ||
.set('kbn-xsrf', 'true') | ||
.send(exceptionList); | ||
if (secondResponseTry.status !== 200) { | ||
throw new Error( | ||
`Unexpected non 200 ok when attempting to create an exception list (second try): ${JSON.stringify( | ||
response.body | ||
)}` | ||
); | ||
} else { | ||
return secondResponseTry.body; | ||
} | ||
} else { | ||
throw new Error('When creating an exception list found an unexpected conflict (404)'); | ||
} | ||
} else if (response.status !== 200) { | ||
throw new Error( | ||
`Unexpected non 200 ok when attempting to create an exception list: ${JSON.stringify( | ||
response.status | ||
)}` | ||
); | ||
} else { | ||
return response.body; | ||
} | ||
}; |
Oops, something went wrong.