backup 3.0.23 → 3.0.24

Sign up to get free protection for your applications and to get access to all the features.
Files changed (197) hide show
  1. data/Gemfile.lock +42 -45
  2. data/Guardfile +7 -4
  3. data/README.md +10 -7
  4. data/backup.gemspec +2 -2
  5. data/lib/backup.rb +27 -97
  6. data/lib/backup/archive.rb +14 -6
  7. data/lib/backup/cli/helpers.rb +52 -49
  8. data/lib/backup/cli/utility.rb +9 -1
  9. data/lib/backup/compressor/base.rb +10 -4
  10. data/lib/backup/compressor/bzip2.rb +22 -26
  11. data/lib/backup/compressor/custom.rb +53 -0
  12. data/lib/backup/compressor/gzip.rb +22 -23
  13. data/lib/backup/compressor/lzma.rb +15 -13
  14. data/lib/backup/compressor/pbzip2.rb +20 -17
  15. data/lib/backup/config.rb +6 -3
  16. data/lib/backup/configuration.rb +33 -0
  17. data/lib/backup/configuration/helpers.rb +114 -28
  18. data/lib/backup/configuration/store.rb +24 -0
  19. data/lib/backup/database/base.rb +0 -6
  20. data/lib/backup/database/mongodb.rb +27 -11
  21. data/lib/backup/database/mysql.rb +19 -14
  22. data/lib/backup/database/postgresql.rb +16 -11
  23. data/lib/backup/database/redis.rb +7 -11
  24. data/lib/backup/database/riak.rb +3 -6
  25. data/lib/backup/dependency.rb +5 -11
  26. data/lib/backup/model.rb +14 -5
  27. data/lib/backup/notifier/campfire.rb +3 -16
  28. data/lib/backup/notifier/hipchat.rb +1 -7
  29. data/lib/backup/notifier/mail.rb +1 -1
  30. data/lib/backup/packager.rb +29 -19
  31. data/lib/backup/pipeline.rb +110 -0
  32. data/lib/backup/storage/dropbox.rb +4 -7
  33. data/lib/backup/syncer/base.rb +8 -4
  34. data/lib/backup/syncer/cloud/base.rb +247 -0
  35. data/lib/backup/syncer/cloud/cloud_files.rb +78 -0
  36. data/lib/backup/syncer/cloud/s3.rb +68 -0
  37. data/lib/backup/syncer/rsync/base.rb +1 -4
  38. data/lib/backup/syncer/rsync/local.rb +9 -5
  39. data/lib/backup/syncer/rsync/pull.rb +1 -1
  40. data/lib/backup/syncer/rsync/push.rb +10 -5
  41. data/lib/backup/version.rb +1 -1
  42. data/spec-live/.gitignore +6 -0
  43. data/spec-live/README +7 -0
  44. data/spec-live/backups/config.rb +153 -0
  45. data/spec-live/backups/config.yml.template +43 -0
  46. data/spec-live/compressor/custom_spec.rb +30 -0
  47. data/spec-live/compressor/gzip_spec.rb +30 -0
  48. data/spec-live/notifier/mail_spec.rb +85 -0
  49. data/spec-live/spec_helper.rb +85 -0
  50. data/spec-live/storage/dropbox_spec.rb +151 -0
  51. data/spec-live/storage/local_spec.rb +83 -0
  52. data/spec-live/storage/scp_spec.rb +193 -0
  53. data/spec-live/syncer/cloud/s3_spec.rb +124 -0
  54. data/spec/archive_spec.rb +86 -31
  55. data/spec/cleaner_spec.rb +8 -0
  56. data/spec/cli/helpers_spec.rb +200 -75
  57. data/spec/cli/utility_spec.rb +11 -3
  58. data/spec/compressor/base_spec.rb +31 -10
  59. data/spec/compressor/bzip2_spec.rb +212 -57
  60. data/spec/compressor/custom_spec.rb +106 -0
  61. data/spec/compressor/gzip_spec.rb +212 -57
  62. data/spec/compressor/lzma_spec.rb +75 -35
  63. data/spec/compressor/pbzip2_spec.rb +93 -52
  64. data/spec/configuration/helpers_spec.rb +406 -0
  65. data/spec/configuration/store_spec.rb +39 -0
  66. data/spec/configuration_spec.rb +62 -0
  67. data/spec/database/base_spec.rb +19 -10
  68. data/spec/database/mongodb_spec.rb +195 -70
  69. data/spec/database/mysql_spec.rb +183 -64
  70. data/spec/database/postgresql_spec.rb +167 -53
  71. data/spec/database/redis_spec.rb +121 -46
  72. data/spec/database/riak_spec.rb +96 -27
  73. data/spec/dependency_spec.rb +2 -0
  74. data/spec/encryptor/base_spec.rb +10 -0
  75. data/spec/encryptor/gpg_spec.rb +29 -13
  76. data/spec/encryptor/open_ssl_spec.rb +40 -21
  77. data/spec/logger_spec.rb +4 -0
  78. data/spec/model_spec.rb +19 -2
  79. data/spec/notifier/base_spec.rb +32 -17
  80. data/spec/notifier/campfire_spec.rb +63 -45
  81. data/spec/notifier/hipchat_spec.rb +79 -56
  82. data/spec/notifier/mail_spec.rb +82 -46
  83. data/spec/notifier/prowl_spec.rb +53 -32
  84. data/spec/notifier/twitter_spec.rb +62 -41
  85. data/spec/packager_spec.rb +95 -36
  86. data/spec/pipeline_spec.rb +259 -0
  87. data/spec/spec_helper.rb +6 -5
  88. data/spec/storage/base_spec.rb +61 -41
  89. data/spec/storage/cloudfiles_spec.rb +69 -45
  90. data/spec/storage/dropbox_spec.rb +158 -36
  91. data/spec/storage/ftp_spec.rb +69 -45
  92. data/spec/storage/local_spec.rb +47 -23
  93. data/spec/storage/ninefold_spec.rb +55 -31
  94. data/spec/storage/rsync_spec.rb +67 -50
  95. data/spec/storage/s3_spec.rb +65 -41
  96. data/spec/storage/scp_spec.rb +65 -41
  97. data/spec/storage/sftp_spec.rb +65 -41
  98. data/spec/syncer/base_spec.rb +91 -4
  99. data/spec/syncer/cloud/base_spec.rb +511 -0
  100. data/spec/syncer/cloud/cloud_files_spec.rb +181 -0
  101. data/spec/syncer/cloud/s3_spec.rb +174 -0
  102. data/spec/syncer/rsync/base_spec.rb +46 -66
  103. data/spec/syncer/rsync/local_spec.rb +55 -26
  104. data/spec/syncer/rsync/pull_spec.rb +15 -4
  105. data/spec/syncer/rsync/push_spec.rb +59 -52
  106. data/templates/cli/utility/compressor/bzip2 +1 -4
  107. data/templates/cli/utility/compressor/custom +11 -0
  108. data/templates/cli/utility/compressor/gzip +1 -4
  109. data/templates/cli/utility/compressor/lzma +3 -0
  110. data/templates/cli/utility/compressor/pbzip2 +3 -0
  111. data/templates/cli/utility/database/mysql +4 -1
  112. data/templates/cli/utility/syncer/cloud_files +17 -19
  113. data/templates/cli/utility/syncer/s3 +18 -20
  114. metadata +38 -92
  115. data/lib/backup/configuration/base.rb +0 -15
  116. data/lib/backup/configuration/compressor/base.rb +0 -9
  117. data/lib/backup/configuration/compressor/bzip2.rb +0 -23
  118. data/lib/backup/configuration/compressor/gzip.rb +0 -23
  119. data/lib/backup/configuration/compressor/lzma.rb +0 -23
  120. data/lib/backup/configuration/compressor/pbzip2.rb +0 -28
  121. data/lib/backup/configuration/database/base.rb +0 -19
  122. data/lib/backup/configuration/database/mongodb.rb +0 -49
  123. data/lib/backup/configuration/database/mysql.rb +0 -42
  124. data/lib/backup/configuration/database/postgresql.rb +0 -41
  125. data/lib/backup/configuration/database/redis.rb +0 -39
  126. data/lib/backup/configuration/database/riak.rb +0 -29
  127. data/lib/backup/configuration/encryptor/base.rb +0 -9
  128. data/lib/backup/configuration/encryptor/gpg.rb +0 -17
  129. data/lib/backup/configuration/encryptor/open_ssl.rb +0 -32
  130. data/lib/backup/configuration/notifier/base.rb +0 -28
  131. data/lib/backup/configuration/notifier/campfire.rb +0 -25
  132. data/lib/backup/configuration/notifier/hipchat.rb +0 -41
  133. data/lib/backup/configuration/notifier/mail.rb +0 -112
  134. data/lib/backup/configuration/notifier/presently.rb +0 -25
  135. data/lib/backup/configuration/notifier/prowl.rb +0 -23
  136. data/lib/backup/configuration/notifier/twitter.rb +0 -21
  137. data/lib/backup/configuration/storage/base.rb +0 -18
  138. data/lib/backup/configuration/storage/cloudfiles.rb +0 -25
  139. data/lib/backup/configuration/storage/dropbox.rb +0 -58
  140. data/lib/backup/configuration/storage/ftp.rb +0 -29
  141. data/lib/backup/configuration/storage/local.rb +0 -17
  142. data/lib/backup/configuration/storage/ninefold.rb +0 -20
  143. data/lib/backup/configuration/storage/rsync.rb +0 -29
  144. data/lib/backup/configuration/storage/s3.rb +0 -25
  145. data/lib/backup/configuration/storage/scp.rb +0 -25
  146. data/lib/backup/configuration/storage/sftp.rb +0 -25
  147. data/lib/backup/configuration/syncer/base.rb +0 -10
  148. data/lib/backup/configuration/syncer/cloud.rb +0 -23
  149. data/lib/backup/configuration/syncer/cloud_files.rb +0 -30
  150. data/lib/backup/configuration/syncer/rsync/base.rb +0 -28
  151. data/lib/backup/configuration/syncer/rsync/local.rb +0 -11
  152. data/lib/backup/configuration/syncer/rsync/pull.rb +0 -11
  153. data/lib/backup/configuration/syncer/rsync/push.rb +0 -31
  154. data/lib/backup/configuration/syncer/s3.rb +0 -23
  155. data/lib/backup/notifier/presently.rb +0 -88
  156. data/lib/backup/syncer/cloud.rb +0 -187
  157. data/lib/backup/syncer/cloud_files.rb +0 -56
  158. data/lib/backup/syncer/s3.rb +0 -47
  159. data/spec/configuration/base_spec.rb +0 -35
  160. data/spec/configuration/compressor/bzip2_spec.rb +0 -29
  161. data/spec/configuration/compressor/gzip_spec.rb +0 -29
  162. data/spec/configuration/compressor/lzma_spec.rb +0 -29
  163. data/spec/configuration/compressor/pbzip2_spec.rb +0 -32
  164. data/spec/configuration/database/base_spec.rb +0 -17
  165. data/spec/configuration/database/mongodb_spec.rb +0 -56
  166. data/spec/configuration/database/mysql_spec.rb +0 -53
  167. data/spec/configuration/database/postgresql_spec.rb +0 -53
  168. data/spec/configuration/database/redis_spec.rb +0 -50
  169. data/spec/configuration/database/riak_spec.rb +0 -35
  170. data/spec/configuration/encryptor/gpg_spec.rb +0 -26
  171. data/spec/configuration/encryptor/open_ssl_spec.rb +0 -35
  172. data/spec/configuration/notifier/base_spec.rb +0 -32
  173. data/spec/configuration/notifier/campfire_spec.rb +0 -32
  174. data/spec/configuration/notifier/hipchat_spec.rb +0 -44
  175. data/spec/configuration/notifier/mail_spec.rb +0 -71
  176. data/spec/configuration/notifier/presently_spec.rb +0 -35
  177. data/spec/configuration/notifier/prowl_spec.rb +0 -29
  178. data/spec/configuration/notifier/twitter_spec.rb +0 -35
  179. data/spec/configuration/storage/cloudfiles_spec.rb +0 -41
  180. data/spec/configuration/storage/dropbox_spec.rb +0 -38
  181. data/spec/configuration/storage/ftp_spec.rb +0 -44
  182. data/spec/configuration/storage/local_spec.rb +0 -29
  183. data/spec/configuration/storage/ninefold_spec.rb +0 -32
  184. data/spec/configuration/storage/rsync_spec.rb +0 -41
  185. data/spec/configuration/storage/s3_spec.rb +0 -38
  186. data/spec/configuration/storage/scp_spec.rb +0 -41
  187. data/spec/configuration/storage/sftp_spec.rb +0 -41
  188. data/spec/configuration/syncer/cloud_files_spec.rb +0 -44
  189. data/spec/configuration/syncer/rsync/base_spec.rb +0 -33
  190. data/spec/configuration/syncer/rsync/local_spec.rb +0 -10
  191. data/spec/configuration/syncer/rsync/pull_spec.rb +0 -10
  192. data/spec/configuration/syncer/rsync/push_spec.rb +0 -43
  193. data/spec/configuration/syncer/s3_spec.rb +0 -38
  194. data/spec/notifier/presently_spec.rb +0 -181
  195. data/spec/syncer/cloud_files_spec.rb +0 -192
  196. data/spec/syncer/s3_spec.rb +0 -192
  197. data/templates/cli/utility/notifier/presently +0 -13
