gitlab-qa 7.25.0 → 7.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/.gitlab/ci/jobs/actioncable.gitlab-ci.yml +41 -0
  3. data/.gitlab/ci/jobs/base.gitlab-ci.yml +281 -0
  4. data/.gitlab/ci/jobs/cloud_activation.gitlab-ci.yml +30 -0
  5. data/.gitlab/ci/jobs/custom_parallel.gitlab-ci.yml +21 -0
  6. data/.gitlab/ci/jobs/ee_previous_to_ce_update.gitlab-ci.yml +18 -0
  7. data/.gitlab/ci/jobs/elasticsearch.gitlab-ci.yml +20 -0
  8. data/.gitlab/ci/jobs/geo.gitlab-ci.yml +18 -0
  9. data/.gitlab/ci/jobs/gitaly_cluster.gitlab-ci.yml +45 -0
  10. data/.gitlab/ci/jobs/group_saml.gitlab-ci.yml +20 -0
  11. data/.gitlab/ci/jobs/instance.gitlab-ci.yml +55 -0
  12. data/.gitlab/ci/jobs/instance_saml.gitlab-ci.yml +41 -0
  13. data/.gitlab/ci/jobs/integrations.gitlab-ci.yml +14 -0
  14. data/.gitlab/ci/jobs/jira.gitlab-ci.yml +41 -0
  15. data/.gitlab/ci/jobs/large_setup.gitlab-ci.yml +19 -0
  16. data/.gitlab/ci/jobs/ldap_no_server.gitlab-ci.yml +20 -0
  17. data/.gitlab/ci/jobs/ldap_no_tls.gitlab-ci.yml +41 -0
  18. data/.gitlab/ci/jobs/ldap_tls.gitlab-ci.yml +41 -0
  19. data/.gitlab/ci/jobs/mattermost.gitlab-ci.yml +41 -0
  20. data/.gitlab/ci/jobs/mtls.gitlab-ci.yml +17 -0
  21. data/.gitlab/ci/jobs/object_storage.gitlab-ci.yml +49 -0
  22. data/.gitlab/ci/jobs/object_storage_aws.gitlab-ci.yml +25 -0
  23. data/.gitlab/ci/jobs/object_storage_gcs.gitlab-ci.yml +23 -0
  24. data/.gitlab/ci/jobs/object_storage_registry_tls.gitlab-ci.yml +41 -0
  25. data/.gitlab/ci/jobs/omnibus_image.gitlab-ci.yml +15 -0
  26. data/.gitlab/ci/jobs/omnibus_upgrade.gitlab-ci.yml +28 -0
  27. data/.gitlab/ci/jobs/packages.gitlab-ci.yml +25 -0
  28. data/.gitlab/ci/jobs/praefect.gitlab-ci.yml +71 -0
  29. data/.gitlab/ci/jobs/registry.gitlab-ci.yml +41 -0
  30. data/.gitlab/ci/jobs/registry_with_cdn.gitlab-ci.yml +43 -0
  31. data/.gitlab/ci/jobs/relative_url.gitlab-ci.yml +65 -0
  32. data/.gitlab/ci/jobs/repository_storage.gitlab-ci.yml +41 -0
  33. data/.gitlab/ci/jobs/sanity_framework.gitlab-ci.yml +24 -0
  34. data/.gitlab/ci/jobs/service_ping_disabled.gitlab-ci.yml +19 -0
  35. data/.gitlab/ci/jobs/smtp.gitlab-ci.yml +19 -0
  36. data/.gitlab/ci/jobs/staging.gitlab-ci.yml +10 -0
  37. data/.gitlab/ci/jobs/update.gitlab-ci.yml +60 -0
  38. data/.gitlab/issue_templates/Default.md +2 -0
  39. data/.gitlab/merge_request_templates/Default.md +2 -0
  40. data/.gitlab-ci.yml +36 -38
  41. data/bin/notify_upstream +98 -0
  42. data/docs/what_tests_can_be_run.md +2 -0
  43. data/lib/gitlab/qa/component/base.rb +17 -6
  44. data/lib/gitlab/qa/component/gitlab.rb +17 -7
  45. data/lib/gitlab/qa/report/gitlab_issue_client.rb +12 -0
  46. data/lib/gitlab/qa/report/relate_failure_issue.rb +29 -5
  47. data/lib/gitlab/qa/report/test_result.rb +8 -0
  48. data/lib/gitlab/qa/report/update_screenshot_path.rb +28 -6
  49. data/lib/gitlab/qa/runner.rb +7 -0
  50. data/lib/gitlab/qa/runtime/env.rb +1 -1
  51. data/lib/gitlab/qa/runtime/omnibus_configuration.rb +1 -1
  52. data/lib/gitlab/qa/runtime/omnibus_configurations/ci_decomposition.rb +32 -0
  53. data/lib/gitlab/qa/scenario/test/instance/deployment_base.rb +5 -0
  54. data/lib/gitlab/qa/scenario/test/instance/image.rb +3 -1
  55. data/lib/gitlab/qa/scenario/test/integration/geo.rb +2 -1
  56. data/lib/gitlab/qa/scenario/test/integration/gitaly_cluster.rb +2 -0
  57. data/lib/gitlab/qa/scenario/test/integration/mattermost.rb +5 -1
  58. data/lib/gitlab/qa/scenario/test/integration/mtls.rb +1 -0
  59. data/lib/gitlab/qa/scenario/test/omnibus/update.rb +1 -0
  60. data/lib/gitlab/qa/scenario/test/omnibus/upgrade.rb +1 -0
  61. data/lib/gitlab/qa/version.rb +1 -1
  62. data/lib/gitlab/qa.rb +1 -0
  63. data/scripts/generate-qa-jobs.rb +41 -1710
  64. data/support/data/admin_access_token_seed.rb +24 -0
  65. metadata +41 -3
  66. data/bin/notify_upstream_commit +0 -61
