gitlab_quality-test_tooling 2.2.0 → 2.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7437a045ff423ca3c6585be2aa13b11d97fd94abb5d8ffd95a14d11f48970b68
4
- data.tar.gz: fd91b826d48c661a7b05f196857ec95c7fc59d478e8718ffa9ca5d534f38ffe5
3
+ metadata.gz: 8d991bf33f977c242a64aeaef438f73085f6aeaf7575674ace10a36ea62484be
4
+ data.tar.gz: 7e2b37d11e14b21d2acb9b8bcd49094331d0fd06e799cf041a494413295367d3
5
5
  SHA512:
6
- metadata.gz: 4de31f3a187af7c92df5b015c631e5fa1278fa6a3d62f8111294ce07c245236b9e30e78a6760859eee4d024ee0de62dd544201e2d3e4beec73ef7be00f443def
7
- data.tar.gz: 1d44821f07f2d61ac2d1b31b0837149bcf015070ffa1c4e6791d4685c3be322ab0991a28bf1551130eaf274045d58855a405b680948673f78aa208c9a34cab77
6
+ metadata.gz: d73508a586cacef8d59d4e40d39ae198d61f22b900f0995705ddf5753467b23676eb71adb90b08e4a9064aa94f250edb78665dd371edef1e735f36e57ccbc547
7
+ data.tar.gz: f858ca470f52e7b5dfe86e49016f5f45ab19132c3946ea5f3d9c445ca739da336bfa5ee0d36fab79d88b8d6d26af5392812cef400a75b52cd9dc9a3081d06627
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gitlab_quality-test_tooling (2.2.0)
4
+ gitlab_quality-test_tooling (2.4.0)
5
5
  activesupport (>= 7.0, < 7.2)
6
6
  amatch (~> 0.4.1)
7
7
  fog-google (~> 1.24, >= 1.24.1)
data/README.md CHANGED
@@ -191,6 +191,16 @@ Usage: exe/existing-test-health-issue [options]
191
191
  -h, --help Show the usage
