Example #1
0
async def test_metadata(ManagedServerLoop) -> None:
    application = Application(metadata=dict(hi="hi", there="there"))
    with ManagedServerLoop(application) as server:
        meta_url = url(server) + 'metadata'
        meta_resp = await http_get(server.io_loop, meta_url)
        meta_json = json.loads(meta_resp.buffer.read().decode())
        assert meta_json == {
            'data': {
                'hi': 'hi',
                'there': 'there'
            },
            'url': '/'
        }

    def meta_func():
        return dict(name='myname', value='no value')

    application1 = Application(metadata=meta_func)

    with ManagedServerLoop(application1) as server:
        meta_url = url(server) + 'metadata'
        meta_resp = await http_get(server.io_loop, meta_url)
        meta_json = json.loads(meta_resp.buffer.read().decode())
        assert meta_json == {
            'data': {
                'name': 'myname',
                'value': 'no value'
            },
            'url': '/'
        }
async def test_server_applications_callable_arg(ManagedServerLoop) -> None:
    def modify_doc(doc):
        doc.title = "Hello, world!"

    with ManagedServerLoop(modify_doc, port=0) as server:
        await http_get(server.io_loop, url(server))
        session = server.get_sessions('/')[0]
        assert session.document.title == "Hello, world!"

    with ManagedServerLoop({"/foo": modify_doc}, port=0) as server:
        await http_get(server.io_loop, url(server) + "foo")
        session = server.get_sessions('/foo')[0]
        assert session.document.title == "Hello, world!"
Example #3
0
def test_log_stats(ManagedServerLoop) -> None:
    application = Application()
    with ManagedServerLoop(application) as server:
        server._tornado._log_stats()
        session1 = pull_session(session_id='session1',
                                url=url(server),
                                io_loop=server.io_loop)
        session2 = pull_session(session_id='session2',
                                url=url(server),
                                io_loop=server.io_loop)
        server._tornado._log_stats()
        session1.close()
        session2.close()
        server._tornado._log_stats()
Example #4
0
async def test_get_sessions(ManagedServerLoop) -> None:
    application = Application()
    with ManagedServerLoop(application) as server:
        server_sessions = server.get_sessions('/')
        assert len(server_sessions) == 0

        await http_get(server.io_loop, url(server))
        server_sessions = server.get_sessions('/')
        assert len(server_sessions) == 1

        await http_get(server.io_loop, url(server))
        server_sessions = server.get_sessions('/')
        assert len(server_sessions) == 2

        server_sessions = server.get_sessions()
        assert len(server_sessions) == 2

        with pytest.raises(ValueError):
            server.get_sessions("/foo")

    with ManagedServerLoop({
            "/foo": application,
            "/bar": application
    }) as server:
        await http_get(server.io_loop, url(server) + "foo")
        server_sessions = server.get_sessions('/foo')
        assert len(server_sessions) == 1
        server_sessions = server.get_sessions('/bar')
        assert len(server_sessions) == 0
        server_sessions = server.get_sessions()
        assert len(server_sessions) == 1

        await http_get(server.io_loop, url(server) + "foo")
        server_sessions = server.get_sessions('/foo')
        assert len(server_sessions) == 2
        server_sessions = server.get_sessions('/bar')
        assert len(server_sessions) == 0
        server_sessions = server.get_sessions()
        assert len(server_sessions) == 2

        await http_get(server.io_loop, url(server) + "bar")
        server_sessions = server.get_sessions('/foo')
        assert len(server_sessions) == 2
        server_sessions = server.get_sessions('/bar')
        assert len(server_sessions) == 1
        server_sessions = server.get_sessions()
        assert len(server_sessions) == 3
async def test__include_headers(ManagedServerLoop) -> None:
    application = Application()
    with ManagedServerLoop(application, include_headers=['Custom']) as server:
        sessions = server.get_sessions('/')
        assert 0 == len(sessions)

        response = await http_get(server.io_loop, url(server), headers={'Custom': 'Test'})
        html = response.body
        token = extract_token_from_json(html)
        payload = get_token_payload(token)
        assert 'headers' in payload
        assert payload['headers'] == {'Custom': 'Test'}