@@ -6,10 +6,25 @@ describe Backup::Database::Base do
6
6
  let(:model) { Backup::Model.new('foo', 'foo') }
7
7
  let(:db) { Backup::Database::Base.new(model) }
8
8
 
9
- it 'should set #utility_path' do
10
- db.utility_path.should be_nil
11
- db.utility_path = 'utility path'
12
- db.utility_path.should == 'utility path'
9
+ it 'should include CLI::Helpers' do
10
+ Backup::Database::Base.
11
+ include?(Backup::CLI::Helpers).should be_true
12
+ end
13
+
14
+ it 'should include Configuration::Helpers' do
15
+ Backup::Database::Base.
16
+ include?(Backup::Configuration::Helpers).should be_true
17
+ end
18
+
19
+ describe '#initialize' do
20
+ it 'should load pre-configured defaults' do
21
+ Backup::Database::Base.any_instance.expects(:load_defaults!)
22
+ db
23
+ end
24
+
25
+ it 'should set a reference to the model' do
26
+ db.instance_variable_get(:@model).should == model
27
+ end
13
28
  end
14
29
 
15
30
  describe '#perform!' do
@@ -22,12 +37,6 @@ describe Backup::Database::Base do
22
37
  end
23
38
  end
24
39
 
25
- context 'since CLI::Helpers are included' do
26
- it 'should respond to the #utility method' do
27
- db.respond_to?(:utility).should be_true
28
- end
29
- end
30
-
31
40
  describe '#prepare!' do
