backup 3.0.20 → 3.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. data/Gemfile +1 -5
  2. data/Gemfile.lock +46 -50
  3. data/README.md +54 -27
  4. data/lib/backup.rb +16 -39
  5. data/lib/backup/archive.rb +42 -18
  6. data/lib/backup/cleaner.rb +110 -25
  7. data/lib/backup/cli/helpers.rb +17 -32
  8. data/lib/backup/cli/utility.rb +46 -107
  9. data/lib/backup/compressor/base.rb +14 -2
  10. data/lib/backup/compressor/bzip2.rb +10 -24
  11. data/lib/backup/compressor/gzip.rb +10 -24
  12. data/lib/backup/compressor/lzma.rb +10 -23
  13. data/lib/backup/compressor/pbzip2.rb +12 -32
  14. data/lib/backup/config.rb +171 -0
  15. data/lib/backup/configuration/compressor/base.rb +1 -2
  16. data/lib/backup/configuration/compressor/pbzip2.rb +4 -4
  17. data/lib/backup/configuration/database/base.rb +2 -1
  18. data/lib/backup/configuration/database/mongodb.rb +8 -0
  19. data/lib/backup/configuration/database/mysql.rb +4 -0
  20. data/lib/backup/configuration/database/postgresql.rb +4 -0
  21. data/lib/backup/configuration/database/redis.rb +4 -0
  22. data/lib/backup/configuration/database/riak.rb +5 -1
  23. data/lib/backup/configuration/encryptor/base.rb +1 -2
  24. data/lib/backup/configuration/encryptor/open_ssl.rb +1 -1
  25. data/lib/backup/configuration/helpers.rb +7 -2
  26. data/lib/backup/configuration/notifier/base.rb +4 -28
  27. data/lib/backup/configuration/storage/base.rb +1 -1
  28. data/lib/backup/configuration/storage/dropbox.rb +14 -4
  29. data/lib/backup/configuration/syncer/base.rb +10 -0
  30. data/lib/backup/configuration/syncer/rsync/base.rb +28 -0
  31. data/lib/backup/configuration/syncer/rsync/local.rb +11 -0
  32. data/lib/backup/configuration/syncer/rsync/pull.rb +11 -0
  33. data/lib/backup/configuration/syncer/rsync/push.rb +31 -0
  34. data/lib/backup/configuration/syncer/s3.rb +0 -4
  35. data/lib/backup/database/base.rb +25 -7
  36. data/lib/backup/database/mongodb.rb +112 -75
  37. data/lib/backup/database/mysql.rb +54 -29
  38. data/lib/backup/database/postgresql.rb +60 -42
  39. data/lib/backup/database/redis.rb +61 -39
  40. data/lib/backup/database/riak.rb +35 -11
  41. data/lib/backup/dependency.rb +4 -5
  42. data/lib/backup/encryptor/base.rb +13 -1
  43. data/lib/backup/encryptor/gpg.rb +39 -39
  44. data/lib/backup/encryptor/open_ssl.rb +28 -38
  45. data/lib/backup/logger.rb +20 -11
  46. data/lib/backup/model.rb +206 -163
  47. data/lib/backup/notifier/base.rb +27 -25
  48. data/lib/backup/notifier/campfire.rb +7 -13
  49. data/lib/backup/notifier/hipchat.rb +28 -28
  50. data/lib/backup/notifier/mail.rb +24 -26
  51. data/lib/backup/notifier/presently.rb +10 -18
  52. data/lib/backup/notifier/prowl.rb +9 -17
  53. data/lib/backup/notifier/twitter.rb +11 -18
  54. data/lib/backup/package.rb +47 -0
  55. data/lib/backup/packager.rb +81 -16
  56. data/lib/backup/splitter.rb +48 -35
  57. data/lib/backup/storage/base.rb +44 -172
  58. data/lib/backup/storage/cloudfiles.rb +31 -46
  59. data/lib/backup/storage/cycler.rb +117 -0
  60. data/lib/backup/storage/dropbox.rb +92 -76
  61. data/lib/backup/storage/ftp.rb +30 -40
  62. data/lib/backup/storage/local.rb +44 -45
  63. data/lib/backup/storage/ninefold.rb +55 -49
  64. data/lib/backup/storage/rsync.rb +49 -56
  65. data/lib/backup/storage/s3.rb +33 -44
  66. data/lib/backup/storage/scp.rb +21 -48
  67. data/lib/backup/storage/sftp.rb +26 -40
  68. data/lib/backup/syncer/base.rb +7 -0
  69. data/lib/backup/syncer/rsync/base.rb +78 -0
  70. data/lib/backup/syncer/rsync/local.rb +53 -0
  71. data/lib/backup/syncer/rsync/pull.rb +38 -0
  72. data/lib/backup/syncer/rsync/push.rb +113 -0
  73. data/lib/backup/syncer/s3.rb +42 -32
  74. data/lib/backup/version.rb +1 -1
  75. data/spec/archive_spec.rb +235 -69
  76. data/spec/cleaner_spec.rb +304 -0
  77. data/spec/cli/helpers_spec.rb +142 -1
  78. data/spec/cli/utility_spec.rb +338 -13
  79. data/spec/compressor/base_spec.rb +31 -0
  80. data/spec/compressor/bzip2_spec.rb +60 -35
  81. data/spec/compressor/gzip_spec.rb +60 -35
  82. data/spec/compressor/lzma_spec.rb +60 -35
  83. data/spec/compressor/pbzip2_spec.rb +98 -37
  84. data/spec/config_spec.rb +321 -0
  85. data/spec/configuration/base_spec.rb +4 -4
  86. data/spec/configuration/compressor/bzip2_spec.rb +1 -0
  87. data/spec/configuration/compressor/gzip_spec.rb +1 -0
  88. data/spec/configuration/compressor/lzma_spec.rb +1 -0
  89. data/spec/configuration/compressor/pbzip2_spec.rb +32 -0
  90. data/spec/configuration/database/base_spec.rb +2 -1
  91. data/spec/configuration/database/mongodb_spec.rb +26 -16
  92. data/spec/configuration/database/mysql_spec.rb +4 -0
  93. data/spec/configuration/database/postgresql_spec.rb +4 -0
  94. data/spec/configuration/database/redis_spec.rb +4 -0
  95. data/spec/configuration/database/riak_spec.rb +4 -0
  96. data/spec/configuration/encryptor/gpg_spec.rb +1 -0
  97. data/spec/configuration/encryptor/open_ssl_spec.rb +1 -0
  98. data/spec/configuration/notifier/base_spec.rb +32 -0
  99. data/spec/configuration/notifier/campfire_spec.rb +1 -0
  100. data/spec/configuration/notifier/hipchat_spec.rb +1 -0
  101. data/spec/configuration/notifier/mail_spec.rb +1 -0
  102. data/spec/configuration/notifier/presently_spec.rb +1 -0
  103. data/spec/configuration/notifier/prowl_spec.rb +1 -0
  104. data/spec/configuration/notifier/twitter_spec.rb +1 -0
  105. data/spec/configuration/storage/cloudfiles_spec.rb +1 -0
  106. data/spec/configuration/storage/dropbox_spec.rb +4 -3
  107. data/spec/configuration/storage/ftp_spec.rb +1 -0
  108. data/spec/configuration/storage/local_spec.rb +1 -0
  109. data/spec/configuration/storage/ninefold_spec.rb +1 -0
  110. data/spec/configuration/storage/rsync_spec.rb +3 -1
  111. data/spec/configuration/storage/s3_spec.rb +1 -0
  112. data/spec/configuration/storage/scp_spec.rb +1 -0
  113. data/spec/configuration/storage/sftp_spec.rb +1 -0
  114. data/spec/configuration/syncer/rsync/base_spec.rb +33 -0
  115. data/spec/configuration/syncer/rsync/local_spec.rb +10 -0
  116. data/spec/configuration/syncer/rsync/pull_spec.rb +10 -0
  117. data/spec/configuration/syncer/{rsync_spec.rb → rsync/push_spec.rb} +12 -15
  118. data/spec/configuration/syncer/s3_spec.rb +2 -3
  119. data/spec/database/base_spec.rb +35 -20
  120. data/spec/database/mongodb_spec.rb +298 -119
  121. data/spec/database/mysql_spec.rb +147 -72
  122. data/spec/database/postgresql_spec.rb +155 -100
  123. data/spec/database/redis_spec.rb +200 -97
  124. data/spec/database/riak_spec.rb +82 -24
  125. data/spec/dependency_spec.rb +49 -0
  126. data/spec/encryptor/base_spec.rb +30 -0
  127. data/spec/encryptor/gpg_spec.rb +105 -28
  128. data/spec/encryptor/open_ssl_spec.rb +85 -114
  129. data/spec/logger_spec.rb +74 -8
  130. data/spec/model_spec.rb +528 -220
  131. data/spec/notifier/base_spec.rb +89 -0
  132. data/spec/notifier/campfire_spec.rb +147 -119
  133. data/spec/notifier/hipchat_spec.rb +140 -145
  134. data/spec/notifier/mail_spec.rb +190 -248
  135. data/spec/notifier/presently_spec.rb +147 -282
  136. data/spec/notifier/prowl_spec.rb +79 -111
  137. data/spec/notifier/twitter_spec.rb +87 -106
  138. data/spec/package_spec.rb +61 -0
  139. data/spec/packager_spec.rb +154 -0
  140. data/spec/spec_helper.rb +36 -13
  141. data/spec/splitter_spec.rb +90 -41
  142. data/spec/storage/base_spec.rb +95 -239
  143. data/spec/storage/cloudfiles_spec.rb +185 -75
  144. data/spec/storage/cycler_spec.rb +239 -0
  145. data/spec/storage/dropbox_spec.rb +318 -87
  146. data/spec/storage/ftp_spec.rb +165 -152
  147. data/spec/storage/local_spec.rb +206 -54
  148. data/spec/storage/ninefold_spec.rb +264 -128
  149. data/spec/storage/rsync_spec.rb +244 -163
  150. data/spec/storage/s3_spec.rb +175 -64
  151. data/spec/storage/scp_spec.rb +156 -150
  152. data/spec/storage/sftp_spec.rb +153 -135
  153. data/spec/syncer/base_spec.rb +22 -0
  154. data/spec/syncer/rsync/base_spec.rb +118 -0
  155. data/spec/syncer/rsync/local_spec.rb +121 -0
  156. data/spec/syncer/rsync/pull_spec.rb +90 -0
  157. data/spec/syncer/rsync/push_spec.rb +327 -0
  158. data/spec/syncer/s3_spec.rb +180 -91
  159. data/templates/cli/utility/config +1 -1
  160. data/templates/cli/utility/database/mongodb +4 -0
  161. data/templates/cli/utility/database/mysql +3 -0
  162. data/templates/cli/utility/database/postgresql +3 -0
  163. data/templates/cli/utility/database/redis +3 -0
  164. data/templates/cli/utility/database/riak +3 -0
  165. data/templates/cli/utility/storage/dropbox +4 -1
  166. data/templates/cli/utility/syncer/rsync_local +12 -0
  167. data/templates/cli/utility/syncer/{rsync → rsync_pull} +2 -2
  168. data/templates/cli/utility/syncer/rsync_push +17 -0
  169. data/templates/storage/dropbox/authorization_url.erb +1 -1
  170. metadata +42 -17
  171. data/lib/backup/configuration/syncer/rsync.rb +0 -45
  172. data/lib/backup/finder.rb +0 -87
  173. data/lib/backup/storage/object.rb +0 -47
  174. data/lib/backup/syncer/rsync.rb +0 -152
  175. data/spec/backup_spec.rb +0 -11
  176. data/spec/finder_spec.rb +0 -91
  177. data/spec/storage/object_spec.rb +0 -74
  178. data/spec/syncer/rsync_spec.rb +0 -195
