oats 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (181) hide show
  1. data/.gitignore +6 -0
  2. data/Gemfile +15 -0
  3. data/README.txt +165 -0
  4. data/Rakefile +2 -0
  5. data/bin/agent +204 -0
  6. data/bin/oats +10 -0
  7. data/bin/occ +29 -0
  8. data/bin/results_cleanup +6 -0
  9. data/doc/COPYING +55 -0
  10. data/doc/LICENSE +55 -0
  11. data/doc/OATS_Framework.doc +0 -0
  12. data/doc/classes/ApplicationLogs.html +239 -0
  13. data/doc/classes/Campaign.html +843 -0
  14. data/doc/classes/CommandlineOptions.html +131 -0
  15. data/doc/classes/Driver.html +182 -0
  16. data/doc/classes/Hash.html +137 -0
  17. data/doc/classes/Ide.html +194 -0
  18. data/doc/classes/MapSelenium.html +197 -0
  19. data/doc/classes/Net.html +107 -0
  20. data/doc/classes/Oats/OatsFilterError.html +119 -0
  21. data/doc/classes/Oats.html +998 -0
  22. data/doc/classes/OatsAssertError.html +119 -0
  23. data/doc/classes/OatsBadInput.html +119 -0
  24. data/doc/classes/OatsData.html +290 -0
  25. data/doc/classes/OatsError.html +117 -0
  26. data/doc/classes/OatsExit.html +117 -0
  27. data/doc/classes/OatsLock.html +254 -0
  28. data/doc/classes/OatsMain.html +182 -0
  29. data/doc/classes/OatsMysqlError.html +113 -0
  30. data/doc/classes/OatsMysqlMissingInput.html +113 -0
  31. data/doc/classes/OatsReportError.html +113 -0
  32. data/doc/classes/OatsSetupError.html +119 -0
  33. data/doc/classes/OatsTestError.html +119 -0
  34. data/doc/classes/OatsTestExit.html +119 -0
  35. data/doc/classes/OatsTestLocateError.html +120 -0
  36. data/doc/classes/OatsVerifyError.html +119 -0
  37. data/doc/classes/Ragent.html +397 -0
  38. data/doc/classes/Rclient.html +236 -0
  39. data/doc/classes/Report.html +368 -0
  40. data/doc/classes/Reports.html +244 -0
  41. data/doc/classes/RestApi.html +333 -0
  42. data/doc/classes/RhttpClient.html +236 -0
  43. data/doc/classes/Rimap.html +170 -0
  44. data/doc/classes/Rmysql.html +176 -0
  45. data/doc/classes/Roptions.html +131 -0
  46. data/doc/classes/Rselenium.html +233 -0
  47. data/doc/classes/Rssh.html +138 -0
  48. data/doc/classes/Runnable.html +174 -0
  49. data/doc/classes/SFTriggers.html +206 -0
  50. data/doc/classes/Selenium/Client/Driver.html +211 -0
  51. data/doc/classes/Selenium/Client.html +107 -0
  52. data/doc/classes/Selenium.html +107 -0
  53. data/doc/classes/SystemCapture.html +304 -0
  54. data/doc/classes/TestCase.html +418 -0
  55. data/doc/classes/TestData.html +235 -0
  56. data/doc/classes/TestList.html +264 -0
  57. data/doc/classes/Tools.html +244 -0
  58. data/doc/classes/Util.html +201 -0
  59. data/doc/classes/Variation.html +206 -0
  60. data/doc/fr_class_index.html +92 -0
  61. data/doc/fr_method_index.html +465 -0
  62. data/doc/index.html +23 -0
  63. data/doc/oats_httpd.conf +32 -0
  64. data/doc/oats_user.yml +25 -0
  65. data/doc/rdoc-style.css +208 -0
  66. data/lib/deep_merge/.gitignore +2 -0
  67. data/lib/deep_merge/core.rb +195 -0
  68. data/lib/deep_merge/deep_merge.rb +1 -0
  69. data/lib/deep_merge/deep_merge_hash.rb +28 -0
  70. data/lib/deep_merge/rails_compat.rb +27 -0
  71. data/lib/oats/application_logs.rb +163 -0
  72. data/lib/oats/build_id.rb +58 -0
  73. data/lib/oats/commandline_options.rb +128 -0
  74. data/lib/oats/diff.rb +278 -0
  75. data/lib/oats/driver.rb +492 -0
  76. data/lib/oats/ide.rb +227 -0
  77. data/lib/oats/keywords.rb +67 -0
  78. data/lib/oats/log4r_init.rb +14 -0
  79. data/lib/oats/mysql.rb +97 -0
  80. data/lib/oats/oats.rb +637 -0
  81. data/lib/oats/oats_data.rb +400 -0
  82. data/lib/oats/oats_exceptions.rb +25 -0
  83. data/lib/oats/oats_lock.rb +261 -0
  84. data/lib/oats/oats_selenium_api.rb +639 -0
  85. data/lib/oats/oselenium.rb +189 -0
  86. data/lib/oats/ossh.rb +36 -0
  87. data/lib/oats/patches_for_eventmachine_12.10.rb +66 -0
  88. data/lib/oats/ragent.rb +321 -0
  89. data/lib/oats/rclient.rb +42 -0
  90. data/lib/oats/report.rb +207 -0
  91. data/lib/oats/roptions.rb +88 -0
  92. data/lib/oats/test_case.rb +510 -0
  93. data/lib/oats/test_data.rb +98 -0
  94. data/lib/oats/test_list.rb +141 -0
  95. data/lib/oats/unixdiff.rb +75 -0
  96. data/lib/oats/util.rb +125 -0
  97. data/lib/oats/version.rb +3 -0
  98. data/lib/oats.rb +36 -0
  99. data/nbproject/configs/agent.properties +0 -0
  100. data/nbproject/configs/gr.properties +0 -0
  101. data/nbproject/project.properties +10 -0
  102. data/nbproject/project.xml +17 -0
  103. data/oats.gemspec +42 -0
  104. data/oats_ini.yml +258 -0
  105. data/oats_tests/Gemfile +18 -0
  106. data/oats_tests/aut_ini.yml +30 -0
  107. data/oats_tests/bin/oats +8 -0
  108. data/oats_tests/environments/qa.yml +4 -0
  109. data/oats_tests/environments/qa_chrome.yml +4 -0
  110. data/oats_tests/examples/core/coreExamples.yml +8 -0
  111. data/oats_tests/examples/core/expectedException.rb +39 -0
  112. data/oats_tests/examples/core/ok_verify.rb +2 -0
  113. data/oats_tests/examples/core/ok_verify.rb_ok/out/myfile.txt +1 -0
  114. data/oats_tests/examples/core/ok_verify.rb_ok/out/myfile2.txt +1 -0
  115. data/oats_tests/examples/core/ok_verify.rb_ok/rats_test.log +2 -0
  116. data/oats_tests/examples/core/unexpectedException.rb +30 -0
  117. data/oats_tests/examples/examples.yml +13 -0
  118. data/oats_tests/examples/gui/guiExamples.yml +7 -0
  119. data/oats_tests/examples/gui/seleniumGoogle.rb +10 -0
  120. data/oats_tests/examples/gui/webdriverGoogle.rb +9 -0
  121. data/oats_tests/examples/keywords/SampleXlList-1.xls +0 -0
  122. data/oats_tests/examples/keywords/SampleXlList-2.xls +0 -0
  123. data/oats_tests/examples/keywords/SampleXlLists.xls +0 -0
  124. data/oats_tests/examples/keywords/keywordsDriver.rb +1 -0
  125. data/oats_tests/examples/keywords/keywordsExamples.yml +8 -0
  126. data/oats_tests/examples/keywords/keywordsTC1.yml +5 -0
  127. data/oats_tests/examples/keywords/keywordsTestlist.yml +16 -0
  128. data/oats_tests/examples/needsWork/addTestDynamically.rb +4 -0
  129. data/oats_tests/examples/needsWork/emailVerify.rb +34 -0
  130. data/oats_tests/examples/needsWork/testSql/rtest.sql +6 -0
  131. data/oats_tests/examples/needsWork/testSql/rtest.yml +11 -0
  132. data/oats_tests/examples/occTest/occTest.rb +13 -0
  133. data/oats_tests/examples/occTest/occTest_1.rb +1 -0
  134. data/oats_tests/examples/occTest/occTest_1_1.rb +1 -0
  135. data/oats_tests/examples/occTest/occTest_1_2.rb +1 -0
  136. data/oats_tests/examples/occTest/occTest_1_3.rb +1 -0
  137. data/oats_tests/examples/occTest/occTest_1_4.rb +1 -0
  138. data/oats_tests/examples/occTest/occTest_2.rb +1 -0
  139. data/oats_tests/examples/occTest/occTest_2_1.rb +1 -0
  140. data/oats_tests/examples/occTest/occTest_2_2.rb +1 -0
  141. data/oats_tests/examples/occTest/occTest_2_3.rb +1 -0
  142. data/oats_tests/examples/occTest/occTest_2_4.rb +1 -0
  143. data/oats_tests/examples/occTest/occTest_3.rb +1 -0
  144. data/oats_tests/examples/occTest/occTest_3_1.rb +1 -0
  145. data/oats_tests/examples/occTest/occTest_3_2.rb +1 -0
  146. data/oats_tests/examples/occTest/occTest_3_3.rb +1 -0
  147. data/oats_tests/examples/occTest/occTest_3_4.rb +1 -0
  148. data/oats_tests/examples/occTest/occTest_4.rb +1 -0
  149. data/oats_tests/examples/occTest/occTestlist.yml +9 -0
  150. data/oats_tests/examples/occTest/occTestlist_1.yml +9 -0
  151. data/oats_tests/examples/occTest/occTestlist_2.yml +9 -0
  152. data/oats_tests/examples/occTest/occTestlist_3.yml +9 -0
  153. data/oats_tests/examples/occTest/variation1.yml +4 -0
  154. data/oats_tests/examples/occTest/variation2.yml +4 -0
  155. data/oats_tests/examples/testFileLocationUnitTests/extn_driver.rb +4 -0
  156. data/oats_tests/examples/testFileLocationUnitTests/folder/oats.yml +3 -0
  157. data/oats_tests/examples/testFileLocationUnitTests/folder/t1.rb +2 -0
  158. data/oats_tests/examples/testFileLocationUnitTests/folder1/t1.yml +2 -0
  159. data/oats_tests/examples/testFileLocationUnitTests/folder1/t1_1.yml +3 -0
  160. data/oats_tests/examples/testFileLocationUnitTests/folder2/oats.yml +3 -0
  161. data/oats_tests/examples/testFileLocationUnitTests/folder2/t1.rb +2 -0
  162. data/oats_tests/examples/testFileLocationUnitTests/folder2/t1.yml +2 -0
  163. data/oats_tests/examples/testFileLocationUnitTests/no_yaml.rb +3 -0
  164. data/oats_tests/examples/testFileLocationUnitTests/post_yaml.rb +1 -0
  165. data/oats_tests/examples/testFileLocationUnitTests/t1.rb +4 -0
  166. data/oats_tests/examples/testFileLocationUnitTests/t1.yml +2 -0
  167. data/oats_tests/examples/testFileLocationUnitTests/t1_1.yml +3 -0
  168. data/oats_tests/examples/testFileLocationUnitTests/testDir/oats.yml +3 -0
  169. data/oats_tests/examples/testFileLocationUnitTests/testDir/t1.rb +2 -0
  170. data/oats_tests/examples/testFileLocationUnitTests/testDir/t1.yml +2 -0
  171. data/oats_tests/examples/testFileLocationUnitTests/testDir2/t1.rb +2 -0
  172. data/oats_tests/examples/testFileLocationUnitTests/testDir2/t1.yml +2 -0
  173. data/oats_tests/examples/testFileLocationUnitTests/unitTestList.yml +36 -0
  174. data/oats_tests/examples/testFileLocationUnitTests/yml_driver.rb +2 -0
  175. data/oats_tests/lib/business.rb +28 -0
  176. data/oats_tests/lib/sample_xl_lists.rb +37 -0
  177. data/test/common_test_unit_setup.rb +21 -0
  178. data/test/test_basic.rb +16 -0
  179. data/test/test_selenium.rb +16 -0
  180. data/test/test_xl_lists.rb +16 -0
  181. metadata +291 -0
