test_bench-telemetry 2.0.0.1 → 2.1.0.1

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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/lib/test_bench/telemetry/controls/event/event_data.rb +15 -0
  3. data/lib/test_bench/telemetry/controls/event/metadata.rb +70 -0
  4. data/lib/test_bench/telemetry/controls/event.rb +112 -51
  5. data/lib/test_bench/telemetry/controls/event_data.rb +129 -0
  6. data/lib/test_bench/telemetry/controls/file.rb +84 -0
  7. data/lib/test_bench/telemetry/controls/handler.rb +48 -43
  8. data/lib/test_bench/telemetry/controls/{detail_level.rb → process_id.rb} +7 -3
  9. data/lib/test_bench/telemetry/controls/projection/receiver.rb +31 -0
  10. data/lib/test_bench/telemetry/controls/projection.rb +84 -0
  11. data/lib/test_bench/telemetry/controls/random.rb +1 -1
  12. data/lib/test_bench/telemetry/controls/sink.rb +23 -1
  13. data/lib/test_bench/telemetry/controls/time.rb +49 -2
  14. data/lib/test_bench/telemetry/controls.rb +10 -33
  15. data/lib/test_bench/telemetry/event.rb +74 -13
  16. data/lib/test_bench/telemetry/{event → event_data}/serialization.rb +78 -53
  17. data/lib/test_bench/telemetry/event_data.rb +13 -0
  18. data/lib/test_bench/telemetry/sink/file.rb +3 -3
  19. data/lib/test_bench/telemetry/sink/handler/event_registry.rb +42 -0
  20. data/lib/test_bench/telemetry/sink/handler.rb +54 -30
  21. data/lib/test_bench/telemetry/sink/projection.rb +132 -0
  22. data/lib/test_bench/telemetry/sink.rb +11 -0
  23. data/lib/test_bench/telemetry/substitute/sink.rb +83 -0
  24. data/lib/test_bench/telemetry/substitute.rb +13 -54
  25. data/lib/test_bench/telemetry/telemetry.rb +60 -19
  26. data/lib/test_bench/telemetry.rb +8 -10
  27. metadata +17 -40
  28. data/lib/test_bench/telemetry/controls/capture_sink/path.rb +0 -30
  29. data/lib/test_bench/telemetry/controls/capture_sink/record.rb +0 -21
  30. data/lib/test_bench/telemetry/controls/comment.rb +0 -19
  31. data/lib/test_bench/telemetry/controls/error.rb +0 -36
  32. data/lib/test_bench/telemetry/controls/events/asserted.rb +0 -32
  33. data/lib/test_bench/telemetry/controls/events/commented.rb +0 -26
  34. data/lib/test_bench/telemetry/controls/events/context_entered.rb +0 -31
  35. data/lib/test_bench/telemetry/controls/events/context_exited.rb +0 -34
  36. data/lib/test_bench/telemetry/controls/events/context_skipped.rb +0 -31
  37. data/lib/test_bench/telemetry/controls/events/detail_decreased.rb +0 -23
  38. data/lib/test_bench/telemetry/controls/events/detail_increased.rb +0 -23
  39. data/lib/test_bench/telemetry/controls/events/error_raised.rb +0 -26
  40. data/lib/test_bench/telemetry/controls/events/file_entered.rb +0 -29
  41. data/lib/test_bench/telemetry/controls/events/file_exited.rb +0 -32
  42. data/lib/test_bench/telemetry/controls/events/fixture_finished.rb +0 -29
  43. data/lib/test_bench/telemetry/controls/events/fixture_started.rb +0 -26
  44. data/lib/test_bench/telemetry/controls/events/run_aborted.rb +0 -29
  45. data/lib/test_bench/telemetry/controls/events/run_finished.rb +0 -32
  46. data/lib/test_bench/telemetry/controls/events/run_started.rb +0 -29
  47. data/lib/test_bench/telemetry/controls/events/test_finished.rb +0 -34
  48. data/lib/test_bench/telemetry/controls/events/test_skipped.rb +0 -31
  49. data/lib/test_bench/telemetry/controls/events/test_started.rb +0 -31
  50. data/lib/test_bench/telemetry/controls/events.rb +0 -27
  51. data/lib/test_bench/telemetry/controls/fixture_name.rb +0 -19
  52. data/lib/test_bench/telemetry/controls/line_number.rb +0 -10
  53. data/lib/test_bench/telemetry/controls/path.rb +0 -87
  54. data/lib/test_bench/telemetry/controls/result.rb +0 -12
  55. data/lib/test_bench/telemetry/controls/title.rb +0 -43
  56. data/lib/test_bench/telemetry/event/events.rb +0 -35
  57. data/lib/test_bench/telemetry/event/type.rb +0 -27
  58. data/lib/test_bench/telemetry/sink/capture/path.rb +0 -69
  59. data/lib/test_bench/telemetry/sink/capture/record/generate.rb +0 -49
  60. data/lib/test_bench/telemetry/sink/capture/record.rb +0 -73
  61. data/lib/test_bench/telemetry/sink/capture.rb +0 -55