@@ -0,0 +1,19 @@
1
+ ce:service_ping_disabled:
2
+ extends:
3
+ - .rules:ce-never-when-triggered-by-feature-flag-definition-change
4
+ - .test
5
+ - .high-capacity
6
+ - .ce-variables
7
+ - .rspec-report-opts
8
+ variables:
9
+ QA_SCENARIO: "Test::Integration::ServicePingDisabled"
10
+
11
+ ee:service_ping_disabled:
12
+ extends:
13
+ - .rules:ee-never-when-triggered-by-feature-flag-definition-change
14
+ - .test
15
+ - .high-capacity
16
+ - .ee-variables
17
+ - .rspec-report-opts
18
+ variables:
19
+ QA_SCENARIO: "Test::Integration::ServicePingDisabled"
@@ -0,0 +1,19 @@
1
+ ce:smtp:
2
+ extends:
3
+ - .rules:ce-never-when-triggered-by-feature-flag-definition-change
4
+ - .test
5
+ - .high-capacity
6
+ - .ce-variables
7
+ - .rspec-report-opts
8
+ variables:
9
+ QA_SCENARIO: "Test::Integration::SMTP"
10
+
11
+ ee:smtp:
12
+ extends:
13
+ - .rules:ee-never-when-triggered-by-feature-flag-definition-change
14
+ - .test
15
+ - .high-capacity
16
+ - .ee-variables
17
+ - .rspec-report-opts
18
+ variables:
19
+ QA_SCENARIO: "Test::Integration::SMTP"
@@ -0,0 +1,10 @@
1
+ staging:
2
+ script:
3
+ - unset EE_LICENSE
4
+ - 'echo "Running: bundle exec exe/gitlab-qa Test::Instance::Staging ${RELEASE:=$DEFAULT_RELEASE} -- $QA_TESTS $QA_RSPEC_TAGS"'
5
+ - bundle exec exe/gitlab-qa Test::Instance::Staging ${RELEASE:=$DEFAULT_RELEASE} -- $QA_TESTS $QA_RSPEC_TAGS
6
+ extends:
7
+ - .rules:only-qa-never-when-triggered-by-feature-flag-definition-change
8
+ - .test
9
+ - .high-capacity
10
+ allow_failure: true
@@ -0,0 +1,60 @@
1
+ ce:update-parallel:
2
+ extends:
3
+ - .rules:ce-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-specified
4
+ - .test
5
+ - .high-capacity
6
+ - .ce-variables
7
+ - .rspec-report-opts
8
+ - .update-scenario-script
9
+ parallel: 5
10
+
11
+ ce:update:
12
+ extends:
13
+ - .rules:ce-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-not-specified
14
+ - .test
15
+ - .high-capacity
16
+ - .ce-variables
17
+ - .rspec-report-opts
18
+ - .update-scenario-script
19
+
20
+ ce:update-quarantine:
21
+ extends:
22
+ - .rules:ce-never-when-triggered-by-feature-flag-definition-change
23
+ - .test
24
+ - .high-capacity
25
+ - .ce-variables
26
+ - .quarantine
27
+ - .rspec-report-opts
28
+ - .update-scenario-script
29
+ variables:
30
+ QA_RSPEC_TAGS: "--tag quarantine --tag ~orchestrated"
31
+
32
+ ee:update-parallel:
33
+ extends:
34
+ - .rules:ee-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-specified
35
+ - .test
36
+ - .high-capacity
37
+ - .ee-variables
38
+ - .rspec-report-opts
39
+ - .update-scenario-script
40
+ parallel: 10
41
+
42
+ ee:update:
43
+ extends:
44
+ - .rules:ee-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-not-specified
45
+ - .test
46
+ - .high-capacity
47
+ - .ee-variables
48
+ - .rspec-report-opts
49
+ - .update-scenario-script
50
+
51
+ ee:update-quarantine:
52
+ extends:
53
+ - .rules:ee-never-when-triggered-by-feature-flag-definition-change
54
+ - .test
55
+ - .high-capacity
56
+ - .ee-variables
57
+ - .quarantine
58
+ - .rspec-report-opts
59
+ variables:
60
+ QA_RSPEC_TAGS: "--tag quarantine --tag ~orchestrated"
@@ -11,3 +11,5 @@ If you feel that your issue can be categorized as a reproducible bug or a featur
11
11
 
