remote_run 0.1.0 → 0.1.1

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.
@@ -0,0 +1,98 @@
1
+ module RemoteRun
2
+ class Configuration
3
+ attr_accessor :remote_path, :local_path, :login_as, :exclude, :temp_path, :quiet
4
+ attr_reader :local_hostname, :identifier, :start_time
5
+ attr_reader :host_manager, :task_manager
6
+
7
+ def initialize
8
+ @task_manager = TaskManager.new
9
+ @host_manager = HostManager.new
10
+
11
+ @local_path = Dir.getwd
12
+ @login_as = `whoami`.strip
13
+ @remote_path = "/tmp/remote"
14
+ @exclude = []
15
+ @temp_path = "/tmp/remote"
16
+ @quiet = false
17
+ @start_time = Time.now
18
+
19
+ # used in the runner
20
+ @identifier = `echo $RANDOM`.strip
21
+ @local_hostname = `hostname`.strip
22
+
23
+ $runner = self
24
+ yield self
25
+ end
26
+
27
+ def hosts
28
+ @host_manager.hosts
29
+ end
30
+
31
+ def tasks
32
+ @task_manager.tasks
33
+ end
34
+
35
+ def hosts=(hostnames)
36
+ hostnames.each do |hostname|
37
+ @host_manager.add(Host.new(hostname))
38
+ end
39
+ end
40
+
41
+ def tasks=(shell_commands)
42
+ shell_commands.each do |shell_command|
43
+ @task_manager.add(Task.new(shell_command))
44
+ end
45
+ end
46
+
47
+ def run
48
+ Runner.new(self).run
49
+ end
50
+
51
+ private
52
+
53
+ class HostManager
54
+ def initialize(&block)
55
+ @hosts = []
56
+ end
57
+
58
+ def add(host)
59
+ Thread.new do
60
+ if host.is_up?
61
+ @hosts << host
62
+ end
63
+ end
64
+ end
65
+
66
+ def hosts
67
+ while @hosts.empty?
68
+ sleep(0.5)
69
+ end
70
+ @hosts
71
+ end
72
+ end
73
+
74
+ class TaskManager
75
+ attr_reader :tasks
76
+
77
+ def initialize
78
+ @tasks = []
79
+ end
80
+
81
+ def add(task)
82
+ @tasks.push(task)
83
+ end
84
+
85
+ def find_task
86
+ @tasks.shift
87
+ end
88
+
89
+ def count
90
+ @tasks.length
91
+ end
92
+
93
+ def has_more_tasks?
94
+ @tasks.size > 0
95
+ end
96
+ end
97
+ end
98
+ end
@@ -1,128 +1,125 @@
1
- class Host
2
- FAIL = 1
3
- PASS = 0
4
- SSH_CONFIG = " -o ControlMaster=auto -o ControlPath=~/.ssh/master-%l-%r@%h:%p -o NumberOfPasswordPrompts=0 -o StrictHostKeyChecking=no -4 "
5
- attr_reader :hostname
6
- attr_reader :lock_file
7
-
8
- def initialize(hostname)
9
- @hostname = hostname
10
- @lock_file = LockFile.new(@hostname, $runner.local_hostname, $runner.identifier)
11
- end
12
-
13
- def lock
14
- unless locked?
15
- @lock_file.get && locked_by_me?
1
+ module RemoteRun
2
+ class Host
3
+ FAIL = 1
4
+ PASS = 0
5
+ SSH_CONFIG = " -o ControlMaster=auto -o ControlPath=~/.ssh/master-%l-%r@%h:%p -o NumberOfPasswordPrompts=0 -o StrictHostKeyChecking=no -4 "
6
+ attr_reader :hostname
7
+
8
+ def initialize(hostname)
9
+ @hostname = hostname
10
+ @lock_file = LockFile.new(@hostname, $runner.local_hostname, $runner.identifier)
16
11
  end
