rush 0.1 → 0.2

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.
@@ -27,6 +27,11 @@ describe Rush::Connection::Local do
27
27
  @con.receive(:action => 'destroy', :full_path => 'file')
28
28
  end
29
29
 
30
+ it "receive -> purge(dir)" do
31
+ @con.should_receive(:purge).with('dir')
32
+ @con.receive(:action => 'purge', :full_path => 'dir')
33
+ end
34
+
30
35
  it "receive -> create_dir(path)" do
31
36
  @con.should_receive(:create_dir).with('dir')
32
37
  @con.receive(:action => 'create_dir', :full_path => 'dir')
@@ -79,7 +84,12 @@ describe Rush::Connection::Local do
79
84
 
80
85
  it "receive -> kill_process" do
81
86
  @con.should_receive(:kill_process).with(123).and_return(true)
82
- @con.receive(:action => 'kill_process', :pid => 123)
87
+ @con.receive(:action => 'kill_process', :pid => '123')
88
+ end
89
+
90
+ it "receive -> bash" do
91
+ @con.should_receive(:bash).with('cmd').and_return('output')
92
+ @con.receive(:action => 'bash', :payload => 'cmd').should == 'output'
83
93
  end
84
94
 
85
95
  it "receive -> unknown action exception" do
@@ -99,6 +109,11 @@ describe Rush::Connection::Local do
99
109
  @con.file_contents(fname).should == "stuff\n"
100
110
  end
101
111
 
112
+ it "file_contents raises DoesNotExist if the file does not exist" do
113
+ fname = "#{@sandbox_dir}/does_not_exist"
114
+ lambda { @con.file_contents(fname) }.should raise_error(Rush::DoesNotExist, fname)
115
+ end
116
+
102
117
  it "destroy to destroy a file or dir" do
103
118
  fname = "#{@sandbox_dir}/delete_me"
104
119
  system "touch #{fname}"
@@ -106,6 +121,20 @@ describe Rush::Connection::Local do
106
121
  File.exists?(fname).should be_false
107
122
  end
108
123
 
124
+ it "purge to purge a dir" do
125
+ system "cd #{@sandbox_dir}; touch {1,2}; mkdir 3; touch 3/4"
126
+ @con.purge(@sandbox_dir)
127
+ File.exists?(@sandbox_dir).should be_true
128
+ Dir.glob("#{@sandbox_dir}/*").should == []
129
+ end
130
+
131
+ it "purge kills hidden (dotfile) entries too" do
132
+ system "cd #{@sandbox_dir}; touch .killme"
133
+ @con.purge(@sandbox_dir)
134
+ File.exists?(@sandbox_dir).should be_true
135
+ `cd #{@sandbox_dir}; ls -lA | wc -l`.to_i.should == 0
136
+ end
137
+
109
138
  it "create_dir creates a directory" do
110
139
  fname = "#{@sandbox_dir}/a/b/c/"
111
140
  @con.create_dir(fname)
@@ -127,6 +156,14 @@ describe Rush::Connection::Local do
127
156
  File.exists?("#{@sandbox_dir}/subdir/a").should be_true
128
157
  end
129
158
 
159
+ it "copy raises DoesNotExist with source path if it doesn't exist or otherwise can't be accessed" do
160
+ lambda { @con.copy('/does/not/exist', '/tmp') }.should raise_error(Rush::DoesNotExist, '/does/not/exist')
161
+ end
162
+
163
+ it "copy raises DoesNotExist with destination path if it can't access the destination" do
164
+ lambda { @con.copy('/tmp', '/does/not/exist') }.should raise_error(Rush::DoesNotExist, '/does/not')
165
+ end
166
+
130
167
  it "read_archive to pull an archive of a dir into a byte stream" do
131
168
  system "touch #{@sandbox_dir}/a"
132
169
  @con.read_archive(@sandbox_dir).size.should > 50
@@ -150,11 +187,20 @@ describe Rush::Connection::Local do
150
187
  @con.index(@sandbox_dir, '*.rb').should == [ 'a.rb' ]
151
188
  end
152
189
 
190
+ it "index raises DoesNotExist when the base path is invalid" do
191
+ lambda { @con.index('/does/not/exist', '*') }.should raise_error(Rush::DoesNotExist, '/does/not/exist')
192
+ end
193
+
153
194
  it "stat gives file stats like size and timestamps" do