12
12
  Thank you for helping to make GitLab a better product.
13
13
  -->
14
+
15
+ <!-- template sourced from https://gitlab.com/gitlab-org/gitlab-qa/-/blob/master/.gitlab/issue_templates/Default.md -->
@@ -44,3 +44,5 @@ This checklist encourages us to confirm any changes have been analyzed to reduce
44
44
  * [ ] I have evaluated the [MR acceptance checklist](https://docs.gitlab.com/ee/development/code_review.html#acceptance-checklist) for this MR.
45
45
 
46
46
  /label ~QA ~Quality
47
+
48
+ <!-- template sourced from https://gitlab.com/gitlab-org/gitlab-qa/-/blob/master/.gitlab/merge_request_templates/Default.md -->
data/.gitlab-ci.yml CHANGED
@@ -49,7 +49,13 @@ prepare:
49
49
  stage: generate
50
50
  extends: .rules:never-on-version-change-or-tag
51
51
  script:
52
- - 'export QA_IMAGE_TAG=${TOP_UPSTREAM_SOURCE_REF:=master} && echo "QA_IMAGE_TAG=$QA_IMAGE_TAG" >> prep_vars.env'
52
+ - |
53
+ if [[ $TOP_UPSTREAM_SOURCE_PROJECT == "gitlab-org/gitlab" && -n $TOP_UPSTREAM_SOURCE_SHA ]]; then
54
+ export QA_IMAGE_TAG=${TOP_UPSTREAM_SOURCE_SHA}
55
+ else
56
+ export QA_IMAGE_TAG=master
57
+ fi
58
+ - 'echo "QA_IMAGE_TAG=$QA_IMAGE_TAG" >> prep_vars.env'
53
59
  - 'echo $QA_IMAGE_TAG'
54
60
  artifacts:
55
61
  reports:
@@ -58,40 +64,6 @@ prepare:
58
64
  - prep_vars.env
59
65
 
60
66
  generate-jobs:
61
- stage: generate
62
- extends: .rules:never-on-version-change-or-tag
63
- script:
64
- # TOP_UPSTREAM_DEFAULT_BRANCH is the default branch name of the original project that triggered a pipeline in this project.
65
- - 'export TOP_UPSTREAM_DEFAULT_BRANCH=${TOP_UPSTREAM_DEFAULT_BRANCH:=master} && echo "TOP_UPSTREAM_DEFAULT_BRANCH=$TOP_UPSTREAM_DEFAULT_BRANCH" >> variables.env'
66
- - 'echo "RELEASE=$RELEASE" >> variables.env'
67
- - 'echo "GITLAB_QA_OPTIONS=$GITLAB_QA_OPTIONS" >> variables.env'
68
- - 'echo "QA_TESTS=$QA_TESTS" >> variables.env'
69
- - 'echo "KNAPSACK_GENERATE_REPORT=$KNAPSACK_GENERATE_REPORT" >> variables.env'
70
- - 'echo "TOP_UPSTREAM_SOURCE_JOB=$TOP_UPSTREAM_SOURCE_JOB" >> variables.env'
71
- - 'echo "TOP_UPSTREAM_SOURCE_REF=$TOP_UPSTREAM_SOURCE_REF" >> variables.env'
72
- - 'echo "DISABLE_RELATING_FAILURE_ISSUES=$DISABLE_RELATING_FAILURE_ISSUES" >> variables.env'
73
- - 'echo "TOP_UPSTREAM_SOURCE_PROJECT=$TOP_UPSTREAM_SOURCE_PROJECT" >> variables.env'
74
- - 'echo "TOP_UPSTREAM_SOURCE_SHA=$TOP_UPSTREAM_SOURCE_SHA" >> variables.env'
75
- - 'echo "NOTIFY_CHANNEL=$NOTIFY_CHANNEL" >> variables.env'
76
- - 'echo "QA_IMAGE=$QA_IMAGE" >> variables.env'
77
- - 'echo "EE_LICENSE=$EE_LICENSE" >> variables.env'
78
- - 'echo "TOP_UPSTREAM_MERGE_REQUEST_IID=$TOP_UPSTREAM_MERGE_REQUEST_IID" >> variables.env'
79
- - 'echo "ALLURE_JOB_NAME=$ALLURE_JOB_NAME" >> variables.env'
80
-
81
- - ./scripts/generate-qa-jobs.rb
82
- - cat generated-qa-jobs.yml
83
- artifacts:
84
- reports:
85
- dotenv: variables.env
86
- paths:
87
- - generated-qa-jobs.yml
88
- - variables.env
89
- expire_in: 2 days
90
- needs:
91
- - job: generate-count-example-files
92
- artifacts: true
93
-
94
- generate-count-example-files:
95
67
  stage: generate
96
68
  extends: .rules:never-on-version-change-or-tag
97
69
  image:
@@ -104,8 +76,9 @@ generate-count-example-files:
104
76
  before_script:
105
77
  - cd /home/gitlab/qa
106
78
  script:
79
+ # Generate count example files
107
80
  - bundle exec bin/qa Test::Instance::All http://dummy.test --count-examples-only -- $QA_TESTS
108
- - bundle exec bin/qa Test::Integration::Mattermost http://dummy.test http://mattermost.test --count-examples-only -- $QA_TESTS
81
+ - bundle exec bin/qa Test::Integration::Mattermost http://dummy.test --mattermost-address http://mattermost.test --count-examples-only -- $QA_TESTS
109
82
  - bundle exec bin/qa Test::Integration::ServicePingDisabled http://dummy.test --count-examples-only -- $QA_TESTS
110
83
  - bundle exec bin/qa QA::EE::Scenario::Test::Geo --count-examples-only --primary-address http://dummy1.test --primary-name gitlab-primary --secondary-address http://dummy2.test --secondary-name gitlab-secondary --without-setup
111
84
  - bundle exec bin/qa Test::Integration::LDAPNoTLS http://dummy.test --count-examples-only -- $QA_TESTS
@@ -127,12 +100,37 @@ generate-count-example-files:
127
100
  - bundle exec bin/qa Test::Instance::All http://dummy.test --count-examples-only -- $QA_TESTS --tag can_use_large_setup
128
101
  - bundle exec bin/qa Test::Instance::All http://dummy.test --count-examples-only -- $QA_TESTS --tag cloud_activation
129
102
  - bundle exec bin/qa Test::Instance::All http://dummy.test --count-examples-only -- $QA_TESTS --tag object_storage
130
-
131
103
  - cp -r no_of_examples $CI_PROJECT_DIR
104
+
105
+ # TOP_UPSTREAM_DEFAULT_BRANCH is the default branch name of the original project that triggered a pipeline in this project.
106
+ - 'export TOP_UPSTREAM_DEFAULT_BRANCH=${TOP_UPSTREAM_DEFAULT_BRANCH:=master} && echo "TOP_UPSTREAM_DEFAULT_BRANCH=$TOP_UPSTREAM_DEFAULT_BRANCH" >> variables.env'
107
+ - 'echo "RELEASE=$RELEASE" >> variables.env'
108
+ - 'echo "GITLAB_QA_OPTIONS=$GITLAB_QA_OPTIONS" >> variables.env'
109
+ - 'echo "QA_TESTS=$QA_TESTS" >> variables.env'
110
+ - 'echo "KNAPSACK_GENERATE_REPORT=$KNAPSACK_GENERATE_REPORT" >> variables.env'
111
+ - 'echo "TOP_UPSTREAM_SOURCE_JOB=$TOP_UPSTREAM_SOURCE_JOB" >> variables.env'
112
+ - 'echo "TOP_UPSTREAM_SOURCE_REF=$TOP_UPSTREAM_SOURCE_REF" >> variables.env'
113
+ - 'echo "DISABLE_RELATING_FAILURE_ISSUES=$DISABLE_RELATING_FAILURE_ISSUES" >> variables.env'
114
+ - 'echo "TOP_UPSTREAM_SOURCE_PROJECT=$TOP_UPSTREAM_SOURCE_PROJECT" >> variables.env'
115
+ - 'echo "TOP_UPSTREAM_SOURCE_SHA=$TOP_UPSTREAM_SOURCE_SHA" >> variables.env'
116
+ - 'echo "NOTIFY_CHANNEL=$NOTIFY_CHANNEL" >> variables.env'
117
+ - 'echo "QA_IMAGE=$QA_IMAGE" >> variables.env'
118
+ - 'echo "EE_LICENSE=$EE_LICENSE" >> variables.env'
119
+ - 'echo "TOP_UPSTREAM_MERGE_REQUEST_IID=$TOP_UPSTREAM_MERGE_REQUEST_IID" >> variables.env'
120
+ - 'echo "ALLURE_JOB_NAME=$ALLURE_JOB_NAME" >> variables.env'
121
+ - mv variables.env $CI_PROJECT_DIR
122
+
123
+ - cd $CI_PROJECT_DIR
124
+ - ./scripts/generate-qa-jobs.rb
125
+ - cat generated-qa-jobs.yml
132
126
  artifacts:
127
+ reports:
128
+ dotenv: variables.env
133
129
  paths:
130
+ - generated-qa-jobs.yml
131
+ - variables.env
134
132
  - no_of_examples
135
- allow_failure: true
133
+ expire_in: 2 days
136
134
 
137
135
  trigger-generated-jobs:
138
136
  stage: triggers
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'gitlab'
5
+
6
+ # Default to "Multi-pipeline (from 'gitlab-org/gitlab-qa' 'notify_upstream:*' jobs)" from current project
7
+ api_token = ENV.fetch('GITLAB_QA_PROJECT_ACCESS_TOKEN') do
8
+ puts "The $GITLAB_BOT_MULTI_PROJECT_PIPELINE_POLLING_TOKEN variable is deprecated in favor of a dedicated project access token: $GITLAB_QA_PROJECT_ACCESS_TOKEN."
9
+ puts "See https://gitlab.com/groups/gitlab-org/quality/-/epics/17 for more details."
10
+ ENV['GITLAB_BOT_MULTI_PROJECT_PIPELINE_POLLING_TOKEN']
11
+ end
12
+
13
+ # Configure credentials to be used with gitlab gem
14
+ Gitlab.configure do |config|
15
+ config.endpoint = 'https://gitlab.com/api/v4'
16
+ config.private_token = api_token
17
+ end
18
+
19
+ class CommitComment
20
+ UPSTREAM_COMMENT = <<~COMMENT
21
+ - The [`gitlab-qa-mirror` downstream pipeline](%<pipeline_url>s) for https://gitlab.com/%<project_path>s/-/merge_requests/%<mr_iid>s/diffs?commit_id=%<commit_sha>s %<status_with_icon>s
22
+ COMMENT
23
+ IDENTIFIABLE_NOTE_TAG = 'gitlab-qa:upstream-notification-note'
24
+
25
+ def self.mr?
26
+ ENV.key?('TOP_UPSTREAM_SOURCE_PROJECT') &&
27
+ ENV.key?('TOP_UPSTREAM_MERGE_REQUEST_IID') &&
28
+ ENV.key?('TOP_UPSTREAM_SOURCE_SHA') &&
29
+ !ENV['TOP_UPSTREAM_SOURCE_PROJECT'].to_s.empty? &&
30
+ !ENV['TOP_UPSTREAM_MERGE_REQUEST_IID'].to_s.empty? &&
31
+ !ENV['TOP_UPSTREAM_SOURCE_SHA'].to_s.empty?
32
+ end
33
+
34
+ def self.post!(status)
35
+ unless mr?
36
+ puts "All the 'TOP_UPSTREAM_SOURCE_PROJECT', 'TOP_UPSTREAM_MERGE_REQUEST_IID', and 'TOP_UPSTREAM_SOURCE_SHA' environment variables need to be present. We cannot post a comment on the upstream merge request."
37
+ return
38
+ end
39
+
40
+ # Look for an existing note
41
+ upstream_notification_note = Gitlab.merge_request_notes(project_path, mr_iid).auto_paginate.find do |note|
42
+ note.body.include?(IDENTIFIABLE_NOTE_TAG)
43
+ end
44
+
45
+ if upstream_notification_note
46
+ Gitlab.edit_merge_request_note(project_path, mr_iid, upstream_notification_note.id, [upstream_notification_note.body, build_comment(status)].join("\n"))
47
+ else
48
+ Gitlab.create_merge_request_comment(project_path, mr_iid, "<!-- #{IDENTIFIABLE_NOTE_TAG} -->\n#{build_comment(status)}")
49
+ end
50
+ rescue Gitlab::Error::Error => error
51
+ puts "Ignoring the following error: #{error}"
52
+ end
53
+
54
+ def self.project_path
55
+ ENV['TOP_UPSTREAM_SOURCE_PROJECT']
56
+ end
57
+
58
+ def self.mr_iid
59
+ ENV['TOP_UPSTREAM_MERGE_REQUEST_IID']
60
+ end
61
+
62
+ def self.pipeline_url
63
+ ENV['CI_PIPELINE_URL']
64
+ end
65
+
66
+ def self.commit_sha
67
+ ENV['TOP_UPSTREAM_SOURCE_SHA']
68
+ end
69
+
70
+ def self.build_comment(status)
71
+ format(UPSTREAM_COMMENT,
72
+ project_path: project_path,
73
+ mr_iid: mr_iid,
74
+ pipeline_url: pipeline_url,
75
+ status_with_icon: status_with_icon(status),
76
+ commit_sha: commit_sha
77
+ )
78
+ end
79
+
80
+ def self.status_with_icon(status)
81
+ case status
82
+ when :success
83
+ "passed. :white_check_mark:"
84
+ when :failure
85
+ "failed! :boom:"
86
+ end
87
+ end
88
+
89
+ def self.post_to_mr(project_id, mr_iid, comment)
90
+ Gitlab.create_merge_request_comment(project_id, mr_iid, comment)
91
+ end
92
+ end
93
+
94
+ status = ARGV.shift.to_s.strip
95
+
96
+ abort "Please provide a status!" if status == ''
97
+
98
+ CommitComment.post!(status.to_sym)
@@ -637,6 +637,8 @@ container is spun up and tests are run from it by running the
637
637
  - `JIRA_ADMIN_USERNAME`: Username for authenticating with Jira server as admin.
638
638
  - `JIRA_ADMIN_PASSWORD`: Password for authenticating with Jira server as admin.
639
639
 
640
+ These values can be found in the shared GitLab QA 1Password vault.
641
+
640
642
  Example:
641
643
 
642
644
  ```
@@ -124,7 +124,6 @@ module Gitlab
124
124
 
125
125
  return unless docker.running?(name)
126
126
 
127
- docker.stop(name)
128
127
  docker.remove(name)
129
128
  end
130
129
 
@@ -147,11 +146,23 @@ module Gitlab
147
146
  end
148
147
 
149
148
  def instance_no_teardown
150
- prepare
151
- start
152
- reconfigure
153
- wait_until_ready
154
- process_exec_commands
149
+ begin
150
+ retries ||= 0
151
+ prepare
152
+ start
153
+ reconfigure
154
+ wait_until_ready
155
+ process_exec_commands
156
+ rescue Docker::Shellout::StatusError => e
157
+ # for scenarios where a service fails during startup, attempt to retry to avoid flaky failures
158
+ if (retries += 1) < 3
159
+ puts "Retry instance_no_teardown due to Docker::Shellout::StatusError -- attempt #{retries}"
160
+ teardown!
161
+ retry
162
+ end
163
+
164
+ raise e
165
+ end
155
166
 
156
167
  yield self if block_given?
157
168
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ # rubocop:disable Metrics/AbcSize
2
3
 
3
4
  require 'securerandom'
4
5
  require 'net/http'
@@ -14,7 +15,7 @@ module Gitlab
14
15
  extend Forwardable
15
16
 
16
17
  attr_reader :release, :omnibus_configuration, :omnibus_gitlab_rails_env
17
- attr_accessor :tls, :skip_availability_check, :runner_network
18
+ attr_accessor :tls, :skip_availability_check, :runner_network, :seed_admin_token, :seed_db
18
19
  attr_writer :name, :relative_path
19
20
 
20
21
  def_delegators :release, :tag, :image, :edition
@@ -42,8 +43,10 @@ module Gitlab
42
43
  @volumes[@gitlab_cert_path] = SSL_PATH
43
44
  @volumes[@authority_cert_path] = TRUSTED_PATH
44
45
 
46
+ @seed_admin_token = Runtime::Scenario.seed_admin_token
47
+ @seed_db = Runtime::Scenario.seed_db
48
+
45
49
  self.release = 'CE'
46
- self.exec_commands += seed_test_data_command if Runtime::Scenario.seed_db
47
50
  end
48
51
 
49
52
  def set_formless_login_token
@@ -154,8 +157,7 @@ module Gitlab
154
157
  @docker.attach(name) do |line, wait|
155
158
  puts line
156
159
  # TODO, workaround which allows to detach from the container
157
- #
158
- break if line =~ /gitlab Reconfigured!/
160
+ break if /gitlab Reconfigured!/.match?(line)
159
161
  end
160
162
  end
161
163
 
@@ -163,7 +165,6 @@ module Gitlab
163
165
  return if skip_availability_check
164
166
 
165
167
  if Availability.new(name, relative_path: relative_path, scheme: scheme, protocol_port: port.to_i).check(Runtime::Env.gitlab_availability_timeout)
166
- sleep 12 # TODO, handle that better
167
168
  puts ' -> GitLab is available.'
168
169
  else
169
170
  abort ' -> GitLab unavailable!'
@@ -171,9 +172,13 @@ module Gitlab
171
172
  end
172
173
 
173
174
  def process_exec_commands
174
- @docker.copy(name, DATA_SEED_PATH, DATA_PATH) if Runtime::Scenario.seed_db
175
+ @docker.copy(name, DATA_SEED_PATH, DATA_PATH) if seed_admin_token || seed_db
176
+
177
+ self.exec_commands += seed_admin_token_command if seed_admin_token
178
+ self.exec_commands += seed_test_data_command if seed_db
175
179
 
176
- exec_commands.each { |command| @docker.exec(name, command) }
180
+ Runtime::Logger.info("Running exec_commands...")
181
+ exec_commands.flatten.uniq.each { |command| @docker.exec(name, command) }
177
182
  end
178
183
 
179
184
  def sha_version
@@ -231,6 +236,10 @@ module Gitlab
231
236
  cmd.uniq
232
237
  end
233
238
 
239
+ def seed_admin_token_command
240
+ ["gitlab-rails runner #{DATA_PATH}/admin_access_token_seed.rb"]
241
+ end
242
+
234
243
  class Availability
235
244
  def initialize(name, relative_path: '', scheme: 'http', protocol_port: 80)
236
245
  @docker = Docker::Engine.new
@@ -276,3 +285,4 @@ module Gitlab
276
285
  end
277
286
  end
278
287
  end
288
+ # rubocop:enable Metrics/AbcSize
@@ -101,6 +101,18 @@ module Gitlab
101
101
  end
102
102
  end
103
103
 
104
+ def upload_file(file_fullpath:)
105
+ ignore_gitlab_client_exceptions do
106
+ Gitlab.upload_file(project, file_fullpath)
107
+ end
108
+ end
109
+
110
+ def ignore_gitlab_client_exceptions
111
+ yield
112
+ rescue StandardError, SystemCallError, OpenSSL::SSL::SSLError, Net::OpenTimeout, Net::ReadTimeout, Gitlab::Error::Error => e
113
+ puts "Ignoring the following error: #{e}"
114
+ end
115
+
104
116
  def handle_gitlab_client_exceptions
105
117
  yield
106
118
  rescue Gitlab::Error::NotFound
@@ -47,7 +47,7 @@ module Gitlab
47
47
  puts " => Searching issues for test '#{test.name}'..."
48
48
 
49
49
  begin
50
- issue = find_and_link_issue(test) || create_issue(test)
50
+ issue = test.quarantine? ? find_and_link_issue(test) : find_and_link_issue(test) || create_issue(test)
51
51
  return unless issue
52
52
 
53
53
  update_labels(issue, test)
@@ -72,6 +72,8 @@ module Gitlab
72
72
  issue = super
73
73
  puts "for test '#{test.name}'."
74
74
 
75
+ post_or_update_failed_job_note(issue, test)
76
+
75
77
  issue
76
78
  end
77
79
 
@@ -82,10 +84,17 @@ module Gitlab
82
84
  end
83
85
  end
84
86
 
87
+ def full_stacktrace(test)
88
+ if test.failures.first['message_lines'].empty?
89
+ test.failures.first['message']
90
+ else
91
+ test.failures.first['message_lines'].join("\n")
92
+ end
93
+ end
94
+
85
95
  def find_relevant_failure_issues(test) # rubocop:disable Metrics/AbcSize
86
96
  ld = Class.new.extend(Gem::Text).method(:levenshtein_distance)
87
- full_stacktrace = test.failures.first['message_lines'].join("\n")
88
- first_test_failure_stacktrace = sanitize_stacktrace(full_stacktrace, FAILURE_STACKTRACE_REGEX) || full_stacktrace
97
+ first_test_failure_stacktrace = sanitize_stacktrace(full_stacktrace(test), FAILURE_STACKTRACE_REGEX) || full_stacktrace(test)
89
98
  clean_first_test_failure_stacktrace = remove_unique_resource_names(first_test_failure_stacktrace)
90
99
 
91
100
  # Search with the `search` param returns 500 errors, so we filter by ~QA and then filter further in Ruby
@@ -156,9 +165,10 @@ module Gitlab
156
165
  def new_issue_description(test)
157
166
  super + [
158
167
  "\n\n### Stack trace",
159
- "```\n#{test.failures.first['message_lines'].join("\n")}\n```",
168
+ "```\n#{full_stacktrace(test)}\n```",
160
169
  "First happened in #{test.ci_job_url}.",
161
- "Related test case: #{test.testcase}."
170
+ "Related test case: #{test.testcase}.",
171
+ screenshot_section(test)
162
172
  ].join("\n\n")
