instana 1.197.0.pre1 → 1.197.0.pre2

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: 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