gitlab_quality-test_tooling 2.2.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
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