rspec-otel 0.0.1 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +13 -3
- data/lib/rspec_otel/matchers/emit_span.rb +126 -0
- data/lib/rspec_otel/matchers.rb +3 -3
- data/lib/rspec_otel/rspec.rb +0 -1
- data/lib/rspec_otel/version.rb +1 -1
- metadata +5 -5
- data/lib/rspec_otel/matchers/have_emitted_span.rb +0 -96
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ea44639a383fcb72b5c235528dc72363e0f3b431198e97c7d0c740bd5032bcd1
|
4
|
+
data.tar.gz: ed21a83d381fc8441ac7e09aa6e06d48582bbb256eaf0f5830c02363d4308f7d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b59d5eb23c4e42a7fb8489ca49a68aed7adf095da7277ea7e372648f678e39851dc5d4bc31e4ecaf8d3fef9d55ff5129168898bbde7430a0fde4feb851a746ee
|
7
|
+
data.tar.gz: 5270c5b5dd720e89e5243cfddeb26ac3aac76d44ff4ef42b75b79fe13667825b1633db676323c573a5d7154a3470e311aaae39f7c4ca1e640b0e323833c450aa
|
data/README.md
CHANGED
@@ -28,7 +28,7 @@ end
|
|
28
28
|
|
29
29
|
### Matching the presence of a span
|
30
30
|
|
31
|
-
You can match the emission of a span with the `
|
31
|
+
You can match the emission of a span with the `emit_span` matcher:
|
32
32
|
|
33
33
|
```ruby
|
34
34
|
require 'spec_helper'
|
@@ -37,7 +37,7 @@ RSpec.describe 'User API' do
|
|
37
37
|
it 'emits a span' do
|
38
38
|
expect do
|
39
39
|
get :user, id: 1
|
40
|
-
end.to
|
40
|
+
end.to emit_span('GET /user').with_attributes({'user.id' => '1'})
|
41
41
|
end
|
42
42
|
end
|
43
43
|
```
|
@@ -45,6 +45,16 @@ end
|
|
45
45
|
Several conditions can be added to the matcher:
|
46
46
|
|
47
47
|
* `with_attributes` - Will match only the spans with the specified attributes.
|
48
|
-
* `
|
48
|
+
* `without_attributes` - Will only match the spans that do not have the specified attributes
|
49
|
+
* `with_event` - Will match only the spans with the specified event.
|
50
|
+
* `without_event` - Will only match the spans that do not have the specified event
|
49
51
|
* `with_status` - Will match only the spans that have the proper status.
|
50
52
|
* `with_exception` - Will match only the spans that have the specified exception event.
|
53
|
+
* `without_exception` - Will match only the spans that do not have the specified exception event.
|
54
|
+
|
55
|
+
The `*_event` condition can be called multiple times with different events.
|
56
|
+
|
57
|
+
## Compatibility
|
58
|
+
|
59
|
+
RSpec Otel ensures compatibility with the currently supported versions of the
|
60
|
+
[Ruby Language](https://www.ruby-lang.org/en/downloads/branches/).
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RspecOtel
|
4
|
+
module Matchers
|
5
|
+
class EmitSpan
|
6
|
+
attr_reader :name
|
7
|
+
|
8
|
+
def initialize(name = nil)
|
9
|
+
@name = name
|
10
|
+
@filters = [
|
11
|
+
->(span) { span.name == name }
|
12
|
+
]
|
13
|
+
end
|
14
|
+
|
15
|
+
def matches?(block)
|
16
|
+
before_spans = []
|
17
|
+
if block.respond_to?(:call)
|
18
|
+
before_spans = RspecOtel.exporter.finished_spans
|
19
|
+
block.call
|
20
|
+
end
|
21
|
+
|
22
|
+
(RspecOtel.exporter.finished_spans - before_spans).each do |span|
|
23
|
+
return true if @filters.all? { |f| f.call(span) }
|
24
|
+
end
|
25
|
+
|
26
|
+
false
|
27
|
+
end
|
28
|
+
|
29
|
+
def with_attributes(attributes)
|
30
|
+
@filters << lambda do |span|
|
31
|
+
attributes_match?(span.attributes, attributes)
|
32
|
+
end
|
33
|
+
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
def without_attributes(attributes)
|
38
|
+
@filters << lambda do |span|
|
39
|
+
!attributes_match?(span.attributes, attributes)
|
40
|
+
end
|
41
|
+
|
42
|
+
self
|
43
|
+
end
|
44
|
+
|
45
|
+
def with_event(name, attributes = {})
|
46
|
+
@filters << lambda do |span|
|
47
|
+
event_match?(span.events, OpenTelemetry::SDK::Trace::Event.new(name, attributes))
|
48
|
+
end
|
49
|
+
self
|
50
|
+
end
|
51
|
+
|
52
|
+
def without_event(name, attributes = {})
|
53
|
+
@filters << lambda do |span|
|
54
|
+
!event_match?(span.events, OpenTelemetry::SDK::Trace::Event.new(name, attributes))
|
55
|
+
end
|
56
|
+
self
|
57
|
+
end
|
58
|
+
|
59
|
+
def with_status(code, description)
|
60
|
+
@filters << lambda do |span|
|
61
|
+
status_match?(span.status, code, description)
|
62
|
+
end
|
63
|
+
self
|
64
|
+
end
|
65
|
+
|
66
|
+
def with_exception(exception = nil)
|
67
|
+
with_event('exception', exception_attributes(exception))
|
68
|
+
end
|
69
|
+
|
70
|
+
def without_exception(exception = nil)
|
71
|
+
without_event('exception', exception_attributes(exception))
|
72
|
+
end
|
73
|
+
|
74
|
+
def failure_message
|
75
|
+
"expected span #{name} to have been emitted, but it couldn't be found"
|
76
|
+
end
|
77
|
+
|
78
|
+
def failure_message_when_negated
|
79
|
+
"expected span #{name} to not have been emitted"
|
80
|
+
end
|
81
|
+
|
82
|
+
def supports_block_expectations?
|
83
|
+
true
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def exception_attributes(exception)
|
89
|
+
attributes = {}
|
90
|
+
unless exception.nil?
|
91
|
+
attributes['exception.type'] = exception.class.to_s
|
92
|
+
attributes['exception.message'] = exception.message
|
93
|
+
end
|
94
|
+
|
95
|
+
attributes
|
96
|
+
end
|
97
|
+
|
98
|
+
def attributes_match?(span_attributes, attributes)
|
99
|
+
attributes.each do |ak, av|
|
100
|
+
sa = span_attributes.select do |k, v|
|
101
|
+
ak == k && av == v
|
102
|
+
end
|
103
|
+
|
104
|
+
return false if sa.empty?
|
105
|
+
end
|
106
|
+
|
107
|
+
true
|
108
|
+
end
|
109
|
+
|
110
|
+
def status_match?(span_status, code, description)
|
111
|
+
code == span_status.code && description == span_status.description
|
112
|
+
end
|
113
|
+
|
114
|
+
def event_match?(span_events, event)
|
115
|
+
return true if span_events.nil?
|
116
|
+
|
117
|
+
se = span_events.select do |s|
|
118
|
+
s.name == event.name &&
|
119
|
+
attributes_match?(s.attributes, event.attributes || {})
|
120
|
+
end
|
121
|
+
|
122
|
+
!se.empty?
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
data/lib/rspec_otel/matchers.rb
CHANGED
@@ -2,10 +2,10 @@
|
|
2
2
|
|
3
3
|
module RspecOtel
|
4
4
|
module Matchers
|
5
|
-
def
|
6
|
-
|
5
|
+
def emit_span(name)
|
6
|
+
EmitSpan.new(name)
|
7
7
|
end
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
-
require 'rspec_otel/matchers/
|
11
|
+
require 'rspec_otel/matchers/emit_span'
|
data/lib/rspec_otel/rspec.rb
CHANGED
data/lib/rspec_otel/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-otel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Damien MATHIEU
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-06-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: opentelemetry-api
|
@@ -39,7 +39,7 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name: rspec
|
42
|
+
name: rspec-core
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
@@ -63,7 +63,7 @@ files:
|
|
63
63
|
- README.md
|
64
64
|
- lib/rspec_otel.rb
|
65
65
|
- lib/rspec_otel/matchers.rb
|
66
|
-
- lib/rspec_otel/matchers/
|
66
|
+
- lib/rspec_otel/matchers/emit_span.rb
|
67
67
|
- lib/rspec_otel/rspec.rb
|
68
68
|
- lib/rspec_otel/version.rb
|
69
69
|
homepage: https://github.com/dmathieu/rspec-otel
|
@@ -86,7 +86,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
86
86
|
- !ruby/object:Gem::Version
|
87
87
|
version: '0'
|
88
88
|
requirements: []
|
89
|
-
rubygems_version: 3.5.
|
89
|
+
rubygems_version: 3.5.6
|
90
90
|
signing_key:
|
91
91
|
specification_version: 4
|
92
92
|
summary: RSpec matchers for the OpenTelemetry framework
|
@@ -1,96 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RspecOtel
|
4
|
-
module Matchers
|
5
|
-
class HaveEmittedSpan
|
6
|
-
attr_reader :name
|
7
|
-
|
8
|
-
def initialize(name)
|
9
|
-
@name = name
|
10
|
-
@attributes = {}
|
11
|
-
end
|
12
|
-
|
13
|
-
def matches?(block)
|
14
|
-
block.call if block.respond_to?(:call)
|
15
|
-
|
16
|
-
RspecOtel.exporter.finished_spans.each do |span|
|
17
|
-
return true if span.name == name &&
|
18
|
-
attributes_match?(span.attributes, @attributes) &&
|
19
|
-
status_match?(span.status, @status) &&
|
20
|
-
events_match?(span.events, @events)
|
21
|
-
end
|
22
|
-
|
23
|
-
false
|
24
|
-
end
|
25
|
-
|
26
|
-
def with_attributes(attributes)
|
27
|
-
@attributes = attributes
|
28
|
-
self
|
29
|
-
end
|
30
|
-
|
31
|
-
def with_event(name, attributes = {})
|
32
|
-
@events ||= []
|
33
|
-
@events << OpenTelemetry::SDK::Trace::Event.new(name, attributes)
|
34
|
-
self
|
35
|
-
end
|
36
|
-
|
37
|
-
def with_status(code, description)
|
38
|
-
@status = { code:, description: }
|
39
|
-
self
|
40
|
-
end
|
41
|
-
|
42
|
-
def with_exception(exception)
|
43
|
-
with_event('exception', {
|
44
|
-
'exception.type' => exception.class.to_s,
|
45
|
-
'exception.message' => exception.message
|
46
|
-
})
|
47
|
-
end
|
48
|
-
|
49
|
-
def failure_message
|
50
|
-
"expected span #{name} to have been emitted, but it couldn't be found"
|
51
|
-
end
|
52
|
-
|
53
|
-
def failure_message_when_negated
|
54
|
-
"expected span #{name} to not have been emitted"
|
55
|
-
end
|
56
|
-
|
57
|
-
def supports_block_expectations?
|
58
|
-
true
|
59
|
-
end
|
60
|
-
|
61
|
-
private
|
62
|
-
|
63
|
-
def attributes_match?(span_attributes, attributes)
|
64
|
-
attributes.each do |ak, av|
|
65
|
-
sa = span_attributes.select do |k, v|
|
66
|
-
ak == k && av == v
|
67
|
-
end
|
68
|
-
|
69
|
-
return false if sa.empty?
|
70
|
-
end
|
71
|
-
|
72
|
-
true
|
73
|
-
end
|
74
|
-
|
75
|
-
def status_match?(span_status, status)
|
76
|
-
status.nil? ||
|
77
|
-
(status[:code] == span_status.code && status[:description] == span_status.description)
|
78
|
-
end
|
79
|
-
|
80
|
-
def events_match?(span_events, events)
|
81
|
-
return true if span_events.nil?
|
82
|
-
|
83
|
-
events.each do |e|
|
84
|
-
se = span_events.select do |s|
|
85
|
-
s.name == e.name &&
|
86
|
-
attributes_match?(s.attributes, e.attributes)
|
87
|
-
end
|
88
|
-
|
89
|
-
return false if se.empty?
|
90
|
-
end
|
91
|
-
|
92
|
-
true
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|