32
41
  it 'should set and create #dump_path' do
33
42
  model = stub(:trigger => 'test_trigger')
@@ -17,86 +17,127 @@ describe Backup::Database::MongoDB do
17
17
  db.additional_options = ['--query', '--foo']
18
18
  db.mongodump_utility = '/path/to/mongodump'
19
19
  db.mongo_utility = '/path/to/mongo'
20
+ db.lock = true
20
21
  end
21
22
  end
22
23
 
24
+ it 'should be a subclass of Database::Base' do
25
+ Backup::Database::MongoDB.superclass.
26
+ should == Backup::Database::Base
27
+ end
28
+
23
29
  describe '#initialize' do
24
30
 
25
- it 'should read the adapter details correctly' do
26
- db.name.should == 'mydatabase'
27
- db.username.should == 'someuser'
28
- db.password.should == 'secret'
29
- db.host.should == 'localhost'
30
- db.port.should == 123
31
-
32
- db.ipv6.should == true
33
- db.only_collections.should == ['users', 'pirates']
34
- db.additional_options.should == ['--query', '--foo']
35
- db.mongodump_utility.should == '/path/to/mongodump'
36
- db.mongo_utility.should == '/path/to/mongo'
37
- db.lock.should == false
31
+ it 'should load pre-configured defaults through Base' do
32
+ Backup::Database::MongoDB.any_instance.expects(:load_defaults!)
33
+ db
38
34
  end