async def test__exclude_cookies(ManagedServerLoop) -> None:
    application = Application()
    with ManagedServerLoop(application, exclude_cookies=['custom']) as server:
        sessions = server.get_sessions('/')
        assert 0 == len(sessions)

        response = await http_get(server.io_loop, url(server), headers={'Cookie': 'custom = test ; custom2 = test2'})
        html = response.body
        token = extract_token_from_json(html)
        payload = get_token_payload(token)
        assert 'cookies' in payload
        assert payload['cookies'] == {'custom2': 'test2'}
Example #7
0
async def test__request_in_session_context(ManagedServerLoop) -> None:
    application = Application()
    with ManagedServerLoop(application) as server:
        response = await http_get(server.io_loop, url(server) + "?foo=10")
        html = response.body
        sessionid = extract_sessionid_from_json(html)

        server_session = server.get_session('/', sessionid)
        server_doc = server_session.document
        session_context = server_doc.session_context
        # do we have a request
        assert session_context.request is not None
Example #8
0
async def test__request_in_session_context_has_arguments(ManagedServerLoop):
    application = Application()
    with ManagedServerLoop(application) as server:
        response = await http_get(server.io_loop, url(server) + "?foo=10")
        html = response.body
        sessionid = extract_sessionid_from_json(html)

        server_session = server.get_session('/', sessionid)
        server_doc = server_session.document
        session_context = server_doc.session_context
        # test if we can get the argument from the request
        assert session_context.request.arguments['foo'] == [b'10']
async def test__no_generate_session_doc(ManagedServerLoop) -> None:
    application = Application()
    with ManagedServerLoop(application, generate_session_ids=False) as server:
        sessions = server.get_sessions('/')
        assert 0 == len(sessions)

        with (pytest.raises(HTTPError)) as info:
            await http_get(server.io_loop, url(server))
        assert 'No bokeh-session-id provided' in repr(info.value)

        sessions = server.get_sessions('/')
        assert 0 == len(sessions)
async def test__exclude_headers(ManagedServerLoop) -> None:
    application = Application()
    with ManagedServerLoop(application, exclude_headers=['Connection', 'Host']) as server:
        sessions = server.get_sessions('/')
        assert 0 == len(sessions)

        response = await http_get(server.io_loop, url(server))
        html = response.body
        token = extract_token_from_json(html)
        payload = get_token_payload(token)
        assert 'headers' in payload
        assert payload["headers"].get("Accept-Encoding") == "gzip"
async def test__reject_no_token_websocket(ManagedServerLoop) -> None:
    application = Application()
    with ManagedServerLoop(application) as server:
        sessions = server.get_sessions('/')
        assert 0 == len(sessions)

        await http_get(server.io_loop, url(server))

        sessions = server.get_sessions('/')
        assert 1 == len(sessions)

        ws = await websocket_open(server.io_loop, ws_url(server), subprotocols=["foo"])
        assert await ws.read_queue.get() is None
Example #12
0
async def test__autocreate_session_doc(ManagedServerLoop) -> None:
    application = Application()
    with ManagedServerLoop(application) as server:
        sessions = server.get_sessions('/')
        assert 0 == len(sessions)

        response = await http_get(server.io_loop, url(server))
        html = response.body
        sessionid = extract_sessionid_from_json(html)

        sessions = server.get_sessions('/')
        assert 1 == len(sessions)
        assert sessionid == sessions[0].id
async def test__reject_unsigned_session_header_doc(ManagedServerLoop) -> None:
    application = Application()
    with ManagedServerLoop(application, sign_sessions=True, secret_key='bar') as server:
        sessions = server.get_sessions('/')
        assert 0 == len(sessions)

        expected = 'foo'
        with (pytest.raises(HTTPError)) as info:
            await http_get(server.io_loop, url(server), headers={"Bokeh-Session-Id": expected})
        assert 'Invalid token or session ID' in repr(info.value)

        sessions = server.get_sessions('/')
        assert 0 == len(sessions)
