moto 0.9.11 → 0.9.17

Sign up to get free protection for your applications and to get access to all the features.
data/lib/initializer.rb DELETED
@@ -1,7 +0,0 @@
1
- module Moto
2
- class Initializer
3
- def initialize(runner)
4
- @runner = runner
5
- end
6
- end
7
- end
data/lib/parser.rb DELETED
@@ -1,182 +0,0 @@
1
- require 'optparse'
2
- require 'yaml'
3
-
4
- require_relative '../lib/cli'
5
- require_relative '../lib/app_generator'
6
- require_relative '../lib/config'
7
- module Moto
8
-
9
- class Parser
10
-
11
- def self.run(argv)
12
- begin
13
-
14
- if argv[0] == '--version'
15
- puts Moto::VERSION
16
- elsif argv[0] == 'run' && argv.length > 1
17
- Moto::Cli.run(run_parse(argv))
18
- elsif argv[0] == 'generate' && argv.length > 1
19
- Moto::AppGenerator.run(generate_parse(argv))
20
- else
21
- show_help
22
- end
23
- rescue SystemExit => e
24
- Kernel.exit(e.status)
25
- rescue Exception => e
26
- puts e.message + "\n\n"
27
- puts e.backtrace.join("\n")
28
- end
29
- end
30
-
31
- def self.run_parse(argv)
32
- require 'bundler/setup'
33
- Bundler.require
34
-
35
- # Default options
36
- options = {}
37
- options[:listeners] = []
38
- options[:run_name] = nil
39
- options[:suite_name] = nil
40
- options[:assignee] = nil
41
- options[:stop_on] = {error: false, fail: false, skip: false}
42
-
43
- # Parse arguments
44
- OptionParser.new do |opts|
45
- opts.on('-t', '--tests Tests', Array) { |v| options[:tests] = v }
46
- opts.on('-g', '--tags Tags', Array) { |v| options[:tags] = v }
47
- opts.on('-f', '--filters Filters', Array) { |v| options[:filters] = v }
48
- opts.on('-l', '--listeners Listeners', Array) { |v| options[:listeners] = v }
49
- opts.on('-e', '--environment Environment') { |v| options[:environment] = v }
50
- opts.on('-r', '--runname RunName') { |v| options[:run_name] = v }
51
- opts.on('-s', '--suitename SuiteName') { |v| options[:suite_name] = v }
52
- opts.on('-a', '--assignee Assignee') { |v| options[:assignee] = v }
53
- opts.on('-c', '--config Config') { |v| options[:config_name] = v }
54
- opts.on('--threads ThreadCount', Integer) { |v| options[:threads] = v }
55
- opts.on('--attempts AttemptCount', Integer) { |v| options[:attempts] = v }
56
- opts.on('--stop-on-error') { options[:stop_on][:error] = true }
57
- opts.on('--stop-on-fail') { options[:stop_on][:fail] = true }
58
- opts.on('--stop-on-skip') { options[:stop_on][:skip] = true }
59
- opts.on('--dry-run') { options[:dry_run] = true }
60
- end.parse!
61
-
62
- if options[:tests]
63
- options[:tests].each do |path|
64
- path.sub!(%r{\/$}, '') # remove trailing "/"
65
- end
66
- end
67
-
68
- if options[:run_name].nil?
69
- options[:run_name] = evaluate_name(options[:tests], options[:tags], options[:filters])
70
- end
71
-
72
- if options[:environment]
73
- Moto::Lib::Config.environment = options[:environment]
74
- Moto::Lib::Config.load_configuration(options[:config_name] ? options[:config_name] : 'moto')
75
- else
76
- puts 'ERROR: Environment is mandatory.'
77
- Kernel.exit(-1)
78
- end
79
-
80
- Moto::Lib::Config.moto[:test_runner][:thread_count] = options[:threads] if options[:threads]
81
- Moto::Lib::Config.moto[:test_runner][:test_attempt_max] = options[:attempts] if options[:attempts]
82
- Moto::Lib::Config.moto[:test_runner][:dry_run] = options[:dry_run] if options[:dry_run]
83
-
84
- return options
85
- end
86
-
87
- # Generate default name based on input parameters
88
- def self.evaluate_name(tests, tags, filters)
89
- name = ''
90
-
91
- if tests
92
- name << "Tests: #{tests.join(',')} "
93
- end
94
-
95
- if tags
96
- name << "Tags: #{tags.join(',')} "
97
- end
98
-
99
- if filters
100
- name << "Filters: #{filters.join(',')} "
101
- end
102
-
103
- return name
104
- end
105
-
106
- # Parses attributes passed to the application when run by 'moto generate'
107
- def self.generate_parse(argv)
108
- options = {}
109
-
110
- OptionParser.new do |opts|
111
- opts.on('-t', '--test Test') { |v| options[:dir ] = v }
112
- opts.on('-a', '--appname AppName') { |v| options[:app_name ] = v }
113
- opts.on('-b', '--baseclass BaseClass') { |v| options[:base_class] = v }
114
- opts.on('-f', '--force') { options[:force ] = true }
115
- end.parse!
116
-
117
- options[:dir] = options[:dir].underscore
118
-
119
- if options[:app_name].nil?
120
- options[:app_name] = 'MotoApp'
121
- end
122
-
123
- return options
124
- end
125
-
126
- def self.show_help
127
- puts """
128
- Moto (#{Moto::VERSION}) CLI Help:
129
- moto --version Display current version
130
-
131
- MOTO RUN:
132
- -t, --tests Tests to be executed.
133
- -g, --tags Tags of tests to be executed.
134
- Use # MOTO_TAGS: TAGNAME in test to assign tag.
135
- -f, --filters Tags that filter tests passed via -t parameter.
136
- Only tests in appropriate directory, having all of the specified tags will be executed.
137
- Use # MOTO_TAGS: TAGNAME1 in test to assign tag.
138
- Use ~ to filter tests that do not contain specific tag, e.g. ~tag
139
-
140
-
141
- -e, --environment Mandatory environment. Environment constants and tests parametrized in certain way depend on this.
142
- -c, --config Name of the config, without extension, to be loaded from MotoApp/config/CONFIG_NAME.rb
143
- Default: moto (which loads: MotoApp/config/moto.rb)
144
-
145
-
146
- -l, --listeners Reporters to be used.
147
- Defaults are Moto::Reporting::Listeners::ConsoleDots, Moto::Reporting::Listeners::JunitXml
148
- One reporter that is always used: Moto::Reporting::Listeners::KernelCode
149
- -s, --suitename Name of the test suite to which should aggregate the results of current test run.
150
- Required when specifying MotoWebUI as one of the listeners.
151
- -r, --runname Name of the test run to which everything will be reported when using MotoWebUI.
152
- Default: Value of -g or -t depending on which one was specified.
153
- -a, --assignee ID of a person responsible for current test run.
154
- Can have a default value set in config/webui section.
155
- --threads Thread count. Run tests in parallel.
156
- --attempts Attempt count. Max number of test execution times if failed.
157
-
158
- --stop-on-error Moto will stop test execution when an error is encountered in test results
159
- --stop-on-fail Moto will stop test execution when a failure is encountered in test results
160
- --stop-on-skip Moto will stop test execution when a skip is encountered in test results
161
- --dry-run Moto will list all test cases which would be run with provided arguments
162
-
163
-
164
- MOTO GENERATE:
165
- -t, --test Path and name of the test to be created.
166
- Examples:
167
- -ttest_name will create MotoApp/tests/test_name/test_name.rb
168
- -tdir/test_name will create MotoApp/tests/dir/test_name/test_name.rb
169
- -a, --appname Name of the application. Will be also used as topmost module in test file.
170
- Default: MotoApp
171
- -b, --baseclass File, without extension, with base class from which test will derive. Assumes one class per file.
172
- Examples:
173
- -btest_base will use the file in MotoApp/lib/test/test_base.rb
174
- -bsubdir/test_base will use the file in MotoApp/lib/test/subdir/test_base.rb
175
- By default class will derive from Moto::Test
176
- -f, --force Forces generator to overwrite previously existing class file in specified location.
177
- You have been warned.
178
- """
179
- end
180
-
181
- end
182
- end
@@ -1,127 +0,0 @@
1
- require 'rest-client'
2
- require 'sys/uname'
3
-
4
- module Moto
5
- module Reporting
6
- module Listeners
7
- class WebuiDeprecated < Base
8
-
9
- REST_MAX_TRIES = 3
10
- REST_TIMEOUT = 15
11
-
12
- def start_run
13
-
14
- @url = config[:url]
15
- @send_log_on_pass = config[:send_log_on_pass]
16
-
17
- data = {
18
- name: run_params[:name],
19
- result: :running,
20
- cnt_all: nil,
21
- cnt_passed: nil,
22
- cnt_failure: nil,
23
- cnt_error: nil,
24
- cnt_skipped: nil,
25
- user: Sys::Uname.sysname.downcase.include?('windows') ? ENV['USERNAME'] : ENV['LOGNAME'],
26
- host: Sys::Uname.nodename,
27
- pid: Process.pid
28
- }
29
-
30
- result = try {
31
- RestClient::Request.execute(method: :post, url: "#{@url}/api/runs", payload: data.to_json, timeout: REST_TIMEOUT, headers: {content_type: :json, accept: :json})
32
- }
33
-
34
- @run = JSON.parse(result)
35
- @tests = {}
36
- end
37
-
38
- def end_run(run_status)
39
- # PUT http://sandbox.dev:3000/api/runs/1
40
- data = {
41
- result: run_status.result,
42
- cnt_all: run_status.tests_all.length,
43
- cnt_passed: run_status.tests_passed.length,
44
- cnt_failure: run_status.tests_failed.length,
45
- cnt_error: run_status.tests_error.length,
46
- cnt_skipped: run_status.tests_skipped.length,
47
- duration: run_status.duration
48
- }
49
-
50
- result = try {
51
- RestClient::Request.execute(method: :put, url: "#{@url}/api/runs/#{@run['id']}", payload: data.to_json, timeout: REST_TIMEOUT, headers: {content_type: :json, accept: :json})
52
- }
53
- @run = JSON.parse(result)
54
- end
55
-
56
- def start_test(test_status, test_metadata)
57
- # POST http://sandbox.dev:3000/api/tests/create
58
- data = {
59
- name: test_status.name,
60
- class_name: test_status.test_class_name,
61
- log: nil,
62
- run_id: @run['id'],
63
- env: test_status.env,
64
- parameters: test_status.params.to_s,
65
- result: :running,
66
- error: nil,
67
- failures: nil
68
- }
69
-
70
- result = try {
71
- RestClient::Request.execute(method: :post, url: "#{@url}/api/tests", payload: data.to_json, timeout: REST_TIMEOUT, headers: {content_type: :json, accept: :json})
72
- }
73
- @tests[test_status.name] = JSON.parse(result)
74
- end
75
-
76
- def end_test(test_status)
77
-
78
- # don't send the log if the test has passed and appropriate flag is set to false
79
- if test_status.results.last.code == Moto::Test::Result::PASSED && !@send_log_on_pass
80
- full_log = nil
81
- else
82
- full_log = File.read(test_status.log_path)
83
- end
84
-
85
- data = {
86
- log: full_log,
87
- result: test_status.results.last.code,
88
- error: test_status.results.last.code == Moto::Test::Result::ERROR ? nil : test_status.results.last.message,
89
- failures: test_failures(test_status),
90
- duration: test_status.duration
91
- }
92
-
93
- result = try {
94
- RestClient::Request.execute(method: :put, url: "#{@url}/api/tests/#{@tests[test_status.name]['id']}", payload: data.to_json, timeout: REST_TIMEOUT, headers: {content_type: :json, accept: :json})
95
- }
96
- @tests[test_status.name] = JSON.parse(result)
97
- end
98
-
99
- # @return [String] string with messages of all failures in a test
100
- def test_failures(test_status)
101
- test_status.results.last.failures.join("\n\t")
102
- end
103
-
104
- # Tries to execute, without an error, block of code passed to the function.
105
- # @param block Block of code to be executed up to MAX_REST_TRIES
106
- def try(&block)
107
-
108
- tries = REST_MAX_TRIES
109
-
110
- begin
111
- yield
112
- rescue
113
- tries -= 1
114
- tries > 0 ? retry : raise
115
- end
116
- end
117
-
118
- # @return [Hash] Hash with config for WebUI
119
- def config
120
- Moto::Lib::Config.moto[:test_reporter][:listeners][:webui]
121
- end
122
- private :config
123
-
124
- end
125
- end
126
- end
127
- end
@@ -1,37 +0,0 @@
1
- require_relative '../reporting/test_reporter'
2
-
3
- module Moto
4
- module Runner
5
- class DryRunner
6
-
7
- # @param [Array] tests_metadata Collection of [Moto::Test::Metadata] objects describing Tests
8
- # @param [Moto::Reporting::TestReporter] test_reporter Reporter of test/run statuses that communicates with external status listeners
9
- def initialize(tests_metadata, test_reporter)
10
- @tests_metadata = tests_metadata
11
- @test_reporter = test_reporter
12
- end
13
-
14
- def run
15
- @test_reporter.report_start_run
16
-
17
- test_generator = TestGenerator.new
18
- @tests_metadata.each do |metadata|
19
- test_variants = test_generator.get_test_with_variants(metadata)
20
- test_variants.each do |tc|
21
- @test_reporter.report_start_test(tc.status, tc.metadata)
22
- tc.status.initialize_run
23
- tc.status.log_exception(Exceptions::TestSkipped.new('Dry run.'))
24
- tc.status.finalize_run
25
- @test_reporter.report_end_test(tc.status)
26
- end
27
- end
28
-
29
- @test_reporter.report_end_run
30
-
31
- # Exit application with code that represents status of test run
32
- Kernel.exit(@test_reporter.run_status.bitmap)
33
- end
34
-
35
- end
36
- end
37
- end
@@ -1,68 +0,0 @@
1
- require 'thread'
2
- require_relative 'test_generator'
3
-
4
- module Moto
5
- module Runner
6
- # Thread safe provider of test instances
7
- class TestProvider
8
-
9
- # @param [Array] tests_metadata
10
- def initialize(tests_metadata)
11
- super()
12
- @test_repeats = Moto::Lib::Config.moto[:test_runner][:test_repeats]
13
- @current_test_repeat = 1
14
- @queue = Queue.new
15
- @tests_metadata = tests_metadata
16
- @test_generator = TestGenerator.new
17
- end
18
-
19
- # Use this to retrieve tests safely in multithreaded environment
20
- def get_test
21
- create_tests
22
- @queue.pop
23
- end
24
-
25
- # Pushes new tests to the queue if possible and the queue is already empty
26
- def create_tests
27
- if @queue.empty?
28
-
29
- test_metadata = get_test_metadata
30
-
31
- if test_metadata
32
- test_variants = @test_generator.get_test_with_variants(test_metadata)
33
- test_variants.each do |test|
34
- @queue.push(test)
35
- end
36
- end
37
-
38
- end
39
- end
40
- private :create_tests
41
-
42
- # Returns metadata of the test while supporting the number of repeats specified by the user
43
- # return [Moto::Test::Metadata]
44
- def get_test_metadata
45
-
46
- if @current_test_repeat == 1
47
- @test_metadata = @tests_metadata.shift
48
- end
49
-
50
- if @current_test_repeat == @test_repeats
51
- @current_test_repeat = 1
52
- else
53
- @current_test_repeat += 1
54
- end
55
-
56
- @test_metadata
57
- end
58
- private :get_test_metadata
59
-
60
- # Number of threads waiting for a job
61
- def num_waiting
62
- @queue.num_waiting
63
- end
64
-
65
- end
66
- end
67
- end
68
-
@@ -1,71 +0,0 @@
1
- require_relative '../reporting/test_reporter'
2
- require_relative './test_provider'
3
-
4
- module Moto
5
- module Runner
6
- class TestRunner
7
-
8
- attr_reader :test_reporter
9
-
10
- # @param [Array] tests_metadata Collection of [Moto::Test::Metadata] objects describing Tests
11
- # @param [Moto::Reporting::TestReporter] test_reporter Reporter of test/run statuses that communicates with external status listeners
12
- # @param [Hash] stop_conditions Describe when TestRunner should abnormally stop its execution
13
- # :error [Boolean]
14
- # :fail [Boolean]
15
- # :skip [Boolean]
16
- def initialize(tests_metadata, test_reporter, stop_conditions)
17
- @tests_metadata = tests_metadata
18
- @test_reporter = test_reporter
19
- @stop_conditions = stop_conditions
20
- end
21
-
22
- def run
23
- test_provider = TestProvider.new(@tests_metadata)
24
- threads_max = Moto::Lib::Config.moto[:test_runner][:thread_count] || 1
25
-
26
- # remove log/screenshot files from previous execution
27
- @tests_metadata.each do |metadata|
28
- FileUtils.rm_rf("#{File.dirname(metadata.test_path)}/logs")
29
- end
30
-
31
- @test_reporter.report_start_run
32
-
33
- # Create as many threads as we're allowed by the config file.
34
- # test_provider.get_test - will invoke Queue.pop thus putting the thread to sleep
35
- # once there is no more work.
36
-
37
- Thread.abort_on_exception = true
38
-
39
- (1..threads_max).each do |index|
40
- Thread.new do
41
- Thread.current[:id] = index
42
- loop do
43
- tc = ThreadContext.new(test_provider.get_test, @test_reporter)
44
- tc.run
45
- end
46
- end
47
- end
48
-
49
- # Waiting for all threads to run out of work so we can end the application
50
- # or abonormal termination to be triggered based on options provided by the user
51
- loop do
52
- run_status = @test_reporter.run_status
53
- if (test_provider.num_waiting == threads_max) ||
54
- (@stop_conditions[:error] && run_status.tests_error.length > 0) ||
55
- (@stop_conditions[:fail] && run_status.tests_failed.length > 0) ||
56
- (@stop_conditions[:skip] && run_status.tests_skipped.length > 0)
57
- break
58
- end
59
-
60
- sleep 2
61
- end
62
-
63
- @test_reporter.report_end_run
64
-
65
- # Exit application with code that represents status of test run
66
- Kernel.exit(@test_reporter.run_status.bitmap)
67
- end
68
-
69
- end
70
- end
71
- end