39
35
 
40
- context 'when options are not set' do
41
- before do
42
- Backup::Database::MongoDB.any_instance.expects(:utility).
43
- with(:mongodump).returns('/real/mongodump')
44
- Backup::Database::MongoDB.any_instance.expects(:utility).
45
- with(:mongo).returns('/real/mongo')
46
- end
36
+ it 'should pass the model reference to Base' do
37
+ db.instance_variable_get(:@model).should == model
38
+ end
47
39
 
48
- it 'should use default values' do
49
- db = Backup::Database::MongoDB.new(model)
50
-
51
- db.name.should be_nil
52
- db.username.should be_nil
53
- db.password.should be_nil
54
- db.host.should be_nil
55
- db.port.should be_nil
56
-
57
- db.ipv6.should be_false
58
- db.only_collections.should == []
59
- db.additional_options.should == []
60
- db.mongodump_utility.should == '/real/mongodump'
61
- db.mongo_utility.should == '/real/mongo'
62
- db.lock.should be_false
40
+ context 'when no pre-configured defaults have been set' do
41
+ context 'when options are specified' do
42
+ it 'should use the given values' do
43
+ db.name.should == 'mydatabase'
44
+ db.username.should == 'someuser'
45
+ db.password.should == 'secret'
46
+ db.host.should == 'localhost'
47
+ db.port.should == 123
48
+
49
+ db.ipv6.should == true
50
+ db.only_collections.should == ['users', 'pirates']
51
+ db.additional_options.should == ['--query', '--foo']
52
+ db.mongodump_utility.should == '/path/to/mongodump'
53
+ db.mongo_utility.should == '/path/to/mongo'
54
+ db.lock.should == true
55
+ end
63
56
  end
64
- end
65
57
 
66
- context 'when configuration defaults have been set' do
67
- after { Backup::Configuration::Database::MongoDB.clear_defaults! }
58
+ context 'when options are not specified' do
59
+ before do
60
+ Backup::Database::MongoDB.any_instance.expects(:utility).
61
+ with(:mongodump).returns('/real/mongodump')
62
+ Backup::Database::MongoDB.any_instance.expects(:utility).
63
+ with(:mongo).returns('/real/mongo')
64
+ end
65
+
66
+ it 'should provide default values' do
67
+ db = Backup::Database::MongoDB.new(model)
68
+
69
+ db.name.should be_nil
70
+ db.username.should be_nil
71
+ db.password.should be_nil
72
+ db.host.should be_nil
73
+ db.port.should be_nil
74
+
75
+ db.ipv6.should be_false
76
+ db.only_collections.should == []
77
+ db.additional_options.should == []
78
+ db.mongodump_utility.should == '/real/mongodump'
79
+ db.mongo_utility.should == '/real/mongo'
80
+ db.lock.should be_false
81
+ end
82
+ end
83
+ end # context 'when no pre-configured defaults have been set'
68
84
 
69
- it 'should use configuration defaults' do
70
- Backup::Configuration::Database::MongoDB.defaults do |db|
85
+ context 'when pre-configured defaults have been set' do
86
+ before do
87
+ Backup::Database::MongoDB.defaults do |db|
71
88
  db.name = 'db_name'
72
89
  db.username = 'db_username'
73
90
  db.password = 'db_password'
74
91
  db.host = 'db_host'
75
92
  db.port = 789
76
93
 
77
- db.ipv6 = true
94
+ db.ipv6 = 'default_ipv6'
78
95
  db.only_collections = ['collection']
79
96
  db.additional_options = ['--opt']
80
97
  db.mongodump_utility = '/default/path/to/mongodump'
81
98
  db.mongo_utility = '/default/path/to/mongo'
82
- db.lock = true
99
+ db.lock = 'default_lock'
83
100
  end
101
+ end
84
102
 
