instana 1.197.0.pre1 → 1.197.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 58219b994af0387dcc4c672577b19c9570e487998be17d315a92902d6e1d86e6
4
- data.tar.gz: 60e586b644f60545ebe6c7690d3ba673354d2133937b3b2bf95db04fbe8f58c4
3
+ metadata.gz: 518b5595452badfeb017ea91f89907026f1d21ee0945982dbeb0f1d55662a45a
4
+ data.tar.gz: 46e3a5473d6e804a54f7e756739e4f34439db51e4e825770763d2647b59eefa8
5
5
  SHA512:
6
- metadata.gz: 4d4ca8c71a1613c05e5f1fec02e5857c544013f0043d4b95e31fc900b81903ba5f3c08abd075afc4643e7761cd54a7595939ad9149575589b44b8e43722ea89a
7
- data.tar.gz: 737447ad9f8ed3c6aef72bead3e66128b83ac1d346bc35f00ad1bd3e0b485f4cd8080faabf8817da23a788f229d32db1739e98484637fd8e70b852b415447d97
6
+ metadata.gz: e0025b1437bd30313df97306835a228083e6d6dbd6253e109d9ba67d85f7ce4b03c677ccfbaff9fa3084f5968add9d01ac9dcd60a1d5338b54c37cebf5d3b306
7
+ data.tar.gz: 7d1fadb443f1ce0304bd4944198300ed0a2043ea9154dbd7fe50b89ed0a101bddd6da7f9086901eac3dc9c95e799a4eb29118fe6c7c8f153908bbb0b75b03788
@@ -5,22 +5,29 @@ module Instana
5
5
  module Backend
6
6
  # @since 1.197.0
7
7
  class HostAgent
8
- def initialize(discovery: Concurrent::Atom.new(nil))
8
+ attr_reader :future
9
+
10
+ def initialize(discovery: Concurrent::Atom.new(nil), logger: ::Instana.logger)
9
11
  @discovery = discovery
10
- @client = nil
12
+ @logger = logger
13
+ @future = nil
11
14
  end
12
15
 
13
- def setup
16
+ def setup; end
17
+
18
+ def spawn_background_thread
14
19
  return if ENV.key?('INSTANA_TEST')
15
20
 
16
- @client = HostAgentLookup.new.call
17
- @discovery
18
- .with_observer(HostAgentActivationObserver.new(@client, @discovery))
19
- .with_observer(HostAgentReportingObserver.new(@client, @discovery))
20
- end
21
+ @future = Concurrent::Promises.future do
22
+ client = until_not_nil { HostAgentLookup.new.call }
23
+ @discovery.delete_observers
24
+ @discovery
25
+ .with_observer(HostAgentActivationObserver.new(client, @discovery))
26
+ .with_observer(HostAgentReportingObserver.new(client, @discovery))
21
27
 
22
- def spawn_background_thread
23
- @discovery.swap { nil }
28
+ @discovery.swap { nil }
29
+ client
30
+ end
24
31
  end
25
32
 
26
33
  # @return [Boolean] true if the agent able to send spans to the backend
@@ -48,6 +55,16 @@ module Instana
48
55
 
49
56
  private
50
57
 
58
+ def until_not_nil
59
+ loop do
60
+ result = yield
61
+ return result unless result.nil?
62
+
63
+ @logger.debug("Waiting on a connection to the agent.")
64
+ sleep(1)
65
+ end
66
+ end
67
+
51
68
  def discovery_value
52
69
  v = @discovery.value
53
70
  v || {}
@@ -12,20 +12,23 @@ module Instana
12
12
 
13
13
  # @param [RequestClient] client used to make requests to the backend
14
14
  # @param [Concurrent::Atom] discovery object used to store discovery response in
15
- def initialize(client, discovery, wait_time: 60, logger: ::Instana.logger, max_wait_tries: 60, proc_table: Sys::ProcTable) # rubocop:disable Metrics/ParameterLists
15
+ def initialize(client, discovery, wait_time: 1, logger: ::Instana.logger, max_wait_tries: 60, proc_table: Sys::ProcTable, socket_proc: default_socket_proc) # rubocop:disable Metrics/ParameterLists
16
16
  @client = client
