|  | module Gauntlt | 
        
          |  | module Turnip | 
        
          |  |  | 
        
          |  | module Cli | 
        
          |  | def unescape(string) | 
        
          |  | string.gsub('\n', "\n").gsub('\"', '"').gsub('\e', "\e") | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def detect_ruby(cmd) | 
        
          |  | if cmd =~ /^ruby\s/ | 
        
          |  | cmd.gsub(/^ruby\s/, "#{current_ruby} ") | 
        
          |  | else | 
        
          |  | cmd | 
        
          |  | end | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def current_dir | 
        
          |  | File.join(*dirs) | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def dirs | 
        
          |  | @dirs ||= ['tmp/aruba'] | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def exit_timeout | 
        
          |  | 3 | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def io_wait | 
        
          |  | 0.1 | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def stop_process(process) | 
        
          |  | @last_exit_status = process.stop(announcer, @aruba_keep_ansi) | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def stop_processes! | 
        
          |  | processes.each do |_, process| | 
        
          |  | stop_process(process) | 
        
          |  | end | 
        
          |  | end | 
        
          |  |  | 
        
          |  |  | 
        
          |  | def last_exit_status | 
        
          |  | return @last_exit_status if @last_exit_status | 
        
          |  | stop_processes! | 
        
          |  | @last_exit_status | 
        
          |  | end | 
        
          |  |  | 
        
          |  |  | 
        
          |  | def run_simple(cmd, fail_on_error=true) | 
        
          |  | run(cmd) do |process| | 
        
          |  | stop_process(process) | 
        
          |  | end | 
        
          |  | @timed_out = last_exit_status.nil? | 
        
          |  | assert_exit_status(0) if fail_on_error | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def _mkdir(dir_name) | 
        
          |  | FileUtils.mkdir_p(dir_name) unless File.directory?(dir_name) | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def in_current_dir(&block) | 
        
          |  | _mkdir(current_dir) | 
        
          |  | Dir.chdir(current_dir, &block) | 
        
          |  | end | 
        
          |  |  | 
        
          |  | class Announcer | 
        
          |  | def initialize(session, options = {}) | 
        
          |  | @session, @options = session, options | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def stdout(content) | 
        
          |  | return unless @options[:stdout] | 
        
          |  | print content | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def stderr(content) | 
        
          |  | return unless @options[:stderr] | 
        
          |  | print content | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def dir(dir) | 
        
          |  | return unless @options[:dir] | 
        
          |  | print "$ cd #{dir}" | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def cmd(cmd) | 
        
          |  | return unless @options[:cmd] | 
        
          |  | print "$ #{cmd}" | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def env(key, value) | 
        
          |  | return unless @options[:env] | 
        
          |  | print %{$ export #{key}="#{value}"} | 
        
          |  | end | 
        
          |  |  | 
        
          |  | private | 
        
          |  |  | 
        
          |  | def print(message) | 
        
          |  | @session.announce_or_puts(message) | 
        
          |  | end | 
        
          |  | end | 
        
          |  |  | 
        
          |  | require 'childprocess' | 
        
          |  | require 'tempfile' | 
        
          |  | require 'shellwords' | 
        
          |  |  | 
        
          |  |  | 
        
          |  | class Process | 
        
          |  | include Shellwords | 
        
          |  |  | 
        
          |  | def initialize(cmd, exit_timeout, io_wait) | 
        
          |  | @exit_timeout = exit_timeout | 
        
          |  | @io_wait = io_wait | 
        
          |  |  | 
        
          |  | @out = Tempfile.new("aruba-out") | 
        
          |  | @err = Tempfile.new("aruba-err") | 
        
          |  | @process = ChildProcess.build(*shellwords(cmd)) | 
        
          |  | @process.io.stdout = @out | 
        
          |  | @process.io.stderr = @err | 
        
          |  | @process.duplex = true | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def run!(&block) | 
        
          |  | @process.start | 
        
          |  | yield self if block_given? | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def stdin | 
        
          |  | wait_for_io do | 
        
          |  | @process.io.stdin.sync = true | 
        
          |  | @process.io.stdin | 
        
          |  | end | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def output(keep_ansi) | 
        
          |  | stdout(keep_ansi) + stderr(keep_ansi) | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def stdout(keep_ansi) | 
        
          |  | wait_for_io do | 
        
          |  | @out.rewind | 
        
          |  | filter_ansi(@out.read, keep_ansi) | 
        
          |  | end | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def stderr(keep_ansi) | 
        
          |  | wait_for_io do | 
        
          |  | @err.rewind | 
        
          |  | filter_ansi(@err.read, keep_ansi) | 
        
          |  | end | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def stop(reader, keep_ansi) | 
        
          |  | return unless @process | 
        
          |  | unless @process.exited? | 
        
          |  | reader.stdout stdout(keep_ansi) | 
        
          |  | reader.stderr stderr(keep_ansi) | 
        
          |  | @process.poll_for_exit(@exit_timeout) | 
        
          |  | end | 
        
          |  | @process.exit_code | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def terminate(keep_ansi) | 
        
          |  | if @process | 
        
          |  | stdout(keep_ansi) && stderr(keep_ansi) # flush output | 
        
          |  | @process.stop | 
        
          |  | stdout(keep_ansi) && stderr(keep_ansi) # flush output | 
        
          |  | end | 
        
          |  | end | 
        
          |  |  | 
        
          |  | private | 
        
          |  |  | 
        
          |  | def wait_for_io(&block) | 
        
          |  | sleep @io_wait if @process.alive? | 
        
          |  | yield | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def filter_ansi(string, keep_ansi) | 
        
          |  | keep_ansi ? string : string.gsub(/\e\[\d+(?>(;\d+)*)m/, '') | 
        
          |  | end | 
        
          |  |  | 
        
          |  | end | 
        
          |  |  | 
        
          |  |  | 
        
          |  | def announcer | 
        
          |  | Announcer.new(self, | 
        
          |  | :stdout => @announce_stdout, | 
        
          |  | :stderr => @announce_stderr, | 
        
          |  | :dir => @announce_dir, | 
        
          |  | :cmd => @announce_cmd, | 
        
          |  | :env => @announce_env) | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def processes | 
        
          |  | @processes ||= [] | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def register_process(name, process) | 
        
          |  | processes << [name, process] | 
        
          |  | end | 
        
          |  |  | 
        
          |  |  | 
        
          |  | def run(cmd) | 
        
          |  | @commands ||= [] | 
        
          |  | @commands << cmd | 
        
          |  |  | 
        
          |  | cmd = detect_ruby(cmd) | 
        
          |  |  | 
        
          |  | in_current_dir do | 
        
          |  | #Aruba.config.hooks.execute(:before_cmd, self, cmd) | 
        
          |  |  | 
        
          |  | announcer.dir(Dir.pwd) | 
        
          |  | announcer.cmd(cmd) | 
        
          |  |  | 
        
          |  | process = Process.new(cmd, exit_timeout, io_wait) | 
        
          |  | register_process(cmd, process) | 
        
          |  | process.run! | 
        
          |  |  | 
        
          |  | block_given? ? yield(process) : process | 
        
          |  | end | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def assert_passing_with(expected) | 
        
          |  | assert_exit_status_and_partial_output(true, expected) | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def assert_exit_status_and_partial_output(expect_to_pass, expected) | 
        
          |  | assert_success(expect_to_pass) | 
        
          |  | assert_partial_output(expected, all_output) | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def assert_success(success) | 
        
          |  | success ? assert_exit_status(0) : assert_not_exit_status(0) | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def assert_exit_status(status) | 
        
          |  | last_exit_status.should eq(status), | 
        
          |  | append_output_to("Exit status was #{last_exit_status} but expected it to be #{status}.") | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def assert_partial_output(expected, actual) | 
        
          |  | unescape(actual).should include(unescape(expected)) | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def append_output_to(message) | 
        
          |  | "#{message} Output:\n\n#{all_output}\n" | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def all_stdout | 
        
          |  | stop_processes! | 
        
          |  | only_processes.inject("") { |out, ps| out << ps.stdout(@aruba_keep_ansi) } | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def all_stderr | 
        
          |  | stop_processes! | 
        
          |  | only_processes.inject("") { |out, ps| out << ps.stderr(@aruba_keep_ansi) } | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def all_output | 
        
          |  | all_stdout << all_stderr | 
        
          |  | end | 
        
          |  |  | 
        
          |  | def only_processes | 
        
          |  | processes.collect{ |_, process| process } | 
        
          |  | end | 
        
          |  |  | 
        
          |  | end | 
        
          |  | end | 
        
          |  | end | 
        
          |  |  | 
        
          |  | module TurnipCliSteps | 
        
          |  | include Gauntlt::Turnip::Cli | 
        
          |  | extend ::Turnip::DSL | 
        
          |  |  | 
        
          |  | step "the file :filename should contain: :partial_content" do |filename, partial_content| | 
        
          |  | check_file_content(file, partial_content, true) | 
        
          |  | end | 
        
          |  |  | 
        
          |  | step 'I run :cmd' do |cmd| | 
        
          |  | run_simple(unescape(cmd), false) | 
        
          |  | end | 
        
          |  |  | 
        
          |  | placeholder :cmd do | 
        
          |  | match /`([^`]*)`/ do |cmd| | 
        
          |  | cmd | 
        
          |  | end | 
        
          |  | end | 
        
          |  |  | 
        
          |  | step "I successfully run `:cmd`" do |cmd| | 
        
          |  | run_simple(unescape(cmd)) | 
        
          |  | end | 
        
          |  |  | 
        
          |  | step "it should pass with:" do |partial_output| | 
        
          |  | assert_passing_with(partial_output) | 
        
          |  | end | 
        
          |  |  | 
        
          |  | end | 
        
          |  |  | 
        
          |  | module Gauntlt::Turnip::NmapSteps | 
        
          |  | extend ::Turnip::DSL | 
        
          |  |  | 
        
          |  | step '"nmap" is installed' do | 
        
          |  | if !(`which nmap` && $?.success?) | 
        
          |  | raise "nmap not installed!" | 
        
          |  | end | 
        
          |  | end | 
        
          |  |  | 
        
          |  | step 'the target hostname is "google.com"' do | 
        
          |  |  | 
        
          |  | end | 
        
          |  |  | 
        
          |  | step 'I launch an "nmap" attack with:' do |cmd| | 
        
          |  | end | 
        
          |  |  | 
        
          |  | step 'the output should contain:' do |string| | 
        
          |  | end | 
        
          |  | end | 
        
          |  |  | 
        
          |  | RSpec.configure do |config| | 
        
          |  | config.include TurnipCliSteps | 
        
          |  | end |