producer-core 0.1.2 → 0.1.3
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.
- 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
|