awshucks 0.0.1

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 (44) hide show
  1. data/CHANGES +4 -0
  2. data/LICENSE +19 -0
  3. data/README +32 -0
  4. data/Rakefile +14 -0
  5. data/TODO +143 -0
  6. data/bin/awshucks +10 -0
  7. data/lib/awshucks.rb +29 -0
  8. data/lib/awshucks/cli.rb +76 -0
  9. data/lib/awshucks/command.rb +98 -0
  10. data/lib/awshucks/commands.rb +3 -0
  11. data/lib/awshucks/commands/backup.rb +59 -0
  12. data/lib/awshucks/commands/backups.rb +25 -0
  13. data/lib/awshucks/commands/help.rb +22 -0
  14. data/lib/awshucks/commands/list.rb +39 -0
  15. data/lib/awshucks/commands/new_config.rb +36 -0
  16. data/lib/awshucks/commands/reset_metadata_cache.rb +38 -0
  17. data/lib/awshucks/commands/restore.rb +54 -0
  18. data/lib/awshucks/config.rb +83 -0
  19. data/lib/awshucks/ext.rb +23 -0
  20. data/lib/awshucks/file_info.rb +23 -0
  21. data/lib/awshucks/file_store.rb +111 -0
  22. data/lib/awshucks/gemspec.rb +48 -0
  23. data/lib/awshucks/scanner.rb +58 -0
  24. data/lib/awshucks/specification.rb +128 -0
  25. data/lib/awshucks/version.rb +18 -0
  26. data/resources/awshucks.yml +21 -0
  27. data/spec/awshucks_spec.rb +7 -0
  28. data/spec/cli_spec.rb +130 -0
  29. data/spec/command_spec.rb +111 -0
  30. data/spec/commands/backup_spec.rb +164 -0
  31. data/spec/commands/backups_spec.rb +41 -0
  32. data/spec/commands/help_spec.rb +42 -0
  33. data/spec/commands/list_spec.rb +77 -0
  34. data/spec/commands/new_config_spec.rb +102 -0
  35. data/spec/commands/reset_metadata_cache_spec.rb +93 -0
  36. data/spec/commands/restore_spec.rb +219 -0
  37. data/spec/config_spec.rb +152 -0
  38. data/spec/ext_spec.rb +28 -0
  39. data/spec/file_info_spec.rb +45 -0
  40. data/spec/file_store_spec.rb +352 -0
  41. data/spec/scanner_spec.rb +106 -0
  42. data/spec/spec_helper.rb +36 -0
  43. data/spec/specification_spec.rb +41 -0
  44. metadata +121 -0
