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
|
@@ -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
|