From 4fd1b45cff18b37630ebabe0bc0b2f4ea763954b Mon Sep 17 00:00:00 2001 From: Douglas Gibbons Date: Sun, 26 Mar 2017 22:50:25 -0700 Subject: [PATCH] Added some real tests --- test/wait-for-it.py | 160 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 151 insertions(+), 9 deletions(-) diff --git a/test/wait-for-it.py b/test/wait-for-it.py index a004b26..f4a6194 100644 --- a/test/wait-for-it.py +++ b/test/wait-for-it.py @@ -4,8 +4,18 @@ import shlex from subprocess import Popen, PIPE import os import sys +import socket +import re - +missing_args_text = "Error: you need to provide a host and port to test." +help_text = "Usage:" +dividing_line = '-'*71 # Output line of dashes +""" + TestWaitForIt tests the wait-for-it.sh shell script. + + The wait-for-it.sh script is assumed to be in the parent directory to the + test script. +""" class TestWaitForIt(unittest.TestCase): @@ -16,26 +26,158 @@ class TestWaitForIt(unittest.TestCase): out, err = proc.communicate() exitcode = proc.returncode return exitcode, out, err + + def open_local_port(self,host="localhost", port=8929, timeout=5): + s = socket.socket() + s.bind((host,port)) + s.listen(timeout) + return s + def check_args(self,args,stdout_regex,stderr_regex,exitcode): + command = self.wait_script+" "+args + actual_exitcode, out, err = self.execute(command) + + # Check stderr + msg = ("Failed check that STDERR:\n"+ + dividing_line + "\n"+err+"\n"+dividing_line+ + "\nmatches:\n"+ + dividing_line + "\n"+stderr_regex+"\n"+dividing_line) + self.assertIsNotNone(re.match(stderr_regex,err,re.DOTALL),msg) + + # Check STDOUT + msg = ("Failed check that STDOUT:\n"+ + dividing_line + "\n"+out+"\n"+dividing_line+ + "\nmatches:\n"+ + dividing_line + "\n"+stdout_regex+"\n"+dividing_line) + self.assertIsNotNone(re.match(stdout_regex,out,re.DOTALL),msg) + + # Check exit code + self.assertEqual(actual_exitcode,exitcode) + def setUp(self): script_path = os.path.dirname(sys.argv[0]) parent_path = os.path.abspath(os.path.join(script_path, os.pardir)) self.wait_script = os.path.join(parent_path,"wait-for-it.sh") - - def test_no_args_return_code(self): + + def test_no_args(self): + """ + Check that no aruments returns the missing args text and the correct + return code + """ + self.check_args( + "", + "^$", + missing_args_text, + 1 + ) # Return code should be 1 when called with no args exitcode, out, err = self.execute(self.wait_script) self.assertEqual(exitcode,1) def test_help(self): - # Execute with "--help" option and check output - exitcode, out, err = self.execute(self.wait_script+" --help") - # STDERR should begin with "Usage:" - self.assertTrue(err.startswith("Usage:")) - # exit code should be 1 - self.assertEqual(exitcode,1) + """ Check that help text is printed with --help argument """ + self.check_args( + "--help", + "", + help_text, + 1 + ) + def test_no_port(self): + """ Check with missing port argument """ + self.check_args( + "--host=localhost", + "", + missing_args_text, + 1 + ) + def test_no_host(self): + """ Check with missing hostname argument """ + self.check_args( + "--port=80", + "", + missing_args_text, + 1 + ) + def test_host_port(self): + """ Check that --host and --port args work correctly """ + soc = self.open_local_port(port=8929) + self.check_args( + "--host=localhost --port=8929 --timeout=1", + "", + "wait-for-it.sh: waiting 1 seconds for localhost:8929", + 0 + ) + soc.close() + + def test_combined_host_port(self): + """ + Tests that wait-for-it.sh returns correctly after establishing a + connectionm using combined host and ports + """ + soc = self.open_local_port(port=8929) + self.check_args( + "localhost:8929 --timeout=1", + "", + "wait-for-it.sh: waiting 1 seconds for localhost:8929", + 0 + ) + soc.close() + + def test_port_failure_with_timeout(self): + """ + Note exit status of 124 is exected, passed from the timeout command + """ + self.check_args( + "localhost:8929 --timeout=1", + "", + ".*wait-for-it.sh: timeout occurred after waiting 1 seconds for localhost:8929", + 124 + ) + + def test_command_execution(self): + """ + Checks that a command executes correctly after a port test passes + """ + soc = self.open_local_port(port=8929) + self.check_args( + "localhost:8929 -- echo \"CMD OUTPUT\"", + "CMD OUTPUT", + ".*wait-for-it.sh: localhost:8929 is available after 0 seconds", + 0 + ) + soc.close() + + + def test_failed_command_execution(self): + """ + Check command failure. The command in question outputs STDERR and an + exit code of 2 + """ + soc = self.open_local_port(port=8929) + self.check_args( + "localhost:8929 -- ls not_real_file", + "", + ".*ls: cannot access 'not_real_file': No such file or directory\n", + 2 + ) + soc.close() + + + def test_command_after_connection_failure(self): + """ + Test that a command still runs even if a connection times out + and that the return code is correct for the comand being run + """ + self.check_args( + "localhost:8929 --timeout=1 -- echo \"CMD OUTPUT\"", + "CMD OUTPUT", + ".*wait-for-it.sh: timeout occurred after waiting 1 seconds for localhost:8929", + 0 + ) + + if __name__ == '__main__': unittest.main()