85
- db = Backup::Database::MongoDB.new(model)
86
- db.name.should == 'db_name'
87
- db.username.should == 'db_username'
88
- db.password.should == 'db_password'
89
- db.host.should == 'db_host'
90
- db.port.should == 789
91
-
92
- db.ipv6.should be_true
93
- db.only_collections.should == ['collection']
94
- db.additional_options.should == ['--opt']
95
- db.mongodump_utility.should == '/default/path/to/mongodump'
96
- db.mongo_utility.should == '/default/path/to/mongo'
97
- db.lock.should be_true
103
+ after { Backup::Database::MongoDB.clear_defaults! }
104
+
105
+ context 'when options are specified' do
106
+ it 'should override the pre-configured defaults' do
107
+ db.name.should == 'mydatabase'
108
+ db.username.should == 'someuser'
109
+ db.password.should == 'secret'
110
+ db.host.should == 'localhost'
111
+ db.port.should == 123
112
+
113
+ db.ipv6.should == true
114
+ db.only_collections.should == ['users', 'pirates']
115
+ db.additional_options.should == ['--query', '--foo']
116
+ db.mongodump_utility.should == '/path/to/mongodump'
117
+ db.mongo_utility.should == '/path/to/mongo'
118
+ db.lock.should == true
119
+ end
98
120
  end
99
- end
121
+
122
+ context 'when options are not specified' do
123
+ it 'should use the pre-configured defaults' do
124
+ db = Backup::Database::MongoDB.new(model)
125
+
126
+ db.name.should == 'db_name'
127
+ db.username.should == 'db_username'
128
+ db.password.should == 'db_password'
129
+ db.host.should == 'db_host'
130
+ db.port.should == 789
131
+
132
+ db.ipv6.should == 'default_ipv6'
133
+ db.only_collections.should == ['collection']
134
+ db.additional_options.should == ['--opt']
135
+ db.mongodump_utility.should == '/default/path/to/mongodump'
136
+ db.mongo_utility.should == '/default/path/to/mongo'
137
+ db.lock.should == 'default_lock'
138
+ end
139
+ end
140
+ end # context 'when no pre-configured defaults have been set'
100
141
  end # describe '#initialize'
101
142
 
102
143
  describe '#perform!' do
@@ -109,6 +150,7 @@ describe Backup::Database::MongoDB do
109
150
  end
110
151
 
111
152
  context 'when #lock is set to false' do
153
+ before { db.lock = false }
112
154
 
113
155
  context 'when #only_collections has not been specified' do
114
156
  before { db.only_collections = [] }
@@ -138,7 +180,6 @@ describe Backup::Database::MongoDB do
138
180
  end # context 'when #lock is set to false'
139
181
 
140
182
  context 'when #lock is set to true' do
141
- before { db.lock = true }
142
183
 
143
184
  context 'when #only_collections has not been specified' do
144
185
  before { db.only_collections = [] }
@@ -171,6 +212,8 @@ describe Backup::Database::MongoDB do
171
212
 
172
213
  context 'when errors occur' do
173
214
  it 'should re-raise error and skip package!' do
215
+ db.lock = false
216
+
174
217
  db.expects(:specific_collection_dump!).in_sequence(s).
175
218
  raises('Test Error Message')
176
219
  db.expects(:package!).never
@@ -186,8 +229,6 @@ describe Backup::Database::MongoDB do
186
229
  end
187
230
 
188
231
  it 'should ensure database is unlocked' do
189
- db.lock = true
190
-
191
232
  db.expects(:lock_database).in_sequence(s)
192
233
  db.expects(:specific_collection_dump!).in_sequence(s).
193
234
  raises('Test Error Message')
@@ -239,6 +280,9 @@ describe Backup::Database::MongoDB do
239
280
 
240
281
  describe '#package!' do
241
282
  let(:compressor) { mock }
283
+ let(:pipeline) { mock }
284
+ let(:timestamp) { Time.now.to_i.to_s[-5, 5] }
285
+ let(:s) { sequence '' }
242
286
 
243
287
  context 'when a compressor is configured' do
244
288
  before do
@@ -247,18 +291,62 @@ describe Backup::Database::MongoDB do
247
291
  db.expects(:utility).with(:tar).returns('tar')
248
292
  model.expects(:compressor).twice.returns(compressor)
249
293
  compressor.expects(:compress_with).yields('compressor_command', '.gz')
294
+ Backup::Pipeline.expects(:new).returns(pipeline)
250
295
  end
251
296
 
252
- it 'should package the dump directory, then remove it' do
253
- timestamp = Time.now.to_i.to_s[-5, 5]
254
- db.expects(:run).with(
255
- "tar -cf - -C '/path/to/dump' 'folder' | compressor_command" +
256
- " > /path/to/dump/folder-#{ timestamp }.tar.gz"
257
- )
258
- FileUtils.expects(:rm_rf).with('/path/to/dump/folder')
297
+ context 'when pipeline command succeeds' do
298
+ it 'should package the dump directory, then remove it' do
299
+
300
+ Backup::Logger.expects(:message).in_sequence(s).with(
301
+ "Database::MongoDB started compressing and packaging:\n" +
302
+ " '/path/to/dump/folder'"
303
+ )
304
+
305
+ pipeline.expects(:<<).in_sequence(s).with(
306
+ "tar -cf - -C '/path/to/dump' 'folder'"
307
+ )
308
+ pipeline.expects(:<<).in_sequence(s).with('compressor_command')
309
+ pipeline.expects(:<<).in_sequence(s).with(
310
+ "cat > /path/to/dump/folder-#{ timestamp }.tar.gz"
311
+ )
312
+
313
+ pipeline.expects(:run).in_sequence(s)
314
+ pipeline.expects(:success?).in_sequence(s).returns(true)
315
+ Backup::Logger.expects(:message).in_sequence(s).with(
316
+ "Database::MongoDB completed compressing and packaging:\n" +
317
+ " '/path/to/dump/folder-#{ timestamp }.tar.gz'"
318
+ )
319
+ FileUtils.expects(:rm_rf).in_sequence(s).with('/path/to/dump/folder')
320
+
321
+ db.send(:package!)
322
+ end
323
+ end #context 'when pipeline command succeeds'
324
+
325
+ context 'when pipeline command fails' do
326
+ before do
327
+ pipeline.stubs(:<<)
328
+ pipeline.expects(:run)
329
+ pipeline.expects(:success?).returns(false)
330
+ pipeline.expects(:error_messages).returns('pipeline_errors')
331
+ end
259
332
 