163
173
  end
164
174
 
@@ -194,6 +204,20 @@ module Gitlab
194
204
 
195
205
  false
196
206
  end
207
+
208
+ def screenshot_section(test)
209
+ section = ''
210
+
211
+ failure = full_stacktrace(test)
212
+
213
+ if test.screenshot? && !failure.include?('500 Internal Server Error') && !failure.include?('fabricate_via_api!')
214
+ relative_url = gitlab.upload_file(file_fullpath: test.failure_screenshot)
215
+
216
+ section = "### Screenshot: #{relative_url.markdown}"
217
+ end
218
+
219
+ section
220
+ end
197
221
  end
198
222
  end
199
223
  end
@@ -95,6 +95,14 @@ module Gitlab
95
95
  report['quarantine']['issue'] if quarantine?
96
96
  end
97
97
 
98
+ def screenshot?
99
+ report['screenshot'].present?
100
+ end
101
+
102
+ def failure_screenshot
103
+ report['screenshot']['image'] if screenshot?
104
+ end
105
+
98
106
  private
99
107
 
100
108
  # rubocop:disable Metrics/AbcSize
@@ -1,4 +1,6 @@
1
1
  require 'nokogiri'
2
+ require 'json'
3
+ require 'active_support/core_ext/object/blank'
2
4
 
