moto 0.9.17 → 1.0.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.
- checksums.yaml +4 -4
- data/bin/moto +1 -1
- data/lib/modes/run/thread_context.rb +24 -10
- data/lib/parameter_parser.rb +7 -0
- data/lib/reporting/listeners/console_dots.rb +24 -7
- data/lib/test/base.rb +7 -1
- data/lib/version.rb +1 -1
- metadata +2 -5
- data/lib/empty_listener.rb +0 -17
- data/lib/runner_logging.rb +0 -26
- data/lib/test_logging.rb +0 -46
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d2216e77b4bfad6cd5598a147586ed6567887fa0
|
4
|
+
data.tar.gz: d8fc5dc3f9cbc7d86c6798ddf0d38225ed556cd9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70c8d3fe2876552c6d14f8bdb8c547f68cde88c42fa791b184cbc72136d838adfb570899d2f39b3ba3ea81905acfcc25d1d519a72df7ac25613e8b99e5163b92
|
7
|
+
data.tar.gz: c2fd5dbd5e26d38b14f608d64ddc7cfea677d6990f7f46781db86ce88369368b90f214e0ea2d8c1296383a20cb3075a9f19dced7be6c1fb818bfb69a7f6d6479
|
data/bin/moto
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require_relative '../lib/test_logging'
|
4
3
|
require_relative '../lib/test/base'
|
5
4
|
|
6
5
|
require_relative '../lib/reporting/listeners/base'
|
@@ -10,4 +9,5 @@ require_relative '../lib/reporting/listeners/junit_xml'
|
|
10
9
|
require_relative '../lib/reporting/listeners/webui'
|
11
10
|
|
12
11
|
require_relative '../lib/parameter_parser'
|
12
|
+
|
13
13
|
Moto::ParameterParser.parse_user_input(ARGV)
|
@@ -18,10 +18,7 @@ module Moto
|
|
18
18
|
FileUtils.mkdir_p(log_directory)
|
19
19
|
end
|
20
20
|
|
21
|
-
|
22
|
-
file.chmod(0o666)
|
23
|
-
Thread.current['logger'] = Logger.new(file)
|
24
|
-
Thread.current['logger'].level = config[:test_log_level] || Logger::DEBUG
|
21
|
+
setup_logger
|
25
22
|
end
|
26
23
|
|
27
24
|
def run
|
@@ -34,20 +31,25 @@ module Moto
|
|
34
31
|
(1..max_attempts).each do |attempt|
|
35
32
|
|
36
33
|
@test.before
|
37
|
-
|
34
|
+
logger.info("Start: #{@test.name} attempt #{attempt}/#{max_attempts}")
|
38
35
|
|
39
36
|
begin
|
40
37
|
@test.run_test
|
41
38
|
rescue Exceptions::TestForcedPassed, Exceptions::TestForcedFailure, Exceptions::TestSkipped => e
|
42
|
-
|
39
|
+
logger.info(e.message)
|
43
40
|
rescue Exception => e
|
44
|
-
|
45
|
-
|
41
|
+
logger.error("#{e.class.name}: #{e.message}")
|
42
|
+
logger.error(e.backtrace.join("\n"))
|
43
|
+
|
44
|
+
if config[:explicit_errors]
|
45
|
+
raise e
|
46
|
+
end
|
47
|
+
|
46
48
|
end
|
47
49
|
|
48
50
|
@test.after
|
49
51
|
|
50
|
-
|
52
|
+
logger.info("Result: #{@test.status.results.last.code}")
|
51
53
|
|
52
54
|
# test should have another attempt in case of an error / failure / none at all
|
53
55
|
unless (@test.status.results.last.code == Moto::Test::Result::ERROR && config[:test_reattempt_on_error]) ||
|
@@ -63,7 +65,7 @@ module Moto
|
|
63
65
|
end # Make another attempt
|
64
66
|
|
65
67
|
# Close and flush stream to file
|
66
|
-
|
68
|
+
logger.close
|
67
69
|
|
68
70
|
# Reporting: end_test
|
69
71
|
@test_reporter.report_end_test(@test.status)
|
@@ -75,6 +77,18 @@ module Moto
|
|
75
77
|
end
|
76
78
|
private :config
|
77
79
|
|
80
|
+
def setup_logger
|
81
|
+
file = File.open(@test.log_path, File::WRONLY | File::TRUNC | File::CREAT)
|
82
|
+
file.chmod(0o666)
|
83
|
+
|
84
|
+
Thread.current['logger'] = Logger.new(file)
|
85
|
+
logger.level = config[:test_log_level] || Logger::DEBUG
|
86
|
+
end
|
87
|
+
|
88
|
+
def logger
|
89
|
+
Thread.current['logger']
|
90
|
+
end
|
91
|
+
|
78
92
|
end
|
79
93
|
end
|
80
94
|
end
|
data/lib/parameter_parser.rb
CHANGED
@@ -65,6 +65,7 @@ module Moto
|
|
65
65
|
opts.on('--stop-on-fail') {options[:stop_on][:fail] = true}
|
66
66
|
opts.on('--stop-on-skip') {options[:stop_on][:skip] = true}
|
67
67
|
opts.on('--dry-run') {options[:dry_run] = true}
|
68
|
+
opts.on('-x', '--explicit_errors') {options[:explicit_errors] = true}
|
68
69
|
end.parse!
|
69
70
|
|
70
71
|
if options[:tests]
|
@@ -89,6 +90,7 @@ module Moto
|
|
89
90
|
Moto::Lib::Config.moto[:test_runner][:thread_count] = options[:threads] if options[:threads]
|
90
91
|
Moto::Lib::Config.moto[:test_runner][:test_attempt_max] = options[:attempts] if options[:attempts]
|
91
92
|
Moto::Lib::Config.moto[:test_runner][:dry_run] = options[:dry_run] if options[:dry_run]
|
93
|
+
Moto::Lib::Config.moto[:test_runner][:explicit_errors] = options[:explicit_errors] if options[:explicit_errors]
|
92
94
|
|
93
95
|
return options
|
94
96
|
end
|
@@ -220,6 +222,11 @@ module Moto
|
|
220
222
|
--stop-on-skip Moto will stop test execution when a skip is encountered in test results
|
221
223
|
--dry-run Moto will list all test cases which would be run with provided arguments
|
222
224
|
|
225
|
+
--x, explicit_errors Use for development of tests - each code error in test will be caught,
|
226
|
+
logged as would normally do but will be also additionaly re-thrown.
|
227
|
+
This will obviously stop execution of selected set of tests but will provide
|
228
|
+
full stack and error message to the developer.
|
229
|
+
|
223
230
|
|
224
231
|
|
225
232
|
==============
|
@@ -1,8 +1,15 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
1
3
|
module Moto
|
2
4
|
module Reporting
|
3
5
|
module Listeners
|
4
6
|
class ConsoleDots < Base
|
5
7
|
|
8
|
+
def initialize(run_params)
|
9
|
+
@displayed_results = 0
|
10
|
+
@semaphore = Mutex.new
|
11
|
+
end
|
12
|
+
|
6
13
|
def end_run(run_status)
|
7
14
|
puts ''
|
8
15
|
puts ''
|
@@ -46,15 +53,25 @@ module Moto
|
|
46
53
|
end
|
47
54
|
|
48
55
|
def end_test(test_status)
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
56
|
+
@semaphore.synchronize do
|
57
|
+
@displayed_results += 1
|
58
|
+
|
59
|
+
representation =
|
60
|
+
case test_status.results.last.code
|
61
|
+
when Moto::Test::Result::PASSED then '.'
|
62
|
+
when Moto::Test::Result::FAILURE then 'F'
|
63
|
+
when Moto::Test::Result::ERROR then 'E'
|
64
|
+
when Moto::Test::Result::SKIPPED then 's'
|
65
|
+
end
|
66
|
+
|
67
|
+
if @displayed_results%50 != 0
|
68
|
+
print representation
|
69
|
+
else
|
70
|
+
puts representation
|
71
|
+
end
|
72
|
+
|
54
73
|
end
|
55
|
-
STDOUT.flush
|
56
74
|
end
|
57
|
-
|
58
75
|
end
|
59
76
|
end
|
60
77
|
end
|
data/lib/test/base.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative 'status'
|
2
|
+
require 'logger'
|
2
3
|
|
3
4
|
module Moto
|
4
5
|
module Test
|
@@ -140,7 +141,7 @@ module Moto
|
|
140
141
|
line_number = caller.select { |l| l.match(/#{static_path}:\d*:in `run'/) }.first[/\d+/].to_i
|
141
142
|
|
142
143
|
status.log_failure("ASSERTION FAILED in line #{line_number}: #{message}")
|
143
|
-
|
144
|
+
logger.error(message)
|
144
145
|
end
|
145
146
|
end
|
146
147
|
|
@@ -151,6 +152,11 @@ module Moto
|
|
151
152
|
Moto::Lib::Config.environment_const(key)
|
152
153
|
end
|
153
154
|
|
155
|
+
# @return [Logger]
|
156
|
+
def logger
|
157
|
+
Thread.current['logger']
|
158
|
+
end
|
159
|
+
|
154
160
|
end
|
155
161
|
end
|
156
162
|
end
|
data/lib/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: moto
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bartek Wilczek
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2017-
|
14
|
+
date: 2017-10-01 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: activesupport
|
@@ -85,7 +85,6 @@ extra_rdoc_files: []
|
|
85
85
|
files:
|
86
86
|
- bin/moto
|
87
87
|
- lib/config.rb
|
88
|
-
- lib/empty_listener.rb
|
89
88
|
- lib/exceptions/base.rb
|
90
89
|
- lib/exceptions/test_forced_failure.rb
|
91
90
|
- lib/exceptions/test_forced_passed.rb
|
@@ -105,14 +104,12 @@ files:
|
|
105
104
|
- lib/reporting/listeners/webui.rb
|
106
105
|
- lib/reporting/run_status.rb
|
107
106
|
- lib/reporting/test_reporter.rb
|
108
|
-
- lib/runner_logging.rb
|
109
107
|
- lib/test/base.rb
|
110
108
|
- lib/test/generator.rb
|
111
109
|
- lib/test/metadata.rb
|
112
110
|
- lib/test/metadata_generator.rb
|
113
111
|
- lib/test/result.rb
|
114
112
|
- lib/test/status.rb
|
115
|
-
- lib/test_logging.rb
|
116
113
|
- lib/version.rb
|
117
114
|
homepage: https://github.com/bwilczek/moto
|
118
115
|
licenses:
|
data/lib/empty_listener.rb
DELETED
data/lib/runner_logging.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
module Moto
|
2
|
-
module RunnerLogging
|
3
|
-
|
4
|
-
# TODO: merge it somehow with TestLogging. Parametrize logger object?
|
5
|
-
def self.included(cls)
|
6
|
-
def cls.method_added(name)
|
7
|
-
excluded_methods = Moto::EmptyListener.instance_methods(false)
|
8
|
-
excluded_methods << :new
|
9
|
-
excluded_methods << :initialize
|
10
|
-
# TODO: configure more excluded classes/methods
|
11
|
-
return if @added
|
12
|
-
@added = true # protect from recursion
|
13
|
-
original_method = "original_#{name}"
|
14
|
-
alias_method original_method, name
|
15
|
-
define_method(name) do |*args|
|
16
|
-
Thread.current['logger'].debug("#{self.class.name}::#{__callee__} ENTER >>> #{args}") unless excluded_methods.include? name
|
17
|
-
result = send original_method, *args
|
18
|
-
Thread.current['logger'].debug("#{self.class.name}::#{__callee__} LEAVE <<< #{result} ") unless excluded_methods.include? name
|
19
|
-
result
|
20
|
-
end
|
21
|
-
@added = false
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
data/lib/test_logging.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
module Moto
|
2
|
-
module TestLogging
|
3
|
-
|
4
|
-
@@ignore_logging = []
|
5
|
-
|
6
|
-
def self.included(cls)
|
7
|
-
|
8
|
-
def cls.ignore_logging(method)
|
9
|
-
full_name = "#{self.name}::#{method}"
|
10
|
-
@@ignore_logging << full_name
|
11
|
-
end
|
12
|
-
|
13
|
-
def cls.method_added(name)
|
14
|
-
|
15
|
-
@@ignore_logging << "#{self.name}::new"
|
16
|
-
@@ignore_logging << "#{self.name}::initialize"
|
17
|
-
|
18
|
-
return if @added
|
19
|
-
@added = true # protect from recursion
|
20
|
-
original_method = "original_#{name}"
|
21
|
-
alias_method original_method, name
|
22
|
-
define_method(name) do |*args|
|
23
|
-
full_name = "#{self.class.name}::#{__callee__}"
|
24
|
-
# TODO: use self.class.ancestors to figure out if ancestor::__callee__ is not in @@ignore_logging
|
25
|
-
skip_logging = @@ignore_logging.include? full_name
|
26
|
-
unless skip_logging
|
27
|
-
self.class.ancestors.each do |a|
|
28
|
-
ancestor_name = "#{a.name}::#{__callee__}"
|
29
|
-
if @@ignore_logging.include? ancestor_name
|
30
|
-
skip_logging = true
|
31
|
-
break
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
Thread.current['logger'].debug("ENTER >>> #{self.class.name}::#{__callee__}(#{args})") unless skip_logging
|
36
|
-
result = send original_method, *args
|
37
|
-
# Below is the hack to properly escape binary data (if any manages to make it to logs)
|
38
|
-
Thread.current['logger'].debug("LEAVE <<< #{self.class.name}::#{__callee__} => #{[result].to_s[1..-2]}") unless skip_logging
|
39
|
-
result
|
40
|
-
end
|
41
|
-
@added = false
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
46
|
-
end
|