Example #14
0
async def test__no_request_arguments_in_session_context(ManagedServerLoop):
    application = Application()
    with ManagedServerLoop(application) as server:
        response = await http_get(server.io_loop, url(server))
        html = response.body
        sessionid = extract_sessionid_from_json(html)

        server_session = server.get_session('/', sessionid)
        server_doc = server_session.document
        session_context = server_doc.session_context
        # if we do not pass any arguments to the url, the request arguments
        # should be empty
        assert len(session_context.request.arguments) == 0
Example #15
0
def test__lifecycle_hooks(ManagedServerLoop: MSL) -> None:
    application = Application()
    handler = HookTestHandler()
    application.add(handler)
    with ManagedServerLoop(application,
                           check_unused_sessions_milliseconds=30) as server:
        client_session = pull_session(session_id=ID("test__lifecycle_hooks"),
                                      url=url(server),
                                      io_loop=server.io_loop)
        client_doc = client_session.document
        assert len(client_doc.roots) == 1

        server_session = server.get_session('/', client_session.id)
        server_doc = server_session.document
        assert len(server_doc.roots) == 1

        # save for later, since doc.roots will be emptied after the session is closed
        client_hook_list = list(client_doc.roots[0].hooks)
        server_hook_list = list(server_doc.roots[0].hooks)

        client_session.close()

        # expire the session quickly rather than after the usual timeout
        server_session.request_expiration()

        server.io_loop.call_later(0.1, lambda: server.io_loop.stop())

        server.io_loop.start()

    assert handler.hooks == [
        "server_loaded",
        "session_created",
        "modify",
        "next_tick",
        "timeout",
        "periodic",
        "session_destroyed",
        "server_unloaded",
    ]

    assert handler.load_count == 1
    assert handler.unload_count == 1

    # 3 instead of 6, because locked callbacks on destroyed sessions become no-ops
    assert handler.session_creation_async_value == 3
    assert client_doc.title == "Modified"
    assert server_doc.title == "Modified"

    # only the handler sees "session_destroyed" since the session is shut down at that point.
    assert client_hook_list == ["session_created", "modify"]
    assert server_hook_list == ["session_created", "modify"]
async def test__reject_expired_session_websocket(ManagedServerLoop) -> None:
    application = Application()
    with ManagedServerLoop(application, session_token_expiration=1) as server:
        sessions = server.get_sessions('/')
        assert 0 == len(sessions)

        response = await http_get(server.io_loop, url(server))
        html = response.body
        token = extract_token_from_json(html)

        time.sleep(1.1)

        ws = await websocket_open(server.io_loop, ws_url(server), subprotocols=["bokeh", token])
        assert await ws.read_queue.get() is None
async def test__accept_session_websocket(ManagedServerLoop) -> None:
    application = Application()
    with ManagedServerLoop(application, session_token_expiration=1) as server:
        sessions = server.get_sessions('/')
        assert 0 == len(sessions)

        response = await http_get(server.io_loop, url(server))
        html = response.body
        token = extract_token_from_json(html)

        ws = await websocket_open(server.io_loop, ws_url(server), subprotocols=["bokeh", token])
        msg = await ws.read_queue.get()
        assert isinstance(msg, str)
        assert 'ACK' in msg
Example #18
0
async def test__autocreate_signed_session_doc(ManagedServerLoop) -> None:
    application = Application()
    with ManagedServerLoop(application, sign_sessions=True, secret_key='foo') as server:
        sessions = server.get_sessions('/')
        assert 0 == len(sessions)

        response = await http_get(server.io_loop, url(server))
        html = response.body
        sessionid = extract_sessionid_from_json(html)

        sessions = server.get_sessions('/')
        assert 1 == len(sessions)
        assert sessionid == sessions[0].id

        assert check_session_id_signature(sessionid, signed=True, secret_key='foo')
