webbynode 0.1.2 → 0.2.0
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/Manifest +88 -4
- data/PostInstall.txt +42 -9
- data/README.rdoc +6 -0
- data/Rakefile +16 -19
- data/assets/webbynode.png +0 -0
- data/bin/webbynode +3 -3
- data/bin/wn +7 -0
- data/cucumber.yml +1 -0
- data/devver.rake +174 -0
- data/features/bootstrap.feature +17 -0
- data/features/step_definitions/command_steps.rb +14 -0
- data/features/support/env.rb +22 -0
- data/features/support/hooks.rb +8 -0
- data/{test/test_webbynode.rb → features/support/io_features.rb} +0 -0
- data/features/support/mocha.rb +15 -0
- data/lib/templates/api_token +14 -0
- data/lib/templates/backup +15 -0
- data/lib/templates/gitignore +4 -0
- data/lib/templates/help +53 -0
- data/lib/webbynode/api_client.rb +121 -0
- data/lib/webbynode/application.rb +21 -0
- data/lib/webbynode/command.rb +332 -0
- data/lib/webbynode/commands/add_backup.rb +33 -0
- data/lib/webbynode/commands/add_key.rb +24 -0
- data/lib/webbynode/commands/alias.rb +153 -0
- data/lib/webbynode/commands/change_dns.rb +29 -0
- data/lib/webbynode/commands/config.rb +15 -0
- data/lib/webbynode/commands/delete.rb +25 -0
- data/lib/webbynode/commands/help.rb +25 -0
- data/lib/webbynode/commands/init.rb +77 -0
- data/lib/webbynode/commands/push.rb +70 -0
- data/lib/webbynode/commands/remote.rb +28 -0
- data/lib/webbynode/commands/restart.rb +25 -0
- data/lib/webbynode/commands/start.rb +23 -0
- data/lib/webbynode/commands/stop.rb +23 -0
- data/lib/webbynode/commands/tasks.rb +149 -0
- data/lib/webbynode/commands/version.rb +8 -0
- data/lib/webbynode/commands/webbies.rb +30 -0
- data/lib/webbynode/git.rb +112 -0
- data/lib/webbynode/io.rb +175 -0
- data/lib/webbynode/notify.rb +19 -0
- data/lib/webbynode/option.rb +84 -0
- data/lib/webbynode/parameter.rb +27 -0
- data/lib/webbynode/properties.rb +43 -0
- data/lib/webbynode/push_and.rb +16 -0
- data/lib/webbynode/remote_executor.rb +21 -0
- data/lib/webbynode/server.rb +39 -0
- data/lib/webbynode/ssh.rb +65 -0
- data/lib/webbynode/ssh_keys.rb +36 -0
- data/lib/webbynode.rb +56 -0
- data/spec/fixtures/aliases +0 -0
- data/spec/fixtures/api/credentials +3 -0
- data/spec/fixtures/api/dns +30 -0
- data/spec/fixtures/api/dns_a_record +20 -0
- data/spec/fixtures/api/dns_a_record_already_exists +15 -0
- data/spec/fixtures/api/dns_a_record_error +13 -0
- data/spec/fixtures/api/dns_new_zone +17 -0
- data/spec/fixtures/api/webbies +26 -0
- data/spec/fixtures/api/webbies_unauthorized +12 -0
- data/spec/fixtures/api/webby +6 -0
- data/spec/fixtures/commands/tasks/after_push +3 -0
- data/spec/fixtures/fixture_helpers +2 -0
- data/spec/fixtures/git/config/210.11.13.12 +9 -0
- data/spec/fixtures/git/config/67.23.79.31 +9 -0
- data/spec/fixtures/git/config/67.23.79.32 +9 -0
- data/spec/fixtures/git/config/config +9 -0
- data/spec/fixtures/git/status/clean +2 -0
- data/spec/fixtures/git/status/dirty +9 -0
- data/spec/fixtures/pushand +2 -0
- data/spec/spec_helper.rb +58 -0
- data/spec/webbynode/api_client_spec.rb +227 -0
- data/spec/webbynode/application_spec.rb +50 -0
- data/spec/webbynode/command_spec.rb +285 -0
- data/spec/webbynode/commands/add_backup_spec.rb +66 -0
- data/spec/webbynode/commands/add_key_spec.rb +58 -0
- data/spec/webbynode/commands/alias_spec.rb +213 -0
- data/spec/webbynode/commands/change_dns_spec.rb +51 -0
- data/spec/webbynode/commands/config_spec.rb +22 -0
- data/spec/webbynode/commands/delete_spec.rb +78 -0
- data/spec/webbynode/commands/help_spec.rb +43 -0
- data/spec/webbynode/commands/init_spec.rb +326 -0
- data/spec/webbynode/commands/push_spec.rb +175 -0
- data/spec/webbynode/commands/remote_spec.rb +76 -0
- data/spec/webbynode/commands/tasks_spec.rb +288 -0
- data/spec/webbynode/commands/version_spec.rb +18 -0
- data/spec/webbynode/commands/webbies_spec.rb +27 -0
- data/spec/webbynode/git_spec.rb +310 -0
- data/spec/webbynode/io_spec.rb +198 -0
- data/spec/webbynode/option_spec.rb +48 -0
- data/spec/webbynode/parameter_spec.rb +70 -0
- data/spec/webbynode/push_and_spec.rb +28 -0
- data/spec/webbynode/remote_executor_spec.rb +25 -0
- data/spec/webbynode/server_spec.rb +101 -0
- data/webbynode.gemspec +25 -16
- metadata +182 -14
- data/lib/wn.rb +0 -106
- data/test/test_helper.rb +0 -9
- data/test/test_wn.rb +0 -220
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
# Load Spec Helper
|
|
2
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'spec_helper')
|
|
3
|
+
|
|
4
|
+
describe Webbynode::Git do
|
|
5
|
+
def should_raise_when_response(exception, command, response, &blk)
|
|
6
|
+
io_handler = mock("io")
|
|
7
|
+
io_handler.should_receive(:exec).with(command).and_return(response)
|
|
8
|
+
|
|
9
|
+
git = Webbynode::Git.new
|
|
10
|
+
git.should_receive(:io).and_return(io_handler)
|
|
11
|
+
lambda { yield git }.should raise_error(exception)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def should_raise(exception, command, &blk)
|
|
15
|
+
should_raise_when_response exception, command,
|
|
16
|
+
"fatal: remote webbynode already exists.", &blk
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def should_raise_giterror(command, &blk)
|
|
20
|
+
should_raise_when_response Webbynode::GitError, command,
|
|
21
|
+
"/private/tmp/other/.git: Permission denied", &blk
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def should_raise_notgitrepo(command, &blk)
|
|
25
|
+
should_raise_when_response Webbynode::GitNotRepoError, command,
|
|
26
|
+
"fatal: Not a git repository (or any of the parent directories): .git", &blk
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "should have an io instance" do
|
|
30
|
+
Webbynode::Git.new.io.class.should == Webbynode::Io
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe "#present?" do
|
|
34
|
+
it "should be true if folder .git exists" do
|
|
35
|
+
io_handler = mock("io")
|
|
36
|
+
io_handler.should_receive(:directory?).with(".git").and_return(true)
|
|
37
|
+
|
|
38
|
+
git = Webbynode::Git.new
|
|
39
|
+
git.should_receive(:io).and_return(io_handler)
|
|
40
|
+
git.should be_present
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "should be false if folder .git doesn't exist" do
|
|
44
|
+
io_handler = mock("io")
|
|
45
|
+
io_handler.should_receive(:directory?).with(".git").and_return(false)
|
|
46
|
+
|
|
47
|
+
git = Webbynode::Git.new
|
|
48
|
+
git.should_receive(:io).and_return(io_handler)
|
|
49
|
+
git.should_not be_present
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
describe "#clean?" do
|
|
54
|
+
context "when git repo is clean" do
|
|
55
|
+
it "should return true" do
|
|
56
|
+
io_handler = mock("io")
|
|
57
|
+
io_handler.should_receive(:exec).with("git status").and_return(read_fixture('git/status/clean'))
|
|
58
|
+
|
|
59
|
+
git = Webbynode::Git.new
|
|
60
|
+
git.should_receive(:io).and_return(io_handler)
|
|
61
|
+
git.should be_clean
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context "when git repo is dirty" do
|
|
66
|
+
it "should return false" do
|
|
67
|
+
io_handler = mock("io")
|
|
68
|
+
io_handler.should_receive(:exec).with("git status").and_return(read_fixture('git/status/dirty'))
|
|
69
|
+
|
|
70
|
+
git = Webbynode::Git.new
|
|
71
|
+
git.should_receive(:io).and_return(io_handler)
|
|
72
|
+
git.should_not be_clean
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
describe "#add_git_init" do
|
|
78
|
+
context "when sucessful" do
|
|
79
|
+
it "should create .gitignore from the template" do
|
|
80
|
+
io = double("io")
|
|
81
|
+
io.should_receive(:create_from_template).with(".gitignore", "gitignore")
|
|
82
|
+
|
|
83
|
+
git = Webbynode::Git.new
|
|
84
|
+
git.stub(:io).and_return(io)
|
|
85
|
+
git.add_git_ignore
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
describe "#init" do
|
|
91
|
+
context "when successful" do
|
|
92
|
+
it "should return true" do
|
|
93
|
+
io_handler = mock("io")
|
|
94
|
+
io_handler.should_receive(:exec).with("git init").and_return("Initialized empty Git repository in /Users/fcoury/tmp/.git/")
|
|
95
|
+
|
|
96
|
+
git = Webbynode::Git.new
|
|
97
|
+
git.should_receive(:io).and_return(io_handler)
|
|
98
|
+
git.init.should be_true
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
context "when unsuccessfull" do
|
|
103
|
+
it "should raise exception if not a git repo" do
|
|
104
|
+
should_raise_notgitrepo("git init") { |git| git.init }
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "should raise a generic Git error if there's another error creating the repo" do
|
|
108
|
+
should_raise_giterror("git init") { |git| git.init }
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
describe "#add_remote" do
|
|
114
|
+
context "when successfull" do
|
|
115
|
+
it "should create a new remote" do
|
|
116
|
+
io_handler = mock("io")
|
|
117
|
+
io_handler.should_receive(:exec).with("git remote add webbynode git@1.2.3.4:the_repo").and_return("")
|
|
118
|
+
|
|
119
|
+
git = Webbynode::Git.new
|
|
120
|
+
git.should_receive(:io).and_return(io_handler)
|
|
121
|
+
git.add_remote("webbynode", "1.2.3.4", "the_repo").should be_true
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
context "when unsuccessfull" do
|
|
126
|
+
it "should raise exception if not a git repo" do
|
|
127
|
+
should_raise_notgitrepo("git remote add other git@5.6.7.8:a_repo") { |git| git.add_remote("other", "5.6.7.8", "a_repo") }
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it "should return raise exception if the remote already exists" do
|
|
131
|
+
should_raise(Webbynode::GitRemoteAlreadyExistsError, "git remote add other git@5.6.7.8:a_repo") { |git|
|
|
132
|
+
git.add_remote("other", "5.6.7.8", "a_repo")
|
|
133
|
+
}
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it "should raise a generic Git error when another error occurs" do
|
|
137
|
+
should_raise_giterror("git remote add other git@5.6.7.8:a_repo") { |git| git.add_remote("other", "5.6.7.8", "a_repo") }
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
describe "#add" do
|
|
143
|
+
context "when successfull" do
|
|
144
|
+
it "should add objects to git" do
|
|
145
|
+
io_handler = mock("io")
|
|
146
|
+
io_handler.should_receive(:exec).with('git add the_file')
|
|
147
|
+
|
|
148
|
+
git = Webbynode::Git.new
|
|
149
|
+
git.should_receive(:io).and_return(io_handler)
|
|
150
|
+
git.add("the_file")
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
it "should handle adding multiple files" do
|
|
154
|
+
io_handler = mock("io")
|
|
155
|
+
io_handler.should_receive(:exec).with('git add one_file/ other_file/')
|
|
156
|
+
|
|
157
|
+
git = Webbynode::Git.new
|
|
158
|
+
git.should_receive(:io).and_return(io_handler)
|
|
159
|
+
git.add("one_file/ other_file/")
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
context "when unsuccessfull" do
|
|
164
|
+
it "should raise exception if not a git repo" do
|
|
165
|
+
should_raise_notgitrepo("git add .") { |git| git.add(".") }
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
it "should raise a generic Git error when another error occurs" do
|
|
169
|
+
should_raise_giterror("git add something") { |git| git.add("something") }
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
describe "#commit" do
|
|
175
|
+
context "when successfull" do
|
|
176
|
+
it "should add objects to git" do
|
|
177
|
+
io_handler = mock("io")
|
|
178
|
+
io_handler.should_receive(:exec).with('git commit -m "Commit comment"').and_return("[master (root-commit) 8f590c7] Commit comment
|
|
179
|
+
43 files changed, 8445 insertions(+), 0 deletions(-)")
|
|
180
|
+
|
|
181
|
+
git = Webbynode::Git.new
|
|
182
|
+
git.should_receive(:io).and_return(io_handler)
|
|
183
|
+
git.commit("Commit comment")
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
it "should escape double quotes" do
|
|
187
|
+
io_handler = mock("io")
|
|
188
|
+
io_handler.should_receive(:exec).with('git commit -m "Commiting \"the comment\""').and_return("[master (root-commit) 8f590c7] Commiting \"the comment\"
|
|
189
|
+
43 files changed, 8445 insertions(+), 0 deletions(-)")
|
|
190
|
+
|
|
191
|
+
git = Webbynode::Git.new
|
|
192
|
+
git.should_receive(:io).and_return(io_handler)
|
|
193
|
+
git.commit('Commiting "the comment"')
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
context "when unsuccessfull" do
|
|
198
|
+
it "should raise exception if not a git repo" do
|
|
199
|
+
should_raise_giterror("git add .") { |git| git.add(".") }
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
describe "#remote_webbynode?" do
|
|
205
|
+
context "when successful" do
|
|
206
|
+
it "should check if webbynode has been initialized inside of an existing git repository" do
|
|
207
|
+
io_handler = mock("Io")
|
|
208
|
+
io_handler.as_null_object
|
|
209
|
+
|
|
210
|
+
git = Webbynode::Git.new
|
|
211
|
+
git.should_receive(:io).and_return(io_handler)
|
|
212
|
+
io_handler.should_receive(:exec).with('git remote').and_return('origin\nwebbynode')
|
|
213
|
+
git.remote_webbynode?.should be_true
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
context "when unsuccessful" do
|
|
218
|
+
it "should not contain remote webbynode" do
|
|
219
|
+
io_handler = mock("Io")
|
|
220
|
+
io_handler.as_null_object
|
|
221
|
+
|
|
222
|
+
git = Webbynode::Git.new
|
|
223
|
+
git.should_receive(:io).and_return(io_handler)
|
|
224
|
+
io_handler.should_receive(:exec).with('git remote').and_return('origin')
|
|
225
|
+
git.remote_webbynode?.should be_false
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
describe "#parse_config" do
|
|
231
|
+
context "when successful" do
|
|
232
|
+
it "git should be present" do
|
|
233
|
+
io_handler = mock("Io")
|
|
234
|
+
io_handler.as_null_object
|
|
235
|
+
|
|
236
|
+
git = Webbynode::Git.new
|
|
237
|
+
git.should_receive(:io).any_number_of_times.and_return(io_handler)
|
|
238
|
+
git.stub!(:remote_webbynode?).and_return(true)
|
|
239
|
+
git.should_receive(:present?).and_return(true)
|
|
240
|
+
File.should_receive(:open).exactly(:once).with(".git/config").and_return(read_fixture('git/config/config'))
|
|
241
|
+
git.parse_config
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
it "should open the git configuration file and parse it" do
|
|
245
|
+
io_handler = mock("io")
|
|
246
|
+
io_handler.as_null_object
|
|
247
|
+
|
|
248
|
+
File.should_receive(:open).exactly(:once).with(".git/config").and_return(read_fixture('git/config/config'))
|
|
249
|
+
git = Webbynode::Git.new
|
|
250
|
+
git.stub!(:remote_webbynode?).and_return(true)
|
|
251
|
+
git.should_receive(:io).any_number_of_times.and_return(io_handler)
|
|
252
|
+
git.parse_config
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
it "should open the git configuration file and parse it only once" do
|
|
256
|
+
io_handler = mock("io")
|
|
257
|
+
io_handler.as_null_object
|
|
258
|
+
|
|
259
|
+
File.should_receive(:open).exactly(:once).with(".git/config").and_return(read_fixture('git/config/config'))
|
|
260
|
+
git = Webbynode::Git.new
|
|
261
|
+
git.stub!(:remote_webbynode?).and_return(true)
|
|
262
|
+
git.should_receive(:io).any_number_of_times.and_return(io_handler)
|
|
263
|
+
5.times {git.parse_config}
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
context "when unsuccessful" do
|
|
268
|
+
it "should raise an exception if the git repository does not exist." do
|
|
269
|
+
git = Webbynode::Git.new
|
|
270
|
+
git.should_receive(:present?).at_least(:once).and_return(false)
|
|
271
|
+
git.stub!(:remote_webbynode?).and_return(true)
|
|
272
|
+
File.should_not_receive(:open)
|
|
273
|
+
lambda {git.parse_config}.should raise_error(Webbynode::GitNotRepoError, "Git repository does not exist.")
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
it "should raise an exception if the git repository does exist, but does not have the git remote for webbynode" do
|
|
277
|
+
git = Webbynode::Git.new
|
|
278
|
+
git.should_receive(:present?).at_least(:once).and_return(true)
|
|
279
|
+
git.stub!(:remote_webbynode?).and_return(false)
|
|
280
|
+
File.should_not_receive(:open)
|
|
281
|
+
lambda {git.parse_config}.should raise_error(Webbynode::GitRemoteDoesNotExistError, "Webbynode has not been initialized.")
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
describe "#parse_remote_ip" do
|
|
288
|
+
context "when successful" do
|
|
289
|
+
it "should parse the configuration file" do
|
|
290
|
+
git = Webbynode::Git.new
|
|
291
|
+
git.should_receive(:parse_config)
|
|
292
|
+
git.parse_remote_ip
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
it "should extract the remote ip from the parsed configuration file" do
|
|
296
|
+
io_handler = mock("io")
|
|
297
|
+
io_handler.as_null_object
|
|
298
|
+
|
|
299
|
+
git = Webbynode::Git.new
|
|
300
|
+
git.stub!(:remote_webbynode?).and_return(true)
|
|
301
|
+
git.should_receive(:io).and_return(io_handler)
|
|
302
|
+
File.should_receive(:open).exactly(:once).with(".git/config").and_return(read_fixture('git/config/config'))
|
|
303
|
+
git.parse_remote_ip
|
|
304
|
+
git.config.should_not be_empty
|
|
305
|
+
git.remote_ip.should eql('1.2.3.4')
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
end
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# Load Spec Helper
|
|
2
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'spec_helper')
|
|
3
|
+
|
|
4
|
+
describe Webbynode::Io do
|
|
5
|
+
describe "#app_name" do
|
|
6
|
+
context "when successful" do
|
|
7
|
+
it "should return the current folder" do
|
|
8
|
+
Dir.should_receive(:pwd).and_return("/some/deep/folder/where/you/find/app_name")
|
|
9
|
+
Webbynode::Io.new.app_name.should == "app_name"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "should transform dots and spaces into underscores" do
|
|
13
|
+
Dir.should_receive(:pwd).and_return("/some/deep/folder/where/you/find/my.app here")
|
|
14
|
+
Webbynode::Io.new.app_name.should == "my_app_here"
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe '#add_setting' do
|
|
20
|
+
let(:io) { Webbynode::Io.new }
|
|
21
|
+
|
|
22
|
+
it "should add a key to the property file .webbynode/settings" do
|
|
23
|
+
props = mock("Hash")
|
|
24
|
+
props.should_receive(:[]=).with("engine", "php")
|
|
25
|
+
props.should_receive(:save)
|
|
26
|
+
|
|
27
|
+
io.should_receive(:properties).with(".webbynode/settings").and_return(props)
|
|
28
|
+
io.add_setting("engine", "php")
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe '#remove_setting' do
|
|
33
|
+
let(:io) { Webbynode::Io.new }
|
|
34
|
+
|
|
35
|
+
it "should add a key to the property file .webbynode/settings" do
|
|
36
|
+
props = mock("Hash")
|
|
37
|
+
props.should_receive(:remove).with("engine")
|
|
38
|
+
props.should_receive(:save)
|
|
39
|
+
|
|
40
|
+
io.should_receive(:properties).with(".webbynode/settings").and_return(props)
|
|
41
|
+
io.remove_setting("engine")
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
describe '#create_local_key' do
|
|
46
|
+
describe "when key file missing" do
|
|
47
|
+
before(:each) do
|
|
48
|
+
File.should_receive(:exists?).with(Webbynode::Commands::AddKey::LocalSshKey).and_return(false)
|
|
49
|
+
@io = Webbynode::Io.new
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
context "with no passphrase" do
|
|
53
|
+
it "should create the key with an empty passphrase" do
|
|
54
|
+
@io.should_receive(:exec).with("ssh-keygen -t rsa -N \"\" -f #{Webbynode::Commands::AddKey::LocalSshKey}").and_return("")
|
|
55
|
+
@io.create_local_key
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
context "with a passphrase" do
|
|
60
|
+
it "should create the key with the provided passphrase" do
|
|
61
|
+
@io.should_receive(:exec).with("ssh-keygen -t rsa -N \"passphrase\" -f #{Webbynode::Commands::AddKey::LocalSshKey}").and_return("")
|
|
62
|
+
@io.create_local_key("passphrase")
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
describe "when key already exists" do
|
|
68
|
+
before(:each) do
|
|
69
|
+
File.should_receive(:exists?).with(Webbynode::Commands::AddKey::LocalSshKey).and_return(true)
|
|
70
|
+
@io = Webbynode::Io.new
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it "should just skip the creation" do
|
|
74
|
+
@io.should_receive(:exec).never
|
|
75
|
+
@io.create_local_key
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
describe '#file_exists?' do
|
|
81
|
+
before(:each) do; @io = Webbynode::Io.new; end
|
|
82
|
+
|
|
83
|
+
it "should return true if file exists" do
|
|
84
|
+
File.should_receive(:exists?).with("file").and_return(true)
|
|
85
|
+
@io.file_exists?("file").should be_true
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it "should return false if file doesn't exist" do
|
|
89
|
+
File.should_receive(:exists?).with("file").and_return(false)
|
|
90
|
+
@io.file_exists?("file").should be_false
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
describe '#templates_path' do
|
|
95
|
+
it "should return the contents of TemplatesPath" do
|
|
96
|
+
io = Webbynode::Io.new
|
|
97
|
+
io.templates_path.should == Webbynode::Io::TemplatesPath
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
describe '#create_from_template' do
|
|
102
|
+
it "should read the template and write a new file with its contents" do
|
|
103
|
+
io = Webbynode::Io.new
|
|
104
|
+
io.should_receive(:read_from_template).with("template_file").and_return("template_file_contents")
|
|
105
|
+
io.should_receive(:create_file).with("output_file", "template_file_contents")
|
|
106
|
+
io.create_from_template("output_file", "template_file")
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
describe '#read_from_template' do
|
|
111
|
+
it "should read a file from the templates path" do
|
|
112
|
+
io = Webbynode::Io.new
|
|
113
|
+
io.should_receive(:templates_path).and_return("/templates")
|
|
114
|
+
io.should_receive(:read_file).with("/templates/template_file").and_return("template_contents")
|
|
115
|
+
io.read_from_template("template_file").should == "template_contents"
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
describe '#create_file' do
|
|
120
|
+
it "should create a file with specified contents" do
|
|
121
|
+
file = double("File")
|
|
122
|
+
File.should_receive(:open).with("file_to_write", "w").and_yield(file)
|
|
123
|
+
file.should_receive(:write).with("file_contents")
|
|
124
|
+
|
|
125
|
+
io = Webbynode::Io.new
|
|
126
|
+
io.create_file("file_to_write", "file_contents")
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it "should accept an optional executable parameter" do
|
|
130
|
+
file = double("File")
|
|
131
|
+
File.should_receive(:open).with("file_to_write", "w").and_yield(file)
|
|
132
|
+
file.should_receive(:write).with("file_contents")
|
|
133
|
+
|
|
134
|
+
FileUtils.should_receive(:chmod).with(0755, "file_to_write")
|
|
135
|
+
|
|
136
|
+
io = Webbynode::Io.new
|
|
137
|
+
io.create_file("file_to_write", "file_contents", true)
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
describe "#exec" do
|
|
142
|
+
context "when successful" do
|
|
143
|
+
it "should execute the command and retrieve the output" do
|
|
144
|
+
io = Webbynode::Io.new
|
|
145
|
+
io.should_receive(:`).with("ls -la 2>&1").and_return("output for ls -la")
|
|
146
|
+
io.exec("ls -la").should == "output for ls -la"
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
describe "#read_file" do
|
|
152
|
+
context "when successful" do
|
|
153
|
+
it "should return file contents" do
|
|
154
|
+
io = Webbynode::Io.new
|
|
155
|
+
File.should_receive(:read).with("filename").and_return("file contents")
|
|
156
|
+
io.read_file("filename").should == "file contents"
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
describe "#directory?" do
|
|
162
|
+
context "when successful" do
|
|
163
|
+
it "should return true when item is a directory" do
|
|
164
|
+
File.should_receive(:directory?).with("dir").and_return(true)
|
|
165
|
+
|
|
166
|
+
io = Webbynode::Io.new
|
|
167
|
+
io.directory?("dir").should == true
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
it "should return false when item is not a directory" do
|
|
171
|
+
File.should_receive(:directory?).with("dir").and_return(false)
|
|
172
|
+
|
|
173
|
+
io = Webbynode::Io.new
|
|
174
|
+
io.directory?("dir").should == false
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
describe "#open_file" do
|
|
180
|
+
it "should open the file" do
|
|
181
|
+
io = Webbynode::Io.new
|
|
182
|
+
File.should_receive(:open).with("filename", anything).and_return("file contents")
|
|
183
|
+
io.open_file("filename", anything).should eql("file contents")
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
describe "#read_config" do
|
|
188
|
+
it "should parse value = key pairs" do
|
|
189
|
+
io = Webbynode::Io.new
|
|
190
|
+
io.should_receive(:read_file).with("config").and_return("a = b\nc = d\nother = rest")
|
|
191
|
+
|
|
192
|
+
cfg = io.read_config("config")
|
|
193
|
+
cfg[:a].should == "b"
|
|
194
|
+
cfg[:c].should == "d"
|
|
195
|
+
cfg[:other].should == "rest"
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Load Spec Helper
|
|
2
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'spec_helper')
|
|
3
|
+
|
|
4
|
+
describe Webbynode::Option do
|
|
5
|
+
it "should require the name" do
|
|
6
|
+
lambda { Webbynode::Option.new }.should raise_error
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "should parse the name" do
|
|
10
|
+
Webbynode::Option.new(:param1).name.should == :param1
|
|
11
|
+
Webbynode::Option.new(:param2).name.should == :param2
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "should parse the type, if given" do
|
|
15
|
+
Webbynode::Option.new(:param1, Integer).kind.should == Integer
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "should assume String for the type, if none given" do
|
|
19
|
+
Webbynode::Option.new(:param1).kind.should == String
|
|
20
|
+
Webbynode::Option.new(:param1, "My description").kind.should == String
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "should parse the description" do
|
|
24
|
+
Webbynode::Option.new(:param1, "My description").desc.should == "My description"
|
|
25
|
+
Webbynode::Option.new(:param1, String, "My description").desc.should == "My description"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "should parse the options" do
|
|
29
|
+
Webbynode::Option.new(:param1, "My description", :amazing => true).options[:amazing].should be_true
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe "#to_s" do
|
|
33
|
+
it "should parse use the name and the value option" do
|
|
34
|
+
Webbynode::Option.new(:param1, "My param", :take => :value).to_s.should == "--param1=value"
|
|
35
|
+
Webbynode::Option.new(:param1, "My param").to_s.should == "--param1"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
describe "validating" do
|
|
40
|
+
it "should validate against values if :in passed" do
|
|
41
|
+
opt = Webbynode::Option.new(:option1, "My option", :validate => { :in => ['a', 'b'] })
|
|
42
|
+
opt.value = 'c'
|
|
43
|
+
opt.should_not be_valid
|
|
44
|
+
opt.errors.should be_include("Invalid value 'c' for option 'option1'. It should be one of 'a' or 'b'.")
|
|
45
|
+
lambda { opt.validate! }.should raise_error(Webbynode::Command::InvalidCommand, "Invalid value 'c' for option 'option1'. It should be one of 'a' or 'b'.")
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Load Spec Helper
|
|
2
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'spec_helper')
|
|
3
|
+
|
|
4
|
+
describe Webbynode::Parameter do
|
|
5
|
+
it "should require the name" do
|
|
6
|
+
lambda { Webbynode::Parameter.new }.should raise_error
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "should allow setting a value" do
|
|
10
|
+
param = Webbynode::Parameter.new(:param1)
|
|
11
|
+
param.value = "hello"
|
|
12
|
+
param.value.should == "hello"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "should parse the name" do
|
|
16
|
+
Webbynode::Parameter.new(:param1).name.should == :param1
|
|
17
|
+
Webbynode::Parameter.new(:param2).name.should == :param2
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "should parse the type, if given" do
|
|
21
|
+
Webbynode::Parameter.new(:param1, Integer).kind.should == Integer
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "should assume String for the type, if none given" do
|
|
25
|
+
Webbynode::Parameter.new(:param1).kind.should == String
|
|
26
|
+
Webbynode::Parameter.new(:param1, "My description").kind.should == String
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "should parse the description" do
|
|
30
|
+
Webbynode::Parameter.new(:param1, "My description").desc.should == "My description"
|
|
31
|
+
Webbynode::Parameter.new(:param1, String, "My description", :required => true).desc.should == "My description"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "should parse the options" do
|
|
35
|
+
Webbynode::Parameter.new(:param1, "My description", :required => true).options[:required].should be_true
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "should be required by default" do
|
|
39
|
+
Webbynode::Parameter.new(:param1).should be_required
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe "#required?" do
|
|
43
|
+
it "should be true if no param's :required is given" do
|
|
44
|
+
Webbynode::Parameter.new(:param1, "My description").options[:required].should be_true
|
|
45
|
+
Webbynode::Parameter.new(:param1, "My description").should be_required
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "should be true if param's :required is true" do
|
|
49
|
+
Webbynode::Parameter.new(:param1, "My description", :required => true).options[:required].should be_true
|
|
50
|
+
Webbynode::Parameter.new(:param1, "My description", :required => true).should be_required
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it "should be false if param's :required is false" do
|
|
54
|
+
Webbynode::Parameter.new(:param1, "My description", :required => false).options[:required].should be_false
|
|
55
|
+
Webbynode::Parameter.new(:param1, "My description", :required => false).should_not be_required
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
describe "#to_s" do
|
|
60
|
+
it "should render as the parameter name if required" do
|
|
61
|
+
Webbynode::Parameter.new(:param1).to_s.should == "param1"
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "should render on square brackets if optional" do
|
|
65
|
+
par = Webbynode::Parameter.new(:param2, "some description", :required => false)
|
|
66
|
+
par.should_not be_required
|
|
67
|
+
par.to_s.should == "[param2]"
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Load Spec Helper
|
|
2
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'spec_helper')
|
|
3
|
+
|
|
4
|
+
describe Webbynode::PushAnd do
|
|
5
|
+
before(:each) do
|
|
6
|
+
@io = mock(:io)
|
|
7
|
+
@pushand = Webbynode::PushAnd.new
|
|
8
|
+
@pushand.should_receive(:io).any_number_of_times.and_return(@io)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "should have an Io instance" do
|
|
12
|
+
Webbynode::PushAnd.new.io.class.should == Webbynode::Io
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe "#present?" do
|
|
16
|
+
it "should return true when .pushand file is present" do
|
|
17
|
+
@io.should_receive(:file_exists?).with(".pushand").and_return(true)
|
|
18
|
+
@pushand.present?.should == true
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe "parse_remote_app_name" do
|
|
23
|
+
it "should parse the .pushand file for the app name" do
|
|
24
|
+
@io.should_receive(:read_file).with(".pushand").and_return("phd $0 app_name dnsentry")
|
|
25
|
+
@pushand.parse_remote_app_name.should == "app_name"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Load Spec Helper
|
|
2
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'spec_helper')
|
|
3
|
+
|
|
4
|
+
describe Webbynode::RemoteExecutor do
|
|
5
|
+
before(:each) do
|
|
6
|
+
@ssh = mock("ssh")
|
|
7
|
+
|
|
8
|
+
@re = Webbynode::RemoteExecutor.new("2.2.2.2")
|
|
9
|
+
@re.should_receive(:ssh).any_number_of_times.and_return(@ssh)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
describe "#exec" do
|
|
13
|
+
it "should execute the raw command on the server" do
|
|
14
|
+
@ssh.should_receive(:execute).with("the same string I pass", false)
|
|
15
|
+
@re.exec "the same string I pass"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe "#create_folder" do
|
|
20
|
+
it "should create the folder on the server" do
|
|
21
|
+
@ssh.should_receive(:execute).with("mkdir -p /var/new_folder")
|
|
22
|
+
@re.create_folder "/var/new_folder"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|