@@ -0,0 +1,84 @@
1
+ module TestBench
2
+ class Telemetry
3
+ module Controls
4
+ module Projection
5
+ def self.example(receiver=nil)
6
+ receiver ||= Receiver.example
7
+
8
+ Example.new(receiver)
9
+ end
10
+
11
+ class Example
12
+ include Telemetry::Sink::Projection
13
+
14
+ attr_accessor :applied_event_data
15
+
16
+ receiver_name :some_receiver
17
+
18
+ apply Event::SomeEvent do |some_event|
19
+ receiver.event(some_event)
20
+ end
21
+
22
+ def apply_event_data(event_data)
23
+ self.applied_event_data = event_data
24
+ end
25
+
26
+ def applied?(event=nil)
27
+ receiver.event?(event)
28
+ end
29
+
30
+ def applied_event_data?(event_data)
31
+ self.applied_event_data == event_data
32
+ end
33
+ end
34
+
35
+ module NoApplyMethod
36
+ def self.example(receiver=nil)
37
+ receiver ||= Receiver.example
38
+
39
+ Example.new(receiver)
40
+ end
41
+
42
+ class Example
43
+ include Telemetry::Sink::Projection
44
+ end
45
+ end
46
+
47
+ module NoArgument
48
+ def self.example(receiver=nil)
49
+ receiver ||= Receiver.example
50
+
51
+ Example.new(receiver)
52
+ end
53
+
54
+ class Example
55
+ include Telemetry::Sink::Projection
56
+
57
+ attr_accessor :applied_event
58
+ def applied? = !!applied_event
59
+
60
+ apply Event::SomeEvent do
61
+ self.applied_event = true
62
+ end
63
+ end
64
+ end
65
+
66
+ module ApplyMethod
67
+ def self.example(event_type=nil)
68
+ event_type ||= Event::SomeEvent.event_type
69
+
70
+ event_name = TestBench::Telemetry::Event::EventName.get(event_type)
71
+
72
+ :"apply_#{event_name}"
73
+ end
74
+
75
+ def self.other_example
76
+ event_type = Event::SomeOtherEvent.event_type
77
+
78
+ example(event_type)
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -1,7 +1,7 @@
1
1
  module TestBench
2
2
  class Telemetry
3
3
  module Controls
4
- Random = TestBench::Random.instance
4
+ Random = TestBench::Random.build
5
5
  end
6
6
  end
7
7
  end
@@ -3,7 +3,29 @@ module TestBench
3
3
  module Controls
4
4
  module Sink
5
5
  def self.example
6
- Handler.example
6
+ Example.new
7
+ end
8
+
9
+ def self.other_example
10
+ OtherExample.new
11
+ end
12
+
13
+ class Example
14
+ include Telemetry::Sink
15
+
16
+ attr_accessor :received_event_data
17
+
18
+ def receive(event_data)
19
+ self.received_event_data = event_data
20
+ end
21
+
22
+ def received?(event_data)
23
+ self.received_event_data == event_data
24
+ end
25
+ end
26
+
27
+ class OtherExample
28
+ include Telemetry::Sink
7
29
  end
8
30
  end
9
31
  end
