ztk 0.2.4 → 0.2.5

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.
@@ -19,5 +19,5 @@
19
19
  ################################################################################
20
20
 
21
21
  module ZTK
22
- VERSION = "0.2.4" unless const_defined?(:VERSION)
22
+ VERSION = "0.2.5" unless const_defined?(:VERSION)
23
23
  end
@@ -28,6 +28,14 @@ SimpleCov.start do
28
28
  add_filter '/spec/'
29
29
  end if ENV["COVERAGE"]
30
30
 
31
+ ENV['LOG_LEVEL'] = "DEBUG"
32
+
33
+ WAIT_SMALL = 3
34
+
31
35
  $logger = ZTK::Logger.new(File.join("/tmp", "test.log"))
32
36
 
37
+ $logger.info { "=" * 80 }
38
+ $logger.info { "STARTING ZTK v#{ZTK::VERSION} TEST RUN @ #{Time.now.utc}" }
39
+ $logger.info { "=" * 80 }
40
+
33
41
  ################################################################################
@@ -0,0 +1,41 @@
1
+ ################################################################################
2
+ #
3
+ # Author: Zachary Patten <zachary@jovelabs.net>
4
+ # Copyright: Copyright (c) Jove Labs
5
+ # License: Apache License, Version 2.0
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+ ################################################################################
20
+
21
+ require "spec_helper"
22
+
23
+ describe ZTK::Base do
24
+
25
+ subject { ZTK::Base }
26
+
27
+ before(:all) do
28
+ $stdout = File.open("/dev/null", "w")
29
+ $stderr = File.open("/dev/null", "w")
30
+ $stdin = File.open("/dev/null", "r")
31
+ end
32
+
33
+ describe "class" do
34
+
35
+ it "should be ZTK::Base" do
36
+ subject.should be ZTK::Base
37
+ end
38
+
39
+ end
40
+
41
+ end
@@ -53,25 +53,23 @@ describe ZTK::Benchmark do
53
53
  mark.should be_an_instance_of Float
54
54
  end
55
55
 
56
- it "should not write to STDOUT if not given a message or mark" do
56
+ it "should throw an exception if executed with a message but without a mark" do
57
57
  stdout = StringIO.new
58
- ZTK::Benchmark.bench(:stdout => stdout) do
59
- sleep(0.1)
60
- end
61
- stdout.size.should == 0
58
+ lambda {
59
+ ZTK::Benchmark.bench(:stdout => stdout, :message => "Hello World")
60
+ }.should raise_error ZTK::BenchmarkError
62
61
  end
63
62
 
64
- it "should not write to STDOUT if not given a message" do
63
+ it "should throw an exception if executed without a message but with a mark" do
65
64
  stdout = StringIO.new
66
- ZTK::Benchmark.bench(:stdout => stdout, :mark => "%0.4f") do
67
- sleep(0.1)
68
- end
69
- stdout.size.should == 0
65
+ lambda {
66
+ ZTK::Benchmark.bench(:stdout => stdout, :mark => "%0.4f")
67
+ }.should raise_error ZTK::BenchmarkError
70
68
  end
71
69
 
72
- it "should not write to STDOUT if not given a mark" do
70
+ it "should not write to STDOUT if not given a message or mark" do
73
71
  stdout = StringIO.new
74
- ZTK::Benchmark.bench(:stdout => stdout, :message => "Hello World") do
72
+ ZTK::Benchmark.bench(:stdout => stdout) do
75
73
  sleep(0.1)
76
74
  end
77
75
  stdout.size.should == 0
@@ -62,16 +62,149 @@ describe ZTK::Command do
62
62
 
63
63
  end
64
64
 