260
- db.send(:package!)
261
- end
333
+ it 'should raise an error' do
334
+ Backup::Logger.expects(:message).with(
335
+ "Database::MongoDB started compressing and packaging:\n" +
336
+ " '/path/to/dump/folder'"
337
+ )
338
+
339
+ expect do
340
+ db.send(:package!)
341
+ end.to raise_error(
342
+ Backup::Errors::Database::PipelineError,
343
+ "Database::PipelineError: Database::MongoDB " +
344
+ "Failed to create compressed dump package:\n" +
345
+ " '/path/to/dump/folder-#{ timestamp }.tar.gz'\n" +
346
+ " pipeline_errors"
347
+ )
348
+ end
349
+ end # context 'when pipeline command fails'
262
350
  end
263
351
 
264
352
  context 'when a compressor is not configured' do
@@ -267,11 +355,11 @@ describe Backup::Database::MongoDB do
267
355
  end
268
356
 
269
357
  it 'should return nil' do
270
- db.expects(:run).never
358
+ Backup::Pipeline.expects(:new).never
271
359
  db.send(:package!).should be_nil
272
360
  end
273
361
  end
274
- end
362
+ end # describe '#package!'
275
363
 
276
364
  describe '#database' do
277
365
  context 'when a database name is given' do
@@ -383,4 +471,41 @@ describe Backup::Database::MongoDB do
383
471
  end
384
472
  end
385
473
  end
474
+
475
+ describe 'deprecations' do
476
+ after do
477
+ Backup::Database::MongoDB.clear_defaults!
478
+ end
479
+
480
+ describe '#utility_path' do
481
+ before do
482
+ Backup::Database::MongoDB.any_instance.stubs(:utility)
483
+ Backup::Logger.expects(:warn).with(
484
+ instance_of(Backup::Errors::ConfigurationError)
485
+ )
486
+ Backup::Logger.expects(:warn).with(
487
+ "Backup::Database::MongoDB.mongodump_utility is being set to 'foo'"
488
+ )
489
+ end
490
+
491
+ context 'when set directly' do
492
+ it 'should issue a deprecation warning and set the replacement value' do
493
+ mongodb = Backup::Database::MongoDB.new(model) do |db|
494
+ db.utility_path = 'foo'
495
+ end
496
+ mongodb.mongodump_utility.should == 'foo'
497
+ end
498
+ end
499
+
500
+ context 'when set as a default' do
501
+ it 'should issue a deprecation warning and set the replacement value' do
502
+ mongodb = Backup::Database::MongoDB.defaults do |db|
503
+ db.utility_path = 'foo'
504
+ end
505
+ mongodb = Backup::Database::MongoDB.new(model)
506
+ mongodb.mongodump_utility.should == 'foo'
507
+ end
508
+ end
509
+ end # describe '#utility_path'
510
+ end
386
511
  end
@@ -20,49 +20,66 @@ describe Backup::Database::MySQL do
20
20
  end
21
21
  end
22
22
 
23
+ it 'should be a subclass of Database::Base' do
24
+ Backup::Database::MySQL.superclass.
25
+ should == Backup::Database::Base
26
+ end
27
+
23
28
  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 == '/mysql.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.mysqldump_utility.should == '/path/to/mysqldump'
29
+
30
+ it 'should load pre-configured defaults through Base' do
31
+ Backup::Database::MySQL.any_instance.expects(:load_defaults!)
32
+ db
36
33
  end
37
34
 
38
- context 'when options are not set' do
39
- before do
40
- Backup::Database::MySQL.any_instance.expects(:utility).
41
- with(:mysqldump).returns('/real/mysqldump')
35
+ it 'should pass the model reference to Base' do
36
+ db.instance_variable_get(:@model).should == model
37
+ end
38
+
39
+ context 'when no pre-configured defaults have been set' do
40
+ context 'when options are specified' do
41
+ it 'should use the given values' do
42
+ db.name.should == 'mydatabase'
43
+ db.username.should == 'someuser'
44
+ db.password.should == 'secret'
45
+ db.host.should == 'localhost'
46
+ db.port.should == '123'
47
+ db.socket.should == '/mysql.sock'
48
+
49
+ db.skip_tables.should == ['logs', 'profiles']
50
+ db.only_tables.should == ['users', 'pirates']
51
+ db.additional_options.should == ['--single-transaction', '--quick']
52
+ db.mysqldump_utility.should == '/path/to/mysqldump'
53
+ end
42
54
  end