@@ -53,8 +53,12 @@ module TestBench
53
53
  ::Time.utc(year, month, day, hours, minutes, seconds, microseconds)
54
54
  end
55
55
 
56
+ def self.other_example
57
+ Other.example
58
+ end
59
+
56
60
  def self.random
57
- example(offset_nanoseconds: Random.integer)
61
+ Random.example
58
62
  end
59
63
 
60
64
  module ISO8601
@@ -64,12 +68,55 @@ module TestBench
64
68
  time.strftime('%Y-%m-%dT%H:%M:%S.%NZ')
65
69
  end
66
70
 
67
- def self.random(...)
71
+ def self.other_example
72
+ time = Time.other_example
73
+
74
+ example(time)
75
+ end
76
+
77
+ def self.random
68
78
  time = Time.random
69
79
 
70
80
  example(time)
71
81
  end
72
82
  end
83
+
84
+ module Offset
85
+ def self.example
86
+ Time.example(offset_nanoseconds:)
87
+ end
88
+
89
+ def self.offset_nanoseconds
90
+ Elapsed.nanoseconds
91
+ end
92
+ end
93
+ Other = Offset
94
+
95
+ module Random
96
+ def self.example
97
+ offset_nanoseconds = Controls::Random.integer
98
+
99
+ Time.example(offset_nanoseconds:)
100
+ end
101
+ end
102
+
103
+ module Elapsed
104
+ def self.example
105
+ seconds
106
+ end
107
+
108
+ def self.nanoseconds
109
+ 111_111_111
110
+ end
111
+
112
+ def self.milliseconds
113
+ 111.111_111
114
+ end
115
+
116
+ def self.seconds
117
+ 0.111_111_111
118
+ end
119
+ end
73
120
  end
74
121
  end
75
122
  end
@@ -1,40 +1,17 @@
1
1
  require 'test_bench/telemetry/controls/random'
2
- require 'test_bench/telemetry/controls/time'
3
2
 
4
- require 'test_bench/telemetry/controls/comment'
5
- require 'test_bench/telemetry/controls/line_number'
6
- require 'test_bench/telemetry/controls/path'
7
- require 'test_bench/telemetry/controls/error'
8
- require 'test_bench/telemetry/controls/result'
9
- require 'test_bench/telemetry/controls/title'
10
- require 'test_bench/telemetry/controls/fixture_name'
11
- require 'test_bench/telemetry/controls/detail_level'
3
+ require 'test_bench/telemetry/controls/file'
12
4
 
13
- require 'test_bench/telemetry/controls/event'
5
+ require 'test_bench/telemetry/controls/process_id'
6
+ require 'test_bench/telemetry/controls/time'
14
7
 
15
- require 'test_bench/telemetry/controls/events'
16
- require 'test_bench/telemetry/controls/events/asserted'
17
- require 'test_bench/telemetry/controls/events/error_raised'
18
- require 'test_bench/telemetry/controls/events/test_started'
19
- require 'test_bench/telemetry/controls/events/test_finished'
20
- require 'test_bench/telemetry/controls/events/test_skipped'
21
- require 'test_bench/telemetry/controls/events/context_entered'
22
- require 'test_bench/telemetry/controls/events/context_exited'
23
- require 'test_bench/telemetry/controls/events/context_skipped'
24
- require 'test_bench/telemetry/controls/events/commented'
25
- require 'test_bench/telemetry/controls/events/detail_increased'
26
- require 'test_bench/telemetry/controls/events/detail_decreased'
27
- require 'test_bench/telemetry/controls/events/run_started'
28
- require 'test_bench/telemetry/controls/events/run_finished'
29
- require 'test_bench/telemetry/controls/events/run_aborted'
30
- require 'test_bench/telemetry/controls/events/file_entered'
31
- require 'test_bench/telemetry/controls/events/file_exited'
32
- require 'test_bench/telemetry/controls/events/fixture_started'
33
- require 'test_bench/telemetry/controls/events/fixture_finished'
8
+ require 'test_bench/telemetry/controls/event_data'
34
9
 
