lib/tsp_runner/runner.rb in tsp_runner-0.1.0 vs lib/tsp_runner/runner.rb in tsp_runner-0.1.1
- old
+ new
@@ -1,36 +1,69 @@
require 'timeout'
module TspRunner
class Runner
- class BaseError < StandardError; end
- class TimeoutError < BaseError; end
- class InvalidError < BaseError; end
+ class InvalidError < StandardError; end
- attr_reader :cmd, :input_filename, :output
+ attr_reader :cmd, :filename, :time_limit
- def initialize(cmd, input_filename)
- @cmd, @input_filename = cmd, input_filename
+ 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 run(time_limit)
- @output = Timeout.timeout(time_limit) { `#{cmd} #{input_filename}` }
+ 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
- raise TimeoutError, 'Failed: timeout'
+ $stderr.puts 'Failed: timeout'
+ exit(1)
end
- def validate!(initial_location_name = nil)
+ 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', output].join("\n")
+ raise InvalidError, ['Failed: invalid, program output:', output].join("\n")
end
end
private
def location_hash
- @location_hash ||= TspRunner::LocationHash.from_file(input_filename)
+ @location_hash ||= TspRunner::LocationHash.from_file(filename)
end
end
end