test_bench-run 0

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