Skip to content

Commit 013ecee

Browse files
committed
quick fix
1 parent 69f955c commit 013ecee

File tree

4 files changed

+77
-18
lines changed

4 files changed

+77
-18
lines changed

lib/datadog/di/code_tracker.rb

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -140,16 +140,23 @@ def iseqs_for_path_suffix(suffix)
140140
exact = registry[suffix]
141141
return [suffix, exact] if exact
142142

143-
inexact = []
144-
registry.each do |path, iseq|
145-
if Utils.path_matches_suffix?(path, suffix)
146-
inexact << [path, iseq]
143+
suffix = suffix.dup
144+
loop do
145+
inexact = []
146+
registry.each do |path, iseq|
147+
if Utils.path_matches_suffix?(path, suffix)
148+
inexact << [path, iseq]
149+
end
147150
end
151+
if inexact.length > 1
152+
raise Error::MultiplePathsMatch, "Multiple paths matched requested suffix"
153+
end
154+
if inexact.any?
155+
return inexact.first
156+
end
157+
return nil unless suffix.include?('/')
158+
suffix.sub!(%r,.*/+,, '')
148159
end
149-
if inexact.length > 1
150-
raise Error::MultiplePathsMatch, "Multiple paths matched requested suffix"
151-
end
152-
inexact.first
153160
end
154161
end
155162

lib/datadog/di/probe.rb

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -155,19 +155,16 @@ def location
155155
# Returns whether the provided +path+ matches the user-designated
156156
# file (of a line probe).
157157
#
158-
# If file is an absolute path (i.e., it starts with a slash), the file
159-
# must be identical to path to match.
160-
#
161-
# If file is not an absolute path, the path matches if the file is its suffix,
162-
# at a path component boundary.
158+
# Delegates to Utils.path_can_match_spec? which performs fuzzy
159+
# matching. See the comments in utils.rb for details.
163160
def file_matches?(path)
164161
if path.nil?
165162
raise ArgumentError, "Cannot match against a nil path"
166163
end
167164
unless file
168165
raise ArgumentError, "Probe does not have a file to match against"
169166
end
170-
Utils.path_matches_suffix?(path, file)
167+
Utils.path_can_match_spec?(path, file)
171168
end
172169

173170
# Instrumentation module for method probes.

lib/datadog/di/utils.rb

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
module Datadog
44
module DI
55
module Utils
6-
# Returns whether the provided +path+ matches the user-designated
7-
# file suffix or path (of a line probe).
6+
# General path matching considerations
7+
# ------------------------------------
88
#
99
# The following use cases must be supported:
1010
# 1. The "probe path" is relative path to the file from source code
@@ -29,7 +29,7 @@ module Utils
2929
# specification in the probe, the tracer must return an error to the
3030
# backend/UI rather than instrumenting any of the matching paths.
3131
#
32-
# The logic for path matching is therefore, generally, as follows:
32+
# The logic for path matching should therefore, generally, be as follows:
3333
# 1. If the "probe path" is absolute, see if it exists at runtime.
3434
# If so, take it as the desired path and finish.
3535
# 2. Attempt to identify the application root, by checking if the current
@@ -75,6 +75,12 @@ module Utils
7575
# indefinitely cache whether a particular filesystem paths exists
7676
# in both positive and negative.
7777
#
78+
# As a "quick fix", currently after performing the suffix matching
79+
# we just strip leading directory components from the "probe path"
80+
# until we get a match via a "suffix of the suffix".
81+
82+
# Returns whether the provided +path+ matches the user-designated
83+
# file suffix (of a line probe).
7884
#
7985
# If suffix is an absolute path (i.e., it starts with a slash), the path
8086
# must be identical for it to match.
@@ -111,6 +117,21 @@ module Utils
111117
# !!(path =~ %r,(/|\A)#{Regexp.quote(suffix)}\z,)
112118
end
113119
end
120+
121+
# Returns whether the provided +path+ matches the "probe path" in
122+
# +spec+. Attempts all of the fuzzy matches by stripping directories
123+
# from the front of +spec+. Does not consider othr known paths to
124+
# identify the case of (potentially) multiple matching paths for +spec+.
125+
module_function def path_can_match_spec?(path, spec)
126+
return true if path_matches_suffix?(path, spec)
127+
128+
spec = spec.dup
129+
loop do
130+
return false unless spec.include?('/')
131+
spec.sub!(%r,.*/+,, '')
132+
return true if path_matches_suffix?(path, spec)
133+
end
134+
end
114135
end
115136
end
116137
end

spec/datadog/di/utils_spec.rb

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
di_test
66

77
describe '.path_matches_suffix?' do
8+
# NB; when updating this list also add to the list in
9+
# path_can_match_spec? test below.
810
[
911
['exact match - absolute path', '/foo/bar.rb', '/foo/bar.rb', true],
1012
# Suffix matching is only applicable to relative paths.
@@ -15,7 +17,7 @@
1517
['extra leading slash in file', '//foo/bar.rb', '/foo/bar.rb', false],
1618
['extra slash in the middle of file', 'foo//bar.rb', '/foo/bar.rb', false],
1719
['nothing in common', 'blah.rb', '/foo/bar.rb', false],
18-
['path is a suffix of file', '/a/foo/bar.rbr', '/foo/bar.rb', false],
20+
['path is a suffix of file', '/a/foo/bar.rb', '/foo/bar.rb', false],
1921

2022
# We expect path to always be an absolute path.
2123
['path is relative', 'bar.rb', 'bar.rb', false],
@@ -29,4 +31,36 @@
2931
end
3032
end
3133
end
34+
35+
describe '.path_can_match_spec?' do
36+
# NB; when updating this list also add to the list in
37+
# path_matches_suffix? test above.
38+
[
39+
['exact match - absolute path', '/foo/bar.rb', '/foo/bar.rb', true],
40+
# Prefixes of suffix are removed until there is a match
41+
['absolute path is a suffix', '/bar.rb', '/foo/bar.rb', true],
42+
# ... but not if basename does not match
43+
['absolute path is a suffix', '/bar.rb', '/foo/bar1.rb', false],
44+
['suffix - multiple path components', 'foo/bar.rb', '/foo/bar.rb', true],
45+
['suffix - at basename', 'bar.rb', '/foo/bar.rb', true],
46+
['suffix - not at path component boundary', 'ar.rb', '/foo/bar.rb', false],
47+
# Extra leading slashes are removed
48+
['extra leading slash in file', '//foo/bar.rb', '/foo/bar.rb', true],
49+
# Extra slashes in the middle are also removed
50+
['extra slash in the middle of file', 'foo//bar.rb', '/foo/bar.rb', true],
51+
['nothing in common', 'blah.rb', '/foo/bar.rb', false],
52+
['path is a suffix of file', '/a/foo/bar.rb', '/foo/bar.rb', true],
53+
54+
# We expect path to always be an absolute path.
55+
['path is relative', 'bar.rb', 'bar.rb', false],
56+
].each do |name, suffix_, path_, result_|
57+
suffix, path, result = suffix_, path_, result_
58+
59+
context name do
60+
it "is #{result}" do
61+
expect(described_class.path_can_match_spec?(path, suffix)).to be result
62+
end
63+
end
64+
end
65+
end
3266
end

0 commit comments

Comments
 (0)