154
195
  @con.stat(@sandbox_dir).should have_key(:ctime)
155
196
  @con.stat(@sandbox_dir).should have_key(:size)
156
197
  end
157
198
 
199
+ it "stat raises DoesNotExist if the entry does not exist" do
200
+ fname = "#{@sandbox_dir}/does_not_exist"
201
+ lambda { @con.stat(fname) }.should raise_error(Rush::DoesNotExist, fname)
202
+ end
203
+
158
204
  if !RUBY_PLATFORM.match(/darwin/) # doesn't work on OS X 'cause du switches are different
159
205
  it "size gives size of a directory and all its contents recursively" do
160
206
  system "mkdir -p #{@sandbox_dir}/a/b/; echo 1234 > #{@sandbox_dir}/a/b/c"
@@ -163,11 +209,12 @@ describe Rush::Connection::Local do
163
209
  end
164
210
 
165
211
  it "parses ps output on os x" do
166
- @con.parse_ps("21712 501 1236 0 /usr/bin/vi somefile.rb").should == {
212
+ @con.parse_ps("21712 501 21711 1236 0 /usr/bin/vi somefile.rb").should == {
167
213
  :pid => "21712",
168
214
  :uid => "501",
169
- :rss => "1236",
170
- :cpu => "0",
215
+ :parent_pid => 21711,
216
+ :mem => 1236,
217
+ :cpu => 0,
171
218
  :command => '/usr/bin/vi',
172
219
  :cmdline => '/usr/bin/vi somefile.rb',
173
220
  }
@@ -175,22 +222,42 @@ describe Rush::Connection::Local do
175
222
 
176
223
  it "gets the list of processes on os x via the ps command" do
177
224
  @con.should_receive(:os_x_raw_ps).and_return <<EOPS
178
- PID UID RSS CPU COMMAND
179
- 1 0 1111 0 cmd1 args
180
- 2 501 222 1 cmd2
225
+ PID UID PPID RSS CPU COMMAND
226
+ 1 0 1 1111 0 cmd1 args
227
+ 2 501 1 222 1 cmd2
181
228
  EOPS
182
229
  @con.os_x_processes.should == [
183
- { :pid => "1", :uid => "0", :rss => "1111", :cpu => "0", :command => "cmd1", :cmdline => "cmd1 args" },
184
- { :pid => "2", :uid => "501", :rss => "222", :cpu => "1", :command => "cmd2", :cmdline => "cmd2" },
230
+ { :pid => "1", :uid => "0", :parent_pid => 1, :mem => 1111, :cpu => 0, :command => "cmd1", :cmdline => "cmd1 args" },
231
+ { :pid => "2", :uid => "501", :parent_pid => 1, :mem => 222, :cpu => 1, :command => "cmd2", :cmdline => "cmd2" },
185
232
  ]
186
233
  end
187
234
 
188
- it "checks whether a given process is alive by pid" do
189
- @con.process_alive(Process.pid).should == true
235
+ it "the current process should be alive" do
236
+ @con.process_alive(Process.pid).should be_true
237
+ end
238
+
239
+ it "a made-up process should not be alive" do
240
+ @con.process_alive(99999).should be_false
190
241
  end
191
242
 
192
243
  it "kills a process by pid" do
193
- ::Process.should_receive(:kill).with('TERM', 123)
194
- @con.kill_process('123')
244
+ ::Process.should_receive(:kill).at_least(:once)
245
+ @con.kill_process(123)
246
+ end
247
+
248
+ it "executes a bash command, returning stdout when successful" do
249
+ @con.bash("echo test").should == "test\n"
250
+ end
251
+
252
+ it "executes a bash command, raising and error (with stderr as the message) when return value is nonzero" do
253
+ lambda { @con.bash("no_such_bin") }.should raise_error(Rush::BashFailed, /command not found/)
254
+ end
255
+
256
+ it "ensure_tunnel to match with remote connection" do
257
+ @con.ensure_tunnel
258
+ end
259
+
260
+ it "always returns true on alive?" do
261
+ @con.should be_alive
195
262
  end
196
263
  end
@@ -12,6 +12,13 @@ describe Rush::Process do
12
12
  system "kill -9 #{@pid}"
13
13
  end
14
14
 
15
+ if !RUBY_PLATFORM.match(/darwin/) # OS x reports pids weird
16
+ it "knows all its child processes" do
17
+ parent = Rush::Process.all.detect { |p| p.pid == Process.pid }
18
+ parent.children.should == [ @process ]
19
+ end
20
+ end
21
+
15
22
  it "gets the list of all processes" do
16
23
  list = Rush::Process.all
17
24
  list.size.should > 5
@@ -34,11 +41,33 @@ describe Rush::Process do
34
41
  @process.cmdline.should match(/process_spec.rb/)
35
42
  end
36
43
 
44
+ it "knows the memory used" do
45
+ @process.mem.should > 0
46
+ end
47
+
48
+ it "knows the cpu used" do
49
+ @process.cpu.should >= 0
50
+ end
51
+
52
+ it "knows the parent process pid" do
53
+ @process.parent_pid.should == Process.pid
54
+ end
55
+
56
+ it "knows the parent process" do
57
+ this = Rush::Box.new.processes.select { |p| p.pid == Process.pid }.first
58
+ @process.parent.should == this
59
+ end
60
+
37
61
  it "can kill itself" do
38
62
  system "sleep 30 &"
39
- @process = Rush::Process.all.detect { |p| p.command == "sleep" }
40
- @process.kill
63
+ process = Rush::Process.all.detect { |p| p.command == "sleep" }
64
+ process.kill
41
65
  sleep 0.1
42
- @process.alive?.should be_false
66
+ process.alive?.should be_false
67
+ end
68
+
69
+ it "if box and pid are the same, process is equal" do
70
+ other = Rush::Process.new({ :pid => @process.pid }, @process.box)
71
+ @process.should == other
43
72
  end
44
73
  end
@@ -27,6 +27,11 @@ describe Rush::Connection::Local do
27
27
  @con.destroy('file')
28
28
  end
29
29
 
30
+ it "transmits purge" do
31
+ @con.should_receive(:transmit).with(:action => 'purge', :full_path => 'dir')
32
+ @con.purge('dir')
33
+ end
34
+
30
35
  it "transmits create_dir" do
31
36
  @con.should_receive(:transmit).with(:action => 'create_dir', :full_path => 'file')
32
37
  @con.create_dir('file')
@@ -81,4 +86,45 @@ describe Rush::Connection::Local do
81
86
  @con.should_receive(:transmit).with(:action => 'kill_process', :pid => 123)
82
87
  @con.kill_process(123)
83
88
  end
89
+
90
+ it "transmits bash" do
91
+ @con.should_receive(:transmit).with(:action => 'bash', :payload => 'cmd').and_return('output')
92
+ @con.bash('cmd').should == 'output'
93
+ end
94
+
95
+ it "an http result code of 401 raises NotAuthorized" do
96
+ lambda { @con.process_result("401", "") }.should raise_error(Rush::NotAuthorized)
97
+ end
98
+
99
+ it "an http result code of 400 raises the exception passed in the result body" do
100
+ @con.stub!(:parse_exception).and_return(Rush::DoesNotExist, "message")
101
+ lambda { @con.process_result("400", "") }.should raise_error(Rush::DoesNotExist)
102
+ end
103
+
104
+ it "an http result code of 501 (or anything other than the other defined codes) raises FailedTransmit" do
105
+ lambda { @con.process_result("501", "") }.should raise_error(Rush::FailedTransmit)
106
+ end
107
+
108
+ it "parse_exception takes the class from the first line and the message from the second" do
109
+ @con.parse_exception("Rush::DoesNotExist\nthe message\n").should == [ Rush::DoesNotExist, "the message" ]
110
+ end
111
+
112
+ it "parse_exception rejects unrecognized exceptions" do
113
+ lambda { @con.parse_exception("NotARushException\n") }.should raise_error
114
+ end
115
+
116
+ it "passes through ensure_tunnel" do
117
+ @con.tunnel.should_receive(:ensure_tunnel)
118
+ @con.ensure_tunnel
119
+ end
120
+
121
+ it "is alive if the box is responding to commands" do
122
+ @con.should_receive(:index).and_return(:dummy)
123
+ @con.should be_alive
124
+ end
125
+
126
+ it "not alive if an attempted command throws an exception" do
127
+ @con.should_receive(:index).and_raise(RuntimeError)
128
+ @con.should_not be_alive
129
+ end
84
130
  end
@@ -7,6 +7,6 @@ describe Rush::Shell do
7
7
  end
8
8
 
9
9
  it "matches open path commands for readline tab completion" do
10
- @shell.path_parts("dir['app").should == [ "dir", "'", "app" ]
10
+ @shell.path_parts("dir['app").should == [ "dir", "'", "app", "" ]
11
11
  end
12
12
  end
@@ -58,19 +58,35 @@ describe Rush::SshTunnel do
58
58
  @tunnel.tunnel_options.should == {
59
59
  :local_port => 1234,
60
60
  :remote_port => 7770,
61
- :ssh_host => 'spec.example.com',
62
- :stall_command => 'sleep 9000'
61
+ :ssh_host => 'spec.example.com'
63
62
  }
64
63
  end
65
64
 
66
- it "constructs the bash ssh command from the options hash" do
65
+ it "ssh_stall_command uses an infinite loop for :timeout => :infinite" do
66
+ @tunnel.ssh_stall_command(:timeout => :infinite).should match(/while .* sleep .* done/)
67
+ end
68
+
69
+ it "ssh_stall_command sleeps for the number of seconds given as the :timeout option" do
70
+ @tunnel.ssh_stall_command(:timeout => 123).should == "sleep 123"
71
+ end
72
+
73
+ it "ssh_stall_command uses the default timeout when no options are given" do
74
+ @tunnel.ssh_stall_command.should == "sleep 9000"
75
+ end
76
+
77
+ it "constructs the ssh tunnel command (everything but stall) from the options hash" do
67
78
  @tunnel.should_receive(:tunnel_options).at_least(:once).and_return(
68
79
  :local_port => 123,
69
80
  :remote_port => 456,
70
- :ssh_host => 'example.com',
71
- :stall_command => 'stall'
81
+ :ssh_host => 'example.com'
72
82
  )
73
- @tunnel.ssh_tunnel_command.should == "ssh -f -L 123:127.0.0.1:456 example.com \"stall\""
83
+ @tunnel.ssh_tunnel_command_without_stall.should == "ssh -f -L 123:127.0.0.1:456 example.com"
84
+ end
85
+
86
+ it "combines the tunnel command without stall and the stall command into the final command" do
87
+ @tunnel.should_receive(:ssh_tunnel_command_without_stall).and_return('ssh command')
88
+ @tunnel.should_receive(:ssh_stall_command).and_return('sleep 123')
89
+ @tunnel.ssh_tunnel_command.should == 'ssh command "sleep 123"'
74
90
  end
75
91
 
76
92
  it "ssh_tunnel_command request that the port be set" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rush
3
3
  version: !ruby/object:Gem::Version
4
- version: "0.1"
4
+ version: "0.2"
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Wiggins
@@ -9,10 +9,36 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-02-20 00:00:00 -08:00
12
+ date: 2008-03-12 00:00:00 -07:00
13
13
  default_executable:
14
- dependencies: []
15
-
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: mongrel
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: rspec
26
+ version_requirement:
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: "0"
32
+ version:
33
+ - !ruby/object:Gem::Dependency
34
+ name: session
35
+ version_requirement:
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: "0"
41
+ version:
16
42
  description: A Ruby replacement for bash+ssh, providing both an interactive shell and a library. Manage both local and remote unix systems from a single client.
17
43
  email: adam@heroku.com
18
44
  executables:
@@ -33,7 +59,9 @@ files:
33
59
  - lib/rush/config.rb
34
60
  - lib/rush/dir.rb
35
61
  - lib/rush/entry.rb
62
+ - lib/rush/exceptions.rb
36
63
  - lib/rush/file.rb
64
+ - lib/rush/find_by.rb
37
65
  - lib/rush/fixnum_ext.rb
38
66
  - lib/rush/head_tail.rb
39
67
  - lib/rush/local.rb
@@ -53,6 +81,7 @@ files:
53
81
  - spec/dir_spec.rb
54
82
  - spec/entry_spec.rb
55
83
  - spec/file_spec.rb
84
+ - spec/find_by_spec.rb
56
85
  - spec/fixnum_ext_spec.rb
57
86
  - spec/local_spec.rb
58
87
  - spec/process_spec.rb