moto 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e048efe2a7dae21ba01da0503fdeb40e56755827
4
+ data.tar.gz: 00882f74920d1fab0729c015e8260ecba2b115ff
5
+ SHA512:
6
+ metadata.gz: 8b89e9d40644d2a751c9e4fd7455d40395f3c2a7d682cec532e6ac8dd9cf02497338e26952ae8156eee510d9289a21dc61f286fcb8c071e29400d9f2fb88931f
7
+ data.tar.gz: e8710637b4dbbb2ccd4e2d9412f932033e79fc7baee4713b82926a4e6ac5c83732b1b76f9a02521bb714cc1835ea436171f3d7677a4e339bddcdb18b6ddca3ed
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'moto'
4
+ MotoCliRunner.run ARGV
@@ -0,0 +1,17 @@
1
+ module Moto
2
+ module EmptyListener
3
+
4
+ def start_run
5
+ end
6
+
7
+ def end_run
8
+ end
9
+
10
+ def start_test(test)
11
+ end
12
+
13
+ def end_test(test)
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,26 @@
1
+ module Moto
2
+ module Listeners
3
+ class Base
4
+
5
+ def initialize(runner)
6
+ @runner=runner
7
+ end
8
+
9
+ def start_run
10
+ # abstract
11
+ end
12
+
13
+ def end_run
14
+ # abstract
15
+ end
16
+
17
+ def start_test(test)
18
+ # abstract
19
+ end
20
+
21
+ def end_test(test)
22
+ # abstract
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+ module Moto
2
+ module Listeners
3
+ class Console < Base
4
+
5
+ def start_run
6
+ @runner.logger.info("Starting...")
7
+ end
8
+
9
+ def end_run
10
+ @runner.logger.info("...done: #{@runner.result.summary[:result]}, duration: #{@runner.result.summary[:duration]}")
11
+ end
12
+
13
+ def start_test(test)
14
+ @runner.logger.info("Starting test #{test.name}")
15
+ end
16
+
17
+ def end_test(test)
18
+ @runner.logger.info("Ending test #{test.name} with result #{@runner.result[test.name][:result]}")
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,42 @@
1
+ require 'logger'
2
+ require 'yaml'
3
+ require 'active_support/inflector'
4
+ require 'active_support/core_ext/object/blank'
5
+
6
+ require_relative '../lib/empty_listener'
7
+ require_relative '../lib/runner'
8
+ require_relative '../lib/thread_context'
9
+ require_relative '../lib/result'
10
+ require_relative '../lib/test'
11
+ require_relative '../lib/listeners/base'
12
+ require_relative '../lib/listeners/console'
13
+
14
+ APP_DIR = Dir.pwd
15
+
16
+ class MotoCliRunner
17
+
18
+ def self.run(argv)
19
+ t = argv[0]
20
+ t = 'MotoApp::Tests::'+t
21
+ a = t.underscore.split('/')
22
+ test_path = (a[1..20]+[a[-1]]).join('/')
23
+
24
+ # TODO: check if this path and constat exists
25
+ require "#{APP_DIR}/#{test_path}"
26
+ test_const = t.safe_constantize
27
+
28
+ tests = [
29
+ test_const.new
30
+ ]
31
+
32
+ # parsing ARGV and creating config will come here
33
+ # instantiation of tests for ARGV params also happens here
34
+ # instantiate listeners/reporters
35
+
36
+ # listeners = []
37
+ listeners = [Moto::Listeners::Console]
38
+ runner = Moto::Runner.new(tests, listeners, thread_cnt: 3, environments: [:qa2, :qa])
39
+ runner.run
40
+ end
41
+
42
+ end
@@ -0,0 +1,59 @@
1
+ module Moto
2
+ class Result
3
+
4
+ PENDING = :pending # -2
5
+ RUNNING = :running # -1
6
+ PASSED = :passed # 0
7
+ FAILURE = :failure # 1
8
+ ERROR = :error # 2
9
+
10
+ attr_reader :summary
11
+
12
+ def [](key)
13
+ @results[key]
14
+ end
15
+
16
+ def initialize(runner)
17
+ @runner = runner
18
+ @results = {}
19
+ @summary = {}
20
+ end
21
+
22
+ def start_run
23
+ # start timer
24
+ @summary[:started_at] = Time.now.to_f
25
+ end
26
+
27
+ def end_run
28
+ # info about duration and overall execution result
29
+ @summary[:finished_at] = Time.now.to_f
30
+ @summary[:duration] = @summary[:finished_at] - @summary[:started_at]
31
+ @summary[:result] = PASSED
32
+ @summary[:result] = FAILURE unless @results.values.select{ |v| v[:failures].count > 0 }.empty?
33
+ @summary[:result] = ERROR unless @results.values.select{ |v| !v[:error].nil? }.empty?
34
+ # TODO: calculate count and percentage of errors/failures
35
+ end
36
+
37
+ def start_test(test)
38
+ @results[test.name] = { class: test.class, result: RUNNING, env: nil, params: nil, name: test.name, error: nil, failures: [] }
39
+ end
40
+
41
+ def end_test(test)
42
+ # calculate result basing on errors/failures
43
+ test.result = PASSED
44
+ test.result = FAILURE unless @results[test.name][:failures].empty?
45
+ test.result = ERROR unless @results[test.name][:error].nil?
46
+ @results[test.name][:result] = test.result
47
+ test.logger.info("Result: #{test.result}")
48
+ end
49
+
50
+ def add_failure(test, msg)
51
+ @results[test.name][:failures] << msg
52
+ end
53
+
54
+ def add_error(test, e)
55
+
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,52 @@
1
+ module Moto
2
+ class Runner
3
+
4
+ attr_reader :result
5
+ attr_reader :listeners
6
+ attr_reader :logger
7
+ attr_reader :environments
8
+
9
+ def initialize(tests, listeners, config = {})
10
+ @tests = tests
11
+ @config = config
12
+ @threads = []
13
+
14
+ # TODO: initialize logger from config (yml or just ruby code)
15
+ @logger = Logger.new(STDOUT)
16
+ # @logger.level = Logger::WARN
17
+
18
+ @result = Moto::Result.new(self)
19
+
20
+ # TODO: validate envs, maybe no-env should be supported as well?
21
+ @environments = config[:environments]
22
+
23
+ @listeners = []
24
+ listeners.each do |l|
25
+ @listeners << l.new(self)
26
+ end
27
+ @listeners.unshift(@result)
28
+ end
29
+
30
+ def run
31
+ @listeners.each { |l| l.start_run }
32
+ test_slices = @tests.each_slice((@tests.size.to_f/@config[:thread_cnt]).ceil).to_a
33
+ (0...test_slices.count).each do |i|
34
+ @threads << Thread.new do
35
+ tc = ThreadContext.new(self, test_slices[i])
36
+ tc.run
37
+ end
38
+ end
39
+ @threads.each{ |t| t.join }
40
+ @listeners.each { |l| l.end_run }
41
+ # aggregate result from @tests list
42
+ end
43
+
44
+ def assert(test, condition, message)
45
+ unless condition
46
+ @result.add_failure(test, message)
47
+ test.logger.error("ASSERTION FAILED: #{message}")
48
+ end
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,71 @@
1
+ module Moto
2
+ class Test
3
+
4
+ attr_writer :context
5
+ attr_accessor :result
6
+ attr_reader :name
7
+
8
+ class << self
9
+ attr_accessor :_path
10
+ end
11
+
12
+ def self.inherited(k)
13
+ k._path = caller.first.match( /(.+):\d+:in/ )[1]
14
+ end
15
+
16
+ def path
17
+ self.class._path
18
+ end
19
+
20
+ def initialize
21
+ # @context = context
22
+ @result = Moto::Result::PENDING
23
+ end
24
+
25
+ def init(env, params)
26
+ @env = env
27
+ @params = params
28
+ set_name
29
+ end
30
+
31
+ def logger
32
+ @context.logger
33
+ end
34
+
35
+ def set_name
36
+ return @name = "#{self.class.to_s}/#{@env}" if @params.empty?
37
+ return @name = "#{self.class.to_s}/#{@env}/#{@params[:__name]}" if @params.key?(:__name)
38
+ @name = self.class.to_s
39
+ end
40
+
41
+ def dir
42
+ # puts self.class.path
43
+ File.dirname(self.path)
44
+ end
45
+
46
+ def filename
47
+ File.basename(path, ".*")
48
+ end
49
+
50
+ def run
51
+ # abstract
52
+ end
53
+
54
+ def before
55
+ # abstract
56
+ end
57
+
58
+ def after
59
+ # abstract
60
+ end
61
+
62
+ def assert(*args)
63
+ @context.runner.assert(self,*args)
64
+ end
65
+
66
+ def client(name)
67
+ @context.client(name)
68
+ end
69
+
70
+ end
71
+ end
@@ -0,0 +1,54 @@
1
+ module Moto
2
+ class ThreadContext
3
+
4
+ # all resources specific for single thread will be initialized here. E.g. browser session
5
+ attr_reader :runner
6
+ attr_reader :logger
7
+
8
+ def initialize(runner, tests)
9
+ @runner = runner
10
+ @tests = tests
11
+ @tests.each do |t|
12
+ t.context = self
13
+ end
14
+ end
15
+
16
+ def client(name)
17
+ # TODO: implement registry caching per name+env
18
+ name = 'MotoApp::Clients::' + name
19
+ a = name.underscore.split('/')
20
+ test_path = (a[1..20]+[a[-1]]).join('/')
21
+ require "#{APP_DIR}/#{test_path}"
22
+ client_const = name.safe_constantize
23
+ client_const.new
24
+ end
25
+
26
+ def run
27
+ @tests.each do |test|
28
+ # TODO: handle running same test in different environments / parameters - set name and logger
29
+ @runner.environments.each do |env|
30
+ params_path = "#{test.dir}/#{test.filename}.yml"
31
+ params_all = [{}]
32
+ params_all = YAML.load_file(params_path).map{|h| Hash[ h.map{|k,v| [ k.to_sym, v ] } ] } if File.exists?(params_path)
33
+ params_all.each do |params|
34
+ test.init(env, params)
35
+ # TODO: log path might be specified (to some extent) by the configuration
36
+ log_path = "#{test.dir}/#{test.name.gsub(/\s+/, '_').gsub('::', '_').gsub('/', '_')}.log"
37
+ @logger = Logger.new(File.open(log_path, File::WRONLY | File::TRUNC | File::CREAT))
38
+ # TODO: make logger level configurable
39
+ # @logger.level = Logger::INFO
40
+ @current_test = test
41
+ @runner.listeners.each { |l| l.start_test(test) }
42
+ test.before
43
+ # TODO: handle exception thrown during test run
44
+ test.run
45
+ test.after
46
+ @runner.listeners.each { |l| l.end_test(test) }
47
+ @logger.close
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ end
54
+ end
metadata ADDED
@@ -0,0 +1,54 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: moto
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Bartek Wilczek
8
+ - Maciej Przybylski
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-08-07 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: With a fancy description
15
+ email: bw@vouk.info
16
+ executables:
17
+ - moto
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - lib/empty_listener.rb
22
+ - lib/moto.rb
23
+ - lib/result.rb
24
+ - lib/runner.rb
25
+ - lib/test.rb
26
+ - lib/thread_context.rb
27
+ - lib/listeners/base.rb
28
+ - lib/listeners/console.rb
29
+ - bin/moto
30
+ homepage: http://vouk.info
31
+ licenses:
32
+ - MIT
33
+ metadata: {}
34
+ post_install_message:
35
+ rdoc_options: []
36
+ require_paths:
37
+ - lib
38
+ required_ruby_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ requirements: []
49
+ rubyforge_project:
50
+ rubygems_version: 2.0.14
51
+ signing_key:
52
+ specification_version: 4
53
+ summary: Moto - yet another testing framework
54
+ test_files: []