oats 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -0,0 +1,510 @@
|
|
1
|
+
# Encapsulates data and methods for each test
|
2
|
+
|
3
|
+
module Oats
|
4
|
+
|
5
|
+
class TestCase
|
6
|
+
# Absolute path of the test
|
7
|
+
attr_reader :path
|
8
|
+
# extension of the test if it is a single rb file instead of a directory
|
9
|
+
attr_reader :is_file
|
10
|
+
# Path of handler defined by Oats.data <<:is_file>_extension>_handler
|
11
|
+
attr_reader :handler
|
12
|
+
# Path of test relative to the dir_tests library
|
13
|
+
attr_reader :id
|
14
|
+
# Type of last executed rtest file 1:rb, 2:ide, 3:sql, 0: post, 4: pre
|
15
|
+
attr_accessor :type
|
16
|
+
# Output result directory
|
17
|
+
attr_reader :result
|
18
|
+
# List of exceptions encountered on the test so far
|
19
|
+
attr_reader :errors
|
20
|
+
# Current status of the test 0:pass, 1:fail, 2:skip
|
21
|
+
attr_accessor :status
|
22
|
+
# Time object referring to the end time of the test.
|
23
|
+
attr_accessor :end_time
|
24
|
+
# Time object referring to the start time of the test.
|
25
|
+
attr_reader :start_time
|
26
|
+
# Array containing names of the downloded files during the test
|
27
|
+
attr_reader :downloaded_files
|
28
|
+
# System capture sets this to the name of last error file if one is created
|
29
|
+
attr_accessor :error_capture_file
|
30
|
+
|
31
|
+
def initialize(test_file, *args)
|
32
|
+
# Do minimal work here to avoid exception. Raise in run, so that test header appears.
|
33
|
+
@id, @is_file, @path, @handler = args.empty? ? TestCase.parse_test_files(test_file) : args
|
34
|
+
if args[0].instance_of?(Array)
|
35
|
+
@is_file = true
|
36
|
+
@path = args[0].shift# Treat as rb below
|
37
|
+
@method = args[0].shift
|
38
|
+
@id = args[0].shift
|
39
|
+
@args = args[0]
|
40
|
+
end
|
41
|
+
TestList.current.variations.last.tests << self
|
42
|
+
@result = nil
|
43
|
+
@status = nil
|
44
|
+
@errors = []
|
45
|
+
@sql_input_error = nil
|
46
|
+
@downloaded_files = []
|
47
|
+
@start_time = Time.now.to_i
|
48
|
+
end
|
49
|
+
|
50
|
+
def TestCase.parse_test_files(test_file)
|
51
|
+
extension = File.extname(test_file)[1..-1]
|
52
|
+
handler = $oats['execution'][extension+'_handler'] if extension
|
53
|
+
if handler
|
54
|
+
handler_located = TestData.locate(handler)
|
55
|
+
Oats.assert handler_located, "Could not find handler file #{handler}"
|
56
|
+
handler = handler_located
|
57
|
+
end
|
58
|
+
if extension == 'xlw'
|
59
|
+
id = test_file.sub(/\.#{extension}\z/,'')
|
60
|
+
test_file = File.join(File.dirname(File.dirname(test_file)), File.basename(test_file,extension) + 'xls')
|
61
|
+
end
|
62
|
+
path = TestData.locate(test_file,true)
|
63
|
+
unless path
|
64
|
+
unless handler
|
65
|
+
path = File.join($oats['execution']['dir_tests'], test_file)
|
66
|
+
if 'xltest' == extension
|
67
|
+
test_file.sub!(/\.#{extension}\z/,'')
|
68
|
+
else
|
69
|
+
path = nil
|
70
|
+
end
|
71
|
+
return test_file, extension, path, handler
|
72
|
+
end
|
73
|
+
test_dir = File.dirname(test_file)
|
74
|
+
if test_dir == '.'
|
75
|
+
path = File.join(File.dirname(handler),File.basename(test_file))
|
76
|
+
else
|
77
|
+
test_dir = TestData.locate(test_dir, true)
|
78
|
+
return test_file, extension, path, handler unless test_dir
|
79
|
+
path = File.join(test_dir,File.basename(test_file))
|
80
|
+
end
|
81
|
+
remove_extension = true
|
82
|
+
end
|
83
|
+
extension ||= File.extname(path)[1..-1] # In case of implied extensions
|
84
|
+
unless id
|
85
|
+
id = path.sub( Regexp.new( '^' + $oats['execution']['dir_tests'] + '/', Regexp::IGNORECASE ) , '')
|
86
|
+
id.sub!(/\.#{extension}\z/,'') unless remove_extension
|
87
|
+
end
|
88
|
+
return id, extension, path, handler
|
89
|
+
end
|
90
|
+
|
91
|
+
def backtrace(obj=nil)
|
92
|
+
TestCase.backtrace(obj)
|
93
|
+
end
|
94
|
+
|
95
|
+
def TestCase.backtrace(obj=nil)
|
96
|
+
obj ||= $!
|
97
|
+
return unless obj.kind_of? Exception
|
98
|
+
filtered = obj.backtrace
|
99
|
+
filtered = obj.backtrace.delete_if { |line| line !~ /[\/|\\]oats\/tests[\/|\\]/} unless $oats['execution']['full_stacktrace']
|
100
|
+
# Doing below only filters the message in the log, not the full backtrace in the results.dump
|
101
|
+
# unless $oats['execution']['full_stacktrace']
|
102
|
+
# filtered = obj.backtrace.delete_if { |line| line !~ /[\/|\\]oats\/tests[\/|\\]/}
|
103
|
+
# if TestCase.respond_to?('backtrace_filter')
|
104
|
+
# new_filtered = []
|
105
|
+
# filtered.each { |line| new_filtered << TestCase.backtrace_filter(line) }
|
106
|
+
# filtered = new_filtered
|
107
|
+
# end
|
108
|
+
# end
|
109
|
+
return "Caught #{obj.class}: #{obj.message}" + ( filtered.empty? ? '' : "\n\t") + filtered.join("\n\t")
|
110
|
+
end
|
111
|
+
|
112
|
+
def run
|
113
|
+
if @type == 0 or @type == 4
|
114
|
+
|
115
|
+
$log.info "*** #{@type == 0 ? 'POST':'PRE'} TEST LIST HANDLER [#{@id}] at #{Time.at(@start_time)}"
|
116
|
+
else
|
117
|
+
$log.info "*** TEST [#{@id}] at #{Time.at(@start_time)}"
|
118
|
+
end
|
119
|
+
unless @path
|
120
|
+
TestData.error Exception.new("Found no #{@id} file"+
|
121
|
+
((@is_file and !%w(rb sql html).include?(@is_file)) ? " nor handler for #{@is_file.inspect}." : ".")
|
122
|
+
)
|
123
|
+
return
|
124
|
+
end
|
125
|
+
if @is_file
|
126
|
+
if !%w(rb sql html xltest).include?(@is_file) and !@handler
|
127
|
+
TestData.error Exception.new("Unrecognized extension #{@is_file} for test file [#{@path}]")
|
128
|
+
return
|
129
|
+
end
|
130
|
+
else
|
131
|
+
unless FileTest.directory?(@path)
|
132
|
+
TestData.error Exception.new("Test file must have extension")
|
133
|
+
return
|
134
|
+
end
|
135
|
+
end
|
136
|
+
if @is_file
|
137
|
+
oats_file = @path.sub(/\.#{@is_file}\z/,'.yml')
|
138
|
+
yaml_dir = File.dirname(@path) unless File.exist?(oats_file)
|
139
|
+
else
|
140
|
+
test_var_dir = File.join(@path,'environments')
|
141
|
+
oats_files = Dir.glob(File.join(@path,'*.yml'))
|
142
|
+
if oats_files.size == 1
|
143
|
+
oats_file = oats_files.first
|
144
|
+
else
|
145
|
+
yaml_dir = @path
|
146
|
+
end
|
147
|
+
end
|
148
|
+
if yaml_dir
|
149
|
+
oats_file = File.join(yaml_dir,'oats.yml')
|
150
|
+
oats_file = nil unless File.exist?(oats_file)
|
151
|
+
end
|
152
|
+
odat = nil
|
153
|
+
if @is_file == 'xltest'
|
154
|
+
pth = @id.split('/')
|
155
|
+
pth.pop
|
156
|
+
suit = pth.pop
|
157
|
+
$oats_global['xl'][@id]['data']['keywords'] = $oats_global['xl'][@id]['keywords']
|
158
|
+
odat = { pth.pop => { 'list' => suit, suit => $oats_global['xl'][@id]['data'] } }
|
159
|
+
end
|
160
|
+
$oats = OatsData.overlay(odat) if odat
|
161
|
+
$oats = OatsData.overlay(oats_file) if oats_file
|
162
|
+
if test_var_dir and File.directory?(test_var_dir)
|
163
|
+
vars_overlayed = []
|
164
|
+
$oats['_']['environments'].each do |var_file|
|
165
|
+
## Overlay all previously introduced variations, but only once
|
166
|
+
var_name = File.basename(var_file,'.*')
|
167
|
+
test_var = File.join(test_var_dir,var_name+'.yml')
|
168
|
+
if File.exist?(test_var) and not vars_overlayed.include?(var_name)
|
169
|
+
$oats = OatsData.overlay(test_var)
|
170
|
+
vars_overlayed << var_name
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
$log.debug 'Effective config file history: ' + OatsData.history[1..-1].inspect
|
176
|
+
|
177
|
+
if $oats['execution']['dir_results']
|
178
|
+
FileUtils.mkdir_p($oats['execution']['dir_results']) unless File.directory?($oats['execution']['dir_results'])
|
179
|
+
result_root = Util.expand_path(id, $oats['execution']['dir_results'])
|
180
|
+
else
|
181
|
+
result_root = File.join(@is_file ? File.dirname(@path) : @path,'result')
|
182
|
+
end
|
183
|
+
hist_path = OatsData.history(true)
|
184
|
+
if hist_path.empty?
|
185
|
+
result_dir = result_root
|
186
|
+
else
|
187
|
+
result_dir = File.join( result_root,
|
188
|
+
hist_path[1..-1].collect{|f|File.basename(f , '.*')}.join('/'))
|
189
|
+
end
|
190
|
+
if $oats['execution']['no_run'] # Reuse the last timestamped result_dir
|
191
|
+
if File.directory?(result_dir)
|
192
|
+
latest = Dir.entries(result_dir).last
|
193
|
+
result_dir = File.join(result_dir,latest)
|
194
|
+
else
|
195
|
+
result_dir_save = result_dir
|
196
|
+
result_dir = nil
|
197
|
+
end
|
198
|
+
else
|
199
|
+
# result_dir = File.join(result_dir, @start_time.to_s[2..-1] ) # Create a new timestamped sub result_dir
|
200
|
+
FileUtils.mkdir_p(result_dir)
|
201
|
+
end
|
202
|
+
@result = result_dir
|
203
|
+
if result_dir
|
204
|
+
test_log = File.join(result_dir,'oats_test.log')
|
205
|
+
Log4r::FileOutputter.new('test_log',
|
206
|
+
:filename=>test_log, :trunc=>false, # :level=>level + 1)
|
207
|
+
:formatter=>Log4r::PatternFormatter.new(:depth=>50,
|
208
|
+
:pattern => "%-5l %d %M", :date_pattern=>"%y-%m-%d %H:%M:%S"))
|
209
|
+
$log.add('test_log')
|
210
|
+
end
|
211
|
+
if $oats['execution']['no_run']
|
212
|
+
@status = 2
|
213
|
+
msg = $oats['execution']['no_run'].instance_of?(String) ? (' to '+$oats['execution']['no_run'].inspect) : ''
|
214
|
+
$log.warn "Skipping execution since execution:no_run is set#{msg}."
|
215
|
+
return
|
216
|
+
end
|
217
|
+
# Clean download directory
|
218
|
+
if $oats_global['download_dir']
|
219
|
+
files = Dir.glob(File.join($oats_global['download_dir'],'*'))
|
220
|
+
FileUtils.rm(files) unless files.empty?
|
221
|
+
end
|
222
|
+
# Initialize classes this test may need
|
223
|
+
# $ide = Ide.new unless ENV['JRUBY_BASE']
|
224
|
+
# Execute the test
|
225
|
+
ApplicationLogs.new_errors(true) # Reset pre-existing errors
|
226
|
+
if @is_file
|
227
|
+
oats_tsts = [ @handler || @path ]
|
228
|
+
else
|
229
|
+
oats_tsts = Dir[File.join(@path,'rtest*.{rb,html,sql}')].delete_if { |e| /\.gen\./ =~ e }
|
230
|
+
oats_tsts.unshift(root + '.html') if File.exist?(@path + '.html') # Compatibility with older tests
|
231
|
+
oats_tsts = Dir[File.join(@path,'*.{rb,html,sql}')] if oats_tsts.empty?
|
232
|
+
raise(OatsError,"No files matching rtest*.{rb,html,sql} found in: #{@path}") if oats_tsts.empty?
|
233
|
+
end
|
234
|
+
if result_dir and Oats.data['execution']['run_in_dir_results']
|
235
|
+
unless @is_file
|
236
|
+
Dir.glob(File.join(@path,'*')).each do |file|
|
237
|
+
FileUtils.cp(file, result_dir ) if File.file?(file)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
run_dir = result_dir
|
241
|
+
else
|
242
|
+
raise(OatsError,"Can not run single rb file test without a result_dir.") if @is_file
|
243
|
+
run_dir = @path
|
244
|
+
end
|
245
|
+
quit_on_error = $oats['execution']['quit_on_error']
|
246
|
+
skip_unless_previous_test_is_ok = $oats['execution']['skip_unless_previous_test_is_ok']
|
247
|
+
Oats.global['rbtests'] = []
|
248
|
+
Dir.chdir(run_dir) do
|
249
|
+
begin
|
250
|
+
oats_tsts.sort!
|
251
|
+
oload_hooks(oats_tsts, 'pre', 'unshift')
|
252
|
+
oload_hooks(oats_tsts, 'post', 'push')
|
253
|
+
# FileUtils.mkdir_p(out)
|
254
|
+
exception_in_rb = false
|
255
|
+
oats_tsts.each do |rt|
|
256
|
+
break if quit_on_error and not errors.empty?
|
257
|
+
if skip_unless_previous_test_is_ok and TestData.previous_test and TestData.previous_test.status != 0
|
258
|
+
$oats['execution']['no_run'] = true
|
259
|
+
Oats.info "Skipping due to previous test failure"
|
260
|
+
end
|
261
|
+
raise(OatsError,"Can not read file [#{rt}]") unless File.readable?(rt) unless @is_file == 'xltest'
|
262
|
+
begin
|
263
|
+
case @is_file
|
264
|
+
when 'html'
|
265
|
+
Oats.ide(rt)
|
266
|
+
when 'sql'
|
267
|
+
Oats.mysql(rt)
|
268
|
+
when /^rb$||^xltest$/
|
269
|
+
begin
|
270
|
+
if @method
|
271
|
+
$log.info "Executing OatsTest:#{@method}"
|
272
|
+
Oats.global['rbtests'] << rt # Not sure if this is needed
|
273
|
+
Oats.global['oloads'] = [] # Not sure if this is needed
|
274
|
+
exception_in_rb = true
|
275
|
+
OatsTest.send(@method,*@args)
|
276
|
+
exception_in_rb = false
|
277
|
+
else
|
278
|
+
next if exception_in_rb # Don't process a second rb if one throws an exception
|
279
|
+
Oats.global['rbtests'] << rt
|
280
|
+
Oats.global['oloads'] = []
|
281
|
+
exception_in_rb = true
|
282
|
+
if @is_file == 'xltest'
|
283
|
+
$log.info "Processing test: #{rt}"
|
284
|
+
Oats::Keywords.process
|
285
|
+
else
|
286
|
+
$log.info "Processing rb file: #{rt}"
|
287
|
+
load(rt,true)
|
288
|
+
end
|
289
|
+
exception_in_rb = false
|
290
|
+
end
|
291
|
+
rescue OatsTestExit # Regular exit from the rb test
|
292
|
+
message = $!.message
|
293
|
+
$log.info message unless message == 'OatsTestExit'
|
294
|
+
rescue Exception => e
|
295
|
+
case e
|
296
|
+
when OatsError, Timeout::Error then $log.error backtrace($!)
|
297
|
+
else $log.error $! # Full stackstrace
|
298
|
+
end
|
299
|
+
TestData.error($!)
|
300
|
+
Oats.system_capture unless Oats.data['selenium']['skip_capture']
|
301
|
+
ensure
|
302
|
+
Oselenium.pause_browser if defined?(Oats::Oselenium)
|
303
|
+
end
|
304
|
+
else
|
305
|
+
raise OatsError, "Unrecognized test extension #{@is_file}"
|
306
|
+
end
|
307
|
+
rescue OatsMysqlNoConnect
|
308
|
+
@sql_input_error = true
|
309
|
+
@status = 2
|
310
|
+
$log.warn "#{$!}. Test is classified as SKIPPED."
|
311
|
+
rescue OatsError # No stack for known errors from rmsql and ide
|
312
|
+
$log.error $!.to_s
|
313
|
+
TestData.error($!)
|
314
|
+
rescue # Otherwise want the stack trace
|
315
|
+
$log.error TestCase.backtrace($!)
|
316
|
+
end
|
317
|
+
end
|
318
|
+
ensure
|
319
|
+
begin
|
320
|
+
$mysql.processlist if timed_out? # Ensure selenium closes if this throws an exception
|
321
|
+
rescue
|
322
|
+
end
|
323
|
+
Oselenium.reset if defined?(Oats::Oselenium) and ($oats['selenium']['keep_alive'].nil? or ! errors.empty?)
|
324
|
+
FileUtils.rm_rf(out) if File.directory?(out) and
|
325
|
+
Dir.glob(File.join(out,'*')).empty?
|
326
|
+
if $oats['execution']['no_run']
|
327
|
+
$log.warn "Classifying test as SKIPPED since execution:no_run is set"
|
328
|
+
@status = 2
|
329
|
+
return
|
330
|
+
end
|
331
|
+
end
|
332
|
+
end # of the out generation phase
|
333
|
+
|
334
|
+
# Verify phase
|
335
|
+
if result_dir
|
336
|
+
verify
|
337
|
+
else
|
338
|
+
$log.warn "Skipping verification, can not find result directory: #{result_dir_save}"
|
339
|
+
end
|
340
|
+
log_errors = ApplicationLogs.new_errors
|
341
|
+
unless log_errors.empty?
|
342
|
+
log_errors.each {|e| $log.error e.chomp }
|
343
|
+
raise(OatsVerifyError,"Found errors in the application logs.")
|
344
|
+
end
|
345
|
+
if errors.empty?
|
346
|
+
@status = 0 unless @status
|
347
|
+
FileUtils.rm Dir[File.join( Oats.data['execution']['run_in_dir_results'] ? result_dir : dir ,'*.gen.*')] \
|
348
|
+
if result_dir and not Oats.data['selenium']['ide']['keep_generated_files']
|
349
|
+
end
|
350
|
+
end # of run
|
351
|
+
|
352
|
+
def oload_hooks(oats_tsts, pre, obj_msg)
|
353
|
+
if rb_file = $oats['execution']['oload_'+pre]
|
354
|
+
rb_file = [ rb_file ] unless rb_file.instance_of?(Array)
|
355
|
+
rb_file.reverse! if pre == 'pre'
|
356
|
+
rb_file.each do |rbf|
|
357
|
+
rbf_fnd = TestCase.locate_test_rb(rbf)
|
358
|
+
if rbf_fnd
|
359
|
+
oats_tsts.send(obj_msg,rbf_fnd)
|
360
|
+
else
|
361
|
+
# eval("self", TOPLEVEL_BINDING).method(:foobar) rescue false
|
362
|
+
begin
|
363
|
+
Oats.info "Executing oload_#{pre}: #{rbf}"
|
364
|
+
eval(rbf)
|
365
|
+
# rescue NoMethodError
|
366
|
+
end
|
367
|
+
# if rbf.method?
|
368
|
+
# raise OatsTestError, "Can not locate execution:oload_#{pre} file [#{rbf}]"
|
369
|
+
# end
|
370
|
+
end
|
371
|
+
end
|
372
|
+
end
|
373
|
+
end
|
374
|
+
private :oload_hooks
|
375
|
+
|
376
|
+
def timed_out?
|
377
|
+
@errors.each do |exc|
|
378
|
+
# $log.info exc # debug
|
379
|
+
return true if exc[0] == 'Timeout::Error'
|
380
|
+
end
|
381
|
+
return false
|
382
|
+
end
|
383
|
+
|
384
|
+
def verify
|
385
|
+
return unless Oats.data['execution']['out_verify'] or Oats.data['execution']['ok_verify']
|
386
|
+
test_ok_out = ok_out
|
387
|
+
test_out = out
|
388
|
+
test_ok = ok
|
389
|
+
test_result = result
|
390
|
+
return if ! File.directory?(test_out) and ! File.directory?(test_ok_out)
|
391
|
+
err = nil
|
392
|
+
if ! File.directory?(test_out) and File.directory?(test_ok_out)
|
393
|
+
err= "Missing test.out folder [#{test_out}], but ok_out folder exists: #{test_ok_out})"
|
394
|
+
if Oats.data['execution']['ok_verify'] == 'UPDATE'
|
395
|
+
err += " Removing test.ok folder from the test. Please commit it to code repository."
|
396
|
+
FileUtils.rm_r(test_ok)
|
397
|
+
end
|
398
|
+
$log.error(err)
|
399
|
+
end
|
400
|
+
if File.directory?(test_out) and ! File.directory?(test_ok_out)
|
401
|
+
err = "Missing test.ok_out folder [#{test_ok_out}], but out folder exists: #{test_out}"
|
402
|
+
$log.error(err)
|
403
|
+
if Oats.data['execution']['ok_verify'] == 'UPDATE'
|
404
|
+
FileUtils.mkdir_p test_ok unless File.directory?(test_ok)
|
405
|
+
Dir.chdir(test_result) do
|
406
|
+
Dir.glob('*').each{|f| FileUtils.cp_r(f, test_ok) unless f =~ /\.rb$/}
|
407
|
+
end
|
408
|
+
$log.warn "Created test.ok_out folder: #{test_ok_out}"
|
409
|
+
end
|
410
|
+
end
|
411
|
+
if err
|
412
|
+
if Oats.data['execution']['ok_verify'].nil?
|
413
|
+
ex = OatsVerifyError.exception(err)
|
414
|
+
TestData.error(ex)
|
415
|
+
elsif Oats.data['execution']['ok_verify'] != 'UPDATE'
|
416
|
+
$log.info "Ignoring missing ok directory since Oats.data execution.ok_verify is set"
|
417
|
+
end
|
418
|
+
return
|
419
|
+
end
|
420
|
+
|
421
|
+
error_line = []
|
422
|
+
out_files = Dir.entries(test_out)
|
423
|
+
ok_out_files = Dir.chdir(test_ok_out){Dir.glob('*')}
|
424
|
+
diff_lines = nil
|
425
|
+
out_files.each do |file|
|
426
|
+
next if File.directory?(file)
|
427
|
+
file_out = File.join(test_out, file)
|
428
|
+
file_ok = File.join(test_ok_out, file)
|
429
|
+
err = nil
|
430
|
+
if File.readable?(file_ok)
|
431
|
+
ok_contents = IO.read(file_ok).gsub(/\s/,'')
|
432
|
+
out_contents = IO.read(file_out).gsub(/\s/,'')
|
433
|
+
unless ok_contents == out_contents
|
434
|
+
err = "File in out folder did not match out folder in: #{file_ok}"
|
435
|
+
diff_lines = `diff -b '#{file_ok}' '#{file_out}'` unless ENV['OS'] == 'Windows_NT'
|
436
|
+
end
|
437
|
+
else
|
438
|
+
err = "Extra output [#{file}] missing from: #{test_ok_out}"
|
439
|
+
end
|
440
|
+
if err
|
441
|
+
error_line << err
|
442
|
+
if Oats.data['execution']['ok_verify'] == 'UPDATE'
|
443
|
+
FileUtils.cp(File.join(test_out,file), test_ok_out)
|
444
|
+
source = File.join(test_result,file)
|
445
|
+
FileUtils.cp(source, test_ok) if File.exist?(source)
|
446
|
+
FileUtils.cp(File.join(test_result,'oats_test.log'), test_ok)
|
447
|
+
end
|
448
|
+
end
|
449
|
+
end
|
450
|
+
extra_ok_files = ok_out_files - out_files
|
451
|
+
extra_ok_files.each do |f|
|
452
|
+
file = File.join(test_ok_out,f)
|
453
|
+
FileUtils.rm(file) if Oats.data['execution']['ok_verify'] == 'UPDATE'
|
454
|
+
error_line << "Missing output file: #{file}"
|
455
|
+
end
|
456
|
+
|
457
|
+
if error_line.empty?
|
458
|
+
$log.info "Contents of #{test_ok} matched the output: #{test_out}"
|
459
|
+
else
|
460
|
+
$log.warn "Differences found in execution.ok_verify:\n\t" +
|
461
|
+
error_line.join("\n\t") +
|
462
|
+
(diff_lines ? "\n" + diff_lines : '')
|
463
|
+
if Oats.data['execution']['ok_verify'] == 'UPDATE'
|
464
|
+
$log.warn "Contents of #{test_ok} is updated to match the output: #{test_out}"
|
465
|
+
elsif Oats.data['execution']['ok_verify'].nil?
|
466
|
+
ex = OatsVerifyError.exception(error_line.inspect)
|
467
|
+
TestData.error(ex)
|
468
|
+
# raise(OatsVerifyError,error_line.last)
|
469
|
+
end
|
470
|
+
end
|
471
|
+
end
|
472
|
+
private :verify
|
473
|
+
|
474
|
+
def TestCase.locate_test_rb(ruby_file_name)
|
475
|
+
file = ruby_file_name.sub(/\..*/,'')
|
476
|
+
file = File.join( $oats['execution']['dir_tests'],'/**/', file+'.rb')
|
477
|
+
Dir.glob(file).first
|
478
|
+
end
|
479
|
+
|
480
|
+
# Basename of test.dir
|
481
|
+
def name
|
482
|
+
return @name if @name
|
483
|
+
@name = File.basename(@id)
|
484
|
+
end
|
485
|
+
|
486
|
+
# Directory under test.result, contains output files to be compared
|
487
|
+
def out
|
488
|
+
return @out if @out
|
489
|
+
@out = File.join(self.result, 'out')
|
490
|
+
end
|
491
|
+
|
492
|
+
# Directory of expected results, manually checked in to code repository under test.dir
|
493
|
+
def ok
|
494
|
+
return @ok if @ok
|
495
|
+
raise OatsError, "Test [#{self.id}] does not have a directory" unless @path
|
496
|
+
if @is_file
|
497
|
+
@ok = @path + '_ok'
|
498
|
+
else
|
499
|
+
@ok = File.join(@path, 'ok')
|
500
|
+
end if @path
|
501
|
+
end
|
502
|
+
|
503
|
+
# Directory under test.ok, contains expected result output files
|
504
|
+
def ok_out
|
505
|
+
return @ok_out if @ok_out
|
506
|
+
@ok_out = File.join(self.ok,'out')
|
507
|
+
end
|
508
|
+
end
|
509
|
+
|
510
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'oats/test_list'
|
2
|
+
require 'oats/test_case'
|
3
|
+
|
4
|
+
module Oats
|
5
|
+
|
6
|
+
# Interface module for TestCase or TestList related operations
|
7
|
+
module TestData
|
8
|
+
@@pause_after_error = false
|
9
|
+
|
10
|
+
# Returns array of test objects in the currently executing list
|
11
|
+
# TestData.tests[-1] is the same as as the current_test
|
12
|
+
def TestData.tests
|
13
|
+
cur_test_list = TestList.current
|
14
|
+
return nil unless cur_test_list
|
15
|
+
vars = cur_test_list.variations
|
16
|
+
return nil unless vars
|
17
|
+
last_var = vars.last
|
18
|
+
return nil unless last_var
|
19
|
+
tests = last_var.tests
|
20
|
+
return nil unless tests
|
21
|
+
return tests
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns last test in the currently executing list
|
25
|
+
# index:: of the test in tests array. Default is last
|
26
|
+
def TestData.current_test
|
27
|
+
TestData.tests[-1]
|
28
|
+
end
|
29
|
+
|
30
|
+
def TestData.previous_test
|
31
|
+
TestData.tests[-2]
|
32
|
+
end
|
33
|
+
|
34
|
+
def TestData.pause_after_error
|
35
|
+
@@pause_after_error
|
36
|
+
end
|
37
|
+
|
38
|
+
def TestData.pause_after_error=(do_pause)
|
39
|
+
@@pause_after_error = do_pause
|
40
|
+
end
|
41
|
+
|
42
|
+
def TestData.error(exception)
|
43
|
+
raise exception unless TestData.current_test
|
44
|
+
error = [exception.class.to_s,exception.message, exception.backtrace]
|
45
|
+
TestData.current_test.errors << error
|
46
|
+
TestData.current_test.status = 1
|
47
|
+
@@pause_after_error = true
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns absolute path after locating file in test directories, or nil
|
51
|
+
# If exact match is not found, searches with added .rb extension
|
52
|
+
# If dir is false, do not return a directory #
|
53
|
+
def TestData.locate(test_file, is_dir = false)
|
54
|
+
option ||= {}
|
55
|
+
# Don't rely on $oats when called from OCC
|
56
|
+
dir_tests = if $oats and $oats['execution'] and $oats['execution']['dir_tests']
|
57
|
+
$oats['execution']['dir_tests']
|
58
|
+
else
|
59
|
+
ENV['OATS_TESTS']
|
60
|
+
end
|
61
|
+
Oats.assert test_file, "Test File must be non-nil"
|
62
|
+
extn = File.extname(test_file)
|
63
|
+
extn = nil if extn == ''
|
64
|
+
found_file = catch :found_file do
|
65
|
+
if ENV['OS'] == 'Windows_NT' ? test_file[1] == ?: : test_file[0] == ?/ # absolute path
|
66
|
+
# Try exact match
|
67
|
+
throw(:found_file, test_file) if File.exist?(test_file) and (is_dir or not FileTest.directory?(test_file))
|
68
|
+
|
69
|
+
# Try globbing the input name as is
|
70
|
+
|
71
|
+
found_file = File.exist?(test_file)
|
72
|
+
throw(:found_file, test_file ) if found_file and (is_dir or not FileTest.directory?(test_file))
|
73
|
+
throw(:found_file, test_file+'.rb') if File.exist?(test_file+'.rb') unless extn
|
74
|
+
end
|
75
|
+
|
76
|
+
# Relative path
|
77
|
+
|
78
|
+
dir_tests = "{#{is_dir},#{dir_tests}}" if is_dir.instance_of?(String) and is_dir != dir_tests
|
79
|
+
|
80
|
+
# 19.2 glob skips over the exact test paths, so try that first
|
81
|
+
file = File.join(dir_tests, test_file)
|
82
|
+
file += '{,.rb}' unless extn
|
83
|
+
found_file = Dir.glob(file).first
|
84
|
+
throw(:found_file, found_file) if found_file and (is_dir or not FileTest.directory?(found_file))
|
85
|
+
|
86
|
+
|
87
|
+
# Try finding it anywhere inside the dir_test tree
|
88
|
+
file = File.join(dir_tests, '**', test_file)
|
89
|
+
file += '{,.rb}' unless extn
|
90
|
+
found_file = Dir.glob(file).first
|
91
|
+
throw(:found_file, found_file) if found_file and (is_dir or not FileTest.directory?(found_file))
|
92
|
+
return nil
|
93
|
+
end
|
94
|
+
Oats::Util.expand_path(found_file)
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|