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.
Files changed (244) hide show
  1. data/.gitignore +7 -0
  2. data/.travis.yml +10 -0
  3. data/Gemfile +28 -0
  4. data/Gemfile.lock +130 -0
  5. data/Guardfile +21 -0
  6. data/LICENSE.md +24 -0
  7. data/README.md +476 -0
  8. data/backup_checksum.gemspec +32 -0
  9. data/bin/backup +11 -0
  10. data/lib/backup.rb +217 -0
  11. data/lib/backup/archive.rb +117 -0
  12. data/lib/backup/binder.rb +22 -0
  13. data/lib/backup/checksum/base.rb +44 -0
  14. data/lib/backup/checksum/shasum.rb +16 -0
  15. data/lib/backup/cleaner.rb +121 -0
  16. data/lib/backup/cli/helpers.rb +88 -0
  17. data/lib/backup/cli/utility.rb +247 -0
  18. data/lib/backup/compressor/base.rb +29 -0
  19. data/lib/backup/compressor/bzip2.rb +50 -0
  20. data/lib/backup/compressor/gzip.rb +47 -0
  21. data/lib/backup/compressor/lzma.rb +50 -0
  22. data/lib/backup/compressor/pbzip2.rb +56 -0
  23. data/lib/backup/config.rb +173 -0
  24. data/lib/backup/configuration/base.rb +15 -0
  25. data/lib/backup/configuration/checksum/base.rb +9 -0
  26. data/lib/backup/configuration/checksum/shasum.rb +9 -0
  27. data/lib/backup/configuration/compressor/base.rb +9 -0
  28. data/lib/backup/configuration/compressor/bzip2.rb +23 -0
  29. data/lib/backup/configuration/compressor/gzip.rb +23 -0
  30. data/lib/backup/configuration/compressor/lzma.rb +23 -0
  31. data/lib/backup/configuration/compressor/pbzip2.rb +28 -0
  32. data/lib/backup/configuration/database/base.rb +19 -0
  33. data/lib/backup/configuration/database/mongodb.rb +49 -0
  34. data/lib/backup/configuration/database/mysql.rb +42 -0
  35. data/lib/backup/configuration/database/postgresql.rb +41 -0
  36. data/lib/backup/configuration/database/redis.rb +39 -0
  37. data/lib/backup/configuration/database/riak.rb +29 -0
  38. data/lib/backup/configuration/encryptor/base.rb +9 -0
  39. data/lib/backup/configuration/encryptor/gpg.rb +17 -0
  40. data/lib/backup/configuration/encryptor/open_ssl.rb +32 -0
  41. data/lib/backup/configuration/helpers.rb +52 -0
  42. data/lib/backup/configuration/notifier/base.rb +28 -0
  43. data/lib/backup/configuration/notifier/campfire.rb +25 -0
  44. data/lib/backup/configuration/notifier/hipchat.rb +41 -0
  45. data/lib/backup/configuration/notifier/mail.rb +112 -0
  46. data/lib/backup/configuration/notifier/presently.rb +25 -0
  47. data/lib/backup/configuration/notifier/prowl.rb +23 -0
  48. data/lib/backup/configuration/notifier/twitter.rb +21 -0
  49. data/lib/backup/configuration/storage/base.rb +18 -0
  50. data/lib/backup/configuration/storage/cloudfiles.rb +25 -0
  51. data/lib/backup/configuration/storage/dropbox.rb +58 -0
  52. data/lib/backup/configuration/storage/ftp.rb +29 -0
  53. data/lib/backup/configuration/storage/local.rb +17 -0
  54. data/lib/backup/configuration/storage/ninefold.rb +20 -0
  55. data/lib/backup/configuration/storage/rsync.rb +29 -0
  56. data/lib/backup/configuration/storage/s3.rb +25 -0
  57. data/lib/backup/configuration/storage/scp.rb +25 -0
  58. data/lib/backup/configuration/storage/sftp.rb +25 -0
  59. data/lib/backup/configuration/syncer/base.rb +10 -0
  60. data/lib/backup/configuration/syncer/cloud.rb +23 -0
  61. data/lib/backup/configuration/syncer/cloud_files.rb +30 -0
  62. data/lib/backup/configuration/syncer/rsync/base.rb +28 -0
  63. data/lib/backup/configuration/syncer/rsync/local.rb +11 -0
  64. data/lib/backup/configuration/syncer/rsync/pull.rb +11 -0
  65. data/lib/backup/configuration/syncer/rsync/push.rb +31 -0
  66. data/lib/backup/configuration/syncer/s3.rb +23 -0
  67. data/lib/backup/database/base.rb +59 -0
  68. data/lib/backup/database/mongodb.rb +232 -0
  69. data/lib/backup/database/mysql.rb +163 -0
  70. data/lib/backup/database/postgresql.rb +146 -0
  71. data/lib/backup/database/redis.rb +139 -0
  72. data/lib/backup/database/riak.rb +69 -0
  73. data/lib/backup/dependency.rb +114 -0
  74. data/lib/backup/encryptor/base.rb +29 -0
  75. data/lib/backup/encryptor/gpg.rb +80 -0
  76. data/lib/backup/encryptor/open_ssl.rb +72 -0
  77. data/lib/backup/errors.rb +124 -0
  78. data/lib/backup/logger.rb +152 -0
  79. data/lib/backup/model.rb +386 -0
  80. data/lib/backup/notifier/base.rb +81 -0
  81. data/lib/backup/notifier/campfire.rb +168 -0
  82. data/lib/backup/notifier/hipchat.rb +99 -0
  83. data/lib/backup/notifier/mail.rb +206 -0
  84. data/lib/backup/notifier/presently.rb +88 -0
  85. data/lib/backup/notifier/prowl.rb +65 -0
  86. data/lib/backup/notifier/twitter.rb +70 -0
  87. data/lib/backup/package.rb +51 -0
  88. data/lib/backup/packager.rb +108 -0
  89. data/lib/backup/pipeline.rb +107 -0
  90. data/lib/backup/splitter.rb +75 -0
  91. data/lib/backup/storage/base.rb +119 -0
  92. data/lib/backup/storage/cloudfiles.rb +87 -0
  93. data/lib/backup/storage/cycler.rb +117 -0
  94. data/lib/backup/storage/dropbox.rb +181 -0
  95. data/lib/backup/storage/ftp.rb +119 -0
  96. data/lib/backup/storage/local.rb +82 -0
  97. data/lib/backup/storage/ninefold.rb +116 -0
  98. data/lib/backup/storage/rsync.rb +149 -0
  99. data/lib/backup/storage/s3.rb +94 -0
  100. data/lib/backup/storage/scp.rb +99 -0
  101. data/lib/backup/storage/sftp.rb +108 -0
  102. data/lib/backup/syncer/base.rb +42 -0
  103. data/lib/backup/syncer/cloud.rb +190 -0
  104. data/lib/backup/syncer/cloud_files.rb +56 -0
  105. data/lib/backup/syncer/rsync/base.rb +52 -0
  106. data/lib/backup/syncer/rsync/local.rb +53 -0
  107. data/lib/backup/syncer/rsync/pull.rb +38 -0
  108. data/lib/backup/syncer/rsync/push.rb +113 -0
  109. data/lib/backup/syncer/s3.rb +47 -0
  110. data/lib/backup/template.rb +46 -0
  111. data/lib/backup/version.rb +43 -0
  112. data/spec/archive_spec.rb +335 -0
  113. data/spec/cleaner_spec.rb +304 -0
  114. data/spec/cli/helpers_spec.rb +176 -0
  115. data/spec/cli/utility_spec.rb +363 -0
  116. data/spec/compressor/base_spec.rb +31 -0
  117. data/spec/compressor/bzip2_spec.rb +83 -0
  118. data/spec/compressor/gzip_spec.rb +83 -0
  119. data/spec/compressor/lzma_spec.rb +83 -0
  120. data/spec/compressor/pbzip2_spec.rb +124 -0
  121. data/spec/config_spec.rb +321 -0
  122. data/spec/configuration/base_spec.rb +35 -0
  123. data/spec/configuration/compressor/bzip2_spec.rb +29 -0
  124. data/spec/configuration/compressor/gzip_spec.rb +29 -0
  125. data/spec/configuration/compressor/lzma_spec.rb +29 -0
  126. data/spec/configuration/compressor/pbzip2_spec.rb +32 -0
  127. data/spec/configuration/database/base_spec.rb +17 -0
  128. data/spec/configuration/database/mongodb_spec.rb +56 -0
  129. data/spec/configuration/database/mysql_spec.rb +53 -0
  130. data/spec/configuration/database/postgresql_spec.rb +53 -0
  131. data/spec/configuration/database/redis_spec.rb +50 -0
  132. data/spec/configuration/database/riak_spec.rb +35 -0
  133. data/spec/configuration/encryptor/gpg_spec.rb +26 -0
  134. data/spec/configuration/encryptor/open_ssl_spec.rb +35 -0
  135. data/spec/configuration/notifier/base_spec.rb +32 -0
  136. data/spec/configuration/notifier/campfire_spec.rb +32 -0
  137. data/spec/configuration/notifier/hipchat_spec.rb +44 -0
  138. data/spec/configuration/notifier/mail_spec.rb +71 -0
  139. data/spec/configuration/notifier/presently_spec.rb +35 -0
  140. data/spec/configuration/notifier/prowl_spec.rb +29 -0
  141. data/spec/configuration/notifier/twitter_spec.rb +35 -0
  142. data/spec/configuration/storage/cloudfiles_spec.rb +41 -0
  143. data/spec/configuration/storage/dropbox_spec.rb +38 -0
  144. data/spec/configuration/storage/ftp_spec.rb +44 -0
  145. data/spec/configuration/storage/local_spec.rb +29 -0
  146. data/spec/configuration/storage/ninefold_spec.rb +32 -0
  147. data/spec/configuration/storage/rsync_spec.rb +41 -0
  148. data/spec/configuration/storage/s3_spec.rb +38 -0
  149. data/spec/configuration/storage/scp_spec.rb +41 -0
  150. data/spec/configuration/storage/sftp_spec.rb +41 -0
  151. data/spec/configuration/syncer/cloud_files_spec.rb +44 -0
  152. data/spec/configuration/syncer/rsync/base_spec.rb +33 -0
  153. data/spec/configuration/syncer/rsync/local_spec.rb +10 -0
  154. data/spec/configuration/syncer/rsync/pull_spec.rb +10 -0
  155. data/spec/configuration/syncer/rsync/push_spec.rb +43 -0
  156. data/spec/configuration/syncer/s3_spec.rb +38 -0
  157. data/spec/database/base_spec.rb +54 -0
  158. data/spec/database/mongodb_spec.rb +428 -0
  159. data/spec/database/mysql_spec.rb +335 -0
  160. data/spec/database/postgresql_spec.rb +278 -0
  161. data/spec/database/redis_spec.rb +260 -0
  162. data/spec/database/riak_spec.rb +108 -0
  163. data/spec/dependency_spec.rb +49 -0
  164. data/spec/encryptor/base_spec.rb +30 -0
  165. data/spec/encryptor/gpg_spec.rb +134 -0
  166. data/spec/encryptor/open_ssl_spec.rb +129 -0
  167. data/spec/errors_spec.rb +306 -0
  168. data/spec/logger_spec.rb +363 -0
  169. data/spec/model_spec.rb +649 -0
  170. data/spec/notifier/base_spec.rb +89 -0
  171. data/spec/notifier/campfire_spec.rb +199 -0
  172. data/spec/notifier/hipchat_spec.rb +188 -0
  173. data/spec/notifier/mail_spec.rb +280 -0
  174. data/spec/notifier/presently_spec.rb +181 -0
  175. data/spec/notifier/prowl_spec.rb +117 -0
  176. data/spec/notifier/twitter_spec.rb +132 -0
  177. data/spec/package_spec.rb +61 -0
  178. data/spec/packager_spec.rb +225 -0
  179. data/spec/pipeline_spec.rb +257 -0
  180. data/spec/spec_helper.rb +59 -0
  181. data/spec/splitter_spec.rb +120 -0
  182. data/spec/storage/base_spec.rb +160 -0
  183. data/spec/storage/cloudfiles_spec.rb +230 -0
  184. data/spec/storage/cycler_spec.rb +239 -0
  185. data/spec/storage/dropbox_spec.rb +370 -0
  186. data/spec/storage/ftp_spec.rb +247 -0
  187. data/spec/storage/local_spec.rb +235 -0
  188. data/spec/storage/ninefold_spec.rb +319 -0
  189. data/spec/storage/rsync_spec.rb +345 -0
  190. data/spec/storage/s3_spec.rb +221 -0
  191. data/spec/storage/scp_spec.rb +209 -0
  192. data/spec/storage/sftp_spec.rb +220 -0
  193. data/spec/syncer/base_spec.rb +22 -0
  194. data/spec/syncer/cloud_files_spec.rb +192 -0
  195. data/spec/syncer/rsync/base_spec.rb +118 -0
  196. data/spec/syncer/rsync/local_spec.rb +121 -0
  197. data/spec/syncer/rsync/pull_spec.rb +90 -0
  198. data/spec/syncer/rsync/push_spec.rb +327 -0
  199. data/spec/syncer/s3_spec.rb +192 -0
  200. data/spec/version_spec.rb +21 -0
  201. data/templates/cli/utility/archive +25 -0
  202. data/templates/cli/utility/compressor/bzip2 +7 -0
  203. data/templates/cli/utility/compressor/gzip +7 -0
  204. data/templates/cli/utility/compressor/lzma +7 -0
  205. data/templates/cli/utility/compressor/pbzip2 +7 -0
  206. data/templates/cli/utility/config +31 -0
  207. data/templates/cli/utility/database/mongodb +18 -0
  208. data/templates/cli/utility/database/mysql +21 -0
  209. data/templates/cli/utility/database/postgresql +17 -0
  210. data/templates/cli/utility/database/redis +16 -0
  211. data/templates/cli/utility/database/riak +11 -0
  212. data/templates/cli/utility/encryptor/gpg +12 -0
  213. data/templates/cli/utility/encryptor/openssl +9 -0
  214. data/templates/cli/utility/model.erb +23 -0
  215. data/templates/cli/utility/notifier/campfire +12 -0
  216. data/templates/cli/utility/notifier/hipchat +15 -0
  217. data/templates/cli/utility/notifier/mail +22 -0
  218. data/templates/cli/utility/notifier/presently +13 -0
  219. data/templates/cli/utility/notifier/prowl +11 -0
  220. data/templates/cli/utility/notifier/twitter +13 -0
  221. data/templates/cli/utility/splitter +7 -0
  222. data/templates/cli/utility/storage/cloud_files +22 -0
  223. data/templates/cli/utility/storage/dropbox +20 -0
  224. data/templates/cli/utility/storage/ftp +12 -0
  225. data/templates/cli/utility/storage/local +7 -0
  226. data/templates/cli/utility/storage/ninefold +9 -0
  227. data/templates/cli/utility/storage/rsync +11 -0
  228. data/templates/cli/utility/storage/s3 +19 -0
  229. data/templates/cli/utility/storage/scp +11 -0
  230. data/templates/cli/utility/storage/sftp +11 -0
  231. data/templates/cli/utility/syncer/cloud_files +48 -0
  232. data/templates/cli/utility/syncer/rsync_local +12 -0
  233. data/templates/cli/utility/syncer/rsync_pull +17 -0
  234. data/templates/cli/utility/syncer/rsync_push +17 -0
  235. data/templates/cli/utility/syncer/s3 +45 -0
  236. data/templates/general/links +11 -0
  237. data/templates/general/version.erb +2 -0
  238. data/templates/notifier/mail/failure.erb +9 -0
  239. data/templates/notifier/mail/success.erb +7 -0
  240. data/templates/notifier/mail/warning.erb +9 -0
  241. data/templates/storage/dropbox/authorization_url.erb +6 -0
  242. data/templates/storage/dropbox/authorized.erb +4 -0
  243. data/templates/storage/dropbox/cache_file_written.erb +10 -0
  244. metadata +311 -0
