Skip to content

Commit 24c7b2d

Browse files
Adds safe guards against in-determinism by checking list items after uploads (#84015)
## Summary Fixes flakey tests by adding explicit list value upload items through either the fixture that was uploaded or by a specific test value in case the uploaded list is a range value. Also filters out any empty values for more safeguards from prettier formatters that add them to fixture files. #84014 ### 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
1 parent 0a0672f commit 24c7b2d

File tree

2 files changed

+93
-16
lines changed

2 files changed

+93
-16
lines changed

x-pack/plugins/security_solution/cypress/integration/value_lists.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ describe('value lists', () => {
148148

149149
it('deletes a "ip_range" from an uploaded file', () => {
150150
const listName = 'cidr_list.txt';
151-
importValueList(listName, 'ip_range');
151+
importValueList(listName, 'ip_range', ['192.168.100.0']);
152152
openValueListsModal();
153153
deleteValueListsFile(listName);
154154
cy.get(VALUE_LISTS_TABLE)
@@ -209,7 +209,7 @@ describe('value lists', () => {
209209

210210
it('exports a "ip_range" list from an uploaded file', () => {
211211
const listName = 'cidr_list.txt';
212-
importValueList(listName, 'ip_range');
212+
importValueList(listName, 'ip_range', ['192.168.100.0']);
213213
openValueListsModal();
214214
exportValueList();
215215
cy.wait('@exportList').then((xhr) => {

x-pack/plugins/security_solution/cypress/tasks/lists.ts

Lines changed: 91 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -77,27 +77,104 @@ export const deleteValueList = (list: string): Cypress.Chainable<Cypress.Respons
7777
};
7878

7979
/**
80-
* Imports a single value list file this using Cypress Request and lists REST API
80+
* Uploads list items using Cypress Request and lists REST API.
81+
*
82+
* This also will remove any upload data such as empty strings that can happen from the fixture
83+
* due to extra lines being added from formatters such as prettier.
84+
* @param file The file name to import
85+
* @param type The type of the file import such as ip/keyword/text etc...
86+
* @param data The contents of the file
87+
* @param testSuggestions The type of test to use rather than the fixture file which is useful for ranges
8188
* Ref: https://www.elastic.co/guide/en/security/current/lists-api-import-list-items.html
8289
*/
83-
export const importValueList = (
90+
export const uploadListItemData = (
8491
file: string,
85-
type: string
92+
type: string,
93+
data: string
8694
): Cypress.Chainable<Cypress.Response> => {
87-
return cy.fixture(file).then((data) => {
88-
return cy.request({
89-
method: 'POST',
90-
url: `api/lists/items/_import?type=${type}`,
91-
encoding: 'binary',
92-
headers: {
93-
'kbn-xsrf': 'upload-value-lists',
94-
'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundaryJLrRH89J8QVArZyv',
95-
},
96-
body: `------WebKitFormBoundaryJLrRH89J8QVArZyv\nContent-Disposition: form-data; name="file"; filename="${file}"\n\n${data}`,
97-
});
95+
const removedEmptyLines = data
96+
.split('\n')
97+
.filter((line) => line.trim() !== '')
98+
.join('\n');
99+
100+
return cy.request({
101+
method: 'POST',
102+
url: `api/lists/items/_import?type=${type}`,
103+
encoding: 'binary',
104+
headers: {
105+
'kbn-xsrf': 'upload-value-lists',
106+
'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundaryJLrRH89J8QVArZyv',
107+
},
108+
body: `------WebKitFormBoundaryJLrRH89J8QVArZyv\nContent-Disposition: form-data; name="file"; filename="${file}"\n\n${removedEmptyLines}`,
109+
});
110+
};
111+
112+
/**
113+
* Checks a single value list file against a data set to ensure it has been uploaded.
114+
*
115+
* You can optionally pass in an array of test suggestions which will be useful for if you are
116+
* using a range such as a CIDR range and need to ensure that test range has been added to the
117+
* list but you cannot run an explicit test against that range.
118+
*
119+
* This also will remove any upload data such as empty strings that can happen from the fixture
120+
* due to extra lines being added from formatters.
121+
* @param file The file that was imported
122+
* @param data The contents to check unless testSuggestions is given.
123+
* @param type The type of the file import such as ip/keyword/text etc...
124+
* @param testSuggestions The type of test to use rather than the fixture file which is useful for ranges
125+
* Ref: https://www.elastic.co/guide/en/security/current/lists-api-import-list-items.html
126+
*/
127+
export const checkListItemData = (
128+
file: string,
129+
data: string,
130+
testSuggestions: string[] | undefined
131+
): Cypress.Chainable<JQuery<HTMLElement>> => {
132+
const importCheckLines =
133+
testSuggestions == null
134+
? data.split('\n').filter((line) => line.trim() !== '')
135+
: testSuggestions;
136+
137+
return cy.wrap(importCheckLines).each((line) => {
138+
return cy
139+
.request({
140+
retryOnStatusCodeFailure: true,
141+
method: 'GET',
142+
url: `api/lists/items?list_id=${file}&value=${line}`,
143+
})
144+
.then((resp) => {
145+
expect(resp.status).to.eq(200);
146+
});
98147
});
99148
};
100149

150+
/**
151+
* Imports a single value list file this using Cypress Request and lists REST API. After it
152+
* imports the data, it will re-check and ensure that the data is there before continuing to
153+
* get us more deterministic.
154+
*
155+
* You can optionally pass in an array of test suggestions which will be useful for if you are
156+
* using a range such as a CIDR range and need to ensure that test range has been added to the
157+
* list but you cannot run an explicit test against that range.
158+
*
159+
* This also will remove any upload data such as empty strings that can happen from the fixture
160+
* due to extra lines being added from formatters.
161+
* @param file The file to import
162+
* @param type The type of the file import such as ip/keyword/text etc...
163+
* @param testSuggestions The type of test to use rather than the fixture file which is useful for ranges
164+
* Ref: https://www.elastic.co/guide/en/security/current/lists-api-import-list-items.html
165+
*/
166+
export const importValueList = (
167+
file: string,
168+
type: string,
169+
testSuggestions: string[] | undefined = undefined
170+
): Cypress.Chainable<JQuery<HTMLElement>> => {
171+
return cy
172+
.fixture<string>(file)
173+
.then((data) => uploadListItemData(file, type, data))
174+
.fixture<string>(file)
175+
.then((data) => checkListItemData(file, data, testSuggestions));
176+
};
177+
101178
/**
102179
* If you are on the value lists from the UI, this will loop over all the HTML elements
103180
* that have action-delete-value-list-${list_name} and delete all of those value lists

0 commit comments

Comments
 (0)