commit 04afd3a2954946d54e12f1da090f368c09a2689f Author: Ximin Luo infinity0@gmx.com Date: Wed Oct 9 14:44:01 2013 +0100
use automake's python test runner --- facilitator/.gitignore | 6 +- facilitator/Makefile.am | 10 +- facilitator/configure.ac | 2 + facilitator/facilitator-test | 192 --------------------------------------- facilitator/facilitator-test.py | 192 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 203 insertions(+), 199 deletions(-)
diff --git a/facilitator/.gitignore b/facilitator/.gitignore index 7574515..9c6d1c7 100644 --- a/facilitator/.gitignore +++ b/facilitator/.gitignore @@ -22,6 +22,6 @@ /flashproxy-facilitator-*.tar.*
# files output by test-driver -/test-*.log -/*-test.log -/*-test.trs +test*.log +*test.log +*test.trs diff --git a/facilitator/Makefile.am b/facilitator/Makefile.am index 559f12c..348bfb0 100644 --- a/facilitator/Makefile.am +++ b/facilitator/Makefile.am @@ -23,7 +23,12 @@ dist_example_DATA = examples/fp-facilitator dist_appengine_DATA = appengine/app.yaml appengine/config.go appengine/fp-reg.go appengine/README appengineconf_DATA = appengine/config.go
-dist_TESTS = facilitator-test +TESTS = facilitator-test.py +# see http://www.gnu.org/software/automake/manual/html_node/Parallel-Test-Harness.... +TEST_EXTENSIONS = .py +PY_LOG_COMPILER = $(PYTHON) +AM_TESTS_ENVIRONMENT = PYTHONPATH='$(srcdir)'; export PYTHONPATH; +AM_PY_LOG_FLAGS =
# stuff built from AC_CONFIG_FILES # see http://www.gnu.org/software/automake/manual/html_node/Scripts.html @@ -31,9 +36,6 @@ CLEANFILES = $(initscript_SCRIPTS)
# our own targets
-check: - ./facilitator-test - # The {pre,post}-{install,remove} targets are just given as reference, and # ought to be separate scripts as part of your distro's installation process. # They are intentionally not linked to the install target since they require diff --git a/facilitator/configure.ac b/facilitator/configure.ac index a212332..3542238 100644 --- a/facilitator/configure.ac +++ b/facilitator/configure.ac @@ -11,6 +11,8 @@ AC_CONFIG_FILES([Makefile init.d/facilitator-reg-daemon])
AC_PROG_LN_S +AM_PATH_PYTHON + # check that we want to install initscripts. don't bother checking that they # are supported, since we might be doing a staged install on a different system. # disabled by default since it ignores ${prefix} so `make distcheck` would fail diff --git a/facilitator/facilitator-test b/facilitator/facilitator-test deleted file mode 100755 index 6dec76d..0000000 --- a/facilitator/facilitator-test +++ /dev/null @@ -1,192 +0,0 @@ -#!/usr/bin/env python - -import socket -import subprocess -import time -import unittest - -import fac - -FACILITATOR_HOST = "127.0.0.1" -FACILITATOR_PORT = 39002 -FACILITATOR_ADDR = (FACILITATOR_HOST, FACILITATOR_PORT) - -def gimme_socket(host, port): - addrinfo = socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM, socket.IPPROTO_TCP)[0] - s = socket.socket(addrinfo[0], addrinfo[1], addrinfo[2]) - s.settimeout(10.0) - s.connect(addrinfo[4]) - return s - -class FacilitatorTest(unittest.TestCase): - IPV4_CLIENT_ADDR = ("1.1.1.1", 9000) - IPV6_CLIENT_ADDR = ("[11::11]", 9000) - IPV4_PROXY_ADDR = ("2.2.2.2", 13000) - IPV6_PROXY_ADDR = ("[22::22]", 13000) - - def gimme_socket(self): - return gimme_socket(FACILITATOR_HOST, FACILITATOR_PORT) - - def setUp(self): - self.process = subprocess.Popen(["./facilitator", "-d", "-p", str(FACILITATOR_PORT), "-r", "0.0.1.0:1", "-l", "/dev/null"]) - time.sleep(0.1) - - def tearDown(self): - ret = self.process.poll() - if ret is not None: - raise Exception("facilitator subprocess exited unexpectedly with status %d" % ret) - self.process.terminate() - - def test_timeout(self): - """Test that the socket will not accept slow writes indefinitely. - Successive sends should not reset the timeout counter.""" - s = self.gimme_socket() - time.sleep(0.3) - s.send("w") - time.sleep(0.3) - s.send("w") - time.sleep(0.3) - s.send("w") - time.sleep(0.3) - s.send("w") - time.sleep(0.3) - self.assertRaises(socket.error, s.send, "w") - - def test_readline_limit(self): - """Test that reads won't buffer indefinitely.""" - s = self.gimme_socket() - buflen = 0 - try: - while buflen + 1024 < 200000: - s.send("X" * 1024) - buflen += 1024 - self.fail("should have raised a socket error") - except socket.error: - pass - - def test_af_v4_v4(self): - """Test that IPv4 proxies can get IPv4 clients.""" - fac.put_reg(FACILITATOR_ADDR, self.IPV4_CLIENT_ADDR) - fac.put_reg(FACILITATOR_ADDR, self.IPV6_CLIENT_ADDR) - reg = fac.get_reg(FACILITATOR_ADDR, self.IPV4_PROXY_ADDR) - self.assertEqual(reg["client"], fac.format_addr(self.IPV4_CLIENT_ADDR)) - - def test_af_v4_v6(self): - """Test that IPv4 proxies do not get IPv6 clients.""" - fac.put_reg(FACILITATOR_ADDR, self.IPV6_CLIENT_ADDR) - reg = fac.get_reg(FACILITATOR_ADDR, self.IPV4_PROXY_ADDR) - self.assertEqual(reg["client"], "") - - def test_af_v6_v4(self): - """Test that IPv6 proxies do not get IPv4 clients.""" - fac.put_reg(FACILITATOR_ADDR, self.IPV4_CLIENT_ADDR) - reg = fac.get_reg(FACILITATOR_ADDR, self.IPV6_PROXY_ADDR) - self.assertEqual(reg["client"], "") - - def test_af_v6_v6(self): - """Test that IPv6 proxies can get IPv6 clients.""" - fac.put_reg(FACILITATOR_ADDR, self.IPV4_CLIENT_ADDR) - fac.put_reg(FACILITATOR_ADDR, self.IPV6_CLIENT_ADDR) - reg = fac.get_reg(FACILITATOR_ADDR, self.IPV6_PROXY_ADDR) - self.assertEqual(reg["client"], fac.format_addr(self.IPV6_CLIENT_ADDR)) - - def test_check_back_in(self): - """Test that facilitator responses contain a CHECK-BACK-IN key with a - numeric value.""" - reg = fac.get_reg(FACILITATOR_ADDR, self.IPV6_PROXY_ADDR) - self.assertGreater(int(reg["check-back-in"]), 0) - -# def test_same_proxy(self): -# """Test that the same proxy doesn't get the same client when asking -# twice.""" -# self.fail() -# -# def test_num_clients(self): -# """Test that the same proxy can pick up up to five different clients but -# no more. Test that a proxy ceasing to handle a client allows the proxy -# to handle another, different client.""" -# self.fail() -# -# def test_num_proxies(self): -# """Test that a single client is handed out to five different proxies but -# no more. Test that a proxy ceasing to handle a client reduces its count -# so another proxy can handle it.""" -# self.fail() -# -# def test_proxy_timeout(self): -# """Test that a proxy ceasing to connect for some time period causes that -# proxy's clients to be unhandled by that proxy.""" -# self.fail() -# -# def test_localhost_only(self): -# """Test that the facilitator doesn't listen on any external -# addresses.""" -# self.fail() -# -# def test_hostname(self): -# """Test that the facilitator rejects hostnames.""" -# self.fail() - -class ParseAddrSpecTest(unittest.TestCase): - def test_ipv4(self): - self.assertEqual(fac.parse_addr_spec("192.168.0.1:9999"), ("192.168.0.1", 9999)) - - def test_ipv6(self): - self.assertEqual(fac.parse_addr_spec("[12::34]:9999"), ("12::34", 9999)) - - def test_defhost_defport_ipv4(self): - self.assertEqual(fac.parse_addr_spec("192.168.0.2:8888", defhost="192.168.0.1", defport=9999), ("192.168.0.2", 8888)) - self.assertEqual(fac.parse_addr_spec("192.168.0.2:", defhost="192.168.0.1", defport=9999), ("192.168.0.2", 9999)) - self.assertEqual(fac.parse_addr_spec("192.168.0.2", defhost="192.168.0.1", defport=9999), ("192.168.0.2", 9999)) - self.assertEqual(fac.parse_addr_spec(":8888", defhost="192.168.0.1", defport=9999), ("192.168.0.1", 8888)) - self.assertEqual(fac.parse_addr_spec(":", defhost="192.168.0.1", defport=9999), ("192.168.0.1", 9999)) - self.assertEqual(fac.parse_addr_spec("", defhost="192.168.0.1", defport=9999), ("192.168.0.1", 9999)) - - def test_defhost_defport_ipv6(self): - self.assertEqual(fac.parse_addr_spec("[1234::2]:8888", defhost="1234::1", defport=9999), ("1234::2", 8888)) - self.assertEqual(fac.parse_addr_spec("[1234::2]:", defhost="1234::1", defport=9999), ("1234::2", 9999)) - self.assertEqual(fac.parse_addr_spec("[1234::2]", defhost="1234::1", defport=9999), ("1234::2", 9999)) - self.assertEqual(fac.parse_addr_spec(":8888", defhost="1234::1", defport=9999), ("1234::1", 8888)) - self.assertEqual(fac.parse_addr_spec(":", defhost="1234::1", defport=9999), ("1234::1", 9999)) - self.assertEqual(fac.parse_addr_spec("", defhost="1234::1", defport=9999), ("1234::1", 9999)) - - def test_noresolve(self): - """Test that parse_addr_spec does not do DNS resolution by default.""" - self.assertRaises(ValueError, fac.parse_addr_spec, "example.com") - -class ParseTransactionTest(unittest.TestCase): - def test_empty_string(self): - self.assertRaises(ValueError, fac.parse_transaction, "") - - def test_correct(self): - self.assertEqual(fac.parse_transaction("COMMAND"), ("COMMAND", ())) - self.assertEqual(fac.parse_transaction("COMMAND X="""), ("COMMAND", (("X", ""),))) - self.assertEqual(fac.parse_transaction("COMMAND X="ABC""), ("COMMAND", (("X", "ABC"),))) - self.assertEqual(fac.parse_transaction("COMMAND X="\A\B\C""), ("COMMAND", (("X", "ABC"),))) - self.assertEqual(fac.parse_transaction("COMMAND X="\\\"""), ("COMMAND", (("X", "\""),))) - self.assertEqual(fac.parse_transaction("COMMAND X="ABC" Y="DEF""), ("COMMAND", (("X", "ABC"), ("Y", "DEF")))) - self.assertEqual(fac.parse_transaction("COMMAND KEY-NAME="ABC""), ("COMMAND", (("KEY-NAME", "ABC"),))) - self.assertEqual(fac.parse_transaction("COMMAND KEY_NAME="ABC""), ("COMMAND", (("KEY_NAME", "ABC"),))) - - def test_missing_command(self): - self.assertRaises(ValueError, fac.parse_transaction, "X="ABC"") - self.assertRaises(ValueError, fac.parse_transaction, " X="ABC"") - - def test_missing_space(self): - self.assertRaises(ValueError, fac.parse_transaction, "COMMAND/X="ABC"") - self.assertRaises(ValueError, fac.parse_transaction, "COMMAND X="ABC"Y="DEF"") - - def test_bad_quotes(self): - self.assertRaises(ValueError, fac.parse_transaction, "COMMAND X="") - self.assertRaises(ValueError, fac.parse_transaction, "COMMAND X="ABC") - self.assertRaises(ValueError, fac.parse_transaction, "COMMAND X="ABC" Y="ABC") - self.assertRaises(ValueError, fac.parse_transaction, "COMMAND X="ABC\") - - def test_truncated(self): - self.assertRaises(ValueError, fac.parse_transaction, "COMMAND X=") - - def test_newline(self): - self.assertRaises(ValueError, fac.parse_transaction, "COMMAND X="ABC" \nY="DEF"") - -if __name__ == "__main__": - unittest.main() diff --git a/facilitator/facilitator-test.py b/facilitator/facilitator-test.py new file mode 100755 index 0000000..6dec76d --- /dev/null +++ b/facilitator/facilitator-test.py @@ -0,0 +1,192 @@ +#!/usr/bin/env python + +import socket +import subprocess +import time +import unittest + +import fac + +FACILITATOR_HOST = "127.0.0.1" +FACILITATOR_PORT = 39002 +FACILITATOR_ADDR = (FACILITATOR_HOST, FACILITATOR_PORT) + +def gimme_socket(host, port): + addrinfo = socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM, socket.IPPROTO_TCP)[0] + s = socket.socket(addrinfo[0], addrinfo[1], addrinfo[2]) + s.settimeout(10.0) + s.connect(addrinfo[4]) + return s + +class FacilitatorTest(unittest.TestCase): + IPV4_CLIENT_ADDR = ("1.1.1.1", 9000) + IPV6_CLIENT_ADDR = ("[11::11]", 9000) + IPV4_PROXY_ADDR = ("2.2.2.2", 13000) + IPV6_PROXY_ADDR = ("[22::22]", 13000) + + def gimme_socket(self): + return gimme_socket(FACILITATOR_HOST, FACILITATOR_PORT) + + def setUp(self): + self.process = subprocess.Popen(["./facilitator", "-d", "-p", str(FACILITATOR_PORT), "-r", "0.0.1.0:1", "-l", "/dev/null"]) + time.sleep(0.1) + + def tearDown(self): + ret = self.process.poll() + if ret is not None: + raise Exception("facilitator subprocess exited unexpectedly with status %d" % ret) + self.process.terminate() + + def test_timeout(self): + """Test that the socket will not accept slow writes indefinitely. + Successive sends should not reset the timeout counter.""" + s = self.gimme_socket() + time.sleep(0.3) + s.send("w") + time.sleep(0.3) + s.send("w") + time.sleep(0.3) + s.send("w") + time.sleep(0.3) + s.send("w") + time.sleep(0.3) + self.assertRaises(socket.error, s.send, "w") + + def test_readline_limit(self): + """Test that reads won't buffer indefinitely.""" + s = self.gimme_socket() + buflen = 0 + try: + while buflen + 1024 < 200000: + s.send("X" * 1024) + buflen += 1024 + self.fail("should have raised a socket error") + except socket.error: + pass + + def test_af_v4_v4(self): + """Test that IPv4 proxies can get IPv4 clients.""" + fac.put_reg(FACILITATOR_ADDR, self.IPV4_CLIENT_ADDR) + fac.put_reg(FACILITATOR_ADDR, self.IPV6_CLIENT_ADDR) + reg = fac.get_reg(FACILITATOR_ADDR, self.IPV4_PROXY_ADDR) + self.assertEqual(reg["client"], fac.format_addr(self.IPV4_CLIENT_ADDR)) + + def test_af_v4_v6(self): + """Test that IPv4 proxies do not get IPv6 clients.""" + fac.put_reg(FACILITATOR_ADDR, self.IPV6_CLIENT_ADDR) + reg = fac.get_reg(FACILITATOR_ADDR, self.IPV4_PROXY_ADDR) + self.assertEqual(reg["client"], "") + + def test_af_v6_v4(self): + """Test that IPv6 proxies do not get IPv4 clients.""" + fac.put_reg(FACILITATOR_ADDR, self.IPV4_CLIENT_ADDR) + reg = fac.get_reg(FACILITATOR_ADDR, self.IPV6_PROXY_ADDR) + self.assertEqual(reg["client"], "") + + def test_af_v6_v6(self): + """Test that IPv6 proxies can get IPv6 clients.""" + fac.put_reg(FACILITATOR_ADDR, self.IPV4_CLIENT_ADDR) + fac.put_reg(FACILITATOR_ADDR, self.IPV6_CLIENT_ADDR) + reg = fac.get_reg(FACILITATOR_ADDR, self.IPV6_PROXY_ADDR) + self.assertEqual(reg["client"], fac.format_addr(self.IPV6_CLIENT_ADDR)) + + def test_check_back_in(self): + """Test that facilitator responses contain a CHECK-BACK-IN key with a + numeric value.""" + reg = fac.get_reg(FACILITATOR_ADDR, self.IPV6_PROXY_ADDR) + self.assertGreater(int(reg["check-back-in"]), 0) + +# def test_same_proxy(self): +# """Test that the same proxy doesn't get the same client when asking +# twice.""" +# self.fail() +# +# def test_num_clients(self): +# """Test that the same proxy can pick up up to five different clients but +# no more. Test that a proxy ceasing to handle a client allows the proxy +# to handle another, different client.""" +# self.fail() +# +# def test_num_proxies(self): +# """Test that a single client is handed out to five different proxies but +# no more. Test that a proxy ceasing to handle a client reduces its count +# so another proxy can handle it.""" +# self.fail() +# +# def test_proxy_timeout(self): +# """Test that a proxy ceasing to connect for some time period causes that +# proxy's clients to be unhandled by that proxy.""" +# self.fail() +# +# def test_localhost_only(self): +# """Test that the facilitator doesn't listen on any external +# addresses.""" +# self.fail() +# +# def test_hostname(self): +# """Test that the facilitator rejects hostnames.""" +# self.fail() + +class ParseAddrSpecTest(unittest.TestCase): + def test_ipv4(self): + self.assertEqual(fac.parse_addr_spec("192.168.0.1:9999"), ("192.168.0.1", 9999)) + + def test_ipv6(self): + self.assertEqual(fac.parse_addr_spec("[12::34]:9999"), ("12::34", 9999)) + + def test_defhost_defport_ipv4(self): + self.assertEqual(fac.parse_addr_spec("192.168.0.2:8888", defhost="192.168.0.1", defport=9999), ("192.168.0.2", 8888)) + self.assertEqual(fac.parse_addr_spec("192.168.0.2:", defhost="192.168.0.1", defport=9999), ("192.168.0.2", 9999)) + self.assertEqual(fac.parse_addr_spec("192.168.0.2", defhost="192.168.0.1", defport=9999), ("192.168.0.2", 9999)) + self.assertEqual(fac.parse_addr_spec(":8888", defhost="192.168.0.1", defport=9999), ("192.168.0.1", 8888)) + self.assertEqual(fac.parse_addr_spec(":", defhost="192.168.0.1", defport=9999), ("192.168.0.1", 9999)) + self.assertEqual(fac.parse_addr_spec("", defhost="192.168.0.1", defport=9999), ("192.168.0.1", 9999)) + + def test_defhost_defport_ipv6(self): + self.assertEqual(fac.parse_addr_spec("[1234::2]:8888", defhost="1234::1", defport=9999), ("1234::2", 8888)) + self.assertEqual(fac.parse_addr_spec("[1234::2]:", defhost="1234::1", defport=9999), ("1234::2", 9999)) + self.assertEqual(fac.parse_addr_spec("[1234::2]", defhost="1234::1", defport=9999), ("1234::2", 9999)) + self.assertEqual(fac.parse_addr_spec(":8888", defhost="1234::1", defport=9999), ("1234::1", 8888)) + self.assertEqual(fac.parse_addr_spec(":", defhost="1234::1", defport=9999), ("1234::1", 9999)) + self.assertEqual(fac.parse_addr_spec("", defhost="1234::1", defport=9999), ("1234::1", 9999)) + + def test_noresolve(self): + """Test that parse_addr_spec does not do DNS resolution by default.""" + self.assertRaises(ValueError, fac.parse_addr_spec, "example.com") + +class ParseTransactionTest(unittest.TestCase): + def test_empty_string(self): + self.assertRaises(ValueError, fac.parse_transaction, "") + + def test_correct(self): + self.assertEqual(fac.parse_transaction("COMMAND"), ("COMMAND", ())) + self.assertEqual(fac.parse_transaction("COMMAND X="""), ("COMMAND", (("X", ""),))) + self.assertEqual(fac.parse_transaction("COMMAND X="ABC""), ("COMMAND", (("X", "ABC"),))) + self.assertEqual(fac.parse_transaction("COMMAND X="\A\B\C""), ("COMMAND", (("X", "ABC"),))) + self.assertEqual(fac.parse_transaction("COMMAND X="\\\"""), ("COMMAND", (("X", "\""),))) + self.assertEqual(fac.parse_transaction("COMMAND X="ABC" Y="DEF""), ("COMMAND", (("X", "ABC"), ("Y", "DEF")))) + self.assertEqual(fac.parse_transaction("COMMAND KEY-NAME="ABC""), ("COMMAND", (("KEY-NAME", "ABC"),))) + self.assertEqual(fac.parse_transaction("COMMAND KEY_NAME="ABC""), ("COMMAND", (("KEY_NAME", "ABC"),))) + + def test_missing_command(self): + self.assertRaises(ValueError, fac.parse_transaction, "X="ABC"") + self.assertRaises(ValueError, fac.parse_transaction, " X="ABC"") + + def test_missing_space(self): + self.assertRaises(ValueError, fac.parse_transaction, "COMMAND/X="ABC"") + self.assertRaises(ValueError, fac.parse_transaction, "COMMAND X="ABC"Y="DEF"") + + def test_bad_quotes(self): + self.assertRaises(ValueError, fac.parse_transaction, "COMMAND X="") + self.assertRaises(ValueError, fac.parse_transaction, "COMMAND X="ABC") + self.assertRaises(ValueError, fac.parse_transaction, "COMMAND X="ABC" Y="ABC") + self.assertRaises(ValueError, fac.parse_transaction, "COMMAND X="ABC\") + + def test_truncated(self): + self.assertRaises(ValueError, fac.parse_transaction, "COMMAND X=") + + def test_newline(self): + self.assertRaises(ValueError, fac.parse_transaction, "COMMAND X="ABC" \nY="DEF"") + +if __name__ == "__main__": + unittest.main()
tor-commits@lists.torproject.org