示例#1
0
 def test_call_valid_call(self):
     """Test a valid call, that should return."""
     # Bug the user if the server isn't running
     self.read_session_from_file()
     try:
         result = core.call(self.SERVER_NAME, "+", [1, 2, 3])
     except Exception as e:
         _raise_unexpected(e)
     eq_(result, 6)
示例#2
0
    def test_http_squatter(self):
        """Test what happens when the call contacts the wrong HTTP process.

        The cache may be out of date. Most of the time, it will point to a dead
        socket, which is easy to deal with. In rare cases, a different TCP
        process may have started on that socket.

        This test checks that the call can cope with a cache that points to a
        different HTTP server. A server like that will still respond to HTTP
        requests, so it needs to be handled differently to an arbitrary TCP
        process.

        """
        # Load the actual server's info
        session = self.read_session_from_file()
        # We ensure the session was loaded
        assert "port" in session, session
        # Cache it
        core._cache_session(self.SERVER_NAME, session)
        # Use a different port to the NC test, in case the NC process didn't end.
        two_ports_down = session["port"] - 2
        assert distutils.spawn.find_executable(
            "nc"), "Netcat is needed to test TCP clashes. Could not find `nc`."
        # Open a dummy netcat HTTP server on the next port down. It's possible
        # to get a port clash here - if we do, that's ok. It doesn't mean
        # `core.py` is broken, it just means we were unlucky. Re-run
        # the tests a few times until you hit a free pair.
        if sys.version_info >= (3, ):
            http_process = subprocess.Popen(
                ["python3", "-m", "http.server", "{}".format(two_ports_down)])
        else:
            http_process = subprocess.Popen([
                "python2", "-m", "SimpleHTTPServer",
                "{}".format(two_ports_down)
            ])
        # Give it a bit to start (HTTP servers are slow to start. This is an
        # unreliable heuristic - bump the number up if it's failing.)
        time.sleep(0.5)
        # Make sure it's running
        assert _check_ping(
            two_ports_down), "The HTTP server didn't seem to start."
        try:
            # Now modify the cache to point to the bad HTTP process. It should
            # connect, return an error, then retry successfully from disk.
            core._server_info_cache[self.SERVER_NAME]["port"] = two_ports_down
            result = core.call(self.SERVER_NAME, "+", [1, 2, 3])
        finally:
            # Clean up the nc process
            http_process.kill()
        eq_(result, 6)
示例#3
0
 def test_wrong_port_in_cache(self):
     """Test an out of date cache, in this case a wrong port."""
     # First, ensure the info is cached.
     session = self.read_session_from_file()
     # We ensure the session was loaded
     assert "port" in session, session
     core._cache_session(self.SERVER_NAME, session)
     # Now modify the cache to be wrong. It should fail to connect, then
     # reload from disk.
     core._server_info_cache[self.SERVER_NAME]["port"] -= 1
     try:
         result = core.call(self.SERVER_NAME, "+", [1, 2, 3])
     except Exception as e:
         _raise_unexpected(e)
     eq_(result, 6)
示例#4
0
    def test_wrong_username_in_cache(self):
        """Test an out of date cache, in this case a wrong username.

        This is designed to test out-of-date credentials in general. Porthole
        authorization itself is tested in the Elisp package.

        """
        # First, ensure the info is cached.
        session = core._session_from_file(self.SERVER_NAME)
        # We ensure the session was loaded
        assert "username" in session, session
        core._cache_session(self.SERVER_NAME, session)
        # Now modify the cache to be wrong. It should fail to connect, then
        # reload from disk.
        core._server_info_cache[self.SERVER_NAME]["username"] = "******"
        try:
            result = core.call(self.SERVER_NAME, "+", [1, 2, 3])
        except Exception as e:
            _raise_unexpected(e)
        eq_(result, 6)
示例#5
0
    def test_tcp_squatter(self):
        """Test what happens when the call contacts the wrong HTTP process.

        The cache may be out of date. Most of the time, it will point to a dead
        socket, which is easy to deal with. In rare cases, a different TCP
        process may have started on that socket.

        This test checks that the call can cope with a cache that points to a
        different TCP process. The new process may respond with mangled
        information, or it may time out. Either way, the session should be
        re-read from disk, at which point it should succeed.

        """
        # Load the actual server's info
        session = self.read_session_from_file()
        # We ensure the session was loaded
        assert "port" in session, session
        # Cache it
        core._cache_session(self.SERVER_NAME, session)
        one_port_down = session["port"] - 1
        assert distutils.spawn.find_executable(
            "nc"), "Netcat is needed to test TCP clashes. Could not find `nc`."
        # Open a dummy netcat TCP process on the next port down. It's possible
        # to get a port clash here - if we do, that's ok. It doesn't mean
        # `core.py` is broken, it just means we were unlucky. Re-run
        # the tests a few times until you hit a free pair.
        nc_process = subprocess.Popen(["nc", "-l", "{}".format(one_port_down)])
        # Give it a bit to start
        time.sleep(0.5)
        # Make sure it's running
        assert _check_ping(
            one_port_down), "The nc server didn't seem to start."
        try:
            # Now modify the cache to point to the NC process. It should
            # connect, then fail, then retry successfully from disk.
            core._server_info_cache[self.SERVER_NAME]["port"] = one_port_down
            result = core.call(self.SERVER_NAME, "+", [1, 2, 3])
        finally:
            # Clean up the nc process
            nc_process.kill()
        eq_(result, 6)
示例#6
0
    def test_call_hidden_function(self):
        """Test that `call` correctly receives JSON-RPC error responses.

        Other JSON-RPC errors won't be prompted. This is fine.

        """
        # Bug the user if the server isn't running
        self.read_session_from_file()
        try:
            # Do this call twice. First, check the exception, then check the
            # response structure.
            assert_raises(
                core.json_rpc.MethodNotExposedError,
                core.call,
                self.SERVER_NAME,
                "insert",
                ["this is some text"],
            )
            result = core.call(self.SERVER_NAME, "insert",
                               ["this is some text"])
            raise ValueError("Should never get here. Result: {}").format(
                result)
        except json_rpc.MethodNotExposedError as e:
            json_response = e.raw_response
            assert isinstance(json_response, dict), json_response
            assert "jsonrpc" in json_response, json_response
            assert json_response["jsonrpc"] == "2.0", json_response
            assert "error" in json_response, json_response
            assert json_response["error"] == e.error, e
            error = e.error
            assert isinstance(error, dict), json_response
            assert "data" in error, json_response
            assert "code" in error, json_response
            assert error["code"], json_response
        except Exception as e:
            _raise_unexpected(e)