rspec-abq 1.0.7 → 1.1.1

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: 5b0646cb04737a465bc4d6e970f646467c0c99216dbfea158be227a310d1788f
4
- data.tar.gz: 23433a92ba1b15d82c4466f1deea8702ea5757aa7c01c73e84e85468430b9227
3
+ metadata.gz: 03b2ac40b5bb4d24a54abbaeb06c9e3705641cc27b5c247aa86972bf04095af4
4
+ data.tar.gz: 4d3095d28da6d63731dcd0a64c1c8968033f02155cf0755230e0ebc50854db57
5
5
  SHA512:
6
- metadata.gz: 4034da120d1294a140edc8ac8f96d2f85aba0e0ea14092a8152f43154634b395391bfd04a80c9191cf7ab58c5b7598855628a144d2b4a73ebe9a7b3798f632dc
7
- data.tar.gz: de01483d3b19fc944832eda36f36398dd99cbf41a9cec52c3fb585d8189edeb1546046352db654f87411c6d923209f08820b6ed6eadc4096f20a2f0cd3dab79f
6
+ metadata.gz: 84005f5d7672dcbc96152d183fe5597f3da8da8d29ed88dc9c83ef5dbd6a70bda68c74589aa24e5e7bb191b43f156760cf4a095457a6059ba19adefe1fa86480
7
+ data.tar.gz: 493eb56209f8bc6049883a67122fb1ddc55818d7ef326d8d46cd8d40525a4c8003b92b897d36b10d3e3cc11a13112b0cfce9b50f3a63b36e21115be9eca1044f
@@ -28,28 +28,33 @@ module RSpec
28
28
  def self.abq_result(example)
29
29
  execution_result = example.execution_result
30
30
  tags, meta = Manifest.extract_metadata_and_tags(example.metadata)
