test_bench-run 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.
Files changed (35) hide show
  1. checksums.yaml +7 -0
  2. data/lib/test_bench/run/controls/directory.rb +54 -0
  3. data/lib/test_bench/run/controls/event_data.rb +7 -0
  4. data/lib/test_bench/run/controls/events/event_data.rb +9 -0
  5. data/lib/test_bench/run/controls/events/file_crashed.rb +109 -0
  6. data/lib/test_bench/run/controls/events/file_finished.rb +56 -0
  7. data/lib/test_bench/run/controls/events/file_started.rb +47 -0
  8. data/lib/test_bench/run/controls/events/finished.rb +50 -0
  9. data/lib/test_bench/run/controls/events/session.rb +9 -0
  10. data/lib/test_bench/run/controls/events/started.rb +41 -0
  11. data/lib/test_bench/run/controls/exception.rb +101 -0
  12. data/lib/test_bench/run/controls/executor.rb +56 -0
  13. data/lib/test_bench/run/controls/file/create.rb +69 -0
  14. data/lib/test_bench/run/controls/file/pattern.rb +29 -0
  15. data/lib/test_bench/run/controls/file.rb +180 -0
  16. data/lib/test_bench/run/controls/path.rb +15 -0
  17. data/lib/test_bench/run/controls/process_id.rb +7 -0
  18. data/lib/test_bench/run/controls/random.rb +7 -0
  19. data/lib/test_bench/run/controls/result.rb +7 -0
  20. data/lib/test_bench/run/controls/time.rb +7 -0
  21. data/lib/test_bench/run/controls.rb +26 -0
  22. data/lib/test_bench/run/events.rb +12 -0
  23. data/lib/test_bench/run/executor/serial.rb +112 -0
  24. data/lib/test_bench/run/executor/substitute.rb +45 -0
  25. data/lib/test_bench/run/executor.rb +44 -0
  26. data/lib/test_bench/run/file/substitute.rb +41 -0
  27. data/lib/test_bench/run/file.rb +73 -0
  28. data/lib/test_bench/run/get_files/substitute.rb +46 -0
  29. data/lib/test_bench/run/get_files.rb +72 -0
  30. data/lib/test_bench/run/output/file.rb +129 -0
  31. data/lib/test_bench/run/output/summary/error.rb +139 -0
  32. data/lib/test_bench/run/output/summary.rb +179 -0
  33. data/lib/test_bench/run/run.rb +101 -0
  34. data/lib/test_bench/run.rb +19 -0
  35. metadata +103 -0
