test_bench-telemetry 2.0.0.0 → 2.1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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 -46
  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