oats 0.0.1
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.
- data/.gitignore +6 -0
- data/Gemfile +15 -0
- data/README.txt +165 -0
- data/Rakefile +2 -0
- data/bin/agent +204 -0
- data/bin/oats +10 -0
- data/bin/occ +29 -0
- data/bin/results_cleanup +6 -0
- data/doc/COPYING +55 -0
- data/doc/LICENSE +55 -0
- data/doc/OATS_Framework.doc +0 -0
- data/doc/classes/ApplicationLogs.html +239 -0
- data/doc/classes/Campaign.html +843 -0
- data/doc/classes/CommandlineOptions.html +131 -0
- data/doc/classes/Driver.html +182 -0
- data/doc/classes/Hash.html +137 -0
- data/doc/classes/Ide.html +194 -0
- data/doc/classes/MapSelenium.html +197 -0
- data/doc/classes/Net.html +107 -0
- data/doc/classes/Oats/OatsFilterError.html +119 -0
- data/doc/classes/Oats.html +998 -0
- data/doc/classes/OatsAssertError.html +119 -0
- data/doc/classes/OatsBadInput.html +119 -0
- data/doc/classes/OatsData.html +290 -0
- data/doc/classes/OatsError.html +117 -0
- data/doc/classes/OatsExit.html +117 -0
- data/doc/classes/OatsLock.html +254 -0
- data/doc/classes/OatsMain.html +182 -0
- data/doc/classes/OatsMysqlError.html +113 -0
- data/doc/classes/OatsMysqlMissingInput.html +113 -0
- data/doc/classes/OatsReportError.html +113 -0
- data/doc/classes/OatsSetupError.html +119 -0
- data/doc/classes/OatsTestError.html +119 -0
- data/doc/classes/OatsTestExit.html +119 -0
- data/doc/classes/OatsTestLocateError.html +120 -0
- data/doc/classes/OatsVerifyError.html +119 -0
- data/doc/classes/Ragent.html +397 -0
- data/doc/classes/Rclient.html +236 -0
- data/doc/classes/Report.html +368 -0
- data/doc/classes/Reports.html +244 -0
- data/doc/classes/RestApi.html +333 -0
- data/doc/classes/RhttpClient.html +236 -0
- data/doc/classes/Rimap.html +170 -0
- data/doc/classes/Rmysql.html +176 -0
- data/doc/classes/Roptions.html +131 -0
- data/doc/classes/Rselenium.html +233 -0
- data/doc/classes/Rssh.html +138 -0
- data/doc/classes/Runnable.html +174 -0
- data/doc/classes/SFTriggers.html +206 -0
- data/doc/classes/Selenium/Client/Driver.html +211 -0
- data/doc/classes/Selenium/Client.html +107 -0
- data/doc/classes/Selenium.html +107 -0
- data/doc/classes/SystemCapture.html +304 -0
- data/doc/classes/TestCase.html +418 -0
- data/doc/classes/TestData.html +235 -0
- data/doc/classes/TestList.html +264 -0
- data/doc/classes/Tools.html +244 -0
- data/doc/classes/Util.html +201 -0
- data/doc/classes/Variation.html +206 -0
- data/doc/fr_class_index.html +92 -0
- data/doc/fr_method_index.html +465 -0
- data/doc/index.html +23 -0
- data/doc/oats_httpd.conf +32 -0
- data/doc/oats_user.yml +25 -0
- data/doc/rdoc-style.css +208 -0
- data/lib/deep_merge/.gitignore +2 -0
- data/lib/deep_merge/core.rb +195 -0
- data/lib/deep_merge/deep_merge.rb +1 -0
- data/lib/deep_merge/deep_merge_hash.rb +28 -0
- data/lib/deep_merge/rails_compat.rb +27 -0
- data/lib/oats/application_logs.rb +163 -0
- data/lib/oats/build_id.rb +58 -0
- data/lib/oats/commandline_options.rb +128 -0
- data/lib/oats/diff.rb +278 -0
- data/lib/oats/driver.rb +492 -0
- data/lib/oats/ide.rb +227 -0
- data/lib/oats/keywords.rb +67 -0
- data/lib/oats/log4r_init.rb +14 -0
- data/lib/oats/mysql.rb +97 -0
- data/lib/oats/oats.rb +637 -0
- data/lib/oats/oats_data.rb +400 -0
- data/lib/oats/oats_exceptions.rb +25 -0
- data/lib/oats/oats_lock.rb +261 -0
- data/lib/oats/oats_selenium_api.rb +639 -0
- data/lib/oats/oselenium.rb +189 -0
- data/lib/oats/ossh.rb +36 -0
- data/lib/oats/patches_for_eventmachine_12.10.rb +66 -0
- data/lib/oats/ragent.rb +321 -0
- data/lib/oats/rclient.rb +42 -0
- data/lib/oats/report.rb +207 -0
- data/lib/oats/roptions.rb +88 -0
- data/lib/oats/test_case.rb +510 -0
- data/lib/oats/test_data.rb +98 -0
- data/lib/oats/test_list.rb +141 -0
- data/lib/oats/unixdiff.rb +75 -0
- data/lib/oats/util.rb +125 -0
- data/lib/oats/version.rb +3 -0
- data/lib/oats.rb +36 -0
- data/nbproject/configs/agent.properties +0 -0
- data/nbproject/configs/gr.properties +0 -0
- data/nbproject/project.properties +10 -0
- data/nbproject/project.xml +17 -0
- data/oats.gemspec +42 -0
- data/oats_ini.yml +258 -0
- data/oats_tests/Gemfile +18 -0
- data/oats_tests/aut_ini.yml +30 -0
- data/oats_tests/bin/oats +8 -0
- data/oats_tests/environments/qa.yml +4 -0
- data/oats_tests/environments/qa_chrome.yml +4 -0
- data/oats_tests/examples/core/coreExamples.yml +8 -0
- data/oats_tests/examples/core/expectedException.rb +39 -0
- data/oats_tests/examples/core/ok_verify.rb +2 -0
- data/oats_tests/examples/core/ok_verify.rb_ok/out/myfile.txt +1 -0
- data/oats_tests/examples/core/ok_verify.rb_ok/out/myfile2.txt +1 -0
- data/oats_tests/examples/core/ok_verify.rb_ok/rats_test.log +2 -0
- data/oats_tests/examples/core/unexpectedException.rb +30 -0
- data/oats_tests/examples/examples.yml +13 -0
- data/oats_tests/examples/gui/guiExamples.yml +7 -0
- data/oats_tests/examples/gui/seleniumGoogle.rb +10 -0
- data/oats_tests/examples/gui/webdriverGoogle.rb +9 -0
- data/oats_tests/examples/keywords/SampleXlList-1.xls +0 -0
- data/oats_tests/examples/keywords/SampleXlList-2.xls +0 -0
- data/oats_tests/examples/keywords/SampleXlLists.xls +0 -0
- data/oats_tests/examples/keywords/keywordsDriver.rb +1 -0
- data/oats_tests/examples/keywords/keywordsExamples.yml +8 -0
- data/oats_tests/examples/keywords/keywordsTC1.yml +5 -0
- data/oats_tests/examples/keywords/keywordsTestlist.yml +16 -0
- data/oats_tests/examples/needsWork/addTestDynamically.rb +4 -0
- data/oats_tests/examples/needsWork/emailVerify.rb +34 -0
- data/oats_tests/examples/needsWork/testSql/rtest.sql +6 -0
- data/oats_tests/examples/needsWork/testSql/rtest.yml +11 -0
- data/oats_tests/examples/occTest/occTest.rb +13 -0
- data/oats_tests/examples/occTest/occTest_1.rb +1 -0
- data/oats_tests/examples/occTest/occTest_1_1.rb +1 -0
- data/oats_tests/examples/occTest/occTest_1_2.rb +1 -0
- data/oats_tests/examples/occTest/occTest_1_3.rb +1 -0
- data/oats_tests/examples/occTest/occTest_1_4.rb +1 -0
- data/oats_tests/examples/occTest/occTest_2.rb +1 -0
- data/oats_tests/examples/occTest/occTest_2_1.rb +1 -0
- data/oats_tests/examples/occTest/occTest_2_2.rb +1 -0
- data/oats_tests/examples/occTest/occTest_2_3.rb +1 -0
- data/oats_tests/examples/occTest/occTest_2_4.rb +1 -0
- data/oats_tests/examples/occTest/occTest_3.rb +1 -0
- data/oats_tests/examples/occTest/occTest_3_1.rb +1 -0
- data/oats_tests/examples/occTest/occTest_3_2.rb +1 -0
- data/oats_tests/examples/occTest/occTest_3_3.rb +1 -0
- data/oats_tests/examples/occTest/occTest_3_4.rb +1 -0
- data/oats_tests/examples/occTest/occTest_4.rb +1 -0
- data/oats_tests/examples/occTest/occTestlist.yml +9 -0
- data/oats_tests/examples/occTest/occTestlist_1.yml +9 -0
- data/oats_tests/examples/occTest/occTestlist_2.yml +9 -0
- data/oats_tests/examples/occTest/occTestlist_3.yml +9 -0
- data/oats_tests/examples/occTest/variation1.yml +4 -0
- data/oats_tests/examples/occTest/variation2.yml +4 -0
- data/oats_tests/examples/testFileLocationUnitTests/extn_driver.rb +4 -0
- data/oats_tests/examples/testFileLocationUnitTests/folder/oats.yml +3 -0
- data/oats_tests/examples/testFileLocationUnitTests/folder/t1.rb +2 -0
- data/oats_tests/examples/testFileLocationUnitTests/folder1/t1.yml +2 -0
- data/oats_tests/examples/testFileLocationUnitTests/folder1/t1_1.yml +3 -0
- data/oats_tests/examples/testFileLocationUnitTests/folder2/oats.yml +3 -0
- data/oats_tests/examples/testFileLocationUnitTests/folder2/t1.rb +2 -0
- data/oats_tests/examples/testFileLocationUnitTests/folder2/t1.yml +2 -0
- data/oats_tests/examples/testFileLocationUnitTests/no_yaml.rb +3 -0
- data/oats_tests/examples/testFileLocationUnitTests/post_yaml.rb +1 -0
- data/oats_tests/examples/testFileLocationUnitTests/t1.rb +4 -0
- data/oats_tests/examples/testFileLocationUnitTests/t1.yml +2 -0
- data/oats_tests/examples/testFileLocationUnitTests/t1_1.yml +3 -0
- data/oats_tests/examples/testFileLocationUnitTests/testDir/oats.yml +3 -0
- data/oats_tests/examples/testFileLocationUnitTests/testDir/t1.rb +2 -0
- data/oats_tests/examples/testFileLocationUnitTests/testDir/t1.yml +2 -0
- data/oats_tests/examples/testFileLocationUnitTests/testDir2/t1.rb +2 -0
- data/oats_tests/examples/testFileLocationUnitTests/testDir2/t1.yml +2 -0
- data/oats_tests/examples/testFileLocationUnitTests/unitTestList.yml +36 -0
- data/oats_tests/examples/testFileLocationUnitTests/yml_driver.rb +2 -0
- data/oats_tests/lib/business.rb +28 -0
- data/oats_tests/lib/sample_xl_lists.rb +37 -0
- data/test/common_test_unit_setup.rb +21 -0
- data/test/test_basic.rb +16 -0
- data/test/test_selenium.rb +16 -0
- data/test/test_xl_lists.rb +16 -0
- metadata +291 -0
data/lib/oats/driver.rb
ADDED
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
require 'oats/report'
|
|
2
|
+
require 'oats/test_data'
|
|
3
|
+
require 'oats/application_logs'
|
|
4
|
+
require 'oats/oats_data'
|
|
5
|
+
require 'oats/roptions'
|
|
6
|
+
require 'oats/build_id'
|
|
7
|
+
|
|
8
|
+
autoload :Spreadsheet, 'spreadsheet'
|
|
9
|
+
|
|
10
|
+
module Oats
|
|
11
|
+
|
|
12
|
+
module Driver
|
|
13
|
+
|
|
14
|
+
def Driver.agent
|
|
15
|
+
ENV['KILL_AGENT' ] = 'KILL_AGENT' if $oats_execution['options']["_:kill_agent"]
|
|
16
|
+
ENV['OATS_USER' ] = $oats_execution['options']["_:oats_user"] if $oats_execution['options']["_:oats_user"]
|
|
17
|
+
ENV['OATS_REPOSITORY_VERSION' ] = $oats_execution['options']["_:repository_version"] if $oats_execution['options']["_:repository_version"]
|
|
18
|
+
nick = $oats_execution['options']["execution:occ:agent_nickname"]
|
|
19
|
+
ENV['OATS_AGENT_NICKNAME' ] = nick if nick
|
|
20
|
+
port = $oats_execution['options']["execution:occ:agent_port"].to_s
|
|
21
|
+
ENV['OATS_AGENT_PORT'] = port if port
|
|
22
|
+
dir = ENV['HOME'] + "/results_archive/#{nick}/agent_logs"
|
|
23
|
+
FileUtils.mkdir_p(dir) unless File.exists?(dir)
|
|
24
|
+
ENV['CONFIG_FILE'] = "#{dir}/config-agent.txt"
|
|
25
|
+
dat = `date +'%m%d%H%M%S'`.chomp
|
|
26
|
+
log_file = "#{dir}/agent_#{dat}.log"
|
|
27
|
+
ENV['LOGFILE'] = log_file
|
|
28
|
+
agent_log_file = "#{dir}/agent.log"
|
|
29
|
+
cmd = ENV['OATS_HOME'] + '/bin/agent'
|
|
30
|
+
pid = `#{cmd}`.chomp
|
|
31
|
+
puts "Running PID: " + pid + ', Log: ' + log_file
|
|
32
|
+
# echo "$NICKNAME $PORT $PID $DISPLAY_NUM" >| $config_agent_file
|
|
33
|
+
10.times do
|
|
34
|
+
if File.exist? log_file
|
|
35
|
+
FileUtils.rm_f agent_log_file
|
|
36
|
+
FileUtils.ln log_file, agent_log_file
|
|
37
|
+
break
|
|
38
|
+
end
|
|
39
|
+
sleep 1
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Main method that starts oats execution in either agent or standalone mode.
|
|
44
|
+
# Parameters are command-line arguments
|
|
45
|
+
# Returns oats_info object containing execution results
|
|
46
|
+
def Driver.run(args)
|
|
47
|
+
unless ENV['HOSTNAME']
|
|
48
|
+
if ENV['OS'] == 'Windows_NT'
|
|
49
|
+
ENV['HOSTNAME'] = ENV['COMPUTERNAME']
|
|
50
|
+
else
|
|
51
|
+
ENV['HOSTNAME'] = `hostname`.chomp
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
ENV['OS'] ||= `uname`.chomp
|
|
55
|
+
|
|
56
|
+
Log4r::Logger.root.level = Log4r::DEBUG
|
|
57
|
+
Log4r::StdoutOutputter.new('console', :level=>1,
|
|
58
|
+
:formatter=>Log4r::PatternFormatter.new(:depth=>50,
|
|
59
|
+
:pattern => "%-5l %d %M", :date_pattern=>"%y-%m-%d %H:%M:%S"))
|
|
60
|
+
$log = Log4r::Logger.new('R')
|
|
61
|
+
$log.add('console')
|
|
62
|
+
options = CommandlineOptions.options(args)
|
|
63
|
+
$oats_info = {}
|
|
64
|
+
$oats_global = {}
|
|
65
|
+
@@quiet = options['_:quiet'] # save quiet option from initial commandline options
|
|
66
|
+
$log.remove('console') if @@quiet
|
|
67
|
+
ENV['HOME'] = Util.expand_path(ENV['HOME']) if ENV['HOME'] # Normalize for cygwin
|
|
68
|
+
if $oats_execution['agent']
|
|
69
|
+
require 'oats/ragent'
|
|
70
|
+
# $oats_execution['agent'] (used by framework) == Oats.global['agent'] (by YAMLs) === options
|
|
71
|
+
$oats = OatsData.load(options['_:ini_file'])
|
|
72
|
+
$oats['_']['options'] = options
|
|
73
|
+
Roptions.override(options)
|
|
74
|
+
# $oats would be reset and and regenerated by agents across jobs.
|
|
75
|
+
|
|
76
|
+
options['execution:occ:agent_host'] = $oats['execution']['occ']['agent_host']
|
|
77
|
+
options['execution:occ:agent_port'] = $oats['execution']['occ']['agent_port']
|
|
78
|
+
options['execution:occ:agent_nickname'] = ($oats['execution']['occ']['agent_nickname'] || options['execution:occ:agent_host'].sub(/\..*/,''))
|
|
79
|
+
$oats['execution']['occ']['agent_nickname'] = options['execution:occ:agent_nickname']
|
|
80
|
+
|
|
81
|
+
if options['_:command']
|
|
82
|
+
require 'oats/rclient'
|
|
83
|
+
options['_:id'] = Time.now.to_i.to_s
|
|
84
|
+
request = { :command => options['_:command'], :args => options['_:args'] }
|
|
85
|
+
request[:id] = options['_:id'] if options['_:id']
|
|
86
|
+
EventMachine::run { EventMachine::connect options['execution:occ:agent_host'],
|
|
87
|
+
options['execution:occ:agent_port'].to_i, Rclient, options['execution:occ:agent_host'], request
|
|
88
|
+
}
|
|
89
|
+
else
|
|
90
|
+
Ragent.start $oats['execution']['occ']
|
|
91
|
+
end
|
|
92
|
+
else
|
|
93
|
+
Driver.start(nil,options)
|
|
94
|
+
end
|
|
95
|
+
$oats_info
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Executes OATS
|
|
99
|
+
# Returns oats_info object containing execution results
|
|
100
|
+
def Driver.start(jid,options)
|
|
101
|
+
begin
|
|
102
|
+
$oats_info = {} # Holds Oats.context, to be transmitted to OCC
|
|
103
|
+
$oats_global = {} # Holds Oats.global for inter-test data, within an execution sequence
|
|
104
|
+
Oats.context['start_time'] = Time.new.to_i
|
|
105
|
+
if jid
|
|
106
|
+
Oats.global['agent'] = $oats_execution['agent']
|
|
107
|
+
Oats.context['jobid'] = jid
|
|
108
|
+
else
|
|
109
|
+
Oats.context['jobid'] = Oats.context['start_time'].to_s[2..-1]
|
|
110
|
+
end
|
|
111
|
+
! options['execution:tail_logs_ip'] and ! OatsLock.set and return false
|
|
112
|
+
$log.remove('console') if options['_:quiet']
|
|
113
|
+
$oats_execution['testlist_init'] and $oats_execution['testlist_init'].each_pair do |klas, args|
|
|
114
|
+
klas.init
|
|
115
|
+
end
|
|
116
|
+
TestList.current = nil # Initialize
|
|
117
|
+
$oats = nil # Holds Oats.data, the resolved oats.yml contents
|
|
118
|
+
oats_data = OatsData.load(options['_:ini_file'])
|
|
119
|
+
$oats = oats_data
|
|
120
|
+
$oats['_']['options'] = options
|
|
121
|
+
Roptions.override(options)
|
|
122
|
+
Oats.result_archive_dir # Adjust results_ dir variables if running on agent mode
|
|
123
|
+
oats_data = $oats
|
|
124
|
+
Oselenium.reset if defined?(Oats::Oselenium) # Initialize class variables and kill running browsers, in case running in server host mode
|
|
125
|
+
# oats_data['execution']['test_files'] = test_files if test_files and ! test_files.empty?
|
|
126
|
+
dir_res = oats_data['execution']['dir_results']
|
|
127
|
+
stop_file = dir_res + '/stop_oats'
|
|
128
|
+
oats_data['execution']['stop_file'] = stop_file
|
|
129
|
+
if stop_file and File.exist?(stop_file)
|
|
130
|
+
$oats_info['stop_oats'] = Time.new.to_i
|
|
131
|
+
FileUtils.mv(stop_file, dir_res + '/stop_file_' + Oats.context['jobid'] )
|
|
132
|
+
end
|
|
133
|
+
Report.archive_results if not oats_data['execution']['tail_logs_ip']
|
|
134
|
+
FileUtils.mkdir_p(dir_res)
|
|
135
|
+
oats_data['execution']['log'] = oats_data['execution']['dir_results'] + '/oats.log'
|
|
136
|
+
oats_log = oats_data['execution']['log']
|
|
137
|
+
unless oats_data['execution']['tail_logs_ip']
|
|
138
|
+
if oats_log
|
|
139
|
+
dir_oats_log = File.dirname(oats_log)
|
|
140
|
+
raise(OatsBadInput,"Can not locate directory of execution:log #{dir_oats_log}") unless File.directory?(dir_oats_log)
|
|
141
|
+
oats_log = Util.expand_path(oats_log)
|
|
142
|
+
# Ensure log_level valid
|
|
143
|
+
level = Log4r::Log4rConfig::LogLevels.index($oats['execution']['log_level'])
|
|
144
|
+
raise(OatsBadInput, "Unrecognized execution:log_level [#{$oats['execution']['log_level']}]") unless level
|
|
145
|
+
Log4r::FileOutputter.new('logfile',
|
|
146
|
+
:filename=>oats_log, :trunc=>false, :level=>level,
|
|
147
|
+
:formatter=>Log4r::PatternFormatter.new(:depth=>50,
|
|
148
|
+
:pattern => "%-5l %d %M", :date_pattern=>"%y-%m-%d %H:%M:%S"))
|
|
149
|
+
$log.info "Redirecting output to logfile: " + oats_log
|
|
150
|
+
$log.add('logfile')
|
|
151
|
+
end
|
|
152
|
+
$log.info "Started OATS execution [#{Oats.context['jobid']}] at #{Time.now}"
|
|
153
|
+
end
|
|
154
|
+
begin
|
|
155
|
+
Oats.info "Tests Root Directory: " + ENV['OATS_TESTS']
|
|
156
|
+
oats_data['_']['environments'] = [] # Keep track of variations stack
|
|
157
|
+
Driver.process_test_yaml(oats_data)
|
|
158
|
+
Report.results($oats_info['test_files'])
|
|
159
|
+
$oats_info['end_time'] = Time.now.to_i
|
|
160
|
+
Report.oats_info_store
|
|
161
|
+
$log.warn "*** Stopping per stop_oats request [#{$oats_info['stop_oats']}]" if $oats_info['stop_oats']
|
|
162
|
+
$log.info "Finished OATS execution [#{Oats.context['jobid']}] at #{Time.at($oats_info['end_time'])} [#{$oats_info['end_time']}]" +
|
|
163
|
+
(oats_log ? ": " + oats_log : '')
|
|
164
|
+
Report.archive_results(true)
|
|
165
|
+
ensure
|
|
166
|
+
Oselenium.reset if defined?(Oats::Oselenium)
|
|
167
|
+
unless oats_data['execution']['tail_logs_ip'] or oats_log.nil?
|
|
168
|
+
Log4r::Outputter['logfile'].close
|
|
169
|
+
$log.remove('logfile')
|
|
170
|
+
end
|
|
171
|
+
OatsLock.reset
|
|
172
|
+
$log.add('console') if options['_:quiet'] and ! @@quiet
|
|
173
|
+
end
|
|
174
|
+
rescue Exception => e
|
|
175
|
+
$log.debug "Top level Exception caught by test driver."
|
|
176
|
+
$log.error $!
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Expand additional test_files given as test_yaml.yml plus variations
|
|
181
|
+
def Driver.process_test_yaml(oats_data, id = nil, test_yaml = nil)
|
|
182
|
+
return if $oats_info['stop_oats']
|
|
183
|
+
$oats = oats_data # TestData.locate needs test_dirs location.
|
|
184
|
+
if test_yaml
|
|
185
|
+
oats_data['execution']['test_files'] = nil # Ensure test files exist and taken from the input oats_file
|
|
186
|
+
case test_yaml
|
|
187
|
+
when /\.yml$/
|
|
188
|
+
yaml_file = TestData.locate(test_yaml)
|
|
189
|
+
unless yaml_file
|
|
190
|
+
Oats.error "Can not locate file: #{test_yaml}"
|
|
191
|
+
return
|
|
192
|
+
end
|
|
193
|
+
oats_data = OatsData.load( yaml_file, oats_data)
|
|
194
|
+
# oats_data['_']['load_history'].last.omit = true
|
|
195
|
+
when /\.xls$/
|
|
196
|
+
suite = id
|
|
197
|
+
book = Spreadsheet.open test_yaml
|
|
198
|
+
tests = $oats_global['xl']
|
|
199
|
+
unless tests and tests[id]
|
|
200
|
+
xl_id = File.dirname(id)
|
|
201
|
+
list_id = File.basename(id)
|
|
202
|
+
path = test_yaml.sub(/#{list_id}\.xls$/, File.basename(xl_id)+'.xls')
|
|
203
|
+
Driver.parse_xl(path, xl_id)
|
|
204
|
+
tests = $oats_global['xl']
|
|
205
|
+
end
|
|
206
|
+
header = nil
|
|
207
|
+
book.worksheet('Business Flow').each do |row|
|
|
208
|
+
unless header
|
|
209
|
+
header = row.dup
|
|
210
|
+
next
|
|
211
|
+
end
|
|
212
|
+
test_name = row.shift
|
|
213
|
+
next unless tests[id].include?(test_name)
|
|
214
|
+
test_id = suite + '/' + test_name
|
|
215
|
+
tests[test_id] = { 'keywords' => row.collect{|i|i}} # Need to convert to Array
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
header = nil
|
|
219
|
+
book.worksheet('Test Data').each do |row|
|
|
220
|
+
unless header
|
|
221
|
+
header = row.dup
|
|
222
|
+
header.shift
|
|
223
|
+
next
|
|
224
|
+
end
|
|
225
|
+
test_name = row.shift
|
|
226
|
+
next unless tests[id].include?(test_name)
|
|
227
|
+
test_id = suite + '/' + test_name
|
|
228
|
+
Oats.assert tests[test_id],
|
|
229
|
+
"No corresponding TC_ID was defined in Business Flow worksheet for Test Data worksheet TC_ID: " + File.basename(test_id)
|
|
230
|
+
tests[test_id]['data'] = {}
|
|
231
|
+
row.each_with_index do |cell,idx|
|
|
232
|
+
next unless header[idx] and cell
|
|
233
|
+
tests[test_id]['data'][header[idx]] = cell
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
list = tests[id].collect{|t| suite + '/' + t + '.xltest'}
|
|
237
|
+
$log.info "Processing worksheet [#{suite}] tests: #{tests[id].inspect}"
|
|
238
|
+
oats_data['execution']['test_files'] = list
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
pre = $oats['execution']['handler_pre_test_list']
|
|
242
|
+
if test_yaml and pre
|
|
243
|
+
pre_tst = TestCase.new(pre)
|
|
244
|
+
pre_tst.type = 4
|
|
245
|
+
pre_tst.run
|
|
246
|
+
TestList.current.pre_test = pre_tst
|
|
247
|
+
TestList.current.variations.last.tests.pop
|
|
248
|
+
$log.error pre_tst.errors.first[1] unless pre_tst.errors.empty?
|
|
249
|
+
end
|
|
250
|
+
variations = oats_data['execution']['environments']
|
|
251
|
+
Oats.assert variations, "Missing entry for Oats.data execution.environments"
|
|
252
|
+
# Don't let environment variations propogate down OatsData.history.inspect variations.inspect
|
|
253
|
+
variations = nil if OatsData.history.find{|var| var =~ /\/environments\/#{variations.first}/ }
|
|
254
|
+
# Should also eliminate propogations of other variations if want to support other variations.
|
|
255
|
+
cur_list = TestList.current
|
|
256
|
+
cur_list.variations.last.end_time = Time.now.to_i if cur_list and cur_list.variations.last.end_time.nil?
|
|
257
|
+
new_list = TestList.new(id,test_yaml)
|
|
258
|
+
if variations.nil? or variations.empty?
|
|
259
|
+
Driver.process_oats_data(oats_data)
|
|
260
|
+
new_list.variations.last.end_time = Time.now.to_i
|
|
261
|
+
else
|
|
262
|
+
# Don't let variations files modify test file
|
|
263
|
+
test_files = oats_data['execution']['test_files']
|
|
264
|
+
# # Don't let current variations propagate down
|
|
265
|
+
variations.each do |variation|
|
|
266
|
+
begin
|
|
267
|
+
new_list.add_variation(variation)
|
|
268
|
+
break if $oats_info['stop_oats']
|
|
269
|
+
variation = variation.sub(/\.yml$/,'') # Get rid of extension, if provided.
|
|
270
|
+
# Look for variation in environments
|
|
271
|
+
environment_variation = Util.expand_path( variation+'.yml',
|
|
272
|
+
File.join(oats_data['execution']['dir_tests'], 'environments') )
|
|
273
|
+
raise(OatsError, "Can not locate variation [#{variation}]: #{environment_variation}" ) \
|
|
274
|
+
unless File.exist?(environment_variation)
|
|
275
|
+
new_oats_data = OatsData.load( environment_variation, oats_data)
|
|
276
|
+
new_oats_data['env']['name'] = variation
|
|
277
|
+
new_oats_data['_']['load_history'].last.in_result_dir = false if variations.length == 1
|
|
278
|
+
new_oats_data['_']['environments'] << variation
|
|
279
|
+
# If the same variation is found in user's directories, merge it
|
|
280
|
+
user_var_dir = oats_data['execution']['dir_environments']
|
|
281
|
+
if user_var_dir and File.directory?(user_var_dir)
|
|
282
|
+
users_variation = Util.expand_path(variation+'.yml',user_var_dir)
|
|
283
|
+
if File.exist?(users_variation) and # in case input was absolute
|
|
284
|
+
not File.identical?(users_variation, environment_variation)
|
|
285
|
+
new_oats_data = OatsData.load( users_variation, new_oats_data)
|
|
286
|
+
new_oats_data['_']['load_history'].last.in_result_dir = false if variations.length == 1
|
|
287
|
+
new_oats_data['_']['environments'] << users_variation
|
|
288
|
+
# Keep only one name, the one in the user's variation in history
|
|
289
|
+
# new_oats_data['_']['load_history'][-2].omit = true
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
new_oats_data['execution']['test_files'] = test_files
|
|
293
|
+
Roptions.overlay($oats['_']['options']) if $oats['_']['options']
|
|
294
|
+
Driver.process_oats_data(new_oats_data)
|
|
295
|
+
rescue OatsError
|
|
296
|
+
$log.error $!.to_s
|
|
297
|
+
$log.error "Test variation is being skipped: #{variation} "
|
|
298
|
+
next
|
|
299
|
+
rescue
|
|
300
|
+
$log.error TestCase.backtrace($!)
|
|
301
|
+
$log.error "Test variation is being skipped: #{variation} "
|
|
302
|
+
next
|
|
303
|
+
ensure
|
|
304
|
+
new_list.variations.last.end_time = Time.now.to_i
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
new_list.end_time = Time.now.to_i
|
|
309
|
+
new_list.variations.last.end_time = new_list.end_time unless new_list.variations.last.end_time
|
|
310
|
+
TestList.current = cur_list if cur_list
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
# Process each test_file in oats_data once
|
|
314
|
+
def Driver.process_oats_data(oats_data)
|
|
315
|
+
stop_file = oats_data['execution']['stop_file']
|
|
316
|
+
$oats = oats_data # Oats Data becomes global only this point down to allow recursion.
|
|
317
|
+
begin
|
|
318
|
+
ApplicationLogs.tail_errors # If the user just wants to tail, this never returns
|
|
319
|
+
rescue OatsBadInput
|
|
320
|
+
$log.fatal $!.to_s
|
|
321
|
+
exit
|
|
322
|
+
end
|
|
323
|
+
# The environment file for tailing is included only in the user's very first variation.
|
|
324
|
+
test_files = oats_data['execution']['test_files']
|
|
325
|
+
if ! test_files or test_files.empty?
|
|
326
|
+
$log.fatal( "Must provide at least one test.")
|
|
327
|
+
$log.fatal 'Effective config file sequence ' + OatsData.history[1..-1].inspect
|
|
328
|
+
return
|
|
329
|
+
end
|
|
330
|
+
BuildId.generate # Specific to the AUT, supplied in the test_dir/lib
|
|
331
|
+
# Dump oats_data and start each test with a fresh copy each time to avoid contamination
|
|
332
|
+
oats_data_dump = Marshal.dump(oats_data)
|
|
333
|
+
while test_file = test_files.shift do
|
|
334
|
+
skip_test = false
|
|
335
|
+
if stop_file and File.exist?(stop_file)
|
|
336
|
+
$oats_info['stop_oats'] = Time.new.to_i
|
|
337
|
+
FileUtils.mv(stop_file, stop_file + '_' + $oats_info['start_time'].to_s[2..-1] )
|
|
338
|
+
end
|
|
339
|
+
break if $oats_info['stop_oats']
|
|
340
|
+
$oats = Marshal.load(oats_data_dump)
|
|
341
|
+
begin
|
|
342
|
+
if test_file.instance_of? Array
|
|
343
|
+
path = test_file[0]
|
|
344
|
+
id = path.sub( Regexp.new( '^' + $oats['execution']['dir_tests'] + '/', Regexp::IGNORECASE ) , '')
|
|
345
|
+
id = id.sub(/\.rb/,'.'+test_file[1])
|
|
346
|
+
tst = TestCase.new(id,test_file)
|
|
347
|
+
tst.run
|
|
348
|
+
else
|
|
349
|
+
id, extension, path, handler = TestCase.parse_test_files(test_file)
|
|
350
|
+
restrict_tests = $oats['execution']['restrict_tests']
|
|
351
|
+
if restrict_tests and restrict_tests.include?(test_file)
|
|
352
|
+
$oats['execution']['no_run'] = 'restrict_tests'
|
|
353
|
+
# skip_test = true
|
|
354
|
+
# next
|
|
355
|
+
end
|
|
356
|
+
if (extension == 'yml' and handler.nil?) or extension == 'xlw'
|
|
357
|
+
unless path
|
|
358
|
+
$log.error "Could not locate test list '#{id}'"
|
|
359
|
+
TestList.current.variations.last.tests.pop
|
|
360
|
+
return
|
|
361
|
+
end
|
|
362
|
+
begin
|
|
363
|
+
Driver.process_test_yaml( $oats, id, path)
|
|
364
|
+
ensure
|
|
365
|
+
$oats = Marshal.load(oats_data_dump)
|
|
366
|
+
post = $oats['execution']['handler_post_test_list']
|
|
367
|
+
if post
|
|
368
|
+
post_tst = TestCase.new(post)
|
|
369
|
+
post_tst.type = 0
|
|
370
|
+
post_tst.run
|
|
371
|
+
TestList.current.post_test = post_tst
|
|
372
|
+
TestList.current.variations.last.tests.pop
|
|
373
|
+
$log.error post_tst.errors.first[1] unless post_tst.errors.empty?
|
|
374
|
+
end
|
|
375
|
+
end
|
|
376
|
+
else
|
|
377
|
+
case extension
|
|
378
|
+
when 'xls'
|
|
379
|
+
# Use it to include for suite.worksheet entries into test_files.
|
|
380
|
+
# Later process these similar to list.yml files
|
|
381
|
+
unless path
|
|
382
|
+
$log.error "Could not locate XL file '#{id}'"
|
|
383
|
+
TestList.current.variations.last.tests.pop
|
|
384
|
+
return
|
|
385
|
+
end
|
|
386
|
+
test_files.concat Driver.parse_xl(path, id)
|
|
387
|
+
|
|
388
|
+
when 'txt'
|
|
389
|
+
list = TestList.txt_tests(path)
|
|
390
|
+
$log.info "Including test list [#{path}]: #{list.inspect}"
|
|
391
|
+
test_files = list + test_files
|
|
392
|
+
skip_test = true
|
|
393
|
+
|
|
394
|
+
else
|
|
395
|
+
tst = TestCase.new(test_file, id, extension, path, handler)
|
|
396
|
+
tst.run
|
|
397
|
+
end
|
|
398
|
+
end
|
|
399
|
+
end
|
|
400
|
+
# rescue OatsError # OatsTestError # Explicit Test Failure Assertion
|
|
401
|
+
# $log.debug "OatsError exception caught by test driver"
|
|
402
|
+
# tst = TestCase.new(test_file,path) unless path # TestData.Locate has failed
|
|
403
|
+
# $log.error $!.to_s.chomp
|
|
404
|
+
# TestData.error($!)
|
|
405
|
+
rescue Exception => e
|
|
406
|
+
$log.debug "General Exception caught by test driver."
|
|
407
|
+
case e
|
|
408
|
+
when OatsVerifyError # Selenium::CommandError, Timeout::Error then $log.error backtrace($!)
|
|
409
|
+
$log.error e.to_s.chomp
|
|
410
|
+
when OatsError
|
|
411
|
+
$log.error TestCase.backtrace(e)
|
|
412
|
+
else
|
|
413
|
+
$log.error e
|
|
414
|
+
end
|
|
415
|
+
tst = TestCase.new(test_file) unless tst # just in case something happened above before test creation
|
|
416
|
+
TestData.error(e)
|
|
417
|
+
ensure
|
|
418
|
+
if $oats_global['test_files'].instance_of?(Array)
|
|
419
|
+
test_files += $oats_global['test_files']
|
|
420
|
+
$oats_global.delete 'test_files'
|
|
421
|
+
end
|
|
422
|
+
next if skip_test or tst.nil? or tst.instance_of?(TestList) # coming from next above
|
|
423
|
+
tst.end_time = Time.new.to_i
|
|
424
|
+
case tst.status
|
|
425
|
+
when 0 then $log.info "PASSED: #{tst.id}"
|
|
426
|
+
when 1 then $log.warn "FAILED: #{tst.id} [#{tst.errors.last[1].chomp}]"
|
|
427
|
+
when 2 then $log.warn "SKIPPED: #{tst.id}"
|
|
428
|
+
else
|
|
429
|
+
if tst.status.nil? and $oats_execution['agent']
|
|
430
|
+
$log.error "Removing results of last test due to empty test.status, possibly due to agent shutdown."
|
|
431
|
+
TestData.tests.pop
|
|
432
|
+
else
|
|
433
|
+
$log.error "Unrecognized test.status: [#{tst.status}] for [#{tst.name}] . Please inform OATS administrator."
|
|
434
|
+
end
|
|
435
|
+
end
|
|
436
|
+
test_outputter = Log4r::Outputter['test_log']
|
|
437
|
+
if test_outputter and ! test_outputter.closed?
|
|
438
|
+
test_outputter.close
|
|
439
|
+
$log.remove('test_log')
|
|
440
|
+
end
|
|
441
|
+
Report.oats_info_store
|
|
442
|
+
end
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
# Return all the included worksheet lists in XL and place all
|
|
448
|
+
# their test arrays in $oats_global['xl']
|
|
449
|
+
def Driver.parse_xl(path,id)
|
|
450
|
+
book = Spreadsheet.open path
|
|
451
|
+
sheet = book.worksheet 'Main'
|
|
452
|
+
Oats.assert sheet, "Could not locate worksheet 'Main' in: " + path
|
|
453
|
+
list = Driver.xl_sheet_tests(sheet, id, 'Main', 'Test_Scenarios')
|
|
454
|
+
Oats.assert !list.empty?, "No executable worksheets are listed in Main worksheet in: " + path
|
|
455
|
+
$log.info "Processing 'Main' worksheet in XL file: " + path
|
|
456
|
+
$log.info "Worksheets to be included: #{list.inspect}"
|
|
457
|
+
tests = $oats_global['xl'] = {}
|
|
458
|
+
test_files = []
|
|
459
|
+
list.each do |ws|
|
|
460
|
+
sheet = book.worksheet ws
|
|
461
|
+
Oats.assert sheet, "XL file does not contain worksheet: " + ws
|
|
462
|
+
suite_ws = id + '/' + ws
|
|
463
|
+
execute_index = test_index = nil
|
|
464
|
+
tests[suite_ws] = Driver.xl_sheet_tests(sheet, id, ws, 'Test_Cases')
|
|
465
|
+
Oats.assert !tests[suite_ws].empty?, "No executable tests are listed in worksheet: " + suite_ws
|
|
466
|
+
test_files.push suite_ws + '.xlw'
|
|
467
|
+
end
|
|
468
|
+
test_files
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
def Driver.xl_sheet_tests(sheet,xl, ws, test_header)
|
|
472
|
+
execute_index = test_index = nil
|
|
473
|
+
msg = " in worksheet '#{ws}' of: #{xl}"
|
|
474
|
+
sheet.collect do |row|
|
|
475
|
+
if test_index
|
|
476
|
+
# Oats.assert row[test_index], "Missing value in column '#{test_header}'" + msg
|
|
477
|
+
row[test_index] if row[execute_index] and (row[execute_index] == true or row[execute_index].downcase == 'true')
|
|
478
|
+
else
|
|
479
|
+
row.each_with_index do |col,idx|
|
|
480
|
+
case col
|
|
481
|
+
when test_header then test_index = idx
|
|
482
|
+
when 'Execute' then execute_index = idx
|
|
483
|
+
end
|
|
484
|
+
end
|
|
485
|
+
Oats.assert test_index, "Missing column '#{test_header}' "+ msg
|
|
486
|
+
Oats.assert test_index, "Missing column 'Execute' "+ msg
|
|
487
|
+
end
|
|
488
|
+
end.compact
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
end
|
|
492
|
+
end
|