rspec-buildkite-analytics 0.5.0 → 0.7.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: a9fc407bacf4405e3d3e2ee4043a9c71f20d75a363d3ba33948b37403a6e8de4
4
- data.tar.gz: 67f8b42a6ac98518d784eea442fb9efc5a1c8dd5ca0037cc5ce5664b180b75ec
3
+ metadata.gz: 2b1c6bc2713e36242b9d710e348574bd05b8cda4e4d3961742a781256595114f
4
+ data.tar.gz: f221e0f6486ceeb41547a344ec72b47c1385d1ec41689d61aa4e9d9653fa51e3
5
5
  SHA512:
6
- metadata.gz: 6c368891ad4401ac9112a618953686c79b2e69bd33824be1477e3416f99f03233210d80ad3d3a1eccd9b251f595f2b879fd79de0eb1d80193544a6812e8ac0b9
7
- data.tar.gz: 2cf265c336146324d21b06d8c3ec4827848dcb0580ac626d49cd82eaab10ef5101f9398bdad10c118c5dfd42276ed2e70441f8c42b6881a8d68bf6a05da73485
6
+ metadata.gz: a2fd21327c874a8efac7822e995ce9b487029462905ea24ea45aa7e34b89ff2fdf90aec46e1a048fed546ea78192471ce05018546845434821c952f76be36951
7
+ data.tar.gz: 29ca02ed84c008bf2adad2ee75d2d02562d398ef976bf5f00b0c4f30ca3ddb3a4475c7ba1e5d6eb1a7d3de0f6628421dc1b7b83bc902506440d417da4b7a8078
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rspec-buildkite-analytics (0.5.0)
4
+ rspec-buildkite-analytics (0.7.0)
5
5
  activesupport (>= 5.2, <= 7.0)
6
6
  rspec-core (~> 3.10)
7
7
  rspec-expectations (~> 3.10)
@@ -10,17 +10,16 @@ PATH
10
10
  GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
- activesupport (6.1.4.1)
13
+ activesupport (7.0.0)
14
14
  concurrent-ruby (~> 1.0, >= 1.0.2)
15
15
  i18n (>= 1.6, < 2)
16
16
  minitest (>= 5.1)
17
17
  tzinfo (~> 2.0)
18
- zeitwerk (~> 2.3)
19
18
  concurrent-ruby (1.1.9)
20
19
  diff-lcs (1.4.4)
21
- i18n (1.8.11)
20
+ i18n (1.9.1)
22
21
  concurrent-ruby (~> 1.0)
23
- minitest (5.14.4)
22
+ minitest (5.15.0)
24
23
  rake (13.0.6)
25
24
  rspec (3.10.0)
26
25
  rspec-core (~> 3.10.0)
@@ -38,7 +37,6 @@ GEM
38
37
  tzinfo (2.0.4)
39
38
  concurrent-ruby (~> 1.0)
40
39
  websocket (1.2.9)
41
- zeitwerk (2.5.1)
42
40
 
43
41
  PLATFORMS
44
42
  ruby
@@ -14,13 +14,17 @@ module RSpec::Buildkite::Analytics::CI
14
14
  "number" => ENV["BUILDKITE_BUILD_NUMBER"],
15
15
  "job_id" => ENV["BUILDKITE_JOB_ID"],
16
16
  "message" => ENV["BUILDKITE_MESSAGE"],
17
- "debug" => ENV["BUILDKITE_ANALYTICS_DEBUG_ENABLED"]
17
+ "debug" => ENV["BUILDKITE_ANALYTICS_DEBUG_ENABLED"],
18
+ "version" => RSpec::Buildkite::Analytics::VERSION,
19
+ "collector" => RSpec::Buildkite::Analytics::NAME
18
20
  }
19
21
  else
20
22
  {
21
23
  "CI" => nil,
22
24
  "key" => SecureRandom.uuid,
23
- "debug" => ENV["BUILDKITE_ANALYTICS_DEBUG_ENABLED"]
25
+ "debug" => ENV["BUILDKITE_ANALYTICS_DEBUG_ENABLED"],
26
+ "version" => RSpec::Buildkite::Analytics::VERSION,
27
+ "collector" => RSpec::Buildkite::Analytics::NAME
24
28
  }
25
29
  end
26
30
  end
@@ -18,6 +18,7 @@ module RSpec::Buildkite::Analytics
18
18
 
19
19
  if trace
20
20
  trace.example = example
21
+ trace.failure_reason, trace.failure_expanded = failure_info(notification) if example.execution_result.status == :failed
21
22
  RSpec::Buildkite::Analytics.session&.write_result(trace)
