require_relative '../test_helper' require 'webmock/minitest' require 'aws-xray-sdk/recorder' require 'aws-xray-sdk/exceptions' require 'aws-xray-sdk/version' require 'aws-xray-sdk/plugins/ec2' # Test global X-Ray recorder class TestRecorder < Minitest::Test @@recorder = XRay::Recorder.new @@recorder.config.sampling = false @@recorder.config.emitter = XRay::TestHelper::StubbedEmitter.new def setup @@recorder.context.clear! @@recorder.emitter.clear end def teardown @@recorder.context.clear! @@recorder.emitter.clear end def test_get_segment segment = @@recorder.begin_segment name: name assert_equal segment, @@recorder.current_segment assert segment.sampled end def test_get_subsegment segment = @@recorder.begin_segment name: name subsegment = @@recorder.begin_subsegment name: name assert_equal segment, @@recorder.current_segment assert_equal subsegment, @@recorder.current_subsegment assert segment.sampled end def test_send_segment segment = @@recorder.begin_segment name: name @@recorder.end_segment assert_equal segment, @@recorder.emitter.entities[0] end def test_send_segment_with_ctx_missing_runtime_error recorder = XRay::Recorder.new config = { context_missing: 'RUNTIME_ERROR', sampling: false, emitter: XRay::TestHelper::StubbedEmitter.new, sampler: XRay::TestHelper::StubbedDefaultSampler.new } recorder.configure(config) segment = recorder.begin_segment name: name recorder.end_segment assert_equal segment, recorder.emitter.entities[0] assert_raises XRay::ContextMissingError do recorder.current_segment end end def test_subsegment_capture segment = @@recorder.begin_segment name at = { k: 'v' } @@recorder.capture('compute') do |subsegment| subsegment.annotations.update at end subsegment = segment.subsegments[0] assert_equal at, subsegment.annotations.to_h assert subsegment.closed? end def test_nested_subsegments @@recorder.begin_segment name subsegment1 = @@recorder.begin_subsegment name @@recorder.begin_subsegment name @@recorder.begin_subsegment name @@recorder.end_subsegment @@recorder.end_subsegment assert_equal subsegment1, @@recorder.current_subsegment end def test_subsegments_streaming threshold = @@recorder.streamer.stream_threshold segment = @@recorder.begin_segment name (threshold + 1).times do |i| @@recorder.begin_subsegment i.to_s end (threshold + 1).times do @@recorder.end_subsegment end assert_equal 2, @@recorder.emitter.entities.count # segment should not be prematurely sent in this case refute @@recorder.emitter.entities.include?(segment) @@recorder.end_segment assert_equal 3, @@recorder.emitter.entities.count assert_equal segment, @@recorder.emitter.entities[2] end def test_sampled_block @@recorder.begin_segment name x = 0 @@recorder.sampled? do x = 1 end assert_equal 1, x assert @@recorder.sampled? end def test_sampling_segments recorder = XRay::Recorder.new config = { sampling: true, emitter: XRay::TestHelper::StubbedEmitter.new, sampler: XRay::TestHelper::StubbedDefaultSampler.new } recorder.configure(config) segment = recorder.begin_segment('name') assert segment.sampled recorder.context.clear! end def test_add_annotation segment = @@recorder.begin_segment name @@recorder.annotations[:k] = 1 assert_equal 1, segment.annotations.to_h[:k] subsegment = @@recorder.begin_subsegment name, segment: segment @@recorder.annotations[:k2] = 2 assert_equal 2, subsegment.annotations.to_h[:k2] refute segment.annotations.to_h.key?(:k2) end def test_add_metadata segment = @@recorder.begin_segment name @@recorder.metadata[:k] = 1 assert_equal 1, segment.to_h[:metadata][:default][:k] subsegment = @@recorder.begin_subsegment name, segment: segment @@recorder.metadata(namespace: :ns)[:k] = 1 @@recorder.metadata(namespace: :ns).update k2: 2 assert_equal 1, subsegment.to_h[:metadata][:ns][:k] assert_equal 2, subsegment.to_h[:metadata][:ns][:k2] end def test_thread_infection segment = @@recorder.begin_segment name thread = Thread.new { @@recorder.inject_context segment do @@recorder.begin_subsegment 'my_sub' @@recorder.end_subsegment end } thread.join @@recorder.end_segment sent_entity = @@recorder.emitter.entities[0] assert_equal segment, sent_entity subsegment = sent_entity.subsegments[0] assert_equal 'my_sub', subsegment.name assert_equal segment.id, subsegment.parent.id end def test_xray_metadata segment = @@recorder.begin_segment name xray_meta = segment.to_h[:aws][:xray] assert_equal 'X-Ray for Ruby', xray_meta[:sdk] assert_equal XRay::VERSION, xray_meta[:sdk_version] service_meta = segment.to_h[:service] assert service_meta[:runtime] assert service_meta[:runtime_version] end def test_plugins_runtime_context dummy_json = '{\"availabilityZone\" : \"us-east-2a\", \"imageId\" : \"ami-03cca83dd001d4666\", \"instanceId\" : \"i-07a181803de94c666\", \"instanceType\" : \"t3.xlarge\"}' stub_request(:put, 'http://169.254.169.254/latest/api/token') .to_return(status: 200, body: 'some_token', headers: {}) stub_request(:get, 'http://169.254.169.254/latest/dynamic/instance-identity/document') .to_return(status: 200, body: dummy_json, headers: {}) recorder = XRay::Recorder.new config = { sampling: false, emitter: XRay::TestHelper::StubbedEmitter.new, plugins: %I[ecs ec2] } recorder.configure(config) segment = recorder.begin_segment name aws_meta = segment.to_h[:aws] assert aws_meta[:ecs] assert segment.origin WebMock.reset! end def test_context_missing_passthrough recorder = XRay::Recorder.new config = { sampling: false, context_missing: 'LOG_ERROR', emitter: XRay::TestHelper::StubbedEmitter.new } recorder.configure(config) recorder.annotations[:k] = 1 recorder.sampled? do recorder.annotations.update k2: 2 recorder.metadata.update k3: 3 end recorder.metadata[:foo] = 'bar' v = recorder.capture(name) do |subsegment| subsegment.annotations[:k] = '1' 1 end assert_equal 1, v assert_nil recorder.emitter.entities end end