17
17
  @discovery = discovery
18
18
  @wait_time = wait_time
19
19
  @logger = logger
20
20
  @max_wait_tries = max_wait_tries
21
21
  @proc_table = proc_table
22
+ @socket_proc = socket_proc
22
23
  end
23
24
 
24
25
  def update(_time, _old_version, new_version)
25
26
  return unless new_version.nil?
26
27
 
28
+ socket = @socket_proc.call(@client)
29
+
27
30
  try_forever_with_backoff do
28
- payload = discovery_payload
31
+ payload = discovery_payload(socket)
29
32
  discovery_response = @client.send_request('PUT', DISCOVERY_URL, payload)
30
33
 
31
34
  raise DiscoveryError, "Discovery response was #{discovery_response.code} with `#{payload}`." unless discovery_response.ok?
@@ -36,11 +39,13 @@ module Instana
36
39
  @logger.debug("Agent ready.")
37
40
  @discovery.swap { discovery }
38
41
  end
42
+
43
+ socket.close
39
44
  end
40
45
 
41
46
  private
42
47
 
43
- def discovery_payload
48
+ def discovery_payload(socket)
44
49
  proc_table = @proc_table.ps(pid: Process.pid)
45
50
  process = ProcessInfo.new(proc_table)
46
51
 
@@ -52,9 +57,10 @@ module Instana
52
57
  cpuSetFileContent: process.cpuset
53
58
  }
54
59
 
55
- if @client.fileno && @client.inode
56
- payload[:fd] = @client.fileno
57
- payload[:inode] = @client.inode
60
+ inode_path = "/proc/self/fd/#{socket.fileno}"
61
+ if socket.fileno && File.exist?(inode_path)
62
+ payload[:fd] = socket.fileno
63
+ payload[:inode] = File.readlink(inode_path)
58
64
  end
59
65
 
60
66
  payload.compact
@@ -76,12 +82,16 @@ module Instana
76
82
  def try_forever_with_backoff
77
83
  yield
78
84
  rescue DiscoveryError, Net::OpenTimeout => e
79
- @logger.error(e)
85
+ @logger.warn(e)
80
86
  sleep(@wait_time)
81
87
  retry
82
88
  rescue StandardError => e
