backup 3.0.27 → 3.1.0
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/LICENSE.md +1 -1
- data/README.md +139 -386
- data/bin/backup +1 -7
- data/lib/backup.rb +3 -9
- data/lib/backup/archive.rb +26 -20
- data/lib/backup/cleaner.rb +2 -2
- data/lib/backup/cli.rb +366 -0
- data/lib/backup/compressor/base.rb +2 -2
- data/lib/backup/compressor/gzip.rb +35 -1
- data/lib/backup/config.rb +1 -2
- data/lib/backup/database/base.rb +2 -2
- data/lib/backup/database/mongodb.rb +3 -3
- data/lib/backup/database/mysql.rb +3 -2
- data/lib/backup/database/postgresql.rb +3 -2
- data/lib/backup/database/riak.rb +18 -5
- data/lib/backup/dependency.rb +144 -93
- data/lib/backup/encryptor/base.rb +2 -2
- data/lib/backup/logger.rb +108 -110
- data/lib/backup/logger/console.rb +51 -0
- data/lib/backup/logger/logfile.rb +113 -0
- data/lib/backup/logger/syslog.rb +116 -0
- data/lib/backup/model.rb +67 -65
- data/lib/backup/notifier/base.rb +1 -1
- data/lib/backup/notifier/hipchat.rb +1 -1
- data/lib/backup/notifier/mail.rb +1 -1
- data/lib/backup/notifier/pushover.rb +6 -3
- data/lib/backup/packager.rb +4 -4
- data/lib/backup/pipeline.rb +17 -3
- data/lib/backup/splitter.rb +2 -2
- data/lib/backup/storage/base.rb +2 -2
- data/lib/backup/storage/cloudfiles.rb +2 -2
- data/lib/backup/storage/dropbox.rb +4 -4
- data/lib/backup/storage/ftp.rb +2 -2
- data/lib/backup/storage/local.rb +2 -2
- data/lib/backup/storage/ninefold.rb +2 -2
- data/lib/backup/storage/rsync.rb +3 -3
- data/lib/backup/storage/s3.rb +2 -2
- data/lib/backup/storage/scp.rb +2 -6
- data/lib/backup/storage/sftp.rb +2 -5
- data/lib/backup/syncer/base.rb +1 -1
- data/lib/backup/syncer/cloud/base.rb +15 -8
- data/lib/backup/syncer/rsync/local.rb +1 -1
- data/lib/backup/syncer/rsync/pull.rb +1 -1
- data/lib/backup/syncer/rsync/push.rb +1 -1
- data/lib/backup/utilities.rb +211 -0
- data/lib/backup/version.rb +1 -1
- data/templates/cli/{utility/archive → archive} +4 -8
- data/templates/cli/{utility/compressor → compressor}/bzip2 +0 -0
- data/templates/cli/{utility/compressor → compressor}/custom +0 -0
- data/templates/cli/{utility/compressor → compressor}/gzip +0 -0
- data/templates/cli/{utility/compressor → compressor}/lzma +0 -0
- data/templates/cli/{utility/compressor → compressor}/pbzip2 +0 -0
- data/templates/cli/config +68 -0
- data/templates/cli/{utility/database → database}/mongodb +1 -1
- data/templates/cli/{utility/database → database}/mysql +1 -1
- data/templates/cli/{utility/database → database}/postgresql +1 -1
- data/templates/cli/{utility/database → database}/redis +0 -0
- data/templates/cli/database/riak +20 -0
- data/templates/cli/{utility/encryptor → encryptor}/gpg +0 -0
- data/templates/cli/{utility/encryptor → encryptor}/openssl +0 -0
- data/templates/cli/{utility/model.erb → model.erb} +4 -4
- data/templates/cli/{utility/notifier → notifier}/campfire +0 -0
- data/templates/cli/{utility/notifier → notifier}/hipchat +0 -0
- data/templates/cli/{utility/notifier → notifier}/mail +0 -0
- data/templates/cli/{utility/notifier → notifier}/prowl +0 -0
- data/templates/cli/{utility/notifier → notifier}/pushover +0 -0
- data/templates/cli/{utility/notifier → notifier}/twitter +0 -0
- data/templates/cli/{utility/splitter → splitter} +0 -0
- data/templates/cli/{utility/storage → storage}/cloud_files +0 -0
- data/templates/cli/{utility/storage → storage}/dropbox +0 -0
- data/templates/cli/{utility/storage → storage}/ftp +0 -0
- data/templates/cli/{utility/storage → storage}/local +0 -0
- data/templates/cli/{utility/storage → storage}/ninefold +0 -0
- data/templates/cli/{utility/storage → storage}/rsync +0 -0
- data/templates/cli/{utility/storage → storage}/s3 +0 -0
- data/templates/cli/{utility/storage → storage}/scp +0 -0
- data/templates/cli/{utility/storage → storage}/sftp +0 -0
- data/templates/cli/{utility/syncer → syncer}/cloud_files +0 -0
- data/templates/cli/{utility/syncer → syncer}/rsync_local +0 -0
- data/templates/cli/{utility/syncer → syncer}/rsync_pull +0 -0
- data/templates/cli/{utility/syncer → syncer}/rsync_push +0 -0
- data/templates/cli/{utility/syncer → syncer}/s3 +0 -0
- metadata +55 -131
- data/.gitignore +0 -8
- data/.travis.yml +0 -10
- data/Gemfile +0 -28
- data/Guardfile +0 -23
- data/backup.gemspec +0 -32
- data/lib/backup/cli/helpers.rb +0 -93
- data/lib/backup/cli/utility.rb +0 -255
- data/spec-live/.gitignore +0 -6
- data/spec-live/README +0 -7
- data/spec-live/backups/config.rb +0 -83
- data/spec-live/backups/config.yml.template +0 -46
- data/spec-live/backups/models.rb +0 -184
- data/spec-live/compressor/custom_spec.rb +0 -30
- data/spec-live/compressor/gzip_spec.rb +0 -30
- data/spec-live/encryptor/gpg_keys.rb +0 -239
- data/spec-live/encryptor/gpg_spec.rb +0 -287
- data/spec-live/notifier/mail_spec.rb +0 -121
- data/spec-live/spec_helper.rb +0 -151
- data/spec-live/storage/dropbox_spec.rb +0 -151
- data/spec-live/storage/local_spec.rb +0 -83
- data/spec-live/storage/scp_spec.rb +0 -193
- data/spec-live/syncer/cloud/s3_spec.rb +0 -124
- data/spec/archive_spec.rb +0 -335
- data/spec/cleaner_spec.rb +0 -312
- data/spec/cli/helpers_spec.rb +0 -301
- data/spec/cli/utility_spec.rb +0 -411
- data/spec/compressor/base_spec.rb +0 -52
- data/spec/compressor/bzip2_spec.rb +0 -217
- data/spec/compressor/custom_spec.rb +0 -106
- data/spec/compressor/gzip_spec.rb +0 -217
- data/spec/compressor/lzma_spec.rb +0 -123
- data/spec/compressor/pbzip2_spec.rb +0 -165
- data/spec/config_spec.rb +0 -321
- data/spec/configuration/helpers_spec.rb +0 -247
- data/spec/configuration/store_spec.rb +0 -39
- data/spec/configuration_spec.rb +0 -62
- data/spec/database/base_spec.rb +0 -63
- data/spec/database/mongodb_spec.rb +0 -510
- data/spec/database/mysql_spec.rb +0 -411
- data/spec/database/postgresql_spec.rb +0 -353
- data/spec/database/redis_spec.rb +0 -334
- data/spec/database/riak_spec.rb +0 -176
- data/spec/dependency_spec.rb +0 -51
- data/spec/encryptor/base_spec.rb +0 -40
- data/spec/encryptor/gpg_spec.rb +0 -909
- data/spec/encryptor/open_ssl_spec.rb +0 -148
- data/spec/errors_spec.rb +0 -306
- data/spec/logger_spec.rb +0 -367
- data/spec/model_spec.rb +0 -666
- data/spec/notifier/base_spec.rb +0 -104
- data/spec/notifier/campfire_spec.rb +0 -217
- data/spec/notifier/hipchat_spec.rb +0 -211
- data/spec/notifier/mail_spec.rb +0 -316
- data/spec/notifier/prowl_spec.rb +0 -138
- data/spec/notifier/pushover_spec.rb +0 -123
- data/spec/notifier/twitter_spec.rb +0 -153
- data/spec/package_spec.rb +0 -61
- data/spec/packager_spec.rb +0 -213
- data/spec/pipeline_spec.rb +0 -259
- data/spec/spec_helper.rb +0 -60
- data/spec/splitter_spec.rb +0 -120
- data/spec/storage/base_spec.rb +0 -166
- data/spec/storage/cloudfiles_spec.rb +0 -254
- data/spec/storage/cycler_spec.rb +0 -247
- data/spec/storage/dropbox_spec.rb +0 -480
- data/spec/storage/ftp_spec.rb +0 -271
- data/spec/storage/local_spec.rb +0 -259
- data/spec/storage/ninefold_spec.rb +0 -343
- data/spec/storage/rsync_spec.rb +0 -362
- data/spec/storage/s3_spec.rb +0 -245
- data/spec/storage/scp_spec.rb +0 -233
- data/spec/storage/sftp_spec.rb +0 -244
- data/spec/syncer/base_spec.rb +0 -109
- data/spec/syncer/cloud/base_spec.rb +0 -515
- data/spec/syncer/cloud/cloud_files_spec.rb +0 -181
- data/spec/syncer/cloud/s3_spec.rb +0 -174
- data/spec/syncer/rsync/base_spec.rb +0 -98
- data/spec/syncer/rsync/local_spec.rb +0 -149
- data/spec/syncer/rsync/pull_spec.rb +0 -98
- data/spec/syncer/rsync/push_spec.rb +0 -333
- data/spec/version_spec.rb +0 -21
- data/templates/cli/utility/config +0 -32
- data/templates/cli/utility/database/riak +0 -11
data/spec/cli/helpers_spec.rb
DELETED
|
@@ -1,301 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
require File.expand_path('../../spec_helper.rb', __FILE__)
|
|
4
|
-
|
|
5
|
-
describe Backup::CLI::Helpers do
|
|
6
|
-
let(:helpers) { Module.new.extend(Backup::CLI::Helpers) }
|
|
7
|
-
|
|
8
|
-
describe '#run' do
|
|
9
|
-
let(:stdout_io) { stub(:read => stdout_messages) }
|
|
10
|
-
let(:stderr_io) { stub(:read => stderr_messages) }
|
|
11
|
-
let(:stdin_io) { stub(:close) }
|
|
12
|
-
let(:process_status) { stub(:success? => process_success) }
|
|
13
|
-
let(:command) { '/path/to/cmd_name arg1 arg2' }
|
|
14
|
-
|
|
15
|
-
context 'when the command is successful' do
|
|
16
|
-
let(:process_success) { true }
|
|
17
|
-
|
|
18
|
-
before do
|
|
19
|
-
Backup::Logger.expects(:message).with(
|
|
20
|
-
"Running system utility 'cmd_name'..."
|
|
21
|
-
)
|
|
22
|
-
|
|
23
|
-
Open4.expects(:popen4).with(command).yields(
|
|
24
|
-
nil, stdin_io, stdout_io, stderr_io
|
|
25
|
-
).returns(process_status)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
context 'and generates no messages' do
|
|
29
|
-
let(:stdout_messages) { '' }
|
|
30
|
-
let(:stderr_messages) { '' }
|
|
31
|
-
|
|
32
|
-
it 'should return stdout and generate no additional log messages' do
|
|
33
|
-
helpers.send(:run, command).should == ''
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
context 'and generates only stdout messages' do
|
|
38
|
-
let(:stdout_messages) { "out line1\nout line2\n" }
|
|
39
|
-
let(:stderr_messages) { '' }
|
|
40
|
-
|
|
41
|
-
it 'should return stdout and log the stdout messages' do
|
|
42
|
-
Backup::Logger.expects(:message).with(
|
|
43
|
-
"cmd_name:STDOUT: out line1\ncmd_name:STDOUT: out line2"
|
|
44
|
-
)
|
|
45
|
-
helpers.send(:run, command).should == stdout_messages.strip
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
context 'and generates only stderr messages' do
|
|
50
|
-
let(:stdout_messages) { '' }
|
|
51
|
-
let(:stderr_messages) { "err line1\nerr line2\n" }
|
|
52
|
-
|
|
53
|
-
it 'should return stdout and log the stderr messages' do
|
|
54
|
-
Backup::Logger.expects(:warn).with(
|
|
55
|
-
"cmd_name:STDERR: err line1\ncmd_name:STDERR: err line2"
|
|
56
|
-
)
|
|
57
|
-
helpers.send(:run, command).should == ''
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
context 'and generates messages on both stdout and stderr' do
|
|
62
|
-
let(:stdout_messages) { "out line1\nout line2\n" }
|
|
63
|
-
let(:stderr_messages) { "err line1\nerr line2\n" }
|
|
64
|
-
|
|
65
|
-
it 'should return stdout and log both stdout and stderr messages' do
|
|
66
|
-
Backup::Logger.expects(:message).with(
|
|
67
|
-
"cmd_name:STDOUT: out line1\ncmd_name:STDOUT: out line2"
|
|
68
|
-
)
|
|
69
|
-
Backup::Logger.expects(:warn).with(
|
|
70
|
-
"cmd_name:STDERR: err line1\ncmd_name:STDERR: err line2"
|
|
71
|
-
)
|
|
72
|
-
helpers.send(:run, command).should == stdout_messages.strip
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
end # context 'when the command is successful'
|
|
76
|
-
|
|
77
|
-
context 'when the command is not successful' do
|
|
78
|
-
let(:process_success) { false }
|
|
79
|
-
let(:message_head) do
|
|
80
|
-
"CLI::SystemCallError: 'cmd_name' Failed on #{ RUBY_PLATFORM }\n" +
|
|
81
|
-
" The following information should help to determine the problem:\n" +
|
|
82
|
-
" Command was: /path/to/cmd_name arg1 arg2\n" +
|
|
83
|
-
" Exit Status: 1\n"
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
before do
|
|
87
|
-
Backup::Logger.expects(:message).with(
|
|
88
|
-
"Running system utility 'cmd_name'..."
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
Open4.expects(:popen4).with(command).yields(
|
|
92
|
-
nil, stdin_io, stdout_io, stderr_io
|
|
93
|
-
).returns(process_status)
|
|
94
|
-
|
|
95
|
-
process_status.stubs(:exitstatus).returns(1)
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
context 'and generates no messages' do
|
|
99
|
-
let(:stdout_messages) { '' }
|
|
100
|
-
let(:stderr_messages) { '' }
|
|
101
|
-
|
|
102
|
-
it 'should raise an error reporting no messages' do
|
|
103
|
-
expect do
|
|
104
|
-
helpers.send(:run, command)
|
|
105
|
-
end.to raise_error {|err|
|
|
106
|
-
err.message.should == message_head +
|
|
107
|
-
" STDOUT Messages: None\n" +
|
|
108
|
-
" STDERR Messages: None"
|
|
109
|
-
}
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
context 'and generates only stdout messages' do
|
|
114
|
-
let(:stdout_messages) { "out line1\nout line2\n" }
|
|
115
|
-
let(:stderr_messages) { '' }
|
|
116
|
-
|
|
117
|
-
it 'should raise an error and report the stdout messages' do
|
|
118
|
-
expect do
|
|
119
|
-
helpers.send(:run, command)
|
|
120
|
-
end.to raise_error {|err|
|
|
121
|
-
err.message.should == message_head +
|
|
122
|
-
" STDOUT Messages: \n" +
|
|
123
|
-
" out line1\n" +
|
|
124
|
-
" out line2\n" +
|
|
125
|
-
" STDERR Messages: None"
|
|
126
|
-
}
|
|
127
|
-
end
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
context 'and generates only stderr messages' do
|
|
131
|
-
let(:stdout_messages) { '' }
|
|
132
|
-
let(:stderr_messages) { "err line1\nerr line2\n" }
|
|
133
|
-
|
|
134
|
-
it 'should raise an error and report the stderr messages' do
|
|
135
|
-
expect do
|
|
136
|
-
helpers.send(:run, command)
|
|
137
|
-
end.to raise_error {|err|
|
|
138
|
-
err.message.should == message_head +
|
|
139
|
-
" STDOUT Messages: None\n" +
|
|
140
|
-
" STDERR Messages: \n" +
|
|
141
|
-
" err line1\n" +
|
|
142
|
-
" err line2"
|
|
143
|
-
}
|
|
144
|
-
end
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
context 'and generates messages on both stdout and stderr' do
|
|
148
|
-
let(:stdout_messages) { "out line1\nout line2\n" }
|
|
149
|
-
let(:stderr_messages) { "err line1\nerr line2\n" }
|
|
150
|
-
|
|
151
|
-
it 'should raise an error and report the stdout and stderr messages' do
|
|
152
|
-
expect do
|
|
153
|
-
helpers.send(:run, command)
|
|
154
|
-
end.to raise_error {|err|
|
|
155
|
-
err.message.should == message_head +
|
|
156
|
-
" STDOUT Messages: \n" +
|
|
157
|
-
" out line1\n" +
|
|
158
|
-
" out line2\n" +
|
|
159
|
-
" STDERR Messages: \n" +
|
|
160
|
-
" err line1\n" +
|
|
161
|
-
" err line2"
|
|
162
|
-
}
|
|
163
|
-
end
|
|
164
|
-
end
|
|
165
|
-
end # context 'when the command is not successful'
|
|
166
|
-
|
|
167
|
-
context 'when the system fails to execute the command' do
|
|
168
|
-
before do
|
|
169
|
-
Backup::Logger.expects(:message).with(
|
|
170
|
-
"Running system utility 'cmd_name'..."
|
|
171
|
-
)
|
|
172
|
-
|
|
173
|
-
Open4.expects(:popen4).raises("exec call failed")
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
it 'should raise an error wrapping the system error raised' do
|
|
177
|
-
expect do
|
|
178
|
-
helpers.send(:run, command)
|
|
179
|
-
end.to raise_error {|err|
|
|
180
|
-
err.message.should == "CLI::SystemCallError: " +
|
|
181
|
-
"Failed to execute system command on #{ RUBY_PLATFORM }\n" +
|
|
182
|
-
" Command was: /path/to/cmd_name arg1 arg2\n" +
|
|
183
|
-
" Reason: RuntimeError\n" +
|
|
184
|
-
" exec call failed"
|
|
185
|
-
}
|
|
186
|
-
end
|
|
187
|
-
end # context 'when the system fails to execute the command'
|
|
188
|
-
end # describe '#run'
|
|
189
|
-
|
|
190
|
-
describe '#utility' do
|
|
191
|
-
after { Backup::CLI::Helpers::UTILITY.clear }
|
|
192
|
-
|
|
193
|
-
context 'when a system path for the utility is available' do
|
|
194
|
-
it 'should return the system path with newline removed' do
|
|
195
|
-
helpers.expects(:`).with('which foo 2>/dev/null').returns("system_path\n")
|
|
196
|
-
helpers.send(:utility, :foo).should == 'system_path'
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
it 'should cache the returned path' do
|
|
200
|
-
helpers.expects(:`).once.with('which cache_me 2>/dev/null').
|
|
201
|
-
returns("cached_path\n")
|
|
202
|
-
|
|
203
|
-
helpers.send(:utility, :cache_me).should == 'cached_path'
|
|
204
|
-
helpers.send(:utility, :cache_me).should == 'cached_path'
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
it 'should cache the value for all extended objects' do
|
|
208
|
-
helpers.expects(:`).once.with('which once_only 2>/dev/null').
|
|
209
|
-
returns("cached_path\n")
|
|
210
|
-
|
|
211
|
-
helpers.send(:utility, :once_only).should == 'cached_path'
|
|
212
|
-
Class.new.extend(Backup::CLI::Helpers).send(
|
|
213
|
-
:utility, :once_only).should == 'cached_path'
|
|
214
|
-
end
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
context 'when a system path for the utility is not available' do
|
|
218
|
-
it 'should raise an error' do
|
|
219
|
-
helpers.expects(:`).with('which unknown 2>/dev/null').returns("\n")
|
|
220
|
-
|
|
221
|
-
expect do
|
|
222
|
-
helpers.send(:utility, :unknown)
|
|
223
|
-
end.to raise_error(Backup::Errors::CLI::UtilityNotFoundError) {|err|
|
|
224
|
-
err.message.should match(/Could not locate 'unknown'/)
|
|
225
|
-
}
|
|
226
|
-
end
|
|
227
|
-
|
|
228
|
-
it 'should not cache any value for the utility' do
|
|
229
|
-
helpers.expects(:`).with('which not_cached 2>/dev/null').twice.returns("\n")
|
|
230
|
-
|
|
231
|
-
expect do
|
|
232
|
-
helpers.send(:utility, :not_cached)
|
|
233
|
-
end.to raise_error(Backup::Errors::CLI::UtilityNotFoundError) {|err|
|
|
234
|
-
err.message.should match(/Could not locate 'not_cached'/)
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
expect do
|
|
238
|
-
helpers.send(:utility, :not_cached)
|
|
239
|
-
end.to raise_error(Backup::Errors::CLI::UtilityNotFoundError) {|err|
|
|
240
|
-
err.message.should match(/Could not locate 'not_cached'/)
|
|
241
|
-
}
|
|
242
|
-
end
|
|
243
|
-
end
|
|
244
|
-
|
|
245
|
-
it 'should raise an error if name is nil' do
|
|
246
|
-
expect do
|
|
247
|
-
helpers.send(:utility, nil)
|
|
248
|
-
end.to raise_error(
|
|
249
|
-
Backup::Errors::CLI::UtilityNotFoundError,
|
|
250
|
-
'CLI::UtilityNotFoundError: Utility Name Empty'
|
|
251
|
-
)
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
it 'should raise an error if name is empty' do
|
|
255
|
-
expect do
|
|
256
|
-
helpers.send(:utility, ' ')
|
|
257
|
-
end.to raise_error(
|
|
258
|
-
Backup::Errors::CLI::UtilityNotFoundError,
|
|
259
|
-
'CLI::UtilityNotFoundError: Utility Name Empty'
|
|
260
|
-
)
|
|
261
|
-
end
|
|
262
|
-
end # describe '#utility'
|
|
263
|
-
|
|
264
|
-
describe '#command_name' do
|
|
265
|
-
context 'given a command line path with no arguments' do
|
|
266
|
-
it 'should return the base command name' do
|
|
267
|
-
cmd = '/path/to/a/command'
|
|
268
|
-
helpers.send(:command_name, cmd).should == 'command'
|
|
269
|
-
end
|
|
270
|
-
end
|
|
271
|
-
|
|
272
|
-
context 'given a command line path with a single argument' do
|
|
273
|
-
it 'should return the base command name' do
|
|
274
|
-
cmd = '/path/to/a/command with_args'
|
|
275
|
-
helpers.send(:command_name, cmd).should == 'command'
|
|
276
|
-
end
|
|
277
|
-
end
|
|
278
|
-
|
|
279
|
-
context 'given a command line path with multiple arguments' do
|
|
280
|
-
it 'should return the base command name' do
|
|
281
|
-
cmd = '/path/to/a/command with multiple args'
|
|
282
|
-
helpers.send(:command_name, cmd).should == 'command'
|
|
283
|
-
end
|
|
284
|
-
end
|
|
285
|
-
|
|
286
|
-
context 'given a command with no path and arguments' do
|
|
287
|
-
it 'should return the base command name' do
|
|
288
|
-
cmd = 'command args'
|
|
289
|
-
helpers.send(:command_name, cmd).should == 'command'
|
|
290
|
-
end
|
|
291
|
-
end
|
|
292
|
-
|
|
293
|
-
context 'given a command with no path and no arguments' do
|
|
294
|
-
it 'should return the base command name' do
|
|
295
|
-
cmd = 'command'
|
|
296
|
-
helpers.send(:command_name, cmd).should == 'command'
|
|
297
|
-
end
|
|
298
|
-
end
|
|
299
|
-
end # describe '#command_name'
|
|
300
|
-
|
|
301
|
-
end
|
data/spec/cli/utility_spec.rb
DELETED
|
@@ -1,411 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
require File.expand_path('../../spec_helper.rb', __FILE__)
|
|
4
|
-
|
|
5
|
-
describe 'Backup::CLI::Utility' do
|
|
6
|
-
let(:cli) { Backup::CLI::Utility }
|
|
7
|
-
let(:utility) { Backup::CLI::Utility.new }
|
|
8
|
-
let(:s) { sequence '' }
|
|
9
|
-
|
|
10
|
-
before { @argv_save = ARGV }
|
|
11
|
-
after { ARGV.replace(@argv_save) }
|
|
12
|
-
|
|
13
|
-
describe '#perform' do
|
|
14
|
-
let(:model_a) { Backup::Model.new(:test_trigger_a, 'test label a') }
|
|
15
|
-
let(:model_b) { Backup::Model.new(:test_trigger_b, 'test label b') }
|
|
16
|
-
|
|
17
|
-
after { Backup::Model.all.clear }
|
|
18
|
-
|
|
19
|
-
it 'should perform the backup for the given trigger' do
|
|
20
|
-
Backup::Logger.expects(:quiet=).in_sequence(s)
|
|
21
|
-
Backup::Config.expects(:update).in_sequence(s)
|
|
22
|
-
|
|
23
|
-
FileUtils.expects(:mkdir_p).in_sequence(s).with(Backup::Config.log_path)
|
|
24
|
-
FileUtils.expects(:mkdir_p).in_sequence(s).with(Backup::Config.cache_path)
|
|
25
|
-
FileUtils.expects(:mkdir_p).in_sequence(s).with(Backup::Config.tmp_path)
|
|
26
|
-
|
|
27
|
-
Backup::Config.expects(:load_config!).in_sequence(s)
|
|
28
|
-
|
|
29
|
-
Backup::Logger.expects(:truncate!)
|
|
30
|
-
|
|
31
|
-
model_a.expects(:prepare!).in_sequence(s)
|
|
32
|
-
model_a.expects(:perform!).in_sequence(s)
|
|
33
|
-
Backup::Logger.expects(:clear!).in_sequence(s)
|
|
34
|
-
|
|
35
|
-
expect do
|
|
36
|
-
ARGV.replace(['perform', '-t', 'test_trigger_a'])
|
|
37
|
-
cli.start
|
|
38
|
-
end.not_to raise_error
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
it 'should perform backups for the multiple triggers' do
|
|
42
|
-
Backup::Logger.expects(:quiet=).in_sequence(s)
|
|
43
|
-
Backup::Config.expects(:update).in_sequence(s)
|
|
44
|
-
|
|
45
|
-
FileUtils.expects(:mkdir_p).in_sequence(s).with(Backup::Config.log_path)
|
|
46
|
-
FileUtils.expects(:mkdir_p).in_sequence(s).with(Backup::Config.cache_path)
|
|
47
|
-
FileUtils.expects(:mkdir_p).in_sequence(s).with(Backup::Config.tmp_path)
|
|
48
|
-
|
|
49
|
-
Backup::Config.expects(:load_config!).in_sequence(s)
|
|
50
|
-
|
|
51
|
-
Backup::Logger.expects(:truncate!)
|
|
52
|
-
|
|
53
|
-
model_a.expects(:prepare!).in_sequence(s)
|
|
54
|
-
model_a.expects(:perform!).in_sequence(s)
|
|
55
|
-
Backup::Logger.expects(:clear!).in_sequence(s)
|
|
56
|
-
|
|
57
|
-
model_b.expects(:prepare!).in_sequence(s)
|
|
58
|
-
model_b.expects(:perform!).in_sequence(s)
|
|
59
|
-
Backup::Logger.expects(:clear!).in_sequence(s)
|
|
60
|
-
|
|
61
|
-
expect do
|
|
62
|
-
ARGV.replace(['perform', '-t', 'test_trigger_a,test_trigger_b'])
|
|
63
|
-
cli.start
|
|
64
|
-
end.not_to raise_error
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
it 'should perform backups for the multiple triggers when using wildcard' do
|
|
68
|
-
Backup::Logger.expects(:quiet=).in_sequence(s)
|
|
69
|
-
Backup::Config.expects(:update).in_sequence(s)
|
|
70
|
-
|
|
71
|
-
FileUtils.expects(:mkdir_p).in_sequence(s).with(Backup::Config.log_path)
|
|
72
|
-
FileUtils.expects(:mkdir_p).in_sequence(s).with(Backup::Config.cache_path)
|
|
73
|
-
FileUtils.expects(:mkdir_p).in_sequence(s).with(Backup::Config.tmp_path)
|
|
74
|
-
|
|
75
|
-
Backup::Config.expects(:load_config!).in_sequence(s)
|
|
76
|
-
|
|
77
|
-
Backup::Logger.expects(:truncate!)
|
|
78
|
-
|
|
79
|
-
model_a.expects(:prepare!).in_sequence(s)
|
|
80
|
-
model_a.expects(:perform!).in_sequence(s)
|
|
81
|
-
Backup::Logger.expects(:clear!).in_sequence(s)
|
|
82
|
-
|
|
83
|
-
model_b.expects(:prepare!).in_sequence(s)
|
|
84
|
-
model_b.expects(:perform!).in_sequence(s)
|
|
85
|
-
Backup::Logger.expects(:clear!).in_sequence(s)
|
|
86
|
-
|
|
87
|
-
expect do
|
|
88
|
-
ARGV.replace(['perform', '-t', 'test_trigger_*'])
|
|
89
|
-
cli.start
|
|
90
|
-
end.not_to raise_error
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
context 'when errors occur' do
|
|
94
|
-
it 'should log the error and exit' do
|
|
95
|
-
Backup::Logger.stubs(:quiet=).raises(SystemCallError, 'yikes!')
|
|
96
|
-
Backup::Logger.expects(:error).with do |err|
|
|
97
|
-
err.message.should ==
|
|
98
|
-
"CLIError: SystemCallError: unknown error - yikes!"
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
expect do
|
|
102
|
-
ARGV.replace(['perform', '-t', 'foo'])
|
|
103
|
-
cli.start
|
|
104
|
-
end.to raise_error(SystemExit) {|exit| exit.status.should == 1 }
|
|
105
|
-
end
|
|
106
|
-
end # context 'when errors occur'
|
|
107
|
-
|
|
108
|
-
end # describe '#perform'
|
|
109
|
-
|
|
110
|
-
describe '#generate:model' do
|
|
111
|
-
before do
|
|
112
|
-
FileUtils.unstub(:mkdir_p)
|
|
113
|
-
FileUtils.unstub(:touch)
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
after do
|
|
117
|
-
Backup::Config.send(:reset!)
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
context 'when given a config_path' do
|
|
121
|
-
context 'when no config file exists' do
|
|
122
|
-
it 'should create both a config and a model under the given path' do
|
|
123
|
-
Dir.mktmpdir do |path|
|
|
124
|
-
model_file = File.join(path, 'custom', 'models', 'test_trigger.rb')
|
|
125
|
-
config_file = File.join(path, 'custom', 'config.rb')
|
|
126
|
-
|
|
127
|
-
out, err = capture_io do
|
|
128
|
-
ARGV.replace(['generate:model',
|
|
129
|
-
'--config-path', File.join(path, 'custom'),
|
|
130
|
-
'--trigger', 'test_trigger'
|
|
131
|
-
])
|
|
132
|
-
cli.start
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
out.should == "Generated model file: '#{ model_file }'.\n" +
|
|
136
|
-
"Generated configuration file: '#{ config_file }'.\n"
|
|
137
|
-
File.exist?(model_file).should be_true
|
|
138
|
-
File.exist?(config_file).should be_true
|
|
139
|
-
end
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
context 'when a config file already exists' do
|
|
144
|
-
it 'should only create a model under the given path' do
|
|
145
|
-
Dir.mktmpdir do |path|
|
|
146
|
-
model_file = File.join(path, 'custom', 'models', 'test_trigger.rb')
|
|
147
|
-
config_file = File.join(path, 'custom', 'config.rb')
|
|
148
|
-
FileUtils.mkdir_p(File.join(path, 'custom'))
|
|
149
|
-
FileUtils.touch(config_file)
|
|
150
|
-
|
|
151
|
-
out, err = capture_io do
|
|
152
|
-
ARGV.replace(['generate:model',
|
|
153
|
-
'--config-path', File.join(path, 'custom'),
|
|
154
|
-
'--trigger', 'test_trigger'
|
|
155
|
-
])
|
|
156
|
-
cli.start
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
out.should == "Generated model file: '#{ model_file }'.\n"
|
|
160
|
-
File.exist?(model_file).should be_true
|
|
161
|
-
end
|
|
162
|
-
end
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
# These pass, but generate Thor warnings...
|
|
166
|
-
#
|
|
167
|
-
# context 'when a model file already exists' do
|
|
168
|
-
# it 'should prompt to overwrite the model under the given path' do
|
|
169
|
-
# Dir.mktmpdir do |path|
|
|
170
|
-
# model_file = File.join(path, 'models', 'test_trigger.rb')
|
|
171
|
-
# config_file = File.join(path, 'config.rb')
|
|
172
|
-
#
|
|
173
|
-
# cli.any_instance.expects(:overwrite?).with(model_file).returns(false)
|
|
174
|
-
#
|
|
175
|
-
# out, err = capture_io do
|
|
176
|
-
# ARGV.replace(['generate:model',
|
|
177
|
-
# '--config-path', path,
|
|
178
|
-
# '--trigger', 'test_trigger'
|
|
179
|
-
# ])
|
|
180
|
-
# cli.start
|
|
181
|
-
# end
|
|
182
|
-
#
|
|
183
|
-
# out.should == "Generated configuration file: '#{ config_file }'.\n"
|
|
184
|
-
# File.exist?(config_file).should be_true
|
|
185
|
-
# File.exist?(model_file).should be_false
|
|
186
|
-
# end
|
|
187
|
-
# end
|
|
188
|
-
# end
|
|
189
|
-
|
|
190
|
-
end # context 'when given a config_path'
|
|
191
|
-
|
|
192
|
-
context 'when not given a config_path' do
|
|
193
|
-
it 'should create both a config and a model under the root path' do
|
|
194
|
-
Dir.mktmpdir do |path|
|
|
195
|
-
Backup::Config.update(:root_path => path)
|
|
196
|
-
model_file = File.join(path, 'models', 'test_trigger.rb')
|
|
197
|
-
config_file = File.join(path, 'config.rb')
|
|
198
|
-
|
|
199
|
-
out, err = capture_io do
|
|
200
|
-
ARGV.replace(['generate:model', '--trigger', 'test_trigger'])
|
|
201
|
-
cli.start
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
out.should == "Generated model file: '#{ model_file }'.\n" +
|
|
205
|
-
"Generated configuration file: '#{ config_file }'.\n"
|
|
206
|
-
File.exist?(model_file).should be_true
|
|
207
|
-
File.exist?(config_file).should be_true
|
|
208
|
-
end
|
|
209
|
-
end
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
it 'should generate the proper help output' do
|
|
213
|
-
ruby19_output = <<-EOS
|
|
214
|
-
Usage:
|
|
215
|
-
#{ File.basename($0) } generate:model --trigger=TRIGGER
|
|
216
|
-
|
|
217
|
-
Options:
|
|
218
|
-
--trigger=TRIGGER
|
|
219
|
-
[--config-path=CONFIG_PATH] # Path to your Backup configuration directory
|
|
220
|
-
[--databases=DATABASES] # (mongodb, mysql, postgresql, redis, riak)
|
|
221
|
-
[--storages=STORAGES] # (cloud_files, dropbox, ftp, local, ninefold, rsync, s3, scp, sftp)
|
|
222
|
-
[--syncers=SYNCERS] # (cloud_files, rsync_local, rsync_pull, rsync_push, s3)
|
|
223
|
-
[--encryptors=ENCRYPTORS] # (gpg, openssl)
|
|
224
|
-
[--compressors=COMPRESSORS] # (bzip2, custom, gzip, lzma, pbzip2)
|
|
225
|
-
[--notifiers=NOTIFIERS] # (campfire, hipchat, mail, prowl, pushover, twitter)
|
|
226
|
-
[--archives]
|
|
227
|
-
[--splitter] # use `--no-splitter` to disable
|
|
228
|
-
# Default: true
|
|
229
|
-
Generates a Backup model file
|
|
230
|
-
|
|
231
|
-
Note:
|
|
232
|
-
'--config-path' is the path to the directory where 'config.rb' is located.
|
|
233
|
-
The model file will be created as '<config_path>/models/<trigger>.rb'
|
|
234
|
-
Default: #{ Backup::Config.root_path }
|
|
235
|
-
EOS
|
|
236
|
-
|
|
237
|
-
out, err = capture_io do
|
|
238
|
-
ARGV.replace(['help', 'generate:model'])
|
|
239
|
-
cli.start
|
|
240
|
-
end
|
|
241
|
-
|
|
242
|
-
expected_lines = ruby19_output.split("\n").map(&:strip).select {|e| !e.empty? }
|
|
243
|
-
output_lines = out.split("\n").map(&:strip).select {|e| !e.empty? }
|
|
244
|
-
|
|
245
|
-
output_lines.sort.should == expected_lines.sort
|
|
246
|
-
end
|
|
247
|
-
end # describe '#generate:model'
|
|
248
|
-
|
|
249
|
-
describe '#generate:config' do
|
|
250
|
-
before do
|
|
251
|
-
FileUtils.unstub(:mkdir_p)
|
|
252
|
-
FileUtils.unstub(:touch)
|
|
253
|
-
end
|
|
254
|
-
|
|
255
|
-
after do
|
|
256
|
-
Backup::Config.send(:reset!)
|
|
257
|
-
end
|
|
258
|
-
|
|
259
|
-
context 'when given a config_path' do
|
|
260
|
-
it 'should create a config file in the given path' do
|
|
261
|
-
Dir.mktmpdir do |path|
|
|
262
|
-
config_file = File.join(path, 'custom', 'config.rb')
|
|
263
|
-
|
|
264
|
-
out, err = capture_io do
|
|
265
|
-
ARGV.replace(['generate:config',
|
|
266
|
-
'--config-path', File.join(path, 'custom'),
|
|
267
|
-
])
|
|
268
|
-
cli.start
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
out.should == "Generated configuration file: '#{ config_file }'.\n"
|
|
272
|
-
File.exist?(config_file).should be_true
|
|
273
|
-
end
|
|
274
|
-
end
|
|
275
|
-
end
|
|
276
|
-
|
|
277
|
-
context 'when not given a config_path' do
|
|
278
|
-
it 'should create a config file in the root path' do
|
|
279
|
-
Dir.mktmpdir do |path|
|
|
280
|
-
Backup::Config.update(:root_path => path)
|
|
281
|
-
config_file = File.join(path, 'config.rb')
|
|
282
|
-
|
|
283
|
-
out, err = capture_io do
|
|
284
|
-
ARGV.replace(['generate:config'])
|
|
285
|
-
cli.start
|
|
286
|
-
end
|
|
287
|
-
|
|
288
|
-
out.should == "Generated configuration file: '#{ config_file }'.\n"
|
|
289
|
-
File.exist?(config_file).should be_true
|
|
290
|
-
end
|
|
291
|
-
end
|
|
292
|
-
end
|
|
293
|
-
|
|
294
|
-
# These pass, but generate Thor warnings...
|
|
295
|
-
#
|
|
296
|
-
# context 'when a config file already exists' do
|
|
297
|
-
# it 'should prompt to overwrite the config file' do
|
|
298
|
-
# Dir.mktmpdir do |path|
|
|
299
|
-
# Backup::Config.update(:root_path => path)
|
|
300
|
-
# config_file = File.join(path, 'config.rb')
|
|
301
|
-
#
|
|
302
|
-
# cli.any_instance.expects(:overwrite?).with(config_file).returns(false)
|
|
303
|
-
#
|
|
304
|
-
# out, err = capture_io do
|
|
305
|
-
# ARGV.replace(['generate:config'])
|
|
306
|
-
# cli.start
|
|
307
|
-
# end
|
|
308
|
-
#
|
|
309
|
-
# out.should be_empty
|
|
310
|
-
# File.exist?(config_file).should be_false
|
|
311
|
-
# end
|
|
312
|
-
# end
|
|
313
|
-
# end
|
|
314
|
-
|
|
315
|
-
end # describe '#generate:config'
|
|
316
|
-
|
|
317
|
-
describe '#decrypt' do
|
|
318
|
-
|
|
319
|
-
# These pass, but generate Thor warnings...
|
|
320
|
-
#
|
|
321
|
-
# it 'should perform OpenSSL decryption' do
|
|
322
|
-
# ARGV.replace(['decrypt', '--encryptor', 'openssl',
|
|
323
|
-
# '--in', 'in_file',
|
|
324
|
-
# '--out', 'out_file',
|
|
325
|
-
# '--base64', '--salt',
|
|
326
|
-
# '--password-file', 'pwd_file'])
|
|
327
|
-
#
|
|
328
|
-
# cli.any_instance.expects(:`).with(
|
|
329
|
-
# "openssl aes-256-cbc -d -base64 -pass file:pwd_file -salt " +
|
|
330
|
-
# "-in 'in_file' -out 'out_file'"
|
|
331
|
-
# )
|
|
332
|
-
# cli.start
|
|
333
|
-
# end
|
|
334
|
-
#
|
|
335
|
-
# it 'should omit -pass option if no --password-file given' do
|
|
336
|
-
# ARGV.replace(['decrypt', '--encryptor', 'openssl',
|
|
337
|
-
# '--in', 'in_file',
|
|
338
|
-
# '--out', 'out_file',
|
|
339
|
-
# '--base64', '--salt'])
|
|
340
|
-
#
|
|
341
|
-
# cli.any_instance.expects(:`).with(
|
|
342
|
-
# "openssl aes-256-cbc -d -base64 -salt " +
|
|
343
|
-
# "-in 'in_file' -out 'out_file'"
|
|
344
|
-
# )
|
|
345
|
-
# cli.start
|
|
346
|
-
# end
|
|
347
|
-
#
|
|
348
|
-
# it 'should perform GnuPG decryption' do
|
|
349
|
-
# ARGV.replace(['decrypt', '--encryptor', 'gpg',
|
|
350
|
-
# '--in', 'in_file',
|
|
351
|
-
# '--out', 'out_file'])
|
|
352
|
-
#
|
|
353
|
-
# cli.any_instance.expects(:`).with(
|
|
354
|
-
# "gpg -o 'out_file' -d 'in_file'"
|
|
355
|
-
# )
|
|
356
|
-
# cli.start
|
|
357
|
-
# end
|
|
358
|
-
|
|
359
|
-
it 'should show a message if given an invalid encryptor' do
|
|
360
|
-
ARGV.replace(['decrypt', '--encryptor', 'foo',
|
|
361
|
-
'--in', 'in_file',
|
|
362
|
-
'--out', 'out_file'])
|
|
363
|
-
out, err = capture_io do
|
|
364
|
-
cli.start
|
|
365
|
-
end
|
|
366
|
-
err.should == ''
|
|
367
|
-
out.should == "Unknown encryptor: foo\n" +
|
|
368
|
-
"Use either 'openssl' or 'gpg'.\n"
|
|
369
|
-
end
|
|
370
|
-
end
|
|
371
|
-
|
|
372
|
-
# would have the same Thor warnings issues...
|
|
373
|
-
# describe '#dependencies' do
|
|
374
|
-
# end
|
|
375
|
-
|
|
376
|
-
describe '#version' do
|
|
377
|
-
it 'should output the current version' do
|
|
378
|
-
utility.expects(:puts).with("Backup #{ Backup::Version.current }")
|
|
379
|
-
utility.version
|
|
380
|
-
end
|
|
381
|
-
|
|
382
|
-
it 'should output the current version for "-v"' do
|
|
383
|
-
ARGV.replace ['-v']
|
|
384
|
-
out, err = capture_io do
|
|
385
|
-
cli.start
|
|
386
|
-
end
|
|
387
|
-
out.should == "Backup #{ Backup::Version.current }\n"
|
|
388
|
-
end
|
|
389
|
-
end
|
|
390
|
-
|
|
391
|
-
describe '#overwrite?' do
|
|
392
|
-
context 'when the path exists' do
|
|
393
|
-
before { File.expects(:exist?).returns(true) }
|
|
394
|
-
|
|
395
|
-
it 'should prompt user' do
|
|
396
|
-
utility.expects(:yes?).with(
|
|
397
|
-
"A file already exists at 'a/path'. Do you want to overwrite? [y/n]"
|
|
398
|
-
).returns(:response)
|
|
399
|
-
utility.send(:overwrite?, 'a/path').should == :response
|
|
400
|
-
end
|
|
401
|
-
end
|
|
402
|
-
|
|
403
|
-
context 'when the path does not exist' do
|
|
404
|
-
before { File.expects(:exist?).returns(false) }
|
|
405
|
-
it 'should return true' do
|
|
406
|
-
utility.expects(:yes?).never
|
|
407
|
-
utility.send(:overwrite?, 'a/path').should be_true
|
|
408
|
-
end
|
|
409
|
-
end
|
|
410
|
-
end
|
|
411
|
-
end
|