Beispiel #1
0
 def test_manager_host_table_or_view(self):
     manager = PerspectiveManager()
     table = Table(data)
     view = table.view()
     manager.host(table, name="table1")
     manager.host(view, name="view1")
     assert manager.get_table("table1").size() == 3
     assert manager.get_view("view1").to_dict() == data
 def test_locked_manager_create_view(self):
     message = {"id": 1, "name": "view1", "cmd": "view_method", "method": "schema", "args": []}
     manager = PerspectiveManager(lock=True)
     table = Table(data)
     view = table.view()
     manager.host_table("table1", table)
     manager.host_view("view1", view)
     manager._process(message, self.post)
     assert manager.get_view("view1").schema() == {
         "a": int,
         "b": str
     }
    def test_manager_on_delete_view(self, sentinel):
        s = sentinel(False)

        def delete_callback():
            s.set(True)

        make_table = {"id": 1, "name": "table1", "cmd": "table", "args": [data]}
        manager = PerspectiveManager()
        manager._process(make_table, self.post)
        make_view = {"id": 2, "table_name": "table1", "view_name": "view1", "cmd": "view"}
        manager._process(make_view, self.post)

        view = manager.get_view("view1")
        view.on_delete(delete_callback)

        delete_view = {"id": 3, "name": "view1", "cmd": "view_method", "method": "delete"}

        manager._process(delete_view, self.post)

        assert len(manager._views) == 0
        assert s.get() is True
    def test_session_new_session(self, sentinel):
        s = sentinel(False)

        def handle_to_dict(msg):
            s.set(True)
            message = json.loads(msg)
            assert message["data"] == data

        message = {
            "id": 1,
            "table_name": "table1",
            "view_name": "view1",
            "cmd": "view"
        }

        manager = PerspectiveManager()
        session = manager.new_session()
        client_id = session.client_id
        table = Table(data)

        manager.host_table("table1", table)

        # create a view through the session to make sure it has a client id
        session.process(message, self.post)

        # make sure the client ID is attached to the new view
        assert len(manager._views.keys()) == 1
        assert manager.get_view("view1")._client_id == client_id

        to_dict_message = {
            "id": 2,
            "name": "view1",
            "cmd": "view_method",
            "method": "to_dict"
        }

        session.process(to_dict_message, handle_to_dict)
        assert s.get() is True
