producer-core 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/features/steps/remote_steps.rb +3 -0
- data/features/support/ssh.rb +1 -0
- data/features/tests/has_file.feature +23 -0
- data/lib/producer/core.rb +2 -0
- data/lib/producer/core/condition/dsl.rb +2 -1
- data/lib/producer/core/remote.rb +4 -0
- data/lib/producer/core/remote/fs.rb +23 -0
- data/lib/producer/core/tests/has_file.rb +11 -0
- data/lib/producer/core/version.rb +1 -1
- data/producer-core.gemspec +1 -0
- data/spec/producer/core/condition/dsl_spec.rb +1 -1
- data/spec/producer/core/remote/fs_spec.rb +80 -0
- data/spec/producer/core/remote_spec.rb +18 -0
- data/spec/producer/core/tests/has_file_spec.rb +28 -0
- data/spec/support/net_ssh_story_helpers.rb +34 -0
- metadata +28 -2
data/features/support/ssh.rb
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
@sshd
|
2
|
+
Feature: `has_file' condition keyword
|
3
|
+
|
4
|
+
Background:
|
5
|
+
Given a recipe with:
|
6
|
+
"""
|
7
|
+
target 'some_host.test'
|
8
|
+
|
9
|
+
task :testing_file_existence do
|
10
|
+
condition { has_file 'some_file' }
|
11
|
+
|
12
|
+
echo 'evaluated'
|
13
|
+
end
|
14
|
+
"""
|
15
|
+
|
16
|
+
Scenario: succeeds when file exists
|
17
|
+
Given a remote file named "some_file"
|
18
|
+
When I successfully execute the recipe
|
19
|
+
Then the output must contain "evaluated"
|
20
|
+
|
21
|
+
Scenario: fails when file does not exist
|
22
|
+
When I successfully execute the recipe
|
23
|
+
Then the output must not contain "evaluated"
|
data/lib/producer/core.rb
CHANGED
@@ -6,6 +6,7 @@ require 'producer/core/actions/shell_command'
|
|
6
6
|
# condition tests (need to be defined before the condition DSL)
|
7
7
|
require 'producer/core/test'
|
8
8
|
require 'producer/core/tests/has_env'
|
9
|
+
require 'producer/core/tests/has_file'
|
9
10
|
|
10
11
|
require 'producer/core/cli'
|
11
12
|
require 'producer/core/condition'
|
@@ -17,6 +18,7 @@ require 'producer/core/recipe'
|
|
17
18
|
require 'producer/core/recipe/dsl'
|
18
19
|
require 'producer/core/remote'
|
19
20
|
require 'producer/core/remote/environment'
|
21
|
+
require 'producer/core/remote/fs'
|
20
22
|
require 'producer/core/task'
|
21
23
|
require 'producer/core/task/dsl'
|
22
24
|
require 'producer/core/version'
|
data/lib/producer/core/remote.rb
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
module Producer
|
2
|
+
module Core
|
3
|
+
class Remote
|
4
|
+
class FS
|
5
|
+
require 'net/sftp'
|
6
|
+
|
7
|
+
def initialize(remote)
|
8
|
+
@remote = remote
|
9
|
+
end
|
10
|
+
|
11
|
+
def sftp
|
12
|
+
@sftp ||= @remote.session.sftp.connect
|
13
|
+
end
|
14
|
+
|
15
|
+
def has_file?(path)
|
16
|
+
sftp.stat!(path).file?
|
17
|
+
rescue Net::SFTP::StatusException
|
18
|
+
false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/producer-core.gemspec
CHANGED
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Producer::Core
|
4
|
+
describe Remote::FS do
|
5
|
+
let(:remote) { Remote.new('some_host.example') }
|
6
|
+
subject(:fs) { Remote::FS.new(remote) }
|
7
|
+
|
8
|
+
describe '#new' do
|
9
|
+
it 'assigns the remote given as argument' do
|
10
|
+
expect(fs.instance_eval { @remote }).to be remote
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#sftp', :ssh do
|
15
|
+
before { sftp_story }
|
16
|
+
|
17
|
+
it 'builds a new SFTP session' do
|
18
|
+
expect(remote.session.sftp).to receive(:connect)
|
19
|
+
fs.sftp
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'returns the new SFTP session' do
|
23
|
+
session = double('session')
|
24
|
+
allow(remote.session.sftp).to receive(:connect) { session }
|
25
|
+
expect(fs.sftp).to be session
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'memoizes the FS' do
|
29
|
+
allow(remote.session.sftp).to receive(:connect) { Object.new }
|
30
|
+
expect(fs.sftp).to be fs.sftp
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# FIXME: We rely a lot on mocking net-sftp heavily, while we already use a
|
35
|
+
# part of net-ssh story helpers, which are more close to integration tests.
|
36
|
+
describe '#has_file?', :ssh do
|
37
|
+
let(:file_path) { "some_file_path" }
|
38
|
+
let(:stat) { double('stat') }
|
39
|
+
|
40
|
+
before do
|
41
|
+
sftp_story
|
42
|
+
allow(fs.sftp).to receive(:stat!) { stat }
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when path given as argument exists' do
|
46
|
+
context 'when path is a file' do
|
47
|
+
before do
|
48
|
+
allow(stat).to receive(:file?) { true }
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'returns true' do
|
52
|
+
expect(fs.has_file?(file_path)).to be true
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'when path is not a file' do
|
57
|
+
before do
|
58
|
+
allow(stat).to receive(:file?) { false }
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'returns false' do
|
62
|
+
expect(fs.has_file?(file_path)).to be false
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'when querying the path raises a Net::SFTP::StatusException' do
|
68
|
+
before do
|
69
|
+
response = double('response', code: '42', message: '…')
|
70
|
+
ex = Net::SFTP::StatusException.new(response)
|
71
|
+
allow(stat).to receive(:file?).and_raise(ex)
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'returns false' do
|
75
|
+
expect(fs.has_file?(file_path)).to be false
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -29,6 +29,24 @@ module Producer::Core
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
+
describe '#fs' do
|
33
|
+
it 'builds a new FS' do
|
34
|
+
expect(Remote::FS).to receive(:new)
|
35
|
+
remote.fs
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'returns the new FS instance' do
|
39
|
+
fs = double('fs')
|
40
|
+
allow(Remote::FS).to receive(:new) { fs }
|
41
|
+
expect(remote.fs).to be fs
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'memoizes the FS' do
|
45
|
+
allow(Remote::FS).to receive(:new) { Object.new }
|
46
|
+
expect(remote.fs).to be remote.fs
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
32
50
|
describe '#execute', :ssh do
|
33
51
|
let(:arguments) { 'some remote command' }
|
34
52
|
let(:command) { "echo #{arguments}" }
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Producer::Core
|
4
|
+
describe Tests::HasFile do
|
5
|
+
let(:env) { Env.new }
|
6
|
+
let(:filepath) { 'some_file' }
|
7
|
+
subject(:has_file) { Tests::HasFile.new(env, filepath) }
|
8
|
+
|
9
|
+
it 'is a kind of test' do
|
10
|
+
expect(has_file).to be_a Test
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#success?', :ssh do
|
14
|
+
before { sftp_story }
|
15
|
+
|
16
|
+
it 'delegates the call on remote FS' do
|
17
|
+
expect(env.remote.fs).to receive(:has_file?).with(filepath)
|
18
|
+
has_file.success?
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'returns the file existence' do
|
22
|
+
existence = double('existence')
|
23
|
+
allow(env.remote.fs).to receive(:has_file?) { existence }
|
24
|
+
expect(has_file.success?).to be existence
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -2,6 +2,24 @@ module NetSSHStoryHelpers
|
|
2
2
|
require 'net/ssh/test'
|
3
3
|
include Net::SSH::Test
|
4
4
|
|
5
|
+
# FIXME: must be moved elsewhere or implemented another way/form.
|
6
|
+
class ::Net::SSH::Test::Channel
|
7
|
+
def gets_packet(type, *args)
|
8
|
+
gets_data(sftp_packet(type, *args))
|
9
|
+
end
|
10
|
+
|
11
|
+
def sends_packet(type, *args)
|
12
|
+
sends_data(sftp_packet(type, *args))
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def sftp_packet(type, *args)
|
18
|
+
data = Net::SSH::Buffer.from(*args)
|
19
|
+
Net::SSH::Buffer.from(:long, data.length + 1, :byte, type, :raw, data).to_s
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
5
23
|
def story_with_new_channel
|
6
24
|
story do |session|
|
7
25
|
ch = session.opens_channel
|
@@ -14,4 +32,20 @@ module NetSSHStoryHelpers
|
|
14
32
|
def story_completed?
|
15
33
|
socket.script.events.empty?
|
16
34
|
end
|
35
|
+
|
36
|
+
def sftp_story
|
37
|
+
story do |session|
|
38
|
+
ch = session.opens_channel
|
39
|
+
ch.sends_subsystem('sftp')
|
40
|
+
ch.sends_packet(
|
41
|
+
Net::SFTP::Constants::PacketTypes::FXP_INIT, :long,
|
42
|
+
Net::SFTP::Session::HIGHEST_PROTOCOL_VERSION_SUPPORTED
|
43
|
+
)
|
44
|
+
ch.gets_packet(
|
45
|
+
Net::SFTP::Constants::PacketTypes::FXP_VERSION, :long,
|
46
|
+
Net::SFTP::Session::HIGHEST_PROTOCOL_VERSION_SUPPORTED
|
47
|
+
)
|
48
|
+
yield ch if block_given?
|
49
|
+
end
|
50
|
+
end
|
17
51
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: producer-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -27,6 +27,22 @@ dependencies:
|
|
27
27
|
- - ! '>='
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: net-sftp
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
30
46
|
- !ruby/object:Gem::Dependency
|
31
47
|
name: rspec
|
32
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,12 +130,14 @@ files:
|
|
114
130
|
- features/recipes/source.feature
|
115
131
|
- features/recipes/target.feature
|
116
132
|
- features/steps/recipe_steps.rb
|
133
|
+
- features/steps/remote_steps.rb
|
117
134
|
- features/support/env_aruba.rb
|
118
135
|
- features/support/env_cucumber-doc_string.rb
|
119
136
|
- features/support/ssh.rb
|
120
137
|
- features/tasks/condition.feature
|
121
138
|
- features/tasks/evaluation.feature
|
122
139
|
- features/tests/has_env.feature
|
140
|
+
- features/tests/has_file.feature
|
123
141
|
- lib/producer/core.rb
|
124
142
|
- lib/producer/core/action.rb
|
125
143
|
- lib/producer/core/actions/echo.rb
|
@@ -134,10 +152,12 @@ files:
|
|
134
152
|
- lib/producer/core/recipe/dsl.rb
|
135
153
|
- lib/producer/core/remote.rb
|
136
154
|
- lib/producer/core/remote/environment.rb
|
155
|
+
- lib/producer/core/remote/fs.rb
|
137
156
|
- lib/producer/core/task.rb
|
138
157
|
- lib/producer/core/task/dsl.rb
|
139
158
|
- lib/producer/core/test.rb
|
140
159
|
- lib/producer/core/tests/has_env.rb
|
160
|
+
- lib/producer/core/tests/has_file.rb
|
141
161
|
- lib/producer/core/version.rb
|
142
162
|
- producer-core.gemspec
|
143
163
|
- spec/fixtures/recipes/empty.rb
|
@@ -153,11 +173,13 @@ files:
|
|
153
173
|
- spec/producer/core/recipe/dsl_spec.rb
|
154
174
|
- spec/producer/core/recipe_spec.rb
|
155
175
|
- spec/producer/core/remote/environment_spec.rb
|
176
|
+
- spec/producer/core/remote/fs_spec.rb
|
156
177
|
- spec/producer/core/remote_spec.rb
|
157
178
|
- spec/producer/core/task/dsl_spec.rb
|
158
179
|
- spec/producer/core/task_spec.rb
|
159
180
|
- spec/producer/core/test_spec.rb
|
160
181
|
- spec/producer/core/tests/has_env_spec.rb
|
182
|
+
- spec/producer/core/tests/has_file_spec.rb
|
161
183
|
- spec/spec_helper.rb
|
162
184
|
- spec/support/exit_helpers.rb
|
163
185
|
- spec/support/fixtures_helpers.rb
|
@@ -186,7 +208,7 @@ rubyforge_project:
|
|
186
208
|
rubygems_version: 1.8.23
|
187
209
|
signing_key:
|
188
210
|
specification_version: 3
|
189
|
-
summary: producer-core-0.1.
|
211
|
+
summary: producer-core-0.1.3
|
190
212
|
test_files:
|
191
213
|
- features/actions/echo.feature
|
192
214
|
- features/actions/sh.feature
|
@@ -196,12 +218,14 @@ test_files:
|
|
196
218
|
- features/recipes/source.feature
|
197
219
|
- features/recipes/target.feature
|
198
220
|
- features/steps/recipe_steps.rb
|
221
|
+
- features/steps/remote_steps.rb
|
199
222
|
- features/support/env_aruba.rb
|
200
223
|
- features/support/env_cucumber-doc_string.rb
|
201
224
|
- features/support/ssh.rb
|
202
225
|
- features/tasks/condition.feature
|
203
226
|
- features/tasks/evaluation.feature
|
204
227
|
- features/tests/has_env.feature
|
228
|
+
- features/tests/has_file.feature
|
205
229
|
- spec/fixtures/recipes/empty.rb
|
206
230
|
- spec/fixtures/recipes/throw.rb
|
207
231
|
- spec/producer/core/action_spec.rb
|
@@ -215,11 +239,13 @@ test_files:
|
|
215
239
|
- spec/producer/core/recipe/dsl_spec.rb
|
216
240
|
- spec/producer/core/recipe_spec.rb
|
217
241
|
- spec/producer/core/remote/environment_spec.rb
|
242
|
+
- spec/producer/core/remote/fs_spec.rb
|
218
243
|
- spec/producer/core/remote_spec.rb
|
219
244
|
- spec/producer/core/task/dsl_spec.rb
|
220
245
|
- spec/producer/core/task_spec.rb
|
221
246
|
- spec/producer/core/test_spec.rb
|
222
247
|
- spec/producer/core/tests/has_env_spec.rb
|
248
|
+
- spec/producer/core/tests/has_file_spec.rb
|
223
249
|
- spec/spec_helper.rb
|
224
250
|
- spec/support/exit_helpers.rb
|
225
251
|
- spec/support/fixtures_helpers.rb
|