tracing-matchers 1.0.0
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 +7 -0
- data/.gitignore +12 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/.travis.yml +6 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +10 -0
- data/LICENSE +201 -0
- data/README.md +169 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/tracing/matchers.rb +155 -0
- data/lib/tracing/matchers/have_span.rb +101 -0
- data/lib/tracing/matchers/have_spans.rb +80 -0
- data/lib/tracing/matchers/have_traces.rb +89 -0
- data/lib/tracing/matchers/span/be_child_of.rb +99 -0
- data/lib/tracing/matchers/span/have_baggage.rb +50 -0
- data/lib/tracing/matchers/span/have_log.rb +51 -0
- data/lib/tracing/matchers/span/have_tag.rb +50 -0
- data/lib/tracing/matchers/span_matchers.rb +72 -0
- data/lib/tracing/matchers/version.rb +5 -0
- data/tracing-matchers.gemspec +29 -0
- metadata +122 -0
@@ -0,0 +1,99 @@
|
|
1
|
+
module Tracing
|
2
|
+
module Matchers
|
3
|
+
module Span
|
4
|
+
# @private
|
5
|
+
class BeChildOf
|
6
|
+
def initialize(parent)
|
7
|
+
@expected = parent
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [Boolean]
|
11
|
+
def matches?(span)
|
12
|
+
@tracer = span.tracer
|
13
|
+
@subject = span
|
14
|
+
# actual is either Span, or SpanContext
|
15
|
+
@actual = parent_of(@subject)
|
16
|
+
|
17
|
+
case
|
18
|
+
when any? then !!@actual
|
19
|
+
when @actual.nil? && @expected then false
|
20
|
+
else
|
21
|
+
expected_span_id == actual_span_id
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [String]
|
26
|
+
def description
|
27
|
+
any? ? "have a parent" : "have #{expected_message} as the parent"
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [String]
|
31
|
+
def failure_message
|
32
|
+
any? ? "expected a parent" : "expected #{expected_message} as the parent, got #{actual_message}"
|
33
|
+
end
|
34
|
+
alias :failure_message_for_should :failure_message
|
35
|
+
|
36
|
+
# @return [String]
|
37
|
+
def failure_message_when_negated
|
38
|
+
any? ? "did not expect the parent" : "did not expect #{expected_message} parent, got #{actual_message}"
|
39
|
+
end
|
40
|
+
alias :failure_message_for_should_not :failure_message_when_negated
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def any?
|
45
|
+
@expected == :any
|
46
|
+
end
|
47
|
+
|
48
|
+
def parent_of(subject)
|
49
|
+
return nil unless subject.context.parent_span_id
|
50
|
+
|
51
|
+
parent_span = @tracer
|
52
|
+
.spans
|
53
|
+
.find { |span| span.context.span_id == subject.context.parent_span_id }
|
54
|
+
|
55
|
+
parent_span || subject.context
|
56
|
+
end
|
57
|
+
|
58
|
+
def actual_span_id
|
59
|
+
case
|
60
|
+
when @actual.respond_to?(:context) then @actual.context.span_id
|
61
|
+
when @actual.respond_to?(:parent_span_id) then @actual.parent_span_id
|
62
|
+
else @actual
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def expected_span_id
|
67
|
+
case
|
68
|
+
when @expected.respond_to?(:context) then @expected.context.span_id
|
69
|
+
when @expected.respond_to?(:span_id) then @expected.span_id
|
70
|
+
when @expected.is_a?(String) then @tracer.spans.find { |span| span.operation_name == @expected }&.context&.span_id
|
71
|
+
else @expected
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def expected_spans(tracer)
|
76
|
+
tracer.spans.select { |span| span.operation_name == @expected }
|
77
|
+
end
|
78
|
+
|
79
|
+
def expected_message
|
80
|
+
case
|
81
|
+
when @expected.respond_to?(:context) then "the span with operation name \"#{@expected.operation_name}\""
|
82
|
+
when @expected.respond_to?(:span_id) then "the span context with id \"#{@expected.span_id}\""
|
83
|
+
when @expected.is_a?(String) then "a span with operation name \"#{@expected}\""
|
84
|
+
else nil
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def actual_message
|
89
|
+
case
|
90
|
+
when @actual.respond_to?(:operation_name) then "a span with operation name \"#{@actual.operation_name}\""
|
91
|
+
when @actual.respond_to?(:parent_span_id) then "a span context with id \"#{@actual.parent_span_id}\""
|
92
|
+
when @actual.nil? then "nothing"
|
93
|
+
else @actual
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Tracing
|
2
|
+
module Matchers
|
3
|
+
module Span
|
4
|
+
# @private
|
5
|
+
class HaveBaggage
|
6
|
+
def initialize(*args)
|
7
|
+
@expected = args.last.is_a?(Hash) ? args.delete_at(-1) : Hash.new
|
8
|
+
args.each_slice(2) { |k, v| @expected[k] = v }
|
9
|
+
end
|
10
|
+
|
11
|
+
# @return [Boolean]
|
12
|
+
def matches?(span)
|
13
|
+
@subject = span
|
14
|
+
@actual = span.context.baggage
|
15
|
+
|
16
|
+
if any?
|
17
|
+
@actual.any?
|
18
|
+
else
|
19
|
+
@expected.all? { |k, v| @actual.key?(k) && v == @actual[k] }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# @return [String]
|
24
|
+
def description
|
25
|
+
desc = "have baggage"
|
26
|
+
desc << " #{@expected}" unless any?
|
27
|
+
desc
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [String]
|
31
|
+
def failure_message
|
32
|
+
any? ? "expected any baggage" : "expected #{@expected} baggage, got #{@actual}"
|
33
|
+
end
|
34
|
+
alias :failure_message_for_should :failure_message
|
35
|
+
|
36
|
+
# @return [String]
|
37
|
+
def failure_message_when_negated
|
38
|
+
any? ? "did not expect any baggage" : "did not expect #{@expected} baggage, got #{@actual}"
|
39
|
+
end
|
40
|
+
alias :failure_message_for_should_not :failure_message_when_negated
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def any?
|
45
|
+
@expected.empty?
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Tracing
|
2
|
+
module Matchers
|
3
|
+
module Span
|
4
|
+
# @private
|
5
|
+
class HaveLog
|
6
|
+
def initialize(**fields)
|
7
|
+
@expected = fields
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [Boolean]
|
11
|
+
def matches?(span)
|
12
|
+
@subject = span
|
13
|
+
@actual = span.logs.map { |log| log.fields.dup.tap { |h| h[:event] = log.event } }
|
14
|
+
|
15
|
+
if any?
|
16
|
+
@actual.any?
|
17
|
+
else
|
18
|
+
@actual.any? do |log|
|
19
|
+
@expected.all? { |k, v| log.key?(k) && v == log[k] }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [String]
|
25
|
+
def description
|
26
|
+
desc = "have log entry"
|
27
|
+
desc << " #{@expected}" unless any?
|
28
|
+
desc
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [String]
|
32
|
+
def failure_message
|
33
|
+
any? ? "expected any log entry" : "expected #{@expected} log entry, got #{@actual}"
|
34
|
+
end
|
35
|
+
alias :failure_message_for_should :failure_message
|
36
|
+
|
37
|
+
# @return [String]
|
38
|
+
def failure_message_when_negated
|
39
|
+
any? ? "did not expect any log entry" : "did not expect #{@expected} log entry, got #{@actual}"
|
40
|
+
end
|
41
|
+
alias :failure_message_for_should_not :failure_message_when_negated
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def any?
|
46
|
+
@expected.empty?
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Tracing
|
2
|
+
module Matchers
|
3
|
+
module Span
|
4
|
+
# @private
|
5
|
+
class HaveTag
|
6
|
+
def initialize(*args)
|
7
|
+
@expected = args.last.is_a?(Hash) ? args.delete_at(-1) : Hash.new
|
8
|
+
args.each_slice(2) { |k, v| @expected[k] = v }
|
9
|
+
end
|
10
|
+
|
11
|
+
# @return [Boolean]
|
12
|
+
def matches?(span)
|
13
|
+
@subject = span
|
14
|
+
@actual = span.tags
|
15
|
+
|
16
|
+
if any?
|
17
|
+
@actual.any?
|
18
|
+
else
|
19
|
+
@expected.all? { |k, v| @actual.key?(k) && v == @actual[k] }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# @return [String]
|
24
|
+
def description
|
25
|
+
desc = "have tags"
|
26
|
+
desc << " #{@expected}" unless any?
|
27
|
+
desc
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [String]
|
31
|
+
def failure_message
|
32
|
+
any? ? "expected any tag" : "expected #{@expected} tags, got #{@actual}"
|
33
|
+
end
|
34
|
+
alias :failure_message_for_should :failure_message
|
35
|
+
|
36
|
+
# @return [String]
|
37
|
+
def failure_message_when_negated
|
38
|
+
any? ? "did not expect any tag" : "did not expect #{@expected} tags, got #{@actual}"
|
39
|
+
end
|
40
|
+
alias :failure_message_for_should_not :failure_message_when_negated
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def any?
|
45
|
+
@expected.empty?
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require "tracing/matchers/span/have_tag"
|
2
|
+
require "tracing/matchers/span/have_log"
|
3
|
+
require "tracing/matchers/span/have_baggage"
|
4
|
+
require "tracing/matchers/span/be_child_of"
|
5
|
+
|
6
|
+
module Tracing
|
7
|
+
module Matchers
|
8
|
+
# The `have_tag` matcher tests that the span includes tags.
|
9
|
+
# @example
|
10
|
+
#
|
11
|
+
# # Passes if span have any tag
|
12
|
+
# expect(span).to have_tag
|
13
|
+
#
|
14
|
+
# # Passes if span includes a tag with "tag" key, and "value" value
|
15
|
+
# expect(span).to have_tag("key", "value")
|
16
|
+
# expect(span).to have_tag("key" => "value")
|
17
|
+
#
|
18
|
+
# @return [HaveTag]
|
19
|
+
def have_tag(*args)
|
20
|
+
Tracing::Matchers::Span::HaveTag.new(*args)
|
21
|
+
end
|
22
|
+
alias :have_tags :have_tag
|
23
|
+
|
24
|
+
# The `have_log` matcher tests that the span includes a tag.
|
25
|
+
# @example
|
26
|
+
#
|
27
|
+
# # Passes if span have any log
|
28
|
+
# expect(span).to have_log
|
29
|
+
#
|
30
|
+
# # Passes if span includes a log entry with event: "error"
|
31
|
+
# expect(span).to have_log(event: "error")
|
32
|
+
#
|
33
|
+
# @return [HaveTag]
|
34
|
+
def have_log(**fields)
|
35
|
+
Tracing::Matchers::Span::HaveLog.new(**fields)
|
36
|
+
end
|
37
|
+
alias :have_logs :have_log
|
38
|
+
|
39
|
+
# The `have_baggage` matcher tests that the span/span context includes baggage.
|
40
|
+
# @example
|
41
|
+
#
|
42
|
+
# # Passes if span have any baggage item
|
43
|
+
# expect(span).to have_baggage
|
44
|
+
#
|
45
|
+
# # Passes if span includes a baggage item with "tag" key, and "value" value
|
46
|
+
# expect(span).to have_baggage("key", "value")
|
47
|
+
# expect(span).to have_baggage("key" => "value")
|
48
|
+
#
|
49
|
+
# @return [HaveBaggage]
|
50
|
+
def have_baggage(*args)
|
51
|
+
Tracing::Matchers::Span::HaveBaggage.new(*args)
|
52
|
+
end
|
53
|
+
alias :have_baggage_item :have_baggage
|
54
|
+
|
55
|
+
# The `be_child_of` matcher tests that the span/span context is a child of some other span/span context.
|
56
|
+
# @example
|
57
|
+
#
|
58
|
+
# # Passes if span is a child of any span
|
59
|
+
# expect(span).to have_parent
|
60
|
+
#
|
61
|
+
# # Passes if span is a child of a specific span context
|
62
|
+
# expect(span).to be_child_of("parent operation")
|
63
|
+
# expect(span).to be_child_of(parent_span)
|
64
|
+
# expect(span).to be_child_of(parent_span_context)
|
65
|
+
#
|
66
|
+
# @return [HaveBaggage]
|
67
|
+
def be_child_of(parent = :any)
|
68
|
+
Tracing::Matchers::Span::BeChildOf.new(parent)
|
69
|
+
end
|
70
|
+
alias :have_parent :be_child_of
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "tracing/matchers/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "tracing-matchers"
|
8
|
+
spec.version = Tracing::Matchers::VERSION
|
9
|
+
spec.authors = ["iaintshine"]
|
10
|
+
spec.email = ["bodziomista@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{RSpec matchers for testing mocked OpenTracing instrumentations}
|
13
|
+
spec.description = %q{}
|
14
|
+
spec.homepage = "https://github.com/iaintshine/ruby-tracing-matchers"
|
15
|
+
spec.license = "Apache-2.0"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
19
|
+
end
|
20
|
+
spec.bindir = "exe"
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_dependency "test-tracer", "~> 1.1"
|
25
|
+
spec.add_dependency "rspec", ">= 2.0"
|
26
|
+
|
27
|
+
spec.add_development_dependency "bundler", "~> 1.15"
|
28
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tracing-matchers
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- iaintshine
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-08-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: test-tracer
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.15'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.15'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
description: ''
|
70
|
+
email:
|
71
|
+
- bodziomista@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- ".rspec"
|
78
|
+
- ".ruby-version"
|
79
|
+
- ".travis.yml"
|
80
|
+
- CODE_OF_CONDUCT.md
|
81
|
+
- Gemfile
|
82
|
+
- LICENSE
|
83
|
+
- README.md
|
84
|
+
- Rakefile
|
85
|
+
- bin/console
|
86
|
+
- bin/setup
|
87
|
+
- lib/tracing/matchers.rb
|
88
|
+
- lib/tracing/matchers/have_span.rb
|
89
|
+
- lib/tracing/matchers/have_spans.rb
|
90
|
+
- lib/tracing/matchers/have_traces.rb
|
91
|
+
- lib/tracing/matchers/span/be_child_of.rb
|
92
|
+
- lib/tracing/matchers/span/have_baggage.rb
|
93
|
+
- lib/tracing/matchers/span/have_log.rb
|
94
|
+
- lib/tracing/matchers/span/have_tag.rb
|
95
|
+
- lib/tracing/matchers/span_matchers.rb
|
96
|
+
- lib/tracing/matchers/version.rb
|
97
|
+
- tracing-matchers.gemspec
|
98
|
+
homepage: https://github.com/iaintshine/ruby-tracing-matchers
|
99
|
+
licenses:
|
100
|
+
- Apache-2.0
|
101
|
+
metadata: {}
|
102
|
+
post_install_message:
|
103
|
+
rdoc_options: []
|
104
|
+
require_paths:
|
105
|
+
- lib
|
106
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
requirements: []
|
117
|
+
rubyforge_project:
|
118
|
+
rubygems_version: 2.6.12
|
119
|
+
signing_key:
|
120
|
+
specification_version: 4
|
121
|
+
summary: RSpec matchers for testing mocked OpenTracing instrumentations
|
122
|
+
test_files: []
|