rexec 1.4.1 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +4 -0
 - data/lib/rexec/daemon/base.rb +40 -47
 - data/lib/rexec/daemon/controller.rb +23 -25
 - data/lib/rexec/daemon/{pidfile.rb → process_file.rb} +7 -7
 - data/lib/rexec/version.rb +2 -2
 - data/rakefile.rb +10 -0
 - data/test/client.rb +14 -14
 - data/test/daemon.rb +32 -33
 - data/test/helper.rb +5 -0
 - data/test/listing_example.rb +15 -14
 - data/test/{daemon_test.rb → test_daemon.rb} +20 -22
 - data/test/{remote_server_test.rb → test_remote_server.rb} +1 -2
 - data/test/test_server.rb +93 -0
 - data/test/test_task.rb +168 -0
 - metadata +30 -49
 - data/test/server_test.rb +0 -94
 - data/test/task_test.rb +0 -170
 
    
        data/Gemfile
    ADDED
    
    
    
        data/lib/rexec/daemon/base.rb
    CHANGED
    
    | 
         @@ -35,84 +35,79 @@ module RExec 
     | 
|
| 
       35 
35 
     | 
    
         
             
            		# 	end
         
     | 
| 
       36 
36 
     | 
    
         
             
            		# 	
         
     | 
| 
       37 
37 
     | 
    
         
             
            		# 	Server.daemonize
         
     | 
| 
      
 38 
     | 
    
         
            +
            		#
         
     | 
| 
      
 39 
     | 
    
         
            +
            		# The base directory specifies a path such that:
         
     | 
| 
      
 40 
     | 
    
         
            +
            		#   working_directory = #{@@base_directory}/#{daemon_name}
         
     | 
| 
      
 41 
     | 
    
         
            +
            		#   log_directory = #{working_directory}/log
         
     | 
| 
      
 42 
     | 
    
         
            +
            		#   log_file_path = #{log_directory}/daemon.log
         
     | 
| 
      
 43 
     | 
    
         
            +
            		#   runtime_directory = #{working_directory}/run
         
     | 
| 
      
 44 
     | 
    
         
            +
            		#   process_file_path = #{runtime_directory}/daemon.pid
         
     | 
| 
       38 
45 
     | 
    
         
             
            		class Base
         
     | 
| 
       39 
     | 
    
         
            -
            			 
     | 
| 
       40 
     | 
    
         
            -
            			@@ 
     | 
| 
       41 
     | 
    
         
            -
            			@@pid_directory = nil
         
     | 
| 
      
 46 
     | 
    
         
            +
            			# For a system-level daemon you might want to specify "/var"
         
     | 
| 
      
 47 
     | 
    
         
            +
            			@@base_directory = "."
         
     | 
| 
       42 
48 
     | 
    
         | 
| 
       43 
49 
     | 
    
         
             
            			# Return the name of the daemon
         
     | 
| 
       44 
50 
     | 
    
         
             
            			def self.daemon_name
         
     | 
| 
       45 
51 
     | 
    
         
             
            				return name.gsub(/[^a-zA-Z0-9]+/, '-')
         
     | 
| 
       46 
52 
     | 
    
         
             
            			end
         
     | 
| 
       47 
53 
     | 
    
         | 
| 
       48 
     | 
    
         
            -
            			#  
     | 
| 
       49 
     | 
    
         
            -
            			def self.var_directory
         
     | 
| 
       50 
     | 
    
         
            -
            				@@var_directory || File.join("", "var")
         
     | 
| 
       51 
     | 
    
         
            -
            			end
         
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
            			# The directory the daemon will run in (Dir.chdir)
         
     | 
| 
      
 54 
     | 
    
         
            +
            			# The directory the daemon will run in.
         
     | 
| 
       54 
55 
     | 
    
         
             
            			def self.working_directory
         
     | 
| 
       55 
     | 
    
         
            -
            				 
     | 
| 
      
 56 
     | 
    
         
            +
            				File.join(@@base_directory, daemon_name)
         
     | 
| 
       56 
57 
     | 
    
         
             
            			end
         
     | 
| 
       57 
58 
     | 
    
         | 
| 
       58 
     | 
    
         
            -
            			# Return the directory to store log files in
         
     | 
| 
      
 59 
     | 
    
         
            +
            			# Return the directory to store log files in.
         
     | 
| 
       59 
60 
     | 
    
         
             
            			def self.log_directory
         
     | 
| 
       60 
     | 
    
         
            -
            				 
     | 
| 
      
 61 
     | 
    
         
            +
            				File.join(working_directory, "log")
         
     | 
| 
       61 
62 
     | 
    
         
             
            			end
         
     | 
| 
       62 
63 
     | 
    
         | 
| 
       63 
     | 
    
         
            -
            			# Standard log file for  
     | 
| 
       64 
     | 
    
         
            -
            			def self. 
     | 