17
- end
18
-
19
- def unlock
20
- @lock_file.release
21
- end
22
-
23
- def run(task)
24
- Runner.log("Running '#{task}' on #{@hostname}", :white)
25
- command = %Q{ssh #{SSH_CONFIG} #{ssh_host_and_user} 'cd #{$runner.remote_path}; #{task}' 2>&1}
26
- system(command)
27
- $?.exitstatus
28
- end
29
12
 
30
- def copy_codebase
31
- Runner.log("Copying from #{$runner.temp_path} to #{@hostname}:#{$runner.remote_path}", :yellow)
32
- system("ssh #{SSH_CONFIG} #{ssh_host_and_user} 'mkdir -p #{$runner.remote_path}'")
33
- excludes = $runner.exclude.map { |dir| "--exclude '#{dir}'"}
34
- if system(%{rsync --delete --delete-excluded #{excludes.join(" ")} --rsh='ssh #{SSH_CONFIG}' --timeout=60 -a #{$runner.temp_path}/ #{ssh_host_and_user}:#{$runner.remote_path}/})
35
- Runner.log("Finished copying to #{@hostname}", :green)
36
- return true
37
- else
38
- Runner.log("rsync failed on #{@hostname}.", :red)
39
- return false
13
+ def lock
14
+ unless locked?
15
+ @lock_file.get && locked_by_me?
16
+ end
40
17
  end
41
- end
42
18
 
43
- def is_up?
44
- result = `ssh #{SSH_CONFIG} -o ConnectTimeout=2 #{ssh_host_and_user} "echo 'success'" 2>/dev/null`.strip
45
- if result == "success"
46
- Runner.log("#{@hostname} is up", :green)
47
- return true
48
- else
49
- Runner.log("#{@hostname} is down: #{result}", :red)
50
- return false
19
+ def unlock
20
+ @lock_file.release
51
21
  end
52
- end
53
-
54
- def start_ssh_master_connection
55
- system("ssh #{SSH_CONFIG} #{ssh_host_and_user} -M &> /dev/null")
56
- end
57
-
58
- private
59
-
60
- def ssh_host_and_user
61
- "#{$runner.login_as}@#{@hostname}"
62
- end
63
-
64
- def locked?
65
- @lock_file.locked?
66
- end
67
22
 
68
- def locked_by_me?
69
- @lock_file.locked_by_me?
70
- end
23
+ def run(task)
24
+ command = %Q{ssh #{SSH_CONFIG} #{ssh_host_and_user} 'cd #{$runner.remote_path}; #{task}' 2>&1}
25
+ system(command)
26
+ $?.exitstatus
27
+ end
71
28
 
72
- class LockFile
73
- FILE = "/tmp/remote-run-lock"
29
+ def copy_codebase
30
+ system("ssh #{SSH_CONFIG} #{ssh_host_and_user} 'mkdir -p #{$runner.remote_path}'")
31
+ excludes = $runner.exclude.map { |dir| "--exclude '#{dir}'"}
32
+ if system(%{rsync --delete --delete-excluded #{excludes.join(" ")} --rsh='ssh #{SSH_CONFIG}' --timeout=60 -a #{$runner.temp_path}/ #{ssh_host_and_user}:#{$runner.remote_path}/})
33
+ return true
34
+ else
35
+ return false
36
+ end
37
+ end
74
38
 
75
- def initialize(remote_hostname, local_hostname, unique_run_marker)
76
- @filename = FILE
77
- @locker = "#{local_hostname}-#{unique_run_marker}"
78
- @remote_file = RemoteFile.new(remote_hostname)
39
+ def is_up?
40
+ result = `ssh #{SSH_CONFIG} -o ConnectTimeout=2 #{ssh_host_and_user} "echo 'success'" 2>/dev/null`.strip
41
+ if result == "success"
42
+ return true
43
+ else
44
+ return false
45
+ end
79
46
  end
80
47
 
81
- def release
82
- if locked_by_me?
83
- @remote_file.delete(@filename)
48
+ def start_ssh_master_connection
49
+ fork do
50
+ system("ssh #{SSH_CONFIG} #{ssh_host_and_user} -M &> /dev/null")
84
51
  end
85
52
  end
86
53
 
54
+ private
55
+
56
+ def ssh_host_and_user
57
+ "#{$runner.login_as}@#{@hostname}"
58
+ end
59
+
87
60
  def locked?
88
- @remote_file.exist?(@filename)
61
+ @lock_file.locked?
89
62
  end
90
63
 
91
64
  def locked_by_me?
92
- @remote_file.exist?(@filename) && @remote_file.read(@filename).strip == @locker
65
+ @lock_file.locked_by_me?
93
66
  end
94
67
 
95
- def get
96
- @remote_file.write(@filename, @locker)
97
- end
68
+ class LockFile
69
+ FILE = "/tmp/remote-run-lock"
98
70
 
99
- class RemoteFile
100
- def initialize(hostname)
101
- @hostname = hostname
71
+ def initialize(remote_hostname, local_hostname, unique_run_marker)
72
+ @filename = FILE
73
+ @locker = "#{local_hostname}-#{unique_run_marker}"
74
+ @remote_file = RemoteFile.new(remote_hostname)
102
75
  end
103
76
 
104
- def exist?(file_path)
105
- run_and_test("test -f #{file_path}")
77
+ def release
78
+ if locked_by_me?
79
+ @remote_file.delete(@filename)
80
+ end
106
81
  end
107
82
 
108
- def read(file_path)
109
- run("test -e #{file_path} && cat #{file_path}")
83
+ def locked?
84
+ @remote_file.exist?(@filename)
110
85
  end
111
86
 
112
- def write(file_path, text)
113
- run_and_test("test -e #{file_path} || echo #{text} > #{file_path}")
87
+ def locked_by_me?
88
+ @remote_file.exist?(@filename) && @remote_file.read(@filename).strip == @locker
114
89
  end
115
90
 
116
- def delete(file_path)
117
- run_and_test("rm -f #{file_path}")
91
+ def get
92
+ @remote_file.write(@filename, @locker)
118
93
  end
119
94
 
120
- def run(command)
121
- `ssh #{Host::SSH_CONFIG} #{$runner.login_as}@#{@hostname} '#{command};'`.strip
122
- end
95
+ class RemoteFile
96
+ def initialize(hostname)
97
+ @hostname = hostname
98
+ end
99
+
100
+ def exist?(file_path)
101
+ run_and_test("test -f #{file_path}")
102
+ end
103
+
104
+ def read(file_path)
105
+ run("test -e #{file_path} && cat #{file_path}")
106
+ end
107
+
108
+ def write(file_path, text)
109
+ run_and_test("test -e #{file_path} || echo #{text} > #{file_path}")
110
+ end
111
+
112
+ def delete(file_path)
113
+ run_and_test("rm -f #{file_path}")
114
+ end
115
+
116
+ def run(command)
117
+ `ssh #{Host::SSH_CONFIG} #{$runner.login_as}@#{@hostname} '#{command};'`.strip
118
+ end
123
119
 
124
- def run_and_test(command)
125
- system("ssh #{Host::SSH_CONFIG} #{$runner.login_as}@#{@hostname} '#{command}' 2>/dev/null")
120
+ def run_and_test(command)
121
+ system("ssh #{Host::SSH_CONFIG} #{$runner.login_as}@#{@hostname} '#{command}' 2>/dev/null")
122
+ end
126
123
  end
127
124
  end
128
125
  end
@@ -1,233 +1,155 @@
1
- class Runner
2
- attr_accessor :remote_path, :local_path, :login_as, :exclude, :temp_path
3
- attr_reader :local_hostname, :identifier
4
- @@start_time = Time.now
5
- @@stty_config = `stty -g`
6
-
7
- def initialize
8
- @task_manager = TaskManager.new
9
- @host_manager = HostManager.new
10
-
11
- # config options
12
- @local_path = Dir.getwd
13
- @login_as = `whoami`.strip
14
- @remote_path = "/tmp/remote"
15
- @exclude = []
16
- @temp_path = "/tmp/remote"
17
-
18
- # used in the runner
19
- @identifier = `echo $RANDOM`.strip
20
- @local_hostname = `hostname`.strip
21
- @results = []
22
- @children = []
23
- @failed = []
24
- @last_timestamp = Time.now.strftime("%S")[0]
25
-
26
- $runner = self
27
- yield self
28
- end
29
-
30
- def self.run(&block)
31
- @@start_time = Time.now
32
- runner = new(&block)
33
- runner.run
34
- end
35
-
36
- def self.run_time
37
- minutes = ((Time.now - @@start_time) / 60).to_i
38
- seconds = ((Time.now - @@start_time) % 60).to_i
39
- "#{minutes}:#{"%02d" % seconds}"
40
- end
41
-
42
- def self.log(message, color = :yellow)
43
- highline = HighLine.new
44
- system("stty #{@@stty_config} 2>/dev/null")
45
- highline.say(highline.color("[Remote :: #{$runner.identifier} :: #{run_time}] #{message}", color))
46
- end
47
-
48
- def hosts
49
- @host_manager.all
50
- end
1
+ module RemoteRun
2
+ class Runner
3
+ def initialize(configuration)
4
+ @configuration = configuration
5
+ @results = []
6
+ @children = []
7
+ @failed = []
8
+ @stty_config = `stty -g`
9
+ @last_timestamp = Time.now.strftime("%S")[0]
10
+ @hosts = []
51
11
 
52
- def hosts=(hostnames)
53
- hostnames.each do |hostname|
54
- @host_manager.add(hostname)
12
+ @task_manager = @configuration.task_manager
13
+ @host_manager = @configuration.host_manager
14
+ @starting_number_of_tasks = @task_manager.count
55
15
  end
56
- end
57
16
 
58
- def tasks=(shell_commands)
59
- shell_commands.each do |shell_command|
60
- @task_manager.add(shell_command)
17
+ def run
18
+ setup_unlock_on_exit
19
+ start_ssh_master_connections
20
+ sync_working_copy_to_temp_location
21
+ start_tasks
22
+ wait_for_tasks_to_finish
23
+ handle_results
61
24
  end
62
- end
63
-
64
- def run
65
- @host_manager.unlock_on_exit
66
- @host_manager.start_ssh_master_connections
67
- sync_working_copy_to_temp_location
68
- hosts = []
69
-
70
- Runner.log("Starting tasks... #{Time.now}")
71
25
 
72
- @starting_number_of_tasks = @task_manager.count
73
- while @task_manager.has_more_tasks?
74
- hosts = @host_manager.hosts.dup if hosts.empty?
26
+ private
75
27
 
76
- display_log
77
- check_for_finished
78
-
79
- if host = hosts.sample
80
- hosts.delete(host)
81
- if host.lock
82
- task = @task_manager.find_task
83
- @children << fork do
84
- begin
85
- this_host = host.dup
86
- unless this_host.copy_codebase
87
- @task_manager.add(task)
88
- status = 0
89
- end
90
- status = this_host.run(task)
91
- host.unlock
92
- Runner.log("#{host.hostname} failed.", :red) if status != 0
93
- rescue Errno::EPIPE
94
- Runner.log("broken pipe on #{host.hostname}...")
95
- ensure
96
- Process.exit!(status)
97
- end
28
+ def setup_unlock_on_exit
29
+ at_exit do
30
+ @configuration.hosts.each do |host|
31
+ begin
32
+ host.unlock
33
+ rescue Errno::EPIPE
98
34
  end
99
35
  end
100
36
  end
101
37
  end
102
38
 
103
- Runner.log("All tasks started... #{Time.now}")
104
-
105
- while @children.length > 0
106
- display_log
107
- check_for_finished
108
- end
109
-
110
- failed_tasks = @results.select { |result| result != 0 }
111
- status_code = if failed_tasks.length == 0
112
- Runner.log("Task passed.", :green)
113
- Host::PASS
114
- else
115
- Runner.log("#{failed_tasks.length} task(s) failed.", :red)
116
- Host::FAIL
117
- end
118
-
119
- Runner.log("Total Time: #{self.class.run_time} minutes.")
120
- status_code
121
- end
122
-
123
- def check_for_finished
124
- @children.each do |child_pid|
125
- if Process.waitpid(child_pid, Process::WNOHANG)
126
- if $?.exitstatus != 0
127
- @failed << child_pid
128
- end
129
-
130
- @results << $?.exitstatus
131
- @children.delete(child_pid)
39
+ def start_ssh_master_connections
40
+ @configuration.hosts.each do |host|
41
+ host.start_ssh_master_connection
132
42
  end
133
43
  end
134
- sleep(0.5)
135
- end
136
-
137
- private
138
44
 
139
- def sync_working_copy_to_temp_location
140
- Runner.log("Creating temporary copy of #{@local_path} in #{@temp_path}...")
141
- excludes = exclude.map { |dir| "--exclude '#{dir}'"}
142
- system("rsync --delete --delete-excluded #{excludes.join(" ")} -aq #{@local_path}/ #{@temp_path}/")
143
- Runner.log("Done.")
144
- end
145
-
146
- def display_log
147
- now = Time.now.strftime("%S")[0]
148
- unless now == @last_timestamp
149
- display_status("Waiting on #{@task_manager.count} of #{@starting_number_of_tasks} tasks to start.") if @task_manager.count > 0
150
- display_status("Waiting on #{@children.length} of #{@starting_number_of_tasks - @task_manager.count} started tasks to finish. #{@failed.size} failed.") if @children.length > 0
151
- $stdout.print("\n\n")
152
- $stdout.flush
153
- @last_timestamp = now
45
+ def sync_working_copy_to_temp_location
46
+ log("Creating temporary copy of #{@configuration.local_path} in #{@configuration.temp_path}...")
47
+ excludes = @configuration.exclude.map { |dir| "--exclude '#{dir}'"}
48
+ system("rsync --delete --delete-excluded #{excludes.join(" ")} -aq #{@configuration.local_path}/ #{@configuration.temp_path}/")
49
+ log("Done.")
154
50
  end
155
- end
156
51
 
157
- def display_status(message)
158
- Runner.log(message, :yellow)
159
- end
52
+ def start_tasks
53
+ log("Starting tasks... #{Time.now}")
160
54
 
161
- class HostManager
162
- def initialize(&block)
163
- @hosts = []
164
- end
55
+ while @task_manager.has_more_tasks?
56
+ display_log
57
+ check_for_finished
58
+ find_lock_and_start
59
+ end
165
60
 
166
- def all
167
- @hosts
61
+ log("All tasks started... #{Time.now}")
168
62
  end
169
63
 
170
- def add(hostname)
171
- host = Host.new(hostname)
172
- Thread.new do
173
- if host.is_up?
174
- @hosts << host
175
- end
64
+ def wait_for_tasks_to_finish
65
+ while @children.length > 0
66
+ display_log
67
+ check_for_finished
176
68
  end
177
69
  end
178
70
 
179
- def hosts
180
- while @hosts.empty?
181
- Runner.log("Waiting for hosts...")
182
- sleep(0.5)
71
+ def handle_results
72
+ failed_tasks = @results.select { |result| result != 0 }
73
+ status_code = if failed_tasks.length == 0
74
+ log("Task passed.", :green)
75
+ Host::PASS
76
+ else
77
+ log("#{failed_tasks.length} task(s) failed.", :red)
78
+ Host::FAIL
183
79
  end
184
80
 
185
- @hosts
81
+ log("Total Time: #{run_time} minutes.")
82
+ status_code
186
83
  end
187
84
 
188
- def unlock_on_exit
189
- at_exit do
190
- all.each do |host|
191
- begin
192
- host.unlock
193
- rescue Errno::EPIPE
194
- end
195
- end
85
+ def start_task(host)
86
+ task = @task_manager.find_task
87
+ @children << fork do
88
+ start_forked_task(host, task)
196
89
  end
197
90
  end
198
91
 
199
- def start_ssh_master_connections
200
- all.each do |host|
201
- fork do
202
- host.start_ssh_master_connection
92
+ def start_forked_task(host, task)
93
+ begin
94
+ this_host = host.dup
95
+ unless this_host.copy_codebase
96
+ @task_manager.add(task)
97
+ status = 0
203
98
  end
99
+ status = this_host.run(task.command)
100
+ host.unlock
101
+ rescue Errno::EPIPE
102
+ ensure
103
+ Process.exit!(status)
204
104
  end
205
105
  end
206
- end
207
106
 
208
- class TaskManager
209
- def initialize
210
- @tasks = []
107
+ def find_lock_and_start
108
+ @hosts = @host_manager.hosts.dup if @hosts.empty?
109
+ if host = @hosts.sample
110
+ @hosts.delete(host)
111
+ if host.lock
112
+ start_task(host)
113
+ end
114
+ end
211
115
  end
212
116
 
213
- def add(script)
214
- @tasks.push(script)
117
+ def run_time
118
+ minutes = ((Time.now - @configuration.start_time) / 60).to_i
119
+ seconds = ((Time.now - @configuration.start_time) % 60).to_i
120
+ "#{minutes}:#{"%02d" % seconds}"
215
121
  end
216
122
 
217
- def find_task
218
- @tasks.shift
123
+ def log(message, color = :yellow)
124
+ unless @configuration.quiet
125
+ highline = HighLine.new
126
+ system("stty #{@stty_config} 2>/dev/null")
127
+ highline.say(highline.color("[Remote :: #{@configuration.identifier} :: #{run_time}] #{message}", color))
128
+ end
219
129
  end
220
130
 
221
- def all
222
- @tasks
131
+ def check_for_finished
132
+ @children.each do |child_pid|
133
+ if task_is_finished?(child_pid)
134
+ @failed << child_pid unless $?.success?
135
+ @results << $?.exitstatus
136
+ @children.delete(child_pid)
137
+ end
138
+ end
223
139
  end
224
140
 
225
- def count
226
- @tasks.length
141
+ def task_is_finished?(pid)
142
+ Process.waitpid(pid, Process::WNOHANG)
227
143
  end
228
144
 
229
- def has_more_tasks?
230
- @tasks.size > 0
145
+ def display_log
146
+ now = Time.now.strftime("%S")[0]
147
+ unless now == @last_timestamp
148
+ log("Waiting on #{@task_manager.count} of #{@starting_number_of_tasks} tasks to start.") if @task_manager.count > 0
149
+ log("Waiting on #{@children.length} of #{@starting_number_of_tasks - @task_manager.count} started tasks to finish. #{@failed.size} failed.") if @children.length > 0
150
+ $stdout.flush
151
+ @last_timestamp = now
152
+ end
231
153
  end
232
154
  end
233
155
  end
@@ -0,0 +1,10 @@
1
+ module RemoteRun
2
+ class Task
3
+ attr_accessor :command
4
+
5
+ def initialize(command)
6
+ @command = command
7
+ end
8
+ end
9
+ end
10
+
@@ -1,3 +1,3 @@
1
1
  module RemoteRun
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
data/lib/remote_run.rb CHANGED
@@ -1,3 +1,8 @@
1
+ require File.join(File.dirname(__FILE__), "remote_run", "task")
1
2
  require File.join(File.dirname(__FILE__), "remote_run", "host")
2
3
  require File.join(File.dirname(__FILE__), "remote_run", "runner")
4
+ require File.join(File.dirname(__FILE__), "remote_run", "configuration")
3
5
  require 'highline'
6
+
7
+ module RemoteRun
8
+ end
@@ -0,0 +1,92 @@
1
+ require 'spec_helper'
2
+
3
+ describe RemoteRun::Configuration::HostManager do
4
+ subject { RemoteRun::Configuration::HostManager.new }
5
+
6
+ describe "#add" do
7
+ it "adds the given host to a list of hosts" do
8
+ subject.add(stub(:host, :is_up? => true, :name => "foobar"))
9
+ subject.hosts.size.should == 1
10
+ subject.hosts.first.name.should == "foobar"
11
+ end
12
+ end
13
+
14
+ describe "#hosts" do
15
+ it "returns all hosts in the list" do
16
+ host = stub(:host, :is_up? => true, :name => "foobar")
17
+ subject.add(host)
18
+ subject.hosts.should == [host]
19
+ end
20
+ end
21
+
22
+ describe "#start_ssh_master_connections" do
23
+ before do
24
+ @host = stub(:host, :is_up? => true, :name => "foobar")
25
+ subject.add(@host)
26
+ end
27
+
28
+ it "asks each host to start their ssh master connection" do
29
+ @host.should_receive(:start_ssh_master_connection)
30
+ subject.start_ssh_master_connections
31
+ end
32
+ end
33
+ end
34
+
35
+ describe RemoteRun::Configuration::TaskManager do
36
+ subject { RemoteRun::Configuration::TaskManager.new }
37
+ describe "#add" do
38
+ it "takes a string and puts it on a list of tasks" do
39
+ task = RemoteRun::Task.new("date")
40
+ subject.add(task)
41
+ subject.tasks.should include(task)
42
+ end
43
+ end
44
+
45
+ describe "#find_task" do
46
+ before do
47
+ @task = RemoteRun::Task.new("date")
48
+ subject.add(@task)
49
+ end
50
+
51
+ it "finds a task from the list, returns it and removes it" do
52
+ subject.tasks.should == [@task]
53
+ subject.find_task.should == @task
54
+ subject.tasks.should == []
55
+ end
56
+ end
57
+
58
+ describe "#tasks" do
59
+ it "returns all of the tasks stored in the manager" do
60
+ task = RemoteRun::Task.new("foo")
61
+ task2 = RemoteRun::Task.new("bar")
62
+ subject.add(task)
63
+ subject.add(task2)
64
+ subject.tasks.should == [task, task2]
65
+ end
66
+ end
67
+
68
+ describe "#count" do
69
+ it "returns the number of tasks stored" do
70
+ task = RemoteRun::Task.new("foo")
71
+ task2 = RemoteRun::Task.new("bar")
72
+ subject.add(task)
73
+ subject.add(task2)
74
+ subject.count.should == 2
75
+ end
76
+ end
77
+
78
+ describe "#has_more_tasks?" do
79
+ it "returns true when there are tasks in the list" do
80
+ task = RemoteRun::Task.new("foo")
81
+ task2 = RemoteRun::Task.new("bar")
82
+ subject.add(task)
83
+ subject.add(task2)
84
+
85
+ subject.has_more_tasks?.should be_true
86
+ subject.find_task
87
+ subject.has_more_tasks?.should be_true
88
+ subject.find_task
89
+ subject.has_more_tasks?.should be_false
90
+ end
91
+ end
92
+ end
@@ -1,8 +1,8 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Host do
3
+ describe RemoteRun::Host do
4
4
  context "when locking" do
5
- let(:host) { Host.new("localhost") }
5
+ let(:host) { RemoteRun::Host.new("localhost") }
6
6
 
7
7
  it "can be locked" do
8
8
  host.lock.should be_true
@@ -21,9 +21,9 @@ describe Host do
21
21
 
22
22
  context "when locked by someone else" do
23
23
  before { lock_file.get }
24
- let(:host) { Host.new("localhost") }
24
+ let(:host) { RemoteRun::Host.new("localhost") }
25
25
  let(:lock_file) {
26
- lock_file = Host::LockFile.new("localhost", "myfakelocalhost", "999")
26
+ lock_file = RemoteRun::Host::LockFile.new("localhost", "myfakelocalhost", "999")
27
27
  }
28
28
 
29
29
  it "cannot be unlocked by me" do
@@ -33,7 +33,7 @@ describe Host do
33
33
 
34
34
  context "when locked by me" do
35
35
  before { host.lock }
36
- let(:host) { Host.new("localhost") }
36
+ let(:host) { RemoteRun::Host.new("localhost") }
37
37
 
38
38
  it "cannot be locked" do
39
39
  host.lock.should be_false
@@ -52,7 +52,7 @@ describe Host do
52
52
 
53
53
  context "when checking to see if a host is up" do
54
54
  context "when using an authorized host" do
55
- let(:host) { Host.new("localhost") }
55
+ let(:host) { RemoteRun::Host.new("localhost") }
56
56
 
57
57
  it "returns true" do
58
58
  host.is_up?.should be_true
@@ -60,7 +60,7 @@ describe Host do
60
60
  end
61
61
 
62
62
  context "when using an unauthorized host" do
63
- let(:host) { Host.new("foozmcbarry") }
63
+ let(:host) { RemoteRun::Host.new("foozmcbarry") }
64
64
 
65
65
  it "returns false" do
66
66
  host.is_up?.should be_false
@@ -74,7 +74,7 @@ describe Host do
74
74
  host.lock
75
75
  end
76
76
 
77
- let(:host) { Host.new("localhost") }
77
+ let(:host) { RemoteRun::Host.new("localhost") }
78
78
 
79
79
  context "when executing a shell command with a zero status code" do
80
80
  it "returns zero" do
@@ -95,7 +95,7 @@ describe Host do
95
95
  host.lock
96
96
  end
97
97
 
98
- let(:host) { Host.new("localhost") }
98
+ let(:host) { RemoteRun::Host.new("localhost") }
99
99
 
100
100
  it "copies the codebase to a remote directory" do
101
101
  $runner.remote_path = "/tmp/testing-remote-run"
File without changes
data/spec/spec_helper.rb CHANGED
@@ -3,13 +3,14 @@ require 'bundler/setup'
3
3
  require 'rspec'
4
4
  require Dir.pwd + '/lib/remote_run'
5
5
 
6
- Runner.new do |config|
6
+ RemoteRun::Configuration.new do |config|
7
7
  config.tasks = []
8
8
  config.hosts = []
9
+ config.quiet = true
9
10
  end
10
11
 
11
12
  RSpec.configure do |config|
12
13
  config.after(:each) do
13
- system("rm -f #{Host::LockFile::FILE}")
14
+ system("rm -f #{RemoteRun::Host::LockFile::FILE}")
14
15
  end
15
16
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: remote_run
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-08-11 00:00:00.000000000Z
12
+ date: 2011-09-13 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: highline
16
- requirement: &2151825780 !ruby/object:Gem::Requirement
16
+ requirement: &2151951040 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2151825780
24
+ version_requirements: *2151951040
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &2151824680 !ruby/object:Gem::Requirement
27
+ requirement: &2151943360 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *2151824680
35
+ version_requirements: *2151943360
36
36
  description: Can be used as a parallel unit test runner
37
37
  email:
38
38
  - casecommons-dev@googlegroups.com
@@ -48,11 +48,15 @@ files:
48
48
  - Readme.md
49
49
  - examples/demo-remote-run
50
50
  - lib/remote_run.rb
51
+ - lib/remote_run/configuration.rb
51
52
  - lib/remote_run/host.rb
52
53
  - lib/remote_run/runner.rb
54
+ - lib/remote_run/task.rb
53
55
  - lib/remote_run/version.rb
54
56
  - remote_run.gemspec
57
+ - spec/remote_run/configuration_spec.rb
55
58
  - spec/remote_run/host_spec.rb
59
+ - spec/remote_run/runner_spec.rb
56
60
  - spec/spec_helper.rb
57
61
  homepage: https://github.com/Casecommons/remote_run
58
62
  licenses: []
@@ -68,7 +72,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
68
72
  version: '0'
69
73
  segments:
70
74
  - 0
71
- hash: -4543623679604844651
75
+ hash: 3128109979642869878
72
76
  required_rubygems_version: !ruby/object:Gem::Requirement
73
77
  none: false
74
78
  requirements:
@@ -77,13 +81,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
77
81
  version: '0'
78
82
  segments:
79
83
  - 0
80
- hash: -4543623679604844651
84
+ hash: 3128109979642869878
81
85
  requirements: []
82
86
  rubyforge_project: remote_run
83
- rubygems_version: 1.8.6
87
+ rubygems_version: 1.8.10
84
88
  signing_key:
85
89
  specification_version: 3
86
90
  summary: Run N shell scripts on a pool of remote hosts
87
91
  test_files:
92
+ - spec/remote_run/configuration_spec.rb
88
93
  - spec/remote_run/host_spec.rb
94
+ - spec/remote_run/runner_spec.rb
89
95
  - spec/spec_helper.rb