def test_partial_structure_subscriptions(self): block_1 = MagicMock(to_dict=MagicMock(return_value={ "attr": "value", "inner": { "attr2": "value" } })) block_2 = MagicMock(to_dict=MagicMock(return_value={"attr": "value"})) sub_1 = MagicMock() sub_1.endpoint = ["block_1", "inner"] sub_1.delta = False sub_2 = MagicMock() sub_2.endpoint = ["block_1", "inner"] sub_2.delta = True changes_1 = [[["block_1", "inner", "attr2"], "new_value"], [["block_1", "attr"], "new_value"]] changes_2 = [[["block_2", "attr"], "block_2_value"]] request_1 = BlockChanges(changes_1) request_2 = BlockChanges(changes_2) p = Process("proc", MagicMock()) p.q.get = MagicMock(side_effect=[request_1, request_2, PROCESS_STOP]) p._subscriptions = [sub_1, sub_2] p._handle_block_add(BlockAdd(block_1, "block_1")) p._handle_block_add(BlockAdd(block_2, "block_2")) p.recv_loop() response_1 = sub_1.respond_with_update.call_args[0][0] response_2 = sub_2.respond_with_delta.call_args[0][0] self.assertEquals({"attr2": "new_value"}, response_1) self.assertEquals([[["attr2"], "new_value"]], response_2)
def test_multiple_notifies_single_change(self): block_1 = MagicMock( to_dict=MagicMock(return_value={"attr": "initial_value"})) block_1.name = "block_1" block_2 = MagicMock( to_dict=MagicMock(return_value={"attr2": "initial_value"})) block_2.name = "block_2" sub_1 = MagicMock() sub_1.endpoint = ["block_1"] sub_1.delta = False sub_2 = MagicMock() sub_2.endpoint = ["block_1"] sub_2.delta = True sub_3 = MagicMock() sub_3.endpoint = ["block_2"] sub_3.delta = False sub_4 = MagicMock() sub_4.endpoint = ["block_2"] sub_4.delta = True change_1 = [["block_1", "attr"], "final_value"] change_2 = [["block_2", "attr2"], "final_value"] request_1 = BlockNotify("block_1") request_2 = BlockChanged(change_1) request_3 = BlockChanged(change_2) request_4 = BlockNotify("block_1") request_5 = BlockNotify("block_1") request_6 = BlockNotify("block_2") p = Process("proc", MagicMock()) p.q.get = MagicMock(side_effect=[request_1, request_2, request_3, request_4, request_5, request_6, PROCESS_STOP]) p.q.put = MagicMock(side_effect=p.q.put) p._subscriptions["block_1"] = [sub_1, sub_2] p._subscriptions["block_2"] = [sub_3, sub_4] p._handle_block_add(BlockAdd(block_1)) p._handle_block_add(BlockAdd(block_2)) p.recv_loop() call_list = sub_1.response_queue.put.call_args_list self.assertEquals(1, len(call_list)) self.assertIsInstance(call_list[0][0][0], Update) self.assertEquals({"attr": "final_value"}, call_list[0][0][0].value) call_list = sub_2.response_queue.put.call_args_list self.assertEquals(1, len(call_list)) self.assertIsInstance(call_list[0][0][0], Delta) self.assertEquals([[["attr"], "final_value"]], call_list[0][0][0].changes) call_list = sub_3.response_queue.put.call_args_list self.assertEquals(1, len(call_list)) self.assertIsInstance(call_list[0][0][0], Update) self.assertEquals({"attr2": "final_value"}, call_list[0][0][0].value) call_list = sub_4.response_queue.put.call_args_list self.assertEquals(1, len(call_list)) self.assertIsInstance(call_list[0][0][0], Delta) self.assertEquals([[["attr2"], "final_value"]], call_list[0][0][0].changes)
def test_partial_structure_subscriptions(self): block_1 = MagicMock(to_dict=MagicMock(return_value={ "attr": "value", "inner": { "attr2": "value" } })) block_2 = MagicMock(to_dict=MagicMock(return_value={"attr": "value"})) sub_1 = Subscribe(None, MagicMock(), ["block_1", "inner"], delta=False) sub_1.set_id(1) sub_1.response_queue.qsize.return_value = 0 sub_2 = Subscribe(None, MagicMock(), ["block_1"], delta=True) sub_2.set_id(2) sub_2.response_queue.qsize.return_value = 0 sub_3 = Subscribe(None, MagicMock(), ["block_1", "inner", "attr2"], delta=False) sub_3.set_id(3) sub_3.response_queue.qsize.return_value = 0 changes_1 = [[["block_1", "inner", "attr2"], "new_value"], [["block_1", "attr"], "new_value"]] changes_2 = [[["block_2", "attr"], "block_2_value"]] request_1 = BlockChanges(changes_1) request_2 = BlockChanges(changes_2) p = Process("proc", MagicMock()) p.q.get = MagicMock(side_effect=[ sub_1, sub_2, sub_3, request_1, request_2, PROCESS_STOP ]) p._handle_block_add(BlockAdd(block_1, "block_1", None)) p._handle_block_add(BlockAdd(block_2, "block_2", None)) p.recv_loop() response_1 = sub_1.response_queue.put.call_args_list[1][0][0]["value"] self.assertEquals({"attr2": "new_value"}, response_1) response_2 = sub_2.response_queue.put.call_args_list[1][0][0][ "changes"] self.assertEquals( [[["inner", "attr2"], "new_value"], [["attr"], "new_value"]], response_2) response_3 = sub_3.response_queue.put.call_args_list[1][0][0]["value"] self.assertEquals("new_value", response_3)
def test_overlapped_changes(self): block = MagicMock( to_dict=MagicMock(return_value={"attr": "value", "attr2": "other"})) block.name = "block" sub_1 = MagicMock() sub_1.endpoint = ["block"] sub_1.delta = False sub_2 = MagicMock() sub_2.endpoint = ["block"] sub_2.delta = True changes_1 = [["block", "attr"], "changing_value"] changes_2 = [["block", "attr"], "final_value"] request_1 = BlockChanged(changes_1) request_2 = BlockChanged(changes_2) request_3 = BlockNotify(block.name) s = MagicMock() p = Process("proc", s) p._subscriptions["block"] = [sub_1, sub_2] p.q.get = MagicMock( side_effect=[request_1, request_2, request_3, PROCESS_STOP]) p._handle_block_add(BlockAdd(block)) p.recv_loop() self.assertEqual(sub_1.response_queue.put.call_count, 1) self.assertEqual(sub_2.response_queue.put.call_count, 1) response_1 = sub_1.response_queue.put.call_args[0][0] response_2 = sub_2.response_queue.put.call_args[0][0] self.assertEquals({"attr": "final_value", "attr2": "other"}, response_1.value) self.assertEquals( [[["attr"], "changing_value"], [["attr"], "final_value"]], response_2.changes)
def test_subscribe(self): block = MagicMock(to_dict=MagicMock(return_value={ "attr": "value", "inner": { "attr2": "other" } })) p = Process("proc", MagicMock()) sub_1 = Subscribe(MagicMock(), MagicMock(), ["block"], False) sub_1.response_queue.qsize.return_value = 0 sub_2 = Subscribe(MagicMock(), MagicMock(), ["block", "inner"], True) sub_2.response_queue.qsize.return_value = 0 p.q.get = MagicMock(side_effect=[sub_1, sub_2, PROCESS_STOP]) p._handle_block_add(BlockAdd(block, "block", None)) p.recv_loop() self.assertEquals([sub_1, sub_2], list(p._subscriptions.values())) response_1 = sub_1.response_queue.put.call_args[0][0] response_2 = sub_2.response_queue.put.call_args[0][0] self.assertEquals({ "attr": "value", "inner": { "attr2": "other" } }, response_1.value) self.assertEquals([[[], {"attr2": "other"}]], response_2.changes)
def test_unsubscribe(self): # Test that we remove the relevant subscription only and that # updates are no longer sent block = MagicMock(to_dict=MagicMock(return_value={ "attr": "0", "inner": { "attr2": "other" } })) p = Process("proc", MagicMock()) sub_1 = Subscribe(MagicMock(), MagicMock(), ["block"], False) sub_2 = Subscribe(MagicMock(), MagicMock(), ["block"], False) sub_1.set_id(1234) sub_2.set_id(4321) change_1 = BlockChanges([[["block", "attr"], "1"]]) change_2 = BlockChanges([[["block", "attr"], "2"]]) unsub_1 = Unsubscribe(MagicMock(), MagicMock()) unsub_1.set_id(1234) p.q.get = MagicMock(side_effect=[ sub_1, sub_2, change_1, unsub_1, change_2, PROCESS_STOP ]) p._handle_block_add(BlockAdd(block, "block")) p.recv_loop() self.assertEqual([sub_2], p._subscriptions) self.assertEquals(1, len(unsub_1.response_queue.put.call_args_list)) response = unsub_1.response_queue.put.call_args_list[0][0][0] self.assertIsNone(response.value) self.assertIs(unsub_1.context, response.context) sub_1_responses = sub_1.response_queue.put.call_args_list sub_2_responses = sub_2.response_queue.put.call_args_list self.assertEquals(2, len(sub_1_responses)) self.assertEquals(3, len(sub_2_responses))
def test_starting_process(self): s = SyncFactory("sched") p = Process("proc", s) b = MagicMock() p._handle_block_add(BlockAdd(b, "myblock", None)) self.assertEqual(p._blocks, dict(myblock=b, proc=ANY)) p.start() request = Post(MagicMock(), MagicMock(), ["myblock", "foo"]) p.q.put(request) # wait for spawns to have done their job p.stop() b.handle_request.assert_called_once_with(request)
def test_partial_structure_subscriptions(self): block_1 = MagicMock( to_dict=MagicMock( return_value={"attr": "value", "inner": {"attr2": "value"}})) block_1.name = "block_1" block_2 = MagicMock( to_dict=MagicMock(return_value={"attr": "value"})) block_2.name = "block_2" sub_1 = MagicMock() sub_1.endpoint = ["block_1", "inner"] sub_1.delta = False sub_2 = MagicMock() sub_2.endpoint = ["block_1", "inner"] sub_2.delta = True changes_1 = [["block_1", "inner", "attr2"], "new_value"] changes_2 = [["block_1", "attr"], "new_value"] changes_3 = [["block_2", "attr"], "block_2_value"] request_1 = BlockChanged(changes_1) request_2 = BlockChanged(changes_2) request_3 = BlockChanged(changes_3) request_4 = BlockNotify(block_1.name) request_5 = BlockNotify(block_2.name) p = Process("proc", MagicMock()) p.q.get = MagicMock(side_effect=[ request_1, request_2, request_3, request_4, request_5, PROCESS_STOP]) p._subscriptions["block_1"] = [sub_1, sub_2] p._handle_block_add(BlockAdd(block_1)) p._handle_block_add(BlockAdd(block_2)) p.recv_loop() response_1 = sub_1.response_queue.put.call_args[0][0] response_2 = sub_2.response_queue.put.call_args[0][0] self.assertEquals({"attr2": "new_value"}, response_1.value) self.assertEquals([[["attr2"], "new_value"]], response_2.changes)
def test_get(self): p = Process("proc", MagicMock()) block = MagicMock() block.name = "myblock" block.to_dict = MagicMock( return_value={"path_1": {"path_2": {"attr": "value"}}}) request = Get(MagicMock(), MagicMock(), ["myblock", "path_1", "path_2"]) p._handle_block_add(BlockAdd(block)) p.q.get = MagicMock(side_effect=[request, PROCESS_STOP]) p.recv_loop() response = request.response_queue.put.call_args[0][0] self.assertIsInstance(response, Return) self.assertEquals({"attr": "value"}, response.value)
def test_unsubscribe(self): # Test that we remove the relevant subscription only and that # updates are no longer sent block = MagicMock(to_dict=MagicMock(return_value={ "attr": "0", "inner": { "attr2": "other" } })) p = Process("proc", MagicMock()) sub_1 = Subscribe(MagicMock(), MagicMock(), ["block"], False) sub_1.response_queue.qsize.return_value = 0 sub_2 = Subscribe(MagicMock(), MagicMock(), ["block"], False) sub_2.response_queue.qsize.return_value = 0 sub_1.set_id(1234) sub_2.set_id(1234) change_1 = BlockChanges([[["block", "attr"], "1"]]) change_2 = BlockChanges([[["block", "attr"], "2"]]) unsub_1 = Unsubscribe(sub_1.context, sub_1.response_queue) unsub_1.set_id(sub_1.id) p.q.get = MagicMock(side_effect=[ sub_1, sub_2, change_1, unsub_1, change_2, PROCESS_STOP ]) p._handle_block_add(BlockAdd(block, "block", None)) p.recv_loop() self.assertEqual([sub_2], list(p._subscriptions.values())) sub_1_responses = sub_1.response_queue.put.call_args_list sub_2_responses = sub_2.response_queue.put.call_args_list self.assertEquals(3, len(sub_1_responses)) self.assertEquals(sub_1_responses[0][0][0].value["attr"], "0") self.assertEquals(sub_1_responses[1][0][0].value["attr"], "1") self.assertIsInstance(sub_1_responses[2][0][0], Return) self.assertEquals(3, len(sub_2_responses)) self.assertEquals(sub_2_responses[0][0][0].value["attr"], "0") self.assertEquals(sub_2_responses[1][0][0].value["attr"], "1") self.assertEquals(sub_2_responses[2][0][0].value["attr"], "2")