22
23
  end
23
24
  end
@@ -45,9 +46,59 @@ module RSpec::Buildkite::Analytics
45
46
  end
46
47
  end
47
48
  end
48
-
49
+
49
50
  alias_method :example_passed, :handle_example
50
51
  alias_method :example_failed, :handle_example
51
52
  alias_method :example_pending, :handle_example
53
+
54
+ private
55
+
56
+ MULTIPLE_ERRORS = [
57
+ RSpec::Expectations::MultipleExpectationsNotMetError,
58
+ RSpec::Core::MultipleExceptionError
59
+ ]
60
+
61
+ def failure_info(notification)
62
+ failure_expanded = []
63
+
64
+ if RSpec::Buildkite::Analytics::Reporter::MULTIPLE_ERRORS.include?(notification.exception.class)
65
+ failure_reason = notification.exception.summary
66
+ notification.exception.all_exceptions.each do |exception|
67
+ # an example with multiple failures doesn't give us a
68
+ # separate message lines and backtrace object to send, so
69
+ # I've reached into RSpec internals and duplicated the
70
+ # construction of these
71
+ message_lines = RSpec::Core::Formatters::ExceptionPresenter.new(exception, notification.example).colorized_message_lines
72
+
73
+ failure_expanded << {
74
+ expanded: format_message_lines(message_lines),
75
+ backtrace: RSpec.configuration.backtrace_formatter.format_backtrace(exception.backtrace)
76
+ }
77
+ end
78
+ else
79
+ message_lines = notification.colorized_message_lines
80
+ failure_reason = strip_diff_colors(message_lines.shift)
81
+
82
+ failure_expanded << {
83
+ expanded: format_message_lines(message_lines),
84
+ backtrace: notification.formatted_backtrace
85
+ }
86
+ end
87
+
88
+ return failure_reason, failure_expanded
89
+ end
90
+
91
+ def format_message_lines(message_lines)
92
+ message_lines.map! { |l| strip_diff_colors(l) }
93
+ # the first line is sometimes blank, depending on the error reported
94
+ message_lines.shift if message_lines.first.blank?
95
+ # the last line is sometimes blank, depending on the error reported
96
+ message_lines.pop if message_lines.last.blank?
97
+ message_lines
98
+ end
99
+
100
+ def strip_diff_colors(string)
101
+ string.gsub(/\e\[([;\d]+)?m/, '')
102
+ end
52
103
  end
53
104
  end
@@ -52,9 +52,22 @@ module RSpec::Buildkite::Analytics
52
52
 
53
53
  @logger = Logger.new
54
54
 
55
- connect
56
- rescue TimeoutError, InitialConnectionFailure => e
57
- $stderr.puts "rspec-buildkite-analytics could not establish an initial connection with Buildkite due to #{e.message}. You may be missing some data for this test suite, please contact support."
55
+ reconnection_count = 0
56
+
57
+ begin
58
+ reconnection_count += 1
59
+ connect
60
+ rescue TimeoutError, InitialConnectionFailure => e
61
+ @logger.write("rspec-buildkite-analytics could not establish an initial connection with Buildkite due to #{e}. Attempting retry #{reconnection_count} of #{MAX_RECONNECTION_ATTEMPTS}...")
62
+ if reconnection_count > MAX_RECONNECTION_ATTEMPTS
63
+ $stderr.puts "rspec-buildkite-analytics could not establish an initial connection with Buildkite due to #{e.message} after #{MAX_RECONNECTION_ATTEMPTS} attempts. You may be missing some data for this test suite, please contact support if this issue persists."
64
+ else
65
+ sleep(WAIT_BETWEEN_RECONNECTIONS)
66
+ @logger.write("retrying reconnection")
67
+ retry
68
+ end
69
+ end
70
+ init_write_thread
58
71
  end
59
72
 
60
73
  def disconnected(connection)
@@ -76,7 +89,8 @@ module RSpec::Buildkite::Analytics
76
89
  begin
77
90
  reconnection_count += 1
78
91
  connect
79
- rescue SocketConnection::HandshakeError, RejectedSubscription, TimeoutError, SocketConnection::SocketError => e
92
+ init_write_thread
93
+ rescue SocketConnection::HandshakeError, RejectedSubscription, TimeoutError, InitialConnectionFailure, SocketConnection::SocketError => e
80
94
  @logger.write("failed reconnection attempt #{reconnection_count} due to #{e}")
81
95
  if reconnection_count > MAX_RECONNECTION_ATTEMPTS
82
96
  $stderr.puts "rspec-buildkite-analytics experienced a disconnection and could not reconnect to Buildkite due to #{e.message}. Please contact support."
@@ -170,8 +184,10 @@ module RSpec::Buildkite::Analytics
170
184
  wait_for_confirm
171
185
 
172
186
  @logger.write("connected")
187
+ end
173
188
 
174
- # As this connect method can be called multiple times in the
189
+ def init_write_thread
190
+ # As this method can be called multiple times in the
175
191
  # reconnection process, kill prev write threads (if any) before
176
192
  # setting up the new one
177
193
  @write_thread&.kill
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_support/core_ext/hash/indifferent_access"
4
+
3
5
  module RSpec::Buildkite::Analytics
4
6
  class Tracer
5
7
  class Span
@@ -22,22 +22,15 @@ require "securerandom"
22
22
  module RSpec::Buildkite::Analytics
23
23
  class Uploader
24
24
  class Trace
25
- attr_accessor :example
25
+ attr_accessor :example, :failure_reason, :failure_expanded
26
26
  attr_reader :id, :history
27
27
 
28
28
  def initialize(example, history)
29
29
  @id = SecureRandom.uuid
30
30
  @example = example
31
31
  @history = history
32
- end
33
-
34
- def failure_message
35
- case example.exception
36
- when RSpec::Expectations::ExpectationNotMetError
37
- example.exception.message
38
- when Exception
39
- "#{example.exception.class}: #{example.exception.message}"
40
- end
32
+ @failure_reason = nil
33
+ @failure_expanded = []
41
34
  end
42
35
 
43
36
  def result_state
@@ -57,9 +50,10 @@ module RSpec::Buildkite::Analytics
57
50
  location: example.location,
58
51
  file_name: generate_file_name(example),
59
52
  result: result_state,
60
- failure: failure_message,
53
+ failure_reason: failure_reason,
54
+ failure_expanded: failure_expanded,
61
55
  history: history,
62
- }.with_indifferent_access
56
+ }.with_indifferent_access.compact
63
57
  end
