ridley 1.0.3 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.ruby-version +1 -1
- data/lib/ridley/chef/cookbook/syntax_check.rb +2 -1
- data/lib/ridley/chef_object.rb +3 -1
- data/lib/ridley/chef_objects/node_object.rb +7 -4
- data/lib/ridley/errors.rb +3 -0
- data/lib/ridley/host_connector/winrm.rb +1 -5
- data/lib/ridley/sandbox_uploader.rb +31 -25
- data/lib/ridley/version.rb +1 -1
- data/ridley.gemspec +1 -0
- data/spec/acceptance/sandbox_resource_spec.rb +2 -2
- data/spec/unit/ridley/chef_object_spec.rb +12 -5
- data/spec/unit/ridley/chef_objects/node_object_spec.rb +49 -0
- data/spec/unit/ridley/sandbox_uploader_spec.rb +25 -28
- metadata +19 -6
- data/lib/ridley/mixin/shell_out.rb +0 -84
- data/spec/unit/ridley/mixin/shell_out_spec.rb +0 -37
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.9.3-
|
1
|
+
1.9.3-p429
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'shellwords'
|
2
|
+
require 'buff/shell_out'
|
2
3
|
|
3
4
|
module Ridley::Chef
|
4
5
|
class Cookbook
|
@@ -67,8 +68,8 @@ module Ridley::Chef
|
|
67
68
|
end
|
68
69
|
end
|
69
70
|
|
71
|
+
include Buff::ShellOut
|
70
72
|
include Ridley::Logging
|
71
|
-
include Ridley::Mixin::ShellOut
|
72
73
|
include Ridley::Mixin::Checksum
|
73
74
|
|
74
75
|
attr_reader :cookbook_path
|
data/lib/ridley/chef_object.rb
CHANGED
@@ -30,10 +30,13 @@ module Ridley
|
|
30
30
|
alias_method :default_attributes, :default
|
31
31
|
alias_method :override_attributes, :override
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
# A merged hash containing a deep merge of all of the attributes respecting the node attribute
|
34
|
+
# precedence level.
|
35
|
+
#
|
36
|
+
# @return [hashie::Mash]
|
37
|
+
def chef_attributes
|
38
|
+
default.merge(normal.merge(override.merge(automatic)))
|
39
|
+
end
|
37
40
|
|
38
41
|
# Set a node level normal attribute given the dotted path representation of the Chef
|
39
42
|
# attribute and value.
|
data/lib/ridley/errors.rb
CHANGED
@@ -65,6 +65,9 @@ module Ridley
|
|
65
65
|
class SandboxCommitError < RidleyError; end
|
66
66
|
class PermissionDenied < RidleyError; end
|
67
67
|
|
68
|
+
class SandboxUploadError < RidleyError; end
|
69
|
+
class ChecksumMismatch < RidleyError; end
|
70
|
+
|
68
71
|
class HTTPError < RidleyError
|
69
72
|
class << self
|
70
73
|
def fabricate(env)
|
@@ -81,11 +81,7 @@ module Ridley
|
|
81
81
|
end
|
82
82
|
end
|
83
83
|
ensure
|
84
|
-
|
85
|
-
command_uploaders.map(&:cleanup)
|
86
|
-
rescue ::WinRM::WinRMHTTPTransportError => ex
|
87
|
-
log.info "Error cleaning up leftover Powershell scripts on some hosts"
|
88
|
-
end
|
84
|
+
command_uploaders.map(&:cleanup)
|
89
85
|
end
|
90
86
|
|
91
87
|
# Returns the command if it does not break the WinRM command length
|
@@ -4,35 +4,30 @@ module Ridley
|
|
4
4
|
class << self
|
5
5
|
# Return the checksum of the contents of the file at the given filepath
|
6
6
|
#
|
7
|
-
# @param [String]
|
8
|
-
#
|
7
|
+
# @param [String] io
|
8
|
+
# a filepath or an IO
|
9
|
+
# @param [Digest::Base] digest
|
9
10
|
#
|
10
11
|
# @return [String]
|
11
12
|
# the binary checksum of the contents of the file
|
12
|
-
def checksum(
|
13
|
-
|
13
|
+
def checksum(io, digest = Digest::MD5.new)
|
14
|
+
io = io.dup
|
15
|
+
while chunk = io.read(1024 * 8)
|
16
|
+
digest.update(chunk)
|
17
|
+
end
|
18
|
+
digest.hexdigest
|
14
19
|
end
|
15
20
|
|
16
21
|
# Return a base64 encoded checksum of the contents of the given file. This is the expected
|
17
22
|
# format of sandbox checksums given to the Chef Server.
|
18
23
|
#
|
19
|
-
# @param [String] path
|
20
|
-
#
|
21
|
-
# @return [String]
|
22
|
-
# a base64 encoded checksum
|
23
|
-
def checksum64(path)
|
24
|
-
Base64.encode64([checksum(path)].pack("H*")).strip
|
25
|
-
end
|
26
|
-
|
27
24
|
# @param [String] io
|
28
|
-
#
|
25
|
+
# a filepath or an IO
|
29
26
|
#
|
30
27
|
# @return [String]
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
35
|
-
digest.hexdigest
|
28
|
+
# a base64 encoded checksum
|
29
|
+
def checksum64(io)
|
30
|
+
Base64.encode64([checksum(io)].pack("H*")).strip
|
36
31
|
end
|
37
32
|
end
|
38
33
|
|
@@ -53,22 +48,33 @@ module Ridley
|
|
53
48
|
# @param [Ridley::SandboxObject] sandbox
|
54
49
|
# @param [String] chk_id
|
55
50
|
# checksum of the file being uploaded
|
56
|
-
# @param [String]
|
57
|
-
#
|
51
|
+
# @param [String, #read] file
|
52
|
+
# a filepath or an IO
|
53
|
+
#
|
54
|
+
# @raise [Errors::ChecksumMismatch]
|
55
|
+
# if the given file does not match the expected checksum
|
58
56
|
#
|
59
57
|
# @return [Hash, nil]
|
60
|
-
def upload(sandbox, chk_id,
|
58
|
+
def upload(sandbox, chk_id, file)
|
61
59
|
checksum = sandbox.checksum(chk_id)
|
62
60
|
|
63
61
|
unless checksum[:needs_upload]
|
64
62
|
return nil
|
65
63
|
end
|
66
64
|
|
67
|
-
|
65
|
+
io = file.respond_to?(:read) ? file : File.new(file, 'rb')
|
66
|
+
calculated_checksum = self.class.checksum64(io)
|
67
|
+
expected_checksum = Base64.encode64([chk_id].pack('H*')).strip
|
68
|
+
|
69
|
+
unless calculated_checksum == expected_checksum
|
70
|
+
raise Errors::ChecksumMismatch,
|
71
|
+
"Error uploading #{chk_id}. Expected #{expected_checksum} but got #{calculated_checksum}"
|
72
|
+
end
|
73
|
+
|
74
|
+
headers = {
|
68
75
|
'Content-Type' => 'application/x-binary',
|
69
|
-
'content-md5' =>
|
76
|
+
'content-md5' => calculated_checksum
|
70
77
|
}
|
71
|
-
contents = File.open(path, 'rb') { |f| f.read }
|
72
78
|
|
73
79
|
url = URI(checksum[:url])
|
74
80
|
upload_path = url.path
|
@@ -86,7 +92,7 @@ module Ridley
|
|
86
92
|
c.response :follow_redirects
|
87
93
|
c.request :chef_auth, self.client_name, self.client_key
|
88
94
|
c.adapter :net_http
|
89
|
-
end.put(upload_path,
|
95
|
+
end.put(upload_path, io.read, headers)
|
90
96
|
rescue Ridley::Errors::HTTPError => ex
|
91
97
|
abort(ex)
|
92
98
|
end
|
data/lib/ridley/version.rb
CHANGED
data/ridley.gemspec
CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.required_ruby_version = ">= 1.9.1"
|
19
19
|
|
20
20
|
s.add_runtime_dependency 'addressable'
|
21
|
+
s.add_runtime_dependency 'buff-shell_out', '~> 0.1'
|
21
22
|
s.add_runtime_dependency 'chozo', '>= 0.6.0'
|
22
23
|
s.add_runtime_dependency 'celluloid', '~> 0.14.0'
|
23
24
|
s.add_runtime_dependency 'celluloid-io', '~> 0.14.0'
|
@@ -8,8 +8,8 @@ describe "Sandbox API operations", type: "acceptance" do
|
|
8
8
|
|
9
9
|
let(:checksums) do
|
10
10
|
[
|
11
|
-
Ridley::SandboxUploader.checksum(fixtures_path.join("recipe_one.rb")),
|
12
|
-
Ridley::SandboxUploader.checksum(fixtures_path.join("recipe_two.rb"))
|
11
|
+
Ridley::SandboxUploader.checksum(File.open(fixtures_path.join("recipe_one.rb"))),
|
12
|
+
Ridley::SandboxUploader.checksum(File.open(fixtures_path.join("recipe_two.rb")))
|
13
13
|
]
|
14
14
|
end
|
15
15
|
|
@@ -142,21 +142,28 @@ describe Ridley::ChefObject do
|
|
142
142
|
end
|
143
143
|
|
144
144
|
describe "#reload" do
|
145
|
-
let(:updated_subject) { double('updated_subject', _attributes_: {
|
145
|
+
let(:updated_subject) { double('updated_subject', _attributes_: { one: "val" }) }
|
146
146
|
|
147
147
|
before(:each) do
|
148
|
-
subject.class.attribute(:
|
149
|
-
|
148
|
+
subject.class.attribute(:one)
|
149
|
+
subject.class.attribute(:two)
|
150
|
+
resource.stub(:find).with(subject).and_return(updated_subject)
|
150
151
|
end
|
151
152
|
|
152
153
|
it "returns itself" do
|
153
154
|
subject.reload.should eql(subject)
|
154
155
|
end
|
155
156
|
|
156
|
-
it "sets the attributes of self to
|
157
|
+
it "sets the attributes of self to equal those of the updated object" do
|
157
158
|
subject.reload
|
158
159
|
|
159
|
-
subject.get_attribute(:
|
160
|
+
subject.get_attribute(:one).should eql("val")
|
161
|
+
end
|
162
|
+
|
163
|
+
it "does not include attributes not set by the updated object" do
|
164
|
+
subject.two = "other"
|
165
|
+
subject.reload
|
166
|
+
expect(subject.two).to be_nil
|
160
167
|
end
|
161
168
|
end
|
162
169
|
|
@@ -5,6 +5,55 @@ describe Ridley::NodeObject do
|
|
5
5
|
let(:instance) { described_class.new(resource) }
|
6
6
|
subject { instance }
|
7
7
|
|
8
|
+
describe "#chef_attributes" do
|
9
|
+
subject { instance.chef_attributes }
|
10
|
+
|
11
|
+
it "returns a Hashie::Mash" do
|
12
|
+
expect(subject).to be_a(Hashie::Mash)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "includes default attributes" do
|
16
|
+
instance.default = default = { default: { one: "val", two: "val" } }
|
17
|
+
expect(subject.to_hash).to include(default)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "includes normal attributes" do
|
21
|
+
instance.normal = normal = { normal: { one: "new", two: "val" } }
|
22
|
+
expect(subject.to_hash).to include(normal)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "includes override attributes" do
|
26
|
+
instance.override = override = { override: { one: "new", two: "val" } }
|
27
|
+
expect(subject.to_hash).to include(override)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "includes automatic attributes" do
|
31
|
+
instance.automatic = automatic = { automatic: { one: "new", two: "val" } }
|
32
|
+
expect(subject.to_hash).to include(automatic)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "overrides default attributes with normal attributes" do
|
36
|
+
instance.default = default = { one: "old", two: "old" }
|
37
|
+
instance.normal = normal = { one: "new" }
|
38
|
+
expect(subject[:one]).to eql("new")
|
39
|
+
expect(subject[:two]).to eql("old")
|
40
|
+
end
|
41
|
+
|
42
|
+
it "overrides normal attributes with override attributes" do
|
43
|
+
instance.normal = normal = { one: "old", two: "old" }
|
44
|
+
instance.override = override = { one: "new" }
|
45
|
+
expect(subject[:one]).to eql("new")
|
46
|
+
expect(subject[:two]).to eql("old")
|
47
|
+
end
|
48
|
+
|
49
|
+
it "overrides override attributes with automatic attributes" do
|
50
|
+
instance.override = override = { one: "old", two: "old" }
|
51
|
+
instance.automatic = automatic = { one: "new" }
|
52
|
+
expect(subject[:one]).to eql("new")
|
53
|
+
expect(subject[:two]).to eql("old")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
8
57
|
describe "#set_chef_attribute" do
|
9
58
|
it "sets an normal node attribute at the nested path" do
|
10
59
|
subject.set_chef_attribute('deep.nested.item', true)
|
@@ -1,6 +1,24 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Ridley::SandboxUploader do
|
4
|
+
describe "ClassMethods" do
|
5
|
+
subject { described_class }
|
6
|
+
|
7
|
+
describe "::checksum" do
|
8
|
+
let(:io) { StringIO.new("some long string") }
|
9
|
+
subject { described_class.checksum(io) }
|
10
|
+
|
11
|
+
it { should eq("2fb66bbfb88cdf9e07a3f1d1dfad71ab") }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "::checksum64" do
|
15
|
+
let(:io) { StringIO.new("some long string") }
|
16
|
+
subject { described_class.checksum64(io) }
|
17
|
+
|
18
|
+
it { should eq("L7Zrv7iM354Ho/HR361xqw==") }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
4
22
|
let(:client_name) { "reset" }
|
5
23
|
let(:client_key) { fixtures_path.join('reset.pem') }
|
6
24
|
let(:connection) do
|
@@ -22,35 +40,14 @@ describe Ridley::SandboxUploader do
|
|
22
40
|
|
23
41
|
let(:sandbox) { Ridley::SandboxObject.new(resource, checksums: checksums) }
|
24
42
|
|
25
|
-
describe "ClassMethods" do
|
26
|
-
subject { described_class }
|
27
|
-
|
28
|
-
describe "::checksum" do
|
29
|
-
subject { described_class.checksum(path) }
|
30
|
-
|
31
|
-
let(:path) { fixtures_path.join('reset.pem') }
|
32
|
-
|
33
|
-
it { should eq("a0608f1eb43ee4cca510bf95f8d209f7") }
|
34
|
-
end
|
35
|
-
|
36
|
-
describe "::checksum64" do
|
37
|
-
subject { described_class.checksum64(path) }
|
38
|
-
|
39
|
-
let(:path) { fixtures_path.join('reset.pem') }
|
40
|
-
|
41
|
-
it { should eq("oGCPHrQ+5MylEL+V+NIJ9w==") }
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
43
|
subject { described_class.new(client_name, client_key, {}) }
|
46
44
|
|
47
45
|
describe "#upload" do
|
48
|
-
let(:chk_id) { "
|
46
|
+
let(:chk_id) { "a0608f1eb43ee4cca510bf95f8d209f7" }
|
49
47
|
let(:path) { fixtures_path.join('reset.pem').to_s }
|
48
|
+
let(:different_path) { fixtures_path.join('recipe_one.rb').to_s }
|
50
49
|
|
51
|
-
before
|
52
|
-
connection.stub(foss?: false)
|
53
|
-
end
|
50
|
+
before { connection.stub(foss?: false) }
|
54
51
|
|
55
52
|
context "when the checksum needs uploading" do
|
56
53
|
let(:checksums) do
|
@@ -67,6 +64,10 @@ describe Ridley::SandboxUploader do
|
|
67
64
|
|
68
65
|
subject.upload(sandbox, chk_id, path)
|
69
66
|
end
|
67
|
+
|
68
|
+
it "raises an exception when the calcuated checksum does not match the expected checksum" do
|
69
|
+
expect { subject.upload(sandbox, chk_id, different_path) }.to raise_error(Ridley::Errors::ChecksumMismatch)
|
70
|
+
end
|
70
71
|
end
|
71
72
|
|
72
73
|
context "when the checksum doesn't need uploading" do
|
@@ -78,10 +79,6 @@ describe Ridley::SandboxUploader do
|
|
78
79
|
}
|
79
80
|
end
|
80
81
|
|
81
|
-
let(:sandbox) do
|
82
|
-
Ridley::SandboxObject.new(double, checksums: checksums)
|
83
|
-
end
|
84
|
-
|
85
82
|
it "returns nil" do
|
86
83
|
subject.upload(sandbox, chk_id, path).should be_nil
|
87
84
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ridley
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-06-
|
13
|
+
date: 2013-06-12 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: addressable
|
@@ -28,6 +28,22 @@ dependencies:
|
|
28
28
|
- - ! '>='
|
29
29
|
- !ruby/object:Gem::Version
|
30
30
|
version: '0'
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: buff-shell_out
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ~>
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0.1'
|
39
|
+
type: :runtime
|
40
|
+
prerelease: false
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ~>
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0.1'
|
31
47
|
- !ruby/object:Gem::Dependency
|
32
48
|
name: chozo
|
33
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -280,7 +296,6 @@ files:
|
|
280
296
|
- lib/ridley/middleware/retry.rb
|
281
297
|
- lib/ridley/mixin.rb
|
282
298
|
- lib/ridley/mixin/checksum.rb
|
283
|
-
- lib/ridley/mixin/shell_out.rb
|
284
299
|
- lib/ridley/resource.rb
|
285
300
|
- lib/ridley/resources.rb
|
286
301
|
- lib/ridley/resources/client_resource.rb
|
@@ -356,7 +371,6 @@ files:
|
|
356
371
|
- spec/unit/ridley/middleware/chef_response_spec.rb
|
357
372
|
- spec/unit/ridley/middleware/gzip_spec.rb
|
358
373
|
- spec/unit/ridley/middleware/parse_json_spec.rb
|
359
|
-
- spec/unit/ridley/mixin/shell_out_spec.rb
|
360
374
|
- spec/unit/ridley/resource_spec.rb
|
361
375
|
- spec/unit/ridley/resources/client_resource_spec.rb
|
362
376
|
- spec/unit/ridley/resources/cookbook_resource_spec.rb
|
@@ -390,7 +404,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
390
404
|
version: '0'
|
391
405
|
segments:
|
392
406
|
- 0
|
393
|
-
hash: -
|
407
|
+
hash: -1556301606897048958
|
394
408
|
requirements: []
|
395
409
|
rubyforge_project:
|
396
410
|
rubygems_version: 1.8.23
|
@@ -457,7 +471,6 @@ test_files:
|
|
457
471
|
- spec/unit/ridley/middleware/chef_response_spec.rb
|
458
472
|
- spec/unit/ridley/middleware/gzip_spec.rb
|
459
473
|
- spec/unit/ridley/middleware/parse_json_spec.rb
|
460
|
-
- spec/unit/ridley/mixin/shell_out_spec.rb
|
461
474
|
- spec/unit/ridley/resource_spec.rb
|
462
475
|
- spec/unit/ridley/resources/client_resource_spec.rb
|
463
476
|
- spec/unit/ridley/resources/cookbook_resource_spec.rb
|
@@ -1,84 +0,0 @@
|
|
1
|
-
module Ridley
|
2
|
-
module Mixin
|
3
|
-
# A Ruby platform agnostic way of executing shell commands on the local system
|
4
|
-
module ShellOut
|
5
|
-
class Response
|
6
|
-
# @return [Fixnum]
|
7
|
-
attr_reader :exitstatus
|
8
|
-
# @return [String]
|
9
|
-
attr_reader :stdout
|
10
|
-
# @return [String]
|
11
|
-
attr_reader :stderr
|
12
|
-
|
13
|
-
# @param [Fixnum] exitstatus
|
14
|
-
# @param [String] stdout
|
15
|
-
# @param [String] stderr
|
16
|
-
def initialize(exitstatus, stdout, stderr)
|
17
|
-
@exitstatus = exitstatus
|
18
|
-
@stdout = stdout
|
19
|
-
@stderr = stderr
|
20
|
-
end
|
21
|
-
|
22
|
-
def success?
|
23
|
-
exitstatus == 0
|
24
|
-
end
|
25
|
-
|
26
|
-
def error?
|
27
|
-
!success?
|
28
|
-
end
|
29
|
-
alias_method :failure?, :error?
|
30
|
-
end
|
31
|
-
|
32
|
-
include Chozo::RubyEngine
|
33
|
-
extend self
|
34
|
-
|
35
|
-
# Executes the given shell command on the local system
|
36
|
-
#
|
37
|
-
# @param [String] command
|
38
|
-
# The command to execute
|
39
|
-
#
|
40
|
-
# @return [ShellOut::Response]
|
41
|
-
def shell_out(command)
|
42
|
-
process_status, out, err = jruby? ? jruby_out(command) : mri_out(command)
|
43
|
-
Response.new(process_status, out, err)
|
44
|
-
end
|
45
|
-
|
46
|
-
private
|
47
|
-
|
48
|
-
# @param [String] command
|
49
|
-
# The command to execute
|
50
|
-
def mri_out(command)
|
51
|
-
out, err = Tempfile.new('ridley.shell_out.stdout'), Tempfile.new('ridley.shell_out.stderr')
|
52
|
-
|
53
|
-
begin
|
54
|
-
pid = Process.spawn(command, out: out.to_i, err: err.to_i)
|
55
|
-
pid, status = Process.waitpid2(pid)
|
56
|
-
exitstatus = status.exitstatus
|
57
|
-
rescue Errno::ENOENT => ex
|
58
|
-
exitstatus = 127
|
59
|
-
out.write("")
|
60
|
-
err.write("command not found: #{command}")
|
61
|
-
end
|
62
|
-
|
63
|
-
out.close
|
64
|
-
err.close
|
65
|
-
|
66
|
-
[ exitstatus, File.read(out), File.read(err) ]
|
67
|
-
end
|
68
|
-
|
69
|
-
# @param [String] command
|
70
|
-
# The command to execute
|
71
|
-
def jruby_out(command)
|
72
|
-
out, err = StringIO.new, StringIO.new
|
73
|
-
$stdout, $stderr = out, err
|
74
|
-
system(command)
|
75
|
-
|
76
|
-
out.rewind
|
77
|
-
err.rewind
|
78
|
-
[ $?, out.read, err.read ]
|
79
|
-
ensure
|
80
|
-
$stdout, $stderr = STDOUT, STDERR
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Ridley::Mixin::ShellOut do
|
4
|
-
describe "shell_out" do
|
5
|
-
let(:command) { "ls" }
|
6
|
-
|
7
|
-
subject(:result) { described_class.shell_out(command) }
|
8
|
-
|
9
|
-
it "returns a ShellOut::Response" do
|
10
|
-
expect(result).to be_a(described_class::Response)
|
11
|
-
end
|
12
|
-
|
13
|
-
its(:stdout) { should be_a(String) }
|
14
|
-
its(:stderr) { should be_a(String) }
|
15
|
-
its(:exitstatus) { should be_a(Fixnum) }
|
16
|
-
its(:success?) { should be_true }
|
17
|
-
its(:error?) { should be_false }
|
18
|
-
|
19
|
-
context "when on MRI" do
|
20
|
-
before { described_class.stub(jruby?: false) }
|
21
|
-
|
22
|
-
it "delegates to #mri_out" do
|
23
|
-
described_class.should_receive(:mri_out).with(command)
|
24
|
-
result
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
context "when on JRuby" do
|
29
|
-
before { described_class.stub(jruby?: true) }
|
30
|
-
|
31
|
-
it "delegates to #jruby_out" do
|
32
|
-
described_class.should_receive(:jruby_out).with(command)
|
33
|
-
result
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|