3
5
  module Gitlab
4
6
  module QA
@@ -9,30 +11,50 @@ module Gitlab
9
11
  end
10
12
 
11
13
  REGEX = %r{(?<gitlab_qa_run>gitlab-qa-run-.*?(?=\/))\/(?<gitlab_ce_ee_qa>gitlab-(ee|ce)-qa-.*?(?=\/))}
14
+ CONTAINER_PATH = File.join(Docker::Volumes::QA_CONTAINER_WORKDIR, 'tmp').freeze
12
15
 
13
16
  def invoke!
14
17
  Dir.glob(@files).each do |rspec_report_file|
15
- report = rewrite_each_screenshot_path(rspec_report_file)
18
+ match_data = rspec_report_file.match(REGEX)
19
+ artifact_path = "#{match_data[:gitlab_qa_run]}/#{match_data[:gitlab_ce_ee_qa]}"
16
20
 
17
- File.write(rspec_report_file, report)
21
+ xml_report = rewrite_each_xml_screenshot_path(rspec_report_file, artifact_path)
22
+
23
+ File.write(rspec_report_file, xml_report)
18
24
 
19
25
  puts "Saved #{rspec_report_file}"
26
+
27
+ json_rspec_report_file = rspec_report_file.gsub('.xml', '.json')
28
+ json_report = rewrite_each_json_screenshot_path(json_rspec_report_file, artifact_path)
29
+
30
+ File.write(json_rspec_report_file, json_report)
31
+
32
+ puts "Saved #{json_rspec_report_file}"
20
33
  end