192
192
  ```
193
193
 
194
+ ### `exe/detect-infrastructure-failures`
195
+
196
+ ```shell
197
+ Purpose: Checks wether a job failed on a known infrastructure error by parsing its trace.
198
+ Usage: exe/detect-infrastructure-failures [options]
199
+ -j, --job-id JOB_ID A valid Job ID
200
+ -p, --project PROJECT Can be an integer or a group/project string
201
+ -t, --token TOKEN A valid access token with `api` scope and Maintainer permission in PROJECT
202
+ ```
203
+
194
204
  ### `exe/flaky-test-issues`
195
205
 
196
206
  ```shell
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "optparse"
6
+
7
+ require_relative "../lib/gitlab_quality/test_tooling"
8
+
9
+ params = {}
10
+
11
+ OptionParser.new do |opts|
12
+ opts.banner = "Usage: #{$PROGRAM_NAME} [options]"
13
+
14
+ opts.on('-j', '--job-id JOB_ID', String, 'A valid job ID') do |job_id|
15
+ params[:job_id] = job_id
16
+ end
17
+
18
+ opts.on('-p', '--project PROJECT', String, 'Can be an integer or a group/project string') do |project|
19
+ params[:project] = project
20
+ end
21
+
22
+ opts.on('-t', '--token TOKEN', String, 'A valid access token with `api` scope and Maintainer permission in PROJECT') do |token|
23
+ params[:token] = token
24
+ end
25
+
26
+ opts.parse(ARGV)
27
+ end
28
+
29
+ raise ArgumentError, "Missing argument(s). Required arguments are: --job-id, --project, --token" if params.empty? || ([:job_id, :project, :token] - params.keys).any?
30
+
31
+ exit GitlabQuality::TestTooling::JobTraceAnalyzer.new(**params).found_infrastructure_error? ? 0 : 1
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'gitlab'
4
+
5
+ module GitlabQuality
6
+ module TestTooling
7
+ module GitlabClient
8
+ class JobClient < GitlabClient
9
+ attr_reader :job_id
10
+
11
+ def initialize(token:, project:, job_id:)
12
+ super
13
+
14
+ @job_id = job_id
15
+ end
16
+
17
+ def job_trace
18
+ trace = ''
19
+
20
+ ignore_gitlab_client_exceptions do
21
+ trace = client.job_trace(project, job_id)
22
+ end
23
+
24
+ trace
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'gitlab_client/job_client'
4
+
5
+ module GitlabQuality
6
+ module TestTooling
7
+ class JobTraceAnalyzer
8
+ attr_reader :project, :token, :job_id
9
+
10
+ FailureTraceDefinition = Struct.new(:type, :trace_start, :trace_end, :language, :label, keyword_init: true)
11
+ FAILURE_TRACE_DEFINITIONS = [
12
+ FailureTraceDefinition.new(
13
+ type: :rspec,
14
+ trace_start: "Failures:\n",
15
+ trace_end: "[TEST PROF INFO]",
16
+ language: :ruby,
17
+ label: '~backend'
18
+ ),
19
+ FailureTraceDefinition.new(
20
+ type: :jest,
21
+ trace_start: "Summary of all failing tests\n",
22
+ trace_end: "\nRan all test suites.",
23
+ language: :javascript,
24
+ label: '~frontend'
25
+ ),
26
+ FailureTraceDefinition.new(
27
+ type: :workhorse,
28
+ trace_start: "make: Entering directory '/builds/gitlab-org/gitlab/workhorse'",
29
+ trace_end: "make: Leaving directory '/builds/gitlab-org/gitlab/workhorse'",
30
+ language: :go,
31
+ label: '~workhorse'
32
+ ),
33
+ FailureTraceDefinition.new(
34
+ type: :rubocop,
35
+ trace_start: "Running RuboCop in graceful mode:",
36
+ trace_end: "section_end",
37
+ language: :ruby,
38
+ label: '~backend'
39
+ )
40
+ ].freeze
41
+
42
+ TRANSIENT_ROOT_CAUSE_TO_TRACE_MAP =
43
+ {
44
+ failed_to_pull_image: ['job failed: failed to pull image'],
45
+ gitlab_com_overloaded: ['gitlab is currently unable to handle this request due to load'],
46
+ runner_disk_full: [
47
+ 'no space left on device',
48
+ 'Check free disk space'
49
+ ],
50
+ job_timeout: [
51
+ 'ERROR: Job failed: execution took longer than',
52
+ 'Rspec suite is exceeding the 80 minute limit and is forced to exit with error'
53
+ ],
54
+ gitaly: ['gitaly spawn failed'],
55
+ infrastructure: [
56
+ 'the requested url returned error: 5', # any 5XX error code should be transient
57
+ 'error: downloading artifacts from coordinator',
58
+ 'error: uploading artifacts as "archive" to coordinator',
59
+ '500 Internal Server Error',
60
+ "Internal Server Error 500",
61
+ '502 Bad Gateway',
62
+ '503 Service Unavailable',
63
+ 'Error: EEXIST: file already exists',
64
+ 'Failed to connect to 127.0.0.1',
65
+ "Failed to open TCP connection to",
66
+ 'connection reset by peer',
67
+ 'segmentation fault',
68
+ 'no space left on device',
69
+ 'Check free disk space',
70
+ 'CLUSTERDOWN'
71
+ ],
72
+ flaky_test: [
73
+ "We have detected a PG::QueryCanceled error in the specs, so we're failing early"
74
+ ]
75
+ }.freeze
76
+
77
+ AFTER_SCRIPT_TRACE_START_MARKER = 'Running after_script'
78
+
79
+ def initialize(project:, token:, job_id:)
80
+ @project = project
81
+ @token = token
82
+ @job_id = job_id
83
+ end
84
+
85
+ def found_infrastructure_error?
86
+ trace_to_search = failure_summary || main_trace
87
+
88
+ TRANSIENT_ROOT_CAUSE_TO_TRACE_MAP[:infrastructure].any? do |search_string|
89
+ found = trace_to_search.downcase.include?(search_string.downcase)
90
+
91
+ puts "Found infrastructure error stacktrace: #{search_string}" if found
92
+
93
+ found
94
+ end
95
+ end
96
+
97
+ private
98
+
99
+ def detected_failure_trace_definition
100
+ return @detected_failure_trace_definition if defined?(@detected_failure_trace_definition)
101
+
102
+ @detected_failure_trace_definition = FAILURE_TRACE_DEFINITIONS.find do |failure_trace_definition|
103
+ job_trace.include?(failure_trace_definition.trace_start) &&
104
+ job_trace.include?(failure_trace_definition.trace_end)
105
+ end
106
+ end
107
+
108
+ def job_trace
109
+ @job_trace ||= GitlabClient::JobClient.new(project: project, token: token, job_id: job_id).job_trace
110
+ end
111
+
112
+ def main_trace
113
+ return job_trace unless job_trace.include?(AFTER_SCRIPT_TRACE_START_MARKER)
114
+
115
+ job_trace.split(AFTER_SCRIPT_TRACE_START_MARKER).first
116
+ end
117
+
118
+ def failure_summary
119
+ return unless detected_failure_trace_definition
120
+
121
+ @failure_summary ||= main_trace
122
+ .split(detected_failure_trace_definition.trace_start)
123
+ .last
124
+ .split(detected_failure_trace_definition.trace_end)
125
+ .first
126
+ .chomp
127
+ end
128
+ end
129
+ end
130
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module GitlabQuality
4
4
  module TestTooling