65
- it "should be able to execute the command \"hostname -f\"" do
66
- stdout = StringIO.new
67
- subject.config do |config|
68
- config.stdout = stdout
65
+ describe "behaviour" do
66
+
67
+ describe "execute" do
68
+
69
+ it "should be able to execute the command \"hostname -f\"" do
70
+ stdout = StringIO.new
71
+ subject.config do |config|
72
+ config.stdout = stdout
73
+ end
74
+ hostname = %x(hostname -f).chomp
75
+ status = subject.exec("hostname -f")
76
+ status.exit_code.should == 0
77
+ stdout.rewind
78
+ stdout.read.chomp.should == hostname
79
+ end
80
+
81
+ it "should timeout after the period specified" do
82
+ stdout = StringIO.new
83
+ subject.config do |config|
84
+ config.stdout = stdout
85
+ config.timeout = WAIT_SMALL
86
+ end
87
+ hostname = %x(hostname -f).chomp
88
+ lambda { subject.exec("hostname -f ; sleep 10") }.should raise_error ZTK::CommandError
89
+ end
90
+
91
+ it "should throw an exception if the exit status is not as expected" do
92
+ stdout = StringIO.new
93
+ subject.config do |config|
94
+ config.stdout = stdout
95
+ end
96
+ lambda { subject.exec("/bin/bash -c 'exit 64'") }.should raise_error ZTK::CommandError
97
+ end
98
+
99
+ it "should return a instance of an OpenStruct object" do
100
+ stdout = StringIO.new
101
+ subject.config do |config|
102
+ config.stdout = stdout
103
+ end
104
+ result = subject.exec(%q{echo "Hello World"})
105
+ result.should be_an_instance_of OpenStruct
106
+ end
107
+
108
+ it "should return the exit code" do
109
+ stdout = StringIO.new
110
+ subject.config do |config|
111
+ config.stdout = stdout
112
+ end
113
+ data = 64
114
+
115
+ result = subject.exec(%Q{/bin/bash -c 'exit #{data}'}, :exit_code => data)
116
+ result.exit_code.should == data
117
+ end
118
+
119
+ it "should return the output" do
120
+ stdout = StringIO.new
121
+ subject.config do |config|
122
+ config.stdout = stdout
123
+ end
124
+ data = "Hello World @ #{Time.now.utc}"
125
+
126
+ result = subject.exec(%Q{echo "#{data}"})
127
+ result.output.match(data).should_not be nil
128
+ end
129
+
130
+ it "should allow us to change the expected exit code" do
131
+ stdout = StringIO.new
132
+ subject.config do |config|
133
+ config.stdout = stdout
134
+ end
135
+ data = 32
136
+ result = subject.exec(%Q{/bin/bash -c 'exit #{data}'}, :exit_code => data)
137
+ end
138
+
139
+ describe "stdout" do
140
+
141
+ it "should capture STDOUT and send it to the appropriate pipe" do
142
+ stdout, stderr, stdin = StringIO.new, StringIO.new, StringIO.new
143
+
144
+ subject.config do |config|
145
+ config.stdout = stdout
146
+ config.stderr = stderr
147
+ config.stdin = stdin
148
+ end
149
+ data = "Hello World @ #{Time.now.utc}"
150
+
151
+ subject.exec(%Q{echo "#{data}" -f >&1})
152
+
153
+ stdout.rewind
154
+ stdout.read.match(data).should_not be nil
155
+
156
+ stderr.rewind
157
+ stderr.read.match(data).should be nil
158
+
159
+ stdin.rewind
160
+ stdin.read.match(data).should be nil
161
+ end
162
+
163
+ end
164
+
165
+ describe "stderr" do
166
+
167
+ it "should capture STDERR and send it to the appropriate pipe" do
168
+ stdout, stderr, stdin = StringIO.new, StringIO.new, StringIO.new
169
+
170
+ subject.config do |config|
171
+ config.stdout = stdout
172
+ config.stderr = stderr
173
+ config.stdin = stdin
174
+ end
175
+ data = "Hello World @ #{Time.now.utc}"
176
+
177
+ subject.exec(%Q{echo "#{data}" -f >&2})
178
+
179
+ stdout.rewind
180
+ stdout.read.match(data).should be nil
181
+
182
+ stderr.rewind
183
+ stderr.read.match(data).should_not be nil
184
+
185
+ stdin.rewind
186
+ stdin.read.match(data).should be nil
187
+ end
188
+ end
189
+
69
190
  end
70
- hostname = %x( hostname -f ).chomp
71
- status = subject.exec("hostname -f")
72
- status.exit.exitstatus.should == 0
73
- stdout.rewind
74
- stdout.read.chomp.should == hostname
191
+
192
+ describe "upload" do
193
+
194
+ it "should raise a 'Not Supported' exception when attempting to upload" do
195
+ lambda { subject.upload("abc", "123") }.should raise_error
196
+ end
197
+
198
+ end
199
+
200
+ describe "download" do
201
+
202
+ it "should raise a 'Not Supported' exception when attempting to download" do
203
+ lambda { subject.download("abc", "123") }.should raise_error
204
+ end
205
+
206
+ end
207
+
75
208
  end
76
209
 
77
210
  end
@@ -45,26 +45,26 @@ describe ZTK::Config do
45
45
 
46
46
  end
47
47
 
48
- describe "behaviour" do
48
+ end
49
49
 
50
- it "should allow setting of arbratary configuration keys" do
51
- subject.thing = "something"
52
- subject.thing.should == "something"
53
- subject[:thing].should == "something"
54
- end
50
+ describe "behaviour" do
55
51
 