21
34
  end
22
35
 
23
36
  private
24
37
 
25
- def rewrite_each_screenshot_path(rspec_report_file)
38
+ def rewrite_each_xml_screenshot_path(rspec_report_file, artifact_path)
26
39
  report = Nokogiri::XML(File.open(rspec_report_file))
27
40
 
28
- match_data = rspec_report_file.match(REGEX)
29
-
30
41
  report.xpath('//system-out').each do |system_out|
31
- system_out.content = system_out.content.gsub(File.join(Docker::Volumes::QA_CONTAINER_WORKDIR, 'tmp'), "#{match_data[:gitlab_qa_run]}/#{match_data[:gitlab_ce_ee_qa]}")
42
+ system_out.content = system_out.content.gsub(CONTAINER_PATH, artifact_path)
32
43
  end
33
44
 
34
45
  report.to_s
35
46
  end
47
+
48
+ def rewrite_each_json_screenshot_path(json_rspec_report_file, artifact_path)
49
+ report = JSON.parse(File.read(json_rspec_report_file))
50
+ examples = report['examples']
51
+
52
+ examples.each do |example|
53
+ example['screenshot']['image'] = example['screenshot']['image'].gsub(CONTAINER_PATH, artifact_path) if example['screenshot'].present?
54
+ end
55
+
56
+ JSON.pretty_generate(report)
57
+ end
36
58
  end