5
- VERSION = "2.2.0"
5
+ VERSION = "2.4.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitlab_quality-test_tooling
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.4.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: 2024-11-20 00:00:00.000000000 Z
11
+ date: 2024-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: climate_control
@@ -414,6 +414,7 @@ description: A collection of test-related tools.
414
414
  email:
415
415
  - quality@gitlab.com
416
416
  executables:
417
+ - detect-infrastructure-failures
417
418
  - existing-test-health-issue
418
419
  - failed-test-issues
419
420
  - flaky-test-issues
@@ -444,6 +445,7 @@ files:
444
445
  - LICENSE.txt
445
446
  - README.md
446
447
  - Rakefile
448
+ - exe/detect-infrastructure-failures
447
449
  - exe/existing-test-health-issue
448
450
  - exe/failed-test-issues
449
451
  - exe/flaky-test-issues
@@ -468,10 +470,12 @@ files:
468
470
  - lib/gitlab_quality/test_tooling/gitlab_client/gitlab_client.rb
469
471
  - lib/gitlab_quality/test_tooling/gitlab_client/issues_client.rb
470
472
  - lib/gitlab_quality/test_tooling/gitlab_client/issues_dry_client.rb
473
+ - lib/gitlab_quality/test_tooling/gitlab_client/job_client.rb
471
474
  - lib/gitlab_quality/test_tooling/gitlab_client/jobs_client.rb
472
475
  - lib/gitlab_quality/test_tooling/gitlab_client/merge_requests_client.rb
473
476
  - lib/gitlab_quality/test_tooling/gitlab_client/merge_requests_dry_client.rb
474
477
  - lib/gitlab_quality/test_tooling/gitlab_client/repository_files_client.rb
478
+ - lib/gitlab_quality/test_tooling/job_trace_analyzer.rb
475
479
  - lib/gitlab_quality/test_tooling/knapsack_reports/spec_run_time.rb
476
480
  - lib/gitlab_quality/test_tooling/knapsack_reports/spec_run_time_report.rb
477
481
  - lib/gitlab_quality/test_tooling/labels_inference.rb