rspec-abq 1.2.1 → 1.2.2
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 +4 -4
- data/lib/rspec/abq/debug_logger.rb +90 -0
- data/lib/rspec/abq/version.rb +1 -1
- data/lib/rspec/abq.rb +26 -13
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 600f920ed258588d3e095996daf8b1b5a8ff67858d0c1df3dea3855740b747a5
|
|
4
|
+
data.tar.gz: a766fe3b12b746d82c9b794a4f2b605d083926b4f39101ba37c3549d422231b8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8d48f7d704adb92e94f140abd282b8f607fc3f537bdcf090d49237392bf011ca465a2b25bcb255f2cf7aa1a0ee84dd077dcfecef41e684aace402444bec3e222
|
|
7
|
+
data.tar.gz: ddf5b9213ea7a18e5b3925ed481dd60df6dfeed7637230e549e3cbb2b54b958268e156e7f5de91cfc6566e81784c99947a98e60892b8bc411bbf2c5be541c1a1
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
module RSpec
|
|
2
|
+
module Abq
|
|
3
|
+
# @!visibility private
|
|
4
|
+
module DebugLogger
|
|
5
|
+
# @!visibility private
|
|
6
|
+
RSPEC_ABQ_DEBUG_LOG_DIR = "RSPEC_ABQ_DEBUG_LOG_DIR"
|
|
7
|
+
|
|
8
|
+
# @!visibility private
|
|
9
|
+
ABQ_RUNNER = "ABQ_RUNNER"
|
|
10
|
+
|
|
11
|
+
class << self
|
|
12
|
+
# @!visibility private
|
|
13
|
+
def enabled?
|
|
14
|
+
ENV.key?(RSPEC_ABQ_DEBUG_LOG_DIR) && !ENV[RSPEC_ABQ_DEBUG_LOG_DIR].to_s.empty?
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# @!visibility private
|
|
18
|
+
def log(message)
|
|
19
|
+
return unless enabled?
|
|
20
|
+
file.puts("[#{timestamp}] #{message}")
|
|
21
|
+
file.flush
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @!visibility private
|
|
25
|
+
def log_start(operation)
|
|
26
|
+
return nil unless enabled?
|
|
27
|
+
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
28
|
+
log("START #{operation}")
|
|
29
|
+
start_time
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# @!visibility private
|
|
33
|
+
def log_end(operation, start_time)
|
|
34
|
+
return unless enabled? && start_time
|
|
35
|
+
elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time
|
|
36
|
+
log("END #{operation} (#{format_duration(elapsed)})")
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# @!visibility private
|
|
40
|
+
def log_operation(operation)
|
|
41
|
+
return yield unless enabled?
|
|
42
|
+
|
|
43
|
+
start_time = log_start(operation)
|
|
44
|
+
begin
|
|
45
|
+
result = yield
|
|
46
|
+
log_end(operation, start_time)
|
|
47
|
+
result
|
|
48
|
+
rescue => e
|
|
49
|
+
log("ERROR #{operation}: #{e.class} - #{e.message}")
|
|
50
|
+
raise
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# @!visibility private
|
|
55
|
+
def close
|
|
56
|
+
return unless @file
|
|
57
|
+
@file.close
|
|
58
|
+
@file = nil
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
def file
|
|
64
|
+
@file ||= begin
|
|
65
|
+
dir = ENV[RSPEC_ABQ_DEBUG_LOG_DIR]
|
|
66
|
+
FileUtils.mkdir_p(dir)
|
|
67
|
+
runner = ENV[ABQ_RUNNER] || "unknown"
|
|
68
|
+
path = File.join(dir, "worker-#{runner}.log")
|
|
69
|
+
File.open(path, "a").tap do |f|
|
|
70
|
+
f.puts("[#{timestamp}] === rspec-abq logger started (pid=#{Process.pid}, runner=#{runner}) ===")
|
|
71
|
+
f.flush
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def timestamp
|
|
77
|
+
Time.now.strftime("%Y-%m-%d %H:%M:%S.%6N")
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def format_duration(seconds)
|
|
81
|
+
if seconds < 1
|
|
82
|
+
"#{(seconds * 1000).round(2)}ms"
|
|
83
|
+
else
|
|
84
|
+
"#{seconds.round(3)}s"
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
data/lib/rspec/abq/version.rb
CHANGED
data/lib/rspec/abq.rb
CHANGED
|
@@ -2,6 +2,8 @@ require "set"
|
|
|
2
2
|
require "rspec/core"
|
|
3
3
|
require "socket"
|
|
4
4
|
require "json"
|
|
5
|
+
require "fileutils"
|
|
6
|
+
require "rspec/abq/debug_logger"
|
|
5
7
|
require "rspec/abq/extensions"
|
|
6
8
|
require "rspec/abq/manifest"
|
|
7
9
|
require "rspec/abq/ordering"
|
|
@@ -145,7 +147,7 @@ module RSpec
|
|
|
145
147
|
# @return [void]
|
|
146
148
|
def self.setup_extensions_if_enabled!
|
|
147
149
|
return unless enabled?
|
|
148
|
-
perform_handshake!
|
|
150
|
+
DebugLogger.log_operation("perform_handshake!") { perform_handshake! }
|
|
149
151
|
Extensions.setup!
|
|
150
152
|
end
|
|
151
153
|
|
|
@@ -213,7 +215,7 @@ module RSpec
|
|
|
213
215
|
# information amongst worker processes. In RSpec, it is used to ensure that random ordering between workers
|
|
214
216
|
# shares the same seed.
|
|
215
217
|
init_message = protocol_read
|
|
216
|
-
protocol_write(INIT_SUCCESS_MESSAGE)
|
|
218
|
+
DebugLogger.log_operation("protocol_write(INIT_SUCCESS_MESSAGE)") { protocol_write(INIT_SUCCESS_MESSAGE) }
|
|
217
219
|
|
|
218
220
|
if init_message["fast_exit"]
|
|
219
221
|
@fast_exit = true
|
|
@@ -234,13 +236,17 @@ module RSpec
|
|
|
234
236
|
# @!visibility private
|
|
235
237
|
def self.socket(connect_timeout: 5)
|
|
236
238
|
@socket ||= begin
|
|
237
|
-
|
|
239
|
+
sock = DebugLogger.log_operation("socket_connect") do
|
|
240
|
+
Socket.tcp(*ENV[ABQ_SOCKET].split(":"), connect_timeout: connect_timeout)
|
|
241
|
+
end
|
|
242
|
+
sock.tap do |socket|
|
|
238
243
|
# Messages sent to/received from the ABQ worker should be done so ASAP.
|
|
239
244
|
# Since we're on a local network, we don't care about packet reduction here.
|
|
240
245
|
socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
|
241
246
|
protocol_write(NATIVE_RUNNER_SPAWNED_MESSAGE, socket)
|
|
242
247
|
end
|
|
243
|
-
rescue
|
|
248
|
+
rescue => e
|
|
249
|
+
DebugLogger.log("socket: connection failed - #{e.class}: #{e.message}")
|
|
244
250
|
raise ConnectionFailed, "Unable to connect to ABQ socket #{ENV[ABQ_SOCKET]}"
|
|
245
251
|
end
|
|
246
252
|
end
|
|
@@ -275,11 +281,16 @@ module RSpec
|
|
|
275
281
|
# @param msg
|
|
276
282
|
def self.protocol_write(msg, socket = Abq.socket)
|
|
277
283
|
json_msg = JSON.dump msg
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
284
|
+
msg_type = msg[:type] || msg["type"] || (msg[:test_result] ? "test_result" : "unknown")
|
|
285
|
+
DebugLogger.log_operation("protocol_write(#{msg_type})") do
|
|
286
|
+
socket.write [json_msg.bytesize].pack("N")
|
|
287
|
+
socket.write json_msg
|
|
288
|
+
end
|
|
289
|
+
rescue SystemCallError, IOError => e
|
|
290
|
+
DebugLogger.log("protocol_write: connection broken - #{e.class}: #{e.message}")
|
|
281
291
|
raise ConnectionBroken
|
|
282
|
-
rescue
|
|
292
|
+
rescue => e
|
|
293
|
+
DebugLogger.log("protocol_write: error - #{e.class}: #{e.message}")
|
|
283
294
|
raise Error
|
|
284
295
|
end
|
|
285
296
|
|
|
@@ -287,18 +298,20 @@ module RSpec
|
|
|
287
298
|
#
|
|
288
299
|
# @param socket [TCPSocket]
|
|
289
300
|
# @return msg
|
|
290
|
-
def self.protocol_read(socket = Abq.socket)
|
|
291
|
-
len_bytes = socket.read 4
|
|
301
|
+
def self.protocol_read(socket = Abq.socket, context: nil)
|
|
302
|
+
len_bytes = DebugLogger.log_operation("protocol_read(#{context || "unknown"}::len)") { socket.read 4 }
|
|
292
303
|
return :abq_done if len_bytes.nil?
|
|
293
304
|
|
|
294
305
|
len = len_bytes.unpack1("N")
|
|
295
|
-
json_msg = socket.read len
|
|
306
|
+
json_msg = DebugLogger.log_operation("protocol_read(#{context || "unknown"}::msg)") { socket.read len }
|
|
296
307
|
return :abq_done if json_msg.nil?
|
|
297
308
|
|
|
298
309
|
JSON.parse json_msg
|
|
299
|
-
rescue SystemCallError, IOError
|
|
310
|
+
rescue SystemCallError, IOError => e
|
|
311
|
+
DebugLogger.log("protocol_read: connection broken - #{e.class}: #{e.message}")
|
|
300
312
|
raise ConnectionBroken
|
|
301
|
-
rescue
|
|
313
|
+
rescue => e
|
|
314
|
+
DebugLogger.log("protocol_read: error - #{e.class}: #{e.message}")
|
|
302
315
|
raise Error
|
|
303
316
|
end
|
|
304
317
|
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.2.
|
|
4
|
+
version: 1.2.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- rwx
|
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date: 2025-
|
|
13
|
+
date: 2025-12-10 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: rspec-core
|
|
@@ -170,6 +170,7 @@ files:
|
|
|
170
170
|
- LICENSE.md
|
|
171
171
|
- README.md
|
|
172
172
|
- lib/rspec/abq.rb
|
|
173
|
+
- lib/rspec/abq/debug_logger.rb
|
|
173
174
|
- lib/rspec/abq/extensions.rb
|
|
174
175
|
- lib/rspec/abq/formatter.rb
|
|
175
176
|
- lib/rspec/abq/manifest.rb
|