backup 3.0.20 → 3.0.21

Sign up to get free protection for your applications and to get access to all the features.
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