class XCKnife::TestDumper

Attributes

logger[R]

Public Class Methods

invoke() click to toggle source
# File lib/xcknife/test_dumper.rb, line 17
def self.invoke
  new(ARGV).run
end
new(args, logger: Logger.new($stdout, progname: 'xcknife test dumper')) click to toggle source
# File lib/xcknife/test_dumper.rb, line 23
def initialize(args, logger: Logger.new($stdout, progname: 'xcknife test dumper'))
  @debug = false
  @max_retry_count = 150
  @temporary_output_folder = nil
  @xcscheme_file = nil
  @parser = build_parser
  @naive_dump_bundle_names = []
  @skip_dump_bundle_names = []
  @simctl_timeout = 0
  parse_arguments(args)
  @device_id ||= 'booted'
  @logger = logger
  @logger.level = @debug ? Logger::DEBUG : Logger::FATAL
  @parser = nil
end

Public Instance Methods

run() click to toggle source
# File lib/xcknife/test_dumper.rb, line 39
def run
  helper = TestDumperHelper.new(@device_id, @max_retry_count, @debug, @logger, @dylib_logfile_path,
                                naive_dump_bundle_names: @naive_dump_bundle_names, skip_dump_bundle_names: @skip_dump_bundle_names, simctl_timeout: @simctl_timeout)
  extra_environment_variables = parse_scheme_file
  logger.info { "Environment variables from xcscheme: #{extra_environment_variables.pretty_inspect}" }
  output_fd = File.open(@output_file, 'w')
  if @temporary_output_folder.nil?
    Dir.mktmpdir('xctestdumper_') do |outfolder|
      list_tests(extra_environment_variables, helper, outfolder, output_fd)
    end
  else
    raise TestDumpError, "Error no such directory: #{@temporary_output_folder}" unless File.directory?(@temporary_output_folder)

    puts "Warning: #{@temporary_output_folder} is not empty! Files can be overwritten." if Dir.entries(@temporary_output_folder).any? { |f| File.file?(File.join(@temporary_output_folder, f)) }
    list_tests(extra_environment_variables, helper, File.absolute_path(@temporary_output_folder), output_fd)
  end
  output_fd.close
  puts 'Done listing test methods'
end

Private Instance Methods

arguments_banner() click to toggle source
# File lib/xcknife/test_dumper.rb, line 113
def arguments_banner
  optional_args = optional_arguments.map { |a| "[#{a}]" }
  (required_arguments + optional_args).join(' ')
end
build_parser() click to toggle source
# File lib/xcknife/test_dumper.rb, line 86
def build_parser
  OptionParser.new do |opts|
    opts.banner += " #{arguments_banner}"
    opts.on('-d', '--debug', 'Debug mode enabled') { |v| @debug = v }
    opts.on('-r', '--retry-count COUNT', 'Max retry count for simulator output', Integer) { |v| @max_retry_count = v }
    opts.on('-x', '--simctl-timeout SECONDS', 'Max allowed time in seconds for simctl commands', Integer) { |v| @simctl_timeout = v }
    opts.on('-t', '--temporary-output OUTPUT_FOLDER', 'Sets temporary Output folder') { |v| @temporary_output_folder = v }
    opts.on('-s', '--scheme XCSCHEME_FILE', 'Reads environments variables from the xcscheme file') { |v| @xcscheme_file = v }
    opts.on('-l', '--dylib_logfile DYLIB_LOG_FILE', 'Path for dylib log file') { |v| @dylib_logfile_path = v }
    opts.on('--naive-dump TEST_BUNDLE_NAMES', 'List of test bundles to dump using static analysis', Array) { |v| @naive_dump_bundle_names = v }
    opts.on('--skip-dump TEST_BUNDLE_NAMES', 'List of test bundles to skip dumping', Array) { |v| @skip_dump_bundle_names = v }

    opts.on_tail('-h', '--help', 'Show this message') do
      puts opts
      exit
    end
  end
end
concat_to_file(test_specification, output_fd) click to toggle source
# File lib/xcknife/test_dumper.rb, line 122
def concat_to_file(test_specification, output_fd)
  file = test_specification.json_stream_file
  IO.readlines(file).each do |line|
    event = OpenStruct.new(JSON.parse(line))
    if should_test_event_be_ignored?(test_specification, event)
      logger.info "Skipped test dumper line #{line}"
    else
      output_fd.write(line)
    end
    output_fd.flush
  end
  output_fd.flush
end
list_tests(extra_environment_variables, helper, outfolder, output_fd) click to toggle source
# File lib/xcknife/test_dumper.rb, line 61
def list_tests(extra_environment_variables, helper, outfolder, output_fd)
  helper.call(@derived_data_folder, outfolder, extra_environment_variables).each do |test_specification|
    concat_to_file(test_specification, output_fd)
  end
end
optional_arguments() click to toggle source
# File lib/xcknife/test_dumper.rb, line 109
def optional_arguments
  %w[device_id simctl_timeout]
end
parse_arguments(args) click to toggle source
# File lib/xcknife/test_dumper.rb, line 74
def parse_arguments(args)
  positional_arguments = parse_options(args)
  warn_and_exit("You must specify *all* required arguments: #{required_arguments.join(', ')}") if positional_arguments.size < required_arguments.size
  @derived_data_folder, @output_file, @device_id = positional_arguments
end
parse_options(args) click to toggle source
# File lib/xcknife/test_dumper.rb, line 80
def parse_options(args)
  @parser.parse(args)
rescue OptionParser::ParseError => e
  warn_and_exit(e)
end
parse_scheme_file() click to toggle source
# File lib/xcknife/test_dumper.rb, line 67
def parse_scheme_file
  return {} unless @xcscheme_file
  raise ArgumentError, "Error: no such xcscheme file: #{@xcscheme_file}" unless File.exist?(@xcscheme_file)

  XCKnife::XcschemeAnalyzer.extract_environment_variables(IO.read(@xcscheme_file))
end
required_arguments() click to toggle source
# File lib/xcknife/test_dumper.rb, line 105
def required_arguments
  %w[derived_data_folder output_file]
end
should_test_event_be_ignored?(test_specification, event) click to toggle source

Current limitation: this only supports class level skipping

# File lib/xcknife/test_dumper.rb, line 137
def should_test_event_be_ignored?(test_specification, event)
  return false unless event['test'] == '1'

  test_specification.skip_test_identifiers.include?(event['className'])
end
warn_and_exit(msg) click to toggle source
# File lib/xcknife/test_dumper.rb, line 118
def warn_and_exit(msg)
  raise TestDumpError, "#{msg.to_s.capitalize} \n\n#{@parser}"
end