64
58
 
65
59
  private
@@ -121,7 +115,8 @@ module RSpec::Buildkite::Analytics
121
115
  "Content-Type" => "application/json",
122
116
  })
123
117
  contact.body = {
124
- run_env: CI.env
118
+ run_env: CI.env,
119
+ format: "websocket"
125
120
  }.to_json
126
121
 
127
122
  response = begin
@@ -130,6 +125,8 @@ module RSpec::Buildkite::Analytics
130
125
  puts "Buildkite Test Analytics: Error communicating with the server: #{e.message}"
131
126
  end
132
127
 
128
+ return unless response
129
+
133
130
  case response.code
134
131
  when "401"
135
132
  puts "Buildkite Test Analytics: Invalid Suite API key. Please double check your Suite API key."
@@ -3,7 +3,8 @@
3
3
  module RSpec
4
4
  module Buildkite
5
5
  module Analytics
6
- VERSION = "0.5.0"
6
+ VERSION = "0.7.0"
7
+ NAME = "rspec-buildkite"
7
8
  end
8
9
  end
9
10
  end
@@ -30,4 +30,10 @@ module RSpec::Buildkite::Analytics
30
30
 
31
31
  self::Uploader.configure
32
32
  end
33
+
34
+ def self.annotate(content)
35
+ tracer = RSpec::Buildkite::Analytics::Uploader.tracer
36
+ tracer&.enter("annotation", **{ content: content })
37
+ tracer&.leave
38
+ end
33
39
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-buildkite-analytics
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Buildkite
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-30 00:00:00.000000000 Z
11
+ date: 2022-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -72,7 +72,7 @@ dependencies:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
74
  version: '1.2'
75
- description:
75
+ description:
76
76
  email:
77
77
  - hello@buildkite.com
78
78
  executables: []
@@ -106,7 +106,7 @@ licenses:
106
106
  metadata:
107
107
  homepage_uri: https://github.com/buildkite/rspec-buildkite-analytics
108
108
  source_code_uri: https://github.com/buildkite/rspec-buildkite-analytics
109
- post_install_message:
109
+ post_install_message:
110
110
  rdoc_options: []
111
111
  require_paths:
112
112
  - lib
@@ -122,7 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
122
122
  version: '0'
123
123
  requirements: []
124
124
  rubygems_version: 3.1.4
125
- signing_key:
125
+ signing_key:
126
126
  specification_version: 4
127
127
  summary: Track execution of specs and report to Buildkite Analytics
128
128
  test_files: []