import unittest
try:
    from unittest import mock
except ImportError:
    import mock
patch = mock.patch
sentinel = mock.sentinel

from ssh_forward_proxy import run_server

class RunServerTest(unittest.TestCase):

    class Error(Exception):
        pass

    def setUp(self):
        self.sys_exit_patch = patch('sys.exit')
        self.sys_exit_patch.start()
    def tearDown(self):
        self.sys_exit_patch.stop()

    @patch('socket.socket.bind')
    def test_bind(self, bind):
        """
        the server should bind to the correct host and port
        """

        # raise an error to stop the server going into the accept loop
        with patch('socket.socket.accept', side_effect=self.Error() ):
            try:
                run_server('host', 1234)
            except self.Error:
                pass
            bind.assert_called_once_with(('host', 1234))

    @patch('socket.socket.bind')
    @patch('socket.socket.accept', return_value=(sentinel.socket, sentinel.address))
    @patch('threading.Thread')
    def test_pserve_thread(self, Thread, accept, bind):
        """
        the server should start a thread for the proxy on accept()
        """

        # raise an error to stop the server going into the accept loop
        thread = Thread.return_value
        thread.start = mock.Mock(side_effect=self.Error() )

        try:
            run_server('host', 1234, key='value', worker=sentinel.worker)
        except self.Error:
            pass
        Thread.assert_called_once_with(target=sentinel.worker, args=(sentinel.socket,), kwargs={'key': 'value'})
        thread.start.assert_called_once_with()

@@ -125,16 +125,41 @@
 ntinel%0A%0A
+import os%0Aimport signal%0A%0A
 from ssh
@@ -279,173 +279,8 @@
 ss%0A%0A
-    def setUp(self):%0A        self.sys_exit_patch = patch('sys.exit')%0A        self.sys_exit_patch.start()%0A    def tearDown(self):%0A        self.sys_exit_patch.stop()%0A%0A
     
@@ -560,19 +560,16 @@
 lf.Error
-() 
 ):%0A     
@@ -897,14 +897,14 @@
 est_
-p
 serve
+r
 _thr
@@ -1195,11 +1195,8 @@
 rror
-() 
 )%0A%0A 
@@ -1438,16 +1438,16 @@
 alue'%7D)%0A
-
         
@@ -1485,8 +1485,941 @@
 _with()%0A
+%0A    @patch('socket.socket.close')%0A    @patch('socket.socket.bind')%0A    def test_keyboard_interrupt(self, bind, close):%0A        %22%22%22%0A        the server should start a thread for the proxy on accept()%0A        %22%22%22%0A%0A        with patch('socket.socket.accept', side_effect=self.send_sig_int):%0A            run_server('host', 1234, key='value', worker=sentinel.worker)%0A            close.assert_called_once_with()%0A%0A    def send_sig_int(self):%0A        pid = os.getpid()%0A        os.kill(pid, signal.SIGINT)%0A%0A    @patch('socket.socket.close')%0A    @patch('socket.socket.bind')%0A    def test_error(self, bind, close):%0A        %22%22%22%0A        the server should start a thread for the proxy on accept()%0A        %22%22%22%0A%0A        with patch('socket.socket.accept', side_effect=self.Error):%0A            with self.assertRaises(self.Error):%0A                run_server('host', 1234, key='value', worker=sentinel.worker)%0A            close.assert_called_once_with()%0A

test that run_server closes socket on errors