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