56
- it "should allow hash bracket style access to configuration keys" do
57
- subject[:thing] = "nothing"
58
- subject[:thing].should == "nothing"
59
- end
52
+ it "should allow setting of arbratary configuration keys" do
53
+ subject.thing = "something"
54
+ subject.thing.should == "something"
55
+ subject[:thing].should == "something"
56
+ end
60
57
 
61
- it "should allow loading of configurations from disk" do
62
- config_file = File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "test-config.rb"))
63
- subject.from_file(config_file)
64
- subject.message.should == "Hello World"
65
- subject.thing.should == 2
66
- end
58
+ it "should allow hash bracket style access to configuration keys" do
59
+ subject[:thing] = "nothing"
60
+ subject[:thing].should == "nothing"
61
+ end
67
62
 
63
+ it "should allow loading of configurations from disk" do
64
+ config_file = File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "test-config.rb"))
65
+ subject.from_file(config_file)
66
+ subject.message.should == "Hello World"
67
+ subject.thing.should == 2
68
68
  end
69
69
 
70
70
  end
@@ -85,7 +85,7 @@ describe ZTK::Logger do
85
85
 
86
86
  it "should allow writing directly to the log device" do
87
87
  data = "Hello World"
88
- IO.write(subject.logdev, data)
88
+ subject.logdev.write(data)
89
89
  IO.read(@logfile).match(data).should_not be nil
90
90
  end
91
91
 
@@ -46,7 +46,7 @@ describe ZTK::RescueRetry do
46
46
  }.should raise_error ZTK::RescueRetryError, "You must supply a block!"
47
47
  end
48
48
 
49
- it "should retry on all exceptions" do
49
+ it "should retry on all exceptions by default if one is not supplied" do
50
50
  $counter = 0
