bitfab 0.12.1 → 0.12.3

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: '08c78bc5383ea19b2bb2cb289ede12e22ede81afaaf13d9500fe7ca49ac6408e'
4
- data.tar.gz: 3c193f89a4843aaea5ec3c00d9e5b5410b787d802256b28ff3ca0eaa1c5d8e1c
3
+ metadata.gz: 0f676920e42d9a98a73b84a843a5592159d9e93d85f72d4248703cef5a2eb47d
4
+ data.tar.gz: 891ef7140bba23d6f55b14f97668f2561275305b2fa43f7ea795920e4d101c82
5
5
  SHA512:
6
- metadata.gz: 2c71dd260c5af46a18eeb2d9d8f74e560509293a4053cff0a2055215e07302ddeeeec0c4f8693551545403343e9ea80cd8bd3a2adae99ce9780f98cb427386d2
7
- data.tar.gz: 72d63187fcf637f6b65854f13a4f837293531cf55707679057b45e52b498bab2dfa78671e48e64833a5a07035f3e20800438184bd2b99cbd32e376347278d264
6
+ metadata.gz: 9384af8b49181607bb86e10c204370eb04b4a8fd76552172065e0c44e0cd6f1349a21cb56e7dae3ca2a308e35a0039d5d706129ae9ffe19e0268e4136d18521c
7
+ data.tar.gz: 1c9a6edb28587660fa88afca67ebf6c2ab2e7d066721c707f907682f2f96d4a8aed62c6d486f42c133b9080729e228d3237b0125d2c33b83c3e98acf275aed16
data/lib/bitfab/client.rb CHANGED
@@ -46,16 +46,18 @@ module Bitfab
46
46
  # code change being tested in this replay (stored on the experiment)
47
47
  # @param code_change_files [Array<Hash>, nil] optional list of edited files,
48
48
  # each as { path:, before:, after: } (use "" for new/deleted files)
49
+ # @param experiment_group_id [String, nil] optional UUID grouping multiple
50
+ # replay runs into a single experiment batch
49
51
  # @param mock [String] mock strategy for child spans: "none" (default),
50
52
  # "all", or "marked". "all" mocks every child span; "marked" only mocks
51
53
  # spans declared with mock_on_replay: true.
52
54
  # @return [Hash] with :items, :test_run_id, :test_run_url
53
55
  def replay(receiver, method_name, trace_function_key:, limit: 5, trace_ids: nil, max_concurrency: 10,
54
- code_change_description: nil, code_change_files: nil, mock: "none")
56
+ code_change_description: nil, code_change_files: nil, experiment_group_id: nil, mock: "none")
55
57
  Replay.run(
56
58
  self, receiver, method_name,
57
59
  trace_function_key:, limit:, trace_ids:, max_concurrency:,
58
- code_change_description:, code_change_files:, mock:
60
+ code_change_description:, code_change_files:, experiment_group_id:, mock:
59
61
  )
60
62
  end
61
63
 
@@ -84,13 +86,12 @@ module Bitfab
84
86
  return yield unless @enabled
85
87
 
86
88
  parent = SpanContext.current
87
- trace_id = parent ? parent[:trace_id] : SecureRandom.uuid
89
+ replay_ctx = ReplayContext.current
90
+ trace_id = parent ? parent[:trace_id] : (replay_ctx&.dig(:trace_id) || SecureRandom.uuid)
88
91
  span_id = SecureRandom.uuid
89
92
  parent_span_id = parent&.dig(:span_id)
90
93
  is_root_span = parent_span_id.nil?
91
94
  started_at = Time.now.utc.strftime("%Y-%m-%dT%H:%M:%S.%3NZ")
92
-
93
- replay_ctx = ReplayContext.current
94
95
  resolved_test_run_id = replay_ctx&.dig(:test_run_id)
95
96
  resolved_input_source_span_id = replay_ctx&.dig(:input_source_span_id)
96
97
  resolved_input_source_trace_id = replay_ctx&.dig(:input_source_trace_id)
@@ -103,7 +103,10 @@ module Bitfab
103
103
  # code change being tested in this replay
104
104
  # @param code_change_files [Array<Hash>, nil] optional list of edited files,
105
105
  # each as { path:, before:, after: } (use "" for new/deleted files)