@@ -0,0 +1,121 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path('../../../spec_helper.rb', __FILE__)
4
+
5
+ describe Backup::Syncer::RSync::Local do
6
+ let(:syncer) do
7
+ Backup::Syncer::RSync::Local.new do |rsync|
8
+ rsync.path = "~/my_backups"
9
+
10
+ rsync.directories do |directory|
11
+ directory.add "/some/directory"
12
+ directory.add "~/home/directory"
13
+ end
14
+
15
+ rsync.mirror = true
16
+ rsync.additional_options = ['--opt-a', '--opt-b']
17
+ end
18
+ end
19
+
20
+ it 'should be a subclass of RSync::Base' do
21
+ Backup::Syncer::RSync::Local.superclass.should == Backup::Syncer::RSync::Base
22
+ end
23
+
24
+ describe '#initialize' do
25
+ it 'should have defined the configuration properly' do
26
+ syncer.path.should == '~/my_backups'
27
+ syncer.directories.should == ["/some/directory", "~/home/directory"]
28
+ syncer.mirror.should == true
29
+ syncer.additional_options.should == ['--opt-a', '--opt-b']
30
+ end
31
+
32
+ context 'when setting configuration defaults' do
33
+ after { Backup::Configuration::Syncer::RSync::Local.clear_defaults! }
34
+
35
+ it 'should override the configured defaults' do
36
+ Backup::Configuration::Syncer::RSync::Local.defaults do |rsync|
37
+ rsync.path = 'old_path'
38
+ #rsync.directories = 'cannot_have_a_default_value'
39
+ rsync.mirror = 'old_mirror'
40
+ rsync.additional_options = 'old_additional_options'
41
+ end
42
+ syncer = Backup::Syncer::RSync::Local.new do |rsync|
43
+ rsync.path = 'new_path'
44
+ rsync.directories = 'new_directories'
45
+ rsync.mirror = 'new_mirror'
46
+ rsync.additional_options = 'new_additional_options'
47
+ end
48
+
49
+ syncer.path.should == 'new_path'
50
+ syncer.directories.should == 'new_directories'
51
+ syncer.mirror.should == 'new_mirror'
52
+ syncer.additional_options.should == 'new_additional_options'
53
+ end
54
+ end # context 'when setting configuration defaults'
55
+ end # describe '#initialize'
56
+
57
+ describe '#perform!' do
58
+ let(:s) { sequence '' }
59
+
60
+ before do
61
+ syncer.expects(:utility).with(:rsync).returns('rsync')
62
+ syncer.expects(:options).returns('options_output')
63
+ end
64
+
65
+ it 'should sync two directories' do
66
+ Backup::Logger.expects(:message).in_sequence(s).with(
67
+ "Syncer::RSync::Local started syncing the following directories:\n" +
68
+ " /some/directory\n" +
69
+ " ~/home/directory"
70
+ )
71
+ syncer.expects(:run).in_sequence(s).with(
72
+ "rsync options_output '/some/directory' " +
73
+ "'#{ File.expand_path('~/home/directory') }' " +
74
+ "'#{ File.expand_path('~/my_backups') }'"
75
+ ).returns('messages from stdout')
76
+ Backup::Logger.expects(:silent).in_sequence(s).with('messages from stdout')
77
+
78
+ syncer.perform!
79
+ end
80
+ end # describe '#perform!'
81
+
82
+ describe '#dest_path' do
83
+ it 'should return @path expanded' do
84
+ syncer.send(:dest_path).should == File.expand_path('~/my_backups')
85
+ end
86
+
87
+ it 'should set @dest_path' do
88
+ syncer.send(:dest_path)
89
+ syncer.instance_variable_get(:@dest_path).should ==
90
+ File.expand_path('~/my_backups')
91
+ end
92
+
93
+ it 'should return @dest_path if already set' do
94
+ syncer.instance_variable_set(:@dest_path, 'foo')
95
+ syncer.send(:dest_path).should == 'foo'
96
+ end
97
+ end
98
+
99
+ describe '#options' do
100
+ context 'when @mirror is true' do
101
+ it 'should return the options with mirroring enabled' do
102
+ syncer.send(:options).should == '--archive --delete --opt-a --opt-b'
103
+ end
104
+ end
105
+
106
+ context 'when @mirror is false' do
107
+ before { syncer.mirror = false }
108
+ it 'should return the options without mirroring enabled' do
109
+ syncer.send(:options).should == '--archive --opt-a --opt-b'
110
+ end
111
+ end
112
+
113
+ context 'when no additional options are given' do
114
+ before { syncer.additional_options = [] }
115
+ it 'should return the options without additional options' do
116
+ syncer.send(:options).should == '--archive --delete'
117
+ end
118
+ end
119
+ end
120
+
121
+ end
@@ -0,0 +1,90 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path('../../../spec_helper.rb', __FILE__)
4
+
5
+ describe Backup::Syncer::RSync::Pull do
6
+ let(:syncer) do
7
+ Backup::Syncer::RSync::Pull.new do |rsync|
8
+ rsync.username = 'my_username'
9
+ rsync.password = 'my_password'
10
+ rsync.ip = '123.45.678.90'
11
+ rsync.port = 22
12
+ rsync.compress = true
13
+ rsync.path = "~/my_backups"
14
+
15
+ rsync.directories do |directory|
16
+ directory.add "/some/directory"
17
+ directory.add "~/home/directory"
18
+ end
19
+
20
+ rsync.mirror = true
21
+ rsync.additional_options = ['--opt-a', '--opt-b']
22
+ end
23
+ end
24
+
25
+ it 'should be a subclass of RSync::Push' do
26
+ Backup::Syncer::RSync::Pull.superclass.should == Backup::Syncer::RSync::Push
27
+ end
28
+
29
+ describe '#perform!' do
30
+ let(:s) { sequence '' }
31
+
32
+ it 'should perform the RSync::Pull operation on two directories' do
33
+ syncer.expects(:utility).twice.with(:rsync).returns('rsync')
34
+ syncer.expects(:options).twice.returns('options_output')
35
+
36
+ syncer.expects(:write_password_file!).in_sequence(s)
37
+
38
+ # first directory
39
+ Backup::Logger.expects(:message).in_sequence(s).with(
40
+ "Syncer::RSync::Pull started syncing '/some/directory'."
41
+ )
42
+ syncer.expects(:run).in_sequence(s).with(
43
+ "rsync options_output 'my_username@123.45.678.90:/some/directory' " +
44
+ "'#{ File.expand_path('~/my_backups') }'"
45
+ ).returns('messages from stdout')
46
+ Backup::Logger.expects(:silent).in_sequence(s).with('messages from stdout')
47
+
48
+ # second directory
49
+ Backup::Logger.expects(:message).in_sequence(s).with(
50
+ "Syncer::RSync::Pull started syncing '~/home/directory'."
51
+ )
52
+ syncer.expects(:run).in_sequence(s).with(
53
+ "rsync options_output 'my_username@123.45.678.90:home/directory' " +
54
+ "'#{ File.expand_path('~/my_backups') }'"
55
+ ).returns('messages from stdout')
56
+ Backup::Logger.expects(:silent).in_sequence(s).with('messages from stdout')
57
+
58
+ syncer.expects(:remove_password_file!).in_sequence(s)
59
+
60
+ syncer.perform!
61
+ end
62
+
63
+ it 'should ensure passoword file removal' do
64
+ syncer.expects(:write_password_file!).raises('error message')
65
+ syncer.expects(:remove_password_file!)
66
+
67
+ expect do
68
+ syncer.perform!
69
+ end.to raise_error(RuntimeError, 'error message')
70
+ end
71
+ end # describe '#perform!'
72
+
73
+ describe '#dest_path' do
74
+ it 'should return @path expanded' do
75
+ syncer.send(:dest_path).should == File.expand_path('~/my_backups')
76
+ end
77
+
78
+ it 'should set @dest_path' do
79
+ syncer.send(:dest_path)
80
+ syncer.instance_variable_get(:@dest_path).should ==
81
+ File.expand_path('~/my_backups')
82
+ end
83
+
84
+ it 'should return @dest_path if already set' do
85
+ syncer.instance_variable_set(:@dest_path, 'foo')
86
+ syncer.send(:dest_path).should == 'foo'
87
+ end
88
+ end
89
+
90
+ end
@@ -0,0 +1,327 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path('../../../spec_helper.rb', __FILE__)
4
+
5
+ describe Backup::Syncer::RSync::Push do
6
+ let(:syncer) do
7
+ Backup::Syncer::RSync::Push.new do |rsync|
8
+ rsync.username = 'my_username'
9
+ rsync.password = 'my_password'
10
+ rsync.ip = '123.45.678.90'
11
+ rsync.port = 22
12
+ rsync.compress = true
13
+ rsync.path = "~/my_backups"
14
+
15
+ rsync.directories do |directory|
16
+ directory.add "/some/directory"
17
+ directory.add "~/home/directory"
18
+ end
19
+
20
+ rsync.mirror = true
21
+ rsync.additional_options = ['--opt-a', '--opt-b']
22
+ end
23
+ end
24
+
25
+ it 'should be a subclass of RSync::Base' do
26
+ Backup::Syncer::RSync::Push.superclass.should == Backup::Syncer::RSync::Base
27
+ end
28
+
29
+ describe '#initialize' do
30
+ it 'should have defined the configuration properly' do
31
+ syncer.username.should == 'my_username'
32
+ syncer.password.should == 'my_password'
33
+ syncer.ip.should == '123.45.678.90'
34
+ syncer.port.should == 22
35
+ syncer.compress.should == true
36
+ syncer.path.should == '~/my_backups'
37
+ syncer.directories.should == ["/some/directory", "~/home/directory"]
38
+ syncer.mirror.should == true
39
+ syncer.additional_options.should == ['--opt-a', '--opt-b']
40
+ end
41
+
42
+ context 'when options are not set' do
43
+ it 'should use default values' do
44
+ syncer = Backup::Syncer::RSync::Push.new
45
+ syncer.username.should == nil
46
+ syncer.password.should == nil
47
+ syncer.ip.should == nil
48
+ syncer.port.should == 22
49
+ syncer.compress.should == false
50
+ syncer.path.should == 'backups'
51
+ syncer.directories.should == []
52
+ syncer.mirror.should == false
53
+ syncer.additional_options.should == []
54
+ end
55
+ end
56
+
57
+ context 'when setting configuration defaults' do
58
+ after { Backup::Configuration::Syncer::RSync::Push.clear_defaults! }
59
+
60
+ it 'should use the configured defaults' do
61
+ Backup::Configuration::Syncer::RSync::Push.defaults do |rsync|
62
+ rsync.username = 'some_username'
63
+ rsync.password = 'some_password'
64
+ rsync.ip = 'some_ip'
65
+ rsync.port = 'some_port'
66
+ rsync.compress = 'some_compress'
67
+ rsync.path = 'some_path'
68
+ #rsync.directories = 'cannot_have_a_default_value'
69
+ rsync.mirror = 'some_mirror'
70
+ rsync.additional_options = 'some_additional_options'
71
+ end
72
+ syncer = Backup::Syncer::RSync::Push.new
73
+ syncer.username.should == 'some_username'
74
+ syncer.password.should == 'some_password'
75
+ syncer.ip.should == 'some_ip'
76
+ syncer.port.should == 'some_port'
77
+ syncer.compress.should == 'some_compress'
78
+ syncer.path.should == 'some_path'
79
+ syncer.directories.should == []
80
+ syncer.mirror.should == 'some_mirror'
81
+ syncer.additional_options.should == 'some_additional_options'
82
+ end
83
+
84
+ it 'should override the configured defaults' do
85
+ Backup::Configuration::Syncer::RSync::Push.defaults do |rsync|
86
+ rsync.username = 'old_username'
87
+ rsync.password = 'old_password'
88
+ rsync.ip = 'old_ip'
89
+ rsync.port = 'old_port'
90
+ rsync.compress = 'old_compress'
91
+ rsync.path = 'old_path'
92
+ #rsync.directories = 'cannot_have_a_default_value'
93
+ rsync.mirror = 'old_mirror'
94
+ rsync.additional_options = 'old_additional_options'
95
+ end
96
+ syncer = Backup::Syncer::RSync::Push.new do |rsync|
97
+ rsync.username = 'new_username'
98
+ rsync.password = 'new_password'
99
+ rsync.ip = 'new_ip'
100
+ rsync.port = 'new_port'
101
+ rsync.compress = 'new_compress'
102
+ rsync.path = 'new_path'
103
+ rsync.directories = 'new_directories'
104
+ rsync.mirror = 'new_mirror'
105
+ rsync.additional_options = 'new_additional_options'
106
+ end
107
+
108
+ syncer.username.should == 'new_username'
109
+ syncer.password.should == 'new_password'
110
+ syncer.ip.should == 'new_ip'
111
+ syncer.port.should == 'new_port'
112
+ syncer.compress.should == 'new_compress'
113
+ syncer.path.should == 'new_path'
114
+ syncer.directories.should == 'new_directories'
115
+ syncer.mirror.should == 'new_mirror'
116
+ syncer.additional_options.should == 'new_additional_options'
117
+ end
118
+ end # context 'when setting configuration defaults'
119
+ end # describe '#initialize'
120
+
121
+ describe '#perform!' do
122
+ let(:s) { sequence '' }
123
+
124
+ before do
125
+ syncer.expects(:utility).with(:rsync).returns('rsync')
126
+ syncer.expects(:options).returns('options_output')
127
+ end
128
+
129
+ it 'should sync two directories' do
130
+ syncer.expects(:write_password_file!).in_sequence(s)
131
+
132
+ Backup::Logger.expects(:message).in_sequence(s).with(
133
+ "Syncer::RSync::Push started syncing the following directories:\n" +
134
+ " /some/directory\n" +
135
+ " ~/home/directory"
136
+ )
137
+ syncer.expects(:run).in_sequence(s).with(
138
+ "rsync options_output '/some/directory' " +
139
+ "'#{ File.expand_path('~/home/directory') }' " +
140
+ "'my_username@123.45.678.90:my_backups'"
141
+ ).returns('messages from stdout')
142
+ Backup::Logger.expects(:silent).in_sequence(s).with('messages from stdout')
143
+
144
+ syncer.expects(:remove_password_file!).in_sequence(s)
145
+
146
+ syncer.perform!
147
+ end
148
+
149
+ it 'should ensure passoword file removal' do
150
+ syncer.expects(:write_password_file!).in_sequence(s)
151
+
152
+ Backup::Logger.expects(:message).in_sequence(s)
153
+ syncer.expects(:run).in_sequence(s).raises('error message')
154
+
155
+ syncer.expects(:remove_password_file!).in_sequence(s)
156
+
157
+ expect do
158
+ syncer.perform!
159
+ end.to raise_error(RuntimeError, 'error message')
160
+ end
161
+ end # describe '#perform!'
162
+
163
+ describe '#dest_path' do
164
+ it 'should remove any preceeding "~/" from @path' do
165
+ syncer.send(:dest_path).should == 'my_backups'
166
+ end
167
+
168
+ it 'should set @dest_path' do
169
+ syncer.send(:dest_path)
170
+ syncer.instance_variable_get(:@dest_path).should == 'my_backups'
171
+ end
172
+
173
+ it 'should return @dest_path if already set' do
174
+ syncer.instance_variable_set(:@dest_path, 'foo')
175
+ syncer.send(:dest_path).should == 'foo'
176
+ end
177
+ end
178
+
179
+ describe '#options' do
180
+ let(:pwdfile) { mock }
181
+
182
+ context 'when @compress is true' do
183
+ it 'should return the options string with compression enabled' do
184
+ syncer.send(:options).should ==
185
+ "--archive --delete --compress -e 'ssh -p 22' --opt-a --opt-b"
186
+ end
187
+ end
188
+
189
+ context 'when @compress is false' do
190
+ before { syncer.compress = false }
191
+ it 'should return the options string without compression enabled' do
192
+ syncer.send(:options).should ==
193
+ "--archive --delete -e 'ssh -p 22' --opt-a --opt-b"
194
+ end
195
+ end
196
+
197
+ context 'when a @password_file is set' do
198
+ before do
199
+ syncer.instance_variable_set(:@password_file, pwdfile)
200
+ pwdfile.expects(:path).returns('/path/to/pwdfile')
201
+ end
202
+
203
+ it 'should return the options string with the password_option' do
204
+ syncer.send(:options).should ==
205
+ "--archive --delete --compress -e 'ssh -p 22' " +
206
+ "--password-file='/path/to/pwdfile' --opt-a --opt-b"
207
+ end
208
+ end
209
+
210
+ context 'when no @additional_options are set' do
211
+ before { syncer.additional_options = [] }
212
+
213
+ it 'should return the options string without additional options' do
214
+ syncer.send(:options).should ==
215
+ "--archive --delete --compress -e 'ssh -p 22'"
216
+ end
217
+ end
218
+
219
+ end # describe '#options'
220
+
221
+ describe '#compress_option' do
222
+ context 'when @compress is true' do
223
+ it 'should return the compression flag' do
224
+ syncer.send(:compress_option).should == '--compress'
225
+ end
226
+ end
227
+
228
+ context 'when @compress is false' do
229
+ before { syncer.compress = false }
230
+ it 'should return nil' do
231
+ syncer.send(:compress_option).should be_nil
232
+ end
233
+ end
234
+ end
235
+
236
+ describe '#port_option' do
237
+ before { syncer.port = 40 }
238
+ it 'should return the option string with the defined port' do
239
+ syncer.send(:port_option).should == "-e 'ssh -p 40'"
240
+ end
241
+ end
242
+
243
+ describe '#password_option' do
244
+ let(:pwdfile) { mock }
245
+
246
+ context 'when @password_file is set' do
247
+ before do
248
+ syncer.instance_variable_set(:@password_file, pwdfile)
249
+ pwdfile.expects(:path).returns('/path/to/pwdfile')
250
+ end
251
+
252
+ it 'should return the option string' do
253
+ syncer.send(:password_option).should ==
254
+ "--password-file='/path/to/pwdfile'"
255
+ end
256
+ end
257
+
258
+ context 'when @password_file is not set' do
259
+ it 'should return nil' do
260
+ syncer.send(:password_option).should be_nil
261
+ end
262
+ end
263
+ end
264
+
265
+ describe '#write_password_file!' do
266
+ let(:pwdfile) { mock }
267
+ let(:s) { sequence '' }
268
+
269
+ context 'when a @password is set' do
270
+ it 'should create, write and close a temporary password file' do
271
+ Tempfile.expects(:new).in_sequence(s).
272
+ with('backup-rsync-password').
273
+ returns(pwdfile)
274
+ pwdfile.expects(:write).in_sequence(s).with('my_password')
275
+ pwdfile.expects(:close).in_sequence(s)
276
+
277
+ syncer.send(:write_password_file!)
278
+ end
279
+
280
+ it 'should set @password_file to a file containing the password' do
281
+ syncer.send(:write_password_file!)
282
+ file = syncer.instance_variable_get(:@password_file)
283
+ File.exist?(file.path).should be_true
284
+ File.read(file.path).should == 'my_password'
285
+
286
+ # cleanup
287
+ file.delete
288
+ file.path.should be_nil
289
+ end
290
+ end
291
+
292
+ context 'when a @password is not set' do
293
+ before { syncer.password = nil }
294
+ it 'should return nil' do
295
+ Tempfile.expects(:new).never
296
+ pwdfile.expects(:write).never
297
+ pwdfile.expects(:close).never
298
+ syncer.send(:write_password_file!).should be_nil
299
+ end
300
+ end
301
+ end
302
+
303
+ describe '#remove_password_file!' do
304
+ let(:pwdfile) { mock }
305
+
306
+ context 'when @password_file is set' do
307
+ before do
308
+ syncer.instance_variable_set(:@password_file, pwdfile)
309
+ end
310
+
311
+ it 'should delete the file and reset @password_file' do
312
+ pwdfile.expects(:delete)
313
+ syncer.send(:remove_password_file!)
314
+ syncer.instance_variable_get(:@password_file).should be_nil
315
+ end
316
+ end
317
+
318
+ context 'when @password_file is not set' do
319
+ it 'should return nil' do
320
+ pwdfile.expects(:delete).never
321
+ syncer.send(:remove_password_file!).should be_nil
322
+ syncer.instance_variable_get(:@password_file).should be_nil
323
+ end
324
+ end
325
+ end
326
+
327
+ end