rush 0.1 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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