Beispiel #5
0
 def test_manager_host_view(self):
     manager = PerspectiveManager()
     table = Table(data)
     view = table.view()
     manager.host_view("view1", view)
     assert manager.get_view("view1").to_dict() == data
    def test_session_multiple_new_sessions(self, sentinel):
        s = sentinel(0)

        def handle_to_dict(msg):
            s.set(s.get() + 1)

            message = json.loads(msg)

            assert message["data"] == {
                "a": [1, 2, 3, 1, 2, 3],
                "b": ["a", "b", "c", "str1", "str2", "str3"]
            }

        manager = PerspectiveManager()
        sessions = [manager.new_session() for i in range(5)]
        table = Table(data)

        manager.host_table("table1", table)

        # create a view on each session
        for i, session in enumerate(sessions):
            # IDs have to conflict - each viewer will send the first message as
            # ID = 1, so we need to make sure we handle that.
            msg = {
                "id": 1,
                "table_name": "table1",
                "view_name": "view" + str(i),
                "cmd": "view"
            }
            session.process(msg, self.post)

        manager_views = list(manager._views.keys())
        for key in ["view" + str(i) for i in range(5)]:
            assert key in manager_views

        for i, session in enumerate(sessions):
            view = manager.get_view("view" + str(i))
            assert view._client_id == session.client_id

        # arbitrarily do an update
        random_session_id = random.randint(0, 4)
        update_message = {
            "id": 2,
            "name": "table1",
            "cmd": "table_method",
            "method": "update",
            "args": [{
                "a": [1, 2, 3],
                "b": ["str1", "str2", "str3"]
            }]
        }
        sessions[random_session_id].process(update_message, self.post)

        # should reflect in all sessions
        for i, session in enumerate(sessions):
            to_dict_message = {
                "id": 3,
                "name": "view" + str(i),
                "cmd": "view_method",
                "method": "to_dict"
            }
            session.process(to_dict_message, handle_to_dict)

        assert s.get() == 5
    def test_session_close_multiple_sessions_with_callbacks(self, sentinel):
        s = sentinel(0)

        manager = PerspectiveManager()
        sessions = [manager.new_session() for i in range(5)]

        # create a table and view using manager
        make_table = {
            "id": 1,
            "name": "table1",
            "cmd": "table",
            "args": [data]
        }
        manager._process(make_table, self.post)

        # create a view on each session
        for i, session in enumerate(sessions):
            # IDs have to conflict - each viewer will send the first message as
            # ID = 1, so we need to make sure we handle that.
            msg = {
                "id": 2,
                "table_name": "table1",
                "view_name": "view" + str(i),
                "cmd": "view"
            }
            session.process(msg, self.post)

        manager_views = list(manager._views.keys())
        for key in ["view" + str(i) for i in range(5)]:
            assert key in manager_views

        for i, session in enumerate(sessions):
            view = manager.get_view("view" + str(i))
            assert view._client_id == session.client_id

        def callback(updated):
            assert updated["port_id"] == 0
            s.set(s.get() + 100)

        # simulate a client that holds callbacks by id
        callbacks = {3: callback}

        def post_update(msg):
            # when `on_update` is triggered, this callback gets the message
            # and has to decide which callback to trigger.
            message = json.loads(msg)
            assert message["id"] is not None
            if message["id"] == 3:
                # trigger callback
                assert message["data"] == {"port_id": 0}
                callbacks[message["id"]](message["data"])

        # create a view and an on_update on each session
        for i, session in enumerate(sessions):
            view_name = "view" + str(i)
            # IDs have to conflict - each viewer will send the first message as
            # ID = 1, so we need to make sure we handle that.
            msg = {
                "id": 2,
                "table_name": "table1",
                "view_name": view_name,
                "cmd": "view"
            }
            session.process(msg, self.post)
            make_on_update = {
                "id": 3,
                "name": view_name,
                "cmd": "view_method",
                "subscribe": True,
                "method": "on_update",
                "callback_id": "callback_1"
            }
            session.process(make_on_update, post_update)

        # call updates using a random session - they should propagate
        random_session_id = random.randint(0, 4)
        random_session = sessions[random_session_id]
        random_client_id = random_session.client_id

        update1 = {
            "id": 4,
            "name": "table1",
            "cmd": "table_method",
            "method": "update",
            "args": [{
                "a": [4],
                "b": ["d"]
            }]
        }
        update2 = {
            "id": 5,
            "name": "table1",
            "cmd": "table_method",
            "method": "update",
            "args": [{
                "a": [5],
                "b": ["e"]
            }]
        }

        random_session.process(update1, self.post)
        random_session.process(update2, self.post)

        # all updates processed, all callbacks fired
        assert s.get() == 1000

        # close a random session, and make sure the other views and callbacks
        # are not affected
        random_session.close()

        # make sure the view is gone - but not the table
        assert "table1" in manager._tables

        assert "view" + str(random_session_id) not in manager._views.keys()
        assert len(manager._views.keys()) == 4

        for callback in manager._callback_cache:
            assert callback["client_id"] != random_client_id

        assert len(manager._callback_cache) == 4
    def test_session_close_session_with_callbacks(self, sentinel):
        s = sentinel(0)

        manager = PerspectiveManager()
        session = manager.new_session()
        client_id = session.client_id

        # create a table and view using manager
        make_table = {
            "id": 1,
            "name": "table1",
            "cmd": "table",
            "args": [data]
        }
        session.process(make_table, self.post)

        make_view = {
            "id": 2,
            "table_name": "table1",
            "view_name": "view1",
            "cmd": "view"
        }
        session.process(make_view, self.post)

        # make sure the client ID is attached to the new view
        assert len(manager._views.keys()) == 1
        assert manager.get_view("view1")._client_id == client_id

        def callback(updated):
            assert updated["port_id"] == 0
            s.set(s.get() + 100)

        # simulate a client that holds callbacks by id
        callbacks = {3: callback}

        def post_update(msg):
            # when `on_update` is triggered, this callback gets the message
            # and has to decide which callback to trigger.
            message = json.loads(msg)
            assert message["id"] is not None
            if message["id"] == 3:
                # trigger callback
                assert message["data"] == {"port_id": 0}
                callbacks[message["id"]](message["data"])

        # hook into the created view and pass it the callback
        make_on_update = {
            "id": 3,
            "name": "view1",
            "cmd": "view_method",
            "subscribe": True,
            "method": "on_update",
            "callback_id": "callback_1"
        }
        session.process(make_on_update, post_update)

        # call updates
        update1 = {
            "id": 4,
            "name": "table1",
            "cmd": "table_method",
            "method": "update",
            "args": [{
                "a": [4],
                "b": ["d"]
            }]
        }
        update2 = {
            "id": 5,
            "name": "table1",
            "cmd": "table_method",
            "method": "update",
            "args": [{
                "a": [5],
                "b": ["e"]
            }]
        }

        session.process(update1, self.post)
        session.process(update2, self.post)

        assert s.get() == 200

        # close the session
        session.close()

        # make sure the view is gone - but not the table
        assert "table1" in manager._tables
        assert manager._views == {}
        assert len(manager._callback_cache) == 0