| 
       65 
     | 
    
         
            -
            				File.join(log_directory, " 
     | 
| 
      
 64 
     | 
    
         
            +
            			# Standard log file for stdout and stderr.
         
     | 
| 
      
 65 
     | 
    
         
            +
            			def self.log_file_path
         
     | 
| 
      
 66 
     | 
    
         
            +
            				File.join(log_directory, "daemon.log")
         
     | 
| 
       66 
67 
     | 
    
         
             
            			end
         
     | 
| 
       67 
68 
     | 
    
         | 
| 
       68 
     | 
    
         
            -
            			#  
     | 
| 
       69 
     | 
    
         
            -
            			def self. 
     | 
| 
       70 
     | 
    
         
            -
            				File.join( 
     | 
| 
      
 69 
     | 
    
         
            +
            			# Runtime data directory for the daemon.
         
     | 
| 
      
 70 
     | 
    
         
            +
            			def self.runtime_directory
         
     | 
| 
      
 71 
     | 
    
         
            +
            				File.join(working_directory, "run")
         
     | 
| 
       71 
72 
     | 
    
         
             
            			end
         
     | 
| 
       72 
73 
     | 
    
         | 
| 
       73 
     | 
    
         
            -
            			# Standard location of pid file
         
     | 
| 
       74 
     | 
    
         
            -
            			def self. 
     | 
| 
       75 
     | 
    
         
            -
            				 
     | 
| 
      
 74 
     | 
    
         
            +
            			# Standard location of process pid file.
         
     | 
| 
      
 75 
     | 
    
         
            +
            			def self.process_file_path
         
     | 
| 
      
 76 
     | 
    
         
            +
            				File.join(runtime_directory, "daemon.pid")
         
     | 
| 
       76 
77 
     | 
    
         
             
            			end
         
     | 
| 
       77 
78 
     | 
    
         | 
| 
       78 
     | 
    
         
            -
            			#  
     | 
| 
       79 
     | 
    
         
            -
            			def self. 
     | 
| 
       80 
     | 
    
         
            -
            				File. 
     | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
       83 
     | 
    
         
            -
            			# Mark the error log
         
     | 
| 
       84 
     | 
    
         
            -
            			def self.mark_err_log
         
     | 
| 
       85 
     | 
    
         
            -
            				fp = File.open(err_fn, "a")
         
     | 
| 
       86 
     | 
    
         
            -
            				fp.puts "=== Error Log Opened @ #{Time.now.to_s} ==="
         
     | 
| 
       87 
     | 
    
         
            -
            				fp.close
         
     | 
| 
      
 79 
     | 
    
         
            +
            			# Mark the output log.
         
     | 
| 
      
 80 
     | 
    
         
            +
            			def self.mark_log
         
     | 
| 
      
 81 
     | 
    
         
            +
            				File.open(log_file_path, "a") do |log_file|
         
     | 
| 
      
 82 
     | 
    
         
            +
            					log_file.puts "=== Log Marked @ #{Time.now.to_s} ==="
         
     | 
| 
      
 83 
     | 
    
         
            +
            				end
         
     | 
| 
       88 
84 
     | 
    
         
             
            			end
         
     | 
| 
       89 
85 
     | 
    
         | 
| 
       90 
     | 
    
         
            -
            			# Prints some information relating to daemon startup problems
         
     | 
| 
       91 
     | 
    
         
            -
            			def self. 
     | 
| 
      
 86 
     | 
    
         
            +
            			# Prints some information relating to daemon startup problems.
         
     | 
| 
      
 87 
     | 
    
         
            +
            			def self.tail_log(output)
         
     | 
| 
       92 
88 
     | 
    
         
             
            				lines = []
         
     | 
| 
       93 
89 
     | 
    
         | 
| 
       94 
     | 
    
         
            -
            				File.open( 
     | 
| 
       95 
     | 
    
         
            -
            					 
     | 
| 
      
 90 
     | 
    
         
            +
            				File.open(error_log_path, "r") do |log_file|
         
     | 
| 
      
 91 
     | 
    
         
            +
            					log_file.seek_end
         
     | 
| 
       96 
92 
     | 
    
         | 
| 
       97 
     | 
    
         
            -
            					 
     | 
| 
      
 93 
     | 
    
         
            +
            					log_file.reverse_each_line do |line|
         
     | 
| 
       98 
94 
     | 
    
         
             
            						lines << line
         
     | 
| 
       99 
     | 
    
         
            -
            						break if line.match("===  
     | 
| 
      
 95 
     | 
    
         
            +
            						break if line.match("=== Log Marked") || line.match("=== Daemon Exception Backtrace")
         
     | 
| 
       100 
96 
     | 
    
         
             
            					end
         
     | 
| 
       101 
97 
     | 
    
         
             
            				end
         
     | 
| 
       102 
98 
     | 
    
         | 
| 
       103 
99 
     | 
    
         
             
            				lines.reverse_each do |line|
         
     | 
| 
       104 
     | 
    
         
            -
            					 
     | 
| 
      
 100 
     | 
    
         
            +
            					output.puts line
         
     | 
| 
       105 
101 
     | 
    
         
             
            				end
         
     | 
| 
       106 
102 
     | 
    
         
             
            			end
         
     | 
| 
       107 
103 
     | 
    
         | 
| 
       108 
     | 
    
         
            -
            			# Check the last few lines of the log file to find out if
         
     | 
| 
       109 
     | 
    
         
            -
            			# the daemon crashed.
         
     | 
| 
      
 104 
     | 
    
         
            +
            			# Check the last few lines of the log file to find out if the daemon crashed.
         
     | 
| 
       110 
105 
     | 
    
         
             
            			def self.crashed?
         
     | 
| 
       111 
     | 
    
         
            -
            				File.open( 
     | 
| 
       112 
     | 
    
         
            -
            					 
     | 
| 
      
 106 
     | 
    
         
            +
            				File.open(error_log_path, "r") do |log_file|
         
     | 
| 
      
 107 
     | 
    
         
            +
            					log_file.seek_end
         
     | 
| 
       113 
108 
     | 
    
         | 
| 
       114 
109 
     | 
    
         
             
            					count = 2
         
     | 
| 
       115 
     | 
    
         
            -
            					 
     | 
| 
      
 110 
     | 
    
         
            +
            					log_file.reverse_each_line do |line|
         
     | 
| 
       116 
111 
     | 
    
         
             
            						return true if line.match("=== Daemon Crashed")
         
     | 
| 
       117 
112 
     | 
    
         | 
| 
       118 
113 
     | 
    
         
             
            						count -= 1
         
     | 
| 
         @@ -146,12 +141,10 @@ module RExec 
     | 
|
| 
       146 
141 
     | 
    
         | 
| 
       147 
142 
     | 
    
         
             
            			# The main function to setup any environment required by the daemon
         
     | 
| 
       148 
143 
     | 
    
         
             
            			def self.prefork
         
     | 
| 
       149 
     | 
    
         
            -
            				@@ 
     | 
| 
       150 
     | 
    
         
            -
            				@@log_directory = File.expand_path(@@log_directory) if @@log_directory
         
     | 
| 
       151 
     | 
    
         
            -
            				@@pid_directory = File.expand_path(@@pid_directory) if @@pid_directory
         
     | 
| 
      
 144 
     | 
    
         
            +
            				@@base_directory = File.expand_path(@@base_directory) if @@base_directory
         
     | 
| 
       152 
145 
     | 
    
         | 
| 
       153 
146 
     | 
    
         
             
            				FileUtils.mkdir_p(log_directory)
         
     | 
| 
       154 
     | 
    
         
            -
            				FileUtils.mkdir_p( 
     | 
| 
      
 147 
     | 
    
         
            +
            				FileUtils.mkdir_p(runtime_directory)
         
     | 
| 
       155 
148 
     | 
    
         
             
            			end
         
     | 
| 
       156 
149 
     | 
    
         | 
| 
       157 
150 
     | 
    
         
             
            			# The main function to start the daemon
         
     | 
| 
         @@ -18,7 +18,7 @@ 
     | 
|
| 
       18 
18 
     | 
    
         
             
            # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
         
     | 
| 
       19 
19 
     | 
    
         
             
            # THE SOFTWARE.
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
     | 
    
         
            -
            require 'rexec/daemon/ 
     | 
| 
      
 21 
     | 
    
         
            +
            require 'rexec/daemon/process_file'
         
     | 
| 
       22 
22 
     | 
    
         
             
            require 'rexec/task'
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
       24 
24 
     | 
    
         
             
            module RExec
         
     | 
| 
         @@ -28,21 +28,19 @@ module RExec 
     | 
|
| 
       28 
28 
     | 
    
         | 
| 
       29 
29 
     | 
    
         
             
            		# This module contains functionality related to starting and stopping the daemon, and code for processing command line input.
         
     | 
| 
       30 
30 
     | 
    
         
             
            		module Controller
         
     | 
| 
       31 
     | 
    
         
            -
            			# This function is called from the daemon executable. It processes ARGV and checks whether the user is asking for
         
     | 
| 
       32 
     | 
    
         
            -
            			# +start+, +stop+, +restart+ or +status+.
         
     | 
| 
      
 31 
     | 
    
         
            +
            			# This function is called from the daemon executable. It processes ARGV and checks whether the user is asking for `start`, `stop`, `restart`, `status`.
         
     | 
| 
       33 
32 
     | 
    
         
             
            			def self.daemonize(daemon)
         
     | 
| 
       34 
     | 
    
         
            -
            				 
     | 
| 
       35 
     | 
    
         
            -
            				case !ARGV.empty? && ARGV[0]
         
     | 
| 
      
 33 
     | 
    
         
            +
            				case ARGV.shift
         
     | 
| 
       36 
34 
     | 
    
         
             
            				when 'start'
         
     | 
| 
       37 
35 
     | 
    
         
             
            					start(daemon)
         
     | 
| 
       38 
36 
     | 
    
         
             
            					status(daemon)
         
     | 
| 
       39 
37 
     | 
    
         
             
            				when 'stop'
         
     | 
| 
       40 
38 
     | 
    
         
             
            					stop(daemon)
         
     | 
| 
       41 
39 
     | 
    
         
             
            					status(daemon)
         
     | 
| 
       42 
     | 
    
         
            -
            					 
     | 
| 
      
 40 
     | 
    
         
            +
            					ProcessFile.cleanup(daemon)
         
     | 
| 
       43 
41 
     | 
    
         
             
            				when 'restart'
         
     | 
| 
       44 
42 
     | 
    
         
             
            					stop(daemon)
         
     | 
| 
       45 
     | 
    
         
            -
            					 
     | 
| 
      
 43 
     | 
    
         
            +
            					ProcessFile.cleanup(daemon)
         
     | 
| 
       46 
44 
     | 
    
         
             
            					start(daemon)
         
     | 
| 
       47 
45 
     | 
    
         
             
            					status(daemon)
         
     | 
| 
       48 
46 
     | 
    
         
             
            				when 'status'
         
     | 
| 
         @@ -57,7 +55,7 @@ module RExec 
     | 
|
| 
       57 
55 
     | 
    
         
             
            			def self.start(daemon)
         
     | 
| 
       58 
56 
     | 
    
         
             
            				puts "Starting daemon..."
         
     | 
| 
       59 
57 
     | 
    
         | 
| 
       60 
     | 
    
         
            -
            				case  
     | 
| 
      
 58 
     | 
    
         
            +
            				case ProcessFile.status(daemon)
         
     | 
| 
       61 
59 
     | 
    
         
             
            				when :running
         
     | 
| 
       62 
60 
     | 
    
         
             
            					$stderr.puts "Daemon already running!"
         
     | 
| 
       63 
61 
     | 
    
         
             
            					return
         
     | 
| 
         @@ -66,26 +64,26 @@ module RExec 
     | 
|
| 
       66 
64 
     | 
    
         
             
            				else
         
     | 
| 
       67 
65 
     | 
    
         
             
            					$stderr.puts "Daemon in unknown state! Will clear previous state and continue."
         
     | 
| 
       68 
66 
     | 
    
         
             
            					status(daemon)
         
     | 
| 
       69 
     | 
    
         
            -
            					 
     | 
| 
      
 67 
     | 
    
         
            +
            					ProcessFile.clear(daemon)
         
     | 
| 
       70 
68 
     | 
    
         
             
            				end
         
     | 
| 
       71 
69 
     | 
    
         | 
| 
       72 
70 
     | 
    
         
             
            				daemon.prefork
         
     | 
| 
       73 
     | 
    
         
            -
            				daemon. 
     | 
| 
      
 71 
     | 
    
         
            +
            				daemon.mark_log
         
     | 
| 
       74 
72 
     | 
    
         | 
| 
       75 
73 
     | 
    
         
             
            				fork do
         
     | 
| 
       76 
74 
     | 
    
         
             
            					Process.setsid
         
     | 
| 
       77 
75 
     | 
    
         
             
            					exit if fork
         
     | 
| 
       78 
76 
     | 
    
         | 
| 
       79 
     | 
    
         
            -
            					 
     | 
| 
      
 77 
     | 
    
         
            +
            					ProcessFile.store(daemon, Process.pid)
         
     | 
| 
       80 
78 
     | 
    
         | 
| 
       81 
79 
     | 
    
         
             
            					File.umask 0000
         
     | 
| 
       82 
80 
     | 
    
         
             
            					Dir.chdir daemon.working_directory
         
     | 
| 
       83 
81 
     | 
    
         | 
| 
       84 
82 
     | 
    
         
             
            					$stdin.reopen "/dev/null"
         
     | 
| 
       85 
     | 
    
         
            -
            					$stdout.reopen daemon. 
     | 
| 
      
 83 
     | 
    
         
            +
            					$stdout.reopen daemon.log_file_path, "a"
         
     | 
| 
       86 
84 
     | 
    
         
             
            					$stdout.sync = true
         
     | 
| 
       87 
85 
     | 
    
         | 
| 
       88 
     | 
    
         
            -
            					$stderr.reopen  
     | 
| 
      
 86 
     | 
    
         
            +
            					$stderr.reopen $stdout
         
     | 
| 
       89 
87 
     | 
    
         
             
            					$stderr.sync = true
         
     | 
| 
       90 
88 
     | 
    
         | 
| 
       91 
89 
     | 
    
         
             
            					begin
         
     | 
| 
         @@ -130,7 +128,7 @@ module RExec 
     | 
|
| 
       130 
128 
     | 
    
         
             
            				puts "Waiting for daemon to start..."
         
     | 
| 
       131 
129 
     | 
    
         
             
            				sleep 0.1
         
     | 
| 
       132 
130 
     | 
    
         
             
            				timer = TIMEOUT
         
     | 
| 
       133 
     | 
    
         
            -
            				pid =  
     | 
| 
      
 131 
     | 
    
         
            +
            				pid = ProcessFile.recall(daemon)
         
     | 
| 
       134 
132 
     | 
    
         | 
| 
       135 
133 
     | 
    
         
             
            				while pid == nil and timer > 0
         
     | 
| 
       136 
134 
     | 
    
         
             
            					# Wait a moment for the forking to finish...
         
     | 
| 
         @@ -140,7 +138,7 @@ module RExec 
     | 
|
| 
       140 
138 
     | 
    
         
             
            					# If the daemon has crashed, it is never going to start...
         
     | 
| 
       141 
139 
     | 
    
         
             
            					break if daemon.crashed?
         
     | 
| 
       142 
140 
     | 
    
         | 
| 
       143 
     | 
    
         
            -
            					pid =  
     | 
| 
      
 141 
     | 
    
         
            +
            					pid = ProcessFile.recall(daemon)
         
     | 
| 
       144 
142 
     | 
    
         | 
| 
       145 
143 
     | 
    
         
             
            					timer -= 1
         
     | 
| 
       146 
144 
     | 
    
         
             
            				end
         
     | 
| 
         @@ -148,15 +146,15 @@ module RExec 
     | 
|
| 
       148 
146 
     | 
    
         | 
| 
       149 
147 
     | 
    
         
             
            			# Prints out the status of the daemon
         
     | 
| 
       150 
148 
     | 
    
         
             
            			def self.status(daemon)
         
     | 
| 
       151 
     | 
    
         
            -
            				case  
     | 
| 
      
 149 
     | 
    
         
            +
            				case ProcessFile.status(daemon)
         
     | 
| 
       152 
150 
     | 
    
         
             
            				when :running
         
     | 
| 
       153 
     | 
    
         
            -
            					puts "Daemon status: running pid=#{ 
     | 
| 
      
 151 
     | 
    
         
            +
            					puts "Daemon status: running pid=#{ProcessFile.recall(daemon)}"
         
     | 
| 
       154 
152 
     | 
    
         
             
            				when :unknown
         
     | 
| 
       155 
153 
     | 
    
         
             
            					if daemon.crashed?
         
     | 
| 
       156 
154 
     | 
    
         
             
            						puts "Daemon status: crashed"
         
     | 
| 
       157 
155 
     | 
    
         | 
| 
       158 
156 
     | 
    
         
             
            						$stdout.flush
         
     | 
| 
       159 
     | 
    
         
            -
            						daemon. 
     | 
| 
      
 157 
     | 
    
         
            +
            						daemon.tail_error_log($stderr)
         
     | 
| 
       160 
158 
     | 
    
         
             
            					else
         
     | 
| 
       161 
159 
     | 
    
         
             
            						puts "Daemon status: unknown"
         
     | 
| 
       162 
160 
     | 
    
         
             
            					end
         
     | 
| 
         @@ -170,27 +168,27 @@ module RExec 
     | 
|
| 
       170 
168 
     | 
    
         
             
            				puts "Stopping daemon..."
         
     | 
| 
       171 
169 
     | 
    
         | 
| 
       172 
170 
     | 
    
         
             
            				# Check if the pid file exists...
         
     | 
| 
       173 
     | 
    
         
            -
            				 
     | 
| 
      
 171 
     | 
    
         
            +
            				unless File.file?(daemon.process_file_path)
         
     | 
| 
       174 
172 
     | 
    
         
             
            					puts "Pid file not found. Is the daemon running?"
         
     | 
| 
       175 
173 
     | 
    
         
             
            					return
         
     | 
| 
       176 
174 
     | 
    
         
             
            				end
         
     | 
| 
       177 
175 
     | 
    
         | 
| 
       178 
     | 
    
         
            -
            				pid =  
     | 
| 
      
 176 
     | 
    
         
            +
            				pid = ProcessFile.recall(daemon)
         
     | 
| 
       179 
177 
     | 
    
         | 
| 
       180 
178 
     | 
    
         
             
            				# Check if the daemon is already stopped...
         
     | 
| 
       181 
     | 
    
         
            -
            				unless  
     | 
| 
      
 179 
     | 
    
         
            +
            				unless ProcessFile.running(daemon)
         
     | 
| 
       182 
180 
     | 
    
         
             
            					puts "Pid #{pid} is not running. Has daemon crashed?"
         
     | 
| 
       183 
181 
     | 
    
         
             
            					return
         
     | 
| 
       184 
182 
     | 
    
         
             
            				end
         
     | 
| 
       185 
183 
     | 
    
         | 
| 
       186 
     | 
    
         
            -
            				pid =  
     | 
| 
      
 184 
     | 
    
         
            +
            				pid = ProcessFile.recall(daemon)
         
     | 
| 
       187 
185 
     | 
    
         
             
            				Process.kill("INT", pid)
         
     | 
| 
       188 
186 
     | 
    
         
             
            				sleep 0.1
         
     | 
| 
       189 
187 
     | 
    
         | 
| 
       190 
188 
     | 
    
         
             
            				# Kill/Term loop - if the daemon didn't die easily, shoot
         
     | 
| 
       191 
189 
     | 
    
         
             
            				# it a few more times.
         
     | 
| 
       192 
190 
     | 
    
         
             
            				attempts = 5
         
     | 
| 
       193 
     | 
    
         
            -
            				while  
     | 
| 
      
 191 
     | 
    
         
            +
            				while ProcessFile.running(daemon) and attempts > 0
         
     | 
| 
       194 
192 
     | 
    
         
             
            					sig = (attempts < 2) ? "KILL" : "TERM"
         
     | 
| 
       195 
193 
     | 
    
         | 
| 
       196 
194 
     | 
    
         
             
            					puts "Sending #{sig} to pid #{pid}..."
         
     | 
| 
         @@ -201,13 +199,13 @@ module RExec 
     | 
|
| 
       201 
199 
     | 
    
         
             
            				end
         
     | 
| 
       202 
200 
     | 
    
         | 
| 
       203 
201 
     | 
    
         
             
            				# If after doing our best the daemon is still running (pretty odd)...
         
     | 
| 
       204 
     | 
    
         
            -
            				if  
     | 
| 
      
 202 
     | 
    
         
            +
            				if ProcessFile.running(daemon)
         
     | 
| 
       205 
203 
     | 
    
         
             
            					puts "Daemon appears to be still running!"
         
     | 
| 
       206 
204 
     | 
    
         
             
            					return
         
     | 
| 
       207 
205 
     | 
    
         
             
            				end
         
     | 
| 
       208 
206 
     | 
    
         | 
| 
       209 
207 
     | 
    
         
             
            				# Otherwise the daemon has been stopped.
         
     | 
| 
       210 
     | 
    
         
            -
            				 
     | 
| 
      
 208 
     | 
    
         
            +
            				ProcessFile.clear(daemon)
         
     | 
| 
       211 
209 
     | 
    
         
             
            			end
         
     | 
| 
       212 
210 
     | 
    
         
             
            		end
         
     | 
| 
       213 
211 
     | 
    
         
             
            	end
         
     | 
| 
         @@ -21,21 +21,21 @@ 
     | 
|
| 
       21 
21 
     | 
    
         
             
            module RExec
         
     | 
| 
       22 
22 
     | 
    
         
             
            	module Daemon
         
     | 
| 
       23 
23 
     | 
    
         
             
            		# This module controls the storage and retrieval of process id files.
         
     | 
| 
       24 
     | 
    
         
            -
            		module  
     | 
| 
      
 24 
     | 
    
         
            +
            		module ProcessFile
         
     | 
| 
       25 
25 
     | 
    
         
             
            			# Saves the pid for the given daemon
         
     | 
| 
       26 
26 
     | 
    
         
             
            			def self.store(daemon, pid)
         
     | 
| 
       27 
     | 
    
         
            -
            				File.open(daemon. 
     | 
| 
      
 27 
     | 
    
         
            +
            				File.open(daemon.process_file_path, 'w') {|f| f << pid}
         
     | 
| 
       28 
28 
     | 
    
         
             
            			end
         
     | 
| 
       29 
29 
     | 
    
         | 
| 
       30 
30 
     | 
    
         
             
            			# Retrieves the pid for the given daemon
         
     | 
| 
       31 
31 
     | 
    
         
             
            			def self.recall(daemon)
         
     | 
| 
       32 
     | 
    
         
            -
            				IO.read(daemon. 
     | 
| 
      
 32 
     | 
    
         
            +
            				IO.read(daemon.process_file_path).to_i rescue nil
         
     | 
| 
       33 
33 
     | 
    
         
             
            			end
         
     | 
| 
       34 
34 
     | 
    
         | 
| 
       35 
35 
     | 
    
         
             
            			# Removes the pid saved for a particular daemon
         
     | 
| 
       36 
36 
     | 
    
         
             
            			def self.clear(daemon)
         
     | 
| 
       37 
     | 
    
         
            -
            				if File.exist? daemon. 
     | 
| 
       38 
     | 
    
         
            -
            					FileUtils.rm(daemon. 
     | 
| 
      
 37 
     | 
    
         
            +
            				if File.exist? daemon.process_file_path
         
     | 
| 
      
 38 
     | 
    
         
            +
            					FileUtils.rm(daemon.process_file_path)
         
     | 
| 
       39 
39 
     | 
    
         
             
            				end
         
     | 
| 
       40 
40 
     | 
    
         
             
            			end
         
     | 
| 
       41 
41 
     | 
    
         | 
| 
         @@ -58,8 +58,8 @@ module RExec 
     | 
|
| 
       58 
58 
     | 
    
         
             
            			# This function returns the status of the daemon. This can be one of +:running+, +:unknown+ (pid file exists but no 
         
     | 
| 
       59 
59 
     | 
    
         
             
            			# corresponding process can be found) or +:stopped+.
         
     | 
| 
       60 
60 
     | 
    
         
             
            			def self.status(daemon)
         
     | 
| 
       61 
     | 
    
         
            -
            				if File.exist? daemon. 
     | 
| 
       62 
     | 
    
         
            -
            					return  
     | 
| 
      
 61 
     | 
    
         
            +
            				if File.exist? daemon.process_file_path
         
     | 
| 
      
 62 
     | 
    
         
            +
            					return ProcessFile.running(daemon) ? :running : :unknown
         
     | 
| 
       63 
63 
     | 
    
         
             
            				else
         
     | 
| 
       64 
64 
     | 
    
         
             
            					return :stopped
         
     | 
| 
       65 
65 
     | 
    
         
             
            				end
         
     | 
    
        data/lib/rexec/version.rb
    CHANGED
    
    
    
        data/rakefile.rb
    ADDED
    
    
    
        data/test/client.rb
    CHANGED
    
    | 
         @@ -19,18 +19,18 @@ 
     | 
|
| 
       19 
19 
     | 
    
         
             
            # THE SOFTWARE.
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
21 
     | 
    
         
             
            $connection.run do |object|
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
      
 22 
     | 
    
         
            +
            	case(object[0])
         
     | 
| 
      
 23 
     | 
    
         
            +
            	when :bounce
         
     | 
| 
      
 24 
     | 
    
         
            +
            		$stderr.puts("Bouncing #{object[1].inspect}...")
         
     | 
| 
      
 25 
     | 
    
         
            +
            		$connection.send_object(object[1])
         
     | 
| 
      
 26 
     | 
    
         
            +
            	when :exception
         
     | 
| 
      
 27 
     | 
    
         
            +
            		$stderr.puts("Raising exception...")
         
     | 
| 
      
 28 
     | 
    
         
            +
            		raise Exception.new("I love exceptions!")
         
     | 
| 
      
 29 
     | 
    
         
            +
            	when :stop
         
     | 
| 
      
 30 
     | 
    
         
            +
            		$stderr.puts("Stopping connection manually...")
         
     | 
| 
      
 31 
     | 
    
         
            +
            		$connection.stop
         
     | 
| 
      
 32 
     | 
    
         
            +
            	when :stderr
         
     | 
| 
      
 33 
     | 
    
         
            +
            		$stderr.puts object[1]
         
     | 
| 
      
 34 
     | 
    
         
            +
            		$stderr.flush
         
     | 
| 
      
 35 
     | 
    
         
            +
            	end
         
     | 
| 
       36 
36 
     | 
    
         
             
            end
         
     | 
    
        data/test/daemon.rb
    CHANGED
    
    | 
         @@ -20,8 +20,9 @@ 
     | 
|
| 
       20 
20 
     | 
    
         
             
            # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
         
     | 
| 
       21 
21 
     | 
    
         
             
            # THE SOFTWARE.
         
     | 
| 
       22 
22 
     | 
    
         | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
      
 23 
     | 
    
         
            +
            $LOAD_PATH.unshift File.expand_path("../../lib/", __FILE__)
         
     | 
| 
       24 
24 
     | 
    
         | 
| 
      
 25 
     | 
    
         
            +
            require 'rubygems'
         
     | 
| 
       25 
26 
     | 
    
         
             
            require 'pathname'
         
     | 
| 
       26 
27 
     | 
    
         | 
| 
       27 
28 
     | 
    
         
             
            require 'rexec'
         
     | 
| 
         @@ -33,41 +34,39 @@ require 'xmlrpc/server' 
     | 
|
| 
       33 
34 
     | 
    
         | 
| 
       34 
35 
     | 
    
         
             
            # Very simple XMLRPC daemon
         
     | 
| 
       35 
36 
     | 
    
         
             
            class TestDaemon < RExec::Daemon::Base
         
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
      
 37 
     | 
    
         
            +
            	@@var_directory = "/tmp/ruby-test/var"
         
     | 
| 
       37 
38 
     | 
    
         | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
                
         
     | 
| 
       41 
     | 
    
         
            -
                @@rpc_server = WEBrick::HTTPServer.new(
         
     | 
| 
       42 
     | 
    
         
            -
                  :Port => 11235,
         
     | 
| 
       43 
     | 
    
         
            -
                  :BindAddress => "0.0.0.0",
         
     | 
| 
       44 
     | 
    
         
            -
                  :SSLEnable => true,
         
     | 
| 
       45 
     | 
    
         
            -
                  :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE,
         
     | 
| 
       46 
     | 
    
         
            -
                  :SSLCertName => [["CN", WEBrick::Utils::getservername]])
         
     | 
| 
       47 
     | 
    
         
            -
                
         
     | 
| 
       48 
     | 
    
         
            -
                @@listener = XMLRPC::WEBrickServlet.new
         
     | 
| 
       49 
     | 
    
         
            -
                
         
     | 
| 
       50 
     | 
    
         
            -
                @@listener.add_handler("add") do |amount|
         
     | 
| 
       51 
     | 
    
         
            -
                  @@count ||= 0
         
     | 
| 
       52 
     | 
    
         
            -
                  @@count += amount
         
     | 
| 
       53 
     | 
    
         
            -
                end
         
     | 
| 
       54 
     | 
    
         
            -
                
         
     | 
| 
       55 
     | 
    
         
            -
                @@listener.add_handler("total") do
         
     | 
| 
       56 
     | 
    
         
            -
                  @@count
         
     | 
| 
       57 
     | 
    
         
            -
                end
         
     | 
| 
       58 
     | 
    
         
            -
                
         
     | 
| 
       59 
     | 
    
         
            -
                @@rpc_server.mount("/RPC2", @@listener)
         
     | 
| 
       60 
     | 
    
         
            -
                
         
     | 
| 
       61 
     | 
    
         
            -
                $stdout.flush
         
     | 
| 
       62 
     | 
    
         
            -
                $stderr.flush
         
     | 
| 
      
 39 
     | 
    
         
            +
            	def self.run
         
     | 
| 
      
 40 
     | 
    
         
            +
            		puts "Starting server..."
         
     | 
| 
       63 
41 
     | 
    
         | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
      
 42 
     | 
    
         
            +
            		@@rpc_server = WEBrick::HTTPServer.new(
         
     | 
| 
      
 43 
     | 
    
         
            +
            			:Port => 31337,
         
     | 
| 
      
 44 
     | 
    
         
            +
            			:BindAddress => "0.0.0.0"
         
     | 
| 
      
 45 
     | 
    
         
            +
            		)
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
            		@@listener = XMLRPC::WEBrickServlet.new
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
            		@@listener.add_handler("add") do |amount|
         
     | 
| 
      
 50 
     | 
    
         
            +
            			@@count ||= 0
         
     | 
| 
      
 51 
     | 
    
         
            +
            			@@count += amount
         
     | 
| 
      
 52 
     | 
    
         
            +
            		end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
            		@@listener.add_handler("total") do
         
     | 
| 
      
 55 
     | 
    
         
            +
            			@@count
         
     | 
| 
      
 56 
     | 
    
         
            +
            		end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
            		@@rpc_server.mount("/RPC2", @@listener)
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
            		$stdout.flush
         
     | 
| 
      
 61 
     | 
    
         
            +
            		$stderr.flush
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
            		@@rpc_server.start
         
     | 
| 
      
 64 
     | 
    
         
            +
            	end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
            	def self.shutdown
         
     | 
| 
       68 
67 
     | 
    
         
             
            		puts "Shutting down server..."
         
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
      
 68 
     | 
    
         
            +
            		@@rpc_server.shutdown
         
     | 
| 
      
 69 
     | 
    
         
            +
            	end
         
     | 
| 
       71 
70 
     | 
    
         
             
            end
         
     | 
| 
       72 
71 
     | 
    
         | 
| 
       73 
72 
     | 
    
         
             
            TestDaemon.daemonize
         
     | 
    
        data/test/helper.rb
    ADDED
    
    
    
        data/test/listing_example.rb
    CHANGED
    
    | 
         @@ -20,19 +20,20 @@ 
     | 
|
| 
       20 
20 
     | 
    
         
             
            # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
         
     | 
| 
       21 
21 
     | 
    
         
             
            # THE SOFTWARE.
         
     | 
| 
       22 
22 
     | 
    
         | 
| 
       23 
     | 
    
         
            -
            require ' 
     | 
| 
      
 23 
     | 
    
         
            +
            require 'helper'
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
       24 
25 
     | 
    
         
             
            require 'rexec'
         
     | 
| 
       25 
26 
     | 
    
         | 
| 
       26 
27 
     | 
    
         
             
            CLIENT = <<EOF
         
     | 
| 
       27 
28 
     | 
    
         | 
| 
       28 
29 
     | 
    
         
             
            $connection.run do |path|
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
      
 30 
     | 
    
         
            +
            	listing = []
         
     | 
| 
       30 
31 
     | 
    
         | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
      
 32 
     | 
    
         
            +
            	IO.popen("ls -la " + path.dump, "r+") do |ls|
         
     | 
| 
      
 33 
     | 
    
         
            +
            		listing = ls.readlines
         
     | 
| 
      
 34 
     | 
    
         
            +
            	end
         
     | 
| 
       34 
35 
     | 
    
         | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
      
 36 
     | 
    
         
            +
            	$connection.send_object(listing)
         
     | 
| 
       36 
37 
     | 
    
         
             
            end
         
     | 
| 
       37 
38 
     | 
    
         | 
| 
       38 
39 
     | 
    
         
             
            EOF
         
     | 
| 
         @@ -41,14 +42,14 @@ command = ARGV[0] || "ruby" 
     | 
|
| 
       41 
42 
     | 
    
         | 
| 
       42 
43 
     | 
    
         
             
            puts "Starting server..."
         
     | 
| 
       43 
44 
     | 
    
         
             
            RExec::start_server(CLIENT, command) do |conn, pid|
         
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
      
 45 
     | 
    
         
            +
            	puts "Sending path..."
         
     | 
| 
      
 46 
     | 
    
         
            +
            	conn.send_object("/")
         
     | 
| 
       46 
47 
     | 
    
         | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
      
 48 
     | 
    
         
            +
            	puts "Waiting for response..."
         
     | 
| 
      
 49 
     | 
    
         
            +
            	listing = conn.receive_object
         
     | 
| 
       49 
50 
     | 
    
         | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
      
 51 
     | 
    
         
            +
            	puts "Received listing:"
         
     | 
| 
      
 52 
     | 
    
         
            +
            	listing.each do |entry|
         
     | 
| 
      
 53 
     | 
    
         
            +
            		puts "\t#{entry}"
         
     | 
| 
      
 54 
     | 
    
         
            +
            	end
         
     | 
| 
       54 
55 
     | 
    
         
             
            end
         
     | 
| 
         @@ -20,30 +20,28 @@ 
     | 
|
| 
       20 
20 
     | 
    
         
             
            # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
         
     | 
| 
       21 
21 
     | 
    
         
             
            # THE SOFTWARE.
         
     | 
| 
       22 
22 
     | 
    
         | 
| 
       23 
     | 
    
         
            -
            require ' 
     | 
| 
      
 23 
     | 
    
         
            +
            require 'helper'
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
       24 
25 
     | 
    
         
             
            require 'pathname'
         
     | 
| 
       25 
26 
     | 
    
         
             
            require 'xmlrpc/client'
         
     | 
| 
       26 
     | 
    
         
            -
            require 'test/unit'
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
28 
     | 
    
         
             
            class DaemonTest < Test::Unit::TestCase
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
                assert_equal 10, total
         
     | 
| 
       48 
     | 
    
         
            -
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
            	DAEMON = (Pathname.new(__FILE__).dirname + "./daemon.rb").realpath
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            	def setup
         
     | 
| 
      
 32 
     | 
    
         
            +
            		system(DAEMON.to_s, "start")
         
     | 
| 
      
 33 
     | 
    
         
            +
            	end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            	def teardown
         
     | 
| 
      
 36 
     | 
    
         
            +
            		system(DAEMON.to_s, "stop")
         
     | 
| 
      
 37 
     | 
    
         
            +
            	end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
            	def test_connection
         
     | 
| 
      
 40 
     | 
    
         
            +
            		rpc = XMLRPC::Client.new_from_uri("http://localhost:31337")
         
     | 
| 
      
 41 
     | 
    
         
            +
            		rpc.call("add", 10)
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            		total = rpc.call("total")
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
            		assert_equal 10, total
         
     | 
| 
      
 46 
     | 
    
         
            +
            	end
         
     | 
| 
       49 
47 
     | 
    
         
             
            end
         
     | 
    
        data/test/test_server.rb
    ADDED
    
    | 
         @@ -0,0 +1,93 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # Copyright (c) 2007, 2011 Samuel G. D. Williams. <http://www.oriontransfer.co.nz>
         
     | 
| 
      
 4 
     | 
    
         
            +
            # 
         
     | 
| 
      
 5 
     | 
    
         
            +
            # Permission is hereby granted, free of charge, to any person obtaining a copy
         
     | 
| 
      
 6 
     | 
    
         
            +
            # of this software and associated documentation files (the "Software"), to deal
         
     | 
| 
      
 7 
     | 
    
         
            +
            # in the Software without restriction, including without limitation the rights
         
     | 
| 
      
 8 
     | 
    
         
            +
            # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
         
     | 
| 
      
 9 
     | 
    
         
            +
            # copies of the Software, and to permit persons to whom the Software is
         
     | 
| 
      
 10 
     | 
    
         
            +
            # furnished to do so, subject to the following conditions:
         
     | 
| 
      
 11 
     | 
    
         
            +
            # 
         
     | 
| 
      
 12 
     | 
    
         
            +
            # The above copyright notice and this permission notice shall be included in
         
     | 
| 
      
 13 
     | 
    
         
            +
            # all copies or substantial portions of the Software.
         
     | 
| 
      
 14 
     | 
    
         
            +
            # 
         
     | 
| 
      
 15 
     | 
    
         
            +
            # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         
     | 
| 
      
 16 
     | 
    
         
            +
            # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
         
     | 
| 
      
 17 
     | 
    
         
            +
            # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
         
     | 
| 
      
 18 
     | 
    
         
            +
            # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
         
     | 
| 
      
 19 
     | 
    
         
            +
            # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
         
     | 
| 
      
 20 
     | 
    
         
            +
            # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
         
     | 
| 
      
 21 
     | 
    
         
            +
            # THE SOFTWARE.
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            require 'helper'
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            require 'fileutils'
         
     | 
| 
      
 26 
     | 
    
         
            +
            require 'pathname'
         
     | 
| 
      
 27 
     | 
    
         
            +
            require 'rexec'
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            class ServerTest < Test::Unit::TestCase
         
     | 
| 
      
 30 
     | 
    
         
            +
            	def test_local_execution
         
     | 
| 
      
 31 
     | 
    
         
            +
            		code = Pathname.new(__FILE__).dirname + "./client.rb"
         
     | 
| 
      
 32 
     | 
    
         
            +
            		sobj = [1, 2, "three", 4]
         
     | 
| 
      
 33 
     | 
    
         
            +
            		stderr_text = "There was no error.. maybe?"
         
     | 
| 
      
 34 
     | 
    
         
            +
            		connection_started = false
         
     | 
| 
      
 35 
     | 
    
         
            +
            		object_received = false
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
            		RExec::start_server(code.read, "ruby", :passthrough => []) do |conn, task|
         
     | 
| 
      
 38 
     | 
    
         
            +
            			connection_started = true
         
     | 
| 
      
 39 
     | 
    
         
            +
            			conn.send_object([:bounce, sobj])
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            			assert_equal sobj, conn.receive_object
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            			assert_raises(Exception) do
         
     | 
| 
      
 44 
     | 
    
         
            +
            				conn.send_object([:exception])
         
     | 
| 
      
 45 
     | 
    
         
            +
            				obj = conn.receive_object
         
     | 
| 
      
 46 
     | 
    
         
            +
                    
         
     | 
| 
      
 47 
     | 
    
         
            +
            				puts "Received object which should have been exception: #{obj.inspect}"
         
     | 
| 
      
 48 
     | 
    
         
            +
            			end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            			conn.dump_errors
         
     | 
| 
      
 51 
     | 
    
         
            +
            			conn.send_object([:stderr, stderr_text])
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            			puts "Attemping to read from #{conn.error.to_i}..."
         
     | 
| 
      
 54 
     | 
    
         
            +
            			assert_equal stderr_text, conn.error.readline.chomp
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
            			conn.stop
         
     | 
| 
      
 57 
     | 
    
         
            +
            		end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            		assert(connection_started, "Connection started")
         
     | 
| 
      
 60 
     | 
    
         
            +
            	end
         
     | 
| 
      
 61 
     | 
    
         
            +
              
         
     | 
| 
      
 62 
     | 
    
         
            +
            	def test_shell_execution
         
     | 
| 
      
 63 
     | 
    
         
            +
            		connection_started = false
         
     | 
| 
      
 64 
     | 
    
         
            +
            		code = Pathname.new(__FILE__).dirname + "client.rb"
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
            		test_obj = [1, 2, 3, 4, "five"]
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
            		RExec::start_server(code.read, "/bin/sh -c ruby", :passthrough => []) do |conn, task|
         
     | 
| 
      
 69 
     | 
    
         
            +
            			connection_started = true
         
     | 
| 
      
 70 
     | 
    
         
            +
            			conn.send_object([:bounce, test_obj])
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
            			assert_equal test_obj, conn.receive_object
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
            			conn.stop
         
     | 
| 
      
 75 
     | 
    
         
            +
            		end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
            		assert(connection_started, "Connection started")
         
     | 
| 
      
 78 
     | 
    
         
            +
            	end
         
     | 
| 
      
 79 
     | 
    
         
            +
              
         
     | 
| 
      
 80 
     | 
    
         
            +
            	def test_shell_execution_non_block
         
     | 
| 
      
 81 
     | 
    
         
            +
            		connection_started = false
         
     | 
| 
      
 82 
     | 
    
         
            +
            		code = Pathname.new(__FILE__).dirname + "client.rb"
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
            		test_obj = [1, 2, 3, 4, "five"]
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
            		conn, task = RExec::start_server(code.read, "/bin/sh -c ruby", :passthrough => [])
         
     | 
| 
      
 87 
     | 
    
         
            +
            		conn.send_object([:bounce, test_obj])
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
            		assert_equal test_obj, conn.receive_object
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
            		conn.stop
         
     | 
| 
      
 92 
     | 
    
         
            +
            	end
         
     | 
| 
      
 93 
     | 
    
         
            +
            end
         
     | 
    
        data/test/test_task.rb
    ADDED
    
    | 
         @@ -0,0 +1,168 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # Copyright (c) 2007, 2011 Samuel G. D. Williams. <http://www.oriontransfer.co.nz>
         
     | 
| 
      
 4 
     | 
    
         
            +
            # 
         
     | 
| 
      
 5 
     | 
    
         
            +
            # Permission is hereby granted, free of charge, to any person obtaining a copy
         
     | 
| 
      
 6 
     | 
    
         
            +
            # of this software and associated documentation files (the "Software"), to deal
         
     | 
| 
      
 7 
     | 
    
         
            +
            # in the Software without restriction, including without limitation the rights
         
     | 
| 
      
 8 
     | 
    
         
            +
            # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
         
     | 
| 
      
 9 
     | 
    
         
            +
            # copies of the Software, and to permit persons to whom the Software is
         
     | 
| 
      
 10 
     | 
    
         
            +
            # furnished to do so, subject to the following conditions:
         
     | 
| 
      
 11 
     | 
    
         
            +
            # 
         
     | 
| 
      
 12 
     | 
    
         
            +
            # The above copyright notice and this permission notice shall be included in
         
     | 
| 
      
 13 
     | 
    
         
            +
            # all copies or substantial portions of the Software.
         
     | 
| 
      
 14 
     | 
    
         
            +
            # 
         
     | 
| 
      
 15 
     | 
    
         
            +
            # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         
     | 
| 
      
 16 
     | 
    
         
            +
            # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
         
     | 
| 
      
 17 
     | 
    
         
            +
            # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
         
     | 
| 
      
 18 
     | 
    
         
            +
            # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
         
     | 
| 
      
 19 
     | 
    
         
            +
            # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
         
     | 
| 
      
 20 
     | 
    
         
            +
            # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
         
     | 
| 
      
 21 
     | 
    
         
            +
            # THE SOFTWARE.
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            require 'helper'
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            require 'fileutils'
         
     | 
| 
      
 26 
     | 
    
         
            +
            require 'pathname'
         
     | 
| 
      
 27 
     | 
    
         
            +
            require 'rexec'
         
     | 
| 
      
 28 
     | 
    
         
            +
            require 'timeout'
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            class TaskTest < Test::Unit::TestCase
         
     | 
| 
      
 31 
     | 
    
         
            +
            	TASK_PATH = Pathname.new(__FILE__).dirname + "./task.rb"
         
     | 
| 
      
 32 
     | 
    
         
            +
            	TEXT = "The quick brown fox jumped over the lazy dog."
         
     | 
| 
      
 33 
     | 
    
         
            +
            	STDOUT_TEXT = "STDOUT: " + TEXT
         
     | 
| 
      
 34 
     | 
    
         
            +
            	STDERR_TEXT = "STDERR: " + TEXT
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            	def test_script_execution
         
     | 
| 
      
 37 
     | 
    
         
            +
            		RExec::Task.open(TASK_PATH) do |task|
         
     | 
| 
      
 38 
     | 
    
         
            +
            			task.input.puts(TEXT)
         
     | 
| 
      
 39 
     | 
    
         
            +
            			task.input.close
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            			assert_equal STDOUT_TEXT, task.output.readline.chomp
         
     | 
| 
      
 42 
     | 
    
         
            +
            			assert_equal STDERR_TEXT, task.error.readline.chomp
         
     | 
| 
      
 43 
     | 
    
         
            +
            		end
         
     | 
| 
      
 44 
     | 
    
         
            +
            	end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            	def test_ruby_execution
         
     | 
| 
      
 47 
     | 
    
         
            +
            		RExec::Task.open(["ruby", '-']) do |task|
         
     | 
| 
      
 48 
     | 
    
         
            +
            			task.input.puts(TASK_PATH.read)
         
     | 
| 
      
 49 
     | 
    
         
            +
            			task.input.puts("\004")
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            			task.input.puts(TEXT)
         
     | 
| 
      
 52 
     | 
    
         
            +
            			task.input.close
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
            			assert_equal STDOUT_TEXT, task.output.readline.chomp
         
     | 
| 
      
 55 
     | 
    
         
            +
            			assert_equal STDERR_TEXT, task.error.readline.chomp
         
     | 
| 
      
 56 
     | 
    
         
            +
            		end
         
     | 
| 
      
 57 
     | 
    
         
            +
            	end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            	def test_spawn_child
         
     | 
| 
      
 60 
     | 
    
         
            +
            		rd, wr = IO.pipe
         
     | 
| 
      
 61 
     | 
    
         
            +
            		pid = RExec::Task.spawn_child do
         
     | 
| 
      
 62 
     | 
    
         
            +
            			rd.close
         
     | 
| 
      
 63 
     | 
    
         
            +
            			wr.write(TEXT)
         
     | 
| 
      
 64 
     | 
    
         
            +
            			wr.close
         
     | 
| 
      
 65 
     | 
    
         
            +
            			exit(10)
         
     | 
| 
      
 66 
     | 
    
         
            +
            		end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
            		wr.close
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
            		pid, status = Process.wait2(pid)
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
            		assert_equal rd.read, TEXT
         
     | 
| 
      
 73 
     | 
    
         
            +
            		assert_equal status, status
         
     | 
| 
      
 74 
     | 
    
         
            +
            	end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
            	def test_spawn_daemon
         
     | 
| 
      
 77 
     | 
    
         
            +
            		rd, wr = IO.pipe
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
            		# We launch one daemon to start another. The first daemon will exit, but the second will keep on running.
         
     | 
| 
      
 80 
     | 
    
         
            +
            		ppid = RExec::Task.spawn_daemon do
         
     | 
| 
      
 81 
     | 
    
         
            +
            			RExec::Task.spawn_daemon do
         
     | 
| 
      
 82 
     | 
    
         
            +
            				rd.close
         
     | 
| 
      
 83 
     | 
    
         
            +
            				sleep 0.5
         
     | 
| 
      
 84 
     | 
    
         
            +
            				wr.puts(TEXT, Process.pid)
         
     | 
| 
      
 85 
     | 
    
         
            +
            				wr.close
         
     | 
| 
      
 86 
     | 
    
         
            +
            				sleep 0.5
         
     | 
| 
      
 87 
     | 
    
         
            +
            			end
         
     | 
| 
      
 88 
     | 
    
         
            +
            		end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
            		wr.close
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
            		Timeout::timeout(5) do
         
     | 
| 
      
 93 
     | 
    
         
            +
            			until !RExec::Task.running?(ppid) do
         
     | 
| 
      
 94 
     | 
    
         
            +
            				sleep(0.1)
         
     | 
| 
      
 95 
     | 
    
         
            +
            			end
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
            			text = rd.readline.chomp
         
     | 
| 
      
 98 
     | 
    
         
            +
            			pid = rd.readline.chomp.to_i
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
            			assert_raises(EOFError) do
         
     | 
| 
      
 101 
     | 
    
         
            +
            				rd.readline
         
     | 
| 
      
 102 
     | 
    
         
            +
            			end
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
            			assert_equal text, TEXT
         
     | 
| 
      
 105 
     | 
    
         
            +
            			assert RExec::Task.running?(pid)
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
            			until !RExec::Task.running?(pid) do
         
     | 
| 
      
 108 
     | 
    
         
            +
            				sleep(0.1)
         
     | 
| 
      
 109 
     | 
    
         
            +
            			end
         
     | 
| 
      
 110 
     | 
    
         
            +
            		end
         
     | 
| 
      
 111 
     | 
    
         
            +
            	end
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
            	def test_task
         
     | 
| 
      
 114 
     | 
    
         
            +
            		test_results = Proc.new do |input, output, error|
         
     | 
| 
      
 115 
     | 
    
         
            +
            			input.puts TEXT
         
     | 
| 
      
 116 
     | 
    
         
            +
            			input.flush
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
            			assert_equal output.readline.chomp, STDOUT_TEXT
         
     | 
| 
      
 119 
     | 
    
         
            +
            			assert_equal error.readline.chomp, STDERR_TEXT
         
     | 
| 
      
 120 
     | 
    
         
            +
            		end
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
            		RExec::Task.open(TASK_PATH) do |task|
         
     | 
| 
      
 123 
     | 
    
         
            +
            			test_results.call(task.input, task.output, task.error)
         
     | 
| 
      
 124 
     | 
    
         
            +
            		end
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
            		rd, wr = IO.pipe
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
            		RExec::Task.open(TASK_PATH, :in => rd) do |task|
         
     | 
| 
      
 129 
     | 
    
         
            +
            			test_results.call(wr, task.output, task.error)
         
     | 
| 
      
 130 
     | 
    
         
            +
            		end
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
            		assert rd.closed?
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
            		assert_raises(Errno::EPIPE) do
         
     | 
| 
      
 135 
     | 
    
         
            +
            			wr.puts "The pipe is closed on the other side.."
         
     | 
| 
      
 136 
     | 
    
         
            +
            		end
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
            		in_rd, in_wr = IO.pipe
         
     | 
| 
      
 139 
     | 
    
         
            +
            		out_rd, out_wr = IO.pipe
         
     | 
| 
      
 140 
     | 
    
         
            +
            		err_rd, err_wr = IO.pipe
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
            		spawn_child_daemon = Proc.new do
         
     | 
| 
      
 143 
     | 
    
         
            +
            			task = RExec::Task.open(TASK_PATH, :in => in_rd, :out => out_wr, :err => err_wr, :daemonize => true)
         
     | 
| 
      
 144 
     | 
    
         
            +
            		end
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
            		task = RExec::Task.open(spawn_child_daemon, :daemonize => true)
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
            		until !task.running? do
         
     | 
| 
      
 149 
     | 
    
         
            +
            			sleep 0.1
         
     | 
| 
      
 150 
     | 
    
         
            +
            		end
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
            		test_results.call(in_wr, out_rd, err_rd)
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
            		assert !task.running?
         
     | 
| 
      
 155 
     | 
    
         
            +
            	end
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
            	def test_task_passthrough
         
     | 
| 
      
 158 
     | 
    
         
            +
            		script = "echo " + "Hello World!".dump + " | #{TASK_PATH.realpath.to_s.dump}"
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
            		RExec::Task.open(script, :passthrough => :all) do
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
      
 162 
     | 
    
         
            +
            		end
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
            		[$stdin, $stdout, $stderr].each do |io|
         
     | 
| 
      
 165 
     | 
    
         
            +
            			assert !io.closed?
         
     | 
| 
      
 166 
     | 
    
         
            +
            		end
         
     | 
| 
      
 167 
     | 
    
         
            +
            	end
         
     | 
| 
      
 168 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,38 +1,29 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            --- !ruby/object:Gem::Specification 
     | 
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: rexec
         
     | 
| 
       3 
     | 
    
         
            -
            version: !ruby/object:Gem::Version 
     | 
| 
       4 
     | 
    
         
            -
               
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: 1.5.0
         
     | 
| 
       5 
5 
     | 
    
         
             
              prerelease: 
         
     | 
| 
       6 
     | 
    
         
            -
              segments: 
         
     | 
| 
       7 
     | 
    
         
            -
              - 1
         
     | 
| 
       8 
     | 
    
         
            -
              - 4
         
     | 
| 
       9 
     | 
    
         
            -
              - 1
         
     | 
| 
       10 
     | 
    
         
            -
              version: 1.4.1
         
     | 
| 
       11 
6 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       12 
     | 
    
         
            -
            authors: 
     | 
| 
      
 7 
     | 
    
         
            +
            authors:
         
     | 
| 
       13 
8 
     | 
    
         
             
            - Samuel Williams
         
     | 
| 
       14 
9 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       15 
10 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       16 
11 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
            date: 2011-08-09 00:00:00 Z
         
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2012-10-15 00:00:00.000000000 Z
         
     | 
| 
       19 
13 
     | 
    
         
             
            dependencies: []
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
14 
     | 
    
         
             
            description: 
         
     | 
| 
       22 
     | 
    
         
            -
            email: samuel 
     | 
| 
       23 
     | 
    
         
            -
            executables: 
     | 
| 
      
 15 
     | 
    
         
            +
            email: samuel@oriontransfer.org
         
     | 
| 
      
 16 
     | 
    
         
            +
            executables:
         
     | 
| 
       24 
17 
     | 
    
         
             
            - daemon-exec
         
     | 
| 
       25 
18 
     | 
    
         
             
            extensions: []
         
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
19 
     | 
    
         
             
            extra_rdoc_files: []
         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
            files: 
         
     | 
| 
      
 20 
     | 
    
         
            +
            files:
         
     | 
| 
       30 
21 
     | 
    
         
             
            - bin/daemon-exec
         
     | 
| 
       31 
22 
     | 
    
         
             
            - lib/rexec/client.rb
         
     | 
| 
       32 
23 
     | 
    
         
             
            - lib/rexec/connection.rb
         
     | 
| 
       33 
24 
     | 
    
         
             
            - lib/rexec/daemon/base.rb
         
     | 
| 
       34 
25 
     | 
    
         
             
            - lib/rexec/daemon/controller.rb
         
     | 
| 
       35 
     | 
    
         
            -
            - lib/rexec/daemon/ 
     | 
| 
      
 26 
     | 
    
         
            +
            - lib/rexec/daemon/process_file.rb
         
     | 
| 
       36 
27 
     | 
    
         
             
            - lib/rexec/daemon.rb
         
     | 
| 
       37 
28 
     | 
    
         
             
            - lib/rexec/environment.rb
         
     | 
| 
       38 
29 
     | 
    
         
             
            - lib/rexec/priviledges.rb
         
     | 
| 
         @@ -44,49 +35,39 @@ files: 
     | 
|
| 
       44 
35 
     | 
    
         
             
            - lib/rexec.rb
         
     | 
| 
       45 
36 
     | 
    
         
             
            - test/client.rb
         
     | 
| 
       46 
37 
     | 
    
         
             
            - test/daemon.rb
         
     | 
| 
       47 
     | 
    
         
            -
            - test/ 
     | 
| 
      
 38 
     | 
    
         
            +
            - test/helper.rb
         
     | 
| 
       48 
39 
     | 
    
         
             
            - test/interrupt.rb
         
     | 
| 
       49 
40 
     | 
    
         
             
            - test/listing_example.rb
         
     | 
| 
       50 
     | 
    
         
            -
            - test/remote_server_test.rb
         
     | 
| 
       51 
     | 
    
         
            -
            - test/server_test.rb
         
     | 
| 
       52 
41 
     | 
    
         
             
            - test/task.rb
         
     | 
| 
       53 
     | 
    
         
            -
            - test/ 
     | 
| 
      
 42 
     | 
    
         
            +
            - test/test_daemon.rb
         
     | 
| 
      
 43 
     | 
    
         
            +
            - test/test_remote_server.rb
         
     | 
| 
      
 44 
     | 
    
         
            +
            - test/test_server.rb
         
     | 
| 
      
 45 
     | 
    
         
            +
            - test/test_task.rb
         
     | 
| 
       54 
46 
     | 
    
         
             
            - README.md
         
     | 
| 
      
 47 
     | 
    
         
            +
            - rakefile.rb
         
     | 
| 
      
 48 
     | 
    
         
            +
            - Gemfile
         
     | 
| 
       55 
49 
     | 
    
         
             
            homepage: http://www.oriontransfer.co.nz/gems/rexec
         
     | 
| 
       56 
50 
     | 
    
         
             
            licenses: []
         
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
51 
     | 
    
         
             
            post_install_message: 
         
     | 
| 
       59 
52 
     | 
    
         
             
            rdoc_options: []
         
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
            require_paths: 
         
     | 
| 
      
 53 
     | 
    
         
            +
            require_paths:
         
     | 
| 
       62 
54 
     | 
    
         
             
            - lib
         
     | 
| 
       63 
     | 
    
         
            -
            required_ruby_version: !ruby/object:Gem::Requirement 
     | 
| 
      
 55 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         
     | 
| 
       64 
56 
     | 
    
         
             
              none: false
         
     | 
| 
       65 
     | 
    
         
            -
              requirements: 
     | 
| 
       66 
     | 
    
         
            -
              - -  
     | 
| 
       67 
     | 
    
         
            -
                - !ruby/object:Gem::Version 
     | 
| 
       68 
     | 
    
         
            -
                   
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
                  - 0
         
     | 
| 
       71 
     | 
    
         
            -
                  version: "0"
         
     | 
| 
       72 
     | 
    
         
            -
            required_rubygems_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 57 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 58 
     | 
    
         
            +
              - - ! '>='
         
     | 
| 
      
 59 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 60 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 61 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
       73 
62 
     | 
    
         
             
              none: false
         
     | 
| 
       74 
     | 
    
         
            -
              requirements: 
     | 
| 
       75 
     | 
    
         
            -
              - -  
     | 
| 
       76 
     | 
    
         
            -
                - !ruby/object:Gem::Version 
     | 
| 
       77 
     | 
    
         
            -
                   
     | 
| 
       78 
     | 
    
         
            -
                  segments: 
         
     | 
| 
       79 
     | 
    
         
            -
                  - 0
         
     | 
| 
       80 
     | 
    
         
            -
                  version: "0"
         
     | 
| 
      
 63 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 64 
     | 
    
         
            +
              - - ! '>='
         
     | 
| 
      
 65 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 66 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
       81 
67 
     | 
    
         
             
            requirements: []
         
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
       83 
68 
     | 
    
         
             
            rubyforge_project: 
         
     | 
| 
       84 
     | 
    
         
            -
            rubygems_version: 1.8. 
     | 
| 
      
 69 
     | 
    
         
            +
            rubygems_version: 1.8.24
         
     | 
| 
       85 
70 
     | 
    
         
             
            signing_key: 
         
     | 
| 
       86 
71 
     | 
    
         
             
            specification_version: 3
         
     | 
| 
       87 
     | 
    
         
            -
            summary: RExec  
     | 
| 
       88 
     | 
    
         
            -
            test_files: 
         
     | 
| 
       89 
     | 
    
         
            -
            - test/daemon_test.rb
         
     | 
| 
       90 
     | 
    
         
            -
            - test/remote_server_test.rb
         
     | 
| 
       91 
     | 
    
         
            -
            - test/server_test.rb
         
     | 
| 
       92 
     | 
    
         
            -
            - test/task_test.rb
         
     | 
| 
      
 72 
     | 
    
         
            +
            summary: RExec assists with and manages the execution of child and daemon tasks.
         
     | 
| 
      
 73 
     | 
    
         
            +
            test_files: []
         
     | 
    
        data/test/server_test.rb
    DELETED
    
    | 
         @@ -1,94 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            #!/usr/bin/env ruby
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            # Copyright (c) 2007, 2011 Samuel G. D. Williams. <http://www.oriontransfer.co.nz>
         
     | 
| 
       4 
     | 
    
         
            -
            # 
         
     | 
| 
       5 
     | 
    
         
            -
            # Permission is hereby granted, free of charge, to any person obtaining a copy
         
     | 
| 
       6 
     | 
    
         
            -
            # of this software and associated documentation files (the "Software"), to deal
         
     | 
| 
       7 
     | 
    
         
            -
            # in the Software without restriction, including without limitation the rights
         
     | 
| 
       8 
     | 
    
         
            -
            # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
         
     | 
| 
       9 
     | 
    
         
            -
            # copies of the Software, and to permit persons to whom the Software is
         
     | 
| 
       10 
     | 
    
         
            -
            # furnished to do so, subject to the following conditions:
         
     | 
| 
       11 
     | 
    
         
            -
            # 
         
     | 
| 
       12 
     | 
    
         
            -
            # The above copyright notice and this permission notice shall be included in
         
     | 
| 
       13 
     | 
    
         
            -
            # all copies or substantial portions of the Software.
         
     | 
| 
       14 
     | 
    
         
            -
            # 
         
     | 
| 
       15 
     | 
    
         
            -
            # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         
     | 
| 
       16 
     | 
    
         
            -
            # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
         
     | 
| 
       17 
     | 
    
         
            -
            # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
         
     | 
| 
       18 
     | 
    
         
            -
            # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
         
     | 
| 
       19 
     | 
    
         
            -
            # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
         
     | 
| 
       20 
     | 
    
         
            -
            # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
         
     | 
| 
       21 
     | 
    
         
            -
            # THE SOFTWARE.
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
            require 'rubygems'
         
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
            require 'test/unit'
         
     | 
| 
       26 
     | 
    
         
            -
            require 'fileutils'
         
     | 
| 
       27 
     | 
    
         
            -
            require 'pathname'
         
     | 
| 
       28 
     | 
    
         
            -
            require 'rexec'
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
            class ServerTest < Test::Unit::TestCase
         
     | 
| 
       31 
     | 
    
         
            -
              def test_local_execution
         
     | 
| 
       32 
     | 
    
         
            -
                code = Pathname.new(__FILE__).dirname + "./client.rb"
         
     | 
| 
       33 
     | 
    
         
            -
                sobj = [1, 2, "three", 4]
         
     | 
| 
       34 
     | 
    
         
            -
                stderr_text = "There was no error.. maybe?"
         
     | 
| 
       35 
     | 
    
         
            -
                connection_started = false
         
     | 
| 
       36 
     | 
    
         
            -
                object_received = false
         
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
                RExec::start_server(code.read, "ruby", :passthrough => []) do |conn, task|
         
     | 
| 
       39 
     | 
    
         
            -
                  connection_started = true
         
     | 
| 
       40 
     | 
    
         
            -
                  conn.send_object([:bounce, sobj])
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
                  assert_equal sobj, conn.receive_object
         
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
                  assert_raises(Exception) do
         
     | 
| 
       45 
     | 
    
         
            -
                    conn.send_object([:exception])
         
     | 
| 
       46 
     | 
    
         
            -
                    obj = conn.receive_object
         
     | 
| 
       47 
     | 
    
         
            -
                    
         
     | 
| 
       48 
     | 
    
         
            -
                    puts "Received object which should have been exception: #{obj.inspect}"
         
     | 
| 
       49 
     | 
    
         
            -
                  end
         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
                  conn.dump_errors
         
     | 
| 
       52 
     | 
    
         
            -
                  conn.send_object([:stderr, stderr_text])
         
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
                  puts "Attemping to read from #{conn.error.to_i}..."
         
     | 
| 
       55 
     | 
    
         
            -
                  assert_equal stderr_text, conn.error.readline.chomp
         
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
                  conn.stop
         
     | 
| 
       58 
     | 
    
         
            -
                end
         
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
                assert(connection_started, "Connection started")
         
     | 
| 
       61 
     | 
    
         
            -
              end
         
     | 
| 
       62 
     | 
    
         
            -
              
         
     | 
| 
       63 
     | 
    
         
            -
              def test_shell_execution
         
     | 
| 
       64 
     | 
    
         
            -
                connection_started = false
         
     | 
| 
       65 
     | 
    
         
            -
                code = Pathname.new(__FILE__).dirname + "client.rb"
         
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
                test_obj = [1, 2, 3, 4, "five"]
         
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
                RExec::start_server(code.read, "/bin/sh -c ruby", :passthrough => []) do |conn, task|
         
     | 
| 
       70 
     | 
    
         
            -
                  connection_started = true
         
     | 
| 
       71 
     | 
    
         
            -
                  conn.send_object([:bounce, test_obj])
         
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
                  assert_equal test_obj, conn.receive_object
         
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
                  conn.stop
         
     | 
| 
       76 
     | 
    
         
            -
                end
         
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
                assert(connection_started, "Connection started")
         
     | 
| 
       79 
     | 
    
         
            -
              end
         
     | 
| 
       80 
     | 
    
         
            -
              
         
     | 
| 
       81 
     | 
    
         
            -
              def test_shell_execution_non_block
         
     | 
| 
       82 
     | 
    
         
            -
                connection_started = false
         
     | 
| 
       83 
     | 
    
         
            -
                code = Pathname.new(__FILE__).dirname + "client.rb"
         
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
                test_obj = [1, 2, 3, 4, "five"]
         
     | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
                conn, task = RExec::start_server(code.read, "/bin/sh -c ruby", :passthrough => [])
         
     | 
| 
       88 
     | 
    
         
            -
                conn.send_object([:bounce, test_obj])
         
     | 
| 
       89 
     | 
    
         
            -
             
     | 
| 
       90 
     | 
    
         
            -
                assert_equal test_obj, conn.receive_object
         
     | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
       92 
     | 
    
         
            -
                conn.stop
         
     | 
| 
       93 
     | 
    
         
            -
              end
         
     | 
| 
       94 
     | 
    
         
            -
            end
         
     | 
    
        data/test/task_test.rb
    DELETED
    
    | 
         @@ -1,170 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            #!/usr/bin/env ruby
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            # Copyright (c) 2007, 2011 Samuel G. D. Williams. <http://www.oriontransfer.co.nz>
         
     | 
| 
       4 
     | 
    
         
            -
            # 
         
     | 
| 
       5 
     | 
    
         
            -
            # Permission is hereby granted, free of charge, to any person obtaining a copy
         
     | 
| 
       6 
     | 
    
         
            -
            # of this software and associated documentation files (the "Software"), to deal
         
     | 
| 
       7 
     | 
    
         
            -
            # in the Software without restriction, including without limitation the rights
         
     | 
| 
       8 
     | 
    
         
            -
            # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
         
     | 
| 
       9 
     | 
    
         
            -
            # copies of the Software, and to permit persons to whom the Software is
         
     | 
| 
       10 
     | 
    
         
            -
            # furnished to do so, subject to the following conditions:
         
     | 
| 
       11 
     | 
    
         
            -
            # 
         
     | 
| 
       12 
     | 
    
         
            -
            # The above copyright notice and this permission notice shall be included in
         
     | 
| 
       13 
     | 
    
         
            -
            # all copies or substantial portions of the Software.
         
     | 
| 
       14 
     | 
    
         
            -
            # 
         
     | 
| 
       15 
     | 
    
         
            -
            # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         
     | 
| 
       16 
     | 
    
         
            -
            # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
         
     | 
| 
       17 
     | 
    
         
            -
            # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
         
     | 
| 
       18 
     | 
    
         
            -
            # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
         
     | 
| 
       19 
     | 
    
         
            -
            # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
         
     | 
| 
       20 
     | 
    
         
            -
            # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
         
     | 
| 
       21 
     | 
    
         
            -
            # THE SOFTWARE.
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
            require 'rubygems'
         
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
            require 'test/unit'
         
     | 
| 
       26 
     | 
    
         
            -
            require 'fileutils'
         
     | 
| 
       27 
     | 
    
         
            -
            require 'pathname'
         
     | 
| 
       28 
     | 
    
         
            -
            require 'rexec'
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
            require 'timeout'
         
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
            class TaskTest < Test::Unit::TestCase
         
     | 
| 
       33 
     | 
    
         
            -
              TASK_PATH = Pathname.new(__FILE__).dirname + "./task.rb"
         
     | 
| 
       34 
     | 
    
         
            -
              TEXT = "The quick brown fox jumped over the lazy dog."
         
     | 
| 
       35 
     | 
    
         
            -
              STDOUT_TEXT = "STDOUT: " + TEXT
         
     | 
| 
       36 
     | 
    
         
            -
              STDERR_TEXT = "STDERR: " + TEXT
         
     | 
| 
       37 
     | 
    
         
            -
              
         
     | 
| 
       38 
     | 
    
         
            -
              def test_script_execution
         
     | 
| 
       39 
     | 
    
         
            -
                RExec::Task.open(TASK_PATH) do |task|
         
     | 
| 
       40 
     | 
    
         
            -
                  task.input.puts(TEXT)
         
     | 
| 
       41 
     | 
    
         
            -
                  task.input.close
         
     | 
| 
       42 
     | 
    
         
            -
                  
         
     | 
| 
       43 
     | 
    
         
            -
                  assert_equal STDOUT_TEXT, task.output.readline.chomp
         
     | 
| 
       44 
     | 
    
         
            -
                  assert_equal STDERR_TEXT, task.error.readline.chomp
         
     | 
| 
       45 
     | 
    
         
            -
                end
         
     | 
| 
       46 
     | 
    
         
            -
              end
         
     | 
| 
       47 
     | 
    
         
            -
              
         
     | 
| 
       48 
     | 
    
         
            -
              def test_ruby_execution
         
     | 
| 
       49 
     | 
    
         
            -
                RExec::Task.open("ruby") do |task|
         
     | 
| 
       50 
     | 
    
         
            -
                  task.input.puts(TASK_PATH.read)
         
     | 
| 
       51 
     | 
    
         
            -
                  task.input.puts("\004")
         
     | 
| 
       52 
     | 
    
         
            -
                  
         
     | 
| 
       53 
     | 
    
         
            -
                  task.input.puts(TEXT)
         
     | 
| 
       54 
     | 
    
         
            -
                  task.input.close
         
     | 
| 
       55 
     | 
    
         
            -
                  
         
     | 
| 
       56 
     | 
    
         
            -
                  assert_equal STDOUT_TEXT, task.output.readline.chomp
         
     | 
| 
       57 
     | 
    
         
            -
                  assert_equal STDERR_TEXT, task.error.readline.chomp
         
     | 
| 
       58 
     | 
    
         
            -
                end
         
     | 
| 
       59 
     | 
    
         
            -
              end
         
     | 
| 
       60 
     | 
    
         
            -
              
         
     | 
| 
       61 
     | 
    
         
            -
              def test_spawn_child
         
     | 
| 
       62 
     | 
    
         
            -
                rd, wr = IO.pipe
         
     | 
| 
       63 
     | 
    
         
            -
                pid = RExec::Task.spawn_child do
         
     | 
| 
       64 
     | 
    
         
            -
                  rd.close
         
     | 
| 
       65 
     | 
    
         
            -
                  wr.write(TEXT)
         
     | 
| 
       66 
     | 
    
         
            -
                  wr.close
         
     | 
| 
       67 
     | 
    
         
            -
                  exit(10)
         
     | 
| 
       68 
     | 
    
         
            -
                end
         
     | 
| 
       69 
     | 
    
         
            -
                
         
     | 
| 
       70 
     | 
    
         
            -
                wr.close
         
     | 
| 
       71 
     | 
    
         
            -
                
         
     | 
| 
       72 
     | 
    
         
            -
                pid, status = Process.wait2(pid)
         
     | 
| 
       73 
     | 
    
         
            -
                
         
     | 
| 
       74 
     | 
    
         
            -
                assert_equal rd.read, TEXT
         
     | 
| 
       75 
     | 
    
         
            -
                assert_equal status, status
         
     | 
| 
       76 
     | 
    
         
            -
              end
         
     | 
| 
       77 
     | 
    
         
            -
              
         
     | 
| 
       78 
     | 
    
         
            -
              def test_spawn_daemon
         
     | 
| 
       79 
     | 
    
         
            -
                rd, wr = IO.pipe
         
     | 
| 
       80 
     | 
    
         
            -
                
         
     | 
| 
       81 
     | 
    
         
            -
                # We launch one daemon to start another. The first daemon will exit, but the second will keep on running.
         
     | 
| 
       82 
     | 
    
         
            -
                ppid = RExec::Task.spawn_daemon do
         
     | 
| 
       83 
     | 
    
         
            -
                  RExec::Task.spawn_daemon do
         
     | 
| 
       84 
     | 
    
         
            -
                    rd.close
         
     | 
| 
       85 
     | 
    
         
            -
                    sleep 0.5
         
     | 
| 
       86 
     | 
    
         
            -
                    wr.puts(TEXT, Process.pid)
         
     | 
| 
       87 
     | 
    
         
            -
                    wr.close
         
     | 
| 
       88 
     | 
    
         
            -
                    sleep 0.5
         
     | 
| 
       89 
     | 
    
         
            -
                  end
         
     | 
| 
       90 
     | 
    
         
            -
                end
         
     | 
| 
       91 
     | 
    
         
            -
                
         
     | 
| 
       92 
     | 
    
         
            -
                wr.close
         
     | 
| 
       93 
     | 
    
         
            -
                
         
     | 
| 
       94 
     | 
    
         
            -
                Timeout::timeout(5) do
         
     | 
| 
       95 
     | 
    
         
            -
                  until !RExec::Task.running?(ppid) do
         
     | 
| 
       96 
     | 
    
         
            -
                    sleep(0.1)
         
     | 
| 
       97 
     | 
    
         
            -
                  end
         
     | 
| 
       98 
     | 
    
         
            -
                  
         
     | 
| 
       99 
     | 
    
         
            -
                  text = rd.readline.chomp
         
     | 
| 
       100 
     | 
    
         
            -
                  pid = rd.readline.chomp.to_i
         
     | 
| 
       101 
     | 
    
         
            -
                  
         
     | 
| 
       102 
     | 
    
         
            -
                  assert_raises(EOFError) do
         
     | 
| 
       103 
     | 
    
         
            -
                    rd.readline
         
     | 
| 
       104 
     | 
    
         
            -
                  end
         
     | 
| 
       105 
     | 
    
         
            -
                  
         
     | 
| 
       106 
     | 
    
         
            -
                  assert_equal text, TEXT
         
     | 
| 
       107 
     | 
    
         
            -
                  assert RExec::Task.running?(pid)
         
     | 
| 
       108 
     | 
    
         
            -
                  
         
     | 
| 
       109 
     | 
    
         
            -
                  until !RExec::Task.running?(pid) do
         
     | 
| 
       110 
     | 
    
         
            -
                    sleep(0.1)
         
     | 
| 
       111 
     | 
    
         
            -
                  end
         
     | 
| 
       112 
     | 
    
         
            -
                end
         
     | 
| 
       113 
     | 
    
         
            -
              end
         
     | 
| 
       114 
     | 
    
         
            -
              
         
     | 
| 
       115 
     | 
    
         
            -
              def test_task
         
     | 
| 
       116 
     | 
    
         
            -
                test_results = Proc.new do |input, output, error|
         
     | 
| 
       117 
     | 
    
         
            -
                  input.puts TEXT
         
     | 
| 
       118 
     | 
    
         
            -
                  input.flush
         
     | 
| 
       119 
     | 
    
         
            -
                  
         
     | 
| 
       120 
     | 
    
         
            -
                  assert_equal output.readline.chomp, STDOUT_TEXT
         
     | 
| 
       121 
     | 
    
         
            -
                  assert_equal error.readline.chomp, STDERR_TEXT
         
     | 
| 
       122 
     | 
    
         
            -
                end
         
     | 
| 
       123 
     | 
    
         
            -
                
         
     | 
| 
       124 
     | 
    
         
            -
                RExec::Task.open(TASK_PATH) do |task|
         
     | 
| 
       125 
     | 
    
         
            -
                  test_results.call(task.input, task.output, task.error)
         
     | 
| 
       126 
     | 
    
         
            -
                end
         
     | 
| 
       127 
     | 
    
         
            -
                
         
     | 
| 
       128 
     | 
    
         
            -
                rd, wr = IO.pipe
         
     | 
| 
       129 
     | 
    
         
            -
                
         
     | 
| 
       130 
     | 
    
         
            -
                RExec::Task.open(TASK_PATH, :in => rd) do |task|
         
     | 
| 
       131 
     | 
    
         
            -
                  test_results.call(wr, task.output, task.error)
         
     | 
| 
       132 
     | 
    
         
            -
                end
         
     | 
| 
       133 
     | 
    
         
            -
                
         
     | 
| 
       134 
     | 
    
         
            -
                assert rd.closed?
         
     | 
| 
       135 
     | 
    
         
            -
                
         
     | 
| 
       136 
     | 
    
         
            -
                assert_raises(Errno::EINVAL) do
         
     | 
| 
       137 
     | 
    
         
            -
                  wr.puts "The pipe is closed on the other side.."
         
     | 
| 
       138 
     | 
    
         
            -
                end
         
     | 
| 
       139 
     | 
    
         
            -
                
         
     | 
| 
       140 
     | 
    
         
            -
                in_rd, in_wr = IO.pipe
         
     | 
| 
       141 
     | 
    
         
            -
                out_rd, out_wr = IO.pipe
         
     | 
| 
       142 
     | 
    
         
            -
                err_rd, err_wr = IO.pipe
         
     | 
| 
       143 
     | 
    
         
            -
                
         
     | 
| 
       144 
     | 
    
         
            -
                spawn_child_daemon = Proc.new do
         
     | 
| 
       145 
     | 
    
         
            -
                  task = RExec::Task.open(TASK_PATH, :in => in_rd, :out => out_wr, :err => err_wr, :daemonize => true)
         
     | 
| 
       146 
     | 
    
         
            -
                end
         
     | 
| 
       147 
     | 
    
         
            -
                
         
     | 
| 
       148 
     | 
    
         
            -
                task = RExec::Task.open(spawn_child_daemon, :daemonize => true)
         
     | 
| 
       149 
     | 
    
         
            -
                
         
     | 
| 
       150 
     | 
    
         
            -
                until !task.running? do
         
     | 
| 
       151 
     | 
    
         
            -
                  sleep 0.1
         
     | 
| 
       152 
     | 
    
         
            -
                end
         
     | 
| 
       153 
     | 
    
         
            -
                
         
     | 
| 
       154 
     | 
    
         
            -
                test_results.call(in_wr, out_rd, err_rd)
         
     | 
| 
       155 
     | 
    
         
            -
                
         
     | 
| 
       156 
     | 
    
         
            -
                assert !task.running?
         
     | 
| 
       157 
     | 
    
         
            -
              end
         
     | 
| 
       158 
     | 
    
         
            -
              
         
     | 
| 
       159 
     | 
    
         
            -
              def test_task_passthrough
         
     | 
| 
       160 
     | 
    
         
            -
                script = "echo " + "Hello World!".dump + " | #{TASK_PATH.realpath.to_s.dump}"
         
     | 
| 
       161 
     | 
    
         
            -
                
         
     | 
| 
       162 
     | 
    
         
            -
                RExec::Task.open(script, :passthrough => :all) do
         
     | 
| 
       163 
     | 
    
         
            -
                  
         
     | 
| 
       164 
     | 
    
         
            -
                end
         
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
       166 
     | 
    
         
            -
                [$stdin, $stdout, $stderr].each do |io|
         
     | 
| 
       167 
     | 
    
         
            -
                  assert !io.closed?
         
     | 
| 
       168 
     | 
    
         
            -
                end
         
     | 
| 
       169 
     | 
    
         
            -
              end
         
     | 
| 
       170 
     | 
    
         
            -
            end
         
     |