Commit: 5f1f4ec8b08460a091468aba8f4358762ba1e01d Author: Matt Ficken <v-maf...@.redmond.corp.microsoft.com> Tue, 25 Oct 2011 18:47:41 -0700 Parents: cbefe7ccc0a817d1c3f4adcb9ffcf7e2da403cfd Branches: master
Link: http://git.php.net/?p=pftt2.git;a=commitdiff;h=5f1f4ec8b08460a091468aba8f4358762ba1e01d Log: various bug fixes Former-commit-id: cbfac78b154bff3a9cad816b4aab441b13e7e32a Changed paths: M PFTT/_pftt.rb M PFTT/lib/diff.rb M PFTT/lib/host.rb M PFTT/lib/middleware.rb M PFTT/lib/middleware/cli.rb M PFTT/lib/middleware/http.rb M PFTT/lib/phpt_test_case.rb M PFTT/lib/phpt_test_result.rb M PFTT/lib/report/inspect/func.rb M PFTT/lib/report/run/by_host/by_build/by_middleware/func.rb M PFTT/lib/scenario.rb M PFTT/lib/scenario/set.rb M PFTT/lib/server/snapshot_getter.rb M PFTT/lib/test_bench.rb M PFTT/lib/test_bench/phpt.rb A PFTT/pftt M PFTT/pftt.cmd A PFTT/pftt_server M PFTT/pftt_server.cmd M PFTT/scripts/SDK4Win/SetupPHPSDK.cmd
diff --git a/PFTT/_pftt.rb b/PFTT/_pftt.rb index 6e81087..92eb7d4 100644 --- a/PFTT/_pftt.rb +++ b/PFTT/_pftt.rb @@ -220,10 +220,10 @@ class PfttOptions < OptionsHash def help_list_actions puts - puts ' func_part - runs selected PHPT tests (ex: manual tool)' puts ' func_full - deploys PHP and runs PHPT tests (ex: automatic tool)' puts ' func_list - write list of PHPT tests to file. useful with func_part' puts ' func_inspect - inspects options/configs used for func_part or func_full' + puts ' func_part - runs selected PHPT tests (ex: manual tool)' puts ' perf - run Performance test' puts ' stress - run Stress test' puts ' unit - run PHPUnit tests from PHP-AzureSDK, MediaWiki, Symfony, etc' @@ -600,9 +600,10 @@ class PfttOptions < OptionsHash begin list = [] - self[:phpt].each{|phpt| + self[:phpt].each do |phpt| + # TODO puts phpt.inspect list.push(PhptTestCase::Array.new(phpt, self[:test_names])) - } + end return list rescue PhptTestCase::Array::DuplicateTestError puts "PFTT: error: same test occurs in multiple directories: #{file}" @@ -619,15 +620,24 @@ CONFIG = PfttOptions.parse(ARGV) # set up our basic test bench factors $hosts = (Host::Array.new.load(CONFIG[:host,:path].convert_path)).filter(CONFIG[:host,:filters]) -$hosts.push(Host::Remote::Ssh.new(:address=>'127.0.0.1', :username=>'administrator', :password=>'password01!'))#Host::Local.new()) # TODO +$hosts.push(#Host::Local.new(),#)# TODO + #OI1-PHP-FUNC-21-27 + Host::Remote::Ssh.new(:address=>'10.200.50.72', :username=>'administrator', :password=>'password01!'), +# Host::Remote::Ssh.new(:address=>'10.200.50.39', :username=>'administrator', :password=>'password01!'), +# Host::Remote::Ssh.new(:address=>'10.200.50.33', :username=>'administrator', :password=>'password01!'), +# Host::Remote::Ssh.new(:address=>'10.200.50.37', :username=>'administrator', :password=>'password01!'), +# Host::Remote::Ssh.new(:address=>'10.200.50.36', :username=>'administrator', :password=>'password01!'), +# Host::Remote::Ssh.new(:address=>'10.200.50.77', :username=>'administrator', :password=>'password01!'), +# Host::Remote::Ssh.new(:address=>'10.200.50.34', :username=>'administrator', :password=>'password01!'), + Host::Remote::Ssh.new(:address=>'127.0.0.1', :username=>'administrator', :password=>'password01!'))#Host::Local.new()) # TODO require 'typed-array' $phps = PhpBuild.get_set(CONFIG[:php,:dir].convert_path||'').filter(CONFIG[:php,:filters]) -$middlewares = [#Middleware::Cli]#, - Middleware::Http::IIS::FastCgi::Base]#, Middleware::Http::Apache::ModPhp::Base] # TODO Middleware::All#.filter([])# TODO CONFIG[:middleware,:filters]) +$middlewares = [Middleware::Cli]#, + #Middleware::Http::IIS::FastCgi::Base]#, Middleware::Http::Apache::ModPhp::Base] # TODO Middleware::All#.filter([])# TODO CONFIG[:middleware,:filters]) # LATER? what about NFSv3 support (which ships with Windows 7<) (not NFSv4) $scenarios = [ - Scenario::Set( + Scenario::Set.new( '1', Scenario::WorkingFileSystem::Local.new()#, #Scenario::RemoteFileSystem::Http.new, @@ -833,14 +843,15 @@ if __FILE__ == $0 unless CONFIG[:action] == 'perf' $testcases = CONFIG.selected_tests() + # TODO puts $testcases.inspect end # # add more threads to keep track of more hosts, but limit the size - $thread_pool_size = $thread_pool_size * $hosts.length - if $thread_pool_size > 60 - $thread_pool_size = 60 - end +# TODO $thread_pool_size = $thread_pool_size * $hosts.length +# if $thread_pool_size > 60 +# $thread_pool_size = 60 +# end # # stop Forefront Endpoint Protection and windows search service/indexer @@ -860,11 +871,12 @@ if __FILE__ == $0 require 'time' + # lock hosts with PFTT Server (if available) so they aren't used by two PFTT clients at same time + lock_all($hosts) + start_time = Time.now() begin - # lock hosts with PFTT Server (if available) so they aren't used by two PFTT clients at same time - lock_all($hosts) - + # if func_full automatically do host configuration if CONFIG[:action] == 'func_full' host_config @@ -880,14 +892,31 @@ if __FILE__ == $0 # iterate over all hosts, middlewares, etc..., running all tests for each test_ctx = test_bench.iterate( $phps, $hosts, $middlewares, $scenarios, $testcases ) + end_time = Time.now() + run_time = end_time - start_time + + # + # reboot remote hosts to clean them up for next time + unless CONFIG[:action] == 'func_part' + $hosts.each do |host| + if host.instance_of?(Host::Remote::Base) + if host.windows? + host.exec!('shutdown /r /t 0') + else + host.exec!('shutdown -r -t 0') + end + + sleep(5) + end + end + end + # ensure # ensure hosts are unlocked release_all($hosts) - + # end - end_time = Time.now() - run_time = end_time - start_time - + # ensure if CONFIG[:action] == 'func_full' # restart wsearch on hosts where it was already running (also, restart MsMpEng.exe) @@ -937,7 +966,7 @@ if __FILE__ == $0 end # # - + exit elsif CONFIG[:action] == 'func_inspect' # inspects what the configuration and arguments will have pftt do for the func_full or func_part actions diff --git a/PFTT/lib/diff.rb b/PFTT/lib/diff.rb index 65ef6e0..8f65abe 100644 --- a/PFTT/lib/diff.rb +++ b/PFTT/lib/diff.rb @@ -1,5 +1,6 @@ require 'abstract_class' +require 'iconv' module Diff class Base @@ -12,6 +13,8 @@ module Diff @middleware = middleware @scn_set = scn_set @php = php + + @iconv = Iconv.new('US-ASCII//IGNORE', 'UTF-8') end def to_s @@ -20,7 +23,8 @@ module Diff when :insert then '+' when :delete then '-' else '' - end + (String.not_nil(line[(line[0]==:delete)?3:1])).gsub(/\n\Z/,'') + # use iconv to fix character encoding problems + end + (@iconv.conv(String.not_nil(line[(line[0]==:delete)?3:1])).gsub(/\n\Z/,'')) end.join("\n") end @@ -666,7 +670,7 @@ module Diff # the order matters because %string% must be replaced before %s. patterns(rex) - return super( rex, result ) or super( rex, result.rstrip.chomp ) + super( rex, result ) or super( rex, result.rstrip.chomp ) end end @@ -697,13 +701,13 @@ module Diff class Php5 < Formatted def patterns(rex) - super(rex) - rex.gsub!('%u\|b%', '') - rex.gsub!('%b\|%u', '') #PHP6+: 'u' - rex.gsub!('%binary_string_optional%', 'string') #PHP6+: 'binary_string' rex.gsub!('%unicode_string_optional%', 'string') #PHP6+: 'Unicode string' + rex.gsub!('%binary_string_optional%', 'string') #PHP6+: 'binary_string' rex.gsub!('%unicode\|string%', 'string') #PHP6+: 'unicode' rex.gsub!('%string\|unicode%', 'string') #PHP6+: 'unicode' + rex.gsub!('%u\|b%', '') + rex.gsub!('%b\|%u', '') #PHP6+: 'u' + super(rex) end def show_expect_info @@ -718,13 +722,13 @@ module Diff class Php6 < Formatted def patterns(rex) - super(rex) - rex.gsub!('%u\|b%', 'u') - rex.gsub!('%b\|%u', 'u') #PHP6+: 'u' - rex.gsub!('%binary_string_optional%', 'binary_string') #PHP6+: 'binary_string' rex.gsub!('%unicode_string_optional%', 'Unicode string') #PHP6+: 'Unicode string' + rex.gsub!('%binary_string_optional%', 'binary_string') #PHP6+: 'binary_string' rex.gsub!('%unicode\|string%', 'unicode') #PHP6+: 'unicode' rex.gsub!('%string\|unicode%', 'unicode') #PHP6+: 'unicode' + rex.gsub!('%u\|b%', 'u') + rex.gsub!('%b\|%u', 'u') #PHP6+: 'u' + super(rex) end def show_expect_info diff --git a/PFTT/lib/host.rb b/PFTT/lib/host.rb index 3dc8e1f..7e1a7d7 100644 --- a/PFTT/lib/host.rb +++ b/PFTT/lib/host.rb @@ -332,7 +332,7 @@ module Host unless @_name # find a name that other hosts on the network will use to reference localhost if windows? - @_name = line!('echo %COMPUTERNAME%') + @_name = unquote_line!('echo %COMPUTERNAME%') else @_name = line!('echo $HOSTNAME') end diff --git a/PFTT/lib/middleware.rb b/PFTT/lib/middleware.rb index d14695c..681698a 100644 --- a/PFTT/lib/middleware.rb +++ b/PFTT/lib/middleware.rb @@ -18,6 +18,14 @@ module Middleware @host.close end + def self.to_s + mw_name + end + + def to_s + mw_name + end + def ==(o) return self.class == o.class end @@ -48,7 +56,7 @@ module Middleware # ask scenarios for the folder to deploy PHP to deploy_to = nil - @scenarios.map{|scn_type, scn| deploy_to||= scn.deployed_php(self) } + # TODO @scenarios.map{|scn_type, scn| deploy_to||= scn.deployed_php(self) } unless deploy_to # fallback on storing php in a sub-folder in %SYSTEMDRIVE%/php-sdk/PFTT-PHPs or ~/php-sdk/PFTT-PHPs @@ -64,7 +72,7 @@ module Middleware # if $force_deploy, make a new directory! otherwise, reuse existing directory (for quick manual testing can't take the time # to copy everything again) - @deployed_php ||= @host.join(deploy_to, ( @php_build[:version] + ( $force_deploy ? '_'+String.random(4) : '' ) ) ) + @deployed_php ||= @host.join(deploy_to, ( @php_build[:version] + ((@php_build[:threadsafe])?'-TS':'-NTS') + ( $force_deploy ? '_'+String.random(4) : '' ) ) ) # if $force_deploy or not File.exists?(php_binary()) or File.mtime(@php_build.path) >= File.mtime(php_binary()) @@ -93,11 +101,11 @@ module Middleware apply_ini(@current_ini) # ask scenarios to add anything they need to this INI - scn_set.ini(platform, @current_ini) + # TODO scn_set.ini(platform, @current_ini) @current_ini end - + def uninstall r=nil _undeploy_php_bin unset_ini diff --git a/PFTT/lib/middleware/cli.rb b/PFTT/lib/middleware/cli.rb index 32b6617..bfa447b 100644 --- a/PFTT/lib/middleware/cli.rb +++ b/PFTT/lib/middleware/cli.rb @@ -12,6 +12,18 @@ module Middleware 'CLI' end + def start! + # nothing to do + end + + def stop! + # nothing to do + end + + def running? + true + end + def clone clone = Middleware::Cli.new(@host.clone, @php_build, @scenarios) clone.deployed_php = @deployed_php @@ -50,7 +62,7 @@ module Middleware # tell scenarios that script is about to be started # scenarios may modify env or current_ini - scenarios.execute_script_start(env, test, script_type, deployed_script, self.php_binary, @php_build, current_ini, @host ) + # TODO scenarios.execute_script_start(env, test, script_type, deployed_script, self.php_binary, @php_build, current_ini, @host ) # generate options for the command execution exe_options = { @@ -81,7 +93,7 @@ module Middleware ].flatten.compact.join(' ') # save (in telemetry folder) the environment variables and the command line string used to run this case case - save_cmd(test_case, env, exe_options[:chdir], cmd_string) + # TODO save_cmd(test_case, env, exe_options[:chdir], cmd_string) # feed in stdin string if present to PHP's standard input if test_case.parts.has_key?(:stdin) @@ -94,7 +106,7 @@ module Middleware # tell scenarios that script has stopped - scenarios.execute_script_stop(test, script_type, deployed_script, self.php_binary, @php_build, @host) + # TODO scenarios.execute_script_stop(test, script_type, deployed_script, self.php_binary, @php_build, @host) # return success|failure and the output [s==0, (o+e)] @@ -104,7 +116,7 @@ module Middleware # saves the command line and environment variables to run the test case into a telemetry folder file # (save as a shell script or batch script) - def save_cmd(test_case, env, chdir, cmd_string) + def save_cmd(test_case, env, chdir, cmd_string) file_name = telemetry_folder(@host, @php, @middleware, @scenarios) + '/' + test_case.relative_path+((@host.windows?)?'.cmd':'.sh') File.open(file_name, 'wb') do |f| if host.posix? diff --git a/PFTT/lib/middleware/http.rb b/PFTT/lib/middleware/http.rb index ca0e7f2..6c9ad13 100644 --- a/PFTT/lib/middleware/http.rb +++ b/PFTT/lib/middleware/http.rb @@ -19,7 +19,7 @@ module Middleware @host.write( current_ini.to_a.join("\n"), ini_file ) true else - false + false end end @@ -36,7 +36,7 @@ module Middleware end def execute_php_script deployed_script, test_case, script_type, scenarios - scenarios.execute_script_start(env, test, script_type, deployed_script, self.php_binary, @php_build, current_ini, @host ) + # TODO scenarios.execute_script_start(env, test, script_type, deployed_script, self.php_binary, @php_build, current_ini, @host ) # send HTTP GET request to web server (middleware) asking it to execute the script # then compare the returned document just as is done for locally executed PHPT script (CLI middleware) @@ -51,17 +51,19 @@ module Middleware url = URI.parse(url) + http = Net::HTTP.new('127.0.0.1', 80) # TODO 80 + if test_case.parts.has_key?(:post_raw) - response = post(request, test_case, http, test_case.parts[:post_raw], url, nil, false) + response = post(test_case, http, test_case.parts[:post_raw], url, nil, false) elsif test_case.parts.has_key?(:post) - response = post(request, test_case, http, test_case.parts[:post_raw], url, 'application/x-www-form-urlencoded', true) + response = post(test_case, http, test_case.parts[:post_raw], url, 'application/x-www-form-urlencoded', true) elsif test_case.parts.has_key?(:gzip_post) - response = post(request, test_case, http, test_case.parts[:post_raw], url, 'gzip', true) + response = post(test_case, http, test_case.parts[:post_raw], url, 'gzip', true) elsif test_case.parts.has_key?(:deflate_post) - response = post(request, test_case, http, test_case.parts[:post_raw], url, 'deflate', true) + response = post(test_case, http, test_case.parts[:post_raw], url, 'deflate', true) else # for --GET-- - response = get(request, test_case, http, url) + response = get(test_case, http, url) end # @@ -99,22 +101,22 @@ module Middleware protected def cookie(request, test_case) - if test_case.parts.has_key(:cookie) + if test_case.parts.has_key?(:cookie) request['Set-Cookie'] = test_case.parts[:cookie] end end def headers(request, test_case) - if test_case.parts.has_key(:header) - test_case.http_headers(Middleware::Cli.new(@host, @php, @scenarios)) do |name, value| + if test_case.parts.has_key?(:header) + test_case.http_headers(mw_cli) do |name, value| request[name] = value end end end # do POST GZIP_POST DEFLATE_POST POST_RAW (add_content_type=false) section - def post(request, test_case, http, data, url, content_type, add_content_type=true) - request = Net::HTTP::Post.new(url) + def post(test_case, http, data, url, content_type, add_content_type=true) + request = Net::HTTP::Post.new(url.request_uri) if add_content_type request['Content-Type'] = content_type end @@ -127,19 +129,24 @@ module Middleware end # do GET section - def get(request, test_case, http, url) + def get(test_case, http, url) if test_case.parts.has_key?(:get) # add the query part of the URL url += '?' + test_case.parts[:get] end - request = Net::HTTP::Get.new(url) + request = Net::HTTP::Get.new(url.request_uri) cookie(request, test_case) headers(request, test_case) http.request(request) end + + def mw_cli + # need CLI to execute some sections of some PHPTs + @cli ||= Middleware::Cli.new(@host, @php, @scenarios) + end end end diff --git a/PFTT/lib/phpt_test_case.rb b/PFTT/lib/phpt_test_case.rb index 561da3c..c4f76e2 100644 --- a/PFTT/lib/phpt_test_case.rb +++ b/PFTT/lib/phpt_test_case.rb @@ -316,20 +316,20 @@ class PhptTestCase @bork_reasons << 'missing required section:'+group.to_s end end - counte = (parts.has_key?(:expect)) ? 1 : 0 - counte += (parts.has_key?(:expectf)) ? 1 : 0 - counte += (parts.has_key?(:expectregex)) ? 1 : 0 - if counte > 0 - @bork_reasons << 'can only have one EXPECT or EXPECTF or EXPECTREGEX section, not '+counte.to_s - end - counth = (parts.has_key?(:get)) ? 1 : 0 - counth = (parts.has_key?(:post)) ? 1 : 0 - counth = (parts.has_key?(:post_raw)) ? 1 : 0 - counth = (parts.has_key?(:gzip_post)) ? 1 : 0 - counth = (parts.has_key?(:deflate_post)) ? 1 : 0 - if counth > 0 - @bork_reasons << 'can only have one GET, POST, POST_RAW, GZIP_POST or DEFLATE_POST section, not '+counth.to_s - end +# TODO counte = (parts.has_key?(:expect)) ? 1 : 0 +# counte += (parts.has_key?(:expectf)) ? 1 : 0 +# counte += (parts.has_key?(:expectregex)) ? 1 : 0 +# if counte > 0 +# @bork_reasons << 'can only have one EXPECT or EXPECTF or EXPECTREGEX section, not '+counte.to_s +# end +# counth = (parts.has_key?(:get)) ? 1 : 0 +# counth = (parts.has_key?(:post)) ? 1 : 0 +# counth = (parts.has_key?(:post_raw)) ? 1 : 0 +# counth = (parts.has_key?(:gzip_post)) ? 1 : 0 +# counth = (parts.has_key?(:deflate_post)) ? 1 : 0 +# if counth > 0 +# @bork_reasons << 'can only have one GET, POST, POST_RAW, GZIP_POST or DEFLATE_POST section, not '+counth.to_s +# end end !@bork_reasons.length.zero? end @@ -395,15 +395,15 @@ class PhptTestCase parts.inspect end - def raw(deploy_dir) - @raw ||= IO.read(File.join(deploy_dir, full_name)) + def raw() + @raw ||= IO.read(File.join('c:/php-sdk/svn/branches/php_5_4/', full_name)) # TODO phptdir end - def parse!(deploy_dir) + def parse!() reset! @result_tester = nil section = :none - raw(deploy_dir).lines do |line| + raw().lines do |line| if line =~ /^--(?<section>[A-Z_]+)--/ section = Regexp.last_match[:section].downcase.to_sym @parts[section]='' @@ -424,7 +424,7 @@ class PhptTestCase @parts[:file].gsub!(%Q{\r\n},%Q{\n}) unless @parts[:file].nil? end - protected + # TODO protected def reset! @parts = {} @@ -432,7 +432,7 @@ class PhptTestCase @options = nil end - private + # TODO private def parse_line( line, context ) return line unless line =~ /^\#\!?include (?<script>.*)/ @@ -479,27 +479,31 @@ class PhptTestCase::Array < TypedArray(PhptTestCase) end } end - + #tests_names = ['math/abs'] # TODO # search each directory for PHPT files - paths.map{|path| + paths.map do |path| Dir.glob( File.join( path, '**/*.phpt' ) ).each do |files| if test_names != nil and test_names.length > 0 - test_names.each{|test_name| + test_names.each do |test_name| + # internally, ruby always uses / for filenames (check for / not \) + test_name.gsub!('\\', '/') +# puts files.inspect +# puts test_name.inspect if files.is_a?(Array) - files.each{|file| + files.each do |file| if file.include?(test_name) add_selected_file(path, file) end - } + end elsif files.include?(test_name) add_selected_file(path, files) end - } + end else add_selected_file(path, files) end end - } + end @selected = nil self end @@ -507,9 +511,10 @@ class PhptTestCase::Array < TypedArray(PhptTestCase) class DuplicateTestError < StandardError end - private + # TODO private def add_selected_file(dir, file) + #puts file file = File.absolute_path(file) if file.starts_with?(dir) file = file[dir.length+1...file.length] diff --git a/PFTT/lib/phpt_test_result.rb b/PFTT/lib/phpt_test_result.rb index 943cee0..cf1d388 100644 --- a/PFTT/lib/phpt_test_result.rb +++ b/PFTT/lib/phpt_test_result.rb @@ -1,15 +1,16 @@ module PhptTestResult class Base - def initialize( test_case, test_bench, deploydir ) + def initialize( test_case, test_bench, deploydir, php ) @test_case = test_case @test_bench = test_bench - files['phpt'] = @test_case.raw(deploydir) + @php = php + files['phpt'] = @test_case.raw()# TODO deploydir) self end attr_reader :test_case, :test_bench - attr_accessor :status + attr_accessor :status def to_s %Q{[#{status.to_s.upcase}] #{@test_bench} #{@test_case.relative_path}} @@ -109,13 +110,12 @@ module PhptTestResult @filtered_expectation, @filtered_result = [@test_case.expectation[:content], result_str].map do |str| str.gsub("\r\n","\n").strip end - @diff = nil @diff_spec = (case @test_case.expectation[:type] when :expect then Diff::Exact when :expectregex then Diff::RegExp when :expectf - case php.properties[:php_version_major] + case @php.properties[:php_version_major] when 5 then Diff::Formatted::Php5 when 6 then Diff::Formatted::Php6 else Diff::Formatted diff --git a/PFTT/lib/report/inspect/func.rb b/PFTT/lib/report/inspect/func.rb index aaadcef..db8b130 100644 --- a/PFTT/lib/report/inspect/func.rb +++ b/PFTT/lib/report/inspect/func.rb @@ -1,7 +1,7 @@ module Report module Inspect - class Func + class Func < Base def initialize(test_cases) @test_cases = test_cases end @@ -9,17 +9,17 @@ module Report str = "\r\n" unless $brief_output - str += 'PHPTs('+test_cases.length+'):' + str += 'PHPTs('+@test_cases.length.to_s+"):\r\n" - test_cases.each do test_case + @test_cases.each do |test_case| str += test_case.full_name + "\r\n" end str += "\r\n" end - str += "HOSTS#{$hosts.length}):\r\n" - str += puts_or_empty($hosts) + str += "HOSTS(#{$hosts.length}):\r\n" + str += puts_or_empty($hosts) if $phps.empty? str += "PFTT: suggestion: run 'pftt get_php' to get a PHP binary build to test\r\n" @@ -32,21 +32,26 @@ module Report str += "MIDDLEWARES(#{$middlewares.length}):\r\n" str += puts_or_empty($middlewares) - flat_scenarios = $scenarios.values.flatten + flat_scenarios = $scenarios#[0].values# TODO [0] .values.flatten - str += "CONTEXTS(#{flat_scenarios.length}):\r\n" + str += "SCENARIO SETS(#{flat_scenarios.length}):\r\n" str += puts_or_empty(flat_scenarios) str += "\r\n" + str end protected def puts_or_empty array if array.empty? - return '<None>' + return "<None>\r\n\r\n" else - return array.to_s + str = "" + array.each do |e| + str += e.to_s+"\r\n" + end + return str+"\r\n" end end diff --git a/PFTT/lib/report/run/by_host/by_build/by_middleware/func.rb b/PFTT/lib/report/run/by_host/by_build/by_middleware/func.rb index 169c286..14243bc 100644 --- a/PFTT/lib/report/run/by_host/by_build/by_middleware/func.rb +++ b/PFTT/lib/report/run/by_host/by_build/by_middleware/func.rb @@ -21,7 +21,7 @@ module Report # str = "\r\n" - + str += " === Test Run Completed === \r\n" str += "\r\n" diff --git a/PFTT/lib/scenario.rb b/PFTT/lib/scenario.rb index 0ab0e99..276a868 100644 --- a/PFTT/lib/scenario.rb +++ b/PFTT/lib/scenario.rb @@ -30,6 +30,10 @@ module Scenario return :unknown end + def to_s + scn_name + end + def self.instantiable All << self end diff --git a/PFTT/lib/scenario/set.rb b/PFTT/lib/scenario/set.rb index a1021f1..3edc949 100644 --- a/PFTT/lib/scenario/set.rb +++ b/PFTT/lib/scenario/set.rb @@ -9,6 +9,7 @@ module Scenario def initialize(id, working_filesystem_scenario, *optional_other_scenarios) @id = id + @working_fs = working_filesystem_scenario optional_other_scenarios.each do |scenario| case scenario.scn_type when :remote_file_system @@ -65,6 +66,10 @@ module Scenario end end + def to_s + "[Set #{@id} #{values.inspect}]" + end + def == (o) o.instance_of?(Scenario::Set) and o.id == @id end diff --git a/PFTT/lib/server/snapshot_getter.rb b/PFTT/lib/server/snapshot_getter.rb index 7060069..142eb27 100644 --- a/PFTT/lib/server/snapshot_getter.rb +++ b/PFTT/lib/server/snapshot_getter.rb @@ -130,7 +130,7 @@ module Server end # def scrape_snapshot_urls def download_file_to_local(remote_url) - local_filename = ((@localhost.windows?)?@localhost.systemdrive+'/PFTT-PHPS/':'~/PFTT-PHPS')+File.basename(remote_url) + local_filename = ((@localhost.windows?)?@localhost.systemdrive+'/php-sdk/builds/':'~/php-sdk/builds/')+File.basename(remote_url) local_dir = local_filename # local dir should be same as local filename of ZIP without the .zip diff --git a/PFTT/lib/test_bench.rb b/PFTT/lib/test_bench.rb index ed83638..23beb77 100644 --- a/PFTT/lib/test_bench.rb +++ b/PFTT/lib/test_bench.rb @@ -59,42 +59,43 @@ module TestBench # provide a hash to the iteration (ex scenarios[:file_system] should have 1 scenario (not array) within the iteration) # input: takes in a a structure like this # {:working_file_system=>[#<Scenario::FileSystem::Smb:0x32ee198>], :database=>[#<Scenario::Database::Mysql::Tcp:0x329b218>]} - scenario_values = scenarios.values.flatten + scenario_values = scenarios# TODO ? .values.flatten # except for :working_file_system, try each combination with no scenarios of that type too (+scenarios.keys.length-1) - cg = CombinationGenerator.new(scenario_values.length+scenarios.keys.length-1, scenarios.keys.length) - scenarios = [] - while cg.hasMore do - idicies = cg.getNext() - - scn_set = {} - skip_set = false - idicies.each do |idx| - if idx >= scenario_values.length - # if here, this is a combination that is meant to not include any of a particular scenario type - next - end - scn = scenario_values[idx] - - if scn_set.has_key? scn.scn_type - skip_set = true - break - else - scn_set[scn.scn_type] = scn - end - end - unless skip_set - scenarios.push(scn_set) - end - end +# TODO cg = CombinationGenerator.new(scenario_values.length+scenarios.keys.length-1, scenarios.keys.length) +# scenarios = [] +# while cg.hasMore do +# idicies = cg.getNext() +# +# scn_set = {} +# skip_set = false +# idicies.each do |idx| +# if idx >= scenario_values.length +# # if here, this is a combination that is meant to not include any of a particular scenario type +# next +# end +# scn = scenario_values[idx] +# +# if scn_set.has_key? scn.scn_type +# skip_set = true +# break +# else +# scn_set[scn.scn_type] = scn +# end +# end +# unless skip_set +# scenarios.push(scn_set) +# end +# end # output: produces a new structure like this # [{:working_file_system=>#<Scenario::FileSystem::Smb:0x32ee198>, :database=>#<Scenario::Database::Mysql::Tcp:0x329b218>}, # {:working_file_system=>#<Scenario::FileSystem::Smb:0x32ee198>, :database=>#<Scenario::Database::Mysql::Ssl:0x3297408>}, {:file_system=>#<Context::FileSystem::Http:0x32e8150>, # # + scenarios = scenario_values # TODO final_test_cases = [] - test_ctx = TestBenchRunContext.new(self, test_cases.flatten.length, final_test_cases) + test_ctx = TestBenchRunContext.new(self, test_cases.flatten.length, test_cases.flatten, final_test_cases) hosts.each do |host| @@ -109,6 +110,11 @@ module TestBench # test_ctx.show_label_legend + + if test_cases.empty? + # no point in deploying, installing, uninstalling, and tearing down + return test_ctx + end # iterate over all scenario sets (where there is one instance of each scenario type (file system, database)) @@ -125,27 +131,36 @@ module TestBench next end - @test_bench.install(scn_set[:working_file_system], middleware) + install(scn_set.working_fs, middleware) + + # tell middleware to start (ex: start IIS) + middleware.start! - test_ctx.create_entries(host, middleware, php, scn_set) + test_ctx.create_entries(host, middleware, php, scn_set, test_cases) - middlewares_uninstall.push([scn_set[:working_file_system], middleware]) + middlewares_uninstall.push([scn_set.working_fs, middleware]) end end end end # execute each, use a pool of worker threads to consume all test case-scenario-host-build-middleware combinations - run(final_test_cases, test_ctx) + unless final_test_cases.empty? + run(final_test_cases, test_ctx) + end # do uninstall middlewares_uninstall.each do |params| + # tell middleware to stop (ex: shutdown IIS) + params[1].stop! + uninstall(params[0], params[1]) end # teardown scenarios on each host hosts.each do |host| scenarios.each do |scn_set| + # TODO where is deploy ?? scn_set.teardown(host) end end @@ -302,8 +317,9 @@ module TestBench class TestBenchRunContext < ResultsContext attr_reader :tr, :test_case_len, :semaphore1, :semaphore2, :semaphore3, :semaphore4, :semaphore5, :chunk_replacement - def initialize(test_bench, test_case_len, final_test_cases) + def initialize(test_bench, test_case_len, test_cases, final_test_cases) @final_test_cases = final_test_cases + @test_cases = test_cases @tr = $auto_triage ? Diff::Base::TriageResults.new() : nil @test_bench = test_bench @@ -361,7 +377,7 @@ module TestBench host_name_i = host_name.length - 1 while host_name_i >= 0 - name = ( scn_id[scn_id_i] + host_name[host_name_i] + mw_name[mw_name_i] + version ).upcase + name = ( scn_id[scn_id_i] + mw_name[mw_name_i] + version + host_name[host_name_i] ).upcase unless @labels.has_key?(name) set_label(host, middleware, host_name, php, mw_name, scn_set, name) @@ -398,7 +414,7 @@ module TestBench @labels.keys.each do |label| host_name, php, mw_name, scn_set = @labels[label] - puts " #{label} - #{host_name} #{mw_name} #{php.to_s} Scenario #[scn_set.id}" + puts " #{label} - Scenario #{scn_set.id} #{mw_name} #{php.to_s} #{host_name} " end puts @@ -439,9 +455,9 @@ module TestBench results = @results[host][middleware][php][scn_set] = PhptTestResult::Array.new() end - if results.length > @test_case_len - raise 'TooManyResultsError' # shouldn't happen - end +# TODO if results.length > @test_case_len +# raise 'TooManyResultsError' # shouldn't happen +# end results.push(result) @@ -457,7 +473,7 @@ module TestBench # user can follow telemetry in real-time label = legend_label(host, php, middleware, scn_set) - console_out(" [#{label}] #{tf}") + console_out(" [#{label}] Telemetry #{tf}") end @semaphore5.synchronize do @@ -466,7 +482,7 @@ module TestBench end if do_finished_host_build_middleware_scenarios - report = @test_bench.finished_host_build_middleware_scenarios(self, tf, host, php, middleware, scenarios, results) + report = @test_bench.finished_host_build_middleware_scenarios(self, tf, host, php, middleware, scn_set, results) @semaphore4.synchronize do # write list of scenarios tested @@ -516,7 +532,7 @@ module TestBench @labels2[host].keys.each do |mw_spec| @labels2[host][mw_spec].keys.each do |php| @labels2[host][mw_spec][php].keys.each do |scn_set| - create_entries(host, mw_spec.new(host, php, scn_set), scn_set) + create_entries(host, mw_spec.new(host, php, scn_set), php, scn_set, test_cases) end end end @@ -544,18 +560,18 @@ module TestBench # 1. delete any remaining entries for this combo delete_entries(host, middleware, scn_set, php) # 2. recreate all of them - create_entries(host, middleware, scn_set) + create_entries(host, middleware, php, scn_set, @test_cases) end def create_entries(host, middleware, php, scn_set, test_cases) - test_cases.each do |test_case| + test_cases.flatten.each do |test_case| # TODO flatten # make sure the test case is compatible too - unless test_case.compatible(host, middleware, php, scn_set) - next - end +# TODO unless test_case.compatible?(host, middleware, php, scn_set) +# next +# end - @final_test_cases.push({:test_case=>test_case, :host=>host, :php=>php, :middleware=>middleware, :scenarios=>scenarios}) + @final_test_cases.push({:test_case=>test_case, :host=>host, :php=>php, :middleware=>middleware, :scenarios=>scn_set}) end end diff --git a/PFTT/lib/test_bench/phpt.rb b/PFTT/lib/test_bench/phpt.rb index fd5202b..dbe5b1c 100644 --- a/PFTT/lib/test_bench/phpt.rb +++ b/PFTT/lib/test_bench/phpt.rb @@ -38,21 +38,25 @@ module TestBench single_thread_test_cases = [] # - # TODO - scenarios = test_case_sets[0][:scenarios][0] + # TODO + #puts test_case_sets.inspect + scn_set = test_case_sets[0][:scenarios]#.values - fs_scn = scenarios[:working_file_system] + #fs_scn = test_case_sets[0][:scenarios].working_fs# TODO [:working_file_system] host = test_case_sets[0][:host] middleware = test_case_sets[0][:middleware] middleware.host = host php = test_case_sets[0][:php] test_cases = test_case_sets#[0] +# if test_cases.is_a?(Array) +# test_cases = test_cases.first # TODO +# end # # create a temporary directory to deploy to. the working filesystem scenario will # decide where (either a local directory, remote SMB share, etc...) - deploy_root = fs_scn.docroot(middleware) + deploy_root = scn_set.working_fs.docroot(middleware) if $force_deploy tmpdir = host.mktmpdir(deploy_root) else @@ -63,18 +67,19 @@ module TestBench # run PHPTs in place unless $force_deploy (only true for the 'func_full' command or --force-deploy argument to 'func_part' command) # parse all the phpt's and upload the files at the same time. uploader = Thread.start{ - if $force_deploy or not host.exist?(tmpdir) - puts 'uploading '+fs_scn.to_s; - host.upload test_cases.path, tmpdir; - puts 'uploaded.' - end +# TODO if $force_deploy or not host.exist?(tmpdir) +# puts 'uploading '+scn_set.working_fs.to_s; +# host.upload test_cases.path, tmpdir; # +# puts 'uploaded.' +# end } test_cases.each do |entry| - entry[:test_case].parse!(tmpdir) + #puts entry.inspect + entry[:test_case].parse!()#tmpdir) end # note: each test_case is an instance of PhptTestCase - puts %Q{selected #{test_cases.size} test cases} + puts %Q{selected #{test_ctx.test_case_len} test cases} puts # wait... does deployment and test case parsing at same time. @@ -143,16 +148,16 @@ module TestBench # # see PhpTestResult::Array#generate_stats - test_case.scn_list = scenarios + test_case.scn_list = scn_set#scenarios # run the test case! if $pftt_debug - run_do_single_test_case(php, host, middleware, tmpdir, deployed, skip_if_code_cache, skip_if_result_cache, test_ctx, test_cases, test_case, fs_scn, scenarios) + run_do_single_test_case(php, host, middleware, tmpdir, deployed, skip_if_code_cache, skip_if_result_cache, test_ctx, test_cases, test_case, scn_set) else begin - run_do_single_test_case(php, host, middleware, tmpdir, deployed, skip_if_code_cache, skip_if_result_cache, test_ctx, test_cases, test_case, fs_scn, scenarios) + run_do_single_test_case(php, host, middleware, tmpdir, deployed, skip_if_code_cache, skip_if_result_cache, test_ctx, test_cases, test_case, scn_set) rescue - test_ctx.add_exception(host, php, middleware, scenarios, $!) + test_ctx.add_exception(host, php, middleware, scn_set, $!) end end @@ -204,8 +209,8 @@ module TestBench # end # end def run - def run_do_single_test_case(php, host, middleware, tmpdir, deployed, skip_if_code_cache, skip_if_result_cache, test_ctx, test_cases, test_case, fs_scn, scenarios) - do_single_test_case(php, host, middleware, tmpdir, deployed, skip_if_code_cache, skip_if_result_cache, test_ctx, test_cases, test_case, tmpdir, fs_scn, scenarios) + def run_do_single_test_case(php, host, middleware, tmpdir, deployed, skip_if_code_cache, skip_if_result_cache, test_ctx, test_cases, test_case, scn_set) + do_single_test_case(php, host, middleware, tmpdir, deployed, skip_if_code_cache, skip_if_result_cache, test_ctx, test_cases, test_case, tmpdir, scn_set) end def write_ext_file(telemetry_folder, ext_list, file_name) @@ -223,14 +228,14 @@ module TestBench f.close() end - def finished_host_build_middleware_scenarios(test_ctx, telemetry_folder, host, php, middleware, scenarios, r) + def finished_host_build_middleware_scenarios(test_ctx, telemetry_folder, host, php, middleware, scn_set, r) r.telemetry_folder = telemetry_folder # ensure report = Report::Run::PerHost::PerBuild::PerMiddleware::Func.new(host, php, middleware, r) # generate a combined INI for all scenarios for both platforms - r.windows_ini = middleware.create_ini(scenarios, :windows) - r.posix_ini = middleware.create_ini(scenarios, :posix) + r.windows_ini = middleware.create_ini(scn_set, :windows) + r.posix_ini = middleware.create_ini(scn_set, :posix) ini_f = File.open(File.join(telemetry_folder, 'Posix.ini'), 'wb') ini_f.puts(r.posix_ini.to_s) @@ -248,7 +253,7 @@ module TestBench return report end - def do_single_test_case(php, host, middleware, deploydir, deployed, skip_if_code_cache, skip_if_result_cache, test_ctx, test_cases, test_case, tmpdir, fs_scn, scenarios) + def do_single_test_case(php, host, middleware, deploydir, deployed, skip_if_code_cache, skip_if_result_cache, test_ctx, test_cases, test_case, tmpdir, scn_set) tmiddleware = middleware.clone # @@ -256,7 +261,7 @@ module TestBench # see http://qa.php.net/phpt_details.php#redirecttest_section if test_case.parts.has_key?(:redirecttest) # #mw_redirecttest requires a Middleware::Cli - redirect_tests = test_case.mw_redirecttest(tmiddleware.instance_of(Middleware::Cli)?tmiddleware:Middleware::Cli.new(host, php, scenarios)) + redirect_tests = test_case.mw_redirecttest(tmiddleware.instance_of(Middleware::Cli)?tmiddleware:Middleware::Cli.new(host, php, scn_set)) unless redirect_tests.empty? test_ctx.add_tests(redirect_tests) return # don't run the rest of this test case @@ -302,7 +307,7 @@ module TestBench begin # run SKIPIF script - skipif = tmiddleware.execute_php_script(deployed[:skipif], test_case, :skipif, scenarios)[1] + skipif = tmiddleware.execute_php_script(deployed[:skipif], test_case, :skipif, scn_set)[1] # evaluate the result to see if we're supposed to skip this test check_skipif = skipif.downcase # preserve original skipif result @@ -355,13 +360,13 @@ module TestBench out_err = '' if $pftt_debug - out_err = do_single_test_case_execute(deployed, test_case, scenarios) + out_err = do_single_test_case_execute(deployed, test_case, scn_set, tmiddleware) else begin - out_err = do_single_test_case_execute(deployed, test_case, scenarios) + out_err = do_single_test_case_execute(deployed, test_case, scn_set, tmiddleware) rescue - test_ctx.add_exception(host, php, middleware, scenarios, $!) + test_ctx.add_exception(host, php, middleware, scn_set, $!) end end @@ -389,41 +394,41 @@ module TestBench # # display, report and store result of this test case if $pftt_debug - do_single_test_case_result(test_ctx, host, php, middleware, test_case, deploydir, result_spec) + do_single_test_case_result(test_ctx, host, php, middleware, scn_set, test_case, deploydir, result_spec) else begin - do_single_test_case_result(test_ctx, host, php, middleware, test_case, deploydir, result_spec) + do_single_test_case_result(test_ctx, host, php, middleware, scn_set, test_case, deploydir, result_spec) rescue end end # end # def do_single_test_case - def do_single_test_case_execute(deployed, test_case, scenarios) - return tmiddleware.execute_php_script( deployed[:file], test_case, :test, scenarios )[1] + def do_single_test_case_execute(deployed, test_case, scn_set, tmiddleware) + return tmiddleware.execute_php_script( deployed[:file], test_case, :test, scn_set )[1] end - def do_single_test_case_result(test_ctx, host, php, middleware, test_case, deploydir, result_spec) + def do_single_test_case_result(test_ctx, host, php, middleware, scn_set, test_case, deploydir, result_spec) result = nil test_ctx.semaphore2.synchronize do # don't modify result_spec, its cached/shared with other threads a = result_spec[0] # take the caught result and build the proper object out of it - result = a.new( test_case, self, deploydir, *result_spec[1...result_spec.length] ) + result = a.new( test_case, self, deploydir, php, *result_spec[1...result_spec.length] ) end if result # generate the diff here in the thread unlocked if result.is_a?(PhptTestResult::Meaningful) - result.generate_diff(test_ctx, host, middleware, php, scenarios, test_ctx.tr) + result.generate_diff(test_ctx, host, middleware, php, scn_set, test_ctx.tr) end # lookup Legend Label for this host/php/middleware combination - label = test_ctx.legend_label(host, php, middleware, scenarios) + label = test_ctx.legend_label(host, php, middleware, scn_set) test_ctx.console_out(" [#{label}] [#{result.status.to_s.upcase}] #{@self} #{test_case.relative_path}") - test_ctx.add_result(host, php, middleware, scenarios, result) + test_ctx.add_result(host, php, middleware, scn_set, result) end end diff --git a/PFTT/pftt b/PFTT/pftt new file mode 100644 index 0000000..71948af --- /dev/null +++ b/PFTT/pftt @@ -0,0 +1,3 @@ +#!/bin/sh +# TODO gem install bundler +bundle exec ruby _pftt.rb $* diff --git a/PFTT/pftt.cmd b/PFTT/pftt.cmd index 664defb..f32c8aa 100644 --- a/PFTT/pftt.cmd +++ b/PFTT/pftt.cmd @@ -1,2 +1,3 @@ @echo off +REM TODO gem install bundler bundle exec ruby _pftt.rb %* diff --git a/PFTT/pftt_server b/PFTT/pftt_server new file mode 100644 index 0000000..b1bd3ec --- /dev/null +++ b/PFTT/pftt_server @@ -0,0 +1,3 @@ +#!/bin/sh +# TODO gem install bundler +bundle exec ruby _pftt_server.rb $* diff --git a/PFTT/pftt_server.cmd b/PFTT/pftt_server.cmd index cc8c343..23783e9 100644 --- a/PFTT/pftt_server.cmd +++ b/PFTT/pftt_server.cmd @@ -1,2 +1,3 @@ @echo off +REM TODO gem install bundler bundle exec ruby _pftt_server.rb %* diff --git a/PFTT/scripts/SDK4Win/SetupPHPSDK.cmd b/PFTT/scripts/SDK4Win/SetupPHPSDK.cmd index 2f859aa..6421aaa 100644 --- a/PFTT/scripts/SDK4Win/SetupPHPSDK.cmd +++ b/PFTT/scripts/SDK4Win/SetupPHPSDK.cmd @@ -35,7 +35,7 @@ IF NOT EXIST %PFTT_RESULTS% MKDIR %PFTT_RESULTS% IF NOT EXIST %PFTT_SCRIPTS% MKDIR %PFTT_SCRIPTS% IF NOT EXIST %PFTT_PHPS% MKDIR %PFTT_PHPS% -set PATH=%PFTT_HOME%;%PFTT_HOME%\Scripts\SDK4Win\;%PATH% +set PATH=%PFTT_HOME%;%PFTT_HOME%\Scripts\SDK4Win\;%PATH%;%SYSTEMDRIVE%\Ruby192\bin REM "%ProgramFiles%\Microsoft SDKs\Windows\v7.0\Bin\SetEnv.cmd" /xp /x86 /release