2
# Programmer: Chris Bunch
3
# Test code for lib/common_functions.rb
4
# Still need to test the following functions:
9
# Decided not to test the following functions:
10
# - shell: Only does the backticks, so nothing to test.
11
# - run_remote_command / scp_file: We currently don't check the return value on the ssh command, so we don't know if the remote command succeeds or not.
12
# - encrypt_password: Params are always validated to be non-nil, so result is always a string and thus always encrypts fine.
13
# - get_appname_via_xml: The only file it opens is already checked for existence, so nothing to test.
16
require 'flexmock/test_unit'
20
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
21
require 'common_functions'
24
class CommonFunctionsTest < Test::Unit::TestCase
25
context "test wait until redirect" do
26
should "return nothing when url is redirecting correctly" do
27
output = flexmock(Net::HTTP)
28
response = { 'location' => "http://192.168.0.1:8080"}
30
output.should_receive(:get_response).and_return(response)
33
uri.should_receive(:parse).and_return("")
35
assert_equal CommonFunctions.wait_until_redirect("", ""), nil
38
should "throw an exception when connection is refused" do
39
stderr = flexmock(STDERR)
40
stderr.should_receive(:write).and_return("")
42
output = flexmock(Net::HTTP)
43
output.should_receive(:get_response).and_raise(Errno::ECONNREFUSED)
45
assert_raise(SystemExit) { CommonFunctions.wait_until_redirect("", "") }
49
context "test user has command" do
50
should "return true when the user has the command" do
51
lib = flexmock(CommonFunctions)
52
lib.should_receive(:shell).and_return("non-empty means they have it")
54
assert_equal true, CommonFunctions.user_has_cmd?("baz")
57
should "return false when the user doesn't have the command" do
58
lib = flexmock(CommonFunctions)
59
lib.should_receive(:shell).and_return("")
61
assert_equal false, CommonFunctions.user_has_cmd?("baz")
65
context "test find real ssh key" do
66
should "return a string with the key when a key works" do
68
file.should_receive(:expand_path).and_return("baz")
70
common = flexmock(CommonFunctions)
71
common.should_receive(:shell).and_return("0\n")
73
assert_equal "baz", CommonFunctions.find_real_ssh_key(["baz"], "host")
76
should "return nil when all keys fail to work" do
77
common = flexmock(CommonFunctions)
78
common.should_receive(:shell).and_return("255\n")
80
assert_nil CommonFunctions.find_real_ssh_key(["baz"], "host")
84
context "test out yaml related functions" do
85
should "throw an exception when the yaml file doesn't exist" do
86
stderr = flexmock(STDERR)
87
stderr.should_receive(:write).and_return("")
90
file.should_receive(:exists?).and_return(false)
92
assert_raise(SystemExit) { CommonFunctions.get_load_balancer_ip("") }
93
assert_raise(SystemExit) { CommonFunctions.get_load_balancer_id("") }
96
should "throw an exception when the yaml file is malformed" do
97
stderr = flexmock(STDERR)
98
stderr.should_receive(:write).and_return("")
100
file = flexmock(File)
101
file.should_receive(:exists?).and_return(true)
103
yaml = flexmock(YAML)
104
yaml.should_receive(:load_file).and_raise(ArgumentError)
106
assert_raise(SystemExit) { CommonFunctions.get_load_balancer_ip("") }
107
assert_raise(SystemExit) { CommonFunctions.get_load_balancer_id("") }
110
should "throw an exception when the yaml file doesn't have the right tag" do
111
stderr = flexmock(STDERR)
112
stderr.should_receive(:write).and_return("")
114
file = flexmock(File)
115
file.should_receive(:exists?).and_return(true)
117
yaml = flexmock(YAML)
118
yaml.should_receive(:load_file).and_return({})
120
assert_raise(SystemExit) { CommonFunctions.get_load_balancer_ip("") }
121
assert_raise(SystemExit) { CommonFunctions.get_load_balancer_id("") }
124
should "return the right value for the right tags when all is good" do
125
file = flexmock(File)
126
file.should_receive(:exists?).and_return(true)
128
yaml = flexmock(YAML)
129
yaml.should_receive(:load_file).and_return({ :load_balancer => "foo", :instance_id => "bar"})
131
assert_equal "foo", CommonFunctions.get_load_balancer_ip("foo")
132
assert_equal "bar", CommonFunctions.get_load_balancer_id("bar")
136
context "test get appname from tar" do
137
should "return appname, python when the app is a python app" do
138
common = flexmock(CommonFunctions)
139
common.should_receive(:get_app_info).and_return(["baz", "", "python"])
141
assert_equal ["baz", "", "python"], CommonFunctions.get_appname_from_tar("")
144
should "return appname, java when the app is a java app" do
145
common = flexmock(CommonFunctions)
147
common.should_receive(:get_app_info).times(2).and_return([nil, nil, nil], ["baz", "", "java"])
148
assert_equal ["baz", "", "java"], CommonFunctions.get_appname_from_tar("")
150
common.should_receive(:get_app_info).times(2).and_return(["", "", nil], ["baz", "", "java"])
151
assert_equal ["baz", "", "java"], CommonFunctions.get_appname_from_tar("")
153
common.should_receive(:get_app_info).times(2).and_return([nil, "", ""], ["baz", "", "java"])
154
assert_equal ["baz", "", "java"], CommonFunctions.get_appname_from_tar("")
157
should "return throw an exception when the app's language is unknown" do
158
stderr = flexmock(STDERR)
159
stderr.should_receive(:write).and_return("")
161
common = flexmock(CommonFunctions)
163
common.should_receive(:get_app_info).and_return([nil, nil, nil])
164
assert_raise(SystemExit) { CommonFunctions.get_appname_from_tar("") }
166
common.should_receive(:get_app_info).and_return(["", "", nil])
167
assert_raise(SystemExit) { CommonFunctions.get_appname_from_tar("") }
169
common.should_receive(:get_app_info).and_return([nil, "", ""])
170
assert_raise(SystemExit) { CommonFunctions.get_appname_from_tar("") }
174
context "test get appname from yaml" do
175
should "throw an exception on malformed yaml" do
176
stderr = flexmock(STDERR)
177
stderr.should_receive(:write).and_return("")
179
yaml = flexmock(YAML)
180
yaml.should_receive(:load_file).and_raise(ArgumentError)
182
assert_raise(SystemExit) { CommonFunctions.get_appname_via_yaml("", "") }
185
should "return the app's name on good yaml" do
186
yaml = flexmock(YAML)
187
yaml.should_receive(:load_file).and_return({ "application" => "baz" })
189
assert_equal "baz", CommonFunctions.get_appname_via_yaml("", "")
193
context "test is port open / closed" do
194
should "return immediately when the port is already open" do
195
common = flexmock(CommonFunctions)
196
common.should_receive(:is_port_open?).and_return(true)
198
assert_nil CommonFunctions.sleep_until_port_is_open("", "")
201
should "return immediately when the port is already closed" do
202
common = flexmock(CommonFunctions)
203
common.should_receive(:is_port_open?).and_return(false)
205
assert_nil CommonFunctions.sleep_until_port_is_closed("", "")
208
should "return when the port is eventually open" do
209
common = flexmock(CommonFunctions)
210
common.should_receive(:is_port_open?).times(3).and_return(false, false, true)
212
kernel = flexmock(Kernel)
213
kernel.should_receive(:sleep).and_return(1)
215
assert_nil CommonFunctions.sleep_until_port_is_open("", "")
218
should "return when the port is eventually closed" do
219
common = flexmock(CommonFunctions)
220
common.should_receive(:is_port_open?).times(3).and_return(true, true, false)
222
kernel = flexmock(Kernel)
223
kernel.should_receive(:sleep).and_return(1)
225
assert_nil CommonFunctions.sleep_until_port_is_closed("", "")
229
context "test convert FQDN -> IP" do
230
should "throw an exception when the FQDN can't be resolved" do
231
stderr = flexmock(STDERR)
232
stderr.should_receive(:write).and_return("")
234
common = flexmock(CommonFunctions)
235
common.should_receive(:shell).and_return("")
237
assert_raise(SystemExit) { CommonFunctions.convert_fqdn_to_ip("") }
240
should "return an IP when the FQDN can be resolved" do
241
common = flexmock(CommonFunctions)
242
common.should_receive(:shell).and_return("baz\nAddress: 192.168.1.1")
244
assert_equal "192.168.1.1", CommonFunctions.convert_fqdn_to_ip("baz")
248
context "test get app info" do
250
stderr = flexmock(STDERR)
251
stderr.should_receive(:write).and_return("")
253
PYTHON_CONFIG = "app.yaml"
254
JAVA_CONFIG = "war/WEB-INF/appengine-web.xml"
257
should "throw an exception if the tar file doesn't exist" do
258
file = flexmock(File)
259
file.should_receive(:exists?).and_return(false)
261
assert_raise(SystemExit) { CommonFunctions.get_app_info("", "") }
264
should "throw an exception if the tar file can't be copied to /tmp" do
265
file = flexmock(File)
266
file.should_receive(:exists?).and_return(true)
268
common = flexmock(CommonFunctions)
269
common.should_receive(:shell).and_return("1\n")
271
fileutils = flexmock(FileUtils)
272
fileutils.should_receive(:cp).and_raise(Errno::EACCES)
273
fileutils.should_receive(:mkdir_p).and_return("")
274
fileutils.should_receive(:rm_rf).and_return("")
276
assert_raise(SystemExit) { CommonFunctions.get_app_info("", "") }
279
should "throw an exception if the tar file can't be untar'ed to /tmp" do
280
file = flexmock(File)
281
file.should_receive(:exists?).and_return(true)
283
common = flexmock(CommonFunctions)
284
common.should_receive(:shell).once.and_return("1\n")
286
fileutils = flexmock(FileUtils)
287
fileutils.should_receive(:cp).and_return("")
288
fileutils.should_receive(:mkdir_p).and_return("")
289
fileutils.should_receive(:rm_rf).and_return("")
291
assert_raise(SystemExit) { CommonFunctions.get_app_info("", "") }
294
should "return nil, nil if no app.yaml / web.xml files are found" do
295
[JAVA_CONFIG,PYTHON_CONFIG].each do |config|
296
file = flexmock(File)
297
file.should_receive(:exists?).once.with("").and_return(true)
299
common = flexmock(CommonFunctions)
300
common.should_receive(:shell).and_return("0\n")
302
fileutils = flexmock(FileUtils)
303
fileutils.should_receive(:cp).and_return("")
304
fileutils.should_receive(:mkdir_p).and_return("")
305
fileutils.should_receive(:rm_rf).and_return("")
307
temp_directory = "TEMP_DIR"
308
flexmock(CommonFunctions).should_receive(:get_random_alphanumeric).once.and_return(temp_directory)
310
file.should_receive(:exists?).once.with("/tmp/#{temp_directory}/#{config}").and_return(false)
312
assert_equal [nil, nil, nil], CommonFunctions.get_app_info("", config)
316
should "throw an exception if the app name is not recognized" do
317
file = flexmock(File)
318
file.should_receive(:exists?).and_return(true)
320
common = flexmock(CommonFunctions)
321
common.should_receive(:shell).and_return("app.haml\n0\n")
323
fileutils = flexmock(FileUtils)
324
fileutils.should_receive(:cp).and_return("")
325
fileutils.should_receive(:mkdir_p).and_return("")
326
fileutils.should_receive(:rm_rf).and_return("")
328
assert_raise(SystemExit) { CommonFunctions.get_app_info("", "app.haml") }
331
should "throw an exception if there is no app name in app.yaml" do
332
file = flexmock(File)
333
file.should_receive(:exists?).and_return(true)
335
common = flexmock(CommonFunctions)
336
common.should_receive(:shell).and_return("#{PYTHON_CONFIG}\n0\n")
337
common.should_receive(:get_appname_via_yaml).and_return(nil)
339
fileutils = flexmock(FileUtils)
340
fileutils.should_receive(:cp).and_return("")
341
fileutils.should_receive(:mkdir_p).and_return("")
342
fileutils.should_receive(:rm_rf).and_return("")
344
assert_raise(SystemExit) { CommonFunctions.get_app_info("", PYTHON_CONFIG) }
347
should "throw an exception if there is no app name in appengine-web.yaml" do
348
file = flexmock(File)
349
file.should_receive(:exists?).and_return(true)
351
common = flexmock(CommonFunctions)
352
common.should_receive(:shell).and_return("#{JAVA_CONFIG}\n0\n")
353
common.should_receive(:get_appname_via_xml).and_return(nil)
355
fileutils = flexmock(FileUtils)
356
fileutils.should_receive(:cp).and_return("")
357
fileutils.should_receive(:mkdir_p).and_return("")
358
fileutils.should_receive(:rm_rf).and_return("")
360
assert_raise(SystemExit) { CommonFunctions.get_app_info("", JAVA_CONFIG) }
363
should "return python and the app's name when a python app is used" do
364
file = flexmock(File)
365
file.should_receive(:exists?).and_return(true)
366
file.should_receive(:size).and_return(1)
368
common = flexmock(CommonFunctions)
369
common.should_receive(:shell).and_return("#{PYTHON_CONFIG}\n0\n")
370
common.should_receive(:get_appname_via_yaml).and_return("baz")
372
fileutils = flexmock(FileUtils)
373
fileutils.should_receive(:cp).and_return("")
374
fileutils.should_receive(:mkdir_p).and_return("")
375
fileutils.should_receive(:rm_rf).and_return("")
377
assert_equal ["baz", "", "python"], CommonFunctions.get_app_info("", PYTHON_CONFIG)
380
should "return java and the app's name when a java app is used" do
381
file = flexmock(File)
382
file.should_receive(:exists?).and_return(true)
383
file.should_receive(:size).and_return(1)
385
common = flexmock(CommonFunctions)
386
common.should_receive(:shell).and_return("#{JAVA_CONFIG}\n0\n")
387
common.should_receive(:get_appname_via_xml).and_return("baz")
388
common.should_receive(:get_random_alphanumeric).and_return("rand")
390
fileutils = flexmock(FileUtils)
391
fileutils.should_receive(:cp).and_return("")
392
fileutils.should_receive(:mkdir_p).and_return("")
393
fileutils.should_receive(:rm_rf).and_return("")
395
assert_equal ["baz", "/tmp/rand/baz.tar.gz", "java"], CommonFunctions.get_app_info("", JAVA_CONFIG)
399
context "test out validate appname" do
400
should "throw an exception if the app has a name that isn't allowed" do
401
stderr = flexmock(STDERR)
402
stderr.should_receive(:write).and_return("")
404
assert_raise(SystemExit) { CommonFunctions.validate_appname("none") }
405
assert_raise(SystemExit) { CommonFunctions.validate_appname("load_balancer") }
408
should "throw an exception if the app has characters that aren't allowed" do
409
stderr = flexmock(STDERR)
410
stderr.should_receive(:write).and_return("")
412
assert_raise(SystemExit) { CommonFunctions.validate_appname("baz@$$!") }
413
assert_raise(SystemExit) { CommonFunctions.validate_appname("1212):") }
414
assert_raise(SystemExit) { CommonFunctions.validate_appname("53az ") }
417
should "return the app's name on success" do
418
["guestbook", "my-app", "app.me", "baz@goo"].each { |app|
419
assert_equal app, CommonFunctions.validate_appname(app)