@@ -0,0 +1,129 @@
1
+ module TestBench
2
+ class Run
3
+ module Output
4
+ class File
5
+ Error = Class.new(RuntimeError)
6
+
7
+ include TestBench::Output
8
+ include Events
9
+
10
+ def session_output
11
+ @session_output ||= TestBench::Output::Substitute.build
12
+ end
13
+ attr_writer :session_output
14
+
15
+ def pended_events
16
+ @pended_events ||= {}
17
+ end
18
+ attr_writer :pended_events
19
+
20
+ def only_failure
21
+ @only_failure.nil? ?
22
+ @only_failure = Defaults.only_failure :
23
+ @only_failure
24
+ end
25
+ alias :only_failure? :only_failure
26
+ attr_writer :only_failure
27
+
28
+ def configure(...)
29
+ TestBench::Session::Output::Writer.configure(self, ...)
30
+
31
+ Session::Output.configure(self, writer:, attr_name: :session_output)
32
+ end
33
+
34
+ handle FileStarted do |file_started|
35
+ process_id = file_started.metadata.process_id
36
+
37
+ start(process_id)
38
+ end
39
+
40
+ handle FileFinished do |file_finished|
41
+ process_id = file_finished.metadata.process_id
42
+ result = file_finished.result
43
+ file = file_finished.file
44
+
45
+ finish_process(process_id, result, file)
46
+ end
47
+
48
+ handle FileCrashed do |file_crashed|
49
+ process_id = file_crashed.metadata.process_id
50
+ file = file_crashed.file
51
+
52
+ result = false
53
+
54
+ finish_process(process_id, result, file)
55
+ end
56
+
57
+ def finish_process(process_id, result, file)
58
+ events = pended_events.delete(process_id)
59
+
60
+ if only_failure && result
61
+ return
62
+ end
63
+
64
+ writer.puts("Running #{file}")
65
+
66
+ writer_sequence = writer.sequence
67
+
68
+ events ||= []
69
+ events.each do |event_data|
70
+ session_output.receive(event_data)
71
+ end
72
+
73
+ if writer.current?(writer_sequence)
74
+ writer.
75
+ style(:faint).
76
+ puts("(Nothing written)")
77
+
78
+ writer.puts
79
+ end
80
+ end
81
+
82
+ def handle_event_data(event_data)
83
+ pend(event_data)
84
+ end
85
+
86
+ def pend_event(event_data)
87
+ process_id = event_data.process_id
88
+
89
+ if not started?(process_id)
90
+ start(process_id)
91
+ end
92
+
93
+ pended_events = self.pended_events[process_id]
94
+ pended_events << event_data
95
+ end
96
+ alias :pend :pend_event
97
+
98
+ def pended_event?(event_data)
99
+ process_id = event_data.process_id
100
+
101
+ pended_events = self.pended_events.fetch(process_id) do
102
+ return false
103
+ end
104
+
105
+ pended_events.include?(event_data)
106
+ end
107
+ alias :pended? :pended_event?
108
+
109
+ def start(process_id)
110
+ if started?(process_id)
111
+ raise Error, "Process already started (Process ID: #{process_id})"
112
+ end
113
+
114
+ pended_events[process_id] = []
115
+ end
116
+
117
+ def started?(process_id)
118
+ pended_events.key?(process_id)
119
+ end
120
+
121
+ module Defaults
122
+ def self.only_failure
123
+ ENV.fetch('TEST_BENCH_ONLY_FAILURE', 'off') == 'on'
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,139 @@
1
+ module TestBench
2
+ class Run
3
+ module Output
4
+ class Summary
5
+ class Error
6
+ StateError = Class.new(RuntimeError)
7
+
8
+ include TestBench::Output
9
+ include Events
10
+
11
+ attr_accessor :current_file
12
+
13
+ def failure_summary
14
+ @failure_summary ||= {}
15
+ end
16
+ attr_writer :failure_summary
17
+
18
+ handle FileStarted do |file_started|
19
+ file = file_started.file
20
+
21
+ start_file(file)
22
+ end
23
+
24
+ handle Session::Events::Failed do |_failed|
25
+ current_file.record_failure
26
+ end
27
+
28
+ handle FileFinished do |file_finished|
29
+ file = file_finished.file
30
+ result = file_finished.result
31
+
32
+ finish_file(file, result)
33
+ end
34
+
35
+ handle FileCrashed do |file_crashed|
36
+ file = file_crashed.file
37
+
38
+ error_message = file_crashed.error_message
39
+
40
+ finish_file(file, error_message:)
41
+ end
42
+
43
+ handle Finished do |finished|
44
+ if not finished.result
45
+ print_summary
46
+ end
47
+ end
48
+
49
+ def print_summary
50
+ writer.style(:bold, :underline, :red).puts("Failure Summary:")
51
+
52
+ failure_summary.each_value do |file_record|
53
+ file, failures, error_message = file_record.to_a
54
+
55
+ writer
56
+ .style(:faint, :red)
57
+ .print("-")
58
+ .style(:reset_intensity, :bold)
59
+ .print(" #{file}")
60
+ .style(:reset_intensity)
61
+ .print(":")
62
+
63
+ if failures > 0
64
+ writer.print(" %i failure%s" % [
65
+ failures,
66
+ failures == 1 ? '' : 's'
67
+ ])
68
+
69
+ if not error_message.nil?
70
+ writer.print(".")
71
+ end
72
+ end
73
+
74
+ if not error_message.nil?
75
+ writer.puts(" File crashed, error:")
76
+
77
+ writer.style(:red).puts(" #{error_message}")
78
+ else
79
+ writer.puts
80
+ end
81
+
82
+ writer.puts
83
+ end
84
+ end
85
+
86
+ def start_file(file)
87
+ if not current_file.nil?
88
+ raise StateError, "Already started file #{current_file.file.inspect} (File: #{file.inspect})"
89
+ end
90
+
91
+ file = File.build(file)
92
+
93
+ self.current_file = file
94
+ end
95
+
96
+ def finish_file(file, result=nil, error_message: nil)
97
+ result ||= false
98
+
99
+ if not current_file?(file)
100
+ raise StateError, "Cannot finish file #{file.inspect} (Current File: #{current_file&.file.inspect})"
101
+ end
102
+
103
+ if not result
104
+ if not error_message.nil?
105
+ current_file.error_message = error_message
106
+ end
107
+
108
+ failure_summary[file] = current_file
109
+ end
110
+
111
+ self.current_file = nil
112
+ end
113
+
114
+ def current_file?(file=nil)
115
+ return false if current_file.nil?
116
+
117
+ if not file.nil?
118
+ file == current_file.file
119
+ else
120
+ true
121
+ end
122
+ end
123
+
124
+ File = Struct.new(:file, :failures, :error_message) do
125
+ def self.build(file)
126
+ failures = 0
127
+
128
+ new(file, failures)
129
+ end
130
+
131
+ def record_failure
132
+ self.failures += 1
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,179 @@
1
+ module TestBench
2
+ class Run
3
+ module Output
4
+ class Summary
5
+ StateError = Class.new(RuntimeError)
6
+
7
+ include TestBench::Output
8
+ include Session::Events
9
+ include Events
10
+
11
+ def tests_finished
12
+ @tests_finished ||= 0
13
+ end
14
+ attr_writer :tests_finished
15
+
16
+ def tests_passed
17
+ @tests_passed ||= 0
18
+ end
19
+ attr_writer :tests_passed
20
+
21
+ def tests_failed
22
+ @tests_failed ||= 0
23
+ end
24
+ attr_writer :tests_failed
25
+
26
+ def tests_skipped
27
+ @tests_skipped ||= 0
28
+ end
29
+ attr_writer :tests_skipped
30
+
31
+ def contexts_skipped
32
+ @contexts_skipped ||= 0
33
+ end
34
+ attr_writer :contexts_skipped
35
+
36
+ def files_finished
37
+ @files_finished ||= 0
38
+ end
39
+ attr_writer :files_finished
40
+
41
+ def files_crashed
42
+ @files_crashed ||= 0
43
+ end
44
+ attr_writer :files_crashed
45
+
46
+ attr_accessor :start_time
47
+ attr_accessor :finish_time
48
+ attr_accessor :elapsed_time
49
+
50
+ handle TestFinished do |test_finished|
51
+ self.tests_finished += 1
52
+
53
+ if test_finished.result
54
+ self.tests_passed += 1
55
+ else
56
+ self.tests_failed += 1
57
+ end
58
+ end
59
+
60
+ handle TestSkipped do |_test_skipped|
61
+ self.tests_skipped += 1
62
+ end
63
+
64
+ handle ContextSkipped do |_test_skipped|
65
+ self.contexts_skipped += 1
66
+ end
67
+
68
+ handle FileFinished do |_file_finished|
69
+ self.files_finished += 1
70
+ end
71
+
72
+ handle FileCrashed do |_file_crashed|
73
+ self.files_crashed += 1
74
+ end
75
+
76
+ handle Started do |started|
77
+ start_time = started.metadata.time
78
+
79
+ self.start_time = start_time
80
+ end
81
+
82
+ handle Finished do |finished|
83
+ finish_time = finished.metadata.time
84
+
85
+ record_finish_time(finish_time)
86
+
87
+ finish
88
+ end
89
+
90
+ def record_finish_time(finish_time)
91
+ if start_time.nil?
92
+ raise StateError, "Start time isn't set"
93
+ end
94
+
95
+ self.finish_time = finish_time
96
+
97
+ elapsed_time = finish_time - start_time
98
+ self.elapsed_time = elapsed_time
99
+ end
100
+
101
+ def finish
102
+ writer.print("Finished running %i file%s, " % [
103
+ files_finished,
104
+ files_finished == 1 ? '' : 's'
105
+ ])
106
+
107
+ if files_crashed > 0
108
+ writer
109
+ .style(:bold, :red)
110
+ .puts("%i file%s crashed" % [
111
+ files_crashed,
112
+ files_crashed == 1 ? '' : 's'
113
+ ])
114
+ else
115
+ writer.puts("0 files crashed")
116
+ end
117
+
118
+ writer.print("Ran %i test%s" % [
119
+ tests_finished,
120
+ tests_finished == 1 ? '' : 's'
121
+ ])
122
+
123
+ if not elapsed_time.nil?
124
+ tests_per_second = tests_finished / elapsed_time
125
+ writer.print(" in %0.3fs (%i test%s/second)" % [
126
+ elapsed_time,
127
+ tests_per_second,
128
+ tests_finished == 1 ? '' : 's'
129
+ ])
130
+ end
131
+ writer.puts
132
+
133
+ skip_count = tests_skipped + contexts_skipped
134
+
135
+ if tests_passed > 0
136
+ if skip_count.zero? && tests_failed.zero?
137
+ writer.style(:bold)
138
+ end
139
+
140
+ writer
141
+ .style(:green)
142
+ .print("#{tests_passed} passed")
143
+ .style(:reset_fg)
144
+
145
+ if skip_count.zero? && tests_failed.zero?
146
+ writer.style(:reset_intensity)
147
+ end
148
+ else
149
+ writer.print("0 passed")
150
+ end
151
+ writer.print(", ")
152
+
153
+ if skip_count.zero?
154
+ writer.print("0 skipped")
155
+ else
156
+ writer
157
+ .style(:bold, :yellow)
158
+ .print("%i%s skipped" % [
159
+ skip_count,
160
+ contexts_skipped > 0 ? '+' : ''
161
+ ])
162
+ .style(:reset_fg, :reset_intensity)
163
+ end
164
+ writer.print(", ")
165
+
166
+ if tests_failed > 0
167
+ writer
168
+ .style(:bold, :red)
169
+ .puts("#{tests_failed} failed")
170
+ else
171
+ writer.puts("0 failed")
172
+ end
173
+
174
+ writer.puts
175
+ end
176
+ end
177
+ end
178
+ end
179
+ end
@@ -0,0 +1,101 @@
1
+ module TestBench
2
+ class Run
3
+ include Session::Handler
4
+ include Events
5
+
6
+ def telemetry
7
+ @telemetry ||= Telemetry::Substitute.build
8
+ end
9
+ attr_writer :telemetry
10
+
11
+ def session
12
+ @session ||= Session::Substitute.build
13
+ end
14
+ attr_writer :session
15
+
16
+ def get_files
17
+ @get_files ||= GetFiles::Substitute.build
18
+ end
19
+ attr_writer :get_files
20
+
21
+ def executor
22
+ @executor ||= Executor::Substitute.build
23
+ end
24
+ attr_writer :executor
25
+
26
+ def path_sequence
27
+ @path_sequence ||= 0
28
+ end
29
+ attr_writer :path_sequence
30
+
31
+ def self.build(exclude_file_pattern: nil, session_store: nil)
32
+ session_store ||= Session::Store.instance
33
+
34
+ instance = new
35
+
36
+ GetFiles.configure(instance, exclude_file_pattern:)
37
+
38
+ Executor::Serial.configure(instance)
39
+
40
+ session = Session.build do |telemetry|
41
+ Output::File.register(telemetry)
42
+ Output::Summary::Error.register(telemetry)
43
+ Output::Summary.register(telemetry)
44
+
45
+ instance.telemetry = telemetry
46
+ end
47
+
48
+ Session.configure(instance, session:)
49
+ session_store.put(session)
50
+
51
+ instance
52
+ end
53
+
54
+ def self.call(path, exclude_file_pattern: nil)
55
+ instance = build(exclude_file_pattern:)
56
+ instance.(path)
57
+ end
58
+
59
+ def call(path)
60
+ run do
61
+ path(path)
62
+ end
63
+ end
64
+
65
+ def run(&block)
66
+ telemetry.record(Started.build)
67
+
68
+ executor.start
69
+
70
+ if not block.nil?
71
+ block.(self)
72
+ end
73
+
74
+ executor.finish
75
+
76
+ if session.passed?
77
+ result = true
78
+ elsif session.failed?
79
+ result = false
80
+ end
81
+
82
+ telemetry.record(Finished.build(result))
83
+ result
84
+ end
85
+ alias :! :run
86
+
87
+ def path(path)
88
+ self.path_sequence += 1
89
+
90
+ get_files.(path) do |file|
91
+ executor.execute(file)
92
+ end
93
+
94
+ rescue GetFiles::FileError
95
+ warn "#{path}: No such file or directory"
96
+
97
+ session.record_failure
98
+ end
99
+ alias :<< :path
100
+ end
101
+ end
@@ -0,0 +1,19 @@
1
+ require 'test_bench/fixture'
2
+
3
+ require 'test_bench/run/events'
4
+
5
+ require 'test_bench/run/get_files'
6
+ require 'test_bench/run/get_files/substitute'
7
+
8
+ require 'test_bench/run/file'
9
+ require 'test_bench/run/file/substitute'
10
+
11
+ require 'test_bench/run/output/file'
12
+ require 'test_bench/run/output/summary/error'
13
+ require 'test_bench/run/output/summary'
14
+
15
+ require 'test_bench/run/executor'
16
+ require 'test_bench/run/executor/substitute'
17
+ require 'test_bench/run/executor/serial'
18
+
19
+ require 'test_bench/run/run'
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: test_bench-run
3
+ version: !ruby/object:Gem::Version
4
+ version: '0'
5
+ platform: ruby
6
+ authors:
7
+ - Nathan Ladd
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-07-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: test_bench-fixture
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: test_bench-bootstrap
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description:
42
+ email: nathanladd+github@gmail.com
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - lib/test_bench/run.rb
48
+ - lib/test_bench/run/controls.rb
49
+ - lib/test_bench/run/controls/directory.rb
50
+ - lib/test_bench/run/controls/event_data.rb
51
+ - lib/test_bench/run/controls/events/event_data.rb
52
+ - lib/test_bench/run/controls/events/file_crashed.rb
53
+ - lib/test_bench/run/controls/events/file_finished.rb
54
+ - lib/test_bench/run/controls/events/file_started.rb
55
+ - lib/test_bench/run/controls/events/finished.rb
56
+ - lib/test_bench/run/controls/events/session.rb
57
+ - lib/test_bench/run/controls/events/started.rb
58
+ - lib/test_bench/run/controls/exception.rb
59
+ - lib/test_bench/run/controls/executor.rb
60
+ - lib/test_bench/run/controls/file.rb
61
+ - lib/test_bench/run/controls/file/create.rb
62
+ - lib/test_bench/run/controls/file/pattern.rb
63
+ - lib/test_bench/run/controls/path.rb
64
+ - lib/test_bench/run/controls/process_id.rb
65
+ - lib/test_bench/run/controls/random.rb
66
+ - lib/test_bench/run/controls/result.rb
67
+ - lib/test_bench/run/controls/time.rb
68
+ - lib/test_bench/run/events.rb
69
+ - lib/test_bench/run/executor.rb
70
+ - lib/test_bench/run/executor/serial.rb
71
+ - lib/test_bench/run/executor/substitute.rb
72
+ - lib/test_bench/run/file.rb
73
+ - lib/test_bench/run/file/substitute.rb
74
+ - lib/test_bench/run/get_files.rb
75
+ - lib/test_bench/run/get_files/substitute.rb
76
+ - lib/test_bench/run/output/file.rb
77
+ - lib/test_bench/run/output/summary.rb
78
+ - lib/test_bench/run/output/summary/error.rb
79
+ - lib/test_bench/run/run.rb
80
+ homepage: https://github.com/test-bench/test-bench-run
81
+ licenses:
82
+ - MIT
83
+ metadata: {}
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ requirements: []
99
+ rubygems_version: 3.4.10
100
+ signing_key:
101
+ specification_version: 4
102
+ summary: ruby
103
+ test_files: []