37
59
  end
38
60
  end
@@ -13,6 +13,8 @@ module Gitlab
13
13
  Runtime::Scenario.define(:qa_image, Runtime::Env.qa_image) if Runtime::Env.qa_image
14
14
  Runtime::Scenario.define(:omnibus_configuration, Runtime::OmnibusConfiguration.new)
15
15
  Runtime::Scenario.define(:seed_db, false)
16
+ Runtime::Scenario.define(:seed_admin_token, true) # Create an admin access token for root user by default
17
+ Runtime::Scenario.define(:omnibus_exec_commands, [])
16
18
 
17
19
  # Omnibus Configurators specified by flags
18
20
  @active_configurators = []
@@ -31,6 +33,10 @@ module Gitlab
31
33
  Runtime::Scenario.define(:teardown, false)
32
34
  end
33
35
 
36
+ opts.on('--no-admin-token', 'Skip admin token creation for root user') do
37
+ Runtime::Scenario.define(:seed_admin_token, false)
38
+ end
39
+
34
40
  opts.on('--qa-image QA_IMAGE', String, 'Specifies a QA image to be used instead of inferring it from the GitLab image. See Gitlab::QA::Release#qa_image') do |value|
35
41
  Runtime::Scenario.define(:qa_image, value)
36
42
  end
@@ -135,6 +141,7 @@ module Gitlab
135
141
  # # Runtime::OmnibusConfiguration::Packages
136
142
  # gitlab_rails['packages_enabled'] = true
137
143
  Runtime::Scenario.omnibus_configuration << "# #{configurator.class.name}"
144
+ Runtime::Scenario.omnibus_exec_commands << configurator.exec_commands
138
145
 
139
146
  # Load the configuration
140
147
  configurator.configuration.split("\n").each { |c| Runtime::Scenario.omnibus_configuration << c }
@@ -217,7 +217,7 @@ module Gitlab
217
217
  end
218
218
 
219
219
  def elastic_version
220
- env_var_value_if_defined('ELASTIC_VERSION') || '6.4.2'.freeze
220
+ env_var_value_if_defined('ELASTIC_VERSION') || '7.17.0'.freeze
221
221
  end
222
222
 
223
223
  def require_license!
@@ -33,7 +33,7 @@ module Gitlab
33
33
  # @return Any instance of [Gitlab::QA::Component::Base]
34
34
  def prepare; end
35
35
 
36
- # Commands to execute before GitLab boots
36
+ # Commands to execute before tests are run against GitLab (after reconfigure)
37
37
  def exec_commands
38
38
  []
39
39
  end