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,61 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require File.expand_path('../spec_helper.rb', __FILE__)
|
|
4
|
+
|
|
5
|
+
describe Backup::Package do
|
|
6
|
+
let(:model) { Backup::Model.new(:test_trigger, 'test label') }
|
|
7
|
+
let(:package) { Backup::Package.new(model) }
|
|
8
|
+
|
|
9
|
+
before do
|
|
10
|
+
model.instance_variable_set(:@time, 'model_time')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe '#initialize' do
|
|
14
|
+
it 'should set all variables' do
|
|
15
|
+
package.time.should == 'model_time'
|
|
16
|
+
package.trigger.should == 'test_trigger'
|
|
17
|
+
package.extension.should == 'tar'
|
|
18
|
+
package.chunk_suffixes.should == []
|
|
19
|
+
package.version.should == Backup::Version.current
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe '#filenames' do
|
|
24
|
+
context 'when the package files were not split' do
|
|
25
|
+
it 'should return an array with the single package filename' do
|
|
26
|
+
package.filenames.should == ['model_time.test_trigger.tar']
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'should reflect changes in the extension' do
|
|
30
|
+
package.extension << '.enc'
|
|
31
|
+
package.filenames.should == ['model_time.test_trigger.tar.enc']
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
context 'when the package files were split' do
|
|
36
|
+
before { package.chunk_suffixes = ['aa', 'ab'] }
|
|
37
|
+
it 'should return an array of the package filenames' do
|
|
38
|
+
package.filenames.should == ['model_time.test_trigger.tar-aa',
|
|
39
|
+
'model_time.test_trigger.tar-ab']
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'should reflect changes in the extension' do
|
|
43
|
+
package.extension << '.enc'
|
|
44
|
+
package.filenames.should == ['model_time.test_trigger.tar.enc-aa',
|
|
45
|
+
'model_time.test_trigger.tar.enc-ab']
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
describe '#basename' do
|
|
51
|
+
it 'should return the base filename for the package' do
|
|
52
|
+
package.basename.should == 'model_time.test_trigger.tar'
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'should reflect changes in the extension' do
|
|
56
|
+
package.extension << '.enc'
|
|
57
|
+
package.basename.should == 'model_time.test_trigger.tar.enc'
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
end
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require File.expand_path('../spec_helper.rb', __FILE__)
|
|
4
|
+
|
|
5
|
+
describe 'Backup::Packager' do
|
|
6
|
+
let(:packager) { Backup::Packager }
|
|
7
|
+
|
|
8
|
+
describe '#package!' do
|
|
9
|
+
let(:model) { mock }
|
|
10
|
+
let(:package) { mock }
|
|
11
|
+
let(:encryptor) { mock }
|
|
12
|
+
let(:splitter) { mock }
|
|
13
|
+
let(:procedure) { mock }
|
|
14
|
+
let(:s) { sequence '' }
|
|
15
|
+
|
|
16
|
+
it 'should setup variables and perform packaging procedures' do
|
|
17
|
+
model.expects(:package).in_sequence(s).returns(package)
|
|
18
|
+
model.expects(:encryptor).in_sequence(s).returns(encryptor)
|
|
19
|
+
model.expects(:splitter).in_sequence(s).returns(splitter)
|
|
20
|
+
|
|
21
|
+
Backup::Logger.expects(:message).in_sequence(s).with(
|
|
22
|
+
'Packaging the backup files...'
|
|
23
|
+
)
|
|
24
|
+
packager.expects(:procedure).in_sequence(s).returns(procedure)
|
|
25
|
+
procedure.expects(:call).in_sequence(s)
|
|
26
|
+
Backup::Logger.expects(:message).in_sequence(s).with(
|
|
27
|
+
'Packaging Complete!'
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
packager.package!(model)
|
|
31
|
+
|
|
32
|
+
packager.instance_variable_get(:@package).should be(package)
|
|
33
|
+
packager.instance_variable_get(:@encryptor).should be(encryptor)
|
|
34
|
+
packager.instance_variable_get(:@splitter).should be(splitter)
|
|
35
|
+
end
|
|
36
|
+
end # describe '#package!'
|
|
37
|
+
|
|
38
|
+
describe '#procedure' do
|
|
39
|
+
|
|
40
|
+
module Fake
|
|
41
|
+
def self.stack_trace
|
|
42
|
+
@stack ||= []
|
|
43
|
+
end
|
|
44
|
+
class Encryptor
|
|
45
|
+
def encrypt_with
|
|
46
|
+
Fake.stack_trace << :encryptor_before
|
|
47
|
+
yield 'encryption_command', '.enc'
|
|
48
|
+
Fake.stack_trace << :encryptor_after
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
class Splitter
|
|
52
|
+
def split_with
|
|
53
|
+
Fake.stack_trace << :splitter_before
|
|
54
|
+
yield 'splitter_command'
|
|
55
|
+
Fake.stack_trace << :splitter_after
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
class Package
|
|
59
|
+
attr_accessor :trigger, :extension
|
|
60
|
+
def basename
|
|
61
|
+
'base_filename.' + extension
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
let(:package) { Fake::Package.new }
|
|
67
|
+
let(:encryptor) { Fake::Encryptor.new }
|
|
68
|
+
let(:splitter) { Fake::Splitter.new }
|
|
69
|
+
|
|
70
|
+
before do
|
|
71
|
+
Fake.stack_trace.clear
|
|
72
|
+
packager.expects(:utility).with(:tar).returns('tar')
|
|
73
|
+
packager.instance_variable_set(:@package, package)
|
|
74
|
+
package.trigger = 'model_trigger'
|
|
75
|
+
package.extension = 'tar'
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
context 'when no encryptor or splitter are defined' do
|
|
79
|
+
it 'should package the backup without encryption into a single file' do
|
|
80
|
+
packager.instance_variable_set(:@encryptor, nil)
|
|
81
|
+
packager.instance_variable_set(:@splitter, nil)
|
|
82
|
+
|
|
83
|
+
packager.expects(:run).with(
|
|
84
|
+
"tar -cf - -C '#{ Backup::Config.tmp_path }' 'model_trigger'" +
|
|
85
|
+
" > #{ File.join(Backup::Config.tmp_path, 'base_filename.tar') }"
|
|
86
|
+
)
|
|
87
|
+
packager.send(:procedure).call
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
context 'when only an encryptor is configured' do
|
|
92
|
+
it 'should package the backup with encryption' do
|
|
93
|
+
packager.instance_variable_set(:@encryptor, encryptor)
|
|
94
|
+
packager.instance_variable_set(:@splitter, nil)
|
|
95
|
+
|
|
96
|
+
packager.expects(:run).with do |command|
|
|
97
|
+
Fake.stack_trace << :command_executed
|
|
98
|
+
command.should ==
|
|
99
|
+
"tar -cf - -C '#{ Backup::Config.tmp_path }' 'model_trigger'" +
|
|
100
|
+
" | encryption_command" +
|
|
101
|
+
" > #{ File.join(Backup::Config.tmp_path, 'base_filename.tar.enc') }"
|
|
102
|
+
end
|
|
103
|
+
packager.send(:procedure).call
|
|
104
|
+
|
|
105
|
+
Fake.stack_trace.should == [
|
|
106
|
+
:encryptor_before, :command_executed, :encryptor_after
|
|
107
|
+
]
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
context 'when only a splitter is configured' do
|
|
112
|
+
it 'should package the backup without encryption through the splitter' do
|
|
113
|
+
packager.instance_variable_set(:@encryptor, nil)
|
|
114
|
+
packager.instance_variable_set(:@splitter, splitter)
|
|
115
|
+
|
|
116
|
+
packager.expects(:run).with do |command|
|
|
117
|
+
Fake.stack_trace << :command_executed
|
|
118
|
+
command.should ==
|
|
119
|
+
"tar -cf - -C '#{ Backup::Config.tmp_path }' 'model_trigger'" +
|
|
120
|
+
" | splitter_command"
|
|
121
|
+
end
|
|
122
|
+
packager.send(:procedure).call
|
|
123
|
+
|
|
124
|
+
Fake.stack_trace.should == [
|
|
125
|
+
:splitter_before, :command_executed, :splitter_after
|
|
126
|
+
]
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
context 'when both an encryptor and a splitter are configured' do
|
|
131
|
+
it 'should package the backup with encryption through the splitter' do
|
|
132
|
+
packager.instance_variable_set(:@encryptor, encryptor)
|
|
133
|
+
packager.instance_variable_set(:@splitter, splitter)
|
|
134
|
+
|
|
135
|
+
packager.expects(:run).with do |command|
|
|
136
|
+
Fake.stack_trace << :command_executed
|
|
137
|
+
command.should ==
|
|
138
|
+
"tar -cf - -C '#{ Backup::Config.tmp_path }' 'model_trigger'" +
|
|
139
|
+
" | encryption_command | splitter_command"
|
|
140
|
+
end
|
|
141
|
+
packager.send(:procedure).call
|
|
142
|
+
|
|
143
|
+
Fake.stack_trace.should == [
|
|
144
|
+
:encryptor_before, :splitter_before,
|
|
145
|
+
:command_executed,
|
|
146
|
+
:splitter_after, :encryptor_after
|
|
147
|
+
]
|
|
148
|
+
package.extension.should == 'tar.enc'
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
end # describe '#procedure'
|
|
153
|
+
|
|
154
|
+
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -9,28 +9,51 @@ require 'bundler/setup'
|
|
|
9
9
|
# Load Backup
|
|
10
10
|
require 'backup'
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
require 'timecop'
|
|
13
|
+
|
|
14
|
+
module Backup::ExampleHelpers
|
|
15
|
+
# ripped from MiniTest :)
|
|
16
|
+
# RSpec doesn't have a method for this? Am I missing something?
|
|
17
|
+
def capture_io
|
|
18
|
+
require 'stringio'
|
|
19
|
+
|
|
20
|
+
orig_stdout, orig_stderr = $stdout, $stderr
|
|
21
|
+
captured_stdout, captured_stderr = StringIO.new, StringIO.new
|
|
22
|
+
$stdout, $stderr = captured_stdout, captured_stderr
|
|
23
|
+
|
|
24
|
+
yield
|
|
25
|
+
|
|
26
|
+
return captured_stdout.string, captured_stderr.string
|
|
27
|
+
ensure
|
|
28
|
+
$stdout = orig_stdout
|
|
29
|
+
$stderr = orig_stderr
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
require 'rspec/autorun'
|
|
15
34
|
RSpec.configure do |config|
|
|
35
|
+
##
|
|
36
|
+
# Use Mocha to mock with RSpec
|
|
16
37
|
config.mock_with :mocha
|
|
38
|
+
|
|
39
|
+
##
|
|
40
|
+
# Example Helpers
|
|
41
|
+
config.include Backup::ExampleHelpers
|
|
42
|
+
|
|
43
|
+
##
|
|
44
|
+
# Actions to perform before each example
|
|
17
45
|
config.before(:each) do
|
|
18
|
-
FileUtils.
|
|
46
|
+
FileUtils.collect_method(:noop).each do |method|
|
|
47
|
+
FileUtils.stubs(method).raises("Unexpected call to FileUtils.#{method}")
|
|
48
|
+
end
|
|
49
|
+
Open4.stubs(:popen4).raises('Unexpected call to CLI::Helpers.run()')
|
|
50
|
+
|
|
19
51
|
[:message, :error, :warn, :normal, :silent].each do |message_type|
|
|
20
52
|
Backup::Logger.stubs(message_type)
|
|
21
53
|
end
|
|
22
|
-
Backup::Model.extension = 'tar'
|
|
23
54
|
end
|
|
24
55
|
end
|
|
25
56
|
|
|
26
|
-
Backup.send(:remove_const, :TRIGGER) if defined? Backup::TRIGGER
|
|
27
|
-
Backup.send(:remove_const, :TIME) if defined? Backup::TIME
|
|
28
|
-
|
|
29
|
-
module Backup
|
|
30
|
-
TRIGGER = 'myapp'
|
|
31
|
-
TIME = Time.now.strftime("%Y.%m.%d.%H.%M.%S")
|
|
32
|
-
end
|
|
33
|
-
|
|
34
57
|
unless @_put_ruby_version
|
|
35
58
|
puts @_put_ruby_version = "\n\nRuby version: #{RUBY_DESCRIPTION}\n\n"
|
|
36
59
|
end
|
data/spec/splitter_spec.rb
CHANGED
|
@@ -3,69 +3,118 @@
|
|
|
3
3
|
require File.expand_path('../spec_helper.rb', __FILE__)
|
|
4
4
|
|
|
5
5
|
describe Backup::Splitter do
|
|
6
|
-
let(:model)
|
|
7
|
-
let(:splitter) { Backup::Splitter.new(model) }
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
])
|
|
6
|
+
let(:model) { Backup::Model.new(:test_trigger, 'test label') }
|
|
7
|
+
let(:splitter) { Backup::Splitter.new(model, 250) }
|
|
8
|
+
let(:package) { mock }
|
|
9
|
+
|
|
10
|
+
describe '#initialize' do
|
|
11
|
+
it 'should set instance variables' do
|
|
12
|
+
splitter.instance_variable_get(:@model).should be(model)
|
|
13
|
+
splitter.instance_variable_get(:@chunk_size).should be(250)
|
|
14
|
+
end
|
|
16
15
|
end
|
|
17
16
|
|
|
18
|
-
describe
|
|
19
|
-
it
|
|
20
|
-
|
|
17
|
+
describe '#split_with' do
|
|
18
|
+
it 'should yield the split command, performing before/after methods' do
|
|
19
|
+
s = sequence ''
|
|
20
|
+
given_block = mock
|
|
21
|
+
block = lambda {|arg| given_block.got(arg) }
|
|
22
|
+
splitter.instance_variable_set(:@split_command, 'split command')
|
|
23
|
+
|
|
24
|
+
splitter.expects(:before_packaging).in_sequence(s)
|
|
25
|
+
given_block.expects(:got).in_sequence(s).with('split command')
|
|
26
|
+
splitter.expects(:after_packaging).in_sequence(s)
|
|
27
|
+
|
|
28
|
+
splitter.split_with(&block)
|
|
21
29
|
end
|
|
22
30
|
end
|
|
23
31
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
32
|
+
# Note: using a 'M' suffix for the byte size is not OSX compatible
|
|
33
|
+
describe '#before_packaging' do
|
|
34
|
+
before do
|
|
35
|
+
model.instance_variable_set(:@package, package)
|
|
36
|
+
splitter.expects(:utility).with(:split).returns('split')
|
|
37
|
+
package.expects(:basename).returns('base_filename')
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'should set @package and @split_command' do
|
|
41
|
+
Backup::Logger.expects(:message).with(
|
|
42
|
+
'Splitter configured with a chunk size of 250MB.'
|
|
43
|
+
)
|
|
44
|
+
splitter.send(:before_packaging)
|
|
45
|
+
|
|
46
|
+
splitter.instance_variable_get(:@package).should be(package)
|
|
47
|
+
|
|
48
|
+
split_suffix = File.join(Backup::Config.tmp_path, 'base_filename-')
|
|
49
|
+
splitter.instance_variable_get(:@split_command).should ==
|
|
50
|
+
"split -b 250m - '#{ split_suffix }'"
|
|
27
51
|
end
|
|
28
52
|
end
|
|
29
53
|
|
|
30
|
-
describe
|
|
54
|
+
describe '#after_packaging' do
|
|
31
55
|
before do
|
|
32
|
-
|
|
56
|
+
splitter.instance_variable_set(:@package, package)
|
|
33
57
|
end
|
|
34
58
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
59
|
+
context 'when splitting occurred during packaging' do
|
|
60
|
+
before do
|
|
61
|
+
splitter.expects(:chunk_suffixes).returns(['aa', 'ab'])
|
|
62
|
+
end
|
|
38
63
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
splitter.
|
|
42
|
-
splitter.split!
|
|
64
|
+
it 'should set the chunk_suffixes for the package' do
|
|
65
|
+
package.expects(:chunk_suffixes=).with(['aa', 'ab'])
|
|
66
|
+
splitter.send(:after_packaging)
|
|
43
67
|
end
|
|
44
68
|
end
|
|
45
69
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
70
|
+
context 'when splitting did not occur during packaging' do
|
|
71
|
+
before do
|
|
72
|
+
splitter.expects(:chunk_suffixes).returns(['aa'])
|
|
73
|
+
package.expects(:basename).twice.returns('base_filename')
|
|
74
|
+
end
|
|
49
75
|
|
|
50
|
-
|
|
51
|
-
|
|
76
|
+
it 'should remove the suffix from the only package file' do
|
|
77
|
+
package.expects(:chunk_suffixes=).never
|
|
78
|
+
FileUtils.expects(:mv).with(
|
|
79
|
+
File.join(Backup::Config.tmp_path, 'base_filename-aa'),
|
|
80
|
+
File.join(Backup::Config.tmp_path, 'base_filename')
|
|
81
|
+
)
|
|
82
|
+
splitter.send(:after_packaging)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end # describe '#after_packaging'
|
|
86
|
+
|
|
87
|
+
describe '#chunk_suffixes' do
|
|
88
|
+
before do
|
|
89
|
+
splitter.expects(:chunks).returns(
|
|
90
|
+
['/path/to/file.tar-aa', '/path/to/file.tar-ab']
|
|
91
|
+
)
|
|
52
92
|
end
|
|
53
93
|
|
|
54
|
-
it
|
|
55
|
-
|
|
56
|
-
|
|
94
|
+
it 'should return an array of chunk suffixes' do
|
|
95
|
+
splitter.send(:chunk_suffixes).should == ['aa', 'ab']
|
|
96
|
+
end
|
|
97
|
+
end
|
|
57
98
|
|
|
58
|
-
|
|
59
|
-
|
|
99
|
+
describe '#chunks' do
|
|
100
|
+
before do
|
|
101
|
+
splitter.instance_variable_set(:@package, package)
|
|
102
|
+
package.expects(:basename).returns('base_filename')
|
|
103
|
+
FileUtils.unstub(:touch)
|
|
60
104
|
end
|
|
61
105
|
|
|
62
|
-
it
|
|
63
|
-
|
|
64
|
-
|
|
106
|
+
it 'should return a sorted array of chunked file paths' do
|
|
107
|
+
Dir.mktmpdir do |dir|
|
|
108
|
+
Backup::Config.expects(:tmp_path).returns(dir)
|
|
109
|
+
FileUtils.touch(File.join(dir, 'base_filename-aa'))
|
|
110
|
+
FileUtils.touch(File.join(dir, 'base_filename-ab'))
|
|
65
111
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
112
|
+
splitter.send(:chunks).should == [
|
|
113
|
+
File.join(dir, 'base_filename-aa'),
|
|
114
|
+
File.join(dir, 'base_filename-ab')
|
|
115
|
+
]
|
|
116
|
+
end
|
|
69
117
|
end
|
|
70
118
|
end
|
|
119
|
+
|
|
71
120
|
end
|
data/spec/storage/base_spec.rb
CHANGED
|
@@ -3,288 +3,144 @@
|
|
|
3
3
|
require File.expand_path('../../spec_helper.rb', __FILE__)
|
|
4
4
|
|
|
5
5
|
describe Backup::Storage::Base do
|
|
6
|
+
let(:model) { Backup::Model.new(:test_trigger, 'test label') }
|
|
7
|
+
let(:package) { mock }
|
|
8
|
+
let(:base) { Backup::Storage::Base.new(model) }
|
|
6
9
|
|
|
7
10
|
describe '#initialize' do
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
it 'should create a new storage object with default values' do
|
|
14
|
-
base = Backup::Storage::Base.new
|
|
11
|
+
it 'should set instance variables' do
|
|
12
|
+
base.instance_variable_get(:@model).should be(model)
|
|
13
|
+
base.instance_variable_defined?(:@storage_id).should be_true
|
|
14
|
+
base.instance_variable_get(:@storage_id).should be_nil
|
|
15
15
|
base.keep.should be_nil
|
|
16
|
-
base.time.should == Backup::TIME
|
|
17
16
|
end
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
base
|
|
18
|
+
context 'when given a storage_id' do
|
|
19
|
+
it 'should set @storage_id' do
|
|
20
|
+
base = Backup::Storage::Base.new(model, 'my storage id')
|
|
21
|
+
base.instance_variable_get(:@storage_id).should == 'my storage id'
|
|
22
22
|
end
|
|
23
|
-
|
|
24
|
-
base = Backup::Storage::Base.new
|
|
25
|
-
base.keep.should == 5
|
|
26
|
-
base.time.should == Backup::TIME
|
|
27
23
|
end
|
|
28
24
|
|
|
29
|
-
|
|
30
|
-
Backup::Configuration::Storage::Base.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
base
|
|
25
|
+
context 'when configuration defaults are set' do
|
|
26
|
+
after { Backup::Configuration::Storage::Base.clear_defaults! }
|
|
27
|
+
it 'should use the defaults' do
|
|
28
|
+
Backup::Configuration::Storage::Base.defaults do |base|
|
|
29
|
+
base.keep = 5
|
|
30
|
+
end
|
|
31
|
+
base = Backup::Storage::Base.new(model)
|
|
32
|
+
base.keep.should be(5)
|
|
36
33
|
end
|
|
37
|
-
base.keep.should == 10
|
|
38
|
-
base.time.should == Backup::TIME
|
|
39
34
|
end
|
|
35
|
+
end # describe '#initialize'
|
|
40
36
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
37
|
+
describe '#perform!' do
|
|
38
|
+
before do
|
|
39
|
+
model.instance_variable_set(:@package, package)
|
|
40
|
+
end
|
|
44
41
|
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
it 'should call #transfer!, then #cycle!' do
|
|
43
|
+
s = sequence ''
|
|
44
|
+
base.expects(:transfer!).in_sequence(s)
|
|
45
|
+
base.expects(:cycle!).in_sequence(s)
|
|
46
|
+
base.perform!
|
|
47
|
+
base.instance_variable_get(:@package).should be(package)
|
|
47
48
|
end
|
|
49
|
+
end
|
|
48
50
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
describe '#storage_name' do
|
|
52
|
+
context 'when given a storage_id' do
|
|
53
|
+
before { base.storage_id = 'storage id' }
|
|
54
|
+
it 'should return a log-friendly name with the storage_id' do
|
|
55
|
+
base.send(:storage_name).should == 'Storage::Base (storage id)'
|
|
52
56
|
end
|
|
53
|
-
base.keep.should == 10
|
|
54
|
-
base.time.should == Backup::TIME
|
|
55
|
-
base.storage_id.should == 'my storage_id'
|
|
56
57
|
end
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
context 'when clearing instance variables for cycling' do
|
|
63
|
-
it 'version stamps the object' do
|
|
64
|
-
cycle_required_variables = %w[ @filename @time @chunk_suffixes ]
|
|
65
|
-
expected_variables = (cycle_required_variables + ['@version']).sort
|
|
66
|
-
|
|
67
|
-
base = Backup::Storage::Base.new do |config|
|
|
68
|
-
config.storage_id = 'bar_id'
|
|
69
|
-
config.keep = 3
|
|
70
|
-
end
|
|
71
|
-
base.time = Time.utc(2011, 12, 2)
|
|
72
|
-
base.chunk_suffixes = ['aa', 'ab']
|
|
73
|
-
base.instance_variable_set(:@filename, 'foo.tar')
|
|
74
|
-
base.version.should be_nil
|
|
75
|
-
|
|
76
|
-
base.send(:clean!)
|
|
77
|
-
base.instance_variables.map(&:to_s).sort.should == expected_variables
|
|
78
|
-
base.time.should == Time.utc(2011, 12, 2)
|
|
79
|
-
base.chunk_suffixes.should == ['aa', 'ab']
|
|
80
|
-
base.filename.should == 'foo.tar'
|
|
81
|
-
base.version.should == Backup::Version.current
|
|
59
|
+
context 'when not given a storage_id' do
|
|
60
|
+
it 'should return a log-friendly name without a storage_id' do
|
|
61
|
+
base.send(:storage_name).should == 'Storage::Base'
|
|
82
62
|
end
|
|
83
63
|
end
|
|
84
|
-
|
|
85
64
|
end
|
|
86
65
|
|
|
87
|
-
describe '#
|
|
66
|
+
describe '#local_path' do
|
|
67
|
+
it 'should return the configured tmp_path' do
|
|
68
|
+
base.send(:local_path).should == Backup::Config.tmp_path
|
|
69
|
+
end
|
|
70
|
+
end
|
|
88
71
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
config.storage_id = 'bar_id'
|
|
96
|
-
config.keep = 3
|
|
97
|
-
end
|
|
98
|
-
base_b.expects(:upgrade_if_needed!)
|
|
72
|
+
describe '#remote_path_for' do
|
|
73
|
+
before do
|
|
74
|
+
package.expects(:trigger).returns('test_trigger')
|
|
75
|
+
package.expects(:time).returns('backup_time')
|
|
76
|
+
base.expects(:path).returns('base/remote/path')
|
|
77
|
+
end
|
|
99
78
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
79
|
+
it 'should return the remote_path for the given package' do
|
|
80
|
+
base.send(:remote_path_for, package).should ==
|
|
81
|
+
File.join('base/remote/path', 'test_trigger', 'backup_time')
|
|
103
82
|
end
|
|
83
|
+
end
|
|
104
84
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
85
|
+
describe '#files_to_transfer_for' do
|
|
86
|
+
let(:given_block) { mock }
|
|
87
|
+
before do
|
|
88
|
+
package.stubs(:filenames).returns(
|
|
89
|
+
['2011.12.31.11.00.02.backup.tar.enc-aa',
|
|
90
|
+
'2011.12.31.11.00.02.backup.tar.enc-ab']
|
|
91
|
+
)
|
|
92
|
+
end
|
|
111
93
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
94
|
+
it 'should yield the full filename and the filename without the timestamp' do
|
|
95
|
+
given_block.expects(:got).with(
|
|
96
|
+
'2011.12.31.11.00.02.backup.tar.enc-aa', 'backup.tar.enc-aa'
|
|
97
|
+
)
|
|
98
|
+
given_block.expects(:got).with(
|
|
99
|
+
'2011.12.31.11.00.02.backup.tar.enc-ab', 'backup.tar.enc-ab'
|
|
100
|
+
)
|
|
101
|
+
base.send(:files_to_transfer_for, package) do |local_file, remote_file|
|
|
102
|
+
given_block.got(local_file, remote_file)
|
|
115
103
|
end
|
|
116
|
-
loaded.time = Time.utc(2011, 12, 2)
|
|
117
|
-
loaded.chunk_suffixes = ['aa', 'ab']
|
|
118
|
-
loaded.instance_variable_set(:@filename, 'foo.tar')
|
|
119
|
-
|
|
120
|
-
loaded.send(:clean!)
|
|
121
|
-
loaded.storage_id.should == nil
|
|
122
|
-
loaded.keep.should == nil
|
|
123
|
-
loaded.version.should == Backup::Version.current
|
|
124
|
-
|
|
125
|
-
loaded.send(:update!, base.configure_block)
|
|
126
|
-
loaded.storage_id.should == 'foo_id'
|
|
127
|
-
loaded.keep.should == 5
|
|
128
|
-
loaded.time.should == Time.utc(2011, 12, 2)
|
|
129
|
-
loaded.chunk_suffixes.should == ['aa', 'ab']
|
|
130
|
-
loaded.filename.should == 'foo.tar'
|
|
131
|
-
loaded.version.should == Backup::Version.current
|
|
132
104
|
end
|
|
133
105
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
it 'upgrades <= 3.0.19' do
|
|
139
|
-
v_3_0_19_yaml = <<-EOF.gsub(/^\s+/,' ').gsub(/^ -/,'-')
|
|
140
|
-
---
|
|
141
|
-
!ruby/object:Backup::Storage::SCP
|
|
142
|
-
username: a_user
|
|
143
|
-
password: a_password
|
|
144
|
-
ip: an_address
|
|
145
|
-
port: a_port
|
|
146
|
-
path: a_path
|
|
147
|
-
keep: a_few
|
|
148
|
-
time: 2011.11.01.01.02.03
|
|
149
|
-
local_file: 2011.11.01.01.02.03.a_backup.tar
|
|
150
|
-
remote_file: 2011.11.01.01.02.03.a_backup.tar
|
|
151
|
-
EOF
|
|
152
|
-
loaded = YAML.load(v_3_0_19_yaml)
|
|
153
|
-
cycle_required_variables = %w[ @filename @time @chunk_suffixes ]
|
|
154
|
-
expected_variables = (cycle_required_variables + ['@version']).sort
|
|
155
|
-
|
|
156
|
-
loaded.send(:upgrade_if_needed!)
|
|
157
|
-
loaded.instance_variables.map(&:to_s).sort.should == expected_variables
|
|
158
|
-
loaded.filename.should == '2011.11.01.01.02.03.a_backup.tar'
|
|
159
|
-
loaded.time.should == '2011.11.01.01.02.03'
|
|
160
|
-
loaded.chunk_suffixes.should == []
|
|
161
|
-
loaded.version.should == Backup::Version.current
|
|
106
|
+
it 'should have an alias method called #transferred_files_for' do
|
|
107
|
+
base.method(:transferred_files_for).should ==
|
|
108
|
+
base.method(:files_to_transfer_for)
|
|
162
109
|
end
|
|
163
|
-
|
|
164
|
-
end # describe '#upgrade_if_needed!'
|
|
110
|
+
end
|
|
165
111
|
|
|
166
112
|
describe '#cycle!' do
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
s = sequence ''
|
|
171
|
-
storage_object = mock
|
|
172
|
-
loaded_object = mock
|
|
173
|
-
|
|
174
|
-
Backup::Storage::Object.expects(:new).in_sequence(s).
|
|
175
|
-
with('Base', nil).returns(storage_object)
|
|
176
|
-
storage_object.expects(:load).in_sequence(s).
|
|
177
|
-
returns([loaded_object])
|
|
178
|
-
loaded_object.expects(:update!).in_sequence(s).
|
|
179
|
-
with(base.configure_block)
|
|
180
|
-
objects = [base, loaded_object]
|
|
181
|
-
objects.each {|object| object.expects(:clean!).in_sequence(s) }
|
|
182
|
-
storage_object.expects(:write).in_sequence(s).
|
|
183
|
-
with(objects)
|
|
184
|
-
|
|
185
|
-
base.keep = 2
|
|
186
|
-
base.send(:cycle!)
|
|
113
|
+
before do
|
|
114
|
+
base.stubs(:storage_name).returns('Storage Name')
|
|
115
|
+
base.instance_variable_set(:@package, package)
|
|
187
116
|
end
|
|
188
117
|
|
|
189
|
-
context 'when
|
|
190
|
-
|
|
191
|
-
it 'should
|
|
192
|
-
num_to_load = 6
|
|
193
|
-
num_to_keep = 3
|
|
194
|
-
obj_to_fail = 2 # we're removing 3, so fail the 2nd one.
|
|
195
|
-
|
|
118
|
+
context 'when keep is set and > 0' do
|
|
119
|
+
before { base.keep = 1 }
|
|
120
|
+
it 'should cycle' do
|
|
196
121
|
s = sequence ''
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
loaded_object#{n}.stubs(:filename).returns("file#{n}")
|
|
204
|
-
loaded_objects << loaded_object#{n}
|
|
205
|
-
EOS
|
|
206
|
-
end
|
|
122
|
+
Backup::Logger.expects(:message).in_sequence(s).
|
|
123
|
+
with('Storage Name: Cycling Started...')
|
|
124
|
+
Backup::Storage::Cycler.expects(:cycle!).in_sequence(s).
|
|
125
|
+
with(base, package)
|
|
126
|
+
Backup::Logger.expects(:message).in_sequence(s).
|
|
127
|
+
with('Storage Name: Cycling Complete!')
|
|
207
128
|
|
|
208
|
-
Backup::Storage::Object.expects(:new).in_sequence(s).
|
|
209
|
-
with('Base', nil).returns(storage_object)
|
|
210
|
-
storage_object.expects(:load).in_sequence(s).
|
|
211
|
-
returns(loaded_objects)
|
|
212
|
-
loaded_objects.each do |loaded_object|
|
|
213
|
-
loaded_object.expects(:update!).in_sequence(s).
|
|
214
|
-
with(base.configure_block)
|
|
215
|
-
end
|
|
216
|
-
objects = [base] + loaded_objects
|
|
217
|
-
|
|
218
|
-
objects_to_remove = objects[num_to_keep..-1]
|
|
219
|
-
objects_to_remove.each_with_index do |object_to_remove, i|
|
|
220
|
-
Backup::Logger.expects(:message).in_sequence(s).
|
|
221
|
-
with {|msg| msg.include?(object_to_remove.filename) }
|
|
222
|
-
if i == obj_to_fail
|
|
223
|
-
object_to_remove.expects(:remove!).in_sequence(s).
|
|
224
|
-
raises(raised_error)
|
|
225
|
-
Backup::Errors::Storage::CycleError.expects(:wrap).in_sequence(s).
|
|
226
|
-
with(raised_error, "#{base.storage_name} failed to remove " +
|
|
227
|
-
"'#{object_to_remove.filename}'").
|
|
228
|
-
returns(:wrapped_error)
|
|
229
|
-
Backup::Logger.expects(:warn).in_sequence(s).
|
|
230
|
-
with(:wrapped_error)
|
|
231
|
-
else
|
|
232
|
-
object_to_remove.expects(:remove!).in_sequence(s)
|
|
233
|
-
end
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
objects = objects - objects_to_remove
|
|
237
|
-
objects.each {|object| object.expects(:clean!).in_sequence(s) }
|
|
238
|
-
storage_object.expects(:write).in_sequence(s).
|
|
239
|
-
with(objects)
|
|
240
|
-
|
|
241
|
-
base.keep = num_to_keep
|
|
242
129
|
base.send(:cycle!)
|
|
243
130
|
end
|
|
244
|
-
|
|
245
131
|
end
|
|
246
132
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
it 'returns sorted filenames for chunk_suffixes' do
|
|
252
|
-
base = Backup::Storage::Base.new
|
|
253
|
-
base.chunk_suffixes = ["aa", "ad", "ae", "ab", "ac"]
|
|
254
|
-
base.stubs(:filename).returns("file.tar")
|
|
255
|
-
base.chunks.should == [
|
|
256
|
-
"#{base.filename}-aa",
|
|
257
|
-
"#{base.filename}-ab",
|
|
258
|
-
"#{base.filename}-ac",
|
|
259
|
-
"#{base.filename}-ad",
|
|
260
|
-
"#{base.filename}-ae",
|
|
261
|
-
]
|
|
262
|
-
|
|
263
|
-
base.chunk_suffixes.should == ["aa", "ad", "ae", "ab", "ac"]
|
|
264
|
-
end
|
|
265
|
-
|
|
266
|
-
end
|
|
267
|
-
|
|
268
|
-
describe '#storage_name' do
|
|
269
|
-
let(:s3) { Backup::Storage::S3.new {} }
|
|
270
|
-
|
|
271
|
-
describe 'returns storage class name with the Backup:: namespace removed' do
|
|
272
|
-
|
|
273
|
-
context 'when storage_id is set' do
|
|
274
|
-
before { s3.storage_id = 'my storage' }
|
|
275
|
-
|
|
276
|
-
it 'appends the storage_id' do
|
|
277
|
-
s3.storage_name.should == 'Storage::S3 (my storage)'
|
|
278
|
-
end
|
|
133
|
+
context 'when keep is not set or == 0' do
|
|
134
|
+
it 'should return nil when not set' do
|
|
135
|
+
base.keep = nil
|
|
136
|
+
base.send(:cycle!).should be_nil
|
|
279
137
|
end
|
|
280
138
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
end
|
|
139
|
+
it 'should return nil when == 0' do
|
|
140
|
+
base.keep = 0
|
|
141
|
+
base.send(:cycle!).should be_nil
|
|
285
142
|
end
|
|
286
|
-
|
|
287
143
|
end
|
|
288
|
-
|
|
289
144
|
end
|
|
145
|
+
|
|
290
146
|
end
|