backup 3.0.23 → 3.0.24
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/Gemfile.lock +42 -45
- data/Guardfile +7 -4
- data/README.md +10 -7
- data/backup.gemspec +2 -2
- data/lib/backup.rb +27 -97
- data/lib/backup/archive.rb +14 -6
- data/lib/backup/cli/helpers.rb +52 -49
- data/lib/backup/cli/utility.rb +9 -1
- data/lib/backup/compressor/base.rb +10 -4
- data/lib/backup/compressor/bzip2.rb +22 -26
- data/lib/backup/compressor/custom.rb +53 -0
- data/lib/backup/compressor/gzip.rb +22 -23
- data/lib/backup/compressor/lzma.rb +15 -13
- data/lib/backup/compressor/pbzip2.rb +20 -17
- data/lib/backup/config.rb +6 -3
- data/lib/backup/configuration.rb +33 -0
- data/lib/backup/configuration/helpers.rb +114 -28
- data/lib/backup/configuration/store.rb +24 -0
- data/lib/backup/database/base.rb +0 -6
- data/lib/backup/database/mongodb.rb +27 -11
- data/lib/backup/database/mysql.rb +19 -14
- data/lib/backup/database/postgresql.rb +16 -11
- data/lib/backup/database/redis.rb +7 -11
- data/lib/backup/database/riak.rb +3 -6
- data/lib/backup/dependency.rb +5 -11
- data/lib/backup/model.rb +14 -5
- data/lib/backup/notifier/campfire.rb +3 -16
- data/lib/backup/notifier/hipchat.rb +1 -7
- data/lib/backup/notifier/mail.rb +1 -1
- data/lib/backup/packager.rb +29 -19
- data/lib/backup/pipeline.rb +110 -0
- data/lib/backup/storage/dropbox.rb +4 -7
- data/lib/backup/syncer/base.rb +8 -4
- data/lib/backup/syncer/cloud/base.rb +247 -0
- data/lib/backup/syncer/cloud/cloud_files.rb +78 -0
- data/lib/backup/syncer/cloud/s3.rb +68 -0
- data/lib/backup/syncer/rsync/base.rb +1 -4
- data/lib/backup/syncer/rsync/local.rb +9 -5
- data/lib/backup/syncer/rsync/pull.rb +1 -1
- data/lib/backup/syncer/rsync/push.rb +10 -5
- data/lib/backup/version.rb +1 -1
- data/spec-live/.gitignore +6 -0
- data/spec-live/README +7 -0
- data/spec-live/backups/config.rb +153 -0
- data/spec-live/backups/config.yml.template +43 -0
- data/spec-live/compressor/custom_spec.rb +30 -0
- data/spec-live/compressor/gzip_spec.rb +30 -0
- data/spec-live/notifier/mail_spec.rb +85 -0
- data/spec-live/spec_helper.rb +85 -0
- data/spec-live/storage/dropbox_spec.rb +151 -0
- data/spec-live/storage/local_spec.rb +83 -0
- data/spec-live/storage/scp_spec.rb +193 -0
- data/spec-live/syncer/cloud/s3_spec.rb +124 -0
- data/spec/archive_spec.rb +86 -31
- data/spec/cleaner_spec.rb +8 -0
- data/spec/cli/helpers_spec.rb +200 -75
- data/spec/cli/utility_spec.rb +11 -3
- data/spec/compressor/base_spec.rb +31 -10
- data/spec/compressor/bzip2_spec.rb +212 -57
- data/spec/compressor/custom_spec.rb +106 -0
- data/spec/compressor/gzip_spec.rb +212 -57
- data/spec/compressor/lzma_spec.rb +75 -35
- data/spec/compressor/pbzip2_spec.rb +93 -52
- data/spec/configuration/helpers_spec.rb +406 -0
- data/spec/configuration/store_spec.rb +39 -0
- data/spec/configuration_spec.rb +62 -0
- data/spec/database/base_spec.rb +19 -10
- data/spec/database/mongodb_spec.rb +195 -70
- data/spec/database/mysql_spec.rb +183 -64
- data/spec/database/postgresql_spec.rb +167 -53
- data/spec/database/redis_spec.rb +121 -46
- data/spec/database/riak_spec.rb +96 -27
- data/spec/dependency_spec.rb +2 -0
- data/spec/encryptor/base_spec.rb +10 -0
- data/spec/encryptor/gpg_spec.rb +29 -13
- data/spec/encryptor/open_ssl_spec.rb +40 -21
- data/spec/logger_spec.rb +4 -0
- data/spec/model_spec.rb +19 -2
- data/spec/notifier/base_spec.rb +32 -17
- data/spec/notifier/campfire_spec.rb +63 -45
- data/spec/notifier/hipchat_spec.rb +79 -56
- data/spec/notifier/mail_spec.rb +82 -46
- data/spec/notifier/prowl_spec.rb +53 -32
- data/spec/notifier/twitter_spec.rb +62 -41
- data/spec/packager_spec.rb +95 -36
- data/spec/pipeline_spec.rb +259 -0
- data/spec/spec_helper.rb +6 -5
- data/spec/storage/base_spec.rb +61 -41
- data/spec/storage/cloudfiles_spec.rb +69 -45
- data/spec/storage/dropbox_spec.rb +158 -36
- data/spec/storage/ftp_spec.rb +69 -45
- data/spec/storage/local_spec.rb +47 -23
- data/spec/storage/ninefold_spec.rb +55 -31
- data/spec/storage/rsync_spec.rb +67 -50
- data/spec/storage/s3_spec.rb +65 -41
- data/spec/storage/scp_spec.rb +65 -41
- data/spec/storage/sftp_spec.rb +65 -41
- data/spec/syncer/base_spec.rb +91 -4
- data/spec/syncer/cloud/base_spec.rb +511 -0
- data/spec/syncer/cloud/cloud_files_spec.rb +181 -0
- data/spec/syncer/cloud/s3_spec.rb +174 -0
- data/spec/syncer/rsync/base_spec.rb +46 -66
- data/spec/syncer/rsync/local_spec.rb +55 -26
- data/spec/syncer/rsync/pull_spec.rb +15 -4
- data/spec/syncer/rsync/push_spec.rb +59 -52
- data/templates/cli/utility/compressor/bzip2 +1 -4
- data/templates/cli/utility/compressor/custom +11 -0
- data/templates/cli/utility/compressor/gzip +1 -4
- data/templates/cli/utility/compressor/lzma +3 -0
- data/templates/cli/utility/compressor/pbzip2 +3 -0
- data/templates/cli/utility/database/mysql +4 -1
- data/templates/cli/utility/syncer/cloud_files +17 -19
- data/templates/cli/utility/syncer/s3 +18 -20
- metadata +38 -92
- data/lib/backup/configuration/base.rb +0 -15
- data/lib/backup/configuration/compressor/base.rb +0 -9
- data/lib/backup/configuration/compressor/bzip2.rb +0 -23
- data/lib/backup/configuration/compressor/gzip.rb +0 -23
- data/lib/backup/configuration/compressor/lzma.rb +0 -23
- data/lib/backup/configuration/compressor/pbzip2.rb +0 -28
- data/lib/backup/configuration/database/base.rb +0 -19
- data/lib/backup/configuration/database/mongodb.rb +0 -49
- data/lib/backup/configuration/database/mysql.rb +0 -42
- data/lib/backup/configuration/database/postgresql.rb +0 -41
- data/lib/backup/configuration/database/redis.rb +0 -39
- data/lib/backup/configuration/database/riak.rb +0 -29
- data/lib/backup/configuration/encryptor/base.rb +0 -9
- data/lib/backup/configuration/encryptor/gpg.rb +0 -17
- data/lib/backup/configuration/encryptor/open_ssl.rb +0 -32
- data/lib/backup/configuration/notifier/base.rb +0 -28
- data/lib/backup/configuration/notifier/campfire.rb +0 -25
- data/lib/backup/configuration/notifier/hipchat.rb +0 -41
- data/lib/backup/configuration/notifier/mail.rb +0 -112
- data/lib/backup/configuration/notifier/presently.rb +0 -25
- data/lib/backup/configuration/notifier/prowl.rb +0 -23
- data/lib/backup/configuration/notifier/twitter.rb +0 -21
- data/lib/backup/configuration/storage/base.rb +0 -18
- data/lib/backup/configuration/storage/cloudfiles.rb +0 -25
- data/lib/backup/configuration/storage/dropbox.rb +0 -58
- data/lib/backup/configuration/storage/ftp.rb +0 -29
- data/lib/backup/configuration/storage/local.rb +0 -17
- data/lib/backup/configuration/storage/ninefold.rb +0 -20
- data/lib/backup/configuration/storage/rsync.rb +0 -29
- data/lib/backup/configuration/storage/s3.rb +0 -25
- data/lib/backup/configuration/storage/scp.rb +0 -25
- data/lib/backup/configuration/storage/sftp.rb +0 -25
- data/lib/backup/configuration/syncer/base.rb +0 -10
- data/lib/backup/configuration/syncer/cloud.rb +0 -23
- data/lib/backup/configuration/syncer/cloud_files.rb +0 -30
- data/lib/backup/configuration/syncer/rsync/base.rb +0 -28
- data/lib/backup/configuration/syncer/rsync/local.rb +0 -11
- data/lib/backup/configuration/syncer/rsync/pull.rb +0 -11
- data/lib/backup/configuration/syncer/rsync/push.rb +0 -31
- data/lib/backup/configuration/syncer/s3.rb +0 -23
- data/lib/backup/notifier/presently.rb +0 -88
- data/lib/backup/syncer/cloud.rb +0 -187
- data/lib/backup/syncer/cloud_files.rb +0 -56
- data/lib/backup/syncer/s3.rb +0 -47
- data/spec/configuration/base_spec.rb +0 -35
- data/spec/configuration/compressor/bzip2_spec.rb +0 -29
- data/spec/configuration/compressor/gzip_spec.rb +0 -29
- data/spec/configuration/compressor/lzma_spec.rb +0 -29
- data/spec/configuration/compressor/pbzip2_spec.rb +0 -32
- data/spec/configuration/database/base_spec.rb +0 -17
- data/spec/configuration/database/mongodb_spec.rb +0 -56
- data/spec/configuration/database/mysql_spec.rb +0 -53
- data/spec/configuration/database/postgresql_spec.rb +0 -53
- data/spec/configuration/database/redis_spec.rb +0 -50
- data/spec/configuration/database/riak_spec.rb +0 -35
- data/spec/configuration/encryptor/gpg_spec.rb +0 -26
- data/spec/configuration/encryptor/open_ssl_spec.rb +0 -35
- data/spec/configuration/notifier/base_spec.rb +0 -32
- data/spec/configuration/notifier/campfire_spec.rb +0 -32
- data/spec/configuration/notifier/hipchat_spec.rb +0 -44
- data/spec/configuration/notifier/mail_spec.rb +0 -71
- data/spec/configuration/notifier/presently_spec.rb +0 -35
- data/spec/configuration/notifier/prowl_spec.rb +0 -29
- data/spec/configuration/notifier/twitter_spec.rb +0 -35
- data/spec/configuration/storage/cloudfiles_spec.rb +0 -41
- data/spec/configuration/storage/dropbox_spec.rb +0 -38
- data/spec/configuration/storage/ftp_spec.rb +0 -44
- data/spec/configuration/storage/local_spec.rb +0 -29
- data/spec/configuration/storage/ninefold_spec.rb +0 -32
- data/spec/configuration/storage/rsync_spec.rb +0 -41
- data/spec/configuration/storage/s3_spec.rb +0 -38
- data/spec/configuration/storage/scp_spec.rb +0 -41
- data/spec/configuration/storage/sftp_spec.rb +0 -41
- data/spec/configuration/syncer/cloud_files_spec.rb +0 -44
- data/spec/configuration/syncer/rsync/base_spec.rb +0 -33
- data/spec/configuration/syncer/rsync/local_spec.rb +0 -10
- data/spec/configuration/syncer/rsync/pull_spec.rb +0 -10
- data/spec/configuration/syncer/rsync/push_spec.rb +0 -43
- data/spec/configuration/syncer/s3_spec.rb +0 -38
- data/spec/notifier/presently_spec.rb +0 -181
- data/spec/syncer/cloud_files_spec.rb +0 -192
- data/spec/syncer/s3_spec.rb +0 -192
- data/templates/cli/utility/notifier/presently +0 -13
data/spec/packager_spec.rb
CHANGED
|
@@ -10,29 +10,67 @@ describe 'Backup::Packager' do
|
|
|
10
10
|
let(:package) { mock }
|
|
11
11
|
let(:encryptor) { mock }
|
|
12
12
|
let(:splitter) { mock }
|
|
13
|
+
let(:pipeline) { mock }
|
|
13
14
|
let(:procedure) { mock }
|
|
14
15
|
let(:s) { sequence '' }
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
17
|
+
context 'when pipeline command is successful' do
|
|
18
|
+
it 'should setup variables and perform packaging procedures' do
|
|
19
|
+
model.expects(:package).in_sequence(s).returns(package)
|
|
20
|
+
model.expects(:encryptor).in_sequence(s).returns(encryptor)
|
|
21
|
+
model.expects(:splitter).in_sequence(s).returns(splitter)
|
|
22
|
+
Backup::Pipeline.expects(:new).in_sequence(s).returns(pipeline)
|
|
23
|
+
|
|
24
|
+
Backup::Logger.expects(:message).in_sequence(s).with(
|
|
25
|
+
'Packaging the backup files...'
|
|
26
|
+
)
|
|
27
|
+
packager.expects(:procedure).in_sequence(s).returns(procedure)
|
|
28
|
+
procedure.expects(:call).in_sequence(s)
|
|
29
|
+
|
|
30
|
+
pipeline.expects(:success?).in_sequence(s).returns(true)
|
|
31
|
+
Backup::Logger.expects(:message).in_sequence(s).with(
|
|
32
|
+
'Packaging Complete!'
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
packager.package!(model)
|
|
36
|
+
|
|
37
|
+
packager.instance_variable_get(:@package).should be(package)
|
|
38
|
+
packager.instance_variable_get(:@encryptor).should be(encryptor)
|
|
39
|
+
packager.instance_variable_get(:@splitter).should be(splitter)
|
|
40
|
+
packager.instance_variable_get(:@pipeline).should be(pipeline)
|
|
41
|
+
end
|
|
42
|
+
end #context 'when pipeline command is successful'
|
|
43
|
+
|
|
44
|
+
context 'when pipeline command is not successful' do
|
|
45
|
+
it 'should raise an error' do
|
|
46
|
+
model.expects(:package).in_sequence(s).returns(package)
|
|
47
|
+
model.expects(:encryptor).in_sequence(s).returns(encryptor)
|
|
48
|
+
model.expects(:splitter).in_sequence(s).returns(splitter)
|
|
49
|
+
Backup::Pipeline.expects(:new).in_sequence(s).returns(pipeline)
|
|
50
|
+
|
|
51
|
+
Backup::Logger.expects(:message).in_sequence(s).with(
|
|
52
|
+
'Packaging the backup files...'
|
|
53
|
+
)
|
|
54
|
+
packager.expects(:procedure).in_sequence(s).returns(procedure)
|
|
55
|
+
procedure.expects(:call).in_sequence(s)
|
|
56
|
+
|
|
57
|
+
pipeline.expects(:success?).in_sequence(s).returns(false)
|
|
58
|
+
pipeline.expects(:error_messages).in_sequence(s).returns('pipeline_errors')
|
|
59
|
+
|
|
60
|
+
expect do
|
|
61
|
+
packager.package!(model)
|
|
62
|
+
end.to raise_error(
|
|
63
|
+
Backup::Errors::Packager::PipelineError,
|
|
64
|
+
"Packager::PipelineError: Failed to Create Backup Package\n" +
|
|
65
|
+
" pipeline_errors"
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
packager.instance_variable_get(:@package).should be(package)
|
|
69
|
+
packager.instance_variable_get(:@encryptor).should be(encryptor)
|
|
70
|
+
packager.instance_variable_get(:@splitter).should be(splitter)
|
|
71
|
+
packager.instance_variable_get(:@pipeline).should be(pipeline)
|
|
72
|
+
end
|
|
73
|
+
end #context 'when pipeline command is successful'
|
|
36
74
|
end # describe '#package!'
|
|
37
75
|
|
|
38
76
|
describe '#procedure' do
|
|
@@ -66,11 +104,14 @@ describe 'Backup::Packager' do
|
|
|
66
104
|
let(:package) { Fake::Package.new }
|
|
67
105
|
let(:encryptor) { Fake::Encryptor.new }
|
|
68
106
|
let(:splitter) { Fake::Splitter.new }
|
|
107
|
+
let(:pipeline) { mock }
|
|
108
|
+
let(:s) { sequence '' }
|
|
69
109
|
|
|
70
110
|
before do
|
|
71
111
|
Fake.stack_trace.clear
|
|
72
112
|
packager.expects(:utility).with(:tar).returns('tar')
|
|
73
113
|
packager.instance_variable_set(:@package, package)
|
|
114
|
+
packager.instance_variable_set(:@pipeline, pipeline)
|
|
74
115
|
package.trigger = 'model_trigger'
|
|
75
116
|
package.extension = 'tar'
|
|
76
117
|
end
|
|
@@ -80,10 +121,14 @@ describe 'Backup::Packager' do
|
|
|
80
121
|
packager.instance_variable_set(:@encryptor, nil)
|
|
81
122
|
packager.instance_variable_set(:@splitter, nil)
|
|
82
123
|
|
|
83
|
-
|
|
84
|
-
"tar -cf - -C '#{ Backup::Config.tmp_path }' 'model_trigger'"
|
|
85
|
-
" > #{ File.join(Backup::Config.tmp_path, 'base_filename.tar') }"
|
|
124
|
+
pipeline.expects(:<<).in_sequence(s).with(
|
|
125
|
+
"tar -cf - -C '#{ Backup::Config.tmp_path }' 'model_trigger'"
|
|
86
126
|
)
|
|
127
|
+
pipeline.expects(:<<).in_sequence(s).with(
|
|
128
|
+
"cat > #{ File.join(Backup::Config.tmp_path, 'base_filename.tar') }"
|
|
129
|
+
)
|
|
130
|
+
pipeline.expects(:run).in_sequence(s)
|
|
131
|
+
|
|
87
132
|
packager.send(:procedure).call
|
|
88
133
|
end
|
|
89
134
|
end
|
|
@@ -93,13 +138,18 @@ describe 'Backup::Packager' do
|
|
|
93
138
|
packager.instance_variable_set(:@encryptor, encryptor)
|
|
94
139
|
packager.instance_variable_set(:@splitter, nil)
|
|
95
140
|
|
|
96
|
-
|
|
141
|
+
pipeline.expects(:<<).in_sequence(s).with(
|
|
142
|
+
"tar -cf - -C '#{ Backup::Config.tmp_path }' 'model_trigger'"
|
|
143
|
+
)
|
|
144
|
+
pipeline.expects(:<<).in_sequence(s).with('encryption_command')
|
|
145
|
+
pipeline.expects(:<<).in_sequence(s).with(
|
|
146
|
+
"cat > #{ File.join(Backup::Config.tmp_path, 'base_filename.tar.enc') }"
|
|
147
|
+
)
|
|
148
|
+
pipeline.expects(:run).in_sequence(s).with do
|
|
97
149
|
Fake.stack_trace << :command_executed
|
|
98
|
-
|
|
99
|
-
"tar -cf - -C '#{ Backup::Config.tmp_path }' 'model_trigger'" +
|
|
100
|
-
" | encryption_command" +
|
|
101
|
-
" > #{ File.join(Backup::Config.tmp_path, 'base_filename.tar.enc') }"
|
|
150
|
+
true
|
|
102
151
|
end
|
|
152
|
+
|
|
103
153
|
packager.send(:procedure).call
|
|
104
154
|
|
|
105
155
|
Fake.stack_trace.should == [
|
|
@@ -113,12 +163,16 @@ describe 'Backup::Packager' do
|
|
|
113
163
|
packager.instance_variable_set(:@encryptor, nil)
|
|
114
164
|
packager.instance_variable_set(:@splitter, splitter)
|
|
115
165
|
|
|
116
|
-
|
|
166
|
+
pipeline.expects(:<<).in_sequence(s).with(
|
|
167
|
+
"tar -cf - -C '#{ Backup::Config.tmp_path }' 'model_trigger'"
|
|
168
|
+
)
|
|
169
|
+
pipeline.expects(:<<).in_sequence(s).with('splitter_command')
|
|
170
|
+
|
|
171
|
+
pipeline.expects(:run).in_sequence(s).with do
|
|
117
172
|
Fake.stack_trace << :command_executed
|
|
118
|
-
|
|
119
|
-
"tar -cf - -C '#{ Backup::Config.tmp_path }' 'model_trigger'" +
|
|
120
|
-
" | splitter_command"
|
|
173
|
+
true
|
|
121
174
|
end
|
|
175
|
+
|
|
122
176
|
packager.send(:procedure).call
|
|
123
177
|
|
|
124
178
|
Fake.stack_trace.should == [
|
|
@@ -132,12 +186,17 @@ describe 'Backup::Packager' do
|
|
|
132
186
|
packager.instance_variable_set(:@encryptor, encryptor)
|
|
133
187
|
packager.instance_variable_set(:@splitter, splitter)
|
|
134
188
|
|
|
135
|
-
|
|
189
|
+
pipeline.expects(:<<).in_sequence(s).with(
|
|
190
|
+
"tar -cf - -C '#{ Backup::Config.tmp_path }' 'model_trigger'"
|
|
191
|
+
)
|
|
192
|
+
pipeline.expects(:<<).in_sequence(s).with('encryption_command')
|
|
193
|
+
pipeline.expects(:<<).in_sequence(s).with('splitter_command')
|
|
194
|
+
|
|
195
|
+
pipeline.expects(:run).in_sequence(s).with do
|
|
136
196
|
Fake.stack_trace << :command_executed
|
|
137
|
-
|
|
138
|
-
"tar -cf - -C '#{ Backup::Config.tmp_path }' 'model_trigger'" +
|
|
139
|
-
" | encryption_command | splitter_command"
|
|
197
|
+
true
|
|
140
198
|
end
|
|
199
|
+
|
|
141
200
|
packager.send(:procedure).call
|
|
142
201
|
|
|
143
202
|
Fake.stack_trace.should == [
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require File.expand_path('../spec_helper.rb', __FILE__)
|
|
4
|
+
|
|
5
|
+
describe 'Backup::Pipeline' do
|
|
6
|
+
let(:pipeline) { Backup::Pipeline.new }
|
|
7
|
+
|
|
8
|
+
describe '#initialize' do
|
|
9
|
+
it 'should create a new pipeline' do
|
|
10
|
+
pipeline.instance_variable_get(:@commands).should == []
|
|
11
|
+
pipeline.errors.should == []
|
|
12
|
+
pipeline.stderr.should == ''
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe '#<<' do
|
|
17
|
+
it 'should add a command string to @commands' do
|
|
18
|
+
pipeline << 'a command string'
|
|
19
|
+
pipeline.instance_variable_get(:@commands).should == ['a command string']
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe '#run' do
|
|
24
|
+
let(:stdout) { mock }
|
|
25
|
+
let(:stderr) { mock }
|
|
26
|
+
|
|
27
|
+
before do
|
|
28
|
+
pipeline.expects(:pipeline).returns('foo')
|
|
29
|
+
# stub CLI::Helpers#command_name so it simply returns what it's passed
|
|
30
|
+
pipeline.class.send(:define_method, :command_name, lambda {|arg| arg } )
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
context 'when pipeline command is successfully executed' do
|
|
34
|
+
before do
|
|
35
|
+
Open4.expects(:popen4).with('foo').yields(nil, nil, stdout, stderr)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
context 'when all commands within the pipeline are successful' do
|
|
39
|
+
before do
|
|
40
|
+
stdout.expects(:read).returns("0|0:1|0:\n")
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
context 'when commands output no stderr messages' do
|
|
44
|
+
before do
|
|
45
|
+
stderr.expects(:read).returns('')
|
|
46
|
+
pipeline.stubs(:stderr_messages).returns(false)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it 'should process the returned stdout/stderr and report no errors' do
|
|
50
|
+
Backup::Logger.expects(:warn).never
|
|
51
|
+
|
|
52
|
+
pipeline.run
|
|
53
|
+
pipeline.stderr.should == ''
|
|
54
|
+
pipeline.errors.should == []
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
context 'when successful commands output messages on stderr' do
|
|
59
|
+
before do
|
|
60
|
+
stderr.expects(:read).returns("stderr output\n")
|
|
61
|
+
pipeline.stubs(:stderr_messages).returns('stderr_messages_output')
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it 'should log a warning with the stderr messages' do
|
|
65
|
+
Backup::Logger.expects(:warn).with('stderr_messages_output')
|
|
66
|
+
|
|
67
|
+
pipeline.run
|
|
68
|
+
pipeline.stderr.should == 'stderr output'
|
|
69
|
+
pipeline.errors.should == []
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end # context 'when all commands within the pipeline are successful'
|
|
73
|
+
|
|
74
|
+
context 'when commands within the pipeline are not successful' do
|
|
75
|
+
before do
|
|
76
|
+
pipeline.instance_variable_set(:@commands, ['first', 'second', 'third'])
|
|
77
|
+
stderr.expects(:read).returns("stderr output\n")
|
|
78
|
+
pipeline.stubs(:stderr_messages).returns('success? should be false')
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
context 'when the commands return in sequence' do
|
|
82
|
+
before do
|
|
83
|
+
stdout.expects(:read).returns("0|0:1|1:2|0:\n")
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it 'should set @errors and @stderr without logging warnings' do
|
|
87
|
+
Backup::Logger.expects(:warn).never
|
|
88
|
+
|
|
89
|
+
pipeline.run
|
|
90
|
+
pipeline.stderr.should == 'stderr output'
|
|
91
|
+
pipeline.errors.count.should be(1)
|
|
92
|
+
pipeline.errors.first.should be_a_kind_of SystemCallError
|
|
93
|
+
pipeline.errors.first.errno.should be(1)
|
|
94
|
+
pipeline.errors.first.message.should match(
|
|
95
|
+
"'second' returned exit code: 1"
|
|
96
|
+
)
|
|
97
|
+
end
|
|
98
|
+
end # context 'when the commands return in sequence'
|
|
99
|
+
|
|
100
|
+
context 'when the commands return out of sequence' do
|
|
101
|
+
before do
|
|
102
|
+
stdout.expects(:read).returns("1|1:2|0:0|0:\n")
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it 'should properly associate the exitstatus for each command' do
|
|
106
|
+
Backup::Logger.expects(:warn).never
|
|
107
|
+
|
|
108
|
+
pipeline.run
|
|
109
|
+
pipeline.stderr.should == 'stderr output'
|
|
110
|
+
pipeline.errors.count.should be(1)
|
|
111
|
+
pipeline.errors.first.should be_a_kind_of SystemCallError
|
|
112
|
+
pipeline.errors.first.errno.should be(1)
|
|
113
|
+
pipeline.errors.first.message.should match(
|
|
114
|
+
"'second' returned exit code: 1"
|
|
115
|
+
)
|
|
116
|
+
end
|
|
117
|
+
end # context 'when the commands return out of sequence'
|
|
118
|
+
|
|
119
|
+
context 'when multiple commands fail (out of sequence)' do
|
|
120
|
+
before do
|
|
121
|
+
stdout.expects(:read).returns("1|1:2|0:0|3:\n")
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it 'should properly associate the exitstatus for each command' do
|
|
125
|
+
Backup::Logger.expects(:warn).never
|
|
126
|
+
|
|
127
|
+
pipeline.run
|
|
128
|
+
pipeline.stderr.should == 'stderr output'
|
|
129
|
+
pipeline.errors.count.should be(2)
|
|
130
|
+
pipeline.errors.each {|err| err.should be_a_kind_of SystemCallError }
|
|
131
|
+
pipeline.errors[0].errno.should be(3)
|
|
132
|
+
pipeline.errors[0].message.should match(
|
|
133
|
+
"'first' returned exit code: 3"
|
|
134
|
+
)
|
|
135
|
+
pipeline.errors[1].errno.should be(1)
|
|
136
|
+
pipeline.errors[1].message.should match(
|
|
137
|
+
"'second' returned exit code: 1"
|
|
138
|
+
)
|
|
139
|
+
end
|
|
140
|
+
end # context 'when the commands return (out of sequence)'
|
|
141
|
+
|
|
142
|
+
end # context 'when commands within the pipeline are not successful'
|
|
143
|
+
end # context 'when pipeline command is successfully executed'
|
|
144
|
+
|
|
145
|
+
context 'when pipeline command fails to execute' do
|
|
146
|
+
before do
|
|
147
|
+
Open4.expects(:popen4).with('foo').raises('exec failed')
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
it 'should raise an error' do
|
|
151
|
+
expect do
|
|
152
|
+
pipeline.run
|
|
153
|
+
end.to raise_error(
|
|
154
|
+
Backup::Errors::Pipeline::ExecutionError,
|
|
155
|
+
"Pipeline::ExecutionError: RuntimeError: exec failed"
|
|
156
|
+
)
|
|
157
|
+
end
|
|
158
|
+
end # context 'when pipeline command fails to execute'
|
|
159
|
+
|
|
160
|
+
end # describe '#run'
|
|
161
|
+
|
|
162
|
+
describe '#success?' do
|
|
163
|
+
it 'returns true when @errors is empty' do
|
|
164
|
+
pipeline.success?.should be_true
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
it 'returns false when @errors is not empty' do
|
|
168
|
+
pipeline.instance_variable_set(:@errors, ['foo'])
|
|
169
|
+
pipeline.success?.should be_false
|
|
170
|
+
end
|
|
171
|
+
end # describe '#success?'
|
|
172
|
+
|
|
173
|
+
describe '#error_messages' do
|
|
174
|
+
before do
|
|
175
|
+
pipeline.instance_variable_set(
|
|
176
|
+
:@errors, [
|
|
177
|
+
StandardError.new('standard error'),
|
|
178
|
+
RuntimeError.new('runtime error')
|
|
179
|
+
]
|
|
180
|
+
)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
context 'when #stderr_messages has messages' do
|
|
184
|
+
before do
|
|
185
|
+
pipeline.expects(:stderr_messages).returns('stderr messages')
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
it 'should output #stderr_messages and formatted system error messages' do
|
|
189
|
+
pipeline.error_messages.should == 'stderr messages' +
|
|
190
|
+
"The following system errors were returned:\n" +
|
|
191
|
+
"Error: StandardError: standard error\n" +
|
|
192
|
+
"Error: RuntimeError: runtime error"
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
context 'when #stderr_messages has no messages' do
|
|
197
|
+
before do
|
|
198
|
+
pipeline.expects(:stderr_messages).returns(false)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
it 'should only output the formatted system error messages' do
|
|
202
|
+
pipeline.error_messages.should ==
|
|
203
|
+
"The following system errors were returned:\n" +
|
|
204
|
+
"Error: StandardError: standard error\n" +
|
|
205
|
+
"Error: RuntimeError: runtime error"
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
end # describe '#error_messages'
|
|
209
|
+
|
|
210
|
+
describe '#pipeline' do
|
|
211
|
+
context 'when there are multiple system commands to execute' do
|
|
212
|
+
before do
|
|
213
|
+
pipeline.instance_variable_set(:@commands, %w{ one two three })
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
it 'should build a pipeline with redirected/collected exit codes' do
|
|
217
|
+
pipeline.send(:pipeline).should ==
|
|
218
|
+
'{ { one 2>&4 ; echo "0|$?:" >&3 ; } | ' +
|
|
219
|
+
'{ two 2>&4 ; echo "1|$?:" >&3 ; } | ' +
|
|
220
|
+
'{ three 2>&4 ; echo "2|$?:" >&3 ; } } 3>&1 1>&2 4>&2'
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
context 'when there is only one system command to execute' do
|
|
225
|
+
before do
|
|
226
|
+
pipeline.instance_variable_set(:@commands, ['foo'])
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
it 'should build the command line in the same manner, but without pipes' do
|
|
230
|
+
pipeline.send(:pipeline).should ==
|
|
231
|
+
'{ { foo 2>&4 ; echo "0|$?:" >&3 ; } } 3>&1 1>&2 4>&2'
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end # describe '#pipeline'
|
|
235
|
+
|
|
236
|
+
describe '#stderr_message' do
|
|
237
|
+
context 'when @stderr has messages' do
|
|
238
|
+
before do
|
|
239
|
+
pipeline.instance_variable_set(:@stderr, "stderr message\n output")
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
it 'should return a formatted message with the @stderr messages' do
|
|
243
|
+
pipeline.send(:stderr_messages).should ==
|
|
244
|
+
" Pipeline STDERR Messages:\n" +
|
|
245
|
+
" (Note: may be interleaved if multiple commands returned error messages)\n" +
|
|
246
|
+
"\n" +
|
|
247
|
+
" stderr message\n" +
|
|
248
|
+
" output\n"
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
context 'when @stderr is empty' do
|
|
253
|
+
it 'should return false' do
|
|
254
|
+
pipeline.send(:stderr_messages).should be_false
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
end # describe '#stderr_message'
|
|
258
|
+
|
|
259
|
+
end #describe 'Backup::Pipeline'
|
data/spec/spec_helper.rb
CHANGED
|
@@ -44,16 +44,17 @@ RSpec.configure do |config|
|
|
|
44
44
|
# Actions to perform before each example
|
|
45
45
|
config.before(:each) do
|
|
46
46
|
FileUtils.collect_method(:noop).each do |method|
|
|
47
|
-
FileUtils.stubs(method).raises("Unexpected call to FileUtils.#{method}")
|
|
47
|
+
FileUtils.stubs(method).raises("Unexpected call to FileUtils.#{ method }")
|
|
48
48
|
end
|
|
49
|
-
Open4.stubs(:popen4).raises('Unexpected call to CLI::Helpers.run()')
|
|
50
49
|
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
Open4.stubs(:popen4).raises('Unexpected call to Open4::popen4()')
|
|
51
|
+
|
|
52
|
+
[:message, :error, :warn, :normal, :silent].each do |method|
|
|
53
|
+
Backup::Logger.stubs(method).raises("Unexpected call to Backup::Logger.#{ method }")
|
|
53
54
|
end
|
|
54
55
|
end
|
|
55
56
|
end
|
|
56
57
|
|
|
57
58
|
unless @_put_ruby_version
|
|
58
|
-
puts @_put_ruby_version = "\n\nRuby version: #{RUBY_DESCRIPTION}\n\n"
|
|
59
|
+
puts @_put_ruby_version = "\n\nRuby version: #{ RUBY_DESCRIPTION }\n\n"
|
|
59
60
|
end
|