106
- def start_replay(trace_function_key, limit, trace_ids: nil, code_change_description: nil, code_change_files: nil)
106
+ # @param experiment_group_id [String, nil] optional UUID grouping multiple
107
+ # replay runs into a single experiment batch
108
+ def start_replay(trace_function_key, limit, trace_ids: nil, code_change_description: nil,
109
+ code_change_files: nil, experiment_group_id: nil)
107
110
  payload = {
108
111
  "traceFunctionKey" => trace_function_key,
109
112
  "limit" => limit
@@ -111,6 +114,7 @@ module Bitfab
111
114
  payload["traceIds"] = trace_ids if trace_ids
112
115
  payload["codeChangeDescription"] = code_change_description unless code_change_description.nil?
113
116
  payload["codeChangeFiles"] = normalize_code_change_files(code_change_files) unless code_change_files.nil?
117
+ payload["experimentGroupId"] = experiment_group_id unless experiment_group_id.nil?
114
118
 
115
119
  request("/api/sdk/replay/start", payload, timeout: 30)
116
120
  end
data/lib/bitfab/replay.rb CHANGED
@@ -22,19 +22,14 @@ module Bitfab
22
22
 
23
23
  # Execute a block with replay context set on the current thread.
24
24
  # The context is automatically cleared when the block completes.
25
- #
26
- # @param test_run_id [String]
27
- # @param input_source_span_id [String, nil]
28
- # @param input_source_trace_id [String, nil]
29
- # @param mock_tree [Hash{String => Hash}, nil] keyed by "#{key}:#{index}"
30
- # @param mock_strategy [String, nil] one of MOCK_STRATEGIES
31
- def with_context(test_run_id:, input_source_span_id: nil, input_source_trace_id: nil,
25
+ def with_context(test_run_id:, input_source_span_id: nil, input_source_trace_id: nil, trace_id: nil,
32
26
  mock_tree: nil, mock_strategy: nil)
33
27
  previous = Thread.current[REPLAY_CONTEXT_KEY]
34
28
  ctx = {
35
29
  test_run_id:,
36
30
  input_source_span_id:,
37
- input_source_trace_id:
31
+ input_source_trace_id:,
32
+ trace_id:
38
33
  }
39
34
  if mock_tree
40
35
  ctx[:mock_tree] = mock_tree
@@ -68,12 +63,14 @@ module Bitfab
68
63
  # code change being tested in this replay (stored on the experiment)
69
64
  # @param code_change_files [Array<Hash>, nil] optional list of edited files,
70
65
  # each as { path:, before:, after: } (empty string for new/deleted files)
66
+ # @param experiment_group_id [String, nil] optional UUID grouping multiple
67
+ # replay runs into a single experiment batch
71
68
  # @param mock [String] mock strategy for child spans: "none" (default),
72
69
  # "all", or "marked". "all" mocks every child span; "marked" only mocks
73
70
  # spans declared with mock_on_replay: true.
74
71
  # @return [Hash] with :items, :test_run_id, :test_run_url
75
72
  def run(client, receiver, method_name, trace_function_key:, limit: 5, trace_ids: nil, max_concurrency: 10,
76
- code_change_description: nil, code_change_files: nil, mock: "none")
73
+ code_change_description: nil, code_change_files: nil, experiment_group_id: nil, mock: "none")
77
74
  unless MOCK_STRATEGIES.include?(mock.to_s)
78
75
  raise ArgumentError, "Invalid mock strategy '#{mock}'. Must be one of: #{MOCK_STRATEGIES.join(", ")}"
79
76
  end
@@ -85,7 +82,8 @@ module Bitfab
85
82
  limit,
86
83
  trace_ids:,
87
84
  code_change_description:,
88
- code_change_files:
85
+ code_change_files:,
86
+ experiment_group_id:
89
87
  )
90
88
  test_run_id = replay_data["testRunId"]
91
89
  test_run_url = replay_data["testRunUrl"]
@@ -100,9 +98,14 @@ module Bitfab
100
98
  Bitfab.flush_traces
101
99
 
102
100
  begin
103
- http_client.complete_replay(test_run_id)
101
+ complete_response = http_client.complete_replay(test_run_id)
102
+ trace_id_map = complete_response&.dig("traceIds") || {}
103
+ result_items.each do |item|
104
+ item[:trace_id] = trace_id_map[item[:trace_id]]
105
+ end
104
106
  rescue => e
105
107
  warn "Bitfab: Failed to complete replay: #{e.message}"
108
+ result_items.each { |item| item[:trace_id] = nil }
106
109
  end
107
110
 
108
111
  {
@@ -248,11 +251,13 @@ module Bitfab
248
251
 
249
252
  fn_result = nil
250
253
  fn_error = nil
254
+ sdk_trace_id = SecureRandom.uuid
251
255
 
252
256
  ReplayContext.with_context(
253
257
  test_run_id:,
254
258
  input_source_span_id:,
255
259
  input_source_trace_id:,
260
+ trace_id: sdk_trace_id,
256
261
  mock_tree:,
257
262
  mock_strategy:
258
263
  ) do
@@ -272,7 +277,8 @@ module Bitfab
272
277
  error: fn_error,
273
278
  duration_ms: metrics[:duration_ms],
274
279
  tokens: metrics[:tokens],
275
- model: metrics[:model]
280
+ model: metrics[:model],
281
+ trace_id: sdk_trace_id
276
282
  }
277
283
  end
278
284
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bitfab
4
- VERSION = "0.12.1"
4
+ VERSION = "0.12.3"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bitfab
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.1
4
+ version: 0.12.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Harvest Team