35
- require 'test_bench/telemetry/controls/handler'
36
-
37
- require 'test_bench/telemetry/controls/capture_sink/path'
38
- require 'test_bench/telemetry/controls/capture_sink/record'
10
+ require 'test_bench/telemetry/controls/event/event_data'
11
+ require 'test_bench/telemetry/controls/event'
12
+ require 'test_bench/telemetry/controls/event/metadata'
39
13
 
40
14
  require 'test_bench/telemetry/controls/sink'
15
+ require 'test_bench/telemetry/controls/handler'
16
+ require 'test_bench/telemetry/controls/projection'
17
+ require 'test_bench/telemetry/controls/projection/receiver'
@@ -1,41 +1,102 @@
1
1
  module TestBench
2
2
  class Telemetry
3
3
  module Event
4
- def self.define(*attribute_names)
5
- Struct.new(*attribute_names, :time) do
4
+ def self.define(*attributes, &blk)
5
+ Struct.new(*attributes, :metadata) do
6
6
  include Event
7
+
8
+ if not blk.nil?
9
+ instance_exec(&blk)
10
+ end
7
11
  end
8
12
  end
9
13
 
10
14
  def self.included(cls)
11
15
  cls.class_exec do
12
16
  extend EventType
17
+ extend EventName
18
+ extend Build
13
19
  end
14
20
  end
15
21
 
16
- def self.each_event_type(&block)
17
- Events.constants(false).each(&block)
18
- end
19
-
20
22
  def event_type
21
23
  self.class.event_type
22
24
  end
23
25
 
24
- def dump
25
- Serialization.dump(self)
26
+ def event_name
27
+ self.class.event_name
26
28
  end
27
29
 
28
- def self.load(data, event_namespace=nil)
29
- event_namespace ||= Events
30
-
31
- Serialization.load(data, event_namespace)
30
+ def data
31
+ values[0...-1]
32
32
  end
33
33
 
34
34
  module EventType
35
35
  def event_type
36
- @event_type ||= Type.get(name)
36
+ *, inner_namespace = self.name.split('::')
37
+
38
+ inner_namespace.to_sym
39
+ end
40
+ end
41
+
42
+ module EventName
43
+ def event_name
44
+ EventName.get(event_type)
45
+ end
46
+
47
+ def self.get(event_type)
48
+ pascal_cased = event_type.to_s
49
+
50
+ underscore_cased = pascal_cased.gsub(%r{(?:\A|[a-z])[A-Z]+}) do |match_text|
51
+ if ('a'..'z').include?(match_text[0])
52
+ match_text.insert(1, '_')
53
+ end
54
+ match_text.downcase!
55
+ match_text
56
+ end
57
+
58
+ underscore_cased.to_sym
37
59
  end
38
60
  end
61
+
62
+ module Export
63
+ def self.call(event)
64
+ event_data = EventData.new
65
+ event_data.type = event.event_type
66
+ event_data.data = event.data
67
+ event_data.process_id = event.metadata.process_id
68
+ event_data.time = event.metadata.time
69
+ event_data
70
+ end
71
+ end
72
+
73
+ module Build
74
+ def build(*attributes, process_id: nil, time: nil)
75
+ metadata = Metadata.new(process_id, time)
76
+
77
+ new(*attributes, metadata)
78
+ end
79
+ end
80
+
81
+ module Import
82
+ Error = Class.new(RuntimeError)
83
+
84
+ def self.call(event_data, event_class)
85
+ if event_class.event_type != event_data.type
86
+ raise Error, "Event class #{event_class} doesn't match EventData type #{event_data.type.inspect}"
87
+ end
88
+
89
+ process_id = event_data.process_id
90
+ time = event_data.time
91
+ data = event_data.data
92
+
93
+ metadata = Metadata.new(process_id, time)
94
+
95
+ event_class.new(*data, metadata)
96
+ end
97
+ end
98
+
99
+ Metadata = Struct.new(:process_id, :time)
39
100
  end
40
101
  end
41
102
  end
@@ -1,64 +1,81 @@
1
1
  module TestBench
2
2
  class Telemetry
3
- module Event
3
+ class EventData
4
4
  module Serialization
5
5
  Error = Class.new(RuntimeError)
6
6
 