83
89
  @logger.error(%(#{e}\n#{e.backtrace.join("\n")}))
84
90
  end
91
+
92
+ def default_socket_proc
93
+ ->(c) { TCPSocket.new(c.host, c.port) }
94
+ end
85
95
  end
86
96
  end
87
97
  end
@@ -18,6 +18,8 @@ module Instana
18
18
  # Convince wrapper around {Net::HTTP}.
19
19
  # @since 1.197.0
20
20
  class RequestClient
21
+ attr_reader :host, :port
22
+
21
23
  class Response < SimpleDelegator
22
24
  # @return [Hash] the decoded json response
23
25
  def json
@@ -31,6 +33,8 @@ module Instana
31
33
  end
32
34
 
33
35
  def initialize(host, port, use_ssl: false)
36
+ @host = host
37
+ @port = port
34
38
  @client = Net::HTTP.start(host, port, use_ssl: use_ssl)
35
39
  end
36
40
 
@@ -57,21 +61,6 @@ module Instana
57
61
  Response.new(response)
58
62
  end
59
63
 
60
- # @return [Integer, NilClass] the fileno of the Net::HTTP socket or nil if it can't be identified
61
- def fileno
62
- socket = @client.instance_variable_get('@socket')
63
- io = socket && socket.instance_variable_get('@io')
64
- io && io.fileno
65
- end
66
-
67
- # @return [String] the inode asscoated with the Net::HTTP socket or nil if it can't be identified
68
- def inode
69
- path = "/proc/self/fd/#{fileno}"
70
- return unless File.exist?(path) && fileno
71
-
72
- File.readlink(path)
73
- end
74
-
75
64
  private
76
65
 
77
66
  def encode_body(data)
@@ -92,7 +92,7 @@ module Instana
92
92
 
93
93
  def agent_snapshots
94
94
  @snapshots.map do |snapshot|
95
- begin
95
+ begin # rubocop:disable Style/RedundantBegin, Lint/RedundantCopDisableDirective
96
96
  snapshot.snapshot
97
97
  rescue StandardError => e
98
98
  @logger.error(e.message)
@@ -51,7 +51,7 @@ module Instana
51
51
  @config[:sanitize_sql] = true
52
52
 
53
53
  # W3 Trace Context Support
54
- @config[:w3_trace_correlation] = ENV.fetch('INSTANA_W3C_TRACE_CORRELATION', 'true').eql?('true')
54
+ @config[:w3_trace_correlation] = ENV['INSTANA_DISABLE_W3C_TRACE_CORRELATION'].nil?
55
55
 
56
56
  @config[:action_controller] = { :enabled => true }
57
57
  @config[:action_view] = { :enabled => true }
@@ -24,14 +24,16 @@ module Instana
24
24
  end
25
25
 
26
26
  # Set request headers; encode IDs as hexadecimal strings
27
- datum[:headers]['X-Instana-T'] = t_context.trace_id_header
28
- datum[:headers]['X-Instana-S'] = t_context.span_id_header
27
+ datum[:headers]['X-Instana-L'] = t_context.level.to_s
29
28
 
30
- if ::Instana.config[:w3_trace_correlation]
31
- datum[:headers]['Traceparent'] = t_context.trace_parent_header
32
- datum[:headers]['Tracestate'] = t_context.trace_state_header
29
+ if t_context.active?
30
+ datum[:headers]['X-Instana-T'] = t_context.trace_id_header
31
+ datum[:headers]['X-Instana-S'] = t_context.span_id_header
33
32
  end
34
33
 
34
+ datum[:headers]['Traceparent'] = t_context.trace_parent_header
35
+ datum[:headers]['Tracestate'] = t_context.trace_state_header unless t_context.trace_state_header.empty?
36
+
35
37
  @stack.request_call(datum)
36
38
  end
37
39
 
@@ -18,16 +18,33 @@ module Instana
18
18
  end
19
19
 
20
20
  def incoming_context
21
- context = if @env['HTTP_X_INSTANA_T']
21
+ context = if !correlation_data.empty?
22
+ {}
23
+ elsif @env['HTTP_X_INSTANA_T']
22
24
  context_from_instana_headers
23
- elsif @env['HTTP_TRACEPARENT'] && ::Instana.config[:w3_trace_correlation]
25
+ elsif @env['HTTP_TRACEPARENT']
24
26
  context_from_trace_parent
27
+ elsif @env['HTTP_TRACESTATE']
28
+ context_from_trace_state
25
29
  else
26
30
  {}
27
31
  end
28
32
 
29
33
  context[:level] = @env['HTTP_X_INSTANA_L'][0] if @env['HTTP_X_INSTANA_L']
30
34
 
35
+ unless ::Instana.config[:w3_trace_correlation]
36
+ trace_state = parse_trace_state
37
+
38
+ if context[:from_w3] && trace_state.empty?
39
+ context.delete(:span_id)
40
+ context[:from_w3] = false
41
+ elsif context[:from_w3] && !trace_state.empty?
42
+ context[:trace_id] = trace_state[:t]
43
+ context[:span_id] = trace_state[:p]
44
+ context[:from_w3] = false
45
+ end
46
+ end
47
+
31
48
  context
32
49
  end
33
50
 
@@ -69,19 +86,43 @@ module Instana
69
86
  end
70
87
 
71
88
  def continuing_from_trace_parent?
72
- incoming_context.include?(:external_trace_id)
89
+ incoming_context[:from_w3]
73
90
  end
74
91
 
75
92
  def synthetic?
76
93
  @env.has_key?('HTTP_X_INSTANA_SYNTHETIC') && @env['HTTP_X_INSTANA_SYNTHETIC'].eql?('1')
77
94
  end
78
95
 
96
+ def long_instana_id?
97
+ ::Instana::Util.header_to_id(@env['HTTP_X_INSTANA_T']).length == 32
98
+ end
99
+
100
+ def external_trace_id?
101
+ continuing_from_trace_parent? || long_instana_id?
102
+ end
103
+
104
+ def external_trace_id
105
+ incoming_context[:long_instana_id] || incoming_context[:external_trace_id]
106
+ end
107
+
79
108
  private
80
109
 
81
110
  def context_from_instana_headers
111
+ sanitized_t = ::Instana::Util.header_to_id(@env['HTTP_X_INSTANA_T'])
112
+ sanitized_s = ::Instana::Util.header_to_id(@env['HTTP_X_INSTANA_S'])
113
+ external_trace_id = if @env['HTTP_TRACEPARENT']
114
+ context_from_trace_parent[:external_trace_id]
115
+ elsif long_instana_id?
116
+ sanitized_t
117
+ end
118
+
82
119
  {
83
- trace_id: ::Instana::Util.header_to_id(@env['HTTP_X_INSTANA_T']),
84
- span_id: ::Instana::Util.header_to_id(@env['HTTP_X_INSTANA_S'])
120
+ span_id: sanitized_s,
121
+ trace_id: long_instana_id? ? sanitized_t[16..-1] : sanitized_t, # rubocop:disable Style/SlicingWithRange, Lint/RedundantCopDisableDirective
122
+ long_instana_id: long_instana_id? ? sanitized_t : nil,
123
+ external_trace_id: external_trace_id,
124
+ external_state: @env['HTTP_TRACESTATE'],
125
+ from_w3: false
85
126
  }.compact
86
127
  end
87
128
 
@@ -90,14 +131,28 @@ module Instana
90
131
  matches = @env['HTTP_TRACEPARENT'].match(W3_TRACE_PARENT_FORMAT)
91
132
  return {} unless matches
92
133
 
134
+ trace_id = ::Instana::Util.header_to_id(matches['trace'][16..-1]) # rubocop:disable Style/SlicingWithRange, Lint/RedundantCopDisableDirective
135
+ span_id = ::Instana::Util.header_to_id(matches['parent'])
136
+
93
137
  {
94
138
  external_trace_id: matches['trace'],
95
139
  external_state: @env['HTTP_TRACESTATE'],
96
- trace_id: ::Instana::Util.header_to_id(matches['trace'][16..-1]), # rubocop:disable Style/SlicingWithRange, Lint/RedundantCopDisableDirective
97
- span_id: ::Instana::Util.header_to_id(matches['parent'])
140
+ trace_id: trace_id,
141
+ span_id: span_id,
142
+ from_w3: true
98
143
  }
99
144
  end
100
145
 
146
+ def context_from_trace_state
147
+ state = parse_trace_state
148
+
149
+ {
150
+ trace_id: state[:t],
151
+ span_id: state[:p],
152
+ from_w3: false
153
+ }.compact
154
+ end
155
+
101
156
  def parse_trace_state
102
157
  return {} unless @env.has_key?('HTTP_TRACESTATE')
103
158
  token = @env['HTTP_TRACESTATE']
@@ -19,14 +19,16 @@ module Instana
19
19
 
20
20
  # Set request headers; encode IDs as hexadecimal strings
21
21
  t_context = ::Instana.tracer.context
22
- request['X-Instana-T'] = t_context.trace_id_header
23
- request['X-Instana-S'] = t_context.span_id_header
22
+ request['X-Instana-L'] = t_context.level.to_s
24
23
 
25
- if ::Instana.config[:w3_trace_correlation]
26
- request['Traceparent'] = t_context.trace_parent_header
27
- request['Tracestate'] = t_context.trace_state_header
24
+ if t_context.active?
25
+ request['X-Instana-T'] = t_context.trace_id_header
26
+ request['X-Instana-S'] = t_context.span_id_header
28
27
  end
29
28
 
29
+ request['Traceparent'] = t_context.trace_parent_header
30
+ request['Tracestate'] = t_context.trace_state_header unless t_context.trace_state_header.empty?
31
+
30
32
  # Collect up KV info now in case any exception is raised
31
33
  kv_payload = { :http => {} }
32
34
  kv_payload[:http][:method] = request.method
@@ -12,7 +12,6 @@ module Instana
12
12
 
13
13
  def call(env)
14
14
  req = InstrumentedRequest.new(env)
15
- return @app.call(env) if req.skip_trace?
16
15
  kvs = {
17
16
  http: req.request_tags,
18
17
  service: ENV['INSTANA_SERVICE_NAME']
@@ -34,12 +33,16 @@ module Instana
34
33
 
35
34
  if req.continuing_from_trace_parent?
36
35
  current_span[:tp] = true
37
- current_span[:lt] = req.incoming_context[:external_trace_id]
36
+ end
37
+
38
+ if req.external_trace_id?
39
+ current_span[:lt] = req.external_trace_id
38
40
  end
39
41
 
40
42
  if req.synthetic?
41
43
  current_span[:sy] = true
42
44
  end
45
+
43
46
  # In case some previous middleware returned a string status, make sure that we're dealing with
44
47
  # an integer. In Ruby nil.to_i, "asdfasdf".to_i will always return 0 from Ruby versions 1.8.7 and newer.
45
48
  # So if an 0 status is reported here, it indicates some other issue (e.g. no status from previous middleware)
@@ -70,15 +73,17 @@ module Instana
70
73
  if ::Instana.tracer.tracing?
71
74
  if headers
72
75
  # Set response headers; encode as hex string
73
- headers['X-Instana-T'] = trace_context.trace_id_header
74
- headers['X-Instana-S'] = trace_context.span_id_header
75
- headers['X-Instana-L'] = '1'
76
+ if trace_context.active?
77
+ headers['X-Instana-T'] = trace_context.trace_id_header
78
+ headers['X-Instana-S'] = trace_context.span_id_header
79
+ headers['X-Instana-L'] = '1'
76
80
 
77
- if ::Instana.config[:w3_trace_correlation]
78
- headers['Traceparent'] = trace_context.trace_parent_header
79
81
  headers['Tracestate'] = trace_context.trace_state_header
82
+ else
83
+ headers['X-Instana-L'] = '0'
80
84
  end
81
85
 
86
+ headers['Traceparent'] = trace_context.trace_parent_header
82
87
  headers['Server-Timing'] = "intid;desc=#{trace_context.trace_id_header}"
83
88
  end
84
89
 
@@ -5,7 +5,7 @@ require 'thread'
5
5
 
6
6
  module Instana
7
7
  class Processor
8
- def initialize
8
+ def initialize(logger: ::Instana.logger)
9
9
  # The main queue before being reported to the
10
10
  # host agent. Spans in this queue are complete
11
11
  # and ready to be sent.
@@ -14,12 +14,22 @@ module Instana
14
14
  # This is the maximum number of spans we send to the host
15
15
  # agent at once.
16
16
  @batch_size = 3000
17
+ @logger = logger
18
+ @pid = $PROCESS_ID
17
19
  end
18
20
 
19
21
  # Adds a span to the span queue
20
22
  #
21
23
  # @param [Trace] - the trace to be added to the queue
22
24
  def add_span(span)
25
+ # :nocov:
26
+ if @pid != $PROCESS_ID
27
+ @logger.info("Proces `#{@pid}` has forked into #{$PROCESS_ID}. Resetting discovery.")
28
+ ::Instana.agent.spawn_background_thread
29
+ @pid = $PROCESS_ID
30
+ end
31
+ # :nocov:
32
+
23
33
  @queue.push(span)
24
34
  end
25
35
 
@@ -28,9 +28,15 @@ module Instana
28
28
  if parent_ctx.is_a?(::Instana::SpanContext)
29
29
  @is_root = false
30
30
 
31
- @data[:t] = parent_ctx.trace_id # Trace ID
31
+ # If we have a parent trace, link to it
32
+ if parent_ctx.trace_id
33
+ @data[:t] = parent_ctx.trace_id # Trace ID
34
+ @data[:p] = parent_ctx.span_id # Parent ID
35
+ else
36
+ @data[:t] = ::Instana::Util.generate_id
37
+ end
38
+
32
39
  @data[:s] = ::Instana::Util.generate_id # Span ID
33
- @data[:p] = parent_ctx.span_id # Parent ID
34
40
 
35
41
  @baggage = parent_ctx.baggage.dup
36
42
  @level = parent_ctx.level
@@ -31,19 +31,22 @@ module Instana
31
31
  end
32
32
 
33
33
  def trace_parent_header
34
- return '' unless valid?
35
-
36
- trace = (@baggage[:external_trace_id] || @trace_id).rjust(32, '0')
37
- parent = @span_id.rjust(16, '0')
34
+ trace = (@baggage[:external_trace_id] || trace_id_header).rjust(32, '0')
35
+ parent = span_id_header.rjust(16, '0')
38
36
  flags = @level == 1 ? "01" : "00"
39
37
 
40
38
  "00-#{trace}-#{parent}-#{flags}"
41
39
  end
42
40
 
43
41
  def trace_state_header
44
- return '' unless valid?
42
+ external_state = @baggage[:external_state] || ''
43
+ state = external_state.split(/,/)
44
+
45
+ if @level == 1
46
+ state = state.reject { |s| s.start_with?('in=') }
47
+ state.unshift("in=#{trace_id_header};#{span_id_header}")
48
+ end
45
49
 
46
- state = ["in=#{trace_id_header};#{span_id_header}", @baggage[:external_state]]
47
50
  state.compact.join(',')
48
51
  end
49
52
 
@@ -51,10 +54,12 @@ module Instana
51
54
  { :trace_id => @trace_id, :span_id => @span_id }
52
55
  end
53
56
 
54
- private
55
-
56
57
  def valid?
57
- @baggage && @trace_id && @span_id
58
+ @baggage && @trace_id && !@trace_id.emtpy?
59
+ end
60
+
61
+ def active?
62
+ @level == 1
58
63
  end
59
64
  end
60
65
  end
data/lib/instana/util.rb CHANGED
@@ -156,8 +156,10 @@ module Instana
156
156
  #
157
157
  # @return [String]
158
158
  #
159
- def header_to_id(header_id)
160
- header_id.is_a?(String) && header_id.match(/\A[a-z\d]{16,32}\z/i) ? header_id : ''
159
+ def header_to_id(given)
160
+ return '' unless given.is_a?(String)
161
+ return '' unless given.match(/\A[a-z\d]{16,32}\z/i)
162
+ given
161
163
  end
162
164
  end
163
165
  end
@@ -2,6 +2,6 @@
2
2
  # (c) Copyright Instana Inc. 2016
3
3
 
4
4
  module Instana
5
- VERSION = "1.197.0.pre1"
5
+ VERSION = "1.197.0.pre2"
6
6
  VERSION_FULL = "instana-#{VERSION}"
7
7
  end
@@ -4,6 +4,10 @@
4
4
  require 'test_helper'
5
5
 
6
6
  class HostAgentActivationObserverTest < Minitest::Test
7
+ def setup
8
+ @socket_proc = ->(_c) { OpenStruct.new(fileno: 0) }
9
+ end
10
+
7
11
  def test_standard_discovery
8
12
  stub_request(:put, "http://10.10.10.10:9292/com.instana.plugin.ruby.discovery")
9
13
  .and_timeout
@@ -17,7 +21,7 @@ class HostAgentActivationObserverTest < Minitest::Test
17
21
  client = Instana::Backend::RequestClient.new('10.10.10.10', 9292)
18
22
  discovery = Concurrent::Atom.new(nil)
19
23
 
20
- subject = Instana::Backend::HostAgentActivationObserver.new(client, discovery, wait_time: 0, logger: Logger.new('/dev/null'), max_wait_tries: 1)
24
+ subject = Instana::Backend::HostAgentActivationObserver.new(client, discovery, wait_time: 0, logger: Logger.new('/dev/null'), max_wait_tries: 1, socket_proc: @socket_proc)
21
25
 
22
26
  subject.update(nil, nil, nil)
23
27
  assert_equal({'pid' => 1234}, discovery.value)
@@ -31,15 +35,18 @@ class HostAgentActivationObserverTest < Minitest::Test
31
35
  .and_return(status: 200, body: '{"ok": true}')
32
36
 
33
37
  client = Instana::Backend::RequestClient.new('10.10.10.10', 9292)
34
- # This is the cleanest way to fake it so it works across all test environments
35
- client.define_singleton_method(:fileno) { '0' }
36
- client.define_singleton_method(:inode) { '0' }
37
-
38
38
  discovery = Concurrent::Atom.new(nil)
39
39
 
40
- subject = Instana::Backend::HostAgentActivationObserver.new(client, discovery, wait_time: 0, logger: Logger.new('/dev/null'), max_wait_tries: 1)
40
+ subject = Instana::Backend::HostAgentActivationObserver.new(client, discovery, wait_time: 0, logger: Logger.new('/dev/null'), max_wait_tries: 1, socket_proc: @socket_proc)
41
41
 
42
- subject.update(nil, nil, nil)
42
+ FakeFS.with_fresh do
43
+ FakeFS::FileSystem.clone('test/support/proc', '/proc')
44
+ FakeFS::FileSystem.clone('test/support/proc/0', "/proc/#{Process.pid}")
45
+ Dir.mkdir('/proc/self/fd')
46
+ File.symlink('/proc/self/sched', "/proc/self/fd/0")
47
+
48
+ subject.update(nil, nil, nil)
49
+ end
43
50
 
44
51
  assert_equal({'pid' => 1234}, discovery.value)
45
52
  end
@@ -48,7 +55,7 @@ class HostAgentActivationObserverTest < Minitest::Test
48
55
  client = Instana::Backend::RequestClient.new('10.10.10.10', 9292)
49
56
  discovery = Concurrent::Atom.new(nil)
50
57
 
51
- subject = Instana::Backend::HostAgentActivationObserver.new(client, discovery, wait_time: 0, logger: Logger.new('/dev/null'), proc_table: nil)
58
+ subject = Instana::Backend::HostAgentActivationObserver.new(client, discovery, wait_time: 0, logger: Logger.new('/dev/null'), proc_table: nil, socket_proc: @socket_proc)
52
59
 
53
60
  subject.update(nil, nil, nil)
54
61
  assert_nil discovery.value
@@ -58,7 +65,7 @@ class HostAgentActivationObserverTest < Minitest::Test
58
65
  client = Instana::Backend::RequestClient.new('10.10.10.10', 9292)
59
66
  discovery = Concurrent::Atom.new(nil)
60
67
 
61
- subject = Instana::Backend::HostAgentActivationObserver.new(client, discovery)
68
+ subject = Instana::Backend::HostAgentActivationObserver.new(client, discovery, socket_proc: @socket_proc)
62
69
  assert_nil subject.update(nil, nil, true)
63
70
  assert_nil discovery.value
64
71
  end
@@ -4,19 +4,34 @@
4
4
  require 'test_helper'
5
5
 
6
6
  class HostAgentTest < Minitest::Test
7
- def test_setup
7
+ def test_spawn_background_thread
8
8
  ENV['INSTANA_TEST'] = nil
9
9
  ::Instana.config[:agent_host] = '10.10.10.10'
10
10
 
11
+ if File.exist?('/sbin/ip')
12
+ addr = `/sbin/ip route | awk '/default/ { print $3 }'`.strip
13
+ stub_request(:get, "http://#{addr}:42699/")
14
+ .to_timeout
15
+ end
16
+
11
17
  stub_request(:get, "http://10.10.10.10:42699/")
18
+ .to_timeout.times(3).then
12
19
  .to_return(status: 200, body: "", headers: {})
13
20
 
14
21
  discovery = Minitest::Mock.new
22
+ discovery.expect(:delete_observers, discovery, [])
15
23
  discovery.expect(:with_observer, discovery, [Instana::Backend::HostAgentActivationObserver])
16
24
  discovery.expect(:with_observer, discovery, [Instana::Backend::HostAgentReportingObserver])
25
+ discovery.expect(:swap, discovery, [])
17
26
 
18
27
  subject = Instana::Backend::HostAgent.new(discovery: discovery)
19
- subject.setup
28
+
29
+ FakeFS.with_fresh do
30
+ FakeFS::FileSystem.clone('test/support/ecs', '/proc')
31
+ subject.spawn_background_thread
32
+ end
33
+
34
+ subject.future.value!
20
35
 
21
36
  discovery.verify
22
37
  ensure
@@ -36,26 +36,4 @@ class RequestClientTest < Minitest::Test
36
36
 
37
37
  refute response.ok?
38
38
  end
39
-
40
- def test_fileno
41
- subject = Instana::Backend::RequestClient.new('example.com', 9292)
42
- assert_nil subject.fileno
43
- end
44
-
45
- def test_inode
46
- subject = Instana::Backend::RequestClient.new('example.com', 9292)
47
- subject.define_singleton_method(:fileno) { '0' } # This is the cleanest way to fake it so it works across all test environments
48
- FakeFS.with_fresh do
49
- FakeFS::FileSystem.clone('test/support/proc', '/proc')
50
- Dir.mkdir('/proc/self/fd')
51
- File.symlink('/proc/self/sched', '/proc/self/fd/0')
52
-
53
- assert_equal '/proc/self/sched', subject.inode
54
- end
55
- end
56
-
57
- def test_inode_no_proc
58
- subject = Instana::Backend::RequestClient.new('example.com', 9292)
59
- assert_nil subject.inode
60
- end
61
39
  end
@@ -29,6 +29,7 @@ class RackInstrumentedRequestTest < Minitest::Test
29
29
  expected = {
30
30
  trace_id: id,
31
31
  span_id: id,
32
+ from_w3: false,
32
33
  level: '1'
33
34
  }
34
35
 
@@ -47,6 +48,7 @@ class RackInstrumentedRequestTest < Minitest::Test
47
48
  external_state: nil,
48
49
  trace_id: 'a3ce929d0e0e4736',
49
50
  span_id: '00f067aa0ba902b7',
51
+ from_w3: true,
50
52
  level: '1'
51
53
  }
52
54
 
data/test/test_helper.rb CHANGED
@@ -45,7 +45,7 @@ require 'fakefs/safe'
45
45
  require 'webmock/minitest'
46
46
  # Webmock: Whitelist local IPs
47
47
  WebMock.disable_net_connect!(
48
- allow: ->(uri) { %w[localhost 127.0.0.1 172.17.0.1 172.0.12.100].include?(uri.host) }
48
+ allow: ->(uri) { %w[localhost 127.0.0.1 172.17.0.1 172.0.12.100].include?(uri.host) && ENV.key?('APPRAISAL_INITIALIZED') }
49
49
  )
50
50
 
51
51
  Dir['test/support/*.rb'].each { |f| load(f) }
@@ -11,8 +11,7 @@ class SpanContextTest < Minitest::Test
11
11
 
12
12
  def test_invalid
13
13
  subject = Instana::SpanContext.new(nil, nil)
14
- assert subject.trace_parent_header.empty?
15
- assert subject.trace_state_header.empty?
14
+ refute subject.valid?
16
15
  end
17
16
 
18
17
  def test_flags_level_zero
@@ -46,6 +46,15 @@ class SpanTest < Minitest::Test
46
46
  assert_equal 'test', span.trace_id
47
47
  end
48
48
 
49
+ def test_span_from_contetx_invalid
50
+ context = Instana::SpanContext.new(nil, nil, 1)
51
+ span = Instana::Span.new(:test, parent_ctx: context)
52
+
53
+ assert_nil span.parent_id
54
+ refute_equal context.span_id, span.trace_id
55
+ assert_equal 1, span.context.level
56
+ end
57
+
49
58
  def test_span_collect_backtraces
50
59
  Instana.config[:collect_backtraces] = true
51
60
  span = Instana::Span.new(:excon)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: instana
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.197.0.pre1
4
+ version: 1.197.0.pre2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Giacomo Lombardo
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-03-30 00:00:00.000000000 Z
11
+ date: 2021-04-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler