gitlab-qa 7.13.3 → 7.16.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitlab/ci/rules.gitlab-ci.yml +70 -0
- data/.gitlab-ci.yml +132 -21
- data/docs/run_qa_against_gdk.md +11 -1
- data/docs/what_tests_can_be_run.md +1 -0
- data/lib/gitlab/qa/component/elasticsearch.rb +1 -0
- data/lib/gitlab/qa/report/generate_test_session.rb +5 -0
- data/lib/gitlab/qa/report/gitlab_issue_client.rb +8 -1
- data/lib/gitlab/qa/report/relate_failure_issue.rb +2 -1
- data/lib/gitlab/qa/report/report_as_issue.rb +12 -3
- data/lib/gitlab/qa/report/report_results.rb +71 -0
- data/lib/gitlab/qa/report/results_in_issues.rb +24 -142
- data/lib/gitlab/qa/report/results_in_testcases.rb +67 -0
- data/lib/gitlab/qa/report/results_reporter_shared.rb +65 -0
- data/lib/gitlab/qa/reporter.rb +15 -7
- data/lib/gitlab/qa/runtime/env.rb +2 -1
- data/lib/gitlab/qa/scenario/test/integration/service_ping_disabled.rb +33 -0
- data/lib/gitlab/qa/version.rb +1 -1
- data/lib/gitlab/qa.rb +4 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '090fb8d7830e6cfd3ee6978b9f7ba4ad6eb4ba5ceec37921e5cde75285fd4015'
|
4
|
+
data.tar.gz: '058a34d1526fc7ae37df2c8b75e3e0888c15785c5bb2d3954b0b72e6a6d653d8'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: de89ce6d1c4a5cf43aebd3510af3f758dc1e8f2d8063878ec6a74d5530d9af9ffa903ad77267caed55ad77125ecb2aa044523cb9366144c82637f02bb765778f
|
7
|
+
data.tar.gz: 9a68591bf7a1a774dbee63a5f0374c0b46df7029e4e90419f184be961cfbddb7d31589e7603299bb1b7f59af20ceb7f2eb5f4071315389dc97958946bc246801
|
@@ -37,6 +37,12 @@
|
|
37
37
|
.if-set-feature-flag: &if-set-feature-flag
|
38
38
|
if: '$GITLAB_QA_OPTIONS =~ /--set-feature-flags/'
|
39
39
|
|
40
|
+
.if-qa-tests-specified: &if-qa-tests-specified
|
41
|
+
if: '$QA_TESTS != null && $QA_TESTS != ""'
|
42
|
+
|
43
|
+
.if-qa-tests-not-specified: &if-qa-tests-not-specified
|
44
|
+
if: '$QA_TESTS == null || $QA_TESTS == ""'
|
45
|
+
|
40
46
|
#########
|
41
47
|
# Rules #
|
42
48
|
#########
|
@@ -98,3 +104,67 @@
|
|
98
104
|
- <<: *if-set-feature-flag
|
99
105
|
when: never
|
100
106
|
- !reference [".rules:only-qa", rules]
|
107
|
+
|
108
|
+
# === When QA_TESTS variable has a value ===
|
109
|
+
|
110
|
+
.rules:ce-never-when-qa-tests-specified:
|
111
|
+
rules:
|
112
|
+
- <<: *if-qa-tests-specified
|
113
|
+
when: never
|
114
|
+
- !reference [".rules:ce-qa", rules]
|
115
|
+
|
116
|
+
.rules:ee-never-when-qa-tests-specified:
|
117
|
+
rules:
|
118
|
+
- <<: *if-qa-tests-specified
|
119
|
+
when: never
|
120
|
+
- !reference [".rules:ee-qa", rules]
|
121
|
+
|
122
|
+
.rules:ce-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-specified:
|
123
|
+
rules:
|
124
|
+
- <<: *if-qa-tests-specified
|
125
|
+
when: never
|
126
|
+
- !reference [".rules:ce-never-when-triggered-by-feature-flag-definition-change", rules]
|
127
|
+
|
128
|
+
.rules:ee-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-specified:
|
129
|
+
rules:
|
130
|
+
- <<: *if-qa-tests-specified
|
131
|
+
when: never
|
132
|
+
- !reference [".rules:ee-never-when-triggered-by-feature-flag-definition-change", rules]
|
133
|
+
|
134
|
+
.rules:only-qa-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-specified:
|
135
|
+
rules:
|
136
|
+
- <<: *if-qa-tests-specified
|
137
|
+
when: never
|
138
|
+
- !reference [".rules:only-qa-never-when-triggered-by-feature-flag-definition-change", rules]
|
139
|
+
|
140
|
+
# === When QA_TESTS variable does not have a value ===
|
141
|
+
|
142
|
+
.rules:ce-never-when-qa-tests-not-specified:
|
143
|
+
rules:
|
144
|
+
- <<: *if-qa-tests-not-specified
|
145
|
+
when: never
|
146
|
+
- !reference [".rules:ce-qa", rules]
|
147
|
+
|
148
|
+
.rules:ee-never-when-qa-tests-not-specified:
|
149
|
+
rules:
|
150
|
+
- <<: *if-qa-tests-not-specified
|
151
|
+
when: never
|
152
|
+
- !reference [".rules:ee-qa", rules]
|
153
|
+
|
154
|
+
.rules:ce-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-not-specified:
|
155
|
+
rules:
|
156
|
+
- <<: *if-qa-tests-not-specified
|
157
|
+
when: never
|
158
|
+
- !reference [".rules:ce-never-when-triggered-by-feature-flag-definition-change", rules]
|
159
|
+
|
160
|
+
.rules:ee-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-not-specified:
|
161
|
+
rules:
|
162
|
+
- <<: *if-qa-tests-not-specified
|
163
|
+
when: never
|
164
|
+
- !reference [".rules:ee-never-when-triggered-by-feature-flag-definition-change", rules]
|
165
|
+
|
166
|
+
.rules:only-qa-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-not-specified:
|
167
|
+
rules:
|
168
|
+
- <<: *if-qa-tests-not-specified
|
169
|
+
when: never
|
170
|
+
- !reference [".rules:only-qa-never-when-triggered-by-feature-flag-definition-change", rules]
|
data/.gitlab-ci.yml
CHANGED
@@ -46,7 +46,8 @@ variables:
|
|
46
46
|
QA_CAN_TEST_GIT_PROTOCOL_V2: "true"
|
47
47
|
QA_CAN_TEST_PRAEFECT: "false"
|
48
48
|
QA_GENERATE_ALLURE_REPORT: "true"
|
49
|
-
QA_TESTCASES_REPORTING_PROJECT: "gitlab-org/
|
49
|
+
QA_TESTCASES_REPORTING_PROJECT: "gitlab-org/gitlab"
|
50
|
+
QA_TEST_RESULTS_ISSUES_PROJECT: "gitlab-org/quality/testcases"
|
50
51
|
QA_TESTCASE_SESSIONS_PROJECT: "gitlab-org/quality/testcase-sessions"
|
51
52
|
# QA_DEFAULT_BRANCH is the default branch name of the instance under test.
|
52
53
|
QA_DEFAULT_BRANCH: "master"
|
@@ -66,6 +67,7 @@ rspec:
|
|
66
67
|
|
67
68
|
.test:
|
68
69
|
stage: test
|
70
|
+
timeout: 1 hour 30 minutes
|
69
71
|
services:
|
70
72
|
- docker:20.10.5-dind
|
71
73
|
tags:
|
@@ -83,7 +85,7 @@ rspec:
|
|
83
85
|
- bundle exec exe/gitlab-qa ${QA_SCENARIO:=Test::Instance::Image} ${RELEASE:=$DEFAULT_RELEASE} $GITLAB_QA_OPTIONS -- $QA_TESTS $QA_RSPEC_TAGS $RSPEC_REPORT_OPTS || test_run_exit_code=$?
|
84
86
|
- bundle exec exe/gitlab-qa-report --update-screenshot-path "gitlab-qa-run-*/**/rspec-*.xml"
|
85
87
|
- export GITLAB_QA_ACCESS_TOKEN="$GITLAB_QA_PRODUCTION_ACCESS_TOKEN"
|
86
|
-
- if [ "$TOP_UPSTREAM_SOURCE_REF" == $TOP_UPSTREAM_DEFAULT_BRANCH ] || [[ "$TOP_UPSTREAM_SOURCE_JOB" == https://ops.gitlab.net* ]]; then exe/gitlab-qa-report --report-
|
88
|
+
- if [ "$TOP_UPSTREAM_SOURCE_REF" == $TOP_UPSTREAM_DEFAULT_BRANCH ] || [[ "$TOP_UPSTREAM_SOURCE_JOB" == https://ops.gitlab.net* ]]; then exe/gitlab-qa-report --report-results "gitlab-qa-run-*/**/rspec-*.json" --test-case-project "$QA_TESTCASES_REPORTING_PROJECT" --results-issue-project "$QA_TEST_RESULTS_ISSUES_PROJECT" || true; fi
|
87
89
|
- exit $test_run_exit_code
|
88
90
|
|
89
91
|
# For jobs that shouldn't report results in issues, e.g., manually run custom jobs
|
@@ -106,7 +108,7 @@ rspec:
|
|
106
108
|
- bundle exec exe/gitlab-qa Test::Omnibus::Update ${RELEASE:=$DEFAULT_RELEASE} ${RELEASE:=$DEFAULT_RELEASE} $GITLAB_QA_OPTIONS -- $QA_TESTS $QA_RSPEC_TAGS $RSPEC_REPORT_OPTS || test_run_exit_code=$?
|
107
109
|
- bundle exec exe/gitlab-qa-report --update-screenshot-path "gitlab-qa-run-*/**/rspec-*.xml"
|
108
110
|
- export GITLAB_QA_ACCESS_TOKEN="$GITLAB_QA_PRODUCTION_ACCESS_TOKEN"
|
109
|
-
- if [ "$TOP_UPSTREAM_SOURCE_REF" == $TOP_UPSTREAM_DEFAULT_BRANCH ] || [[ "$TOP_UPSTREAM_SOURCE_JOB" == https://ops.gitlab.net* ]]; then exe/gitlab-qa-report --report-
|
111
|
+
- if [ "$TOP_UPSTREAM_SOURCE_REF" == $TOP_UPSTREAM_DEFAULT_BRANCH ] || [[ "$TOP_UPSTREAM_SOURCE_JOB" == https://ops.gitlab.net* ]]; then exe/gitlab-qa-report --report-results "gitlab-qa-run-*/**/rspec-*.json" --test-case-project "$QA_TESTCASES_REPORTING_PROJECT" --results-issue-project "$QA_TEST_RESULTS_ISSUES_PROJECT" || true; fi
|
110
112
|
- exit $test_run_exit_code
|
111
113
|
|
112
114
|
.ce-variables:
|
@@ -187,9 +189,9 @@ ee:custom-parallel:
|
|
187
189
|
allow_failure: true
|
188
190
|
parallel: 10
|
189
191
|
|
190
|
-
ce:instance:
|
192
|
+
ce:instance-parallel:
|
191
193
|
extends:
|
192
|
-
- .rules:ce-qa
|
194
|
+
- .rules:ce-never-when-qa-tests-specified
|
193
195
|
- .test
|
194
196
|
- .high-capacity
|
195
197
|
- .ce-variables
|
@@ -197,6 +199,14 @@ ce:instance:
|
|
197
199
|
- .rspec-report-opts
|
198
200
|
parallel: 5
|
199
201
|
|
202
|
+
ce:instance:
|
203
|
+
extends:
|
204
|
+
- .rules:ce-never-when-qa-tests-not-specified
|
205
|
+
- .test
|
206
|
+
- .high-capacity
|
207
|
+
- .ce-variables
|
208
|
+
- .rspec-report-opts
|
209
|
+
|
200
210
|
ce:instance-quarantine:
|
201
211
|
extends:
|
202
212
|
- .rules:ce-qa
|
@@ -208,9 +218,9 @@ ce:instance-quarantine:
|
|
208
218
|
variables:
|
209
219
|
QA_RSPEC_TAGS: "--tag quarantine --tag ~orchestrated"
|
210
220
|
|
211
|
-
ee:instance:
|
221
|
+
ee:instance-parallel:
|
212
222
|
extends:
|
213
|
-
- .rules:ee-qa
|
223
|
+
- .rules:ee-never-when-qa-tests-specified
|
214
224
|
- .test
|
215
225
|
- .high-capacity
|
216
226
|
- .ee-variables
|
@@ -218,6 +228,14 @@ ee:instance:
|
|
218
228
|
- .rspec-report-opts
|
219
229
|
parallel: 5
|
220
230
|
|
231
|
+
ee:instance:
|
232
|
+
extends:
|
233
|
+
- .rules:ee-never-when-qa-tests-not-specified
|
234
|
+
- .test
|
235
|
+
- .high-capacity
|
236
|
+
- .ee-variables
|
237
|
+
- .rspec-report-opts
|
238
|
+
|
221
239
|
ee:instance-quarantine:
|
222
240
|
extends:
|
223
241
|
- .rules:ee-qa
|
@@ -229,9 +247,9 @@ ee:instance-quarantine:
|
|
229
247
|
variables:
|
230
248
|
QA_RSPEC_TAGS: "--tag quarantine --tag ~orchestrated"
|
231
249
|
|
232
|
-
ce:relative_url:
|
250
|
+
ce:relative_url-parallel:
|
233
251
|
extends:
|
234
|
-
- .rules:ce-never-when-triggered-by-feature-flag-definition-change
|
252
|
+
- .rules:ce-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-specified
|
235
253
|
- .test
|
236
254
|
- .high-capacity
|
237
255
|
- .ce-variables
|
@@ -241,6 +259,16 @@ ce:relative_url:
|
|
241
259
|
variables:
|
242
260
|
QA_SCENARIO: "Test::Instance::RelativeUrl"
|
243
261
|
|
262
|
+
ce:relative_url:
|
263
|
+
extends:
|
264
|
+
- .rules:ce-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-not-specified
|
265
|
+
- .test
|
266
|
+
- .high-capacity
|
267
|
+
- .ce-variables
|
268
|
+
- .rspec-report-opts
|
269
|
+
variables:
|
270
|
+
QA_SCENARIO: "Test::Instance::RelativeUrl"
|
271
|
+
|
244
272
|
ce:relative_url-quarantine:
|
245
273
|
extends:
|
246
274
|
- .rules:ce-never-when-triggered-by-feature-flag-definition-change
|
@@ -253,9 +281,9 @@ ce:relative_url-quarantine:
|
|
253
281
|
QA_SCENARIO: "Test::Instance::RelativeUrl"
|
254
282
|
QA_RSPEC_TAGS: "--tag quarantine --tag ~orchestrated"
|
255
283
|
|
256
|
-
ee:relative_url:
|
284
|
+
ee:relative_url-parallel:
|
257
285
|
extends:
|
258
|
-
- .rules:ee-never-when-triggered-by-feature-flag-definition-change
|
286
|
+
- .rules:ee-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-specified
|
259
287
|
- .test
|
260
288
|
- .high-capacity
|
261
289
|
- .ee-variables
|
@@ -265,6 +293,16 @@ ee:relative_url:
|
|
265
293
|
variables:
|
266
294
|
QA_SCENARIO: "Test::Instance::RelativeUrl"
|
267
295
|
|
296
|
+
ee:relative_url:
|
297
|
+
extends:
|
298
|
+
- .rules:ee-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-not-specified
|
299
|
+
- .test
|
300
|
+
- .high-capacity
|
301
|
+
- .ee-variables
|
302
|
+
- .rspec-report-opts
|
303
|
+
variables:
|
304
|
+
QA_SCENARIO: "Test::Instance::RelativeUrl"
|
305
|
+
|
268
306
|
ee:relative_url-quarantine:
|
269
307
|
extends:
|
270
308
|
- .rules:ee-never-when-triggered-by-feature-flag-definition-change
|
@@ -336,9 +374,9 @@ ee:image:
|
|
336
374
|
- .test
|
337
375
|
- .ee-variables
|
338
376
|
|
339
|
-
ce:update:
|
377
|
+
ce:update-parallel:
|
340
378
|
extends:
|
341
|
-
- .rules:ce-never-when-triggered-by-feature-flag-definition-change
|
379
|
+
- .rules:ce-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-specified
|
342
380
|
- .test
|
343
381
|
- .high-capacity
|
344
382
|
- .ce-variables
|
@@ -347,6 +385,15 @@ ce:update:
|
|
347
385
|
- .update-scenario-script
|
348
386
|
parallel: 5
|
349
387
|
|
388
|
+
ce:update:
|
389
|
+
extends:
|
390
|
+
- .rules:ce-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-not-specified
|
391
|
+
- .test
|
392
|
+
- .high-capacity
|
393
|
+
- .ce-variables
|
394
|
+
- .rspec-report-opts
|
395
|
+
- .update-scenario-script
|
396
|
+
|
350
397
|
ce:update-quarantine:
|
351
398
|
extends:
|
352
399
|
- .rules:ce-never-when-triggered-by-feature-flag-definition-change
|
@@ -359,9 +406,9 @@ ce:update-quarantine:
|
|
359
406
|
variables:
|
360
407
|
QA_RSPEC_TAGS: "--tag quarantine --tag ~orchestrated"
|
361
408
|
|
362
|
-
ee:update:
|
409
|
+
ee:update-parallel:
|
363
410
|
extends:
|
364
|
-
- .rules:ee-never-when-triggered-by-feature-flag-definition-change
|
411
|
+
- .rules:ee-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-specified
|
365
412
|
- .test
|
366
413
|
- .high-capacity
|
367
414
|
- .ee-variables
|
@@ -370,6 +417,15 @@ ee:update:
|
|
370
417
|
- .update-scenario-script
|
371
418
|
parallel: 10
|
372
419
|
|
420
|
+
ee:update:
|
421
|
+
extends:
|
422
|
+
- .rules:ee-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-not-specified
|
423
|
+
- .test
|
424
|
+
- .high-capacity
|
425
|
+
- .ee-variables
|
426
|
+
- .rspec-report-opts
|
427
|
+
- .update-scenario-script
|
428
|
+
|
373
429
|
ee:update-quarantine:
|
374
430
|
extends:
|
375
431
|
- .rules:ee-never-when-triggered-by-feature-flag-definition-change
|
@@ -382,17 +438,26 @@ ee:update-quarantine:
|
|
382
438
|
QA_RSPEC_TAGS: "--tag quarantine --tag ~orchestrated"
|
383
439
|
|
384
440
|
# The Test::Omnibus::Upgrade scenario isn't run on master (because it always uses the latest CE/EE image) so we don't report the test results in issues
|
385
|
-
ce:upgrade:
|
441
|
+
ce:upgrade-parallel:
|
386
442
|
script:
|
387
443
|
- bundle exec exe/gitlab-qa Test::Omnibus::Upgrade CE -- $RSPEC_REPORT_OPTS
|
388
444
|
extends:
|
389
|
-
- .rules:only-qa-never-when-triggered-by-feature-flag-definition-change
|
445
|
+
- .rules:only-qa-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-specified
|
390
446
|
- .test
|
391
447
|
- .high-capacity
|
392
448
|
- .rspec-report-opts
|
393
449
|
- .knapsack-variables
|
394
450
|
parallel: 5
|
395
451
|
|
452
|
+
ce:upgrade:
|
453
|
+
script:
|
454
|
+
- bundle exec exe/gitlab-qa Test::Omnibus::Upgrade CE -- $RSPEC_REPORT_OPTS
|
455
|
+
extends:
|
456
|
+
- .rules:only-qa-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-not-specified
|
457
|
+
- .test
|
458
|
+
- .high-capacity
|
459
|
+
- .rspec-report-opts
|
460
|
+
|
396
461
|
ce:upgrade-quarantine:
|
397
462
|
script:
|
398
463
|
- bundle exec exe/gitlab-qa Test::Omnibus::Upgrade CE -- --tag quarantine --tag ~orchestrated $RSPEC_REPORT_OPTS
|
@@ -464,6 +529,26 @@ ee:mattermost-quarantine:
|
|
464
529
|
variables:
|
465
530
|
QA_SCENARIO: "Test::Integration::Mattermost"
|
466
531
|
|
532
|
+
ce:service_ping_disabled:
|
533
|
+
extends:
|
534
|
+
- .rules:ce-never-when-triggered-by-feature-flag-definition-change
|
535
|
+
- .test
|
536
|
+
- .high-capacity
|
537
|
+
- .ce-variables
|
538
|
+
- .rspec-report-opts
|
539
|
+
variables:
|
540
|
+
QA_SCENARIO: "Test::Integration::ServicePingDisabled"
|
541
|
+
|
542
|
+
ee:service_ping_disabled:
|
543
|
+
extends:
|
544
|
+
- .rules:ee-never-when-triggered-by-feature-flag-definition-change
|
545
|
+
- .test
|
546
|
+
- .high-capacity
|
547
|
+
- .ee-variables
|
548
|
+
- .rspec-report-opts
|
549
|
+
variables:
|
550
|
+
QA_SCENARIO: "Test::Integration::ServicePingDisabled"
|
551
|
+
|
467
552
|
# Disabling geo jobs temporarily due to https://gitlab.com/gitlab-org/gitlab/-/issues/273063
|
468
553
|
# ee:geo:
|
469
554
|
# extends:
|
@@ -920,9 +1005,9 @@ ee:elasticsearch-quarantine:
|
|
920
1005
|
variables:
|
921
1006
|
QA_SCENARIO: "Test::Integration::Elasticsearch"
|
922
1007
|
|
923
|
-
ce:praefect:
|
1008
|
+
ce:praefect-parallel:
|
924
1009
|
extends:
|
925
|
-
- .rules:ce-never-when-triggered-by-feature-flag-definition-change
|
1010
|
+
- .rules:ce-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-specified
|
926
1011
|
- .test
|
927
1012
|
- .high-capacity
|
928
1013
|
- .ce-variables
|
@@ -933,6 +1018,17 @@ ce:praefect:
|
|
933
1018
|
QA_SCENARIO: "Test::Integration::Praefect"
|
934
1019
|
QA_CAN_TEST_PRAEFECT: "true"
|
935
1020
|
|
1021
|
+
ce:praefect:
|
1022
|
+
extends:
|
1023
|
+
- .rules:ce-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-not-specified
|
1024
|
+
- .test
|
1025
|
+
- .high-capacity
|
1026
|
+
- .ce-variables
|
1027
|
+
- .rspec-report-opts
|
1028
|
+
variables:
|
1029
|
+
QA_SCENARIO: "Test::Integration::Praefect"
|
1030
|
+
QA_CAN_TEST_PRAEFECT: "true"
|
1031
|
+
|
936
1032
|
ce:praefect-quarantine:
|
937
1033
|
extends:
|
938
1034
|
- .rules:ce-never-when-triggered-by-feature-flag-definition-change
|
@@ -946,9 +1042,9 @@ ce:praefect-quarantine:
|
|
946
1042
|
QA_CAN_TEST_PRAEFECT: "true"
|
947
1043
|
QA_RSPEC_TAGS: "--tag quarantine --tag ~orchestrated"
|
948
1044
|
|
949
|
-
ee:praefect:
|
1045
|
+
ee:praefect-parallel:
|
950
1046
|
extends:
|
951
|
-
- .rules:ee-never-when-triggered-by-feature-flag-definition-change
|
1047
|
+
- .rules:ee-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-specified
|
952
1048
|
- .test
|
953
1049
|
- .high-capacity
|
954
1050
|
- .ee-variables
|
@@ -959,6 +1055,17 @@ ee:praefect:
|
|
959
1055
|
QA_SCENARIO: "Test::Integration::Praefect"
|
960
1056
|
QA_CAN_TEST_PRAEFECT: "true"
|
961
1057
|
|
1058
|
+
ee:praefect:
|
1059
|
+
extends:
|
1060
|
+
- .rules:ee-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-not-specified
|
1061
|
+
- .test
|
1062
|
+
- .high-capacity
|
1063
|
+
- .ee-variables
|
1064
|
+
- .rspec-report-opts
|
1065
|
+
variables:
|
1066
|
+
QA_SCENARIO: "Test::Integration::Praefect"
|
1067
|
+
QA_CAN_TEST_PRAEFECT: "true"
|
1068
|
+
|
962
1069
|
ee:praefect-quarantine:
|
963
1070
|
extends:
|
964
1071
|
- .rules:ee-never-when-triggered-by-feature-flag-definition-change
|
@@ -981,6 +1088,7 @@ ce:gitaly-cluster:
|
|
981
1088
|
- .rspec-report-opts
|
982
1089
|
variables:
|
983
1090
|
QA_SCENARIO: "Test::Integration::GitalyCluster"
|
1091
|
+
QA_LOG_PATH: "tmp/gitaly_cluster.log"
|
984
1092
|
|
985
1093
|
ce:gitaly-cluster-quarantine:
|
986
1094
|
extends:
|
@@ -992,6 +1100,7 @@ ce:gitaly-cluster-quarantine:
|
|
992
1100
|
- .rspec-report-opts
|
993
1101
|
variables:
|
994
1102
|
QA_SCENARIO: "Test::Integration::GitalyCluster"
|
1103
|
+
QA_LOG_PATH: "tmp/gitaly_cluster.log"
|
995
1104
|
|
996
1105
|
ee:gitaly-cluster:
|
997
1106
|
extends:
|
@@ -1002,6 +1111,7 @@ ee:gitaly-cluster:
|
|
1002
1111
|
- .rspec-report-opts
|
1003
1112
|
variables:
|
1004
1113
|
QA_SCENARIO: "Test::Integration::GitalyCluster"
|
1114
|
+
QA_LOG_PATH: "tmp/gitaly_cluster.log"
|
1005
1115
|
|
1006
1116
|
ee:gitaly-cluster-quarantine:
|
1007
1117
|
extends:
|
@@ -1013,6 +1123,7 @@ ee:gitaly-cluster-quarantine:
|
|
1013
1123
|
- .rspec-report-opts
|
1014
1124
|
variables:
|
1015
1125
|
QA_SCENARIO: "Test::Integration::GitalyCluster"
|
1126
|
+
QA_LOG_PATH: "tmp/gitaly_cluster.log"
|
1016
1127
|
|
1017
1128
|
ce:mtls:
|
1018
1129
|
extends:
|
data/docs/run_qa_against_gdk.md
CHANGED
@@ -49,6 +49,16 @@ make a few changes to your `gdk/gitlab/config/gitlab.yml` file.
|
|
49
49
|
**Note:** The hostname of the URL provided to `gitlab-qa` must match the hostname configured for GDK.
|
50
50
|
If they do not match, a test will be signed out when it visits a page directly because the hostname of the URL visited will be different from the hostname that was used when signing in.
|
51
51
|
|
52
|
+
**Note:** When you log into your GDK instance of GitLab for the first time, the root password requires a change.
|
53
|
+
GitLab QA expects the default initial password to be used in tests; see all default values listed in
|
54
|
+
[Supported GitLab environment variables](what_tests_can_be_run.md#supported-gitlab-environment-variables).
|
55
|
+
If you have changed your root password, you must set the `GITLAB_INITIAL_ROOT_PASSWORD` environment
|
56
|
+
variable.
|
57
|
+
|
58
|
+
```
|
59
|
+
export GITLAB_INITIAL_ROOT_PASSWORD="<GDK root password>"
|
60
|
+
```
|
61
|
+
|
52
62
|
### Running EE tests
|
53
63
|
|
54
64
|
When running EE tests you'll need to have a license available. GitLab engineers can [request a license](https://about.gitlab.com/handbook/developer-onboarding/#working-on-gitlab-ee).
|
@@ -101,7 +111,7 @@ your DNS and point to the IP/port of `dnsdock` application.
|
|
101
111
|
|
102
112
|
### Docker on macOS caveats
|
103
113
|
|
104
|
-
When using OS X Docker, you need to go to Preferences > Advanced and allocate at least **5.0 GB**,
|
114
|
+
When using OS X Docker, you need to go to Preferences > Resources > Advanced and allocate at least **5.0 GB**,
|
105
115
|
otherwise some steps may fail to execute the `chrome-webdriver`.
|
106
116
|
|
107
117
|
When using docker-machine, see [this StackOverflow link for increasing memory](https://stackoverflow.com/questions/32834082/how-to-increase-docker-machine-memory-mac/36982696#36982696).
|
@@ -62,6 +62,7 @@ All environment variables used by GitLab QA should be defined in [`lib/gitlab/qa
|
|
62
62
|
| `QA_ARTIFACTS_DIR` |`/tmp/gitlab-qa`| Path to a directory where artifacts (logs and screenshots) for failing tests will be saved. | No|
|
63
63
|
| `DOCKER_HOST` |`http://localhost`| Docker host to run tests against. | No|
|
64
64
|
| `WEBDRIVER_HEADLESS` |- | When running locally, set to `false` to allow Chrome tests to be visible - watch your tests being run. | No|
|
65
|
+
| `CHROME_DISABLE_DEV_SHM` | `false` | Set to `true` to disable `/dev/shm` usage in Chrome on Linux. | No|
|
65
66
|
| `QA_ADDITIONAL_REPOSITORY_STORAGE` |- | The name of additional, non-default storage to be used with tests tagged `repository_storage`, run via the `Test::Instance::RepositoryStorage` scenario. Note: Admin access is required to change repository storage. | No|
|
66
67
|
| `QA_PRAEFECT_REPOSITORY_STORAGE` |- | The name of repository storage using Praefect. Note: Admin access is required to change repository storage. | No|
|
67
68
|
| `QA_COOKIES` |- | Optionally set to "cookie1=value;cookie2=value" in order to add a cookie to every request. This can be used to set the canary cookie by setting it to "gitlab_canary=true". | No|
|
@@ -107,7 +107,14 @@ module Gitlab
|
|
107
107
|
retry
|
108
108
|
rescue StandardError => e
|
109
109
|
pipeline = QA::Runtime::Env.pipeline_from_project_name
|
110
|
-
channel =
|
110
|
+
channel = case pipeline
|
111
|
+
when "canary"
|
112
|
+
"qa-production"
|
113
|
+
when "staging-canary"
|
114
|
+
"qa-staging"
|
115
|
+
else
|
116
|
+
"qa-#{pipeline}"
|
117
|
+
end
|
111
118
|
error_msg = warn_exception(e)
|
112
119
|
|
113
120
|
return unless QA::Runtime::Env.ci_commit_ref_name == QA::Runtime::Env.default_branch
|
@@ -19,6 +19,7 @@ module Gitlab
|
|
19
19
|
def initialize(max_diff_ratio: DEFAULT_MAX_DIFF_RATIO_FOR_DETECTION, **kwargs)
|
20
20
|
super
|
21
21
|
@max_diff_ratio = max_diff_ratio.to_f
|
22
|
+
@issue_type = 'issue'
|
22
23
|
end
|
23
24
|
|
24
25
|
private
|
@@ -63,7 +64,7 @@ module Gitlab
|
|
63
64
|
puts " => Found issue #{issue.web_url} for test '#{test.name}' with a diff ratio of #{(diff_ratio * 100).round(2)}%."
|
64
65
|
else
|
65
66
|
issue = create_issue(test)
|
66
|
-
puts "
|
67
|
+
puts "for test '#{test.name}'."
|
67
68
|
end
|
68
69
|
|
69
70
|
issue
|
@@ -22,7 +22,7 @@ module Gitlab
|
|
22
22
|
|
23
23
|
private
|
24
24
|
|
25
|
-
attr_reader :gitlab, :files, :project
|
25
|
+
attr_reader :gitlab, :files, :project, :issue_type
|
26
26
|
|
27
27
|
def run!
|
28
28
|
raise NotImplementedError
|
@@ -77,11 +77,18 @@ module Gitlab
|
|
77
77
|
end
|
78
78
|
|
79
79
|
def create_issue(test)
|
80
|
-
gitlab.create_issue(
|
80
|
+
issue = gitlab.create_issue(
|
81
81
|
title: title_from_test(test),
|
82
82
|
description: new_issue_description(test),
|
83
|
-
labels: new_issue_labels(test).to_a
|
83
|
+
labels: new_issue_labels(test).to_a,
|
84
|
+
issue_type: issue_type
|
84
85
|
)
|
86
|
+
|
87
|
+
new_link = issue_type == 'test_case' ? issue.web_url.sub('/issues/', '/quality/test_cases/') : issue.web_url
|
88
|
+
|
89
|
+
puts "Created new #{issue_type}: #{new_link}"
|
90
|
+
|
91
|
+
issue
|
85
92
|
end
|
86
93
|
|
87
94
|
def issue_labels(issue)
|
@@ -111,6 +118,8 @@ module Gitlab
|
|
111
118
|
'found:gitlab.com'
|
112
119
|
when 'canary', 'staging'
|
113
120
|
"found:#{pipeline}.gitlab.com"
|
121
|
+
when 'staging-canary'
|
122
|
+
"found:canary.staging.gitlab.com"
|
114
123
|
when 'preprod'
|
115
124
|
'found:pre.gitlab.com'
|
116
125
|
when 'staging-orchestrated', 'nightly', QA::Runtime::Env.default_branch, 'staging-ref', 'release'
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module QA
|
5
|
+
module Report
|
6
|
+
# Uses the API to create or update GitLab test cases and issues with the results of tests from RSpec report files.
|
7
|
+
class ReportResults < ReportAsIssue
|
8
|
+
# TODO: Remove old_testcase_project_reporter once all test case links are updated to the gitlab project. See https://gitlab.com/gitlab-org/quality/team-tasks/-/issues/1079
|
9
|
+
attr_accessor :testcase_project_reporter, :results_issue_project_reporter, :files, :test_case_project, :results_issue_project, :gitlab, :old_testcase_project_reporter
|
10
|
+
|
11
|
+
def initialize(token:, input_files:, test_case_project:, results_issue_project:, dry_run: false, **kwargs)
|
12
|
+
@testcase_project_reporter = Gitlab::QA::Report::ResultsInTestCases.new(token: token, input_files: input_files, project: test_case_project, dry_run: dry_run, **kwargs)
|
13
|
+
# TODO: Remove the line below once all test case links are updated to the gitlab project. See https://gitlab.com/gitlab-org/quality/team-tasks/-/issues/1079
|
14
|
+
@old_testcase_project_reporter = Gitlab::QA::Report::ResultsInTestCases.new(token: token, input_files: input_files, project: results_issue_project, dry_run: dry_run, **kwargs)
|
15
|
+
@results_issue_project_reporter = Gitlab::QA::Report::ResultsInIssues.new(token: token, input_files: input_files, project: results_issue_project, dry_run: dry_run, **kwargs)
|
16
|
+
@test_case_project = test_case_project
|
17
|
+
@results_issue_project = results_issue_project
|
18
|
+
@files = Array(input_files)
|
19
|
+
@gitlab = testcase_project_reporter.gitlab
|
20
|
+
end
|
21
|
+
|
22
|
+
def assert_project!
|
23
|
+
return if test_case_project && results_issue_project
|
24
|
+
|
25
|
+
abort "Please provide valid project IDs or paths with the `--results-issue-project` and `--test-case-project` options!"
|
26
|
+
end
|
27
|
+
|
28
|
+
def run!
|
29
|
+
puts "Reporting test results in `#{files.join(',')}` as test cases in project `#{test_case_project}`"\
|
30
|
+
" and issues in project `#{results_issue_project}` via the API at `#{Runtime::Env.gitlab_api_base}`."
|
31
|
+
|
32
|
+
test_results_per_file do |test_results|
|
33
|
+
puts "Reporting tests in #{test_results.path}"
|
34
|
+
|
35
|
+
test_results.each do |test|
|
36
|
+
puts "Reporting test: #{test.file} | #{test.name}\n"
|
37
|
+
|
38
|
+
report_test(test) unless test.skipped
|
39
|
+
end
|
40
|
+
|
41
|
+
test_results.write
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def report_test(test)
|
48
|
+
# TODO: Remove the line below and replace correct_testcase_project_reporter with testcase_project_reporter
|
49
|
+
# once all test case links are updated to the gitlab project. See https://gitlab.com/gitlab-org/quality/team-tasks/-/issues/1079
|
50
|
+
correct_testcase_project_reporter = using_old_testcase_link(test) ? old_testcase_project_reporter : testcase_project_reporter
|
51
|
+
|
52
|
+
testcase = correct_testcase_project_reporter.find_or_create_testcase(test)
|
53
|
+
# The API returns the test case with an issue URL since it is technically a type of issue.
|
54
|
+
# This updates the URL to a valid test case link.
|
55
|
+
test.testcase = testcase.web_url.sub('/issues/', '/quality/test_cases/')
|
56
|
+
|
57
|
+
issue, is_new = results_issue_project_reporter.get_related_issue(testcase, test)
|
58
|
+
|
59
|
+
correct_testcase_project_reporter.add_issue_link_to_testcase(testcase, issue, test) if is_new
|
60
|
+
|
61
|
+
correct_testcase_project_reporter.update_testcase(testcase, test)
|
62
|
+
results_issue_project_reporter.update_issue(issue, test)
|
63
|
+
end
|
64
|
+
|
65
|
+
def using_old_testcase_link(test)
|
66
|
+
test.testcase.include?(results_issue_project)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -1,120 +1,62 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'nokogiri'
|
4
|
-
require 'active_support/core_ext/enumerable'
|
5
|
-
|
6
3
|
module Gitlab
|
7
4
|
module QA
|
8
5
|
module Report
|
9
|
-
# Uses the API to create or update GitLab issues with the results of tests from RSpec report files.
|
6
|
+
# Uses the API to create or update GitLab test result issues with the results of tests from RSpec report files.
|
10
7
|
class ResultsInIssues < ReportAsIssue
|
11
|
-
|
12
|
-
|
13
|
-
RESULTS_SECTION_TEMPLATE = "\n\n### DO NOT EDIT BELOW THIS LINE\n\nActive and historical test results:"
|
14
|
-
|
15
|
-
def run!
|
16
|
-
puts "Reporting test results in `#{files.join(',')}` as issues in project `#{project}` via the API at `#{Runtime::Env.gitlab_api_base}`."
|
17
|
-
|
18
|
-
test_results_per_file do |test_results|
|
19
|
-
puts "Reporting tests in #{test_results.path}"
|
8
|
+
include ResultsReporterShared
|
20
9
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
report_test(test) unless test.skipped
|
25
|
-
end
|
26
|
-
|
27
|
-
test_results.write
|
28
|
-
end
|
10
|
+
def initialize(**kwargs)
|
11
|
+
super
|
12
|
+
@issue_type = 'issue'
|
29
13
|
end
|
30
14
|
|
31
|
-
def
|
32
|
-
testcase = find_testcase(test) || create_testcase(test)
|
33
|
-
test.testcase ||= testcase.web_url.sub('/issues/', '/quality/test_cases/')
|
34
|
-
|
15
|
+
def get_related_issue(testcase, test)
|
35
16
|
issue = find_linked_results_issue_by_iid(testcase, test)
|
17
|
+
is_new = false
|
36
18
|
|
37
19
|
if issue
|
38
|
-
issue = update_issue_title(issue, test
|
20
|
+
issue = update_issue_title(issue, test) if issue_title_needs_updating?(issue, test)
|
39
21
|
else
|
40
22
|
puts "No valid issue link found"
|
41
23
|
issue = find_or_create_results_issue(test)
|
42
|
-
|
43
|
-
add_issue_to_testcase(testcase, issue)
|
24
|
+
is_new = true
|
44
25
|
end
|
45
26
|
|
46
|
-
|
47
|
-
update_issue(issue, test)
|
27
|
+
[issue, is_new]
|
48
28
|
end
|
49
29
|
|
50
|
-
def
|
51
|
-
|
30
|
+
def update_issue(issue, test)
|
31
|
+
new_labels = issue_labels(issue)
|
32
|
+
new_labels |= ['Testcase Linked']
|
52
33
|
|
53
|
-
|
54
|
-
|
34
|
+
labels_updated = update_labels(issue, test, new_labels)
|
35
|
+
note_posted = note_status(issue, test)
|
36
|
+
|
37
|
+
if labels_updated || note_posted
|
38
|
+
puts "Issue updated."
|
55
39
|
else
|
56
|
-
|
40
|
+
puts "Test passed, no results issue update needed."
|
57
41
|
end
|
58
|
-
|
59
|
-
testcase
|
60
42
|
end
|
61
43
|
|
62
|
-
|
63
|
-
iid = testcase_iid_from_url(test.testcase)
|
64
|
-
|
65
|
-
return unless iid
|
66
|
-
|
67
|
-
find_issue_by_iid(iid, 'test_case')
|
68
|
-
end
|
44
|
+
private
|
69
45
|
|
70
46
|
def find_linked_results_issue_by_iid(testcase, test)
|
71
47
|
iid = issue_iid_from_testcase(testcase)
|
72
48
|
|
73
49
|
return unless iid
|
74
50
|
|
75
|
-
find_issue_by_iid(iid
|
76
|
-
end
|
77
|
-
|
78
|
-
def find_issue_by_iid(iid, issue_type)
|
79
|
-
issues = gitlab.find_issues(iid: iid) do |issue|
|
80
|
-
issue.state == 'opened' && issue.issue_type == issue_type
|
81
|
-
end
|
82
|
-
|
83
|
-
warn(%(#{issue_type} iid "#{iid}" not valid)) if issues.empty?
|
84
|
-
|
85
|
-
issues.first
|
86
|
-
end
|
87
|
-
|
88
|
-
def update_issue_title(issue, test, issue_type)
|
89
|
-
warn(%(#{issue_type} title needs to be updated from '#{issue.title.strip}' to '#{title_from_test(test)}'))
|
90
|
-
|
91
|
-
gitlab.edit_issue(iid: issue.iid, options: { title: title_from_test(test) })
|
92
|
-
end
|
93
|
-
|
94
|
-
def create_testcase(test)
|
95
|
-
title = title_from_test(test)
|
96
|
-
puts "Creating test case '#{title}' ..."
|
97
|
-
|
98
|
-
gitlab.create_issue(
|
99
|
-
title: title,
|
100
|
-
description: new_testcase_description(test),
|
101
|
-
labels: new_issue_labels(test),
|
102
|
-
issue_type: 'test_case'
|
103
|
-
)
|
104
|
-
end
|
105
|
-
|
106
|
-
def testcase_iid_from_url(url)
|
107
|
-
return warn(%(\nPlease update #{url} to test case url")) if url&.include?('/-/issues/')
|
108
|
-
|
109
|
-
url && url.split('/').last.to_i
|
51
|
+
find_issue_by_iid(iid)
|
110
52
|
end
|
111
53
|
|
112
|
-
def
|
113
|
-
|
54
|
+
def find_or_create_results_issue(test)
|
55
|
+
find_issue(test) || create_issue(test)
|
114
56
|
end
|
115
57
|
|
116
58
|
def issue_iid_from_testcase(testcase)
|
117
|
-
results = testcase.description.partition(
|
59
|
+
results = testcase.description.partition(TEST_CASE_RESULTS_SECTION_TEMPLATE).last if testcase.description.include?(TEST_CASE_RESULTS_SECTION_TEMPLATE)
|
118
60
|
|
119
61
|
return puts "No issue link found" unless results
|
120
62
|
|
@@ -123,66 +65,6 @@ module Gitlab
|
|
123
65
|
issue_iid&.to_i
|
124
66
|
end
|
125
67
|
|
126
|
-
def find_or_create_results_issue(test)
|
127
|
-
issue = find_issue(test, 'issue')
|
128
|
-
|
129
|
-
if issue
|
130
|
-
puts "Found existing issue: #{issue.web_url}"
|
131
|
-
else
|
132
|
-
issue = create_issue(test)
|
133
|
-
puts "Created new issue: #{issue.web_url}"
|
134
|
-
end
|
135
|
-
|
136
|
-
issue
|
137
|
-
end
|
138
|
-
|
139
|
-
def find_issue(test, issue_type)
|
140
|
-
issues = gitlab.find_issues(options: { search: search_term(test) }) do |issue|
|
141
|
-
issue.state == 'opened' && issue.issue_type == issue_type && issue.title.strip == title_from_test(test)
|
142
|
-
end
|
143
|
-
|
144
|
-
warn(%(Too many #{issue_type}s found with the file path "#{test.file}" and name "#{test.name}")) if issues.many?
|
145
|
-
|
146
|
-
issues.first
|
147
|
-
end
|
148
|
-
|
149
|
-
def add_issue_to_testcase(testcase, issue)
|
150
|
-
results_section = testcase.description.include?(RESULTS_SECTION_TEMPLATE) ? '' : RESULTS_SECTION_TEMPLATE
|
151
|
-
|
152
|
-
gitlab.edit_issue(iid: testcase.iid, options: { description: (testcase.description + results_section + "\n\n#{issue.web_url}") })
|
153
|
-
|
154
|
-
puts "Added issue #{issue.web_url} to testcase #{testcase.web_url}"
|
155
|
-
end
|
156
|
-
|
157
|
-
def update_issue(issue, test)
|
158
|
-
new_labels = issue_labels(issue)
|
159
|
-
new_labels |= ['Testcase Linked']
|
160
|
-
|
161
|
-
labels_updated = update_labels(issue, test, new_labels)
|
162
|
-
note_posted = note_status(issue, test)
|
163
|
-
|
164
|
-
if labels_updated || note_posted
|
165
|
-
puts "Issue updated."
|
166
|
-
else
|
167
|
-
puts "Test passed, no update needed."
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
def new_issue_labels(test)
|
172
|
-
['Quality', "devops::#{test.stage}", 'status::automated']
|
173
|
-
end
|
174
|
-
|
175
|
-
def up_to_date_labels(test:, issue: nil, new_labels: Set.new)
|
176
|
-
labels = super
|
177
|
-
labels |= new_issue_labels(test).to_set
|
178
|
-
labels.delete_if { |label| label.start_with?("#{pipeline}::") }
|
179
|
-
labels << (test.failures.empty? ? "#{pipeline}::passed" : "#{pipeline}::failed")
|
180
|
-
end
|
181
|
-
|
182
|
-
def search_term(test)
|
183
|
-
%("#{partial_file_path(test.file)}" "#{search_safe(test.name)}")
|
184
|
-
end
|
185
|
-
|
186
68
|
def note_status(issue, test)
|
187
69
|
return false if test.skipped
|
188
70
|
return false if test.failures.empty?
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module QA
|
5
|
+
module Report
|
6
|
+
# Uses the API to create or update GitLab test cases with the results of tests from RSpec report files.
|
7
|
+
class ResultsInTestCases < ReportAsIssue
|
8
|
+
attr_reader :issue_type, :gitlab
|
9
|
+
|
10
|
+
include ResultsReporterShared
|
11
|
+
|
12
|
+
def initialize(**kwargs)
|
13
|
+
super
|
14
|
+
@issue_type = 'test_case'
|
15
|
+
end
|
16
|
+
|
17
|
+
def find_or_create_testcase(test)
|
18
|
+
find_testcase(test) || create_issue(test)
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_issue_link_to_testcase(testcase, issue, test)
|
22
|
+
results_section = testcase.description.include?(TEST_CASE_RESULTS_SECTION_TEMPLATE) ? '' : TEST_CASE_RESULTS_SECTION_TEMPLATE
|
23
|
+
|
24
|
+
gitlab.edit_issue(iid: testcase.iid, options: { description: (testcase.description + results_section + "\n\n#{issue.web_url}") })
|
25
|
+
# We are using test.testcase for the url here instead of testcase.web_url since it has the updated test case path
|
26
|
+
puts "Added results issue #{issue.web_url} link to test case #{test.testcase}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def update_testcase(testcase, test)
|
30
|
+
puts "Test case labels updated." if update_labels(testcase, test)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def find_testcase(test)
|
36
|
+
testcase = find_testcase_by_iid(test)
|
37
|
+
|
38
|
+
if testcase
|
39
|
+
testcase = update_issue_title(testcase, test) if issue_title_needs_updating?(testcase, test)
|
40
|
+
else
|
41
|
+
testcase = find_issue(test)
|
42
|
+
end
|
43
|
+
|
44
|
+
testcase
|
45
|
+
end
|
46
|
+
|
47
|
+
def find_testcase_by_iid(test)
|
48
|
+
iid = testcase_iid_from_url(test.testcase)
|
49
|
+
|
50
|
+
return unless iid
|
51
|
+
|
52
|
+
find_issue_by_iid(iid)
|
53
|
+
end
|
54
|
+
|
55
|
+
def testcase_iid_from_url(url)
|
56
|
+
return warn(%(\nPlease update #{url} to test case url")) if url&.include?('/-/issues/')
|
57
|
+
|
58
|
+
url && url.split('/').last.to_i
|
59
|
+
end
|
60
|
+
|
61
|
+
def new_issue_description(test)
|
62
|
+
"#{super}#{TEST_CASE_RESULTS_SECTION_TEMPLATE}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/core_ext/enumerable'
|
4
|
+
|
5
|
+
module Gitlab
|
6
|
+
module QA
|
7
|
+
module Report
|
8
|
+
module ResultsReporterShared
|
9
|
+
TEST_CASE_RESULTS_SECTION_TEMPLATE = "\n\n### DO NOT EDIT BELOW THIS LINE\n\nActive and historical test results:"
|
10
|
+
|
11
|
+
def find_issue(test)
|
12
|
+
issues = search_for_issues(test)
|
13
|
+
|
14
|
+
warn(%(Too many #{issue_type}s found with the file path "#{test.file}" and name "#{test.name}")) if issues.many?
|
15
|
+
puts "Found existing #{issue_type}: #{issues.first.web_url}" unless issues.empty?
|
16
|
+
|
17
|
+
issues.first
|
18
|
+
end
|
19
|
+
|
20
|
+
def find_issue_by_iid(iid)
|
21
|
+
issues = gitlab.find_issues(iid: iid) do |issue|
|
22
|
+
issue.state == 'opened' && issue.issue_type == issue_type
|
23
|
+
end
|
24
|
+
|
25
|
+
warn(%(#{issue_type} iid "#{iid}" not valid)) if issues.empty?
|
26
|
+
|
27
|
+
issues.first
|
28
|
+
end
|
29
|
+
|
30
|
+
def issue_title_needs_updating?(issue, test)
|
31
|
+
issue.title.strip != title_from_test(test) && !%w[canary production preprod release].include?(pipeline)
|
32
|
+
end
|
33
|
+
|
34
|
+
def new_issue_labels(test)
|
35
|
+
['Quality', "devops::#{test.stage}", 'status::automated']
|
36
|
+
end
|
37
|
+
|
38
|
+
def search_term(test)
|
39
|
+
%("#{partial_file_path(test.file)}" "#{search_safe(test.name)}")
|
40
|
+
end
|
41
|
+
|
42
|
+
def up_to_date_labels(test:, issue: nil, new_labels: Set.new)
|
43
|
+
labels = super
|
44
|
+
labels |= new_issue_labels(test).to_set
|
45
|
+
labels.delete_if { |label| label.start_with?("#{pipeline}::") }
|
46
|
+
labels << (test.failures.empty? ? "#{pipeline}::passed" : "#{pipeline}::failed")
|
47
|
+
end
|
48
|
+
|
49
|
+
def update_issue_title(issue, test)
|
50
|
+
warn(%(#{issue_type} title needs to be updated from '#{issue.title.strip}' to '#{title_from_test(test)}'))
|
51
|
+
|
52
|
+
gitlab.edit_issue(iid: issue.iid, options: { title: title_from_test(test) })
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def search_for_issues(test)
|
58
|
+
gitlab.find_issues(options: { search: search_term(test) }) do |issue|
|
59
|
+
issue.state == 'opened' && issue.issue_type == issue_type && issue.title.strip == title_from_test(test)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/gitlab/qa/reporter.rb
CHANGED
@@ -17,8 +17,8 @@ module Gitlab
|
|
17
17
|
report_options[:input_files] = files if files
|
18
18
|
end
|
19
19
|
|
20
|
-
opts.on('--report-
|
21
|
-
report_options[:
|
20
|
+
opts.on('--report-results FILES', String, 'Report test results from JUnit XML files in GitLab test cases and results issues') do |files|
|
21
|
+
report_options[:report_results] = true
|
22
22
|
report_options[:input_files] = files if files
|
23
23
|
end
|
24
24
|
|
@@ -31,16 +31,24 @@ module Gitlab
|
|
31
31
|
report_options[:max_diff_ratio] = value
|
32
32
|
end
|
33
33
|
|
34
|
-
opts.on('-p', '--project PROJECT_ID', String, 'A valid project ID. Can be an integer or a group/project string. Required by --
|
34
|
+
opts.on('-p', '--project PROJECT_ID', String, 'A valid project ID. Can be an integer or a group/project string. Required by --relate-failure-issue') do |value|
|
35
35
|
report_options[:project] = value
|
36
36
|
end
|
37
37
|
|
38
|
+
opts.on('--results-issue-project RESULTS_ISSUE_PROJECT_ID', String, 'A valid project ID. Can be an integer or a group/project string. Required by --report-results') do |value|
|
39
|
+
report_options[:results_issue_project] = value
|
40
|
+
end
|
41
|
+
|
42
|
+
opts.on('--test-case-project TEST_CASE_PROJECT_ID', String, 'A valid project ID. Can be an integer or a group/project string. Required by --report-results') do |value|
|
43
|
+
report_options[:test_case_project] = value
|
44
|
+
end
|
45
|
+
|
38
46
|
opts.on('--generate-test-session FILES', String, 'Generate test session report') do |files|
|
39
47
|
report_options[:generate_test_session] = true
|
40
48
|
report_options[:input_files] = files if files
|
41
49
|
end
|
42
50
|
|
43
|
-
opts.on('-t', '--token ACCESS_TOKEN', String, 'A valid access token. Required by --report-
|
51
|
+
opts.on('-t', '--token ACCESS_TOKEN', String, 'A valid access token. Required by --report-results and --relate-failure-issue') do |value|
|
44
52
|
report_options[:token] = value
|
45
53
|
end
|
46
54
|
|
@@ -60,7 +68,7 @@ module Gitlab
|
|
60
68
|
report_options[:files] = files
|
61
69
|
end
|
62
70
|
|
63
|
-
opts.on('--dry-run', "Perform a dry-run (don't create or update issues)") do |files|
|
71
|
+
opts.on('--dry-run', "Perform a dry-run (don't create or update issues or test cases)") do |files|
|
64
72
|
report_options[:dry_run] = true
|
65
73
|
end
|
66
74
|
|
@@ -86,9 +94,9 @@ module Gitlab
|
|
86
94
|
report_options[:token] = Runtime::TokenFinder.find_token!(report_options[:token])
|
87
95
|
Gitlab::QA::Report::RelateFailureIssue.new(**report_options).invoke!
|
88
96
|
|
89
|
-
elsif report_options.delete(:
|
97
|
+
elsif report_options.delete(:report_results)
|
90
98
|
report_options[:token] = Runtime::TokenFinder.find_token!(report_options[:token])
|
91
|
-
Gitlab::QA::Report::
|
99
|
+
Gitlab::QA::Report::ReportResults.new(**report_options).invoke!
|
92
100
|
|
93
101
|
elsif report_options.delete(:generate_test_session)
|
94
102
|
report_options[:token] = Runtime::TokenFinder.find_token!(report_options[:token])
|
@@ -123,7 +123,8 @@ module Gitlab
|
|
123
123
|
'GOOGLE_JSON_KEY' => :google_json_key,
|
124
124
|
'GCS_BUCKET_NAME' => :gcs_bucket_name,
|
125
125
|
'SMOKE_ONLY' => :smoke_only,
|
126
|
-
'NO_ADMIN' => :no_admin
|
126
|
+
'NO_ADMIN' => :no_admin,
|
127
|
+
'CHROME_DISABLE_DEV_SHM' => :chrome_disable_dev_shm
|
127
128
|
}.freeze
|
128
129
|
|
129
130
|
ENV_VARIABLES.each do |env_name, method_name|
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module QA
|
5
|
+
module Scenario
|
6
|
+
module Test
|
7
|
+
module Integration
|
8
|
+
class ServicePingDisabled < Scenario::Template
|
9
|
+
def perform(release, *rspec_args)
|
10
|
+
Component::Gitlab.perform do |gitlab|
|
11
|
+
gitlab.release = release
|
12
|
+
gitlab.network = 'test'
|
13
|
+
|
14
|
+
gitlab.omnibus_configuration << <<~OMNIBUS
|
15
|
+
gitlab_rails['usage_ping_enabled'] = false;
|
16
|
+
OMNIBUS
|
17
|
+
|
18
|
+
gitlab.instance do
|
19
|
+
Component::Specs.perform do |specs|
|
20
|
+
specs.suite = 'Test::Integration::ServicePingDisabled'
|
21
|
+
specs.release = gitlab.release
|
22
|
+
specs.network = gitlab.network
|
23
|
+
specs.args = [gitlab.address, *rspec_args]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/gitlab/qa/version.rb
CHANGED
data/lib/gitlab/qa.rb
CHANGED
@@ -72,6 +72,7 @@ module Gitlab
|
|
72
72
|
autoload :ClientSSL, 'gitlab/qa/scenario/test/integration/client_ssl'
|
73
73
|
autoload :Registry, 'gitlab/qa/scenario/test/integration/registry'
|
74
74
|
autoload :RegistryTLS, 'gitlab/qa/scenario/test/integration/registry_tls'
|
75
|
+
autoload :ServicePingDisabled, 'gitlab/qa/scenario/test/integration/service_ping_disabled'
|
75
76
|
end
|
76
77
|
|
77
78
|
module Sanity
|
@@ -122,7 +123,10 @@ module Gitlab
|
|
122
123
|
autoload :JUnitTestResults, 'gitlab/qa/report/junit_test_results'
|
123
124
|
autoload :PrepareStageReports, 'gitlab/qa/report/prepare_stage_reports'
|
124
125
|
autoload :ReportAsIssue, 'gitlab/qa/report/report_as_issue'
|
126
|
+
autoload :ReportResults, 'gitlab/qa/report/report_results'
|
125
127
|
autoload :ResultsInIssues, 'gitlab/qa/report/results_in_issues'
|
128
|
+
autoload :ResultsInTestCases, 'gitlab/qa/report/results_in_testcases'
|
129
|
+
autoload :ResultsReporterShared, 'gitlab/qa/report/results_reporter_shared'
|
126
130
|
autoload :GenerateTestSession, 'gitlab/qa/report/generate_test_session'
|
127
131
|
autoload :SummaryTable, 'gitlab/qa/report/summary_table'
|
128
132
|
autoload :TestResult, 'gitlab/qa/report/test_result'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gitlab-qa
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 7.
|
4
|
+
version: 7.16.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitLab Quality
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-12-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: climate_control
|
@@ -256,7 +256,10 @@ files:
|
|
256
256
|
- lib/gitlab/qa/report/prepare_stage_reports.rb
|
257
257
|
- lib/gitlab/qa/report/relate_failure_issue.rb
|
258
258
|
- lib/gitlab/qa/report/report_as_issue.rb
|
259
|
+
- lib/gitlab/qa/report/report_results.rb
|
259
260
|
- lib/gitlab/qa/report/results_in_issues.rb
|
261
|
+
- lib/gitlab/qa/report/results_in_testcases.rb
|
262
|
+
- lib/gitlab/qa/report/results_reporter_shared.rb
|
260
263
|
- lib/gitlab/qa/report/summary_table.rb
|
261
264
|
- lib/gitlab/qa/report/test_result.rb
|
262
265
|
- lib/gitlab/qa/report/update_screenshot_path.rb
|
@@ -309,6 +312,7 @@ files:
|
|
309
312
|
- lib/gitlab/qa/scenario/test/integration/registry.rb
|
310
313
|
- lib/gitlab/qa/scenario/test/integration/registry_tls.rb
|
311
314
|
- lib/gitlab/qa/scenario/test/integration/saml.rb
|
315
|
+
- lib/gitlab/qa/scenario/test/integration/service_ping_disabled.rb
|
312
316
|
- lib/gitlab/qa/scenario/test/integration/smtp.rb
|
313
317
|
- lib/gitlab/qa/scenario/test/integration/ssh_tunnel.rb
|
314
318
|
- lib/gitlab/qa/scenario/test/omnibus/image.rb
|