7
- def self.dump(event)
8
- event_type = event.event_type.to_s
7
+ def self.dump(event_data)
8
+ type = event_data.type.to_s
9
+ process_id = dump_value(event_data.process_id)
10
+ time = dump_value(event_data.time)
11
+ data = event_data.data
9
12
 
10
- data = String.new(encoding: 'BINARY')
13
+ text = String.new(encoding: 'BINARY')
11
14
 
12
- data << event_type
15
+ text << type
13
16
 
14
- event.values.each do |value|
15
- data << "\t"
16
- data << dump_value(value)
17
+ text << "\t"
18
+ text << process_id
19
+
20
+ text << "\t"
21
+ text << time
22
+
23
+ data.each do |value|
24
+ text << "\t"
25
+ text << dump_value(value)
17
26
  end
18
27
 
19
- data << "\r\n"
20
- data
28
+ text << "\r\n"
29
+ text
21
30
  end
22
31
 
23
32
  def self.dump_value(value)
24
33
  case value
25
- when NilClass
26
- ''
27
- when Time
28
- value.strftime('%Y-%m-%dT%H:%M:%S.%NZ')
29
- when String
30
- value.dump
31
34
  when Integer
32
35
  value.to_s
36
+ when Time
37
+ value.strftime('%Y-%m-%dT%H:%M:%S.%NZ')
38
+ when NilClass
39
+ ''
33
40
  when TrueClass, FalseClass
34
41
  value.to_s
42
+ when String
43
+ value.dump
35
44
  end
36
45
  end
37
46
 
38
- def self.load(data, event_namespace)
39
- match_data = Pattern.match(data)
47
+ def self.load(text)
48
+ match_data = Pattern.match(text)
40
49
  if match_data.nil?
41
- raise Error, "Cannot deserialize #{data.inspect}"
50
+ raise Error, "Cannot deserialize #{text.inspect}"
42
51
  end
43
52
 
44
- event_type = match_data['event_type'].to_sym
45
- if not event_namespace.const_defined?(event_type, false)
46
- raise Error, "Unknown event type #{event_type.inspect}"
47
- end
53
+ type = match_data['type'].to_sym
54
+ process_id = load_value(match_data['process_id'])
55
+ time = load_value(match_data['time_attribute'])
48
56
 
49
- values = match_data['values'].split("\t").map do |value_data|
50
- load_value(value_data)
57
+ event_data = EventData.new
58
+ event_data.type = type
59
+ event_data.process_id = process_id
60
+ event_data.time = time
61
+ event_data.data = []
62
+
63
+ data_text = match_data['data']
64
+
65
+ data_text.insert(0, "\t")
66
+ data_text.scan(/\t([^\t]*)/) do |(value_text)|
67
+ value = load_value(value_text)
68
+ event_data.data << value
51
69
  end
52
70
 
53
- event_class = event_namespace.const_get(event_type, false)
54
- event_class.new(*values)
71
+ event_data
55
72
  end
56
73
 
57
- def self.load_value(value_data)
58
- match_data = Pattern.match_value(value_data)
74
+ def self.load_value(value_text)
75
+ match_data = Pattern.match_value(value_text)
59
76
 
60
- if match_data['nil']
61
- nil
77
+ if match_data['integer']
78
+ Integer(value_text)
62
79
  elsif match_data['time']
63
80
  year = match_data['year'].to_i
64
81
  month = match_data['month'].to_i
@@ -71,46 +88,54 @@ module TestBench
71
88
  usec = Rational(nanosecond, 1_000)
72
89
 
73
90
  Time.utc(year, month, day, hour, minute, second, usec)
74
- elsif match_data['string']
75
- value_data.undump
76
- elsif match_data['integer']
77
- Integer(value_data)
91
+ elsif match_data['nil']
92
+ nil
78
93
  elsif match_data['true']
79
94
  true
80
95
  elsif match_data['false']
81
96
  false
97
+ elsif match_data['string']
98
+ value_text.undump
82
99
  end
83
100
  end
84
101
 
85
102
  module Pattern
86
103
  def self.match(data)
87
- event.match(data)
104
+ event_data.match(data)
88
105
  end
89
106
 
