netguru-safe 0.2.9
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.
- data/.autotest +42 -0
- data/.document +5 -0
- data/.gitignore +11 -0
- data/CHANGELOG +25 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +44 -0
- data/LICENSE +20 -0
- data/README.markdown +237 -0
- data/Rakefile +32 -0
- data/TODO +11 -0
- data/VERSION +1 -0
- data/astrails-safe.gemspec +37 -0
- data/bin/astrails-safe +53 -0
- data/examples/example_helper.rb +19 -0
- data/lib/astrails/safe.rb +73 -0
- data/lib/astrails/safe/archive.rb +24 -0
- data/lib/astrails/safe/backup.rb +20 -0
- data/lib/astrails/safe/cloudfiles.rb +77 -0
- data/lib/astrails/safe/config/builder.rb +60 -0
- data/lib/astrails/safe/config/node.rb +76 -0
- data/lib/astrails/safe/gpg.rb +46 -0
- data/lib/astrails/safe/gzip.rb +25 -0
- data/lib/astrails/safe/local.rb +51 -0
- data/lib/astrails/safe/mongodump.rb +23 -0
- data/lib/astrails/safe/mysqldump.rb +32 -0
- data/lib/astrails/safe/pgdump.rb +36 -0
- data/lib/astrails/safe/pipe.rb +17 -0
- data/lib/astrails/safe/s3.rb +75 -0
- data/lib/astrails/safe/sftp.rb +88 -0
- data/lib/astrails/safe/sink.rb +35 -0
- data/lib/astrails/safe/source.rb +47 -0
- data/lib/astrails/safe/stream.rb +20 -0
- data/lib/astrails/safe/svndump.rb +13 -0
- data/lib/astrails/safe/tmp_file.rb +48 -0
- data/lib/astrails/safe/version.rb +5 -0
- data/lib/extensions/mktmpdir.rb +45 -0
- data/spec/integration/airbrake_integration_spec.rb +76 -0
- data/spec/integration/archive_integration_spec.rb +88 -0
- data/spec/integration/cleanup_spec.rb +61 -0
- data/spec/spec.opts +5 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/unit/archive_spec.rb +67 -0
- data/spec/unit/cloudfiles_spec.rb +177 -0
- data/spec/unit/config_spec.rb +234 -0
- data/spec/unit/gpg_spec.rb +148 -0
- data/spec/unit/gzip_spec.rb +64 -0
- data/spec/unit/local_spec.rb +110 -0
- data/spec/unit/mongodump_spec.rb +54 -0
- data/spec/unit/mysqldump_spec.rb +83 -0
- data/spec/unit/pgdump_spec.rb +45 -0
- data/spec/unit/s3_spec.rb +163 -0
- data/spec/unit/svndump_spec.rb +39 -0
- data/templates/script.rb +160 -0
- metadata +222 -0
@@ -0,0 +1,177 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe Astrails::Safe::Cloudfiles do
|
4
|
+
|
5
|
+
def def_config
|
6
|
+
{
|
7
|
+
:cloudfiles => {
|
8
|
+
:container => "_container",
|
9
|
+
:user => "_user",
|
10
|
+
:api_key => "_api_key",
|
11
|
+
},
|
12
|
+
:keep => {
|
13
|
+
:cloudfiles => 2
|
14
|
+
}
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def def_backup(extra = {})
|
19
|
+
{
|
20
|
+
:kind => "_kind",
|
21
|
+
:filename => "/backup/somewhere/_kind-_id.NOW.bar",
|
22
|
+
:extension => ".bar",
|
23
|
+
:id => "_id",
|
24
|
+
:timestamp => "NOW"
|
25
|
+
}.merge(extra)
|
26
|
+
end
|
27
|
+
|
28
|
+
def cloudfiles(config = def_config, backup = def_backup)
|
29
|
+
Astrails::Safe::Cloudfiles.new(
|
30
|
+
Astrails::Safe::Config::Node.new(nil, config),
|
31
|
+
Astrails::Safe::Backup.new(backup)
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
describe :cleanup do
|
36
|
+
|
37
|
+
before(:each) do
|
38
|
+
@cloudfiles = cloudfiles
|
39
|
+
|
40
|
+
@files = [4,1,3,2].map { |i| "aaaaa#{i}" }
|
41
|
+
|
42
|
+
@container = "container"
|
43
|
+
|
44
|
+
stub(@container).objects(:prefix => "_kind/_id/_kind-_id.") { @files }
|
45
|
+
stub(@container).delete_object(anything)
|
46
|
+
|
47
|
+
stub(CloudFiles::Connection).
|
48
|
+
new('_user', '_api_key', true, false).stub!.
|
49
|
+
container('_container') {@container}
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should check [:keep, :cloudfiles]" do
|
53
|
+
@cloudfiles.config[:keep].data["cloudfiles"] = nil
|
54
|
+
dont_allow(@cloudfiles.backup).filename
|
55
|
+
@cloudfiles.send :cleanup
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should delete extra files" do
|
59
|
+
mock(@container).delete_object('aaaaa1')
|
60
|
+
mock(@container).delete_object('aaaaa2')
|
61
|
+
@cloudfiles.send :cleanup
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
describe :active do
|
67
|
+
before(:each) do
|
68
|
+
@cloudfiles = cloudfiles
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should be true when all params are set" do
|
72
|
+
@cloudfiles.should be_active
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should be false if container is missing" do
|
76
|
+
@cloudfiles.config[:cloudfiles].data["container"] = nil
|
77
|
+
@cloudfiles.should_not be_active
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should be false if user is missing" do
|
81
|
+
@cloudfiles.config[:cloudfiles].data["user"] = nil
|
82
|
+
@cloudfiles.should_not be_active
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should be false if api_key is missing" do
|
86
|
+
@cloudfiles.config[:cloudfiles].data["api_key"] = nil
|
87
|
+
@cloudfiles.should_not be_active
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe :path do
|
92
|
+
before(:each) do
|
93
|
+
@cloudfiles = cloudfiles
|
94
|
+
end
|
95
|
+
it "should use cloudfiles/path 1st" do
|
96
|
+
@cloudfiles.config[:cloudfiles].data["path"] = "cloudfiles_path"
|
97
|
+
@cloudfiles.config[:local] = {:path => "local_path"}
|
98
|
+
@cloudfiles.send(:path).should == "cloudfiles_path"
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should use local/path 2nd" do
|
102
|
+
@cloudfiles.config[:local] = {:path => "local_path"}
|
103
|
+
@cloudfiles.send(:path).should == "local_path"
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should use constant 3rd" do
|
107
|
+
@cloudfiles.send(:path).should == "_kind/_id"
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
describe :save do
|
113
|
+
def add_stubs(*stubs)
|
114
|
+
stubs.each do |s|
|
115
|
+
case s
|
116
|
+
when :connection
|
117
|
+
@connection = "connection"
|
118
|
+
stub(CloudFiles::Authentication).new
|
119
|
+
stub(CloudFiles::Connection).
|
120
|
+
new('_user', '_api_key', true, false) {@connection}
|
121
|
+
when :file_size
|
122
|
+
stub(@cloudfiles).get_file_size("foo") {123}
|
123
|
+
when :create_container
|
124
|
+
@container = "container"
|
125
|
+
stub(@container).create_object("_kind/_id/backup/somewhere/_kind-_id.NOW.bar.bar", true) {@object}
|
126
|
+
stub(@connection).create_container {@container}
|
127
|
+
when :file_open
|
128
|
+
stub(File).open("foo")
|
129
|
+
when :cloudfiles_store
|
130
|
+
@object = "object"
|
131
|
+
stub(@object).write(nil) {true}
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
before(:each) do
|
137
|
+
@cloudfiles = cloudfiles(def_config, def_backup(:path => "foo"))
|
138
|
+
@full_path = "_kind/_id/backup/somewhere/_kind-_id.NOW.bar.bar"
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should fail if no backup.file is set" do
|
142
|
+
@cloudfiles.backup.path = nil
|
143
|
+
proc {@cloudfiles.send(:save)}.should raise_error(RuntimeError)
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should establish Cloud Files connection" do
|
147
|
+
add_stubs(:connection, :file_size, :create_container, :file_open, :cloudfiles_store)
|
148
|
+
@cloudfiles.send(:save)
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should open local file" do
|
152
|
+
add_stubs(:connection, :file_size, :create_container, :cloudfiles_store)
|
153
|
+
mock(File).open("foo")
|
154
|
+
@cloudfiles.send(:save)
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should call write on the cloudfile object with files' descriptor" do
|
158
|
+
add_stubs(:connection, :file_size, :create_container, :cloudfiles_store)
|
159
|
+
stub(File).open("foo") {"qqq"}
|
160
|
+
mock(@object).write("qqq") {true}
|
161
|
+
@cloudfiles.send(:save)
|
162
|
+
end
|
163
|
+
|
164
|
+
it "should upload file" do
|
165
|
+
add_stubs(:connection, :file_size, :create_container, :file_open, :cloudfiles_store)
|
166
|
+
@cloudfiles.send(:save)
|
167
|
+
end
|
168
|
+
|
169
|
+
it "should fail on files bigger then 5G" do
|
170
|
+
add_stubs(:connection)
|
171
|
+
mock(File).stat("foo").stub!.size {5*1024*1024*1024+1}
|
172
|
+
mock(STDERR).puts(anything)
|
173
|
+
dont_allow(Benchmark).realtime
|
174
|
+
@cloudfiles.send(:save)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
@@ -0,0 +1,234 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe Astrails::Safe::Config do
|
4
|
+
it "should parse example config" do
|
5
|
+
config = Astrails::Safe::Config::Node.new do
|
6
|
+
airbrake do
|
7
|
+
api_key "test_airbrake_api_key"
|
8
|
+
end
|
9
|
+
|
10
|
+
local do
|
11
|
+
path "path"
|
12
|
+
end
|
13
|
+
|
14
|
+
s3 do
|
15
|
+
key "s3 key"
|
16
|
+
secret "secret"
|
17
|
+
bucket "bucket"
|
18
|
+
path "path1"
|
19
|
+
end
|
20
|
+
|
21
|
+
sftp do
|
22
|
+
user "sftp user"
|
23
|
+
password "sftp password"
|
24
|
+
host "sftp host"
|
25
|
+
end
|
26
|
+
|
27
|
+
gpg do
|
28
|
+
key "gpg-key"
|
29
|
+
password "astrails"
|
30
|
+
end
|
31
|
+
|
32
|
+
keep do
|
33
|
+
local 4
|
34
|
+
s3 20
|
35
|
+
end
|
36
|
+
|
37
|
+
mysqldump do
|
38
|
+
options "-ceKq --single-transaction --create-options"
|
39
|
+
|
40
|
+
user "astrails"
|
41
|
+
password ""
|
42
|
+
host "localhost"
|
43
|
+
port 3306
|
44
|
+
socket "/var/run/mysqld/mysqld.sock"
|
45
|
+
|
46
|
+
database :blog
|
47
|
+
|
48
|
+
database :production do
|
49
|
+
keep :local => 3
|
50
|
+
|
51
|
+
gpg do
|
52
|
+
password "custom-production-pass"
|
53
|
+
end
|
54
|
+
|
55
|
+
skip_tables [:logger_exceptions, :request_logs]
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
pgdump do
|
61
|
+
options "-i -x -O"
|
62
|
+
|
63
|
+
user "astrails"
|
64
|
+
password ""
|
65
|
+
host "localhost"
|
66
|
+
port 5432
|
67
|
+
|
68
|
+
database :blog
|
69
|
+
|
70
|
+
database :production do
|
71
|
+
keep :local => 3
|
72
|
+
|
73
|
+
skip_tables [:logger_exceptions, :request_logs]
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
svndump do
|
79
|
+
repo :my_repo do
|
80
|
+
repo_path "/home/svn/my_repo"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
tar do
|
85
|
+
archive "git-repositories" do
|
86
|
+
files "/home/git/repositories"
|
87
|
+
end
|
88
|
+
|
89
|
+
archive "etc-files" do
|
90
|
+
files "/etc"
|
91
|
+
exclude "/etc/puppet/other"
|
92
|
+
end
|
93
|
+
|
94
|
+
archive "dot-configs" do
|
95
|
+
files "/home/*/.[^.]*"
|
96
|
+
end
|
97
|
+
|
98
|
+
archive "blog" do
|
99
|
+
files "/var/www/blog.astrails.com/"
|
100
|
+
exclude ["/var/www/blog.astrails.com/log", "/var/www/blog.astrails.com/tmp"]
|
101
|
+
end
|
102
|
+
|
103
|
+
archive :misc do
|
104
|
+
files [ "/backup/*.rb" ]
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
mongodump do
|
109
|
+
host "host"
|
110
|
+
database "database"
|
111
|
+
user "user"
|
112
|
+
password "password"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
expected = {
|
117
|
+
"airbrake" => {"api_key" => "test_airbrake_api_key"},
|
118
|
+
|
119
|
+
"local" => {"path" => "path"},
|
120
|
+
|
121
|
+
"s3" => {
|
122
|
+
"key" => "s3 key",
|
123
|
+
"secret" => "secret",
|
124
|
+
"bucket" => "bucket",
|
125
|
+
"path" => "path1",
|
126
|
+
},
|
127
|
+
|
128
|
+
"sftp" => {
|
129
|
+
"user" => "sftp user",
|
130
|
+
"password" => "sftp password",
|
131
|
+
"host" => "sftp host",
|
132
|
+
},
|
133
|
+
|
134
|
+
"gpg" => {"password" => "astrails", "key" => "gpg-key"},
|
135
|
+
|
136
|
+
"keep" => {"s3" => 20, "local" => 4},
|
137
|
+
|
138
|
+
"mysqldump" => {
|
139
|
+
"options" => "-ceKq --single-transaction --create-options",
|
140
|
+
"user" => "astrails",
|
141
|
+
"password" => "",
|
142
|
+
"host" => "localhost",
|
143
|
+
"port" => 3306,
|
144
|
+
"socket" => "/var/run/mysqld/mysqld.sock",
|
145
|
+
|
146
|
+
"databases" => {
|
147
|
+
"blog" => {},
|
148
|
+
"production" => {
|
149
|
+
"keep" => {"local" => 3},
|
150
|
+
"gpg" => {"password" => "custom-production-pass"},
|
151
|
+
"skip_tables" => ["logger_exceptions", "request_logs"],
|
152
|
+
},
|
153
|
+
},
|
154
|
+
},
|
155
|
+
|
156
|
+
"pgdump" => {
|
157
|
+
"options" => "-i -x -O",
|
158
|
+
"user" => "astrails",
|
159
|
+
"password" => "",
|
160
|
+
"host" => "localhost",
|
161
|
+
"port" => 5432,
|
162
|
+
|
163
|
+
"databases" => {
|
164
|
+
"blog" => {},
|
165
|
+
"production" => {
|
166
|
+
"keep" => {"local" => 3},
|
167
|
+
"skip_tables" => ["logger_exceptions", "request_logs"],
|
168
|
+
},
|
169
|
+
},
|
170
|
+
},
|
171
|
+
|
172
|
+
"svndump" => {
|
173
|
+
"repos" => {
|
174
|
+
"my_repo"=> {
|
175
|
+
"repo_path" => "/home/svn/my_repo"
|
176
|
+
}
|
177
|
+
}
|
178
|
+
},
|
179
|
+
|
180
|
+
"tar" => {
|
181
|
+
"archives" => {
|
182
|
+
"git-repositories" => {"files" => "/home/git/repositories"},
|
183
|
+
"etc-files" => {"files" => "/etc", "exclude" => "/etc/puppet/other"},
|
184
|
+
"dot-configs" => {"files" => "/home/*/.[^.]*"},
|
185
|
+
"blog" => {
|
186
|
+
"files" => "/var/www/blog.astrails.com/",
|
187
|
+
"exclude" => ["/var/www/blog.astrails.com/log", "/var/www/blog.astrails.com/tmp"],
|
188
|
+
},
|
189
|
+
"misc" => { "files" => ["/backup/*.rb"] },
|
190
|
+
},
|
191
|
+
},
|
192
|
+
|
193
|
+
"mongodump" => {
|
194
|
+
"host" => "host",
|
195
|
+
"databases" => {
|
196
|
+
"database" => {}
|
197
|
+
},
|
198
|
+
"user" => "user",
|
199
|
+
"password" => "password"
|
200
|
+
}
|
201
|
+
}
|
202
|
+
|
203
|
+
config.to_hash.should == expected
|
204
|
+
end
|
205
|
+
|
206
|
+
it "should make an array from multivalues" do
|
207
|
+
config = Astrails::Safe::Config::Node.new do
|
208
|
+
skip_tables "a"
|
209
|
+
skip_tables "b"
|
210
|
+
files "/foo"
|
211
|
+
files "/bar"
|
212
|
+
exclude "/foo/bar"
|
213
|
+
exclude "/foo/bar/baz"
|
214
|
+
end
|
215
|
+
|
216
|
+
expected = {
|
217
|
+
"skip_tables" => ["a", "b"],
|
218
|
+
"files" => ["/foo", "/bar"],
|
219
|
+
"exclude" => ["/foo/bar", "/foo/bar/baz"],
|
220
|
+
}
|
221
|
+
|
222
|
+
config.to_hash.should == expected
|
223
|
+
end
|
224
|
+
|
225
|
+
it "should raise error on key duplication" do
|
226
|
+
proc do
|
227
|
+
Astrails::Safe::Config::Node.new do
|
228
|
+
path "foo"
|
229
|
+
path "bar"
|
230
|
+
end
|
231
|
+
end.should raise_error(ArgumentError, "duplicate value for 'path'")
|
232
|
+
end
|
233
|
+
|
234
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe Astrails::Safe::Gpg do
|
4
|
+
def def_backup
|
5
|
+
{
|
6
|
+
:compressed => false,
|
7
|
+
:command => "command",
|
8
|
+
:extension => ".foo",
|
9
|
+
:filename => "qweqwe"
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
def gpg(config = {}, backup = def_backup)
|
14
|
+
Astrails::Safe::Gpg.new(
|
15
|
+
Astrails::Safe::Config::Node.new(nil, config),
|
16
|
+
Astrails::Safe::Backup.new(backup)
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
after(:each) { Astrails::Safe::TmpFile.cleanup }
|
21
|
+
|
22
|
+
describe :process do
|
23
|
+
|
24
|
+
before(:each) do
|
25
|
+
@gpg = gpg()
|
26
|
+
stub(@gpg).gpg_password_file {"pwd-file"}
|
27
|
+
stub(@gpg).pipe {"|gpg -BLAH"}
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "when active" do
|
31
|
+
before(:each) do
|
32
|
+
stub(@gpg).active? {true}
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should add .gpg extension" do
|
36
|
+
mock(@gpg.backup.extension) << '.gpg'
|
37
|
+
@gpg.process
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should add command pipe" do
|
41
|
+
mock(@gpg.backup.command) << (/\|gpg -BLAH/)
|
42
|
+
@gpg.process
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should set compressed" do
|
46
|
+
mock(@gpg.backup).compressed = true
|
47
|
+
@gpg.process
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "when inactive" do
|
52
|
+
before(:each) do
|
53
|
+
stub(@gpg).active? {false}
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should not touch extension" do
|
57
|
+
dont_allow(@gpg.backup.extension) << anything
|
58
|
+
@gpg.process
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should not touch command" do
|
62
|
+
dont_allow(@gpg.backup.command) << anything
|
63
|
+
@gpg.process
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should not touch compressed" do
|
67
|
+
dont_allow(@gpg.backup).compressed = anything
|
68
|
+
@gpg.process
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe :active? do
|
74
|
+
|
75
|
+
describe "with key" do
|
76
|
+
it "should be true" do
|
77
|
+
gpg(:gpg => {:key => :foo}).should be_active
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "with password" do
|
82
|
+
it "should be true" do
|
83
|
+
gpg(:gpg => {:password => :foo}).should be_active
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "without key & password" do
|
88
|
+
it "should be false" do
|
89
|
+
gpg.should_not be_active
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "with key & password" do
|
94
|
+
it "should raise RuntimeError" do
|
95
|
+
lambda {
|
96
|
+
gpg(:gpg => {:key => "foo", :password => "bar"}).send :active?
|
97
|
+
}.should raise_error(RuntimeError, "can't use both gpg password and pubkey")
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe :pipe do
|
103
|
+
|
104
|
+
describe "with key" do
|
105
|
+
def kgpg(extra={})
|
106
|
+
gpg({:gpg => {:key => "foo", :options => "GPG-OPT"}.merge(extra), :options => "OPT"})
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should not call gpg_password_file" do
|
110
|
+
g = kgpg
|
111
|
+
dont_allow(g).gpg_password_file(anything)
|
112
|
+
g.send(:pipe)
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should use '-r' and :options" do
|
116
|
+
kgpg.send(:pipe).should == "|gpg GPG-OPT -e -r foo"
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should use the 'command' options" do
|
120
|
+
kgpg(:command => 'other-gpg').send(:pipe).should == "|other-gpg GPG-OPT -e -r foo"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "with password" do
|
125
|
+
def pgpg(extra = {})
|
126
|
+
returning(gpg({:gpg => {:password => "bar", :options => "GPG-OPT"}.merge(extra), :options => "OPT"})) do |g|
|
127
|
+
stub(g).gpg_password_file(anything) {"pass-file"}
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should use '--passphrase-file' and :options" do
|
132
|
+
pgpg.send(:pipe).should == "|gpg GPG-OPT -c --passphrase-file pass-file"
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should use the 'command' options" do
|
136
|
+
pgpg(:command => 'other-gpg').send(:pipe).should == "|other-gpg GPG-OPT -c --passphrase-file pass-file"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe :gpg_password_file do
|
142
|
+
it "should create password file" do
|
143
|
+
file = gpg.send(:gpg_password_file, "foo")
|
144
|
+
File.exists?(file).should be_true
|
145
|
+
File.read(file).should == "foo"
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|