Sha256: 2b1d26d3045ad8ad443a49e24e6c9a9b25a19cae37f012af787e3f515f946ac5

Contents?: true

Size: 1.92 KB

Versions: 1

Compression:

Stored size: 1.92 KB

Contents

require 'timeout'

module TspRunner
  class Runner
    class InvalidError < StandardError; end

    attr_reader :cmd, :filename, :time_limit

    def self.usage
      puts "Usage: #{$0} <time limit> <input file> <command> [command arg 1]..."
      puts ''
      puts ' time limit    - maximum duration the executable can run in seconds'
      puts ' input file    - input file with location names and lat/lons'
      puts ' command       - command line executable that calculates the path'
      puts ' command arg n - optional args for the command line executable'
    end

    def initialize(time_limit, filename, *cmd_and_opts)
      @time_limit = time_limit
      @filename = filename
      @cmd = cmd_and_opts.join(' ')
    end

    def validate_input
      return false if time_limit.nil? || filename.nil? || cmd.to_s.length == 0
      Integer(time_limit.to_s, 10)
      unless File.exists?(filename.to_s)
        puts "Input file does not exist: #{filename}"
        return false
      end
      true
    rescue ArgumentError
      puts "Invalid time limit: #{time_limit}"
      false
    end

    def run
      unless validate_input
        self.class.usage
        return
      end

      output = Timeout.timeout(time_limit.to_i) { `#{cmd} #{filename}` }
      distance = validate!(output, 'San Francisco')
      puts("Success: #{distance} km")
    rescue InvalidError => error
      $stderr.puts error
      exit(1)
    rescue Timeout::Error
      $stderr.puts 'Failed: timeout'
      exit(1)
    end

    def validate!(output, initial_location_name = nil)
      solution = TspRunner::Solution.from_string(output, location_hash)
      if solution.valid?(initial_location_name)
        solution.total_distance / 1000.0
      else
        raise InvalidError, ['Failed: invalid, program output:', output].join("\n")
      end
    end

    private

    def location_hash
      @location_hash ||= TspRunner::LocationHash.from_file(filename)
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
tsp_runner-0.1.1 lib/tsp_runner/runner.rb