data/lib/oats/ide.rb ADDED
@@ -0,0 +1,227 @@
1
+ # IDE Class to run an IDE based HTML suite after transforming it based on oats_data
2
+
3
+ module Oats
4
+
5
+ # Runs an IDE based HTML suite after transforming it based on current Oats data
6
+ class Ide
7
+ def initialize()
8
+ super
9
+ @suite_base_url_signin_type = nil;
10
+ @first_test_url = nil;
11
+ end
12
+
13
+ # Run input_suite_path while in a TestData.dir . Assumes Oats.data is initialized for TestData.dir
14
+ # input_suite_path:: path to the suite HTML
15
+ # hash:: list from => to values to use for regeneration of the included test cases.
16
+ def run (input_suite_path, hash = nil )
17
+ begin
18
+ run_ide(input_suite_path, hash)
19
+ ensure
20
+ TestData.current_test.collect_downloaded_output
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def run_ide (input_suite_path, hash = nil )
27
+ suite_path = get_path(input_suite_path)
28
+ name = File.basename(suite_path)
29
+ doc = open(suite_path ) { |f| Hpricot(f) }
30
+ # FileUtils.rm Dir[File.join(TestData.current_test.dir,'*.gen.*')] # Clean previously generated files
31
+ FileUtils.rm Dir['*.gen.*'] # Clean previously generated files in pwd
32
+ if doc.search("head[@profile='http://selenium-ide.openqa.org/profiles/test-case']").empty?
33
+ regen_suite = nil
34
+ doc.search('a[@href]') do |a|
35
+ if Oats.data['execution']['run_in_dir_results']
36
+ generated_test = regenerate_html(a['href'], test.result, File.dirname(suite_path), hash)
37
+ else
38
+ generated_test = regenerate_html(a['href'], test.dir, File.dirname(suite_path), hash)
39
+ end
40
+ if generated_test
41
+ regen_suite = true
42
+ a.set_attribute(:href,generated_test)
43
+ end
44
+ end
45
+ html_suite_path = File.join(test.dir , File.basename(suite_path,'.*') + '.gen.html')
46
+ regen_suite = true if regen_suite or html_suite_path != suite_path
47
+ html_suite_path = File.join(test.result , File.basename(suite_path,'.*') + '.gen.html') if Oats.data['execution']['run_in_dir_results']
48
+ $log.info "Creating: #{html_suite_path}"
49
+ File.open( html_suite_path, 'w' ) { |out| out.print doc } if regen_suite
50
+ else # A single test HTML, not the suite
51
+ raise OatsTestError, "Input file is not an IDE suite: " + html_suite_path
52
+ end
53
+
54
+ # Execute html_suite_path
55
+ result_file = File.join(test.result, File.basename(name, '.*') + '_results.html')
56
+ if Oats.data['selenium']['ide']['generate']
57
+ $log.warn "Option execution:ide:generate is set. Test will not be executed."
58
+ $log.debug "Target result_file was: #{result_file}"
59
+ return
60
+ end
61
+ rc_jar_file = File.join(Oats.data['_']['vendor'],'selenium-server.jar')
62
+ browser = '*' + Oats.data['selenium']['browser_type'].sub(/ .*/,'')
63
+ url = nil
64
+ if @suite_base_url_signin_type
65
+ url = Oats.data[@suite_base_url_signin_type]["SignIn"]["url"]
66
+ else
67
+ if @first_test_url
68
+ url = @first_test_url
69
+ else
70
+ raise(OatsError, "None of the tests in #{suite_path} specified a base URL.")
71
+ end
72
+ end
73
+ if url
74
+ base_url = url.match('https?://[^/]*/?')
75
+ else
76
+ base_url = nil
77
+ end
78
+ port = Oats.data['selenium']['ide']['port']
79
+ if Oats.data['env']['web']['host']
80
+ base_url = 'http://' + Oats.data['env']['web']['host']
81
+ else
82
+ base_url = base_url[0]
83
+ end
84
+ # if base_url
85
+ # base_url = base_url[0]
86
+ # else
87
+ # base_url = 'http://' + Oats.data['env']['web']['host']
88
+ # $log.warn "Can not determine the base url from [#{url}]. Assuming base url is [#{base_url}]" \
89
+ # unless @suite_base_url_signin_type and Oats.data[@suite_base_url_signin_type]["SignIn"]
90
+ # end
91
+ command = "java -jar \"#{rc_jar_file}\" -port #{port}"
92
+ command += " -timeout #{Oats.data['selenium']['ide']['suite_timeout']}" if Oats.data['selenium']['ide']['suite_timeout']
93
+ # Don't use profiles when using RC in IDE mode
94
+ command += " -firefoxprofileTemplate \"#{$oats_global['firefox_profile_dir']}\"" \
95
+ if Oats.data['selenium']['browser_type'] =~ /firefox/ and $oats_global['firefox_profile_dir']
96
+ command += " -htmlSuite #{browser} #{base_url} \"#{html_suite_path}\" \"#{result_file}\" 2>&1"
97
+ $log.info "Starting Selenium Remote Control: #{command}"
98
+ # return # DEBUG
99
+ first_rc_try = true
100
+ failure_line = nil
101
+ catch :end_rc do
102
+ 2.times do
103
+ IO.popen(command) do |io|
104
+ while io.gets do
105
+ $log.info chomp
106
+ if /Selenium is already running on port/ =~ $_
107
+ if first_rc_try
108
+ io.readlines.each {|line|$log.info line.chomp }
109
+ Util.clear_port(Oats.data['selenium']['ide']['port'],$log)
110
+ $log.info "Will attempt to restart Selenium RC..."
111
+ else
112
+ # raise(OatsError, $_, caller[1..3])
113
+ raise(OatsError, $_)
114
+ throw(:end_rc)
115
+ end
116
+ first_rc_try = false
117
+ elsif /fail/i =~ $_ and /Failed to start: SocketListener/ !~ $_
118
+ failure_line = $_
119
+ throw(:end_rc)
120
+ elsif /exception/i =~ $_ # Like server.SeleniumCommandTimedOutException
121
+ failure_line = $_
122
+ end
123
+ end
124
+ end
125
+ throw(:end_rc) if first_rc_try
126
+ end
127
+ end
128
+ # pause_val = Oats.data['execution']['ide']['pause_on_exit']
129
+ seconds = 999999
130
+ pause_val = $oats['selenium']['pause_on_exit']
131
+ if not pause_val.integer? or
132
+ pause_val <= 0
133
+ seconds = nil
134
+ elsif pause_val == 1
135
+ seconds = nil unless failure_line
136
+ elsif pause_val > 0
137
+ seconds = pause_val
138
+ end
139
+ raise(OatsError, "Result file is not readable: #{result_file}") unless File.readable?(result_file)
140
+ if seconds
141
+ # Need to quote browser path for cygwin because it may have spaces.
142
+ begin
143
+ timeout(seconds) do
144
+ # $stderr.puts "Paused because selenium:pause_on_exit is set to [#{pause_val}]"
145
+ # $stderr.puts "PLEASE HIT <ENTER> TO CONTINUE!"
146
+ successful = system( '"' +Oats.data['selenium']['ide']['result_browser'] + '" file://'+result_file)
147
+ $log.error "Error trying to open results file: #{$?}" \
148
+ unless successful or $? == 256
149
+ end
150
+ rescue Timeout::Error
151
+ end
152
+ end
153
+ TestData.pause_after_error = false
154
+ $log.info "Results are at: file://#{result_file}"
155
+ raise(OatsTestError, failure_line) if failure_line
156
+ end
157
+
158
+ # Helper method to replace HTML file contents based on oats and test data mappings.
159
+ def map_file_contents(oats_data, test_data, file_contents,key_path)
160
+ return unless test_data
161
+ # $log.debug key_path
162
+ if @suite_base_url_signin_type.nil?
163
+ @suite_base_url_signin_type = 'Campaign' if key_path == 'root:Campaign:SignIn'
164
+ @suite_base_url_signin_type = 'Admin' if key_path == 'root:Admin:SignIn'
165
+ # $log.debug "Base URL is set to #{baseUrl}"
166
+ end
167
+ test_data.each do |key,val|
168
+ repVal = oats_data[key]
169
+ next if val.nil? or repVal.nil?
170
+ if val.class == Hash
171
+ map_file_contents( repVal, val, file_contents,key_path + ':' + key)
172
+ else
173
+ file_contents.gsub!(val, repVal.to_s)
174
+ test_data[key] = repVal
175
+ end
176
+ end
177
+ end
178
+
179
+ # Updates HTML file contents based on current oats_data into test_dir_out
180
+ # Returns generated file name or nil if no new file is generated
181
+ def regenerate_html(file_in, dir_out, dir_in = dir_out, hash = nil)
182
+ basename = File.basename(file_in,'.*')
183
+ file_in_absolute = File.expand_path(file_in,dir_in) # get absolute path
184
+ unless File.exist?(file_in_absolute)
185
+ file_in_absolute = Dir.glob( File.join( $oats['execution']['dir_tests'],
186
+ '/**/', file_in.sub(/^(\.\.\/)*/, ''))).first
187
+ # file_in = file_in.sub!(/[^\/]*\//,'')
188
+ raise(OatsError,"Can not locate IDE test case file: [#{file_in}]") unless file_in_absolute
189
+ end
190
+ file_in_root = file_in_absolute.sub(/(.*)\..*$/,'\1')
191
+ yaml_in = file_in_root + '.yml'
192
+ file_out_root = File.join(dir_out, basename)
193
+ file_gen = file_out_root +'.gen.html'
194
+ yml_out = file_out_root +'.gen.yml'
195
+ new_base_name = basename
196
+ if File.exist?(file_gen)
197
+ new_base_name = File.basename(File.dirname(file_in)) + '_' + new_base_name
198
+ file_gen = File.join(dir_out, new_base_name ) +'.gen.html'
199
+ yml_out = File.join(dir_out, new_base_name ) +'.gen.yml'
200
+ end
201
+ if @suite_base_url_signin_type.nil? and @first_test_url.nil?
202
+ doc = open(file_in_absolute) { |f| Hpricot(f) }
203
+ link = doc.at("link[@rel='selenium.base']")
204
+ @first_test_url = link['href'] unless link.nil?
205
+ end
206
+ unless File.exist?(yaml_in)
207
+ return nil if file_in_root == file_out_root
208
+ $log.info "Copying [#{file_in_absolute}] to: #{file_gen}]"
209
+ FileUtils.cp(file_in_absolute, file_gen)
210
+ return basename + '.gen.html'
211
+ end
212
+ $log.debug "Regenerating [#{file_in_absolute}] into [#{file_gen}] based on [#{yaml_in}]"
213
+ file_contents = IO.read(file_in_absolute)
214
+ test_data = YAML.load_file(yaml_in)
215
+ map_file_contents(Oats.data, test_data, file_contents, 'root')
216
+ hash.each { |val, rep_val| file_contents.gsub!(val, rep_val) } if hash
217
+ if Oats.data['selenium']['browser_type'] =~ /iexplore/
218
+ file_contents.sub!(/(<\/IE-ONLY>.*-->)/,'<-- \1')
219
+ file_contents.sub!(/(<!--.*<IE-ONLY>)/,'\1 -->')
220
+ end
221
+ File.open( file_gen, 'w' ) { |out| out.print file_contents }
222
+ File.open( yml_out, 'w' ) { |out| YAML.dump( test_data, out ) }
223
+ basename + '.gen.html'
224
+ end
225
+
226
+ end
227
+ end
@@ -0,0 +1,67 @@
1
+
2
+ module Oats
3
+
4
+ # Process keyword driven testing
5
+ class Keywords
6
+ class << self
7
+
8
+ # Same as selenium.wait_and_type, but maps key via OatsX.locator, and uses
9
+ # OatsX.data[key] for value
10
+ def wait_and_type(key, *args)
11
+ selenium.wait_and_type(locator(key), oats_data[key], *args)
12
+ end
13
+
14
+ # Same as selenium.wait_for_element, but maps key via OatsX.locator first
15
+ def wait_and_click(key)
16
+ selenium.wait_and_click(locator(key))
17
+ end
18
+
19
+ # Same as selenium.wait_for_element, maps key via OatsX.locator first
20
+ def wait_and_text(key)
21
+ selenium.wait_for_element(locator(key)).text
22
+ end
23
+
24
+ # Returned the key or mappings if defined in the <class>::LOCATOR_MAP
25
+ def locator(key)
26
+ self::LOCATOR_MAP[key] || key
27
+ end
28
+
29
+
30
+ # Return data from XL spreadsheet entries via Oats.data('xl.data')
31
+ # OatsX.oats_data(key_string) or OatsX.oats_data[key_string]
32
+ def oats_data(cell = nil, clas = self)
33
+ xl_root = $oats[clas.name]
34
+ list = xl_root['list'] || Oats.data('keywords.list')
35
+ if list
36
+ xl_root_list = xl_root[list]
37
+ else
38
+ xl_root_list = xl_root
39
+ end
40
+ # Oats.assert list, "Oats.data keywords.list is not defined."
41
+ val = cell ? xl_root_list[cell] : xl_root_list
42
+ Oats.assert( val, "No keywords are defined for #{clas}" + (list ? ".#{list}" : '') ) if cell == 'keywords'
43
+ Marshal.load(Marshal.dump(val)) # Protect Oats.data from modification
44
+ end
45
+
46
+ # Handles keyword processing.
47
+ # Used by OATS framework to run XL driven test suites.
48
+ # Users can also call this from yaml_handlers.
49
+ def process
50
+ # Class name comes from Oats.data oats_keywords_cleass, or in the case of XL files from TestCase ID
51
+ class_name = Oats.data('keywords.class') || File.basename(File.dirname(File.dirname(Oats.test.id)))
52
+ begin
53
+ keywords_class = Kernel.const_get class_name
54
+ rescue NameError
55
+ raise OatsTestError, "Can not find class: " + class_name
56
+ end
57
+ oats_data('keywords',keywords_class).each do |action|
58
+ Oats.assert keywords_class.respond_to?(action),
59
+ "There is no method defined in #{class_name} to the handle keyword 'a#{action}'."
60
+ Oats.info "Performing " + action
61
+ keywords_class.send action
62
+ end
63
+ end
64
+
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,14 @@
1
+ # Log4r can be configured using YAML. This example uses log4r_yaml.yaml
2
+ require 'log4r'
3
+ require 'log4r/yamlconfigurator'
4
+ # we use various outputters, so require them, otherwise config chokes
5
+ require 'log4r/outputter/datefileoutputter'
6
+ require 'log4r/outputter/emailoutputter'
7
+ include Log4r
8
+
9
+ cfg = YamlConfigurator # shorthand
10
+ cfg['HOME'] = ENV['HOME'] # the only parameter in the YAML, our HOME directory
11
+
12
+ # load the YAML file with this
13
+ cfg.load_yaml_file('log4r.yaml')
14
+
data/lib/oats/mysql.rb ADDED
@@ -0,0 +1,97 @@
1
+ #require 'mysql' # http://www.tmtm.org/en/ruby/mysql
2
+ require "tempfile"
3
+ require 'oats/oats_exceptions'
4
+
5
+ module Oats
6
+ class OatsMysqlError < OatsTestError ; end
7
+ class OatsMysqlMissingInput < OatsMysqlError ; end
8
+ class OatsMysqlNoConnect < OatsMysqlError ; end
9
+ # Oats.mysql creates an instance of this class to interact with MySQL DBs
10
+ class Mysql
11
+
12
+ # See Oats.mysql for more accurate/detailed documentation
13
+ # sql_input:: Path to a file.sql to execute
14
+ # connect:: Override for Oats.data sql:connect
15
+ # returns array of rows of results. Each row is an array of columns.
16
+ def run(sql_input, connect = nil, sql_out_name = nil)
17
+ raise OatsMysqlNoConnect, "Oats.data sql:connect is null" unless Oats.data['sql']['connect']
18
+ test = TestData.current_test
19
+ unless /\s/ =~ sql_input # If there is space in name, assume it is not a file
20
+ abs_path = File.expand_path(sql_input,test.path)
21
+ end
22
+ if File.exist?(abs_path)
23
+ mysql_input_file = OatsData.regenerate_file(abs_path)
24
+ mysql_input_file = abs_path unless mysql_input_file
25
+ name = File.basename(sql_input,'.*')
26
+ sql_input = IO.read(mysql_input_file)
27
+ sql_input = nil if sql_input.length > 200
28
+ else
29
+ tf = Tempfile.new("OatsMysqlInput")
30
+ tf.puts(sql_input)
31
+ tf.close
32
+ mysql_input_file = Util.expand_path(tf.path)
33
+ name = 'mysql_default'
34
+ end
35
+ sql_out_name = name + '.txt' unless sql_out_name
36
+ sql_out = File.join(test.result, sql_out_name) if sql_out_name
37
+ err_file = sql_out + '.err'
38
+ command = (ENV['OS'] != 'Darwin' ? 'mysql' : '/usr/local/mysql/bin/mysql') +
39
+ " #{parameters(connect)} < #{mysql_input_file} > #{sql_out} 2> #{err_file}"
40
+ # $log.debug "Executing: #{command}"
41
+ $log.info "SQL: #{sql_input}" if sql_input
42
+ FileUtils.mkdir_p(test.out)
43
+ ok = system(command)
44
+ $log.error("MySQL failed with return code: #{$?}") unless ok
45
+ FileUtils.rm_f(err_file) unless File.size?(err_file)
46
+ FileUtils.rm_f(sql_out) unless File.size?(sql_out)
47
+ if File.exist?(err_file)
48
+ errors = IO.readlines(err_file)
49
+ errors.size == 1 or errors[0...-1].each {|line| $log.error line.chomp}
50
+ raise(OatsMysqlError,errors.last.chomp) unless errors.empty?
51
+ end
52
+ rows = IO.readlines(sql_out) if File.exist?(sql_out)
53
+ return [] unless rows
54
+ rows.shift
55
+ if rows[1] =~ /\t/
56
+ return rows.collect{|t| t.chomp.split(/\t/) }
57
+ else
58
+ return rows.collect{|t| t.chomp }
59
+ end
60
+ end
61
+
62
+
63
+ def processlist
64
+ raise OatsMysqlNoConnect, "Oats.data sql:connect is null" unless Oats.data['sql']['connect']
65
+ sql_out = 'mysql_processlist.txt'
66
+ command = "mysqladmin #{parameters('connect',true)} processlist > #{sql_out}"
67
+ success = system(command)
68
+ $log.error("MySQL failed with return code: #{$?}") unless success
69
+ FileUtils.rm_f(sql_out) unless File.size?(sql_out)
70
+ end
71
+
72
+ private
73
+
74
+ def parameters(connect,proc_list=false)
75
+ sql = Oats.data['sql']
76
+ connect ||= sql['connect']
77
+ conn = sql[connect]
78
+ user = conn['user']
79
+ err "Oats MySQL requires input for sql:user" unless user
80
+ password = conn['password']
81
+ err "Oats MySQL requires a string input for sql:password" unless password
82
+ password = " -p#{password}" unless password == ""
83
+ host = conn['host']
84
+ err "Oats MySQL requires input for sql:host" unless host
85
+ params = "-u#{user}#{password} -h#{host}"
86
+ return params if proc_list
87
+ db = conn['database']
88
+ err "Oats MySQL requires input for sql:db" unless db
89
+ "#{params} -D#{db}"
90
+ end
91
+
92
+ def err(inp)
93
+ raise(OatsMysqlMissingInput,inp)
94
+ end
95
+
96
+ end
97
+ end