moto 0.0.17 → 0.0.18
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/lib/cli.rb +9 -16
- data/lib/initializer.rb +7 -0
- data/lib/result.rb +1 -1
- data/lib/runner.rb +19 -15
- data/lib/test_generator.rb +1 -1
- data/lib/thread_context.rb +59 -62
- data/lib/thread_pool.rb +32 -0
- data/lib/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3799edbb3011aab7abc3f801548862865d5dc196
|
4
|
+
data.tar.gz: 49183582720dd86f5f1fd4335a5e5ca3d9228731
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49c6e8a0e15ee3275fced887be1e25296be84dedf652e54f372040b1d5b8fe55593efe32a0b659a3a707d4b3289491b0bff10a77c741decdc4b003491164335d
|
7
|
+
data.tar.gz: 32d7e271f59cbdbc46f8712b5ef2bc0c141f38057c1a633fc8f85c7f679f5799065390d9965810939d0a249fdec6894314bf73811004d9f55d317a77ce6e667c
|
data/lib/cli.rb
CHANGED
@@ -18,6 +18,7 @@ require_relative './test_logging'
|
|
18
18
|
require_relative './runner_logging'
|
19
19
|
require_relative './runner'
|
20
20
|
require_relative './thread_context'
|
21
|
+
require_relative './thread_pool'
|
21
22
|
require_relative './result'
|
22
23
|
require_relative './assert'
|
23
24
|
require_relative './test'
|
@@ -51,29 +52,21 @@ module Moto
|
|
51
52
|
end
|
52
53
|
|
53
54
|
# TODO Optimization for files without #MOTO_TAGS
|
54
|
-
unless argv[
|
55
|
+
unless argv[:tags].nil?
|
55
56
|
tests_total = Dir.glob("#{MotoApp::DIR}/tests/**/*.rb")
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
if line.include?(tag_name + ',')
|
63
|
-
test_paths_absolute.include?(test_dir) || test_paths_absolute << test_dir
|
64
|
-
break
|
65
|
-
else
|
66
|
-
break
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
57
|
+
tests_total.each do |test_path|
|
58
|
+
test_body = File.read(test_path)
|
59
|
+
matches = test_body.match(/^#(\s*)MOTO_TAGS:([^\n\r]+)$/m)
|
60
|
+
if matches
|
61
|
+
test_tags = matches.to_a[2].gsub(/\s*/, '').split(',')
|
62
|
+
test_paths_absolute << test_path unless (argv[:tags]&test_tags).empty?
|
70
63
|
end
|
71
64
|
end
|
72
65
|
end
|
73
66
|
|
74
67
|
#TODO Display criteria used
|
75
68
|
if test_paths_absolute.empty?
|
76
|
-
puts 'No tests found for given arguments'
|
69
|
+
puts 'No tests found for given arguments.'
|
77
70
|
exit 1
|
78
71
|
end
|
79
72
|
|
data/lib/initializer.rb
ADDED
data/lib/result.rb
CHANGED
@@ -35,7 +35,7 @@ module Moto
|
|
35
35
|
@summary[:duration] = @summary[:finished_at] - @summary[:started_at]
|
36
36
|
@summary[:result] = PASSED
|
37
37
|
@summary[:result] = FAILURE unless @results.values.select{ |v| v[:failures].count > 0 }.empty?
|
38
|
-
@summary[:result] = ERROR unless @results.values.select{ |v|
|
38
|
+
@summary[:result] = ERROR unless @results.values.select{ |v| v[:result] == ERROR }.empty?
|
39
39
|
@summary[:cnt_all] = @results.count
|
40
40
|
@summary[:tests_passed] = @results.select{ |k,v| v[:result] == PASSED }
|
41
41
|
@summary[:tests_failure] = @results.select{ |k,v| v[:result] == FAILURE }
|
data/lib/runner.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Moto
|
2
2
|
class Runner
|
3
|
-
|
3
|
+
|
4
4
|
attr_reader :result
|
5
5
|
attr_reader :listeners
|
6
6
|
attr_reader :logger
|
@@ -8,24 +8,24 @@ module Moto
|
|
8
8
|
attr_reader :assert
|
9
9
|
attr_reader :config
|
10
10
|
attr_reader :name
|
11
|
-
|
11
|
+
|
12
12
|
def initialize(tests, listeners, environments, config, name)
|
13
13
|
@tests = tests
|
14
14
|
@config = config
|
15
|
-
@
|
15
|
+
@thread_pool = ThreadPool.new(my_config[:thread_count] || 1)
|
16
16
|
@name = name
|
17
|
-
|
17
|
+
|
18
18
|
# TODO: initialize logger from config (yml or just ruby code)
|
19
19
|
# @logger = Logger.new(STDOUT)
|
20
20
|
@logger = Logger.new(File.open("#{MotoApp::DIR}/moto.log", File::WRONLY | File::APPEND | File::CREAT))
|
21
21
|
# @logger.level = Logger::WARN
|
22
|
-
|
22
|
+
|
23
23
|
@result = Result.new(self)
|
24
|
-
|
24
|
+
|
25
25
|
# TODO: validate envs, maybe no-env should be supported as well?
|
26
26
|
environments << :__default if environments.empty?
|
27
27
|
@environments = environments
|
28
|
-
|
28
|
+
|
29
29
|
@listeners = []
|
30
30
|
if listeners.empty?
|
31
31
|
my_config[:default_listeners].each do |l|
|
@@ -38,7 +38,7 @@ module Moto
|
|
38
38
|
end
|
39
39
|
@listeners.unshift(@result)
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
def my_config
|
43
43
|
caller_path = caller.first.to_s.split(/:\d/)[0]
|
44
44
|
keys = []
|
@@ -55,19 +55,23 @@ module Moto
|
|
55
55
|
eval "@config#{keys.map{|k| "[:#{k}]" }.join('')}"
|
56
56
|
end
|
57
57
|
|
58
|
-
# TODO: assigning tests to threads dynamically
|
59
58
|
def run
|
59
|
+
if File.exists?( "#{MotoApp::DIR}/lib/initializer.rb" )
|
60
|
+
require("#{Moto::DIR}/lib/initializer.rb")
|
61
|
+
require("#{MotoApp::DIR}/lib/initializer.rb")
|
62
|
+
initializer = MotoApp::Initializer.new(self)
|
63
|
+
initializer.init
|
64
|
+
end
|
60
65
|
@listeners.each { |l| l.start_run }
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
tc = ThreadContext.new(self, slice)
|
66
|
+
@tests.each do |test|
|
67
|
+
@thread_pool.schedule do
|
68
|
+
tc = ThreadContext.new(self, test)
|
65
69
|
tc.run
|
66
70
|
end
|
67
71
|
end
|
68
|
-
@
|
72
|
+
@thread_pool.shutdown
|
69
73
|
@listeners.each { |l| l.end_run }
|
70
74
|
end
|
71
|
-
|
75
|
+
|
72
76
|
end
|
73
77
|
end
|
data/lib/test_generator.rb
CHANGED
@@ -23,6 +23,7 @@ module Moto
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def create_module_tree(root_module, next_modules)
|
26
|
+
return root_module if next_modules.empty?
|
26
27
|
next_module_name = next_modules.shift
|
27
28
|
if root_module.const_defined?(next_module_name.to_sym)
|
28
29
|
m = root_module.const_get(next_module_name.to_sym)
|
@@ -30,7 +31,6 @@ module Moto
|
|
30
31
|
m = Module.new
|
31
32
|
root_module.const_set(next_module_name.to_sym, m)
|
32
33
|
end
|
33
|
-
return m if next_modules.empty?
|
34
34
|
create_module_tree(m, next_modules)
|
35
35
|
end
|
36
36
|
|
data/lib/thread_context.rb
CHANGED
@@ -2,32 +2,30 @@ require 'erb'
|
|
2
2
|
|
3
3
|
module Moto
|
4
4
|
class ThreadContext
|
5
|
-
|
5
|
+
|
6
6
|
# all resources specific for single thread will be initialized here. E.g. browser session
|
7
7
|
attr_reader :runner
|
8
8
|
attr_reader :logger
|
9
9
|
# attr_reader :log_path
|
10
10
|
attr_reader :current_test
|
11
|
-
|
12
|
-
def initialize(runner,
|
11
|
+
|
12
|
+
def initialize(runner, test)
|
13
13
|
@runner = runner
|
14
|
-
@
|
14
|
+
@test = test
|
15
15
|
@clients = {}
|
16
|
-
@
|
17
|
-
t.context = self
|
18
|
-
end
|
16
|
+
@test.context = self
|
19
17
|
@config = {}
|
20
18
|
Dir.glob("config/*.yml").each do |f|
|
21
19
|
@config.deep_merge! YAML.load_file(f)
|
22
20
|
end
|
23
21
|
end
|
24
|
-
|
22
|
+
|
25
23
|
def client(name)
|
26
24
|
return @clients[name] if @clients.key? name
|
27
|
-
|
25
|
+
|
28
26
|
name_app = 'MotoApp::Clients::' + name
|
29
27
|
name_moto = 'Moto::Clients::' + name
|
30
|
-
|
28
|
+
|
31
29
|
c = try_client(name_app, "#{MotoApp::DIR}/lib")
|
32
30
|
unless c.nil?
|
33
31
|
@clients[name] = c
|
@@ -41,11 +39,11 @@ module Moto
|
|
41
39
|
end
|
42
40
|
raise "Could not find client class for name #{name}"
|
43
41
|
end
|
44
|
-
|
42
|
+
|
45
43
|
def try_client(name, dir)
|
46
|
-
begin
|
44
|
+
begin
|
47
45
|
a = name.underscore.split('/')
|
48
|
-
client_path = a[1
|
46
|
+
client_path = a[1..-1].join('/')
|
49
47
|
require "#{dir}/#{client_path}"
|
50
48
|
client_const = name.constantize
|
51
49
|
instance = client_const.new(self)
|
@@ -53,13 +51,13 @@ module Moto
|
|
53
51
|
instance.start_run
|
54
52
|
instance.start_test(@current_test)
|
55
53
|
return instance
|
56
|
-
rescue Exception => e
|
54
|
+
rescue Exception => e
|
57
55
|
# puts e
|
58
|
-
# puts e.backtrace
|
56
|
+
# puts e.backtrace
|
59
57
|
return nil
|
60
58
|
end
|
61
59
|
end
|
62
|
-
|
60
|
+
|
63
61
|
def const(key)
|
64
62
|
key = key.to_s
|
65
63
|
key = "#{@current_test.env.to_s}.#{key}" if @current_test.env != :__default
|
@@ -76,57 +74,56 @@ module Moto
|
|
76
74
|
end
|
77
75
|
v
|
78
76
|
end
|
79
|
-
|
77
|
+
|
80
78
|
def run
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
@
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
#
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
(1..max_attempts).each do |attempt|
|
95
|
-
test.init(env, params, params_index)
|
96
|
-
# TODO: log path might be specified (to some extent) by the configuration
|
97
|
-
test.log_path = "#{test.dir}/#{test.name.gsub(/\s+/, '_').gsub('::', '_').gsub('/', '_')}.log"
|
98
|
-
@logger = Logger.new(File.open(test.log_path, File::WRONLY | File::TRUNC | File::CREAT))
|
99
|
-
# TODO: make logger level configurable
|
100
|
-
@logger.level = @runner.my_config[:log_level]
|
101
|
-
@current_test = test
|
102
|
-
@runner.listeners.each { |l| l.start_test(test) }
|
103
|
-
@clients.each_value { |c| c.start_test(test) }
|
104
|
-
test.before
|
105
|
-
@logger.info "Start: #{test.name} attempt #{attempt}/#{max_attempts}"
|
106
|
-
begin
|
107
|
-
test.run
|
108
|
-
rescue Exceptions::TestForcedPassed, Exceptions::TestForcedFailure, Exceptions::TestSkipped => e
|
109
|
-
logger.info(e.message)
|
110
|
-
@runner.result.add_error(test, e)
|
111
|
-
rescue Exception => e
|
112
|
-
@logger.error("#{e.class.name}: #{e.message}")
|
113
|
-
@logger.error(e.backtrace.join("\n"))
|
114
|
-
@runner.result.add_error(test, e)
|
115
|
-
end
|
116
|
-
test.after
|
117
|
-
@clients.each_value { |c| c.end_test(test) }
|
118
|
-
# HAX: running end_test on results now, on other listeners after logger is closed
|
119
|
-
@runner.listeners.first.end_test(test)
|
120
|
-
@logger.info("Result: #{test.result}")
|
121
|
-
@logger.close
|
122
|
-
@runner.listeners[1..-1].each { |l| l.end_test(test) }
|
123
|
-
break unless [Result::FAILURE, Result::ERROR].include? test.result
|
124
|
-
end # RETRY
|
79
|
+
# remove log files from previous execution
|
80
|
+
Dir.glob("#{@test.dir}/*.log").each {|f| File.delete f }
|
81
|
+
max_attempts = @runner.my_config[:max_attempts] || 1
|
82
|
+
@runner.environments.each do |env|
|
83
|
+
params_path = "#{@test.dir}/#{@test.filename}.yml"
|
84
|
+
params_all = [{}]
|
85
|
+
params_all = YAML.load(ERB.new(File.read(params_path)).result) if File.exists?(params_path)
|
86
|
+
#params_all = YAML.load_file(params_path) if File.exists?(params_path)
|
87
|
+
params_all.each_with_index do |params, params_index|
|
88
|
+
# Filtering out param sets that are specific to certain envs
|
89
|
+
unless params['__env'].nil?
|
90
|
+
allowed_envs = params['__env'].is_a?(String) ? [params['__env']] : params['__env']
|
91
|
+
next unless allowed_envs.include? env
|
125
92
|
end
|
93
|
+
(1..max_attempts).each do |attempt|
|
94
|
+
@test.init(env, params, params_index)
|
95
|
+
# TODO: log path might be specified (to some extent) by the configuration
|
96
|
+
@test.log_path = "#{@test.dir}/#{@test.name.gsub(/\s+/, '_').gsub('::', '_').gsub('/', '_')}.log"
|
97
|
+
@logger = Logger.new(File.open(@test.log_path, File::WRONLY | File::TRUNC | File::CREAT))
|
98
|
+
@logger.level = @runner.my_config[:log_level] || Logger::DEBUG
|
99
|
+
@current_test = @test
|
100
|
+
@runner.listeners.each { |l| l.start_test(@test) }
|
101
|
+
@clients.each_value { |c| c.start_test(@test) }
|
102
|
+
@test.before
|
103
|
+
@logger.info "Start: #{@test.name} attempt #{attempt}/#{max_attempts}"
|
104
|
+
begin
|
105
|
+
@test.run
|
106
|
+
rescue Exceptions::TestForcedPassed, Exceptions::TestForcedFailure, Exceptions::TestSkipped => e
|
107
|
+
logger.info(e.message)
|
108
|
+
@runner.result.add_error(@test, e)
|
109
|
+
rescue Exception => e
|
110
|
+
@logger.error("#{e.class.name}: #{e.message}")
|
111
|
+
@logger.error(e.backtrace.join("\n"))
|
112
|
+
@runner.result.add_error(@test, e)
|
113
|
+
end
|
114
|
+
@test.after
|
115
|
+
@clients.each_value { |c| c.end_test(@test) }
|
116
|
+
# HAX: running end_test on results now, on other listeners after logger is closed
|
117
|
+
@runner.listeners.first.end_test(@test)
|
118
|
+
@logger.info("Result: #{@test.result}")
|
119
|
+
@logger.close
|
120
|
+
@runner.listeners[1..-1].each { |l| l.end_test(@test) }
|
121
|
+
break unless [Result::FAILURE, Result::ERROR].include? @test.result
|
122
|
+
end # RETRY
|
126
123
|
end
|
127
124
|
end
|
128
125
|
@clients.each_value { |c| c.end_run }
|
129
126
|
end
|
130
|
-
|
127
|
+
|
131
128
|
end
|
132
129
|
end
|
data/lib/thread_pool.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
module Moto
|
2
|
+
class ThreadPool
|
3
|
+
|
4
|
+
def initialize(size=1)
|
5
|
+
@size = size
|
6
|
+
@jobs = Queue.new
|
7
|
+
@pool = Array.new(@size) do |i|
|
8
|
+
Thread.new do
|
9
|
+
Thread.current[:id] = i
|
10
|
+
catch(:exit) do
|
11
|
+
loop do
|
12
|
+
job, args = @jobs.pop
|
13
|
+
job.call(*args)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def schedule(*args, &block)
|
21
|
+
@jobs << [block, args]
|
22
|
+
end
|
23
|
+
|
24
|
+
def shutdown
|
25
|
+
@size.times do
|
26
|
+
schedule { throw :exit }
|
27
|
+
end
|
28
|
+
@pool.each(&:join)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
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.0.
|
4
|
+
version: 0.0.18
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bartek Wilczek
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2016-01-11 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
@@ -86,6 +86,7 @@ files:
|
|
86
86
|
- lib/cli.rb
|
87
87
|
- lib/empty_listener.rb
|
88
88
|
- lib/forward_context_methods.rb
|
89
|
+
- lib/initializer.rb
|
89
90
|
- lib/page.rb
|
90
91
|
- lib/parser.rb
|
91
92
|
- lib/result.rb
|
@@ -95,6 +96,7 @@ files:
|
|
95
96
|
- lib/test_generator.rb
|
96
97
|
- lib/test_logging.rb
|
97
98
|
- lib/thread_context.rb
|
99
|
+
- lib/thread_pool.rb
|
98
100
|
- lib/version.rb
|
99
101
|
- lib/clients/base.rb
|
100
102
|
- lib/clients/website.rb
|