51
51
  lambda {
52
52
  ZTK::RescueRetry.try(:tries => 3) do
@@ -57,7 +57,7 @@ describe ZTK::RescueRetry do
57
57
  $counter.should == 3
58
58
  end
59
59
 
60
- it "should retry on specific exceptions" do
60
+ it "should retry on supplied exception" do
61
61
  $counter = 0
62
62
  lambda {
63
63
  ZTK::RescueRetry.try(:tries => 3, :on => EOFError) do
@@ -68,7 +68,7 @@ describe ZTK::RescueRetry do
68
68
  $counter.should == 3
69
69
  end
70
70
 
71
- it "should not retry on specific exceptions if exceptions do not match" do
71
+ it "should not retry on exception if it does not match the supplied exception" do
72
72
  $counter = 0
73
73
  lambda {
74
74
  ZTK::RescueRetry.try(:tries => 3, :on => EOFError) do
@@ -0,0 +1,51 @@
1
+ ################################################################################
2
+ #
3
+ # Author: Zachary Patten <zachary@jovelabs.net>
4
+ # Copyright: Copyright (c) Jove Labs
5
+ # License: Apache License, Version 2.0
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+ ################################################################################
20
+
21
+ require "spec_helper"
22
+
23
+ describe ZTK::Spinner do
24
+
25
+ subject { ZTK::Spinner }
26
+
27
+ before(:all) do
28
+ $stdout = File.open("/dev/null", "w")
29
+ $stderr = File.open("/dev/null", "w")
30
+ $stdin = File.open("/dev/null", "r")
31
+ end
32
+
33
+ describe "class" do
34
+
35
+ it "should be ZTK::Spinner" do
36
+ subject.should be ZTK::Spinner
37
+ end
38
+
39
+ end
40
+
41
+ describe "behaviour" do
42
+
43
+ it "should throw an exception if executed without a block" do
44
+ lambda {
45
+ ZTK::Spinner.spin
46
+ }.should raise_error ZTK::SpinnerError, "You must supply a block!"
47
+ end
48
+
49
+ end
50
+
51
+ end
@@ -60,183 +60,449 @@ describe ZTK::SSH do
60
60
 
61
61
  end
62
62
 
63
- # this stuff doesn't work as is under travis-ci
64
- if !ENV['CI'] && !ENV['TRAVIS']
63
+ end
65
64
 
66
- describe "direct behaviour" do
65
+ # this stuff doesn't work as is under travis-ci right now
66
+ describe "direct SSH behaviour" do
67
67
 
68
- describe "execute" do
68
+ describe "execute" do
69
69
 
70
- it "should be able to connect to 127.0.0.1 as the current user and execute a command (your key must be in ssh-agent)" do
71
- stdout, stderr = StringIO.new, StringIO.new
72
- subject.config do |config|
73
- config.stdout = stdout
74
- config.stderr = stderr
75
- config.user = ENV["USER"]
76
- config.host_name = "127.0.0.1"
77
- end
70
+ it "should be able to connect to 127.0.0.1 as the current user and execute a command (your key must be in ssh-agent)" do
71
+ stdout, stderr, stdin = StringIO.new, StringIO.new, StringIO.new
72
+ subject.config do |config|
73
+ config.stdout, config.stderr, config.stdin = stdout, stderr, stdin
78
74
 
79
- data = %x(hostname -f).chomp
75
+ config.user = ENV["USER"]
76
+ config.host_name = "127.0.0.1"
77
+ end
80
78
 
81
- status = subject.exec("hostname -f")
82
- status.exit.exitstatus.should == 0
83
- stdout.rewind
84
- stdout.read.chomp.should == data
85
- end
79
+ data = %x(hostname -f).chomp
86
80
 
81
+ status = subject.exec("hostname -f")
82
+ status.exit_code.should == 0
83
+ stdout.rewind
84
+ stdout.read.chomp.should == data
85
+ end
86
+
87
+ it "should timeout after the period specified" do
88
+ stdout, stderr, stdin = StringIO.new, StringIO.new, StringIO.new
89
+ subject.config do |config|
90
+ config.stdout, config.stderr, config.stdin = stdout, stderr, stdin
91
+
92
+ config.user = ENV["USER"]
93
+ config.host_name = "127.0.0.1"
94
+ config.timeout = WAIT_SMALL
87
95
  end
96
+ hostname = %x(hostname -f).chomp
97
+ lambda { subject.exec("hostname -f ; sleep 10") }.should raise_error ZTK::SSHError
98
+ end
88
99
 
89
- describe "upload" do
100
+ it "should throw an exception if the exit status is not as expected" do
101
+ stdout, stderr, stdin = StringIO.new, StringIO.new, StringIO.new
102
+ subject.config do |config|
103
+ config.stdout, config.stderr, config.stdin = stdout, stderr, stdin
90
104
 
91
- it "should be able to upload a file to 127.0.0.1 as the current user and execute a command (your key must be in ssh-agent)" do
92
- stdout, stderr = StringIO.new, StringIO.new
93
- subject.config do |config|
94
- config.stdout = stdout
95
- config.stderr = stderr
96
- config.user = ENV["USER"]
97
- config.host_name = "127.0.0.1"
98
- end
105
+ config.user = ENV["USER"]
106
+ config.host_name = "127.0.0.1"
107
+ end
108
+ lambda { subject.exec("/bin/bash -c 'exit 64'") }.should raise_error ZTK::SSHError
109
+ end
99
110
 
100
- data = "Hello World"
111
+ it "should return a instance of an OpenStruct object" do
112
+ stdout, stderr, stdin = StringIO.new, StringIO.new, StringIO.new
113
+ subject.config do |config|
114
+ config.stdout, config.stderr, config.stdin = stdout, stderr, stdin
101
115
 
102
- remote_file = File.join("/tmp", "ssh-upload-remote")
103
- File.exists?(remote_file) && File.delete(remote_file)
116
+ config.user = ENV["USER"]
117
+ config.host_name = "127.0.0.1"
118
+ end
119
+ result = subject.exec(%q{echo "Hello World"})
120
+ result.should be_an_instance_of OpenStruct
121
+ end
104
122
 
105
- local_file = File.join("/tmp", "ssh-upload-local")
106
- IO.write(local_file, data)
123
+ it "should return the exit code" do
124
+ stdout, stderr, stdin = StringIO.new, StringIO.new, StringIO.new
125
+ subject.config do |config|
126
+ config.stdout, config.stderr, config.stdin = stdout, stderr, stdin
107
127
 
108
- File.exists?(remote_file).should == false
109
- subject.upload(local_file, remote_file)
110
- File.exists?(remote_file).should == true
128
+ config.user = ENV["USER"]
129
+ config.host_name = "127.0.0.1"
130
+ end
131
+ data = 64
111
132
 
112
- File.exists?(remote_file) && File.delete(remote_file)
113
- File.exists?(local_file) && File.delete(local_file)
114
- end
133
+ result = subject.exec(%Q{/bin/bash -c 'exit #{data}'}, :exit_code => data)
134
+ result.exit_code.should == data
135
+ end
115
136
 
137
+ it "should return the output" do
138
+ stdout, stderr, stdin = StringIO.new, StringIO.new, StringIO.new
139
+ subject.config do |config|
140
+ config.stdout, config.stderr, config.stdin = stdout, stderr, stdin
141
+
142
+ config.user = ENV["USER"]
143
+ config.host_name = "127.0.0.1"
116
144
  end
145
+ data = "Hello World @ #{Time.now.utc}"
146
+
147
+ result = subject.exec(%Q{echo "#{data}"})
148
+ result.output.match(data).should_not be nil
149
+ end
150
+
151
+ it "should allow us to change the expected exit code" do
152
+ stdout, stderr, stdin = StringIO.new, StringIO.new, StringIO.new
153
+ subject.config do |config|
154
+ config.stdout, config.stderr, config.stdin = stdout, stderr, stdin
155
+
156
+ config.user = ENV["USER"]
157
+ config.host_name = "127.0.0.1"
158
+ end
159
+ data = 32
160
+ result = subject.exec(%Q{/bin/bash -c 'exit #{data}'}, :exit_code => data)
161
+ end
117
162
 
118
- describe "download" do
163
+ describe "stdout" do
119
164
 
120
- it "should be able to download a file from 127.0.0.1 as the current user and execute a command (your key must be in ssh-agent)" do
121
- stdout, stderr = StringIO.new, StringIO.new
122
- subject.config do |config|
123
- config.stdout = stdout
124
- config.stderr = stderr
125
- config.user = ENV["USER"]
126
- config.host_name = "127.0.0.1"
127
- end
165
+ it "should capture STDOUT and send it to the appropriate pipe" do
166
+ stdout, stderr, stdin = StringIO.new, StringIO.new, StringIO.new
167
+ subject.config do |config|
168
+ config.stdout, config.stderr, config.stdin = stdout, stderr, stdin
128
169
 
129
- data = "Hello World"
170
+ config.user = ENV["USER"]
171
+ config.host_name = "127.0.0.1"
172
+ end
173
+ data = "Hello World @ #{Time.now.utc}"
174
+
175
+ subject.exec(%Q{echo "#{data}" -f >&1})
176
+
177
+ stdout.rewind
178
+ stdout.read.match(data).should_not be nil
179
+
180
+ stderr.rewind
181
+ stderr.read.match(data).should be nil
130
182
 
131
- local_file = File.join("/tmp", "ssh-download-local")
132
- File.exists?(local_file) && File.delete(local_file)
183
+ stdin.rewind
184
+ stdin.read.match(data).should be nil
185
+ end
186
+
187
+ end
133
188
 
134
- remote_file = File.join("/tmp", "ssh-download-remote")
135
- IO.write(remote_file, data)
189
+ describe "stderr" do
136
190
 
137
- File.exists?(local_file).should == false
138
- subject.download(remote_file, local_file)
139
- File.exists?(local_file).should == true
191
+ it "should capture STDERR and send it to the appropriate pipe" do
192
+ stdout, stderr, stdin = StringIO.new, StringIO.new, StringIO.new
193
+ subject.config do |config|
194
+ config.stdout, config.stderr, config.stdin = stdout, stderr, stdin
140
195
 
141
- File.exists?(local_file) && File.delete(local_file)
142
- File.exists?(remote_file) && File.delete(remote_file)
196
+ config.user = ENV["USER"]
197
+ config.host_name = "127.0.0.1"
143
198
  end
199
+ data = "Hello World @ #{Time.now.utc}"
144
200
 
201
+ subject.exec(%Q{echo "#{data}" -f >&2})
202
+
203
+ stdout.rewind
204
+ stdout.read.match(data).should be nil
205
+
206
+ stderr.rewind
207
+ stderr.read.match(data).should_not be nil
208
+
209
+ stdin.rewind
210
+ stdin.read.match(data).should be nil
211
+ end
212
+ end
213
+
214
+ end
215
+
216
+ describe "upload" do
217
+
218
+ it "should be able to upload a file to 127.0.0.1 as the current user and execute a command (your key must be in ssh-agent)" do
219
+ stdout, stderr, stdin = StringIO.new, StringIO.new, StringIO.new
220
+ subject.config do |config|
221
+ config.stdout, config.stderr, config.stdin = stdout, stderr, stdin
222
+
223
+ config.user = ENV["USER"]
224
+ config.host_name = "127.0.0.1"
225
+ end
226
+
227
+ data = "Hello World @ #{Time.now.utc}"
228
+
229
+ remote_file = File.join("/tmp", "ssh-upload-remote")
230
+ File.exists?(remote_file) && File.delete(remote_file)
231
+
232
+ local_file = File.join("/tmp", "ssh-upload-local")
233
+ IO.write(local_file, data)
234
+
235
+ File.exists?(remote_file).should == false
236
+ subject.upload(local_file, remote_file)
237
+ File.exists?(remote_file).should == true
238
+
239
+ File.exists?(remote_file) && File.delete(remote_file)
240
+ File.exists?(local_file) && File.delete(local_file)
241
+ end
242
+
243
+ end
244
+
245
+ describe "download" do
246
+
247
+ it "should be able to download a file from 127.0.0.1 as the current user and execute a command (your key must be in ssh-agent)" do
248
+ stdout, stderr, stdin = StringIO.new, StringIO.new, StringIO.new
249
+ subject.config do |config|
250
+ config.stdout, config.stderr, config.stdin = stdout, stderr, stdin
251
+
252
+ config.user = ENV["USER"]
253
+ config.host_name = "127.0.0.1"
145
254
  end
146
255
 
256
+ data = "Hello World @ #{Time.now.utc}"
257
+
258
+ local_file = File.join("/tmp", "ssh-download-local")
259
+ File.exists?(local_file) && File.delete(local_file)
260
+
261
+ remote_file = File.join("/tmp", "ssh-download-remote")
262
+ IO.write(remote_file, data)
263
+
264
+ File.exists?(local_file).should == false
265
+ subject.download(remote_file, local_file)
266
+ File.exists?(local_file).should == true
267
+
268
+ File.exists?(local_file) && File.delete(local_file)
269
+ File.exists?(remote_file) && File.delete(remote_file)
147
270
  end
148
271
 
149
- describe "proxy behaviour" do
272
+ end
150
273
 
151
- describe "execute" do
274
+ end if !ENV['CI'] && !ENV['TRAVIS']
152
275
 
153
- it "should be able to proxy through 127.0.0.1, connecting to 127.0.0.1 as the current user and execute a command (your key must be in ssh-agent)" do
154
- stdout, stderr = StringIO.new, StringIO.new
155
- subject.config do |config|
156
- config.stdout = stdout
157
- config.stderr = stderr
158
- config.user = ENV["USER"]
159
- config.host_name = "127.0.0.1"
160
- config.proxy_user = ENV["USER"]
161
- config.proxy_host_name = "127.0.0.1"
162
- end
276
+ describe "proxy SSH behaviour" do
163
277
 
164
- data = %x( hostname -f ).chomp
278
+ describe "execute" do
165
279
 
166
- status = subject.exec("hostname -f")
167
- status.exit.exitstatus.should == 0
168
- stdout.rewind
169
- stdout.read.chomp.should == data
170
- end
280
+ it "should be able to proxy through 127.0.0.1, connecting to 127.0.0.1 as the current user and execute a command (your key must be in ssh-agent)" do
281
+ stdout, stderr, stdin = StringIO.new, StringIO.new, StringIO.new
282
+ subject.config do |config|
283
+ config.stdout, config.stderr, config.stdin = stdout, stderr, stdin
171
284
 
285
+ config.user = ENV["USER"]
286
+ config.host_name = "127.0.0.1"
287
+ config.proxy_user = ENV["USER"]
288
+ config.proxy_host_name = "127.0.0.1"
172
289
  end
173
290
 
174
- describe "upload" do
291
+ data = %x( hostname -f ).chomp
175
292
 
176
- it "should be able to upload a file to 127.0.0.1 as the current user and execute a command (your key must be in ssh-agent)" do
177
- stdout, stderr = StringIO.new, StringIO.new
178
- subject.config do |config|
179
- config.stdout = stdout
180
- config.stderr = stderr
181
- config.user = ENV["USER"]
182
- config.host_name = "127.0.0.1"
183
- config.proxy_user = ENV["USER"]
184
- config.proxy_host_name = "127.0.0.1"
185
- end
293
+ status = subject.exec("hostname -f")
294
+ status.exit_code.should == 0
295
+ stdout.rewind
296
+ stdout.read.chomp.should == data
297
+ end
186
298
 
187
- data = "Hello World"
299
+ it "should timeout after the period specified" do
300
+ stdout, stderr, stdin = StringIO.new, StringIO.new, StringIO.new
301
+ subject.config do |config|
302
+ config.stdout, config.stderr, config.stdin = stdout, stderr, stdin
188
303
 
189
- remote_file = File.join("/tmp", "ssh-upload-remote")
190
- File.exists?(remote_file) && File.delete(remote_file)
304
+ config.user = ENV["USER"]
305
+ config.host_name = "127.0.0.1"
306
+ config.proxy_user = ENV["USER"]
307
+ config.proxy_host_name = "127.0.0.1"
308
+ config.timeout = WAIT_SMALL
309
+ end
310
+ hostname = %x(hostname -f).chomp
311
+ lambda { subject.exec("hostname -f ; sleep 10") }.should raise_error ZTK::SSHError
312
+ end
191
313
 
192
- local_file = File.join("/tmp", "ssh-upload-local")
193
- IO.write(local_file, data)
314
+ it "should throw an exception if the exit status is not as expected" do
315
+ stdout, stderr, stdin = StringIO.new, StringIO.new, StringIO.new
316
+ subject.config do |config|
317
+ config.stdout, config.stderr, config.stdin = stdout, stderr, stdin
194
318
 
195
- File.exists?(remote_file).should == false
196
- subject.upload(local_file, remote_file)
197
- File.exists?(remote_file).should == true
319
+ config.user = ENV["USER"]
320
+ config.host_name = "127.0.0.1"
321
+ config.proxy_user = ENV["USER"]
322
+ config.proxy_host_name = "127.0.0.1"
323
+ end
324
+ lambda { subject.exec("/bin/bash -c 'exit 64'") }.should raise_error ZTK::SSHError
325
+ end
198
326
 
199
- File.exists?(remote_file) && File.delete(remote_file)
200
- File.exists?(local_file) && File.delete(local_file)
201
- end
327
+ it "should return a instance of an OpenStruct object" do
328
+ stdout, stderr, stdin = StringIO.new, StringIO.new, StringIO.new
329
+ subject.config do |config|
330
+ config.stdout, config.stderr, config.stdin = stdout, stderr, stdin
331
+
332
+ config.user = ENV["USER"]
333
+ config.host_name = "127.0.0.1"
334
+ config.proxy_user = ENV["USER"]
335
+ config.proxy_host_name = "127.0.0.1"
336
+ end
337
+ result = subject.exec(%q{echo "Hello World"})
338
+ result.should be_an_instance_of OpenStruct
339
+ end
202
340
 
341
+ it "should return the exit code" do
342
+ stdout, stderr, stdin = StringIO.new, StringIO.new, StringIO.new
343
+ subject.config do |config|
344
+ config.stdout, config.stderr, config.stdin = stdout, stderr, stdin
345
+
346
+ config.user = ENV["USER"]
347
+ config.host_name = "127.0.0.1"
348
+ config.proxy_user = ENV["USER"]
349
+ config.proxy_host_name = "127.0.0.1"
203
350
  end
351
+ data = 64
204
352
 
205
- describe "download" do
353
+ result = subject.exec(%Q{/bin/bash -c 'exit #{data}'}, :exit_code => data)
354
+ result.exit_code.should == data
355
+ end
356
+
357
+ it "should return the output" do
358
+ stdout, stderr, stdin = StringIO.new, StringIO.new, StringIO.new
359
+ subject.config do |config|
360
+ config.stdout, config.stderr, config.stdin = stdout, stderr, stdin
361
+
362
+ config.user = ENV["USER"]
363
+ config.host_name = "127.0.0.1"
364
+ config.proxy_user = ENV["USER"]
365
+ config.proxy_host_name = "127.0.0.1"
366
+ end
367
+ data = "Hello World @ #{Time.now.utc}"
206
368
 
207
- it "should be able to download a file from 127.0.0.1 as the current user and execute a command (your key must be in ssh-agent)" do
208
- stdout, stderr = StringIO.new, StringIO.new
209
- subject.config do |config|
210
- config.stdout = stdout
211
- config.stderr = stderr
212
- config.user = ENV["USER"]
213
- config.host_name = "127.0.0.1"
214
- config.proxy_user = ENV["USER"]
215
- config.proxy_host_name = "127.0.0.1"
216
- end
369
+ result = subject.exec(%Q{echo "#{data}"})
370
+ result.output.match(data).should_not be nil
371
+ end
217
372
 
218
- data = "Hello World"
373
+ it "should allow us to change the expected exit code" do
374
+ stdout, stderr, stdin = StringIO.new, StringIO.new, StringIO.new
375
+ subject.config do |config|
376
+ config.stdout, config.stderr, config.stdin = stdout, stderr, stdin
219
377
 
220
- local_file = File.join("/tmp", "ssh-download-local")
221
- File.exists?(local_file) && File.delete(local_file)
378
+ config.user = ENV["USER"]
379
+ config.host_name = "127.0.0.1"
380
+ config.proxy_user = ENV["USER"]
381
+ config.proxy_host_name = "127.0.0.1"
382
+ end
383
+ data = 32
384
+ result = subject.exec(%Q{/bin/bash -c 'exit #{data}'}, :exit_code => data)
385
+ end
222
386
 
223
- remote_file = File.join("/tmp", "ssh-download-remote")
224
- IO.write(remote_file, data)
387
+ describe "stdout" do
225
388
 
226
- File.exists?(local_file).should == false
227
- subject.download(remote_file, local_file)
228
- File.exists?(local_file).should == true
389
+ it "should capture STDOUT and send it to the appropriate pipe" do
390
+ stdout, stderr, stdin = StringIO.new, StringIO.new, StringIO.new
391
+ subject.config do |config|
392
+ config.stdout, config.stderr, config.stdin = stdout, stderr, stdin
229
393
 
230
- File.exists?(local_file) && File.delete(local_file)
231
- File.exists?(remote_file) && File.delete(remote_file)
394
+ config.user = ENV["USER"]
395
+ config.host_name = "127.0.0.1"
396
+ config.proxy_user = ENV["USER"]
397
+ config.proxy_host_name = "127.0.0.1"
232
398
  end
399
+ data = "Hello World @ #{Time.now.utc}"
400
+
401
+ subject.exec(%Q{echo "#{data}" -f >&1})
233
402
 
403
+ stdout.rewind
404
+ stdout.read.match(data).should_not be nil
405
+
406
+ stderr.rewind
407
+ stderr.read.match(data).should be nil
408
+
409
+ stdin.rewind
410
+ stdin.read.match(data).should be nil
234
411
  end
235
412
 
236
413
  end
237
414
 
415
+ describe "stderr" do
416
+
417
+ it "should capture STDERR and send it to the appropriate pipe" do
418
+ stdout, stderr, stdin = StringIO.new, StringIO.new, StringIO.new
419
+ subject.config do |config|
420
+ config.stdout, config.stderr, config.stdin = stdout, stderr, stdin
421
+
422
+ config.user = ENV["USER"]
423
+ config.host_name = "127.0.0.1"
424
+ config.proxy_user = ENV["USER"]
425
+ config.proxy_host_name = "127.0.0.1"
426
+ end
427
+ data = "Hello World @ #{Time.now.utc}"
428
+
429
+ subject.exec(%Q{echo "#{data}" -f >&2})
430
+
431
+ stdout.rewind
432
+ stdout.read.match(data).should be nil
433
+
434
+ stderr.rewind
435
+ stderr.read.match(data).should_not be nil
436
+
437
+ stdin.rewind
438
+ stdin.read.match(data).should be nil
439
+ end
440
+ end
441
+
238
442
  end
239
443
 
240
- end
444
+ describe "upload" do
445
+
446
+ it "should be able to upload a file to 127.0.0.1 as the current user and execute a command (your key must be in ssh-agent)" do
447
+ stdout, stderr, stdin = StringIO.new, StringIO.new, StringIO.new
448
+ subject.config do |config|
449
+ config.stdout, config.stderr, config.stdin = stdout, stderr, stdin
450
+
451
+ config.user = ENV["USER"]
452
+ config.host_name = "127.0.0.1"
453
+ config.proxy_user = ENV["USER"]
454
+ config.proxy_host_name = "127.0.0.1"
455
+ end
456
+
457
+ data = "Hello World @ #{Time.now.utc}"
458
+
459
+ remote_file = File.join("/tmp", "ssh-upload-remote")
460
+ File.exists?(remote_file) && File.delete(remote_file)
461
+
462
+ local_file = File.join("/tmp", "ssh-upload-local")
463
+ IO.write(local_file, data)
464
+
465
+ File.exists?(remote_file).should == false
466
+ subject.upload(local_file, remote_file)
467
+ File.exists?(remote_file).should == true
468
+
469
+ File.exists?(remote_file) && File.delete(remote_file)
470
+ File.exists?(local_file) && File.delete(local_file)
471
+ end
472
+
473
+ end
474
+
475
+ describe "download" do
476
+
477
+ it "should be able to download a file from 127.0.0.1 as the current user and execute a command (your key must be in ssh-agent)" do
478
+ stdout, stderr, stdin = StringIO.new, StringIO.new, StringIO.new
479
+ subject.config do |config|
480
+ config.stdout, config.stderr, config.stdin = stdout, stderr, stdin
481
+
482
+ config.user = ENV["USER"]
483
+ config.host_name = "127.0.0.1"
484
+ config.proxy_user = ENV["USER"]
485
+ config.proxy_host_name = "127.0.0.1"
486
+ end
487
+
488
+ data = "Hello World @ #{Time.now.utc}"
489
+
490
+ local_file = File.join("/tmp", "ssh-download-local")
491
+ File.exists?(local_file) && File.delete(local_file)
492
+
493
+ remote_file = File.join("/tmp", "ssh-download-remote")
494
+ IO.write(remote_file, data)
495
+
496
+ File.exists?(local_file).should == false
497
+ subject.download(remote_file, local_file)
498
+ File.exists?(local_file).should == true
499
+
500
+ File.exists?(local_file) && File.delete(local_file)
501
+ File.exists?(remote_file) && File.delete(remote_file)
502
+ end
503
+
504
+ end
505
+
506
+ end if !ENV['CI'] && !ENV['TRAVIS']
241
507
 
242
508
  end