43
55
 
44
- it 'should use default values' do
45
- db = Backup::Database::MySQL.new(model)
56
+ context 'when options are not specified' do
57
+ before do
58
+ Backup::Database::MySQL.any_instance.expects(:utility).
59
+ with(:mysqldump).returns('/real/mysqldump')
60
+ end
46
61
 
47
- db.name.should == :all
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
62
+ it 'should provide default values' do
63
+ db = Backup::Database::MySQL.new(model)
53
64
 
54
- db.skip_tables.should == []
55
- db.only_tables.should == []
56
- db.additional_options.should == []
57
- db.mysqldump_utility.should == '/real/mysqldump'
58
- end
59
- end
65
+ db.name.should == :all
66
+ db.username.should be_nil
67
+ db.password.should be_nil
68
+ db.host.should be_nil
69
+ db.port.should be_nil
70
+ db.socket.should be_nil
60
71
 
61
- context 'when configuration defaults have been set' do
62
- after { Backup::Configuration::Database::MySQL.clear_defaults! }
72
+ db.skip_tables.should == []
73
+ db.only_tables.should == []
74
+ db.additional_options.should == []
75
+ db.mysqldump_utility.should == '/real/mysqldump'
76
+ end
77
+ end
78
+ end # context 'when no pre-configured defaults have been set'
63
79
 
64
- it 'should use configuration defaults' do
65
- Backup::Configuration::Database::MySQL.defaults do |db|
80
+ context 'when pre-configured defaults have been set' do
81
+ before do
82
+ Backup::Database::MySQL.defaults do |db|
66
83
  db.name = 'db_name'
67
84
  db.username = 'db_username'
68
85
  db.password = 'db_password'
@@ -75,25 +92,50 @@ describe Backup::Database::MySQL do
75
92
  db.additional_options = ['--add', '--opts']
76
93
  db.mysqldump_utility = '/default/path/to/mysqldump'
77
94
  end
95
+ end
78
96
 
79
- db = Backup::Database::MySQL.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.mysqldump_utility.should == '/default/path/to/mysqldump'
97
+ after { Backup::Database::MySQL.clear_defaults! }
98
+
99
+ context 'when options are specified' do
100
+ it 'should override the pre-configured defaults' do
101
+ db.name.should == 'mydatabase'
102
+ db.username.should == 'someuser'
103
+ db.password.should == 'secret'
104
+ db.host.should == 'localhost'
105
+ db.port.should == '123'
106
+ db.socket.should == '/mysql.sock'
107
+
108
+ db.skip_tables.should == ['logs', 'profiles']
109
+ db.only_tables.should == ['users', 'pirates']
110
+ db.additional_options.should == ['--single-transaction', '--quick']
111
+ db.mysqldump_utility.should == '/path/to/mysqldump'
112
+ end
91
113
  end
92
- end
114
+
115
+ context 'when options are not specified' do
116
+ it 'should use the pre-configured defaults' do
117
+ db = Backup::Database::MySQL.new(model)
118
+
119
+ db.name.should == 'db_name'
120
+ db.username.should == 'db_username'
121
+ db.password.should == 'db_password'
122
+ db.host.should == 'db_host'
123
+ db.port.should == 789
124
+ db.socket.should == '/foo.sock'
125
+
126
+ db.skip_tables.should == ['skip', 'tables']
127
+ db.only_tables.should == ['only', 'tables']
128
+ db.additional_options.should == ['--add', '--opts']
129
+ db.mysqldump_utility.should == '/default/path/to/mysqldump'
130
+ end
131
+ end
132
+ end # context 'when no pre-configured defaults have been set'
93
133
  end # describe '#initialize'
94
134
 
95
135
  describe '#perform!' do
96
136
  let(:s) { sequence '' }
137
+ let(:pipeline) { mock }
138
+
97
139
  before do
98
140
  # superclass actions
99
141
  db.expects(:prepare!).in_sequence(s)
@@ -102,17 +144,25 @@ describe Backup::Database::MySQL do
102
144
 
103
145
  db.stubs(:mysqldump).returns('mysqldump_command')
104
146
  db.stubs(:dump_filename).returns('dump_filename')
147
+ Backup::Pipeline.expects(:new).returns(pipeline)
105
148
  end
106
149
 
107
150
  context 'when no compressor is configured' do
108
151
  before do
109
- model.expects(:compressor).in_sequence(s).returns(nil)
152
+ model.expects(:compressor).returns(nil)
110
153
  end
111
154
 
112
155
  it 'should run mysqldump without compression' do
