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/oats.rb
ADDED
|
@@ -0,0 +1,637 @@
|
|
|
1
|
+
require 'oats/util'
|
|
2
|
+
require 'oats/oats_exceptions'
|
|
3
|
+
# Need these set for OCC when this is required from OCC
|
|
4
|
+
ENV['OATS_HOME'] ||= File.expand_path( '..', File.dirname(__FILE__) )
|
|
5
|
+
ENV['OATS_TESTS'] ||= (ENV['OATS_HOME'] + '/oats_tests')
|
|
6
|
+
|
|
7
|
+
module Oats
|
|
8
|
+
|
|
9
|
+
# Main method that starts oats execution.
|
|
10
|
+
# Parameters are command-line arguments
|
|
11
|
+
# Returns oats_info object containing execution results
|
|
12
|
+
def Oats.run(args = nil)
|
|
13
|
+
Driver.run(args)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Registers classes to initialize class methods by calling call <Class>.init before
|
|
17
|
+
# each TestList execution. To use, put inside the class: Oats.testlist_init(self)
|
|
18
|
+
def Oats.testlist_init(klas, *args)
|
|
19
|
+
$oats_execution['testlist_init'] ||= {}
|
|
20
|
+
$oats_execution['testlist_init'][klas] = args
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Merges indicated YAML into the test's Oats.data
|
|
24
|
+
def Oats.yaml(yaml_file)
|
|
25
|
+
OatsData.include_yaml_file yaml_file
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Adds new test to the current test_files
|
|
29
|
+
# OatsTest.names method(s) should be defined under the OatsTest module in the lib
|
|
30
|
+
# Example:
|
|
31
|
+
# Oats.add_test Oats.add_test "method_test", "testid_#{i}", "parameter_#{i}"
|
|
32
|
+
# module OatsTest # Place this definition in the 'lib' to be auto-required
|
|
33
|
+
# def self.method_test(params)
|
|
34
|
+
# Oats.info "Running new test: #{Oats.test.id} with params: #{params.inspect}"
|
|
35
|
+
# end
|
|
36
|
+
# end
|
|
37
|
+
def Oats.add_test(*args)
|
|
38
|
+
# Oats.assert self.respond_to?(name), "Method OatsTest.#{names} is not defined."
|
|
39
|
+
# args[0] = TestData.current_test.dir.sub(/\.rb/,".#{args[0]}.methodTest")
|
|
40
|
+
|
|
41
|
+
# args.unshift TestData.current_test.dir
|
|
42
|
+
$oats_global['test_files'] ||= []
|
|
43
|
+
$oats_global['test_files'].push(args[0])
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Raises OatsAssertError unless is includer.include?(includee) is true
|
|
47
|
+
# If given pre_message preceeds the standard message showing expected and actuals.
|
|
48
|
+
# Example:
|
|
49
|
+
# Oats.assert_include('is','this, "Should never fail")
|
|
50
|
+
def Oats.assert_include?(includee, includer, pre_message = nil)
|
|
51
|
+
pre_message += ' ' if pre_message
|
|
52
|
+
Oats.assert(includer.include?(includee),"#{pre_message} Failed since #{includer.inspect} does not include #{includee.inspect}")
|
|
53
|
+
end
|
|
54
|
+
# Raises OatsAssertError unless two parameters are '=='
|
|
55
|
+
# If given pre_message preceeds the standard message showing expected and actuals.
|
|
56
|
+
# Example:
|
|
57
|
+
# Oats.assert_equal(old_count, new_count, "After deletion, creative counts did not decrease.")
|
|
58
|
+
def Oats.assert_equal(expected, actual, pre_message = nil)
|
|
59
|
+
pre_message += ' ' if pre_message
|
|
60
|
+
Oats.assert(expected == actual,"#{pre_message}Expected value #{expected.inspect} does not match actual #{actual.inspect}")
|
|
61
|
+
end
|
|
62
|
+
# Raises OatsAssertError if two parameters are '=='
|
|
63
|
+
def Oats.assert_not_equal(expected, actual, pre_message = nil)
|
|
64
|
+
pre_message += ' ' if pre_message
|
|
65
|
+
Oats.assert(expected != actual,"#{pre_message}Expected different but received the same value: #{actual.inspect}")
|
|
66
|
+
end
|
|
67
|
+
# Raises OatsTestError unless test is true
|
|
68
|
+
def Oats.assert(test, message = nil)
|
|
69
|
+
message = 'Assertion failed.' unless message
|
|
70
|
+
raise(OatsAssertError, message) unless test
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Returns a browser (selenium driver), logging into RL site or opening URL.
|
|
74
|
+
# The browser is retrieved and reused in the subsequent rtest.*rb executions,
|
|
75
|
+
# but it is automatically closed at the end of each Oats test. If exists, the
|
|
76
|
+
# browser is also accessible via the global $selenium.
|
|
77
|
+
# The arguments url_or_site and credentials will be passed to Oselenium.login
|
|
78
|
+
#
|
|
79
|
+
# Parameters:
|
|
80
|
+
# url_or_site:: String, A URL, or site:
|
|
81
|
+
# [root@oats ]
|
|
82
|
+
# Required parameter for the first invocation, can be
|
|
83
|
+
# omitted in subsequent invocations to get the current browser.
|
|
84
|
+
# Re-issueing it w/o logging out of the same site will reopen
|
|
85
|
+
# the landing page. A different site will cause logout of the
|
|
86
|
+
# old site and login to the new site. User will be created if
|
|
87
|
+
# it does not already exists.
|
|
88
|
+
# new_browser:: If true, will create a new browser while keeping the old one.
|
|
89
|
+
# credentials:: Hash to contain credentials['email'] and, credentials['password']
|
|
90
|
+
#
|
|
91
|
+
# Methods in addition to the selenium driver methods are:
|
|
92
|
+
# login(site):: Same as Oats.browser(url_or_site), for a site. Returns nil if
|
|
93
|
+
# site is not recognized.
|
|
94
|
+
# logout:: Logs out of the last logged in sites if any and returns browser.
|
|
95
|
+
# Logout may not succeed if logout button is unavailable.
|
|
96
|
+
#
|
|
97
|
+
# Examples:
|
|
98
|
+
# browser = Oats.browser('oats')
|
|
99
|
+
# browser.click("link=Orders")
|
|
100
|
+
# browser.login('root@')
|
|
101
|
+
# browser.logout
|
|
102
|
+
#
|
|
103
|
+
def Oats.browser(*args)
|
|
104
|
+
require 'oats/oselenium' unless defined?(Oats::Oselenium)
|
|
105
|
+
Oselenium.browser(*args)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Capture system screenshot and logs
|
|
109
|
+
# Returns captured file name if successful, or nil.
|
|
110
|
+
def Oats.system_capture
|
|
111
|
+
return if $selenium.nil? or # Snapshots are not supported on Ubuntu/Chrome
|
|
112
|
+
($oats['selenium']['browser_type'] == 'chrome' and ENV['OS'] == 'Linux')
|
|
113
|
+
ct = TestData.current_test
|
|
114
|
+
file = Util.file_unique(fn="page_screenshot.png", ct.result)
|
|
115
|
+
Oats.info "Will attempt to capture #{fn}."
|
|
116
|
+
begin
|
|
117
|
+
timeout($oats['selenium']['capture_timeout']) { selenium.save_screenshot(file) }
|
|
118
|
+
ct.error_capture_file = fn
|
|
119
|
+
rescue Exception => e
|
|
120
|
+
$log.warn "Could not capture page screenshot: #{e}"
|
|
121
|
+
end
|
|
122
|
+
return ct.error_capture_file
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Loads the indicated ruby file file after locating it in the tests directory.
|
|
126
|
+
#
|
|
127
|
+
# Parameters:
|
|
128
|
+
# ruby_file_name: Name or path snippet of a the ruby file. Could be a glob.
|
|
129
|
+
#
|
|
130
|
+
# Examples:
|
|
131
|
+
# Oats.oload 'rtest_AddCreatives'
|
|
132
|
+
# Oats.oload 'verifyAddCreatives/rtest_Add*'
|
|
133
|
+
def Oats.oload(ruby_file_name)
|
|
134
|
+
file = TestCase.locate_test_rb(ruby_file_name)
|
|
135
|
+
if file
|
|
136
|
+
begin
|
|
137
|
+
Oats.debug "Loading rb file: #{file}"
|
|
138
|
+
Oats.global['oloads'].push file
|
|
139
|
+
load(file)
|
|
140
|
+
ensure
|
|
141
|
+
Oats.debug "Finished rb file: #{file}"
|
|
142
|
+
Oats.global['oloads'].pop
|
|
143
|
+
end
|
|
144
|
+
else
|
|
145
|
+
raise OatsError, "Can not locate ruby file to load: #{ruby_file_name}"
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Hash object providing access to the oats.yml state entries at the time of
|
|
150
|
+
# test execution. Note that Oats.data contents are isolated from modification
|
|
151
|
+
# across tests. If path is not found, returns nil unless do_raise_if_missing
|
|
152
|
+
# is set.
|
|
153
|
+
# map_string:: Period seperated YAML path into the current Oats.data
|
|
154
|
+
# If not specified, returns the full hash.
|
|
155
|
+
# do_raise_if_missing:: set true to raise OatsTestError if key is missing
|
|
156
|
+
# Examples:
|
|
157
|
+
# Oats.data 'selenium.browser' == 'firefox
|
|
158
|
+
# Oats.data['selenium']['browser'] == 'firefox'
|
|
159
|
+
def Oats.data(map_str = nil, do_raise_if_missing = nil)
|
|
160
|
+
return $oats unless map_str
|
|
161
|
+
data_keys = map_str.split('.')
|
|
162
|
+
value = $oats
|
|
163
|
+
# until ! value.kind_of?(Hash) or data_keys.size == 0 do
|
|
164
|
+
loop do
|
|
165
|
+
return value if data_keys.empty?
|
|
166
|
+
if value.instance_of? Hash
|
|
167
|
+
key = data_keys.shift
|
|
168
|
+
if do_raise_if_missing
|
|
169
|
+
Oats.assert(value.has_key?(key), "Can not locate #{key} for #{map_str} at ")
|
|
170
|
+
end
|
|
171
|
+
value = value[key]
|
|
172
|
+
else
|
|
173
|
+
return nil
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# Adjust result dir YAML entries if running on agent mode
|
|
179
|
+
def Oats.result_archive_dir
|
|
180
|
+
return $oats['result_archive_dir'] if $oats['result_archive_dir']
|
|
181
|
+
oats_data = $oats
|
|
182
|
+
oats_data['execution']['dir_results'] = Util.expand_path(oats_data['execution']['dir_results'])
|
|
183
|
+
oats_data['result_archive_dir'] = oats_data['execution']['dir_results'] + '_archive'
|
|
184
|
+
if $oats_execution['agent']
|
|
185
|
+
agent_nickname = Ragent.occ['agent_nickname']
|
|
186
|
+
if oats_data['execution']['dir_results'] !~ /#{agent_nickname}$/
|
|
187
|
+
# Should move to a better place.This is unrelated to results, Just picking up the agent file.
|
|
188
|
+
agent_ini_file = File.join(ENV['HOME'], agent_nickname + '_oats.yml')
|
|
189
|
+
oats_data = OatsData.load(agent_ini_file,oats_data) if File.exist?(agent_ini_file)
|
|
190
|
+
oats_data['result_archive_dir'] += '/' + agent_nickname
|
|
191
|
+
oats_data['execution']['dir_results'] += '/' + agent_nickname
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
FileUtils.mkdir_p(oats_data['result_archive_dir'])
|
|
195
|
+
return oats_data['result_archive_dir']
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# Returns input or ''. Used to force ruby eval of Oat.data YML values
|
|
199
|
+
def Oats.eval(input=nil)
|
|
200
|
+
return input || ''
|
|
201
|
+
end
|
|
202
|
+
# Returns hash object containing info about persistent oats internal variables
|
|
203
|
+
# for the complete oats execution. Contents of Oats.context are also persisted into
|
|
204
|
+
# the results.dump in the results directory.
|
|
205
|
+
#
|
|
206
|
+
# Examples:
|
|
207
|
+
# Oats.context['stop_oats'] == true # Request stopping oats after current test
|
|
208
|
+
def Oats.context
|
|
209
|
+
$oats_info
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
# Output debug level log entries.
|
|
213
|
+
def Oats.debug(arg)
|
|
214
|
+
$log.debug(arg)
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# Output error level log entries.
|
|
218
|
+
def Oats.error(arg)
|
|
219
|
+
ex = OatsTestError.exception(arg.to_s)
|
|
220
|
+
TestData.error(ex)
|
|
221
|
+
$log.error(arg)
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
# Exit a OATS Test from the middle without throwing an error.
|
|
225
|
+
def Oats.exit(message=nil)
|
|
226
|
+
raise OatsTestExit, message if message
|
|
227
|
+
raise OatsTestExit
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
# Raise OatsTestExit and SKIP current test if there was a previous test and
|
|
231
|
+
# if previous test dif not pass or or_if_true is true
|
|
232
|
+
def Oats.skip_unless_previous_test_is_ok(or_if_true = false)
|
|
233
|
+
return unless TestData.previous_test
|
|
234
|
+
if or_if_true or TestData.previous_test.status != 0
|
|
235
|
+
Oats.data['execution']['no_run'] = true
|
|
236
|
+
Oats.exit "Skipping this test since previous test did not pass."
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
# Exception raised by Oats.filter
|
|
241
|
+
class OatsFilterError < OatsError ; end
|
|
242
|
+
|
|
243
|
+
# Returns Windows file path of a file name to be used with file uploads.
|
|
244
|
+
# name:: globbed file name inside the test directory or under test/data folder.
|
|
245
|
+
# Examples:
|
|
246
|
+
# image = Oats.file "125x125_GIF_4K.gif"
|
|
247
|
+
def Oats.file(name)
|
|
248
|
+
file = name if File.exist?(name)
|
|
249
|
+
file = Dir.glob(File.join(Oats.test.path, name)).first unless file
|
|
250
|
+
file = Dir.glob(File.join( $oats['execution']['dir_tests'], 'data', '**',name)).first unless file
|
|
251
|
+
Oats.assert file, "Can not locate file with name [#{name}]"
|
|
252
|
+
Oselenium.remote_webdriver_map_file_path(file)
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
# Moves files downloaded by selenium into the test.result directory.
|
|
257
|
+
# Input is shell glob names, defaulting to '*'.
|
|
258
|
+
# Returns array of basenames of copied files.
|
|
259
|
+
# Assumes downloaded file is not empty
|
|
260
|
+
def Oats.collect_downloaded(file_glob_name = '*')
|
|
261
|
+
downloaded_files = []
|
|
262
|
+
result_dir = TestData.current_test.result
|
|
263
|
+
# cur_test.collect_downloaded_output if cur_test && cur_test.instance_of?(TestCase)
|
|
264
|
+
Oats.wait_until("There were no files in: #{$oats_global['download_dir']}", 15) do
|
|
265
|
+
Dir.glob(File.join($oats_global['download_dir'],file_glob_name)) do |e|
|
|
266
|
+
# Ensure file is fully downloaded
|
|
267
|
+
old_size = 0
|
|
268
|
+
Oats.wait_until do
|
|
269
|
+
new_size = File.size?(e) # Returns nil if size is zero. Assumes downloaded file is not empty
|
|
270
|
+
if new_size and new_size == old_size # File size stabilized
|
|
271
|
+
FileUtils.mv(e, result_dir )
|
|
272
|
+
downloaded_files.push(File.basename(e))
|
|
273
|
+
else
|
|
274
|
+
old_size = new_size
|
|
275
|
+
false
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
downloaded_files != []
|
|
280
|
+
end
|
|
281
|
+
return downloaded_files
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
# Removes the random words from files in 'Oats.test.result' by applying
|
|
286
|
+
# prescribed filter to each line of file and replaces it. The return value is
|
|
287
|
+
# the filtered contents of the file. The filtered contents are also placed in
|
|
288
|
+
# test.out to be compared as expected results. Errors will raise OatsFilterError.
|
|
289
|
+
# * With a block replaces each line with result of the block.
|
|
290
|
+
# * Without block, uses a pattern and replacement parameters for filtering.
|
|
291
|
+
# * If pattern and replacement is missing it copies the whole input file.
|
|
292
|
+
# * If in_file is a string, no output file is generated unless out_file is given.
|
|
293
|
+
#
|
|
294
|
+
# Parameters:
|
|
295
|
+
# in_file:: Name or path of file that is to be filtered and moved to
|
|
296
|
+
# Oats.test.out. It can also be String Array or String containing the
|
|
297
|
+
# actual contents. If the file contains a space, it is assumed to be
|
|
298
|
+
# contents. Missing input or file raises OatsFilterError.
|
|
299
|
+
# out_file:: File name to use for the output file. This is an optional
|
|
300
|
+
# parameter which can be skipped. If skipped, basename of the
|
|
301
|
+
# infile is used.
|
|
302
|
+
# pattern:: A regexp pattern to pass on to a gsub or grep method. Grep is
|
|
303
|
+
# used if replacement parameter is unspecified, in other words
|
|
304
|
+
# file_contents.grep(/pattern_string/)
|
|
305
|
+
# replacement:: Fixed string to replace the pattern by calling
|
|
306
|
+
# file_contents.gsub(pattern,replacement)
|
|
307
|
+
#
|
|
308
|
+
# Examples:
|
|
309
|
+
# Oats.filter('input.txt') # Moves input.txt to test.out for auto-verification.
|
|
310
|
+
# Oats.filter('input.txt','output.txt,/this/) # Considers only lines containing 'this'
|
|
311
|
+
# Oats.filter('input.txt',/this.*that/,'thisAndThat') # Replaces indicated content
|
|
312
|
+
# Oats.filter('input.txt') { |line| line unless line == 'this\n' } # Omits 'this\n' line
|
|
313
|
+
def Oats.filter(in_file, *param)
|
|
314
|
+
raise(OatsFilterError,"At least one inputis required.") unless in_file
|
|
315
|
+
test = TestData.current_test
|
|
316
|
+
case in_file
|
|
317
|
+
when String
|
|
318
|
+
raise(OatsFilterError,"Input string can not be empty.") if in_file == ''
|
|
319
|
+
if /\s/ =~ in_file # If there is space in name, assume it is not a file
|
|
320
|
+
input_is_file = false
|
|
321
|
+
lines = in_file.split($/)
|
|
322
|
+
else
|
|
323
|
+
input_is_file = true
|
|
324
|
+
if File.exist?(in_file)
|
|
325
|
+
filter_file = Util.expand_path(in_file)
|
|
326
|
+
else
|
|
327
|
+
in_files = Dir[in_file]
|
|
328
|
+
filter_file = in_files[0] unless in_files.empty?
|
|
329
|
+
end
|
|
330
|
+
unless filter_file
|
|
331
|
+
result_dir = test.result
|
|
332
|
+
filter_file = Util.expand_path(in_file, result_dir)
|
|
333
|
+
filter_file = nil unless File.exist?(filter_file)
|
|
334
|
+
end
|
|
335
|
+
unless filter_file
|
|
336
|
+
filter_file = Util.expand_path(in_file, result_dir)
|
|
337
|
+
in_files = Dir[filter_file]
|
|
338
|
+
if in_files.empty?
|
|
339
|
+
filter_file = nil
|
|
340
|
+
else
|
|
341
|
+
filter_file = in_files[0]
|
|
342
|
+
end
|
|
343
|
+
end
|
|
344
|
+
raise(OatsFilterError,"Can not locate file to filter: [#{in_file}] in: " + result_dir) unless filter_file
|
|
345
|
+
raise(OatsFilterError,"Can not read file to filter: #{filter_file}") unless File.readable?(filter_file)
|
|
346
|
+
end
|
|
347
|
+
when Array
|
|
348
|
+
input_is_file = false
|
|
349
|
+
lines = in_file
|
|
350
|
+
else
|
|
351
|
+
raise(OatsFilterError,'Unrecognized input type.')
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
if not param.empty? and param[0].instance_of?(String)
|
|
355
|
+
out_file = File.join(test.out, File.basename(param[0]))
|
|
356
|
+
param.shift
|
|
357
|
+
elsif input_is_file
|
|
358
|
+
out_file = File.join(test.out, File.basename(filter_file))
|
|
359
|
+
else
|
|
360
|
+
out_file = nil
|
|
361
|
+
end
|
|
362
|
+
FileUtils.mkdir_p(test.out) if test.out
|
|
363
|
+
if param.empty?
|
|
364
|
+
pattern = nil
|
|
365
|
+
else
|
|
366
|
+
pattern = param[0]
|
|
367
|
+
param.shift
|
|
368
|
+
end
|
|
369
|
+
if param.empty?
|
|
370
|
+
replacement = nil
|
|
371
|
+
else
|
|
372
|
+
replacement = param[0]
|
|
373
|
+
param.shift
|
|
374
|
+
end
|
|
375
|
+
lines = IO.readlines(filter_file) if input_is_file
|
|
376
|
+
# FileUtils.rm(filter_file)
|
|
377
|
+
out_lines = if block_given?
|
|
378
|
+
lines.collect { |line| yield(line) }
|
|
379
|
+
elsif replacement
|
|
380
|
+
lines.collect { |line| line.sub!(pattern,replacement) }
|
|
381
|
+
elsif pattern
|
|
382
|
+
lines.grep(pattern)
|
|
383
|
+
else
|
|
384
|
+
if out_file and filter_file
|
|
385
|
+
FileUtils.cp(filter_file, out_file) # Do not mv here.
|
|
386
|
+
# Otherwise out_file can not produce unique files
|
|
387
|
+
return lines ? lines : []
|
|
388
|
+
end
|
|
389
|
+
lines ? lines : []
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
if out_lines
|
|
393
|
+
out_lines.delete_if{ |line| line.chomp == '' } unless out_lines.empty?
|
|
394
|
+
if out_file and not out_lines.empty?
|
|
395
|
+
File.open(out_file,'a+') { |ios| ios.write(out_lines.join) }
|
|
396
|
+
end
|
|
397
|
+
else
|
|
398
|
+
out_lines = []
|
|
399
|
+
end
|
|
400
|
+
out_lines
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
# Creates a file handle to output into the out directory with given name
|
|
404
|
+
# Returns the comparison with any previous ok file if exists.
|
|
405
|
+
#
|
|
406
|
+
# Parameters:
|
|
407
|
+
# file_name: Appends '_<count>' to the this name if the file already exists.
|
|
408
|
+
# content: String to output, must supply only if a block is not given.
|
|
409
|
+
# no_raise: If set to true, just return comparison, don't raise exception
|
|
410
|
+
# Examples:
|
|
411
|
+
# Oats.out_file('my_file.txt', "Check this string" }
|
|
412
|
+
# Oats.out_file('my_file.txt') { |f| f.puts "Check this string" }
|
|
413
|
+
def Oats.out_file(file_name, content = nil, no_raise = nil)
|
|
414
|
+
out_path = Util.file_unique(file_name, Oats.test.result)
|
|
415
|
+
File.open(out_path, 'w+') do |f|
|
|
416
|
+
if block_given?
|
|
417
|
+
yield f
|
|
418
|
+
else
|
|
419
|
+
f.puts content
|
|
420
|
+
end
|
|
421
|
+
end
|
|
422
|
+
Oats.assert(File.exist?(out_path), "Can not find file #{out_path}") # Verify did create the file
|
|
423
|
+
File.basename(out_path)
|
|
424
|
+
# file_ok = File.join Oats.test.ok_out, basename
|
|
425
|
+
# is_ok = true
|
|
426
|
+
# if File.exist?(file_ok)
|
|
427
|
+
# is_ok = FileUtils.compare_file(out_path, file_ok)
|
|
428
|
+
# Oats.assert is_ok || no_raise, "Found differences in file: #{file_ok}"
|
|
429
|
+
# Oats.info "Matched ok contents [#{content||basename}"
|
|
430
|
+
# end
|
|
431
|
+
# return is_ok
|
|
432
|
+
end
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
# Runs the input_suite_path from a particular Oats.test. Assumes Oats.data is
|
|
436
|
+
# initialized for Oats.test
|
|
437
|
+
#
|
|
438
|
+
# Parameters:
|
|
439
|
+
# input_suite_path:: path to the IDE suite HTML
|
|
440
|
+
# hash:: list from => to values to use for regeneration of the included test
|
|
441
|
+
# cases.
|
|
442
|
+
#
|
|
443
|
+
# Examples:
|
|
444
|
+
# Oats.ide.run('../campaign/rtest.html', 'this_token" => 'that_value')
|
|
445
|
+
def Oats.ide(input_suite_path, hash = nil )
|
|
446
|
+
$ide.run(input_suite_path, hash )
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
# Obsolete. Create classes and use class variables to carry over global info.
|
|
450
|
+
def Oats.global
|
|
451
|
+
$oats_global
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
# Output info level log entries.
|
|
455
|
+
def Oats.info(arg)
|
|
456
|
+
# return if arg.nil?
|
|
457
|
+
arg = arg.inspect unless arg.instance_of?(String)
|
|
458
|
+
$log.info(arg)
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
# Execute MySQL files or statements, return result set in an array of rows.
|
|
464
|
+
# Empty result set results in an empty array. First row [0] of the result
|
|
465
|
+
# contains the column headers. If each row has multiple fields, the row is
|
|
466
|
+
# returned in an array of strings. Otherwise each row a string containing the
|
|
467
|
+
# single column value.
|
|
468
|
+
#
|
|
469
|
+
# Parameters:
|
|
470
|
+
# sql_input:: String denoting a file or SQL content (assumed if s has a space)
|
|
471
|
+
# connect:: Override for Oats.data sql:connect
|
|
472
|
+
# sql_out_name:: File name to place the SQL output into the test.out directory.
|
|
473
|
+
|
|
474
|
+
# Examples
|
|
475
|
+
# Oats.mysql('input.sql') => produces input.txt and returns its contents
|
|
476
|
+
# Oats.mysql('input.sql', 'output.txt) => produces output.txt and returns its contents
|
|
477
|
+
# mysql_results = Oats.mysql "SELECT bu_lastname, FROM BusinessUser where bu_email='levent.atasoy@oats.org;XYZ'"
|
|
478
|
+
# result = Oats.mysql(my_sql_statement)
|
|
479
|
+
# result.is_empty? # true if SQL returns nothing
|
|
480
|
+
# result.last # string value for the last row of a single select statement
|
|
481
|
+
# result[1][2] # second column for the first return result row
|
|
482
|
+
|
|
483
|
+
def Oats.mysql(*sql_input)
|
|
484
|
+
require 'oats/mysql' unless defined?(Oats::Mysql) == 'constant'
|
|
485
|
+
$mysql ||= Oats::Mysql.new
|
|
486
|
+
$mysql.run(*sql_input)
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
# Executes a script on an server via ssh using PuTTy/plink
|
|
490
|
+
# Assumes pageant with keys for the username is up and running.
|
|
491
|
+
# Returns the result of the standard output and standard error.
|
|
492
|
+
#
|
|
493
|
+
# Parameters:
|
|
494
|
+
# cmd_file:: Path of the executable relative to dir
|
|
495
|
+
# dir:: Directory to cd prior to executing cmd_file. Home of user if omitted.
|
|
496
|
+
# host/session: Name for putty on which to execute cmd_file. Defaults via Oats.data
|
|
497
|
+
# username:: Putty connection data Login username. Defaults via Oats.data.
|
|
498
|
+
# If username is 'root', executes the cmd_file as sudo root with
|
|
499
|
+
# Oats.data[ssh.root_sudo_username].
|
|
500
|
+
# root_sudo_username must be able to
|
|
501
|
+
# - access host via Plink/Pageant
|
|
502
|
+
# - sudo -s on the host
|
|
503
|
+
# - cd to dir without being root.
|
|
504
|
+
#
|
|
505
|
+
# Examples
|
|
506
|
+
# out = Oats.rssh('/home/transfer.pl')
|
|
507
|
+
# Oats.rssh('./transfer.pl', /home')
|
|
508
|
+
# Oats.rssh('cat that.log','/var/www/app')
|
|
509
|
+
# Oats.rssh('ls httpd', '/var/log', nil, 'root')
|
|
510
|
+
def Oats.rssh(cmd_file, dir = nil , host = nil, username = nil)
|
|
511
|
+
Ossh.run(cmd_file, dir, host, username )
|
|
512
|
+
end
|
|
513
|
+
|
|
514
|
+
# Copies a file to the server via ssh using PuTTy/plink
|
|
515
|
+
# Assumes pageant with keys for the username is up and running.
|
|
516
|
+
# Returns the result of the standard output and standard error, which is
|
|
517
|
+
# typically empty.
|
|
518
|
+
#
|
|
519
|
+
# Parameters:
|
|
520
|
+
# content_file:: Path of the content file, or the content string if file
|
|
521
|
+
# does not exist.
|
|
522
|
+
# target_file_path:: Path of the file on the server
|
|
523
|
+
# host/session: Same parameter as in Oats.rssh
|
|
524
|
+
# username:: Same parameter as in Oats.rssh
|
|
525
|
+
#
|
|
526
|
+
# Examples
|
|
527
|
+
# Oats.rput 'xxx xxxxxxx', '/tmp/myfile.txt' , 'qapp001.dyn.wh.oats.org'
|
|
528
|
+
# Oats.rput 'c:/qa/oats-user.yml', '/tmp/myfile.txt' , 'qapp001.dyn.wh.oats.org'
|
|
529
|
+
def Oats.rput(content_file, target_file_path = nil, host = nil, username = nil)
|
|
530
|
+
Ossh.run(content_file, target_file_path, host, username, true)
|
|
531
|
+
end
|
|
532
|
+
|
|
533
|
+
# Returns the current TestData object. You can use the public instance methods
|
|
534
|
+
# of TestCase to access to test path components or other test information.
|
|
535
|
+
def Oats.test
|
|
536
|
+
TestData.current_test
|
|
537
|
+
end
|
|
538
|
+
|
|
539
|
+
# Samples the given block each second until it returns true or times out.
|
|
540
|
+
# Raises OatsTestError if times out or returns last value of block.
|
|
541
|
+
#
|
|
542
|
+
# Parameters (also allowed as Hash):
|
|
543
|
+
# :message Exception message to issue upon timeout.
|
|
544
|
+
# Appended with 'in N seconds' unless seconds is negative.
|
|
545
|
+
# :seconds For timeout, defaults from Oats.data selenium.command_timeout
|
|
546
|
+
# :is_return Returns false if times out instead of raising OatsTestError.
|
|
547
|
+
# If :message is nil, :is_return defaults to true
|
|
548
|
+
# :interval Seconds to wait in betweeen calls to block
|
|
549
|
+
#
|
|
550
|
+
# Example:
|
|
551
|
+
# wait_str = 'loadingIcon'
|
|
552
|
+
# Oats.wait_until("Page did not have [#{wait_str}]") {
|
|
553
|
+
# $selenium.get_html_source.include?(wait_str)
|
|
554
|
+
# }
|
|
555
|
+
def Oats.wait_until(*args)
|
|
556
|
+
raise(OatsTestError, 'Oats.wait_until requires an input block.') unless block_given?
|
|
557
|
+
if args[0].kind_of?(Hash)
|
|
558
|
+
options = args[0]
|
|
559
|
+
message = options[:message]
|
|
560
|
+
seconds = options[:seconds]
|
|
561
|
+
is_return = options[:is_return]
|
|
562
|
+
interval = options[:interval]
|
|
563
|
+
else
|
|
564
|
+
message, seconds, is_return, interval = *args
|
|
565
|
+
end
|
|
566
|
+
interval ||= 1
|
|
567
|
+
seconds ||= Oats.data['execution']['wait_until_timeout']
|
|
568
|
+
is_return = true if message.nil?
|
|
569
|
+
if seconds < 0
|
|
570
|
+
seconds = seconds.abs
|
|
571
|
+
message += " in #{seconds} seconds"
|
|
572
|
+
end
|
|
573
|
+
begin
|
|
574
|
+
return_val = false
|
|
575
|
+
Timeout::timeout seconds do
|
|
576
|
+
loop do
|
|
577
|
+
return_val = yield
|
|
578
|
+
break if return_val
|
|
579
|
+
sleep interval
|
|
580
|
+
end
|
|
581
|
+
return return_val
|
|
582
|
+
end
|
|
583
|
+
rescue Timeout::Error
|
|
584
|
+
if is_return
|
|
585
|
+
Oats.warn message if message
|
|
586
|
+
return false
|
|
587
|
+
else
|
|
588
|
+
raise(OatsTestError, message) if message
|
|
589
|
+
raise OatsTestError
|
|
590
|
+
end
|
|
591
|
+
end
|
|
592
|
+
end
|
|
593
|
+
|
|
594
|
+
# Returns a unique string for each machine for each call.
|
|
595
|
+
# The string will start with the input prefix if supplied.
|
|
596
|
+
# If the input prefix matches the pattern of unique output, then only the
|
|
597
|
+
# unique suffix is modified.
|
|
598
|
+
#
|
|
599
|
+
# Parameters:
|
|
600
|
+
# prefix:: Prefix string to use.
|
|
601
|
+
#
|
|
602
|
+
# Examples:
|
|
603
|
+
# Oats.unique => "mach_83580508"
|
|
604
|
+
# Oats.unique('this') => "this-835805081"
|
|
605
|
+
# Oats.unique(Oats.unique('this')) => "this-835805082"
|
|
606
|
+
def Oats.unique(prefix = nil)
|
|
607
|
+
agent = $oats_execution['agent'] ? $oats_execution['agent']['execution:occ:agent_nickname'] : nil
|
|
608
|
+
prefix = ENV['HOSTNAME'].sub(/\..*/,'').downcase unless prefix or agent
|
|
609
|
+
postfix = (agent ? agent + '_' : '') + Time.now.to_i.to_s[-8..-1]
|
|
610
|
+
if Oats.global['unique']
|
|
611
|
+
extra = Oats.global['unique'].sub(/#{postfix}/,'')
|
|
612
|
+
unless extra == Oats.global['unique']
|
|
613
|
+
if extra == ''
|
|
614
|
+
postfix = "#{postfix}1"
|
|
615
|
+
else
|
|
616
|
+
postfix = postfix + ((extra.to_i) + 1).to_s
|
|
617
|
+
end
|
|
618
|
+
end
|
|
619
|
+
end
|
|
620
|
+
Oats.global['unique'] = postfix
|
|
621
|
+
if prefix
|
|
622
|
+
separator = '-'
|
|
623
|
+
else
|
|
624
|
+
prefix = ''
|
|
625
|
+
separator = ''
|
|
626
|
+
end
|
|
627
|
+
postfix_pattern = separator + (agent ? agent + '_' : '') + '\d\d\d\d\d\d\d\d\d*'
|
|
628
|
+
return prefix.sub(/#{postfix_pattern}$/, '') + separator + "#{postfix}"
|
|
629
|
+
end
|
|
630
|
+
|
|
631
|
+
# Output warning level log entries.
|
|
632
|
+
def Oats.warn(arg)
|
|
633
|
+
$log.warn(arg)
|
|
634
|
+
end
|
|
635
|
+
|
|
636
|
+
end
|
|
637
|
+
|