backup 3.0.20 → 3.0.21
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 +1 -5
- data/Gemfile.lock +46 -50
- data/README.md +54 -27
- data/lib/backup.rb +16 -39
- data/lib/backup/archive.rb +42 -18
- data/lib/backup/cleaner.rb +110 -25
- data/lib/backup/cli/helpers.rb +17 -32
- data/lib/backup/cli/utility.rb +46 -107
- data/lib/backup/compressor/base.rb +14 -2
- data/lib/backup/compressor/bzip2.rb +10 -24
- data/lib/backup/compressor/gzip.rb +10 -24
- data/lib/backup/compressor/lzma.rb +10 -23
- data/lib/backup/compressor/pbzip2.rb +12 -32
- data/lib/backup/config.rb +171 -0
- data/lib/backup/configuration/compressor/base.rb +1 -2
- data/lib/backup/configuration/compressor/pbzip2.rb +4 -4
- data/lib/backup/configuration/database/base.rb +2 -1
- data/lib/backup/configuration/database/mongodb.rb +8 -0
- data/lib/backup/configuration/database/mysql.rb +4 -0
- data/lib/backup/configuration/database/postgresql.rb +4 -0
- data/lib/backup/configuration/database/redis.rb +4 -0
- data/lib/backup/configuration/database/riak.rb +5 -1
- data/lib/backup/configuration/encryptor/base.rb +1 -2
- data/lib/backup/configuration/encryptor/open_ssl.rb +1 -1
- data/lib/backup/configuration/helpers.rb +7 -2
- data/lib/backup/configuration/notifier/base.rb +4 -28
- data/lib/backup/configuration/storage/base.rb +1 -1
- data/lib/backup/configuration/storage/dropbox.rb +14 -4
- data/lib/backup/configuration/syncer/base.rb +10 -0
- data/lib/backup/configuration/syncer/rsync/base.rb +28 -0
- data/lib/backup/configuration/syncer/rsync/local.rb +11 -0
- data/lib/backup/configuration/syncer/rsync/pull.rb +11 -0
- data/lib/backup/configuration/syncer/rsync/push.rb +31 -0
- data/lib/backup/configuration/syncer/s3.rb +0 -4
- data/lib/backup/database/base.rb +25 -7
- data/lib/backup/database/mongodb.rb +112 -75
- data/lib/backup/database/mysql.rb +54 -29
- data/lib/backup/database/postgresql.rb +60 -42
- data/lib/backup/database/redis.rb +61 -39
- data/lib/backup/database/riak.rb +35 -11
- data/lib/backup/dependency.rb +4 -5
- data/lib/backup/encryptor/base.rb +13 -1
- data/lib/backup/encryptor/gpg.rb +39 -39
- data/lib/backup/encryptor/open_ssl.rb +28 -38
- data/lib/backup/logger.rb +20 -11
- data/lib/backup/model.rb +206 -163
- data/lib/backup/notifier/base.rb +27 -25
- data/lib/backup/notifier/campfire.rb +7 -13
- data/lib/backup/notifier/hipchat.rb +28 -28
- data/lib/backup/notifier/mail.rb +24 -26
- data/lib/backup/notifier/presently.rb +10 -18
- data/lib/backup/notifier/prowl.rb +9 -17
- data/lib/backup/notifier/twitter.rb +11 -18
- data/lib/backup/package.rb +47 -0
- data/lib/backup/packager.rb +81 -16
- data/lib/backup/splitter.rb +48 -35
- data/lib/backup/storage/base.rb +44 -172
- data/lib/backup/storage/cloudfiles.rb +31 -46
- data/lib/backup/storage/cycler.rb +117 -0
- data/lib/backup/storage/dropbox.rb +92 -76
- data/lib/backup/storage/ftp.rb +30 -40
- data/lib/backup/storage/local.rb +44 -45
- data/lib/backup/storage/ninefold.rb +55 -49
- data/lib/backup/storage/rsync.rb +49 -56
- data/lib/backup/storage/s3.rb +33 -44
- data/lib/backup/storage/scp.rb +21 -48
- data/lib/backup/storage/sftp.rb +26 -40
- data/lib/backup/syncer/base.rb +7 -0
- data/lib/backup/syncer/rsync/base.rb +78 -0
- data/lib/backup/syncer/rsync/local.rb +53 -0
- data/lib/backup/syncer/rsync/pull.rb +38 -0
- data/lib/backup/syncer/rsync/push.rb +113 -0
- data/lib/backup/syncer/s3.rb +42 -32
- data/lib/backup/version.rb +1 -1
- data/spec/archive_spec.rb +235 -69
- data/spec/cleaner_spec.rb +304 -0
- data/spec/cli/helpers_spec.rb +142 -1
- data/spec/cli/utility_spec.rb +338 -13
- data/spec/compressor/base_spec.rb +31 -0
- data/spec/compressor/bzip2_spec.rb +60 -35
- data/spec/compressor/gzip_spec.rb +60 -35
- data/spec/compressor/lzma_spec.rb +60 -35
- data/spec/compressor/pbzip2_spec.rb +98 -37
- data/spec/config_spec.rb +321 -0
- data/spec/configuration/base_spec.rb +4 -4
- data/spec/configuration/compressor/bzip2_spec.rb +1 -0
- data/spec/configuration/compressor/gzip_spec.rb +1 -0
- data/spec/configuration/compressor/lzma_spec.rb +1 -0
- data/spec/configuration/compressor/pbzip2_spec.rb +32 -0
- data/spec/configuration/database/base_spec.rb +2 -1
- data/spec/configuration/database/mongodb_spec.rb +26 -16
- data/spec/configuration/database/mysql_spec.rb +4 -0
- data/spec/configuration/database/postgresql_spec.rb +4 -0
- data/spec/configuration/database/redis_spec.rb +4 -0
- data/spec/configuration/database/riak_spec.rb +4 -0
- data/spec/configuration/encryptor/gpg_spec.rb +1 -0
- data/spec/configuration/encryptor/open_ssl_spec.rb +1 -0
- data/spec/configuration/notifier/base_spec.rb +32 -0
- data/spec/configuration/notifier/campfire_spec.rb +1 -0
- data/spec/configuration/notifier/hipchat_spec.rb +1 -0
- data/spec/configuration/notifier/mail_spec.rb +1 -0
- data/spec/configuration/notifier/presently_spec.rb +1 -0
- data/spec/configuration/notifier/prowl_spec.rb +1 -0
- data/spec/configuration/notifier/twitter_spec.rb +1 -0
- data/spec/configuration/storage/cloudfiles_spec.rb +1 -0
- data/spec/configuration/storage/dropbox_spec.rb +4 -3
- data/spec/configuration/storage/ftp_spec.rb +1 -0
- data/spec/configuration/storage/local_spec.rb +1 -0
- data/spec/configuration/storage/ninefold_spec.rb +1 -0
- data/spec/configuration/storage/rsync_spec.rb +3 -1
- data/spec/configuration/storage/s3_spec.rb +1 -0
- data/spec/configuration/storage/scp_spec.rb +1 -0
- data/spec/configuration/storage/sftp_spec.rb +1 -0
- data/spec/configuration/syncer/rsync/base_spec.rb +33 -0
- data/spec/configuration/syncer/rsync/local_spec.rb +10 -0
- data/spec/configuration/syncer/rsync/pull_spec.rb +10 -0
- data/spec/configuration/syncer/{rsync_spec.rb → rsync/push_spec.rb} +12 -15
- data/spec/configuration/syncer/s3_spec.rb +2 -3
- data/spec/database/base_spec.rb +35 -20
- data/spec/database/mongodb_spec.rb +298 -119
- data/spec/database/mysql_spec.rb +147 -72
- data/spec/database/postgresql_spec.rb +155 -100
- data/spec/database/redis_spec.rb +200 -97
- data/spec/database/riak_spec.rb +82 -24
- data/spec/dependency_spec.rb +49 -0
- data/spec/encryptor/base_spec.rb +30 -0
- data/spec/encryptor/gpg_spec.rb +105 -28
- data/spec/encryptor/open_ssl_spec.rb +85 -114
- data/spec/logger_spec.rb +74 -8
- data/spec/model_spec.rb +528 -220
- data/spec/notifier/base_spec.rb +89 -0
- data/spec/notifier/campfire_spec.rb +147 -119
- data/spec/notifier/hipchat_spec.rb +140 -145
- data/spec/notifier/mail_spec.rb +190 -248
- data/spec/notifier/presently_spec.rb +147 -282
- data/spec/notifier/prowl_spec.rb +79 -111
- data/spec/notifier/twitter_spec.rb +87 -106
- data/spec/package_spec.rb +61 -0
- data/spec/packager_spec.rb +154 -0
- data/spec/spec_helper.rb +36 -13
- data/spec/splitter_spec.rb +90 -41
- data/spec/storage/base_spec.rb +95 -239
- data/spec/storage/cloudfiles_spec.rb +185 -75
- data/spec/storage/cycler_spec.rb +239 -0
- data/spec/storage/dropbox_spec.rb +318 -87
- data/spec/storage/ftp_spec.rb +165 -152
- data/spec/storage/local_spec.rb +206 -54
- data/spec/storage/ninefold_spec.rb +264 -128
- data/spec/storage/rsync_spec.rb +244 -163
- data/spec/storage/s3_spec.rb +175 -64
- data/spec/storage/scp_spec.rb +156 -150
- data/spec/storage/sftp_spec.rb +153 -135
- data/spec/syncer/base_spec.rb +22 -0
- data/spec/syncer/rsync/base_spec.rb +118 -0
- data/spec/syncer/rsync/local_spec.rb +121 -0
- data/spec/syncer/rsync/pull_spec.rb +90 -0
- data/spec/syncer/rsync/push_spec.rb +327 -0
- data/spec/syncer/s3_spec.rb +180 -91
- data/templates/cli/utility/config +1 -1
- data/templates/cli/utility/database/mongodb +4 -0
- data/templates/cli/utility/database/mysql +3 -0
- data/templates/cli/utility/database/postgresql +3 -0
- data/templates/cli/utility/database/redis +3 -0
- data/templates/cli/utility/database/riak +3 -0
- data/templates/cli/utility/storage/dropbox +4 -1
- data/templates/cli/utility/syncer/rsync_local +12 -0
- data/templates/cli/utility/syncer/{rsync → rsync_pull} +2 -2
- data/templates/cli/utility/syncer/rsync_push +17 -0
- data/templates/storage/dropbox/authorization_url.erb +1 -1
- metadata +42 -17
- data/lib/backup/configuration/syncer/rsync.rb +0 -45
- data/lib/backup/finder.rb +0 -87
- data/lib/backup/storage/object.rb +0 -47
- data/lib/backup/syncer/rsync.rb +0 -152
- data/spec/backup_spec.rb +0 -11
- data/spec/finder_spec.rb +0 -91
- data/spec/storage/object_spec.rb +0 -74
- data/spec/syncer/rsync_spec.rb +0 -195
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require File.expand_path('../spec_helper.rb', __FILE__)
|
|
4
|
+
|
|
5
|
+
describe 'Backup::Cleaner' do
|
|
6
|
+
let(:model) { Backup::Model.new(:test_trigger, 'test label') }
|
|
7
|
+
let(:cleaner) { Backup::Cleaner }
|
|
8
|
+
|
|
9
|
+
describe '#prepare' do
|
|
10
|
+
let(:error_tail) do
|
|
11
|
+
" Please check the log for messages and/or your notifications\n" +
|
|
12
|
+
" concerning this backup: 'test label (test_trigger)'\n" +
|
|
13
|
+
" The temporary files which had to be removed should not have existed."
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
context 'when neither the tmp_path is dirty or package files exist' do
|
|
17
|
+
it 'should do nothing' do
|
|
18
|
+
cleaner.expects(:packaging_folder_dirty?).returns(false)
|
|
19
|
+
cleaner.expects(:tmp_path_package_files).returns([])
|
|
20
|
+
FileUtils.expects(:rm_rf).never
|
|
21
|
+
FileUtils.expects(:rm_f).never
|
|
22
|
+
Backup::Logger.expects(:warn).never
|
|
23
|
+
|
|
24
|
+
cleaner.prepare(model)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
context 'when the tmp_path is dirty' do
|
|
29
|
+
it 'should remove tmp_path and log a warning' do
|
|
30
|
+
cleaner.expects(:packaging_folder_dirty?).returns(true)
|
|
31
|
+
cleaner.expects(:tmp_path_package_files).returns([])
|
|
32
|
+
FileUtils.expects(:rm_f).never
|
|
33
|
+
|
|
34
|
+
FileUtils.expects(:rm_rf).with(
|
|
35
|
+
File.join(Backup::Config.tmp_path, 'test_trigger')
|
|
36
|
+
)
|
|
37
|
+
Backup::Logger.expects(:warn).with do |err|
|
|
38
|
+
err.should be_an_instance_of Backup::Errors::CleanerError
|
|
39
|
+
err.message.should == "CleanerError: Cleanup Warning\n" +
|
|
40
|
+
" The temporary backup folder still contains files!\n" +
|
|
41
|
+
" '#{ File.join(Backup::Config.tmp_path, 'test_trigger') }'\n" +
|
|
42
|
+
" These files will now be removed.\n" +
|
|
43
|
+
" \n" + error_tail
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
cleaner.prepare(model)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
context 'when package files exist' do
|
|
51
|
+
it 'should remove the files and log a warning' do
|
|
52
|
+
cleaner.expects(:packaging_folder_dirty?).returns(false)
|
|
53
|
+
cleaner.expects(:tmp_path_package_files).returns(['file1', 'file2'])
|
|
54
|
+
FileUtils.expects(:rm_rf).never
|
|
55
|
+
|
|
56
|
+
FileUtils.expects(:rm_f).with('file1')
|
|
57
|
+
FileUtils.expects(:rm_f).with('file2')
|
|
58
|
+
|
|
59
|
+
Backup::Logger.expects(:warn).with do |err|
|
|
60
|
+
err.should be_an_instance_of Backup::Errors::CleanerError
|
|
61
|
+
err.message.should == "CleanerError: Cleanup Warning\n" +
|
|
62
|
+
" The temporary backup folder '#{ Backup::Config.tmp_path }'\n" +
|
|
63
|
+
" appears to contain the package files from the previous backup!\n" +
|
|
64
|
+
" file1\n" +
|
|
65
|
+
" file2\n" +
|
|
66
|
+
" These files will now be removed.\n" +
|
|
67
|
+
" \n" + error_tail
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
cleaner.prepare(model)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
context 'both the tmp_path is dirty and package files exist' do
|
|
75
|
+
it 'should clean both and log a warning' do
|
|
76
|
+
cleaner.expects(:packaging_folder_dirty?).returns(true)
|
|
77
|
+
cleaner.expects(:tmp_path_package_files).returns(['file1', 'file2'])
|
|
78
|
+
|
|
79
|
+
FileUtils.expects(:rm_rf).with(
|
|
80
|
+
File.join(Backup::Config.tmp_path, 'test_trigger')
|
|
81
|
+
)
|
|
82
|
+
FileUtils.expects(:rm_f).with('file1')
|
|
83
|
+
FileUtils.expects(:rm_f).with('file2')
|
|
84
|
+
|
|
85
|
+
Backup::Logger.expects(:warn).with do |err|
|
|
86
|
+
err.should be_an_instance_of Backup::Errors::CleanerError
|
|
87
|
+
err.message.should == "CleanerError: Cleanup Warning\n" +
|
|
88
|
+
" The temporary backup folder still contains files!\n" +
|
|
89
|
+
" '#{ File.join(Backup::Config.tmp_path, 'test_trigger') }'\n" +
|
|
90
|
+
" These files will now be removed.\n" +
|
|
91
|
+
" \n" +
|
|
92
|
+
" #{ '-' * 74 }\n" +
|
|
93
|
+
" The temporary backup folder '#{ Backup::Config.tmp_path }'\n" +
|
|
94
|
+
" appears to contain the package files from the previous backup!\n" +
|
|
95
|
+
" file1\n" +
|
|
96
|
+
" file2\n" +
|
|
97
|
+
" These files will now be removed.\n" +
|
|
98
|
+
" \n" + error_tail
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
cleaner.prepare(model)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
end # describe '#prepare'
|
|
106
|
+
|
|
107
|
+
describe '#remove_packaging' do
|
|
108
|
+
it 'should remove the packaging directory and log a message' do
|
|
109
|
+
Backup::Logger.expects(:message).with(
|
|
110
|
+
"Cleaning up the temporary files..."
|
|
111
|
+
)
|
|
112
|
+
FileUtils.expects(:rm_rf).with(
|
|
113
|
+
File.join(Backup::Config.tmp_path, 'test_trigger')
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
cleaner.remove_packaging(model)
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
describe '#remove_package' do
|
|
121
|
+
let(:package) { mock }
|
|
122
|
+
it 'should remove the files for the given package and log a message' do
|
|
123
|
+
package.expects(:filenames).returns(['file1', 'file2'])
|
|
124
|
+
Backup::Logger.expects(:message).with(
|
|
125
|
+
"Cleaning up the package files..."
|
|
126
|
+
)
|
|
127
|
+
FileUtils.expects(:rm_f).with(
|
|
128
|
+
File.join(Backup::Config.tmp_path, 'file1')
|
|
129
|
+
)
|
|
130
|
+
FileUtils.expects(:rm_f).with(
|
|
131
|
+
File.join(Backup::Config.tmp_path, 'file2')
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
cleaner.remove_package(package)
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
describe '#warnings' do
|
|
139
|
+
let(:error_tail) do
|
|
140
|
+
" Make sure you check these files before the next scheduled backup for\n" +
|
|
141
|
+
" 'test label (test_trigger)'\n" +
|
|
142
|
+
" These files will be removed at that time!"
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
context 'when neither the tmp_path is dirty or package files exist' do
|
|
146
|
+
it 'should do nothing' do
|
|
147
|
+
cleaner.expects(:packaging_folder_dirty?).returns(false)
|
|
148
|
+
cleaner.expects(:tmp_path_package_files).returns([])
|
|
149
|
+
Backup::Logger.expects(:warn).never
|
|
150
|
+
|
|
151
|
+
cleaner.warnings(model)
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
context 'when the tmp_path is dirty' do
|
|
156
|
+
it 'should remove tmp_path and log a warning' do
|
|
157
|
+
cleaner.expects(:packaging_folder_dirty?).returns(true)
|
|
158
|
+
cleaner.expects(:tmp_path_package_files).returns([])
|
|
159
|
+
|
|
160
|
+
Backup::Logger.expects(:warn).with do |err|
|
|
161
|
+
err.should be_an_instance_of Backup::Errors::CleanerError
|
|
162
|
+
err.message.should == "CleanerError: Cleanup Warning\n" +
|
|
163
|
+
" The temporary backup folder still contains files!\n" +
|
|
164
|
+
" '#{ File.join(Backup::Config.tmp_path, 'test_trigger') }'\n" +
|
|
165
|
+
" This folder may contain completed Archives and/or Database backups.\n" +
|
|
166
|
+
" \n" + error_tail
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
cleaner.warnings(model)
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
context 'when package files exist' do
|
|
174
|
+
it 'should remove the files and log a warning' do
|
|
175
|
+
cleaner.expects(:packaging_folder_dirty?).returns(false)
|
|
176
|
+
cleaner.expects(:tmp_path_package_files).returns(['file1', 'file2'])
|
|
177
|
+
|
|
178
|
+
Backup::Logger.expects(:warn).with do |err|
|
|
179
|
+
err.should be_an_instance_of Backup::Errors::CleanerError
|
|
180
|
+
err.message.should == "CleanerError: Cleanup Warning\n" +
|
|
181
|
+
" The temporary backup folder '#{ Backup::Config.tmp_path }'\n" +
|
|
182
|
+
" appears to contain the backup files which were to be stored:\n" +
|
|
183
|
+
" file1\n" +
|
|
184
|
+
" file2\n" +
|
|
185
|
+
" \n" + error_tail
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
cleaner.warnings(model)
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
context 'both the tmp_path is dirty and package files exist' do
|
|
193
|
+
it 'should clean both and log a warning' do
|
|
194
|
+
cleaner.expects(:packaging_folder_dirty?).returns(true)
|
|
195
|
+
cleaner.expects(:tmp_path_package_files).returns(['file1', 'file2'])
|
|
196
|
+
|
|
197
|
+
Backup::Logger.expects(:warn).with do |err|
|
|
198
|
+
err.should be_an_instance_of Backup::Errors::CleanerError
|
|
199
|
+
err.message.should == "CleanerError: Cleanup Warning\n" +
|
|
200
|
+
" The temporary backup folder still contains files!\n" +
|
|
201
|
+
" '#{ File.join(Backup::Config.tmp_path, 'test_trigger') }'\n" +
|
|
202
|
+
" This folder may contain completed Archives and/or Database backups.\n" +
|
|
203
|
+
" \n" +
|
|
204
|
+
" #{ '-' * 74 }\n" +
|
|
205
|
+
" The temporary backup folder '#{ Backup::Config.tmp_path }'\n" +
|
|
206
|
+
" appears to contain the backup files which were to be stored:\n" +
|
|
207
|
+
" file1\n" +
|
|
208
|
+
" file2\n" +
|
|
209
|
+
" \n" + error_tail
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
cleaner.warnings(model)
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
end # describe '#warnings'
|
|
217
|
+
|
|
218
|
+
describe '#packaging_folder_dirty?' do
|
|
219
|
+
before do
|
|
220
|
+
cleaner.instance_variable_set(:@model, model)
|
|
221
|
+
FileUtils.unstub(:mkdir_p)
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
context 'when files exist in the packaging folder' do
|
|
225
|
+
it 'should return true' do
|
|
226
|
+
Dir.mktmpdir do |path|
|
|
227
|
+
Backup::Config.update(:root_path => path)
|
|
228
|
+
FileUtils.mkdir_p(
|
|
229
|
+
File.join(Backup::Config.tmp_path, 'test_trigger', 'archives')
|
|
230
|
+
)
|
|
231
|
+
cleaner.send(:packaging_folder_dirty?).should be_true
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
context 'when files do not exist in the packaging folder' do
|
|
237
|
+
it 'should return false' do
|
|
238
|
+
Dir.mktmpdir do |path|
|
|
239
|
+
Backup::Config.update(:root_path => path)
|
|
240
|
+
FileUtils.mkdir_p(
|
|
241
|
+
File.join(Backup::Config.tmp_path, 'test_trigger')
|
|
242
|
+
)
|
|
243
|
+
cleaner.send(:packaging_folder_dirty?).should be_false
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
describe '#tmp_path_package_files' do
|
|
250
|
+
before do
|
|
251
|
+
cleaner.instance_variable_set(:@model, model)
|
|
252
|
+
FileUtils.unstub(:mkdir_p)
|
|
253
|
+
FileUtils.unstub(:touch)
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
context 'when packaging files exist in the tmp_path' do
|
|
257
|
+
it 'should return the files' do
|
|
258
|
+
Dir.mktmpdir do |path|
|
|
259
|
+
Backup::Config.update(:root_path => path)
|
|
260
|
+
FileUtils.mkdir_p(Backup::Config.tmp_path)
|
|
261
|
+
|
|
262
|
+
package_files = [
|
|
263
|
+
'2012.01.06.12.05.30.test_trigger.tar',
|
|
264
|
+
'2012.02.06.12.05.30.test_trigger.tar-aa',
|
|
265
|
+
'2012.03.06.12.05.30.test_trigger.tar.enc',
|
|
266
|
+
'2012.04.06.12.05.30.test_trigger.tar.enc-aa'
|
|
267
|
+
].map! {|f| File.join(Backup::Config.tmp_path, f) }
|
|
268
|
+
|
|
269
|
+
other_files = [
|
|
270
|
+
'2012.01.06.12.05.30.test_trigger.target.tar',
|
|
271
|
+
'2012.01.06.12.05.30.other_trigger.tar',
|
|
272
|
+
'foo.tar'
|
|
273
|
+
].map! {|f| File.join(Backup::Config.tmp_path, f) }
|
|
274
|
+
|
|
275
|
+
FileUtils.touch(package_files + other_files)
|
|
276
|
+
Dir[File.join(Backup::Config.tmp_path, '*')].count.should be(7)
|
|
277
|
+
|
|
278
|
+
cleaner.send(:tmp_path_package_files).sort.should == package_files
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
context 'when no packaging files exist in the tmp_path' do
|
|
284
|
+
it 'should return an empty array' do
|
|
285
|
+
Dir.mktmpdir do |path|
|
|
286
|
+
Backup::Config.update(:root_path => path)
|
|
287
|
+
FileUtils.mkdir_p(Backup::Config.tmp_path)
|
|
288
|
+
|
|
289
|
+
other_files = [
|
|
290
|
+
'2012.01.06.12.05.30.test_trigger.target.tar',
|
|
291
|
+
'2012.01.06.12.05.30.other_trigger.tar',
|
|
292
|
+
'foo.tar'
|
|
293
|
+
].map! {|f| File.join(Backup::Config.tmp_path, f) }
|
|
294
|
+
|
|
295
|
+
FileUtils.touch(other_files)
|
|
296
|
+
Dir[File.join(Backup::Config.tmp_path, '*')].count.should be(3)
|
|
297
|
+
|
|
298
|
+
cleaner.send(:tmp_path_package_files).should == []
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
end
|
data/spec/cli/helpers_spec.rb
CHANGED
|
@@ -3,7 +3,148 @@
|
|
|
3
3
|
require File.expand_path('../../spec_helper.rb', __FILE__)
|
|
4
4
|
|
|
5
5
|
describe Backup::CLI::Helpers do
|
|
6
|
-
let(:helpers) { Module.new.extend(
|
|
6
|
+
let(:helpers) { Module.new.extend(Backup::CLI::Helpers) }
|
|
7
|
+
|
|
8
|
+
describe '#run' do
|
|
9
|
+
let(:stdin) { mock }
|
|
10
|
+
let(:stdout) { mock }
|
|
11
|
+
let(:stderr) { mock }
|
|
12
|
+
let(:process_status) { mock }
|
|
13
|
+
|
|
14
|
+
it 'should run the given command using POpen4' do
|
|
15
|
+
Open4.expects(:popen4).with('/path/to/command args').
|
|
16
|
+
returns([123, stdin, stdout, stderr])
|
|
17
|
+
Process.expects(:waitpid2).with(123).returns([123, process_status])
|
|
18
|
+
stdout.expects(:read).returns('stdout message')
|
|
19
|
+
stderr.expects(:read).returns('stderr message')
|
|
20
|
+
|
|
21
|
+
helpers.expects(:command_name).with('/path/to/command args').
|
|
22
|
+
returns('command')
|
|
23
|
+
helpers.expects(:raise_if_command_failed!).with(
|
|
24
|
+
'command',
|
|
25
|
+
{:status => process_status,
|
|
26
|
+
:stdout => 'stdout message',
|
|
27
|
+
:stderr => 'stderr message',
|
|
28
|
+
:ignore_exit_codes => [0]}
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
helpers.run('/path/to/command args').should == 'stdout message'
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'should accept ignore_exit_codes and add 0 to the list' do
|
|
35
|
+
Open4.expects(:popen4).with('/path/to/command args').
|
|
36
|
+
returns([123, stdin, stdout, stderr])
|
|
37
|
+
Process.expects(:waitpid2).with(123).returns([123, process_status])
|
|
38
|
+
stdout.expects(:read).returns('stdout message')
|
|
39
|
+
stderr.expects(:read).returns('stderr message')
|
|
40
|
+
|
|
41
|
+
helpers.expects(:command_name).with('/path/to/command args').
|
|
42
|
+
returns('command')
|
|
43
|
+
helpers.expects(:raise_if_command_failed!).with(
|
|
44
|
+
'command',
|
|
45
|
+
{:status => process_status,
|
|
46
|
+
:stdout => 'stdout message',
|
|
47
|
+
:stderr => 'stderr message',
|
|
48
|
+
:ignore_exit_codes => [1, 2, 0]}
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
helpers.run(
|
|
52
|
+
'/path/to/command args', :ignore_exit_codes => [1, 2]
|
|
53
|
+
).should == 'stdout message'
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
describe '#utility' do
|
|
58
|
+
context 'when a system path for the utility is available' do
|
|
59
|
+
it 'should return the system path with newline removed' do
|
|
60
|
+
helpers.expects(:`).with('which foo 2>/dev/null').returns("system_path\n")
|
|
61
|
+
helpers.utility(:foo).should == 'system_path'
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it 'should cache the returned path' do
|
|
65
|
+
helpers.expects(:`).once.with('which cache_me 2>/dev/null').
|
|
66
|
+
returns("cached_path\n")
|
|
67
|
+
|
|
68
|
+
helpers.utility(:cache_me).should == 'cached_path'
|
|
69
|
+
helpers.utility(:cache_me).should == 'cached_path'
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it 'should cache the value for all extended objects' do
|
|
73
|
+
helpers.expects(:`).once.with('which once_only 2>/dev/null').
|
|
74
|
+
returns("cached_path\n")
|
|
75
|
+
|
|
76
|
+
helpers.utility(:once_only).should == 'cached_path'
|
|
77
|
+
Class.new.extend(Backup::CLI::Helpers).utility(:once_only).
|
|
78
|
+
should == 'cached_path'
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
context 'when a system path for the utility is not available' do
|
|
84
|
+
it 'should raise an error' do
|
|
85
|
+
helpers.expects(:`).with('which unknown 2>/dev/null').returns("\n")
|
|
86
|
+
|
|
87
|
+
expect do
|
|
88
|
+
helpers.utility(:unknown)
|
|
89
|
+
end.to raise_error(Backup::Errors::CLI::UtilityNotFoundError) {|err|
|
|
90
|
+
err.message.should match(/Path to 'unknown' could not be found/)
|
|
91
|
+
}
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it 'should not cache any value for the utility' do
|
|
95
|
+
helpers.expects(:`).with('which not_cached 2>/dev/null').twice.returns("\n")
|
|
96
|
+
|
|
97
|
+
expect do
|
|
98
|
+
helpers.utility(:not_cached)
|
|
99
|
+
end.to raise_error(Backup::Errors::CLI::UtilityNotFoundError) {|err|
|
|
100
|
+
err.message.should match(/Path to 'not_cached' could not be found/)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
expect do
|
|
104
|
+
helpers.utility(:not_cached)
|
|
105
|
+
end.to raise_error(Backup::Errors::CLI::UtilityNotFoundError) {|err|
|
|
106
|
+
err.message.should match(/Path to 'not_cached' could not be found/)
|
|
107
|
+
}
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end # describe '#utility'
|
|
111
|
+
|
|
112
|
+
describe '#command_name' do
|
|
113
|
+
context 'given a command line path with no arguments' do
|
|
114
|
+
it 'should return the base command name' do
|
|
115
|
+
cmd = '/path/to/a/command'
|
|
116
|
+
helpers.command_name(cmd).should == 'command'
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
context 'given a command line path with a single argument' do
|
|
121
|
+
it 'should return the base command name' do
|
|
122
|
+
cmd = '/path/to/a/command with_args'
|
|
123
|
+
helpers.command_name(cmd).should == 'command'
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
context 'given a command line path with multiple arguments' do
|
|
128
|
+
it 'should return the base command name' do
|
|
129
|
+
cmd = '/path/to/a/command with multiple args'
|
|
130
|
+
helpers.command_name(cmd).should == 'command'
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
context 'given a command with no path and arguments' do
|
|
135
|
+
it 'should return the base command name' do
|
|
136
|
+
cmd = 'command args'
|
|
137
|
+
helpers.command_name(cmd).should == 'command'
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
context 'given a command with no path and no arguments' do
|
|
142
|
+
it 'should return the base command name' do
|
|
143
|
+
cmd = 'command'
|
|
144
|
+
helpers.command_name(cmd).should == 'command'
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end # describe '#command_name'
|
|
7
148
|
|
|
8
149
|
describe '#raise_if_command_failed!' do
|
|
9
150
|
|