31
- {
32
- test_result: {
33
- status: status(example),
34
- id: example.id,
35
- display_name: example.metadata[:full_description],
36
- output: if execution_result.exception
37
- RSpec::Core::Formatters::ExceptionPresenter
38
- .new(execution_result.exception, example)
39
- .fully_formatted(1)
40
- end,
41
- runtime: (execution_result.run_time * 1_000_000_000).round,
42
- tags: tags,
43
- meta: meta,
44
- location: {
45
- file: example.metadata[:file_path],
46
- line: example.metadata[:line_number]
47
- },
48
- started_at: execution_result.started_at.utc.iso8601,
49
- finished_at: execution_result.finished_at.utc.iso8601,
50
- lineage: RSpec::Core::Metadata.ascend(example.metadata).map { |meta| meta[:description] }.reverse
51
- }
31
+ test_result = {
32
+ status: status(example),
33
+ id: example.id,
34
+ display_name: example.metadata[:full_description],
35
+ output: if execution_result.exception
36
+ RSpec::Core::Formatters::ExceptionPresenter
37
+ .new(execution_result.exception, example)
38
+ .fully_formatted(1)
39
+ end,
40
+ runtime: (execution_result.run_time * 1_000_000_000).round,
41
+ tags: tags,
42
+ meta: meta,
43
+ location: {
44
+ file: example.metadata[:file_path],
45
+ line: example.metadata[:line_number]
46
+ },
47
+ started_at: execution_result.started_at.utc.iso8601,
48
+ finished_at: execution_result.finished_at.utc.iso8601,
49
+ lineage: RSpec::Core::Metadata.ascend(example.metadata).map { |meta| meta[:description] }.reverse
52
50
  }
51
+
52
+ past_rspec_retry_attempts = rspec_retry_attempts(example)
53
+ if past_rspec_retry_attempts
54
+ test_result[:past_attempts] = past_rspec_retry_attempts
55
+ end
56
+
57
+ {test_result: test_result}
53
58
  end
54
59
 
55
60
  private_class_method def self.status(example)
@@ -82,6 +87,27 @@ module RSpec
82
87
  end
83
88
  end
84
89
  end
90
+
91
+ private_class_method def self.rspec_retry_attempts(example)
92
+ return unless defined?(RSpec::Retry)
93
+ return unless example.metadata.key?(:retry_attempts)
94
+ return unless example.metadata.key?(:retry_exceptions)
95
+
96
+ retry_attempts = example.metadata[:retry_attempts]
97
+ retry_exceptions = example.metadata[:retry_exceptions]
98
+ return unless retry_attempts > 0
99
+
100
+ retry_attempts.times.map do |attempt_index|
101
+ {
102
+ status: {type: :failure},
103
+ id: example.id,
104
+ display_name: example.metadata[:full_description],
105
+ output: retry_exceptions[attempt_index],
106
+ runtime: 0, # rspec-retry does not expose individual durations
107
+ meta: {} # rspec-retry exposes no other metadata beyond attempt and exceptions
108
+ }
109
+ end
110
+ end
85
111
  end
86
112
  end
87
113
  end
@@ -1,6 +1,6 @@
1
1
  module RSpec
2
2
  module Abq
3
3
  # current version!
4
- VERSION = "1.0.7"
4
+ VERSION = "1.1.1"
5
5
  end
6
6
  end
data/lib/rspec/abq.rb CHANGED
@@ -148,8 +148,20 @@ module RSpec
148
148
  Extensions.setup!
149
149
  end
150
150
 
151
+ # Base ABQ error.
152
+ Error = Class.new(StandardError)
153
+
151
154
  # raised when check_configuration fails
152
- UnsupportedConfigurationError = Class.new(StandardError)
155
+ UnsupportedConfigurationError = Class.new(Error)
156
+
157
+ # Failed to connect and initialize handshake.
158
+ ConnectionFailed = Class.new(Error)
159
+
160
+ # Communication between abq sockets follows the following protocol:
161
+ # - The first 4 bytes an unsigned 32-bit integer (big-endian) representing
162
+ # the size of the rest of the message.
163
+ # - The rest of the message is a JSON-encoded payload.
164
+ ConnectionBroken = Class.new(Error)
153
165
 
154
166
  # raises if RSpec is configured in a way that's incompatible with rspec-abq
155
167
  def self.check_configuration!(config)
@@ -214,12 +226,16 @@ module RSpec
214
226
 
215
227
  # Creates the socket to communicate with the worker and sends the worker the protocol
216
228
  # @!visibility private
217
- def self.socket
218
- @socket ||= TCPSocket.new(*ENV[ABQ_SOCKET].split(":")).tap do |socket|
219
- # Messages sent to/received from the ABQ worker should be done so ASAP.
220
- # Since we're on a local network, we don't care about packet reduction here.
221
- socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
222
- protocol_write(NATIVE_RUNNER_SPAWNED_MESSAGE, socket)
229
+ def self.socket(connect_timeout: 5)
230
+ @socket ||= begin
231
+ Socket.tcp(*ENV[ABQ_SOCKET].split(":"), connect_timeout: connect_timeout).tap do |socket|
232
+ # Messages sent to/received from the ABQ worker should be done so ASAP.
233
+ # Since we're on a local network, we don't care about packet reduction here.
234
+ socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
235
+ protocol_write(NATIVE_RUNNER_SPAWNED_MESSAGE, socket)
236
+ end
237
+ rescue
238
+ raise ConnectionFailed, "Unable to connect to ABQ socket #{ENV[ABQ_SOCKET]}"
223
239
  end
224
240
  end
225
241
 
@@ -245,25 +261,18 @@ module RSpec
245
261
  end
246
262
  end
247
263
 
248
- # Communication between abq sockets follows the following protocol:
249
- # - The first 4 bytes an unsigned 32-bit integer (big-endian) representing
250
- # the size of the rest of the message.
251
- # - The rest of the message is a JSON-encoded payload.
252
- class AbqConnBroken < StandardError
253
- end
254
-
255
264
  # Writes a message to an Abq socket using the 4-byte header protocol.
256
265
  #
257
266
  # @param socket [TCPSocket]
258
267
  # @param msg
259
268
  def self.protocol_write(msg, socket = Abq.socket)
260
269
  json_msg = JSON.dump msg
261
- begin
262
- socket.write [json_msg.bytesize].pack("N")
263
- socket.write json_msg
264
- rescue
265
- raise AbqConnBroken
266
- end
270
+ socket.write [json_msg.bytesize].pack("N")
271
+ socket.write json_msg
272
+ rescue SystemCallError, IOError
273
+ raise ConnectionBroken
274
+ rescue
275
+ raise Error
267
276
  end
268
277
 
269
278
  # Writes a message to an Abq socket using the 4-byte header protocol.
@@ -273,10 +282,16 @@ module RSpec
273
282
  def self.protocol_read(socket = Abq.socket)
274
283
  len_bytes = socket.read 4
275
284
  return :abq_done if len_bytes.nil?
285
+
276
286
  len = len_bytes.unpack1("N")
277
287
  json_msg = socket.read len
278
288
  return :abq_done if json_msg.nil?
289
+
279
290
  JSON.parse json_msg
291
+ rescue SystemCallError, IOError
292
+ raise ConnectionBroken
293
+ rescue
294
+ raise Error
280
295
  end
281
296
  end
282
297
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-abq
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.7
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ayaz Hafiz
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-02-02 00:00:00.000000000 Z
12
+ date: 2023-02-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec-core