113
- db.expects(:run).in_sequence(s).with(
114
- "mysqldump_command > '/dump/path/dump_filename.sql'"
156
+ pipeline.expects(:<<).in_sequence(s).with('mysqldump_command')
157
+ pipeline.expects(:<<).in_sequence(s).with(
158
+ "cat > '/dump/path/dump_filename.sql'"
159
+ )
160
+ pipeline.expects(:run).in_sequence(s)
161
+ pipeline.expects(:success?).in_sequence(s).returns(true)
162
+ Backup::Logger.expects(:message).in_sequence(s).with(
163
+ 'Database::MySQL Complete!'
115
164
  )
165
+
116
166
  db.perform!
117
167
  end
118
168
  end
@@ -120,18 +170,46 @@ describe Backup::Database::MySQL do
120
170
  context 'when a compressor is configured' do
121
171
  before do
122
172
  compressor = mock
123
- model.expects(:compressor).twice.in_sequence(s).returns(compressor)
124
- compressor.expects(:compress_with).in_sequence(s).yields('gzip', '.gz')
173
+ model.expects(:compressor).twice.returns(compressor)
174
+ compressor.expects(:compress_with).yields('gzip', '.gz')
125
175
  end
126
176
 
127
177
  it 'should run mysqldump with compression' do
128
- db.expects(:run).in_sequence(s).with(
129
- "mysqldump_command | gzip > '/dump/path/dump_filename.sql.gz'"
178
+ pipeline.expects(:<<).in_sequence(s).with('mysqldump_command')
179
+ pipeline.expects(:<<).in_sequence(s).with('gzip')
180
+ pipeline.expects(:<<).in_sequence(s).with(
181
+ "cat > '/dump/path/dump_filename.sql.gz'"
182
+ )
183
+ pipeline.expects(:run).in_sequence(s)
184
+ pipeline.expects(:success?).in_sequence(s).returns(true)
185
+ Backup::Logger.expects(:message).in_sequence(s).with(
186
+ 'Database::MySQL Complete!'
130
187
  )
188
+
131
189
  db.perform!
132
190
  end
133
191
  end
134
192
 
193
+ context 'when pipeline command fails' do
194
+ before do
195
+ model.expects(:compressor).returns(nil)
196
+ pipeline.stubs(:<<)
197
+ pipeline.expects(:run)
198
+ pipeline.expects(:success?).returns(false)
199
+ pipeline.expects(:error_messages).returns('pipeline_errors')
200
+ end
201
+
202
+ it 'should raise an error' do
203
+ expect do
204
+ db.perform!
205
+ end.to raise_error(
206
+ Backup::Errors::Database::PipelineError,
207
+ "Database::PipelineError: Database::MySQL Dump Failed!\n" +
208
+ " pipeline_errors"
209
+ )
210
+ end
211
+ end # context 'when pipeline command fails'
212
+
135
213
  end # describe '#perform!'
136
214
 
137
215
  describe '#mysqldump' do
@@ -261,18 +339,22 @@ describe Backup::Database::MySQL do
261
339
  "--ignore-table='mydatabase.logs' --ignore-table='mydatabase.profiles'"
262
340
  end
263
341
 
264
- context 'when #skip_tables is not set' do
265
- before { db.skip_tables = [] }
266
- it 'should return an empty string' do
267
- db.send(:tables_to_skip).should == ''
268
- end
342
+ it 'should return an empty string if #skip_tables is empty' do
343
+ db.skip_tables = []
344
+ db.send(:tables_to_skip).should == ''
269
345
  end
270
346
 
271
- context 'when dump_all? is true' do
272
- before { db.stubs(:dump_all?).returns(true) }
273
- it 'should return nil' do
274
- db.send(:tables_to_skip).should be_nil
275
- end
347
+ it 'should accept table names prefixed with the database name' do
348
+ db.skip_tables = ['table_name', 'db_name.table_name']
349
+ db.send(:tables_to_skip).should ==
350
+ "--ignore-table='mydatabase.table_name' --ignore-table='db_name.table_name'"
351
+ end
352
+
353
+ it 'should not prefix table name if dump_all? is true' do
354
+ db.name = :all
355
+ db.skip_tables = ['table_name', 'db_name.table_name']
356
+ db.send(:tables_to_skip).should ==
357
+ "--ignore-table='table_name' --ignore-table='db_name.table_name'"
276
358
  end
277
359
  end
278
360
 
@@ -290,4 +372,41 @@ describe Backup::Database::MySQL do
290
372
  end
291
373
  end
292
374
  end
375
+
376
+ describe 'deprecations' do
377
+ after do
378
+ Backup::Database::MySQL.clear_defaults!
379
+ end
380
+
381
+ describe '#utility_path' do
382
+ before do
383
+ Backup::Database::MySQL.any_instance.stubs(:utility)
384
+ Backup::Logger.expects(:warn).with(
385
+ instance_of(Backup::Errors::ConfigurationError)
386
+ )
387
+ Backup::Logger.expects(:warn).with(
388
+ "Backup::Database::MySQL.mysqldump_utility is being set to 'foo'"
389
+ )
390
+ end
391
+
392
+ context 'when set directly' do
393
+ it 'should issue a deprecation warning and set the replacement value' do
394
+ mysql = Backup::Database::MySQL.new(model) do |db|
395
+ db.utility_path = 'foo'
396
+ end
397
+ mysql.mysqldump_utility.should == 'foo'
398
+ end
399
+ end
400
+
401
+ context 'when set as a default' do
402
+ it 'should issue a deprecation warning and set the replacement value' do
403
+ mysql = Backup::Database::MySQL.defaults do |db|
404
+ db.utility_path = 'foo'
405
+ end
406
+ mysql = Backup::Database::MySQL.new(model)
407
+ mysql.mysqldump_utility.should == 'foo'
408
+ end
409
+ end
410
+ end # describe '#utility_path'
411
+ end
293
412
  end