@@ -0,0 +1,278 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path('../../spec_helper.rb', __FILE__)
4
+
5
+ describe Backup::Database::PostgreSQL do
6
+ let(:model) { Backup::Model.new('foo', 'foo') }
7
+ let(:db) do
8
+ Backup::Database::PostgreSQL.new(model) do |db|
9
+ db.name = 'mydatabase'
10
+ db.username = 'someuser'
11
+ db.password = 'secret'
12
+ db.host = 'localhost'
13
+ db.port = '123'
14
+ db.socket = '/pgsql.sock'
15
+
16
+ db.skip_tables = ['logs', 'profiles']
17
+ db.only_tables = ['users', 'pirates']
18
+ db.additional_options = ['--single-transaction', '--quick']
19
+ db.pg_dump_utility = '/path/to/pg_dump'
20
+ end
21
+ end
22
+
23
+ describe '#initialize' do
24
+ it 'should read the adapter details correctly' do
25
+ db.name.should == 'mydatabase'
26
+ db.username.should == 'someuser'
27
+ db.password.should == 'secret'
28
+ db.host.should == 'localhost'
29
+ db.port.should == '123'
30
+ db.socket.should == '/pgsql.sock'
31
+
32
+ db.skip_tables.should == ['logs', 'profiles']
33
+ db.only_tables.should == ['users', 'pirates']
34
+ db.additional_options.should == ['--single-transaction', '--quick']
35
+ db.pg_dump_utility.should == '/path/to/pg_dump'
36
+ end
37
+
38
+ context 'when options are not set' do
39
+ before do
40
+ Backup::Database::PostgreSQL.any_instance.expects(:utility).
41
+ with(:pg_dump).returns('/real/pg_dump')
42
+ end
43
+
44
+ it 'should use default values' do
45
+ db = Backup::Database::PostgreSQL.new(model)
46
+
47
+ db.name.should be_nil
48
+ db.username.should be_nil
49
+ db.password.should be_nil
50
+ db.host.should be_nil
51
+ db.port.should be_nil
52
+ db.socket.should be_nil
53
+
54
+ db.skip_tables.should == []
55
+ db.only_tables.should == []
56
+ db.additional_options.should == []
57
+ db.pg_dump_utility.should == '/real/pg_dump'
58
+ end
59
+ end
60
+
61
+ context 'when configuration defaults have been set' do
62
+ after { Backup::Configuration::Database::PostgreSQL.clear_defaults! }
63
+
64
+ it 'should use configuration defaults' do
65
+ Backup::Configuration::Database::PostgreSQL.defaults do |db|
66
+ db.name = 'db_name'
67
+ db.username = 'db_username'
68
+ db.password = 'db_password'
69
+ db.host = 'db_host'
70
+ db.port = 789
71
+ db.socket = '/foo.sock'
72
+
73
+ db.skip_tables = ['skip', 'tables']
74
+ db.only_tables = ['only', 'tables']
75
+ db.additional_options = ['--add', '--opts']
76
+ db.pg_dump_utility = '/default/path/to/pg_dump'
77
+ end
78
+
79
+ db = Backup::Database::PostgreSQL.new(model)
80
+ db.name.should == 'db_name'
81
+ db.username.should == 'db_username'
82
+ db.password.should == 'db_password'
83
+ db.host.should == 'db_host'
84
+ db.port.should == 789
85
+ db.socket.should == '/foo.sock'
86
+
87
+ db.skip_tables.should == ['skip', 'tables']
88
+ db.only_tables.should == ['only', 'tables']
89
+ db.additional_options.should == ['--add', '--opts']
90
+ db.pg_dump_utility.should == '/default/path/to/pg_dump'
91
+ end
92
+ end
93
+ end # describe '#initialize'
94
+
95
+ describe '#perform!' do
96
+ let(:s) { sequence '' }
97
+ let(:pipeline) { mock }
98
+
99
+ before do
100
+ # superclass actions
101
+ db.expects(:prepare!).in_sequence(s)
102
+ db.expects(:log!).in_sequence(s)
103
+ db.instance_variable_set(:@dump_path, '/dump/path')
104
+
105
+ db.stubs(:pgdump).returns('pgdump_command')
106
+ Backup::Pipeline.expects(:new).returns(pipeline)
107
+ end
108
+
109
+ context 'when no compressor is configured' do
110
+ before do
111
+ model.expects(:compressor).returns(nil)
112
+ end
113
+
114
+ it 'should run pgdump without compression' do
115
+ pipeline.expects(:<<).in_sequence(s).with('pgdump_command')
116
+ pipeline.expects(:<<).in_sequence(s).with(
117
+ "cat > '/dump/path/mydatabase.sql'"
118
+ )
119
+ pipeline.expects(:run).in_sequence(s)
120
+ pipeline.expects(:success?).in_sequence(s).returns(true)
121
+ Backup::Logger.expects(:message).in_sequence(s).with(
122
+ 'Database::PostgreSQL Complete!'
123
+ )
124
+
125
+ db.perform!
126
+ end
127
+ end
128
+
129
+ context 'when a compressor is configured' do
130
+ before do
131
+ compressor = mock
132
+ model.expects(:compressor).twice.returns(compressor)
133
+ compressor.expects(:compress_with).yields('gzip', '.gz')
134
+ end
135
+
136
+ it 'should run pgdump with compression' do
137
+ pipeline.expects(:<<).in_sequence(s).with('pgdump_command')
138
+ pipeline.expects(:<<).in_sequence(s).with('gzip')
139
+ pipeline.expects(:<<).in_sequence(s).with(
140
+ "cat > '/dump/path/mydatabase.sql.gz'"
141
+ )
142
+ pipeline.expects(:run).in_sequence(s)
143
+ pipeline.expects(:success?).in_sequence(s).returns(true)
144
+ Backup::Logger.expects(:message).in_sequence(s).with(
145
+ 'Database::PostgreSQL Complete!'
146
+ )
147
+
148
+ db.perform!
149
+ end
150
+ end
151
+
152
+ context 'when pipeline command fails' do
153
+ before do
154
+ model.expects(:compressor).returns(nil)
155
+ pipeline.stubs(:<<)
156
+ pipeline.expects(:run)
157
+ pipeline.expects(:success?).returns(false)
158
+ pipeline.expects(:error_messages).returns('pipeline_errors')
159
+ end
160
+
161
+ it 'should raise an error' do
162
+ expect do
163
+ db.perform!
164
+ end.to raise_error(
165
+ Backup::Errors::Database::PipelineError,
166
+ "Database::PipelineError: Database::PostgreSQL Dump Failed!\n" +
167
+ " pipeline_errors"
168
+ )
169
+ end
170
+ end # context 'when pipeline command fails'
171
+
172
+ end # describe '#perform!'
173
+
174
+ describe '#pgdump' do
175
+ it 'should return the pgdump command string' do
176
+ db.send(:pgdump).should ==
177
+ "PGPASSWORD='secret' /path/to/pg_dump --username='someuser' " +
178
+ "--host='localhost' --port='123' --host='/pgsql.sock' " +
179
+ "--single-transaction --quick --table='users' --table='pirates' " +
180
+ "--exclude-table='logs' --exclude-table='profiles' mydatabase"
181
+ end
182
+
183
+ context 'without a password' do
184
+ before { db.password = nil }
185
+ it 'should not leave a preceeding space' do
186
+ db.send(:pgdump).should ==
187
+ "/path/to/pg_dump --username='someuser' " +
188
+ "--host='localhost' --port='123' --host='/pgsql.sock' " +
189
+ "--single-transaction --quick --table='users' --table='pirates' " +
190
+ "--exclude-table='logs' --exclude-table='profiles' mydatabase"
191
+ end
192
+ end
193
+ end
194
+
195
+ describe '#password_options' do
196
+ it 'returns the environment variable set for the password' do
197
+ db.send(:password_options).should == "PGPASSWORD='secret' "
198
+ end
199
+
200
+ context 'when password is not set' do
201
+ before { db.password = nil }
202
+ it 'should return an empty string' do
203
+ db.send(:password_options).should == ''
204
+ end
205
+ end
206
+ end
207
+
208
+ describe '#username_options' do
209
+ it 'should return the postgresql syntax for the username options' do
210
+ db.send(:username_options).should == "--username='someuser'"
211
+ end
212
+
213
+ context 'when username is not set' do
214
+ before { db.username = nil }
215
+ it 'should return an empty string' do
216
+ db.send(:username_options).should == ''
217
+ end
218
+ end
219
+ end
220
+
221
+ describe '#connectivity_options' do
222
+ it 'should return the postgresql syntax for the connectivity options' do
223
+ db.send(:connectivity_options).should ==
224
+ "--host='localhost' --port='123' --host='/pgsql.sock'"
225
+ end
226
+
227
+ context 'when only the socket is set' do
228
+ before do
229
+ db.host = ''
230
+ db.port = nil
231
+ end
232
+
233
+ it 'should return only the socket' do
234
+ db.send(:connectivity_options).should == "--host='/pgsql.sock'"
235
+ end
236
+ end
237
+ end
238
+
239
+ describe '#user_options' do
240
+ it 'should return a string of additional options specified by the user' do
241
+ db.send(:user_options).should == '--single-transaction --quick'
242
+ end
243
+
244
+ context 'when #additional_options is not set' do
245
+ before { db.additional_options = [] }
246
+ it 'should return an empty string' do
247
+ db.send(:user_options).should == ''
248
+ end
249
+ end
250
+ end
251
+
252
+ describe '#tables_to_dump' do
253
+ it 'should return a string for the pg_dump selected table to dump option' do
254
+ db.send(:tables_to_dump).should == "--table='users' --table='pirates'"
255
+ end
256
+
257
+ context 'when #only_tables is not set' do
258
+ before { db.only_tables = [] }
259
+ it 'should return an empty string' do
260
+ db.send(:tables_to_dump).should == ''
261
+ end
262
+ end
263
+ end
264
+
265
+ describe '#tables_to_skip' do
266
+ it 'should return a string for the pg_dump --ignore-tables option' do
267
+ db.send(:tables_to_skip).should == "--exclude-table='logs' --exclude-table='profiles'"
268
+ end
269
+
270
+ context 'when #skip_tables is not set' do
271
+ before { db.skip_tables = [] }
272
+ it 'should return an empty string' do
273
+ db.send(:tables_to_skip).should == ''
274
+ end
275
+ end
276
+ end
277
+
278
+ end
@@ -0,0 +1,260 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path('../../spec_helper.rb', __FILE__)
4
+
5
+ describe Backup::Database::Redis do
6
+ let(:model) { Backup::Model.new('foo', 'foo') }
7
+ let(:db) do
8
+ Backup::Database::Redis.new(model) do |db|
9
+ db.name = 'mydatabase'
10
+ db.path = '/var/lib/redis/db/'
11
+ db.password = 'secret'
12
+ db.host = 'localhost'
13
+ db.port = '123'
14
+ db.socket = '/redis.sock'
15
+ db.invoke_save = true
16
+
17
+ db.additional_options = ['--query', '--foo']
18
+ db.redis_cli_utility = '/path/to/redis-cli'
19
+ end
20
+ end
21
+
22
+ describe '#initialize' do
23
+ it 'should read the adapter details correctly' do
24
+ db.name.should == 'mydatabase'
25
+ db.path.should == '/var/lib/redis/db/'
26
+ db.password.should == 'secret'
27
+ db.host.should == 'localhost'
28
+ db.port.should == '123'
29
+ db.socket.should == '/redis.sock'
30
+ db.invoke_save.should == true
31
+
32
+ db.additional_options.should == ['--query', '--foo']
33
+ db.redis_cli_utility.should == '/path/to/redis-cli'
34
+ end
35
+
36
+ context 'when options are not set' do
37
+ before do
38
+ Backup::Database::Redis.any_instance.expects(:utility).
39
+ with('redis-cli').returns('/real/redis-cli')
40
+ end
41
+
42
+ it 'should use default values' do
43
+ db = Backup::Database::Redis.new(model)
44
+
45
+ db.name.should == 'dump'
46
+ db.path.should be_nil
47
+ db.password.should be_nil
48
+ db.host.should be_nil
49
+ db.port.should be_nil
50
+ db.socket.should be_nil
51
+ db.invoke_save.should be_nil
52
+
53
+ db.additional_options.should == []
54
+ db.redis_cli_utility.should == '/real/redis-cli'
55
+ end
56
+ end
57
+
58
+ context 'when configuration defaults have been set' do
59
+ after { Backup::Configuration::Database::Redis.clear_defaults! }
60
+
61
+ it 'should use configuration defaults' do
62
+ Backup::Configuration::Database::Redis.defaults do |db|
63
+ db.name = 'db_name'
64
+ db.path = 'db_path'
65
+ db.password = 'db_password'
66
+ db.host = 'db_host'
67
+ db.port = 789
68
+ db.socket = '/foo.sock'
69
+ db.invoke_save = true
70
+
71
+ db.additional_options = ['--add', '--opts']
72
+ db.redis_cli_utility = '/default/path/to/redis-cli'
73
+ end
74
+
75
+ db = Backup::Database::Redis.new(model)
76
+ db.name.should == 'db_name'
77
+ db.path.should == 'db_path'
78
+ db.password.should == 'db_password'
79
+ db.host.should == 'db_host'
80
+ db.port.should == 789
81
+ db.socket.should == '/foo.sock'
82
+ db.invoke_save.should == true
83
+
84
+ db.additional_options.should == ['--add', '--opts']
85
+ db.redis_cli_utility.should == '/default/path/to/redis-cli'
86
+ end
87
+ end
88
+ end # describe '#initialize'
89
+
90
+ describe '#perform!' do
91
+ let(:s) { sequence '' }
92
+ before do
93
+ # superclass actions
94
+ db.expects(:prepare!).in_sequence(s)
95
+ db.expects(:log!).in_sequence(s)
96
+ end
97
+
98
+ context 'when #invoke_save is true' do
99
+ before { db.invoke_save = true }
100
+ it 'should copy over after persisting (saving) the most recent updates' do
101
+ db.expects(:invoke_save!).in_sequence(s)
102
+ db.expects(:copy!).in_sequence(s)
103
+
104
+ db.perform!
105
+ end
106
+ end
107
+
108
+ context 'when #invoke_save is not true' do
109
+ before { db.invoke_save = nil }
110
+ it 'should copy over without persisting (saving) first' do
111
+ db.expects(:invoke_save!).never
112
+ db.expects(:copy!).in_sequence(s)
113
+
114
+ db.perform!
115
+ end
116
+ end
117
+
118
+ end # describe '#perform!'
119
+
120
+ describe '#invoke_save!' do
121
+ before do
122
+ db.stubs(:credential_options).returns(:credential_options_output)
123
+ db.stubs(:connectivity_options).returns(:connectivity_options_output)
124
+ db.stubs(:user_options).returns(:user_options_output)
125
+ end
126
+
127
+ context 'when response is OK' do
128
+ it 'should run the redis-cli command string' do
129
+ db.expects(:run).with(
130
+ '/path/to/redis-cli credential_options_output ' +
131
+ 'connectivity_options_output user_options_output SAVE'
132
+ ).returns('result OK for command')
133
+
134
+ expect do
135
+ db.send(:invoke_save!)
136
+ end.not_to raise_error
137
+ end
138
+ end
139
+
140
+ context 'when response is not OK' do
141
+ it 'should raise an error' do
142
+ db.stubs(:run).returns('result not ok for command')
143
+ db.stubs(:database).returns('database_filename')
144
+
145
+ expect do
146
+ db.send(:invoke_save!)
147
+ end.to raise_error {|err|
148
+ err.should be_an_instance_of Backup::Errors::Database::Redis::CommandError
149
+ err.message.should match(/Could not invoke the Redis SAVE command/)
150
+ err.message.should match(/The database_filename file/)
151
+ err.message.should match(/Redis CLI response: result not ok/)
152
+ }
153
+ end
154
+ end
155
+
156
+ end # describe '#invoke_save!'
157
+
158
+ describe '#copy!' do
159
+ let(:src_path) { '/var/lib/redis/db/mydatabase.rdb' }
160
+ let(:dst_path) { '/dump/path/mydatabase.rdb' }
161
+ let(:compressor) { mock }
162
+
163
+ context 'when the database exists' do
164
+ before do
165
+ db.instance_variable_set(:@dump_path, '/dump/path')
166
+ File.expects(:exist?).with(src_path).returns(true)
167
+ end
168
+
169
+ context 'when no compressor is configured' do
170
+ it 'should copy the database' do
171
+ db.expects(:run).never
172
+
173
+ FileUtils.expects(:cp).with(src_path, dst_path)
174
+ db.send(:copy!)
175
+ end
176
+ end
177
+
178
+ context 'when a compressor is configured' do
179
+ before do
180
+ model.stubs(:compressor).returns(compressor)
181
+ compressor.expects(:compress_with).yields('compressor_command', '.gz')
182
+ end
183
+
184
+ it 'should copy the database using the compressor' do
185
+ FileUtils.expects(:cp).never
186
+
187
+ db.expects(:run).with(
188
+ "compressor_command -c #{ src_path } > #{ dst_path }.gz"
189
+ )
190
+ db.send(:copy!)
191
+ end
192
+ end
193
+ end
194
+
195
+ context 'when the database does not exist' do
196
+ it 'should raise an error if the database dump file is not found' do
197
+ File.expects(:exist?).returns(false)
198
+ expect do
199
+ db.send(:copy!)
200
+ end.to raise_error do |err|
201
+ err.should be_an_instance_of Backup::Errors::Database::Redis::NotFoundError
202
+ err.message.should match(/Redis database dump not found/)
203
+ err.message.should match(/File path was #{src_path}/)
204
+ end
205
+ end
206
+ end
207
+ end # describe '#copy!'
208
+
209
+ describe '#database' do
210
+ it 'should return the database name with the extension added' do
211
+ db.send(:database).should == 'mydatabase.rdb'
212
+ end
213
+ end
214
+
215
+ describe '#credential_options' do
216
+ context 'when #password is set' do
217
+ it 'should return the redis-cli syntax for the credential options' do
218
+ db.send(:credential_options).should == "-a 'secret'"
219
+ end
220
+ end
221
+
222
+ context 'when password is not set' do
223
+ it 'should return an empty string' do
224
+ db.password = nil
225
+ db.send(:credential_options).should == ''
226
+ end
227
+ end
228
+ end
229
+
230
+ describe '#connectivity_options' do
231
+ it 'should return the redis syntax for the connectivity options' do
232
+ db.send(:connectivity_options).should ==
233
+ "-h 'localhost' -p '123' -s '/redis.sock'"
234
+ end
235
+
236
+ context 'when only the #port is set' do
237
+ it 'should return only the port' do
238
+ db.host = nil
239
+ db.socket = nil
240
+ db.send(:connectivity_options).should == "-p '123'"
241
+ end
242
+ end
243
+ end
244
+
245
+ describe '#user_options' do
246
+ context 'when #additional_options are set' do
247
+ it 'should return the options' do
248
+ db.send(:user_options).should == '--query --foo'
249
+ end
250
+ end
251
+
252
+ context 'when #additional_options is not set' do
253
+ it 'should return an empty string' do
254
+ db.additional_options = []
255
+ db.send(:user_options).should == ''
256
+ end
257
+ end
258
+ end
259
+
260
+ end