backup_checksum 3.0.23
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/.gitignore +7 -0
- data/.travis.yml +10 -0
- data/Gemfile +28 -0
- data/Gemfile.lock +130 -0
- data/Guardfile +21 -0
- data/LICENSE.md +24 -0
- data/README.md +476 -0
- data/backup_checksum.gemspec +32 -0
- data/bin/backup +11 -0
- data/lib/backup.rb +217 -0
- data/lib/backup/archive.rb +117 -0
- data/lib/backup/binder.rb +22 -0
- data/lib/backup/checksum/base.rb +44 -0
- data/lib/backup/checksum/shasum.rb +16 -0
- data/lib/backup/cleaner.rb +121 -0
- data/lib/backup/cli/helpers.rb +88 -0
- data/lib/backup/cli/utility.rb +247 -0
- data/lib/backup/compressor/base.rb +29 -0
- data/lib/backup/compressor/bzip2.rb +50 -0
- data/lib/backup/compressor/gzip.rb +47 -0
- data/lib/backup/compressor/lzma.rb +50 -0
- data/lib/backup/compressor/pbzip2.rb +56 -0
- data/lib/backup/config.rb +173 -0
- data/lib/backup/configuration/base.rb +15 -0
- data/lib/backup/configuration/checksum/base.rb +9 -0
- data/lib/backup/configuration/checksum/shasum.rb +9 -0
- data/lib/backup/configuration/compressor/base.rb +9 -0
- data/lib/backup/configuration/compressor/bzip2.rb +23 -0
- data/lib/backup/configuration/compressor/gzip.rb +23 -0
- data/lib/backup/configuration/compressor/lzma.rb +23 -0
- data/lib/backup/configuration/compressor/pbzip2.rb +28 -0
- data/lib/backup/configuration/database/base.rb +19 -0
- data/lib/backup/configuration/database/mongodb.rb +49 -0
- data/lib/backup/configuration/database/mysql.rb +42 -0
- data/lib/backup/configuration/database/postgresql.rb +41 -0
- data/lib/backup/configuration/database/redis.rb +39 -0
- data/lib/backup/configuration/database/riak.rb +29 -0
- data/lib/backup/configuration/encryptor/base.rb +9 -0
- data/lib/backup/configuration/encryptor/gpg.rb +17 -0
- data/lib/backup/configuration/encryptor/open_ssl.rb +32 -0
- data/lib/backup/configuration/helpers.rb +52 -0
- data/lib/backup/configuration/notifier/base.rb +28 -0
- data/lib/backup/configuration/notifier/campfire.rb +25 -0
- data/lib/backup/configuration/notifier/hipchat.rb +41 -0
- data/lib/backup/configuration/notifier/mail.rb +112 -0
- data/lib/backup/configuration/notifier/presently.rb +25 -0
- data/lib/backup/configuration/notifier/prowl.rb +23 -0
- data/lib/backup/configuration/notifier/twitter.rb +21 -0
- data/lib/backup/configuration/storage/base.rb +18 -0
- data/lib/backup/configuration/storage/cloudfiles.rb +25 -0
- data/lib/backup/configuration/storage/dropbox.rb +58 -0
- data/lib/backup/configuration/storage/ftp.rb +29 -0
- data/lib/backup/configuration/storage/local.rb +17 -0
- data/lib/backup/configuration/storage/ninefold.rb +20 -0
- data/lib/backup/configuration/storage/rsync.rb +29 -0
- data/lib/backup/configuration/storage/s3.rb +25 -0
- data/lib/backup/configuration/storage/scp.rb +25 -0
- data/lib/backup/configuration/storage/sftp.rb +25 -0
- data/lib/backup/configuration/syncer/base.rb +10 -0
- data/lib/backup/configuration/syncer/cloud.rb +23 -0
- data/lib/backup/configuration/syncer/cloud_files.rb +30 -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 +23 -0
- data/lib/backup/database/base.rb +59 -0
- data/lib/backup/database/mongodb.rb +232 -0
- data/lib/backup/database/mysql.rb +163 -0
- data/lib/backup/database/postgresql.rb +146 -0
- data/lib/backup/database/redis.rb +139 -0
- data/lib/backup/database/riak.rb +69 -0
- data/lib/backup/dependency.rb +114 -0
- data/lib/backup/encryptor/base.rb +29 -0
- data/lib/backup/encryptor/gpg.rb +80 -0
- data/lib/backup/encryptor/open_ssl.rb +72 -0
- data/lib/backup/errors.rb +124 -0
- data/lib/backup/logger.rb +152 -0
- data/lib/backup/model.rb +386 -0
- data/lib/backup/notifier/base.rb +81 -0
- data/lib/backup/notifier/campfire.rb +168 -0
- data/lib/backup/notifier/hipchat.rb +99 -0
- data/lib/backup/notifier/mail.rb +206 -0
- data/lib/backup/notifier/presently.rb +88 -0
- data/lib/backup/notifier/prowl.rb +65 -0
- data/lib/backup/notifier/twitter.rb +70 -0
- data/lib/backup/package.rb +51 -0
- data/lib/backup/packager.rb +108 -0
- data/lib/backup/pipeline.rb +107 -0
- data/lib/backup/splitter.rb +75 -0
- data/lib/backup/storage/base.rb +119 -0
- data/lib/backup/storage/cloudfiles.rb +87 -0
- data/lib/backup/storage/cycler.rb +117 -0
- data/lib/backup/storage/dropbox.rb +181 -0
- data/lib/backup/storage/ftp.rb +119 -0
- data/lib/backup/storage/local.rb +82 -0
- data/lib/backup/storage/ninefold.rb +116 -0
- data/lib/backup/storage/rsync.rb +149 -0
- data/lib/backup/storage/s3.rb +94 -0
- data/lib/backup/storage/scp.rb +99 -0
- data/lib/backup/storage/sftp.rb +108 -0
- data/lib/backup/syncer/base.rb +42 -0
- data/lib/backup/syncer/cloud.rb +190 -0
- data/lib/backup/syncer/cloud_files.rb +56 -0
- data/lib/backup/syncer/rsync/base.rb +52 -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 +47 -0
- data/lib/backup/template.rb +46 -0
- data/lib/backup/version.rb +43 -0
- data/spec/archive_spec.rb +335 -0
- data/spec/cleaner_spec.rb +304 -0
- data/spec/cli/helpers_spec.rb +176 -0
- data/spec/cli/utility_spec.rb +363 -0
- data/spec/compressor/base_spec.rb +31 -0
- data/spec/compressor/bzip2_spec.rb +83 -0
- data/spec/compressor/gzip_spec.rb +83 -0
- data/spec/compressor/lzma_spec.rb +83 -0
- data/spec/compressor/pbzip2_spec.rb +124 -0
- data/spec/config_spec.rb +321 -0
- data/spec/configuration/base_spec.rb +35 -0
- data/spec/configuration/compressor/bzip2_spec.rb +29 -0
- data/spec/configuration/compressor/gzip_spec.rb +29 -0
- data/spec/configuration/compressor/lzma_spec.rb +29 -0
- data/spec/configuration/compressor/pbzip2_spec.rb +32 -0
- data/spec/configuration/database/base_spec.rb +17 -0
- data/spec/configuration/database/mongodb_spec.rb +56 -0
- data/spec/configuration/database/mysql_spec.rb +53 -0
- data/spec/configuration/database/postgresql_spec.rb +53 -0
- data/spec/configuration/database/redis_spec.rb +50 -0
- data/spec/configuration/database/riak_spec.rb +35 -0
- data/spec/configuration/encryptor/gpg_spec.rb +26 -0
- data/spec/configuration/encryptor/open_ssl_spec.rb +35 -0
- data/spec/configuration/notifier/base_spec.rb +32 -0
- data/spec/configuration/notifier/campfire_spec.rb +32 -0
- data/spec/configuration/notifier/hipchat_spec.rb +44 -0
- data/spec/configuration/notifier/mail_spec.rb +71 -0
- data/spec/configuration/notifier/presently_spec.rb +35 -0
- data/spec/configuration/notifier/prowl_spec.rb +29 -0
- data/spec/configuration/notifier/twitter_spec.rb +35 -0
- data/spec/configuration/storage/cloudfiles_spec.rb +41 -0
- data/spec/configuration/storage/dropbox_spec.rb +38 -0
- data/spec/configuration/storage/ftp_spec.rb +44 -0
- data/spec/configuration/storage/local_spec.rb +29 -0
- data/spec/configuration/storage/ninefold_spec.rb +32 -0
- data/spec/configuration/storage/rsync_spec.rb +41 -0
- data/spec/configuration/storage/s3_spec.rb +38 -0
- data/spec/configuration/storage/scp_spec.rb +41 -0
- data/spec/configuration/storage/sftp_spec.rb +41 -0
- data/spec/configuration/syncer/cloud_files_spec.rb +44 -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/push_spec.rb +43 -0
- data/spec/configuration/syncer/s3_spec.rb +38 -0
- data/spec/database/base_spec.rb +54 -0
- data/spec/database/mongodb_spec.rb +428 -0
- data/spec/database/mysql_spec.rb +335 -0
- data/spec/database/postgresql_spec.rb +278 -0
- data/spec/database/redis_spec.rb +260 -0
- data/spec/database/riak_spec.rb +108 -0
- data/spec/dependency_spec.rb +49 -0
- data/spec/encryptor/base_spec.rb +30 -0
- data/spec/encryptor/gpg_spec.rb +134 -0
- data/spec/encryptor/open_ssl_spec.rb +129 -0
- data/spec/errors_spec.rb +306 -0
- data/spec/logger_spec.rb +363 -0
- data/spec/model_spec.rb +649 -0
- data/spec/notifier/base_spec.rb +89 -0
- data/spec/notifier/campfire_spec.rb +199 -0
- data/spec/notifier/hipchat_spec.rb +188 -0
- data/spec/notifier/mail_spec.rb +280 -0
- data/spec/notifier/presently_spec.rb +181 -0
- data/spec/notifier/prowl_spec.rb +117 -0
- data/spec/notifier/twitter_spec.rb +132 -0
- data/spec/package_spec.rb +61 -0
- data/spec/packager_spec.rb +225 -0
- data/spec/pipeline_spec.rb +257 -0
- data/spec/spec_helper.rb +59 -0
- data/spec/splitter_spec.rb +120 -0
- data/spec/storage/base_spec.rb +160 -0
- data/spec/storage/cloudfiles_spec.rb +230 -0
- data/spec/storage/cycler_spec.rb +239 -0
- data/spec/storage/dropbox_spec.rb +370 -0
- data/spec/storage/ftp_spec.rb +247 -0
- data/spec/storage/local_spec.rb +235 -0
- data/spec/storage/ninefold_spec.rb +319 -0
- data/spec/storage/rsync_spec.rb +345 -0
- data/spec/storage/s3_spec.rb +221 -0
- data/spec/storage/scp_spec.rb +209 -0
- data/spec/storage/sftp_spec.rb +220 -0
- data/spec/syncer/base_spec.rb +22 -0
- data/spec/syncer/cloud_files_spec.rb +192 -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 +192 -0
- data/spec/version_spec.rb +21 -0
- data/templates/cli/utility/archive +25 -0
- data/templates/cli/utility/compressor/bzip2 +7 -0
- data/templates/cli/utility/compressor/gzip +7 -0
- data/templates/cli/utility/compressor/lzma +7 -0
- data/templates/cli/utility/compressor/pbzip2 +7 -0
- data/templates/cli/utility/config +31 -0
- data/templates/cli/utility/database/mongodb +18 -0
- data/templates/cli/utility/database/mysql +21 -0
- data/templates/cli/utility/database/postgresql +17 -0
- data/templates/cli/utility/database/redis +16 -0
- data/templates/cli/utility/database/riak +11 -0
- data/templates/cli/utility/encryptor/gpg +12 -0
- data/templates/cli/utility/encryptor/openssl +9 -0
- data/templates/cli/utility/model.erb +23 -0
- data/templates/cli/utility/notifier/campfire +12 -0
- data/templates/cli/utility/notifier/hipchat +15 -0
- data/templates/cli/utility/notifier/mail +22 -0
- data/templates/cli/utility/notifier/presently +13 -0
- data/templates/cli/utility/notifier/prowl +11 -0
- data/templates/cli/utility/notifier/twitter +13 -0
- data/templates/cli/utility/splitter +7 -0
- data/templates/cli/utility/storage/cloud_files +22 -0
- data/templates/cli/utility/storage/dropbox +20 -0
- data/templates/cli/utility/storage/ftp +12 -0
- data/templates/cli/utility/storage/local +7 -0
- data/templates/cli/utility/storage/ninefold +9 -0
- data/templates/cli/utility/storage/rsync +11 -0
- data/templates/cli/utility/storage/s3 +19 -0
- data/templates/cli/utility/storage/scp +11 -0
- data/templates/cli/utility/storage/sftp +11 -0
- data/templates/cli/utility/syncer/cloud_files +48 -0
- data/templates/cli/utility/syncer/rsync_local +12 -0
- data/templates/cli/utility/syncer/rsync_pull +17 -0
- data/templates/cli/utility/syncer/rsync_push +17 -0
- data/templates/cli/utility/syncer/s3 +45 -0
- data/templates/general/links +11 -0
- data/templates/general/version.erb +2 -0
- data/templates/notifier/mail/failure.erb +9 -0
- data/templates/notifier/mail/success.erb +7 -0
- data/templates/notifier/mail/warning.erb +9 -0
- data/templates/storage/dropbox/authorization_url.erb +6 -0
- data/templates/storage/dropbox/authorized.erb +4 -0
- data/templates/storage/dropbox/cache_file_written.erb +10 -0
- metadata +311 -0
data/spec/errors_spec.rb
ADDED
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require File.expand_path('../spec_helper.rb', __FILE__)
|
|
4
|
+
|
|
5
|
+
# Note: none of these tests require the use of the ErrorsHelper
|
|
6
|
+
describe 'Errors::Error' do
|
|
7
|
+
let(:klass) { Backup::Errors::Error }
|
|
8
|
+
|
|
9
|
+
it 'allow errors to cascade through the system' do
|
|
10
|
+
class ErrorA < klass; end
|
|
11
|
+
class ErrorB < klass; end
|
|
12
|
+
class ErrorC < klass; end
|
|
13
|
+
class ErrorD < klass; end
|
|
14
|
+
|
|
15
|
+
expect do
|
|
16
|
+
begin
|
|
17
|
+
begin
|
|
18
|
+
begin
|
|
19
|
+
raise ErrorA, 'an error occurred in Zone A'
|
|
20
|
+
rescue => err
|
|
21
|
+
raise ErrorB.wrap(err, <<-EOS)
|
|
22
|
+
an error occurred in Zone B
|
|
23
|
+
|
|
24
|
+
the following error should give a reason
|
|
25
|
+
EOS
|
|
26
|
+
end
|
|
27
|
+
rescue => err
|
|
28
|
+
raise ErrorC.wrap(err)
|
|
29
|
+
end
|
|
30
|
+
rescue => err
|
|
31
|
+
raise ErrorD.wrap(err, 'an error occurred in Zone D')
|
|
32
|
+
end
|
|
33
|
+
end.to raise_error(ErrorD,
|
|
34
|
+
"ErrorD: an error occurred in Zone D\n" +
|
|
35
|
+
" Reason: ErrorC\n" +
|
|
36
|
+
" ErrorB: an error occurred in Zone B\n" +
|
|
37
|
+
" \n" +
|
|
38
|
+
" the following error should give a reason\n" +
|
|
39
|
+
" Reason: ErrorA\n" +
|
|
40
|
+
" an error occurred in Zone A"
|
|
41
|
+
)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
describe '#initialize' do
|
|
45
|
+
|
|
46
|
+
it 'creates a StandardError' do
|
|
47
|
+
klass.new.should be_a_kind_of StandardError
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
context 'when given a message' do
|
|
51
|
+
|
|
52
|
+
it 'formats a simple message' do
|
|
53
|
+
err = klass.new('error message')
|
|
54
|
+
err.message.should == 'Error: error message'
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it 'formats a multi-line message' do
|
|
58
|
+
err = klass.new(" error message\n" +
|
|
59
|
+
" This is a multi-line error message.\n" +
|
|
60
|
+
"It should be properly indented. ")
|
|
61
|
+
|
|
62
|
+
err.message.should == "Error: error message\n" +
|
|
63
|
+
" This is a multi-line error message.\n" +
|
|
64
|
+
" It should be properly indented."
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
context 'when given an original error' do
|
|
68
|
+
|
|
69
|
+
it 'includes the original error' do
|
|
70
|
+
orig_err = StandardError.new('original message')
|
|
71
|
+
err = klass.new('error message', orig_err)
|
|
72
|
+
err.message.should == "Error: error message\n" +
|
|
73
|
+
" Reason: StandardError\n" +
|
|
74
|
+
" original message"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it 'formats all messages' do
|
|
78
|
+
orig_err = StandardError.new(" original message\n" +
|
|
79
|
+
" This is a multi-line error message.\n" +
|
|
80
|
+
"It should be properly indented.")
|
|
81
|
+
err = klass.new(" error message\n" +
|
|
82
|
+
" This is a multi-line error message.\n" +
|
|
83
|
+
"It should be properly indented. ", orig_err)
|
|
84
|
+
|
|
85
|
+
err.message.should == "Error: error message\n" +
|
|
86
|
+
" This is a multi-line error message.\n" +
|
|
87
|
+
" It should be properly indented.\n" +
|
|
88
|
+
" Reason: StandardError\n" +
|
|
89
|
+
" original message\n" +
|
|
90
|
+
" This is a multi-line error message.\n" +
|
|
91
|
+
" It should be properly indented."
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it 'uses the original error backtrace' do
|
|
95
|
+
begin
|
|
96
|
+
raise StandardError.new
|
|
97
|
+
rescue => err
|
|
98
|
+
klass.new(nil, err).backtrace.
|
|
99
|
+
should == err.backtrace
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it 'reports if original error had no message' do
|
|
104
|
+
orig_err = StandardError.new
|
|
105
|
+
err = klass.new('error message', orig_err)
|
|
106
|
+
err.message.should == "Error: error message\n" +
|
|
107
|
+
" Reason: StandardError (no message given)"
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
end # context 'when given an original error'
|
|
111
|
+
|
|
112
|
+
context 'when given an original Errors::Error' do
|
|
113
|
+
let(:subklass) do
|
|
114
|
+
class SubKlass < klass; end
|
|
115
|
+
SubKlass
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it 'includes the original error' do
|
|
119
|
+
orig_err = subklass.new('original message')
|
|
120
|
+
err = klass.new('error message', orig_err)
|
|
121
|
+
err.message.should == "Error: error message\n" +
|
|
122
|
+
" Reason: SubKlass\n" +
|
|
123
|
+
" original message"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it 'formats all messages' do
|
|
127
|
+
orig_err = subklass.new(" original message\n" +
|
|
128
|
+
" This is a multi-line error message.\n" +
|
|
129
|
+
"It should be properly indented.")
|
|
130
|
+
err = klass.new(" error message\n" +
|
|
131
|
+
" This is a multi-line error message.\n" +
|
|
132
|
+
"It should be properly indented. ", orig_err)
|
|
133
|
+
|
|
134
|
+
err.message.should == "Error: error message\n" +
|
|
135
|
+
" This is a multi-line error message.\n" +
|
|
136
|
+
" It should be properly indented.\n" +
|
|
137
|
+
" Reason: SubKlass\n" +
|
|
138
|
+
" original message\n" +
|
|
139
|
+
" This is a multi-line error message.\n" +
|
|
140
|
+
" It should be properly indented."
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
it 'uses the original error backtrace' do
|
|
144
|
+
begin
|
|
145
|
+
raise subklass.new
|
|
146
|
+
rescue => err
|
|
147
|
+
klass.new(nil, err).backtrace.
|
|
148
|
+
should == err.backtrace
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it 'reports if original error had no message' do
|
|
153
|
+
orig_err = subklass.new
|
|
154
|
+
err = klass.new('error message', orig_err)
|
|
155
|
+
err.message.should == "Error: error message\n" +
|
|
156
|
+
" Reason: SubKlass (no message given)"
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
end # context 'when given an original Errors::Error'
|
|
160
|
+
|
|
161
|
+
end # context 'when given a message'
|
|
162
|
+
|
|
163
|
+
context 'when given no message' do
|
|
164
|
+
|
|
165
|
+
it 'strips the module namespace from the default message' do
|
|
166
|
+
err = klass.new
|
|
167
|
+
err.message.should == 'Error'
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
context 'when given an original error' do
|
|
171
|
+
|
|
172
|
+
it 'uses the original error message' do
|
|
173
|
+
orig_err = StandardError.new
|
|
174
|
+
err = klass.new(nil, orig_err)
|
|
175
|
+
err.message.should == 'Error: StandardError'
|
|
176
|
+
|
|
177
|
+
orig_err = StandardError.new('original message')
|
|
178
|
+
err = klass.new(nil, orig_err)
|
|
179
|
+
err.message.should == 'Error: StandardError: original message'
|
|
180
|
+
|
|
181
|
+
orig_err = StandardError.new(" original message\n" +
|
|
182
|
+
" This is a multi-line error message.\n" +
|
|
183
|
+
"It should be properly indented.")
|
|
184
|
+
err = klass.new(nil, orig_err)
|
|
185
|
+
err.message.should == "Error: StandardError: original message\n" +
|
|
186
|
+
" This is a multi-line error message.\n" +
|
|
187
|
+
" It should be properly indented."
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
end # context 'when given an original error'
|
|
191
|
+
|
|
192
|
+
context 'when given an original Errors::Error' do
|
|
193
|
+
let(:subklass) do
|
|
194
|
+
class SubKlass < klass; end
|
|
195
|
+
SubKlass
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
it 'uses the original error message' do
|
|
199
|
+
orig_err = subklass.new
|
|
200
|
+
err = klass.new(nil, orig_err)
|
|
201
|
+
err.message.should == 'Error: SubKlass'
|
|
202
|
+
|
|
203
|
+
orig_err = subklass.new('original message')
|
|
204
|
+
err = klass.new(nil, orig_err)
|
|
205
|
+
err.message.should == 'Error: SubKlass: original message'
|
|
206
|
+
|
|
207
|
+
orig_err = subklass.new(" original message\n" +
|
|
208
|
+
" This is a multi-line error message.\n" +
|
|
209
|
+
"It should be properly indented.")
|
|
210
|
+
err = klass.new(nil, orig_err)
|
|
211
|
+
err.message.should == "Error: SubKlass: original message\n" +
|
|
212
|
+
" This is a multi-line error message.\n" +
|
|
213
|
+
" It should be properly indented."
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
end # context 'when given an original Errors::Error'
|
|
217
|
+
|
|
218
|
+
end # context 'when given no message'
|
|
219
|
+
|
|
220
|
+
end # describe '#initialize'
|
|
221
|
+
|
|
222
|
+
describe '#wrap' do
|
|
223
|
+
describe 'swaps the parameters to provide a cleaner way to' do
|
|
224
|
+
|
|
225
|
+
it 'raise a wrapped error with a message' do
|
|
226
|
+
orig_err = StandardError.new <<-EOS
|
|
227
|
+
original message
|
|
228
|
+
This is a multi-line error message.
|
|
229
|
+
It should be properly indented.
|
|
230
|
+
EOS
|
|
231
|
+
|
|
232
|
+
expect do
|
|
233
|
+
raise klass.wrap(orig_err), <<-EOS
|
|
234
|
+
error message
|
|
235
|
+
This is a multi-line error message.
|
|
236
|
+
It should be properly indented.
|
|
237
|
+
EOS
|
|
238
|
+
end.to raise_error(klass,
|
|
239
|
+
"Error: error message\n" +
|
|
240
|
+
" This is a multi-line error message.\n" +
|
|
241
|
+
" It should be properly indented.\n" +
|
|
242
|
+
" Reason: StandardError\n" +
|
|
243
|
+
" original message\n" +
|
|
244
|
+
" This is a multi-line error message.\n" +
|
|
245
|
+
" It should be properly indented."
|
|
246
|
+
)
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
it 'return a wrapped error with a message' do
|
|
250
|
+
orig_err = StandardError.new <<-EOS
|
|
251
|
+
original message
|
|
252
|
+
This is a multi-line error message.
|
|
253
|
+
It should be properly indented.
|
|
254
|
+
EOS
|
|
255
|
+
|
|
256
|
+
err = klass.wrap(orig_err, <<-EOS)
|
|
257
|
+
error message
|
|
258
|
+
This will wrap the original error
|
|
259
|
+
and it's message will be given below
|
|
260
|
+
EOS
|
|
261
|
+
|
|
262
|
+
err.message.should ==
|
|
263
|
+
"Error: error message\n" +
|
|
264
|
+
" This will wrap the original error\n" +
|
|
265
|
+
" and it's message will be given below\n" +
|
|
266
|
+
" Reason: StandardError\n" +
|
|
267
|
+
" original message\n" +
|
|
268
|
+
" This is a multi-line error message.\n" +
|
|
269
|
+
" It should be properly indented."
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
end # describe 'swaps the parameters to provide a cleaner way to'
|
|
273
|
+
end # describe '#wrap'
|
|
274
|
+
|
|
275
|
+
end # describe 'Errors::Error'
|
|
276
|
+
|
|
277
|
+
describe 'ErrorHelper' do
|
|
278
|
+
let(:base) { Backup::Errors }
|
|
279
|
+
|
|
280
|
+
it 'dynamically creates namespaces and subclasses of Errors::Error' do
|
|
281
|
+
Backup::Errors::FooBarError.new.
|
|
282
|
+
should be_a_kind_of base::Error
|
|
283
|
+
Backup::Errors::Foo::Bar::Error.new.
|
|
284
|
+
should be_a_kind_of base::Error
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
context 'new error classes created within new namespaces' do
|
|
288
|
+
it 'retain the added portion of namespace in their messages' do
|
|
289
|
+
orig_err = StandardError.new('original message')
|
|
290
|
+
err = base::FooMod::FooError.new('error message', orig_err)
|
|
291
|
+
err.message.should ==
|
|
292
|
+
"FooMod::FooError: error message\n" +
|
|
293
|
+
" Reason: StandardError\n" +
|
|
294
|
+
" original message"
|
|
295
|
+
|
|
296
|
+
err2 = base::Foo::Bar::Mod::FooBarError.wrap(err, 'foobar message')
|
|
297
|
+
err2.message.should ==
|
|
298
|
+
"Foo::Bar::Mod::FooBarError: foobar message\n" +
|
|
299
|
+
" Reason: FooMod::FooError\n" +
|
|
300
|
+
" error message\n" +
|
|
301
|
+
" Reason: StandardError\n" +
|
|
302
|
+
" original message"
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
end # describe ErrorHelper
|
data/spec/logger_spec.rb
ADDED
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require File.expand_path('../spec_helper.rb', __FILE__)
|
|
4
|
+
|
|
5
|
+
describe Backup::Logger do
|
|
6
|
+
let(:logger_time) { Time.now.strftime("%Y/%m/%d %H:%M:%S") }
|
|
7
|
+
let(:logfile_path) { File.join(Backup::Config.log_path, 'backup.log') }
|
|
8
|
+
let(:logfile_mock) { mock }
|
|
9
|
+
let(:s) { sequence '' }
|
|
10
|
+
|
|
11
|
+
before do
|
|
12
|
+
Timecop.freeze(Time.now)
|
|
13
|
+
|
|
14
|
+
# stubbed in spec_helper
|
|
15
|
+
[:message, :error, :warn, :normal, :silent].each do |message_type|
|
|
16
|
+
subject.unstub(message_type)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
subject.quiet = nil
|
|
20
|
+
subject.send(:remove_instance_variable, :@messages) rescue nil
|
|
21
|
+
subject.send(:remove_instance_variable, :@has_warnings) rescue nil
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe '#message' do
|
|
25
|
+
it 'sends a regular message to the console and log file' do
|
|
26
|
+
subject.expects(:loggify).in_sequence(s).
|
|
27
|
+
with('regular message', :message, :green).
|
|
28
|
+
returns(:green_regular_message)
|
|
29
|
+
subject.expects(:to_console).in_sequence(s).
|
|
30
|
+
with(:green_regular_message)
|
|
31
|
+
subject.expects(:loggify).in_sequence(s).
|
|
32
|
+
with('regular message', :message).
|
|
33
|
+
returns(:uncolored_regular_message)
|
|
34
|
+
subject.expects(:to_file).in_sequence(s).
|
|
35
|
+
with(:uncolored_regular_message)
|
|
36
|
+
|
|
37
|
+
subject.message('regular message')
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
describe '#error' do
|
|
42
|
+
it 'sends an error message to the console (stderr) and log file' do
|
|
43
|
+
subject.expects(:loggify).in_sequence(s).
|
|
44
|
+
with('error message', :error, :red).
|
|
45
|
+
returns(:red_error_message)
|
|
46
|
+
subject.expects(:to_console).in_sequence(s).
|
|
47
|
+
with(:red_error_message, true)
|
|
48
|
+
subject.expects(:loggify).in_sequence(s).
|
|
49
|
+
with('error message', :error).
|
|
50
|
+
returns(:uncolored_error_message)
|
|
51
|
+
subject.expects(:to_file).in_sequence(s).
|
|
52
|
+
with(:uncolored_error_message)
|
|
53
|
+
|
|
54
|
+
subject.error('error message')
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
describe '#warn' do
|
|
59
|
+
it 'sends a warning message to the console (stderr) and log file' do
|
|
60
|
+
subject.expects(:loggify).in_sequence(s).
|
|
61
|
+
with('warning message', :warning, :yellow).
|
|
62
|
+
returns(:yellow_warning_message)
|
|
63
|
+
subject.expects(:to_console).in_sequence(s).
|
|
64
|
+
with(:yellow_warning_message, true)
|
|
65
|
+
subject.expects(:loggify).in_sequence(s).
|
|
66
|
+
with('warning message', :warning).
|
|
67
|
+
returns(:uncolored_warning_message)
|
|
68
|
+
subject.expects(:to_file).in_sequence(s).
|
|
69
|
+
with(:uncolored_warning_message)
|
|
70
|
+
|
|
71
|
+
subject.warn('warning message')
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it 'sets has_warnings? to true' do
|
|
75
|
+
subject.stubs(:to_console)
|
|
76
|
+
subject.stubs(:to_file)
|
|
77
|
+
expect { subject.warn('warning') }.to
|
|
78
|
+
change{ subject.has_warnings? }.from(false).to(true)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
describe '#normal' do
|
|
83
|
+
it 'sends a normal, unformatted message to the console and log file' do
|
|
84
|
+
subject.expects(:loggify).in_sequence(s).
|
|
85
|
+
with('normal message').
|
|
86
|
+
returns(:unformatted_message)
|
|
87
|
+
subject.expects(:to_console).in_sequence(s).
|
|
88
|
+
with(:unformatted_message)
|
|
89
|
+
subject.expects(:loggify).in_sequence(s).
|
|
90
|
+
with('normal message').
|
|
91
|
+
returns(:unformatted_message)
|
|
92
|
+
subject.expects(:to_file).in_sequence(s).
|
|
93
|
+
with(:unformatted_message)
|
|
94
|
+
|
|
95
|
+
subject.normal('normal message')
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
describe '#silent' do
|
|
100
|
+
it 'sends a silent message to the log file' do
|
|
101
|
+
subject.expects(:to_console).never
|
|
102
|
+
subject.expects(:loggify).in_sequence(s).
|
|
103
|
+
with('silent message', :silent).
|
|
104
|
+
returns(:silent_message)
|
|
105
|
+
subject.expects(:to_file).in_sequence(s).
|
|
106
|
+
with(:silent_message)
|
|
107
|
+
|
|
108
|
+
subject.silent('silent message')
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
describe '#messages' do
|
|
113
|
+
|
|
114
|
+
it 'returns an empty array if no messages have been sent' do
|
|
115
|
+
subject.messages.should == []
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it 'returns an array of all lines sent to the log file' do
|
|
119
|
+
File.stubs(:open).yields(stub(:puts))
|
|
120
|
+
strings = ['an array', 'of message', 'strings']
|
|
121
|
+
subject.send(:to_file, strings)
|
|
122
|
+
subject.messages.should == strings
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it 'does not track lines sent to the console' do
|
|
126
|
+
subject.stubs(:puts)
|
|
127
|
+
strings = ['an array', 'of message', 'strings']
|
|
128
|
+
subject.send(:to_console, strings)
|
|
129
|
+
subject.messages.should == []
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
end # describe '#messages'
|
|
133
|
+
|
|
134
|
+
describe '#clear!' do
|
|
135
|
+
it 'should clear the log and reset has_warnings?' do
|
|
136
|
+
subject.messages << 'foo'
|
|
137
|
+
subject.instance_variable_set(:@has_warnings, true)
|
|
138
|
+
subject.messages.count.should == 1
|
|
139
|
+
subject.has_warnings?.should be_true
|
|
140
|
+
|
|
141
|
+
subject.clear!
|
|
142
|
+
subject.messages.should be_empty
|
|
143
|
+
subject.has_warnings?.should be_false
|
|
144
|
+
end
|
|
145
|
+
end # describe '#clear!'
|
|
146
|
+
|
|
147
|
+
describe '#truncate!' do
|
|
148
|
+
context 'when log file does not exist' do
|
|
149
|
+
before { File.stubs(:exist?).returns(false) }
|
|
150
|
+
it 'should do nothing' do
|
|
151
|
+
File.expects(:stat).never
|
|
152
|
+
subject.truncate!
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
context 'when log file is <= max_bytes' do
|
|
157
|
+
before { File.stubs(:exist?).returns(true) }
|
|
158
|
+
it 'should do nothing' do
|
|
159
|
+
stat = mock
|
|
160
|
+
File.expects(:stat).twice.with(
|
|
161
|
+
File.join(Backup::Config.log_path, 'backup.log')
|
|
162
|
+
).returns(stat)
|
|
163
|
+
|
|
164
|
+
[1, 2].each do |size|
|
|
165
|
+
stat.expects(:size).returns(size)
|
|
166
|
+
|
|
167
|
+
FileUtils.expects(:mv).never
|
|
168
|
+
File.expects(:open).never
|
|
169
|
+
FileUtils.expects(:rm_f).never
|
|
170
|
+
|
|
171
|
+
subject.truncate!(2)
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
context 'when log file is > max_bytes' do
|
|
177
|
+
before do
|
|
178
|
+
FileUtils.unstub(:mkdir_p)
|
|
179
|
+
FileUtils.unstub(:mv)
|
|
180
|
+
FileUtils.unstub(:rm)
|
|
181
|
+
FileUtils.unstub(:rm_f)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it 'should truncate the file, removing older lines' do
|
|
185
|
+
max_bytes = 5_000
|
|
186
|
+
line_len = 120
|
|
187
|
+
Dir.mktmpdir do |dir|
|
|
188
|
+
Backup::Config.update(:root_path => dir)
|
|
189
|
+
FileUtils.mkdir_p(Backup::Config.log_path)
|
|
190
|
+
log_file = File.join(Backup::Config.log_path, 'backup.log')
|
|
191
|
+
|
|
192
|
+
lineno = 0
|
|
193
|
+
over_max = (max_bytes * 1.25).to_i
|
|
194
|
+
File.open(log_file, 'w') do |f|
|
|
195
|
+
until f.pos > over_max
|
|
196
|
+
f.puts "#{ lineno += 1 }: ".ljust(line_len, 'x')
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
File.stat(log_file).size.
|
|
200
|
+
should be_within(line_len + 2).of(over_max)
|
|
201
|
+
|
|
202
|
+
subject.truncate!(max_bytes)
|
|
203
|
+
|
|
204
|
+
File.stat(log_file).size.
|
|
205
|
+
should be_within(line_len + 2).of(max_bytes)
|
|
206
|
+
|
|
207
|
+
File.readlines(log_file).last.chomp.
|
|
208
|
+
should == "#{ lineno }: ".ljust(line_len, 'x')
|
|
209
|
+
|
|
210
|
+
File.exist?(log_file + '~').should be_false
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
end # describe '#truncate!'
|
|
216
|
+
|
|
217
|
+
describe '#loggify' do
|
|
218
|
+
|
|
219
|
+
it 'returns an array of strings split on newline separators' do
|
|
220
|
+
str_aa = "first line\nsecond line"
|
|
221
|
+
str_ab = "first line\nsecond line\n"
|
|
222
|
+
expected_a = ["[#{logger_time}][msg_type] first line",
|
|
223
|
+
"[#{logger_time}][msg_type] second line"]
|
|
224
|
+
|
|
225
|
+
str_b = 'string with no newline'
|
|
226
|
+
expected_b = ["[#{logger_time}][msg_type] string with no newline"]
|
|
227
|
+
|
|
228
|
+
subject.send(:loggify, str_aa, :msg_type).should == expected_a
|
|
229
|
+
subject.send(:loggify, str_ab, :msg_type).should == expected_a
|
|
230
|
+
subject.send(:loggify, str_b, :msg_type).should == expected_b
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
it 'formats a string with color if color is given' do
|
|
234
|
+
green_type = ["[#{logger_time}][#{"\e[32mmsg_type\e[0m"}] foo"]
|
|
235
|
+
yellow_type = ["[#{logger_time}][#{"\e[33mmsg_type\e[0m"}] foo"]
|
|
236
|
+
red_type = ["[#{logger_time}][#{"\e[31mmsg_type\e[0m"}] foo"]
|
|
237
|
+
|
|
238
|
+
subject.send(:loggify, 'foo', :msg_type, :green ).should == green_type
|
|
239
|
+
subject.send(:loggify, 'foo', :msg_type, :yellow).should == yellow_type
|
|
240
|
+
subject.send(:loggify, 'foo', :msg_type, :red ).should == red_type
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
it 'does not colorize if no color given' do
|
|
244
|
+
no_color = ["[#{logger_time}][msg_type] foo"]
|
|
245
|
+
subject.send(:loggify, 'foo', :msg_type).should == no_color
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
it 'accepts blank lines in the message' do
|
|
249
|
+
str = "first line\n\nthird line"
|
|
250
|
+
expected = ["[#{logger_time}][msg_type] first line",
|
|
251
|
+
"[#{logger_time}][msg_type] ",
|
|
252
|
+
"[#{logger_time}][msg_type] third line"]
|
|
253
|
+
|
|
254
|
+
subject.send(:loggify, str, :msg_type).should == expected
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
it 'accepts an object responding to #to_s for the message' do
|
|
258
|
+
obj = StandardError.new("first line\nsecond line")
|
|
259
|
+
expected = ["[#{logger_time}][msg_type] first line",
|
|
260
|
+
"[#{logger_time}][msg_type] second line"]
|
|
261
|
+
|
|
262
|
+
subject.send(:loggify, obj, :msg_type).should == expected
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
it 'returns an unformatted lines if type is not given' do
|
|
266
|
+
str_a = 'single line'
|
|
267
|
+
str_b = "first line\n\nthird line"
|
|
268
|
+
expected_a = ['single line']
|
|
269
|
+
expected_b = ['first line', '', 'third line']
|
|
270
|
+
|
|
271
|
+
subject.send(:loggify, str_a).should == expected_a
|
|
272
|
+
subject.send(:loggify, str_b).should == expected_b
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
end # describe '#loggify'
|
|
276
|
+
|
|
277
|
+
describe '#to_console' do
|
|
278
|
+
|
|
279
|
+
context 'when +stderr+ is not set (false)' do
|
|
280
|
+
it 'writes an array of strings to stdout' do
|
|
281
|
+
lines = [ 'line one', 'line two', 'line three']
|
|
282
|
+
lines.each {|line| subject.expects(:puts).with(line).in_sequence(s) }
|
|
283
|
+
subject.send(:to_console, lines)
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
context 'when +stderr+ is set (true)' do
|
|
288
|
+
it 'writes an array of strings to stdout' do
|
|
289
|
+
lines = [ 'line one', 'line two', 'line three']
|
|
290
|
+
lines.each {|line| Kernel.expects(:warn).with(line).in_sequence(s) }
|
|
291
|
+
subject.send(:to_console, lines, true)
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
it 'returns nil if quiet? is true' do
|
|
296
|
+
subject.quiet = true
|
|
297
|
+
subject.expects(:puts).never
|
|
298
|
+
subject.send(:to_console, 'a string')
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
end # describe '#to_console'
|
|
302
|
+
|
|
303
|
+
describe '#to_file' do
|
|
304
|
+
|
|
305
|
+
it 'writes an array of strings to the log file' do
|
|
306
|
+
lines = ['line one', 'line two', 'line three']
|
|
307
|
+
File.stubs(:open).yields(logfile_mock)
|
|
308
|
+
lines.each {|line| logfile_mock.expects(:puts).with(line).in_sequence(s) }
|
|
309
|
+
subject.send(:to_file, lines)
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
it 'appends each line written to #messages' do
|
|
313
|
+
lines = ['line one', 'line two', 'line three']
|
|
314
|
+
File.stubs(:open)
|
|
315
|
+
a_mock = mock
|
|
316
|
+
subject.expects(:messages).returns(a_mock)
|
|
317
|
+
a_mock.expects(:push).with('line one', 'line two', 'line three')
|
|
318
|
+
subject.send(:to_file, lines)
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
it 'only opens the log file once to append multiple lines' do
|
|
322
|
+
lines = ['line one', 'line two', 'line three']
|
|
323
|
+
File.expects(:open).once.with(logfile_path, 'a').yields(logfile_mock)
|
|
324
|
+
logfile_mock.expects(:puts).times(3)
|
|
325
|
+
subject.send(:to_file, lines)
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
end # describe '#to_file'
|
|
329
|
+
|
|
330
|
+
describe 'color methods' do
|
|
331
|
+
|
|
332
|
+
it 'color methods send strings to #colorize with color codes' do
|
|
333
|
+
colors = [ [:green, 32], [:yellow, 33], [:red, 31] ]
|
|
334
|
+
colors.each do |color, code|
|
|
335
|
+
subject.expects(:colorize).with('foo', code).in_sequence(s)
|
|
336
|
+
end
|
|
337
|
+
colors.each {|color, code| subject.send(color, 'foo') }
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
it '#colorize adds the code to the string' do
|
|
341
|
+
[32, 33, 31].each do |code|
|
|
342
|
+
subject.send(:colorize, 'foo', code).
|
|
343
|
+
should == "\e[#{code}mfoo\e[0m"
|
|
344
|
+
end
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
end # color methods
|
|
348
|
+
|
|
349
|
+
describe '#quiet' do
|
|
350
|
+
it 'should be nil by default' do
|
|
351
|
+
# of course, 'before' is setting it to nil ;)
|
|
352
|
+
subject.quiet.should be_nil
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
it 'can be set true/false' do
|
|
356
|
+
subject.quiet = true
|
|
357
|
+
subject.quiet.should be_true
|
|
358
|
+
subject.quiet = false
|
|
359
|
+
subject.quiet.should be_false
|
|
360
|
+
end
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
end
|