@@ -0,0 +1,164 @@
1
+ require File.join(File.dirname(__FILE__),"..","spec_helper.rb")
2
+
3
+ describe Awshucks::BackupCommand do
4
+ it "has 'backup' as the command" do
5
+ Awshucks::BackupCommand.command.should == 'backup'
6
+ end
7
+ end
8
+
9
+ describe Awshucks::BackupCommand, '#execute, with no command-line argument' do
10
+
11
+ before(:each) do
12
+ @config = mock('config')
13
+ @config.stub!(:connection)
14
+ @config.stub!(:bucket).and_return('bucket')
15
+
16
+ @backup = mock('backup')
17
+ @backup.stub!(:location).and_return('/primary/backup')
18
+ @backup.stub!(:name).and_return('test backup')
19
+
20
+ @config.should_receive(:backups).and_return([@backup, @backup])
21
+
22
+ @file_store = mock("mock file store")
23
+ @file_store.stub!(:save_cache)
24
+ Awshucks::FileStore.should_receive(:new).twice.and_return(@file_store)
25
+
26
+ @command = Awshucks::BackupCommand.new
27
+
28
+ @old_stdout, $stdout = $stdout, StringIO.new
29
+ end
30
+
31
+ after(:each) do
32
+ $stdout = @old_stdout
33
+ end
34
+
35
+ it "scans the filesystem for all configured backup locations" do
36
+ Awshucks::Scanner.should_receive(:each_file).twice
37
+ @command.execute([], @config)
38
+ end
39
+
40
+ it "prints out each backup as it runs" do
41
+ Awshucks::Scanner.stub!(:each_file)
42
+ @command.execute([], @config)
43
+ $stdout.string.should =~ /backing up \/primary\/backup.*backing up/m
44
+ end
45
+
46
+ it "saves each file store's cache when it's done using them" do
47
+ Awshucks::Scanner.stub!(:each_file)
48
+ @file_store.should_receive(:save_cache).twice
49
+ @command.execute([], @config)
50
+ end
51
+
52
+ end
53
+
54
+ describe Awshucks::BackupCommand, '#execute, with an invalid backup specified' do
55
+
56
+ before(:each) do
57
+ @old_stderr, $stderr = $stderr, StringIO.new
58
+ @config = mock('config')
59
+
60
+ @command = Awshucks::BackupCommand.new
61
+ end
62
+
63
+ after(:each) do
64
+ $stderr = @old_stderr
65
+ end
66
+
67
+ it "prints out an error" do
68
+ @config.should_receive(:backup).with('test').and_raise(Awshucks::UnknownBackupError.new('test'))
69
+ @command.execute(['test'], @config)
70
+ $stderr.string.should_not be_empty
71
+ end
72
+ end
73
+
74
+ describe Awshucks::BackupCommand, '#execute, with a single backup specified' do
75
+
76
+ before(:each) do
77
+ @config = mock('config')
78
+ @config.stub!(:connection)
79
+ @config.stub!(:bucket).and_return('bucket')
80
+
81
+ @backup = mock('backup')
82
+ @backup.stub!(:location).and_return('/primary/backup')
83
+ @backup.stub!(:name).and_return('test backup')
84
+
85
+ @config.should_receive(:backup).with('test').and_return(@backup)
86
+
87
+ @file_store = mock("mock file store")
88
+ @file_store.stub!(:save_cache)
89
+ Awshucks::FileStore.stub!(:new).and_return(@file_store)
90
+
91
+ @info = mock('file info')
92
+ @info.stub!(:filename).and_return 'file'
93
+ @info.stub!(:mtime).and_return Time.now
94
+ @info.stub!(:size).and_return 12345
95
+
96
+ @command = Awshucks::BackupCommand.new
97
+
98
+ @old_stdout, $stdout = $stdout, StringIO.new
99
+ end
100
+
101
+ after(:each) do
102
+ $stdout = @old_stdout
103
+ end
104
+
105
+ it "scans the filesystem at the configurated location" do
106
+ Awshucks::Scanner.should_receive(:each_file).with('/primary/backup')
107
+ @command.execute(['test'], @config)
108
+ end
109
+
110
+ it "will not store the file if the same as the file store's" do
111
+ Awshucks::Scanner.should_receive(:each_file).with('/primary/backup').and_yield(@info)
112
+ @file_store.should_receive(:different_from?).and_return(false)
113
+
114
+ @file_store.should_not_receive(:store)
115
+
116
+ @command.execute(['test'], @config)
117
+ end
118
+
119
+ it "prints out a status message if the file hasn't been changed" do
120
+ Awshucks::Scanner.stub!(:each_file).and_yield(@info)
121
+ @file_store.should_receive(:different_from?).and_return(false)
122
+
123
+ @command.execute(['test'], @config)
124
+
125
+ $stdout.string.should =~ /file.*unchanged/
126
+ end
127
+
128
+ it "stores the file if it's different from the file store" do
129
+ sum = 'this is a pretend md5 sum'
130
+
131
+ Awshucks::Scanner.should_receive(:each_file).with('/primary/backup').and_yield(@info)
132
+ @file_store.stub!(:different_from?).and_return(true)
133
+ @file_store.should_receive(:store).with(@info)
134
+
135
+ @command.execute(['test'], @config)
136
+ end
137
+
138
+ it "prints out a message for each file uploaded" do
139
+ Awshucks::Scanner.stub!(:each_file).and_yield(@info)
140
+ @file_store.stub!(:different_from?).and_return(true)
141
+ @file_store.stub!(:store)
142
+
143
+ @command.execute(['test'], @config)
144
+ $stdout.string.should =~ /file.*uploading/
145
+ end
146
+
147
+ it "saves the metadata cache when it's done" do
148
+ Awshucks::Scanner.stub!(:each_file)
149
+ @file_store.should_receive(:save_cache)
150
+ @command.execute(['test'], @config)
151
+
152
+ end
153
+
154
+ it "saves the metadata cache even if an exception is raised" do
155
+ Awshucks::Scanner.stub!(:each_file).and_raise(SystemExit)
156
+ @file_store.should_receive(:save_cache)
157
+ lambda {@command.execute(['test'], @config)}.should raise_error(SystemExit)
158
+ end
159
+
160
+ end
161
+
162
+ # describe Awshucks::BackupCommand, '#execute, when the dry run option is set' do
163
+ # it "shouldn't do anything"
164
+ # end
@@ -0,0 +1,41 @@
1
+ require File.join(File.dirname(__FILE__),"..","spec_helper.rb")
2
+
3
+ describe Awshucks::BackupsCommand do
4
+ it "has 'backups' as the command" do
5
+ Awshucks::BackupsCommand.command.should == 'backups'
6
+ end
7
+ end
8
+
9
+ describe Awshucks::BackupsCommand, '#execute' do
10
+
11
+ before(:each) do
12
+ @config = mock('config')
13
+
14
+ @backup = mock('backup')
15
+ @backup.stub!(:name).and_return('test_backup', 'secondary_backup')
16
+ @backup.stub!(:location).and_return('/primary/backup', '/secondary')
17
+
18
+ @config.should_receive(:backups).and_return([@backup, @backup])
19
+
20
+ @command = Awshucks::BackupsCommand.new
21
+
22
+ @old_stdout, $stdout = $stdout, StringIO.new
23
+ end
24
+
25
+ after(:each) do
26
+ $stdout = @old_stdout
27
+ end
28
+
29
+ it "prints out the backup configuration name" do
30
+ @command.execute([], @config)
31
+ $stdout.string.should =~ /test_backup:/
32
+ $stdout.string.should =~ /secondary_backup:/
33
+ end
34
+
35
+ it "prints out the location for each backup" do
36
+ @command.execute([], @config)
37
+ $stdout.string.should =~ /location:.*\/primary\/backup/
38
+ $stdout.string.should =~ /location:.*\/secondary/
39
+ end
40
+
41
+ end
@@ -0,0 +1,42 @@
1
+ require File.join(File.dirname(__FILE__),"..","spec_helper.rb")
2
+
3
+ describe Awshucks::HelpCommand do
4
+ it "has 'help' as the command" do
5
+ Awshucks::HelpCommand.command.should == 'help'
6
+ end
7
+ end
8
+
9
+ describe Awshucks::HelpCommand, '#execute' do
10
+
11
+ before(:each) do
12
+ @cmd = mock('command')
13
+ @config = mock('config')
14
+ @old_stdout, $stdout = $stdout, StringIO.new
15
+ @old_stderr, $stderr = $stderr, StringIO.new
16
+ @help = Awshucks::HelpCommand.new
17
+ end
18
+
19
+ after(:each) do
20
+ $stdout = @old_stdout
21
+ $stderr = @old_stderr
22
+ end
23
+
24
+ it "displays the main help message if the args list is empty" do
25
+ @config.should_receive(:help_message)
26
+ @help.execute([], @config)
27
+ end
28
+
29
+ it "displays usage for the provided command in args" do
30
+ Awshucks::Command.stub!(:commands).and_return({'pretend' => @cmd})
31
+ @cmd.should_receive(:option_string).and_return('pretend options output string')
32
+ @help.execute(['pretend'], @config)
33
+ $stdout.string.should include('pretend options output string')
34
+ end
35
+
36
+ it "prints an error if the provided command isn't found" do
37
+ Awshucks::Command.stub!(:commands).and_return({})
38
+ @help.execute(['pretend'], @config)
39
+ $stderr.string.should =~ /pretend/
40
+ end
41
+
42
+ end
@@ -0,0 +1,77 @@
1
+ require File.join(File.dirname(__FILE__),"..","spec_helper.rb")
2
+
3
+ describe Awshucks::ListCommand do
4
+ it "has 'list' as the command" do
5
+ Awshucks::ListCommand.command.should == 'list'
6
+ end
7
+ end
8
+
9
+ describe Awshucks::ListCommand, '#execute, with no backup configuration specified' do
10
+
11
+ before(:each) do
12
+ @config = mock('config')
13
+ @config.stub!(:connection).and_return nil
14
+ @config.stub!(:bucket).and_return('testbucket')
15
+
16
+ @file_store = mock(Awshucks::FileStore)
17
+ Awshucks::FileStore.should_receive(:new).twice.with(nil, 'testbucket', 'testbackup').and_return(@file_store)
18
+
19
+ @list = Awshucks::ListCommand.new
20
+
21
+ @backup = mock('backup information')
22
+ @backup.stub!(:location).and_return('test_location')
23
+ @backup.stub!(:name).and_return('testbackup')
24
+
25
+ @old_stdout, $stdout = $stdout, StringIO.new
26
+ end
27
+
28
+ after(:each) do
29
+ $stdout = @old_stdout
30
+ end
31
+
32
+ it "lists the files for each backup" do
33
+ @config.should_receive(:backups).and_return([@backup, @backup])
34
+ @file_store.should_receive(:each_file).twice.and_yield('test/file')
35
+ @list.execute([], @config)
36
+ end
37
+
38
+ end
39
+
40
+ describe Awshucks::ListCommand, '#execute, with a backup configuration specified' do
41
+
42
+ before(:each) do
43
+ @config = mock('config')
44
+ @config.stub!(:connection).and_return nil
45
+ @config.stub!(:bucket).and_return('testbucket')
46
+
47
+ @file_store = mock(Awshucks::FileStore)
48
+
49
+ @list = Awshucks::ListCommand.new
50
+
51
+ @backup = mock('backup information')
52
+ @backup.stub!(:location).and_return('test_location')
53
+ @backup.stub!(:name).and_return('testbackup')
54
+
55
+ @old_stderr, $stderr = $stderr, StringIO.new
56
+ @old_stdout, $stdout = $stdout, StringIO.new
57
+ end
58
+
59
+ after(:each) do
60
+ $stderr = @old_stderr
61
+ $stdout = @old_stdout
62
+ end
63
+
64
+ it "lists each file for the backup" do
65
+ @config.should_receive(:backup).with('testbackup').and_return(@backup)
66
+ Awshucks::FileStore.should_receive(:new).with(nil, 'testbucket', 'testbackup').and_return(@file_store)
67
+ @file_store.should_receive(:each_file).and_yield('file')
68
+
69
+ @list.execute(['testbackup'], @config)
70
+ end
71
+
72
+ it "prints a warning if the backup config isn't found" do
73
+ @config.stub!(:backup).and_raise(Awshucks::UnknownBackupError.new('foo'))
74
+ @list.execute(['foo'], @config)
75
+ end
76
+
77
+ end
@@ -0,0 +1,102 @@
1
+ require File.join(File.dirname(__FILE__),"..","spec_helper.rb")
2
+
3
+ describe Awshucks::NewConfigCommand do
4
+ it "has 'new_config' as the command" do
5
+ Awshucks::NewConfigCommand.command.should == 'new_config'
6
+ end
7
+ end
8
+
9
+ describe Awshucks::NewConfigCommand, '#execute' do
10
+
11
+ before(:each) do
12
+ @command = Awshucks::NewConfigCommand.new
13
+ @old_stdout, $stdout = $stdout, StringIO.new
14
+ @old_stderr, $stderr = $stderr, StringIO.new
15
+ end
16
+
17
+ after(:each) do
18
+ $stdout = @old_stdout
19
+ $stderr = @old_stderr
20
+ FileUtils.rm(dummy_file_path('awshucks.yml')) if File.exists?(dummy_file_path('awshucks.yml'))
21
+ end
22
+
23
+ it "copies awshucks.yml from the resources directory to the current working directory" do
24
+ FileUtils.should_receive(:cp).with(
25
+ File.join(Awshucks::RESOURCE_DIR, 'awshucks.yml'),
26
+ dummy_file_path('awshucks.yml')
27
+ )
28
+ Dir.chdir(dummy_fs_path) do
29
+ @command.execute([], nil)
30
+ end
31
+
32
+ end
33
+
34
+ it "refuses to overwrite the file if it already exists" do
35
+ FileUtils.should_not_receive(:cp)
36
+ FileUtils.touch(dummy_file_path('awshucks.yml'))
37
+ Dir.chdir(dummy_fs_path) do
38
+ @command.execute([], nil)
39
+ end
40
+ end
41
+
42
+ it "complains if the file already exists" do
43
+ FileUtils.should_not_receive(:cp)
44
+ FileUtils.touch(dummy_file_path('awshucks.yml'))
45
+ Dir.chdir(dummy_fs_path) do
46
+ @command.execute([], nil)
47
+ end
48
+ $stderr.string.should include(File.join(dummy_file_path('awshucks.yml')))
49
+ end
50
+
51
+ # it "overwrites the existing file if the --force option is specified" do
52
+ # FileUtils.touch(dummy_file_path('awshucks.yml'))
53
+ # FileUtils.should_receive(:cp).with(
54
+ # File.join(Awshucks::RESOURCE_DIR, 'awshucks.yml'),
55
+ # File.join(dummy_fs_path, 'awshucks.yml')
56
+ # )
57
+ # Dir.chdir(dummy_fs_path) do
58
+ # @command.execute(['-f'], nil)
59
+ # end
60
+ # $stderr.string.should be_empty
61
+ # end
62
+
63
+ it "prints out the path where it's creating the new config file" do
64
+ FileUtils.stub!(:cp)
65
+ Dir.chdir(dummy_fs_path) do
66
+ @command.execute([], nil)
67
+ end
68
+ $stdout.string.should include(File.join(dummy_fs_path, 'awshucks.yml'))
69
+ end
70
+
71
+ end
72
+
73
+ describe Awshucks::NewConfigCommand, '#execute' do
74
+
75
+ before(:each) do
76
+ @command = Awshucks::NewConfigCommand.new
77
+ @old_stdout, $stdout = $stdout, StringIO.new
78
+ end
79
+
80
+ after(:each) do
81
+ $stdout = @old_stdout
82
+ end
83
+
84
+ it "copies awshucks.yml from the resources directory to the specified path" do
85
+ FileUtils.should_receive(:cp).with(
86
+ File.join(Awshucks::RESOURCE_DIR, 'awshucks.yml'),
87
+ File.join(dummy_fs_path, 'foo/test.yml')
88
+ )
89
+ Dir.chdir(dummy_fs_path) do
90
+ @command.execute(['foo/test.yml'], nil)
91
+ end
92
+ end
93
+
94
+ it "prints out the path where it's creating the new config file" do
95
+ FileUtils.stub!(:cp)
96
+ Dir.chdir(dummy_fs_path) do
97
+ @command.execute(['foo/test.yml'], nil)
98
+ end
99
+ $stdout.string.should include(File.join(dummy_fs_path, 'foo/test.yml'))
100
+ end
101
+
102
+ end
@@ -0,0 +1,93 @@
1
+ require File.join(File.dirname(__FILE__),"..","spec_helper.rb")
2
+
3
+ describe Awshucks::ResetMetadataCacheCommand do
4
+ it "has 'reset_metadata_cache' as the command" do
5
+ Awshucks::ResetMetadataCacheCommand.command.should == 'reset_metadata_cache'
6
+ end
7
+ end
8
+
9
+ describe Awshucks::BackupsCommand, '#execute with no arguments' do
10
+
11
+ before(:each) do
12
+ @config = mock('config')
13
+ @config.stub!(:connection)
14
+ @config.stub!(:bucket).and_return('bucket')
15
+
16
+ @backup = mock('backup')
17
+ @backup.stub!(:location).and_return('/primary/backup')
18
+ @backup.stub!(:name).and_return('test backup')
19
+
20
+ @config.should_receive(:backups).and_return([@backup, @backup])
21
+
22
+ @file_store = mock("mock file store")
23
+ @file_store.should_receive(:reset_cache).twice
24
+ Awshucks::FileStore.should_receive(:new).twice.and_return(@file_store)
25
+
26
+ @command = Awshucks::ResetMetadataCacheCommand.new
27
+
28
+ @old_stdout, $stdout = $stdout, StringIO.new
29
+ end
30
+
31
+ after(:each) do
32
+ $stdout = @old_stdout
33
+ end
34
+
35
+ it "instantiates a file store for each backup and invokes reset_cache on each" do
36
+ @command.execute([], @config)
37
+ end
38
+
39
+ end
40
+
41
+ describe Awshucks::BackupsCommand, '#execute with a backup configuration specified' do
42
+
43
+ before(:each) do
44
+ @config = mock('config')
45
+ @config.stub!(:connection)
46
+ @config.stub!(:bucket).and_return('bucket')
47
+
48
+ @backup = mock('backup')
49
+ @backup.stub!(:location).and_return('/primary/backup')
50
+ @backup.stub!(:name).and_return('test backup')
51
+
52
+ @config.should_receive(:backup).and_return(@backup)
53
+
54
+ @file_store = mock("mock file store")
55
+ @file_store.should_receive(:reset_cache)
56
+ Awshucks::FileStore.should_receive(:new).and_return(@file_store)
57
+
58
+ @command = Awshucks::ResetMetadataCacheCommand.new
59
+ @old_stdout, $stdout = $stdout, StringIO.new
60
+ end
61
+
62
+ after(:each) do
63
+ $stdout = @old_stdout
64
+ end
65
+
66
+ it "instantiates a file store for the given backup configuration and calls reset_cache" do
67
+ @command.execute(['test_backup'], @config)
68
+ end
69
+
70
+ end
71
+
72
+ describe Awshucks::BackupsCommand, '#execute with an invalid backup configuration specified' do
73
+
74
+ before(:each) do
75
+ @config = mock('config')
76
+ @config.stub!(:connection)
77
+ @config.stub!(:bucket).and_return('bucket')
78
+
79
+ @command = Awshucks::ResetMetadataCacheCommand.new
80
+ @old_stderr, $stderr = $stderr, StringIO.new
81
+ end
82
+
83
+ after(:each) do
84
+ $stderr = @old_stderr
85
+ end
86
+
87
+ it "prints out an error message" do
88
+ @config.should_receive(:backup).with('invalid').and_raise(Awshucks::UnknownBackupError.new('invalid'))
89
+ @command.execute(['invalid'], @config)
90
+ $stderr.string.should_not be_empty
91
+ end
92
+
93
+ end