#!/usr/bin/env ruby # Author:: The TTK Team. # Copyright:: Copyright (c) 2004, 2005 TTK team. All rights reserved. # License:: LGPL # $Id: ttk 611 2005-06-05 17:17:11Z ertai $ begin require 'pathname' require 'yaml' ME = Pathname.new($0).basename ME_DIR = Pathname.new(__FILE__).dirname $PROGRAME_NAME = ME $PROGRAME_NAME.freeze $VERBOSE = true # you can use 'export RUBYOPT="-w"' too require 'ostruct' require Pathname.new(__FILE__).dirname.parent + 'lib/ttk' SPEC_DYN_YML = ME_DIR + '..' + 'SPEC.dyn.yml' SPEC_DYN = YAML::load(SPEC_DYN_YML.read) TTK_VERSION = SPEC_DYN.version.to_s TTK_DATE = SPEC_DYN.date VERSION_PATH = ME_DIR + '..' + 'VERSION' require 'erb' TTK_VERSION_TEXT = ERB.new(VERSION_PATH.read, nil, '<%>').result(binding) require "#{ME_DIR}/getopts/ttk" argv = ARGV.dup opts = TTK::Getopts::TTK.parse(argv) require 'profile' if opts[:profile_on] unless opts[:no_default_observer] opts[:observers] << opts[:current_dumper].new(opts[:current_output]) end log_factory = TTK::LoggerFactory.new log_factory.severity_level = opts[:log_severity] log_factory.severity_level = ENV['TTK_DEBUG'] if ENV.has_key?('TTK_DEBUG') log_factory.verbosity_level = opts[:log_verbosity] log_factory.section_tree << TTK::Logger::SectionNode.new('basicObserver') log_factory.active_section = opts[:log_section] log = log_factory.create(*opts[:observers]) log.info_basicObserver do log.add_observer(TTK::Dumpers::Basic.new(STDERR)) nil end symtbl = TTK::SymTbl.new symtbl[:ttk] = Pathname.new($0).expand_path symtbl[:core_ex] = CoreEx.dir symtbl[:symtbl_class] = symtbl.class symtbl[:pwd] = Pathname.pwd.expand_path symtbl[:loader] = opts[:current_loader].new symtbl[:tester_uris] = opts[:tester_uris] symtbl.freeze_key(:tester_uris) symtbl[:force_fetch] = opts[:force_fetch] symtbl.freeze_key(:force_fetch) symtbl[:log_factory] = log_factory symtbl[:log] = log opts[:cache] ||= (opts[:cache_dir] == TempPath.tmpdir) symtbl[:cache] = {} if opts[:cache] symtbl[:cache_proc] = opts[:cache_proc] symtbl.freeze_key(:cache_proc) if opts[:current_input].nil? t = TTK::Strategies::Suite.new t.name = 'root' t.symtbl = symtbl t.wclass = opts[:wclass] t.attributes = opts[:attributes] t.symbols = opts[:symbols] t.contents = argv # Load the cache file if cache_dir is set. if cache_dir = opts[:cache_dir] cache = cache_dir + 'cache.yml' t.symtbl[:use_cache] = TTK::Loaders::Yaml.new.load(cache.read) end # Disable the automatic cleaning of TempPath for the cache mode. if opts[:cache] TempPath.auto_clean = false end # Run the root test. status = t.run # Generate the cache file. if opts[:cache] cache_file = TempPath.tmpdir + 'cache.yml' cache = t.symtbl[:cache] t.symtbl.local.delete :cache cache.each do |name, test| todel = [:use_cache] test[:symtbl].each do |k, v| if [SynFlow, SynFlowFactory].any? { |klass| v.is_a? klass } todel << k end end todel.each { |k| test[:symtbl].delete(k) } end cache_file.open('w') { |f| f.puts cache.to_yaml } end relaunch = TempPath.tmpdir + 'relaunch' if opts[:cache] # Update the argument for the cache mode ARGV.delete '-C' ARGV << '--cache-dir' << TempPath.tmpdir.to_s # Generate a little helper script to use the cache mode. unless relaunch.exist? relaunch.open('w') do |f| f.puts '#!/usr/bin/env ruby' f.puts <<-rb exec(#{$0.inspect}, *#{ARGV.inspect}) rb end relaunch.chmod(0500) end end log.close unless log.nil? if opts[:cache] or opts[:cache_dir] # Ask the user what to do. if ask('Would you relaunch the test suite now (use the cache)', :y) == :y exec relaunch.to_s else if ask('Would you remove the temporary dir', :y) == :y TempPath.auto_clean = true else STDERR.puts <<-msg --- /------------------------------------------------------------------. | TTK was running in cache mode to re-run the same test just type: | | #{relaunch.to_s.ljust(63)}| `------------------------------------------------------------------/ msg end end end # Handle the --dump-status option. STDOUT.puts status.to_yaml if opts[:dump_status] exit(2) unless status.pass? else symtbl[:loader].load(opts[:current_input]).to_ttk_log(log) end rescue Exception => ex TempPath.auto_clean = true if defined? TempPath Thread.critical = true if defined? Thread raise ex if ex.is_a? SystemExit if log.nil? msg = (ex.respond_to? :tiny_pp)? ex.tiny_pp : "#{ex.inspect}" STDERR.puts "ERROR:\n #{msg}" else log.error { ex } end exit(1) ensure log.close unless log.nil? end