spec/elastic_apm/trace_context_spec.rb (141 lines of code) (raw):
# Licensed to Elasticsearch B.V. under one or more contributor
# license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright
# ownership. Elasticsearch B.V. licenses this file to you under
# the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true
require 'spec_helper'
module ElasticAPM
RSpec.describe TraceContext do
describe '.parse' do
subject { described_class.parse(env: env) }
context 'with a valid traceparent' do
let(:env) do
Rack::MockRequest.env_for(
'/',
'HTTP_ELASTIC_APM_TRACEPARENT' =>
'00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-00'
)
end
its(:traceparent) { is_expected.to be_a TraceContext::Traceparent }
it "doesn't set sample_rate" do
expect(subject.tracestate.sample_rate).to be nil
expect(subject.tracestate.to_header).to eq ""
end
end
context 'with an invalid traceparent' do
let(:env) do
Rack::MockRequest.env_for(
'/',
'HTTP_ELASTIC_APM_TRACEPARENT' =>
'0asdf0-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-00'
)
end
it 'raises error' do
expect { subject }
.to raise_error(TraceContext::InvalidTraceparentHeader)
end
end
context 'with both traceparent and tracestate' do
let(:env) do
Rack::MockRequest.env_for(
'/',
'HTTP_ELASTIC_APM_TRACEPARENT' =>
'00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-00',
'HTTP_TRACESTATE' => 'thing=value'
)
end
its(:traceparent) { is_expected.to be_a TraceContext::Traceparent }
its(:tracestate) { is_expected.to be_a TraceContext::Tracestate }
end
context 'with traceparent and an empty tracestate' do
let(:env) do
Rack::MockRequest.env_for(
'/',
'HTTP_ELASTIC_APM_TRACEPARENT' =>
'00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-00',
'HTTP_TRACESTATE' => ''
)
end
its(:traceparent) { is_expected.to be_a TraceContext::Traceparent }
its(:tracestate) { is_expected.to be_a TraceContext::Tracestate }
it 'generates no tracestate header' do
expect(subject.tracestate.to_header).to eq ""
end
end
context 'with neither' do
let(:env) do
Rack::MockRequest.env_for('/')
end
it { is_expected.to be nil }
end
context 'with only tracestate' do
let(:env) do
Rack::MockRequest.env_for(
'/',
'HTTP_TRACESTATE' => 'thing=value'
)
end
it { is_expected.to be nil }
end
end
describe '#child' do
let(:parent) do
described_class.new.tap do |tp|
tp.traceparent.trace_id = '1' * 32
tp.traceparent.id = '2' * 16
tp.traceparent.flags = '00000011'
end
end
subject { parent.child }
it 'makes a child copy' do
expect(subject.traceparent).to_not be parent.traceparent
end
end
describe '#apply_headers' do
subject do
described_class.new.tap do |tp|
tp.traceparent.trace_id = '1' * 32
tp.traceparent.id = '2' * 16
tp.traceparent.flags = '00000011'
end
end
context 'when prefixed is disabled', :intercept do
it 'applies only prefix-less header' do
calls = {}
block = ->(k, v) { calls[k] = v }
with_agent(use_elastic_traceparent_header: false) do
subject.apply_headers(&block)
end
expect(calls).to match(
'Traceparent' => String
)
expect(calls.length).to eq 1
end
end
context 'when prefixed is enabled', :intercept do
it 'applies both headers' do
calls = {}
block = ->(k, v) { calls[k] = v }
with_agent do
subject.apply_headers(&block)
end
expect(calls).to match(
'Traceparent' => String,
'Elastic-Apm-Traceparent' => String
)
expect(calls.values.uniq.length).to eq 1
end
end
context 'with tracestate', :intercept do
it 'sets tracestate header' do
calls = {}
block = ->(k, v) { calls[k] = v }
subject.tracestate = TraceContext::Tracestate.parse('es=s:1.0,b=na')
with_agent do
subject.apply_headers(&block)
end
expect(calls).to match(
'Traceparent' => String,
'Elastic-Apm-Traceparent' => String,
'Tracestate' => 'es=s:1.0,b=na'
)
end
end
end
end
end