diff --git a/lib/datadog/di/probe_notification_builder.rb b/lib/datadog/di/probe_notification_builder.rb index c8634ac4364..2f058eaadd7 100644 --- a/lib/datadog/di/probe_notification_builder.rb +++ b/lib/datadog/di/probe_notification_builder.rb @@ -121,7 +121,7 @@ def build_snapshot(probe, rv: nil, snapshot: nil, path: nil, }, # In python tracer duration is under debugger.snapshot, # but UI appears to expect it here at top level. - duration: duration ? (duration * 10**9).to_i : nil, + duration: duration ? (duration * 10**9).to_i : 0, host: nil, logger: { name: probe.file, @@ -139,7 +139,7 @@ def build_snapshot(probe, rv: nil, snapshot: nil, path: nil, "dd.span_id": Datadog::Tracing.active_span&.id&.to_s, ddsource: 'dd_debugger', message: probe.template && evaluate_template(probe.template, - duration: duration ? duration * 1000 : nil), + duration: duration ? duration * 1000 : 0), timestamp: timestamp, } end diff --git a/spec/datadog/di/probe_notification_builder_spec.rb b/spec/datadog/di/probe_notification_builder_spec.rb index 7d1b0804703..5f25bf2dcdc 100644 --- a/spec/datadog/di/probe_notification_builder_spec.rb +++ b/spec/datadog/di/probe_notification_builder_spec.rb @@ -42,32 +42,140 @@ end describe '#build_received' do - it 'returns a hash' do - expect(builder.build_received(probe)).to be_a(Hash) + let(:payload) do + builder.build_received(probe) + end + + let(:expected) do + { + ddsource: 'dd_debugger', + debugger: { + diagnostics: { + parentId: nil, + probeId: '123', + probeVersion: 0, + runtimeId: String, + status: 'RECEIVED', + }, + }, + message: "Probe 123 has been received correctly", + service: 'test service', + timestamp: Integer, + } + end + + it 'returns a hash with expected contents' do + expect(payload).to be_a(Hash) + expect(payload).to match(expected) end end describe '#build_installed' do - it 'returns a hash' do - expect(builder.build_installed(probe)).to be_a(Hash) + let(:payload) do + builder.build_installed(probe) + end + + let(:expected) do + { + ddsource: 'dd_debugger', + debugger: { + diagnostics: { + parentId: nil, + probeId: '123', + probeVersion: 0, + runtimeId: String, + status: 'INSTALLED', + }, + }, + message: "Probe 123 has been instrumented correctly", + service: 'test service', + timestamp: Integer, + } + end + + it 'returns a hash with expected contents' do + expect(payload).to be_a(Hash) + expect(payload).to match(expected) end end describe '#build_emitting' do - it 'returns a hash' do - expect(builder.build_emitting(probe)).to be_a(Hash) + let(:payload) do + builder.build_emitting(probe) + end + + let(:expected) do + { + ddsource: 'dd_debugger', + debugger: { + diagnostics: { + parentId: nil, + probeId: '123', + probeVersion: 0, + runtimeId: String, + status: 'EMITTING', + }, + }, + message: "Probe 123 is emitting", + service: 'test service', + timestamp: Integer, + } + end + + it 'returns a hash with expected contents' do + expect(payload).to be_a(Hash) + expect(payload).to match(expected) end end describe '#build_executed' do + let(:payload) { builder.build_executed(probe) } + context 'with template' do let(:probe) do Datadog::DI::Probe.new(id: '123', type: :log, file: 'X', line_no: 1, template: 'hello world') end - it 'returns a hash' do - expect(builder.build_executed(probe)).to be_a(Hash) + let(:expected) do + { + ddsource: 'dd_debugger', + "dd.span_id": nil, + "dd.trace_id": nil, + "debugger.snapshot": { + captures: nil, + evaluationErrors: [], + id: String, + language: 'ruby', + probe: { + id: '123', + location: { + file: nil, + lines: [1], + }, + version: 0, + }, + stack: nil, + timestamp: Integer, + }, + message: "hello world", + service: 'test service', + timestamp: Integer, + logger: { + method: 'no_method', + name: 'X', + thread_id: nil, + thread_name: 'Thread.main', + version: 2, + }, + duration: 0, + host: nil, + } + end + + it 'returns a hash with expected contents' do + expect(payload).to be_a(Hash) + expect(payload).to match(expected) end end @@ -77,8 +185,45 @@ capture_snapshot: false) end - it 'returns a hash' do - expect(builder.build_executed(probe)).to be_a(Hash) + let(:expected) do + { + ddsource: 'dd_debugger', + "dd.span_id": nil, + "dd.trace_id": nil, + "debugger.snapshot": { + captures: nil, + evaluationErrors: [], + id: String, + language: 'ruby', + probe: { + id: '123', + location: { + file: nil, + lines: [1], + }, + version: 0, + }, + stack: nil, + timestamp: Integer, + }, + message: nil, + service: 'test service', + timestamp: Integer, + logger: { + method: 'no_method', + name: 'X', + thread_id: nil, + thread_name: 'Thread.main', + version: 2, + }, + duration: 0, + host: nil, + } + end + + it 'returns a hash with expected contents' do + expect(payload).to be_a(Hash) + expect(payload).to match(expected) end end @@ -91,13 +236,92 @@ let(:trace_point) do instance_double(TracePoint).tap do |tp| # Returns an empty binding - expect(tp).to receive(:binding).and_return(binding) + expect(tp).to receive(:binding).and_return(get_binding) expect(tp).to receive(:path).and_return('/foo.rb') end end - it 'returns a hash' do - expect(builder.build_executed(probe, trace_point: trace_point)).to be_a(Hash) + let(:get_binding) do + x = 1 + binding + end + + let(:payload) do + builder.build_executed(probe, trace_point: trace_point) + end + + let(:expected) do + { + ddsource: 'dd_debugger', + "dd.span_id": nil, + "dd.trace_id": nil, + "debugger.snapshot": { + captures: { + lines: { + 1 => { + locals: local_captures, + }, + }, + }, + evaluationErrors: [], + id: String, + language: 'ruby', + probe: { + id: '123', + location: { + file: '/foo.rb', + lines: [1], + }, + version: 0, + }, + stack: nil, + timestamp: Integer, + }, + message: nil, + service: 'test service', + timestamp: Integer, + logger: { + method: 'no_method', + name: 'X', + thread_id: nil, + thread_name: 'Thread.main', + version: 2, + }, + duration: 0, + host: nil, + } + end + + shared_examples 'returns a hash with expected contents' do + it 'returns a hash with expected contents' do + expect(payload).to be_a(Hash) + expect(payload).to match(expected) + end + end + + context 'when binding is empty' do + let(:get_binding) do + binding + end + + let(:local_captures) do + {} + end + + include_examples 'returns a hash with expected contents' + end + + context 'when binding is not empty' do + let(:get_binding) do + x = 1 + binding + end + + let(:local_captures) do + {x: {type: 'Integer', value: '1'}} + end + + include_examples 'returns a hash with expected contents' end end end