Example #19
0
async def test__reject_unsigned_session_doc(ManagedServerLoop):
    application = Application()
    with ManagedServerLoop(application, sign_sessions=True,
                           secret_key='bar') as server:
        sessions = server.get_sessions('/')
        assert 0 == len(sessions)

        expected = 'foo'
        with (pytest.raises(HTTPError)) as info:
            await http_get(server.io_loop,
                           url(server) + "?bokeh-session-id=" + expected)
        assert 'Invalid session ID' in repr(info.value)

        sessions = server.get_sessions('/')
        assert 0 == len(sessions)
async def test__reject_wrong_subprotocol_websocket(ManagedServerLoop) -> None:
    application = Application()
    with ManagedServerLoop(application) as server:
        sessions = server.get_sessions('/')
        assert 0 == len(sessions)

        response = await http_get(server.io_loop, url(server))
        html = response.body
        token = extract_token_from_json(html)

        sessions = server.get_sessions('/')
        assert 1 == len(sessions)

        ws = await websocket_open(server.io_loop, ws_url(server), subprotocols=["foo", token])
        assert await ws.read_queue.get() is None
Example #21
0
async def test__use_provided_session_doc(ManagedServerLoop) -> None:
    application = Application()
    with ManagedServerLoop(application) as server:
        sessions = server.get_sessions('/')
        assert 0 == len(sessions)

        expected = 'foo'
        response = await http_get(server.io_loop, url(server) + "?bokeh-session-id=" + expected)
        html = response.body
        sessionid = extract_sessionid_from_json(html)
        assert expected == sessionid

        sessions = server.get_sessions('/')
        assert 1 == len(sessions)
        assert expected == sessions[0].id
async def test__actual_port_number(ManagedServerLoop) -> None:
    application = Application()
    with ManagedServerLoop(application, port=0) as server:
        port = server.port
        assert port > 0
        await http_get(server.io_loop, url(server))
def autoload_url(server):
    return url(server) + \
        "autoload.js?bokeh-autoload-element=foo"
def test__lifecycle_hooks(ManagedServerLoop) -> None:
    application = Application()
    handler = HookTestHandler()
    application.add(handler)
    with ManagedServerLoop(application, check_unused_sessions_milliseconds=30) as server:
        # wait for server callbacks to run before we mix in the
        # session, this keeps the test deterministic
        def check_done():
            if len(handler.hooks) == 4:
                server.io_loop.stop()
        server_load_checker = PeriodicCallback(check_done, 1)
        server_load_checker.start()
        server.io_loop.start()
        server_load_checker.stop()

        # now we create a session
        client_session = pull_session(session_id='test__lifecycle_hooks',
                                      url=url(server),
                                      io_loop=server.io_loop)
        client_doc = client_session.document
        assert len(client_doc.roots) == 1

        server_session = server.get_session('/', client_session.id)
        server_doc = server_session.document
        assert len(server_doc.roots) == 1

        # we have to capture these here for examination later, since after
        # the session is closed, doc.roots will be emptied
        client_hook_list = client_doc.roots[0]
        server_hook_list = server_doc.roots[0]

        client_session.close()
        # expire the session quickly rather than after the
        # usual timeout
        server_session.request_expiration()

        def on_done():
            server.io_loop.stop()

        server.io_loop.call_later(0.1, on_done)

        server.io_loop.start()

    assert handler.hooks == ["server_loaded",
                             "next_tick_server",
                             "timeout_server",
                             "periodic_server",
                             "session_created",
                             "modify",
                             "next_tick_session",
                             "timeout_session",
                             "periodic_session",
                             "session_destroyed",
                             "server_unloaded"]

    assert handler.load_count == 1
    assert handler.unload_count == 1
    # this is 3 instead of 6 because locked callbacks on destroyed sessions
    # are turned into no-ops
    assert handler.session_creation_async_value == 3
    assert client_doc.title == "Modified"
    assert server_doc.title == "Modified"
    # only the handler sees the event that adds "session_destroyed" since
    # the session is shut down at that point.
    assert client_hook_list.hooks == ["session_created", "modify"]
    assert server_hook_list.hooks == ["session_created", "modify"]