90
- def self.match_value(value_data)
107
+ def self.match_value(value_text)
91
108
  pattern = %r{\A#{value}\z}
92
109
 
93
- pattern.match(value_data)
110
+ pattern.match(value_text)
111
+ end
112
+
113
+ def self.event_data
114
+ %r{\A#{type}\t#{process_id}\t#{time_attribute}\t#{data}\r\n\z}
115
+ end
116
+
117
+ def self.type
118
+ %r{(?<type>[A-Z][[:alnum:]]+)}
94
119
  end
95
120
 
96
- def self.event
97
- %r{\A#{event_type}\t#{values}\r\n\z}
121
+ def self.process_id
122
+ %r{(?<process_id>#{integer})}
98
123
  end
99
124
 
100
- def self.event_type
101
- %r{(?<event_type>[A-Z][[:alpha:]]+)}
125
+ def self.time_attribute
126
+ %r{(?<time_attribute>#{time})}
102
127
  end
103
128
 
104
- def self.values
105
- %r{(?<values>#{value}(?:\t#{value})*)}
129
+ def self.data
130
+ %r{(?<data>#{value}(?:\t#{value})*)}
106
131
  end
107
132
 
108
133
  def self.value
109
- %r{#{self.nil}|#{time}|#{string}|#{integer}|#{boolean}}
134
+ %r{#{integer}|#{time}|#{self.nil}|#{boolean}|#{string}}
110
135
  end
111
136
 
112
- def self.nil
113
- %r{(?<nil>(?=[\n\t])?)}
137
+ def self.integer
138
+ %r{(?<integer>[[:digit:]]+)}
114
139
  end
115
140
 
116
141
  def self.time
@@ -125,17 +150,17 @@ module TestBench
125
150
  %r{(?<time>#{year}-#{month}-#{day}T#{hour}:#{minute}:#{second}\.#{nanosecond}Z)}
126
151
  end
127
152
 
128
- def self.string
129
- %r{(?<string>".*")}
130
- end
131
-
132
- def self.integer
133
- %r{(?<integer>[[:digit:]]+)}
153
+ def self.nil
154
+ %r{(?<nil>(?=[\t\r\z])?)}
134
155
  end
135
156
 
136
157
  def self.boolean
137
158
  %r{(?<true>true)|(?<false>false)}
138
159
  end
160
+
161
+ def self.string
162
+ %r{(?<string>".*")}
163
+ end
139
164
  end
140
165
  end
141
166
  end
@@ -0,0 +1,13 @@
1
+ module TestBench
2
+ class Telemetry
3
+ EventData = Struct.new(:type, :process_id, :time, :data) do
4
+ def self.load(text)
5
+ EventData::Serialization.load(text)
6
+ end
7
+
8
+ def dump
9
+ EventData::Serialization.dump(self)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -20,10 +20,10 @@ module TestBench
20
20
  end
21
21
  end
22
22
 
23
- def call(event)
24
- data = event.dump
23
+ def receive(event_data)
24
+ text = event_data.dump
25
25
 
26
- io.write(data)
26
+ io.write(text)
27
27
  end
28
28
  end
29
29
  end
@@ -0,0 +1,42 @@
1
+ module TestBench
2
+ class Telemetry
3
+ module Sink
4
+ module Handler
5
+ class EventRegistry
6
+ Error = Class.new(RuntimeError)
7
+
8
+ def event_classes
9
+ @event_classes ||= {}
10
+ end
11
+ attr_writer :event_classes
12
+
13
+ def event_types
14
+ event_classes.keys
15
+ end
16
+
17
+ def get(event_type)
18
+ event_classes.fetch(event_type) do
19
+ raise Error, "#{event_type} isn't registered"
20
+ end
21
+ end
22
+
23
+ def register(event_class)
24
+ if registered?(event_class)
25
+ raise Error, "#{event_class} is already registered"
26
+ end
27
+
28
+ event_type = event_class.event_type
29
+
30
+ event_classes[event_type] = event_class
31
+ end
32
+
33
+ def registered?(event_class)
34
+ event_type = event_class.event_type
35
+
36
+ event_classes.key?(event_type)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end