def test_send_want_start_task_session(self, mock_send): node = p2p_factories.Node() super_node = p2p_factories.Node() self.peer_session.send_want_to_start_task_session(node, "CONN_ID", super_node) msg = mock_send.call_args[0][0] assert isinstance(msg, message.p2p.WantToStartTaskSession) assert isinstance(msg.node_info, dict) assert isinstance(msg.super_node_info, dict) self.peer_session._react_to_want_to_start_task_session(msg)
def test_set_task_session(self, mock_send): node = p2p_factories.Node() super_node = p2p_factories.Node() self.peer_session.send_set_task_session("KEY_ID", node, "CONN_ID", super_node) msg = mock_send.call_args[0][0] assert isinstance(msg, message.p2p.SetTaskSession) assert isinstance(msg.node_info, dict) assert isinstance(msg.super_node_info, dict) assert msg.key_id == "KEY_ID" self.peer_session._react_to_set_task_session(msg)
def test_task_header_update(self): e = Environment() e.accept_tasks = True tk = TaskHeaderKeeper(environments_manager=EnvironmentsManager(), node=p2p.Node(), min_price=10) tk.environments_manager.add_environment(e) task_header = get_task_header() task_id = task_header.task_id task_header.fixed_header.deadline = timeout_to_deadline(10) task_header.fixed_header.update_checksum() assert tk.add_task_header(task_header) assert task_id in tk.supported_tasks assert tk.add_task_header(task_header) assert task_id in tk.supported_tasks task_header = copy.deepcopy(task_header) task_header.fixed_header.max_price = 1 task_header.fixed_header.update_checksum() # An attempt to update fixed header should *not* succeed assert not tk.add_task_header(task_header) assert task_id in tk.supported_tasks tk.task_headers = {} tk.supported_tasks = [] assert tk.add_task_header(task_header) assert task_id not in tk.supported_tasks
def test_old_tasks(frozen_time, _): # pylint: disable=no-self-argument tk = TaskHeaderKeeper(environments_manager=EnvironmentsManager(), node=p2p.Node(), min_price=10) e = Environment() e.accept_tasks = True tk.environments_manager.add_environment(e) task_header = get_task_header() task_header.fixed_header.deadline = timeout_to_deadline(10) assert tk.add_task_header(task_header) task_id = task_header.task_id task_header2 = get_task_header("abc") task_header2.fixed_header.deadline = timeout_to_deadline(1) task_id2 = task_header2.task_id assert tk.add_task_header(task_header2) assert tk.task_headers.get(task_id2) is not None assert tk.task_headers.get(task_id) is not None assert tk.removed_tasks.get(task_id2) is None assert tk.removed_tasks.get(task_id) is None assert len(tk.supported_tasks) == 2 frozen_time.tick(timedelta(seconds=1.1)) # pylint: disable=no-member tk.remove_old_tasks() assert tk.task_headers.get(task_id2) is None assert tk.task_headers.get(task_id) is not None assert tk.removed_tasks.get(task_id2) is not None assert tk.removed_tasks.get(task_id) is None assert len(tk.supported_tasks) == 1 assert tk.supported_tasks[0] == task_id
def test_estimated_network_size_buckets_bigger_than_k(self): for _ in range(self.peer_keeper.k): self.peer_keeper.buckets[0].peers.append( p2p_factories.Node(), ) size = self.peer_keeper.get_estimated_network_size() self.assertEqual(size, 0)
def test_is_supported(self): em = EnvironmentsManager() em.environments = {} em.support_statuses = {} tk = TaskHeaderKeeper(environments_manager=EnvironmentsManager(), node=p2p.Node(), min_price=10.0) header = get_task_header() header.fixed_header.environment = None header.fixed_header.max_price = None header.fixed_header.min_version = None self.assertFalse(tk.check_support(header)) header.fixed_header.environment = Environment.get_id() header.fixed_header.max_price = 0 supported = tk.check_support(header) self.assertFalse(supported) self.assertIn(UnsupportReason.ENVIRONMENT_MISSING, supported.desc) e = Environment() e.accept_tasks = True tk.environments_manager.add_environment(e) supported = tk.check_support(header) self.assertFalse(supported) self.assertIn(UnsupportReason.MAX_PRICE, supported.desc) header.fixed_header.max_price = 10.0 supported = tk.check_support(header) self.assertFalse(supported) self.assertIn(UnsupportReason.APP_VERSION, supported.desc) header.fixed_header.min_version = golem.__version__ self.assertTrue(tk.check_support(header)) header.fixed_header.max_price = 10.0 self.assertTrue(tk.check_support(header)) config_desc = mock.Mock() config_desc.min_price = 13.0 tk.change_config(config_desc) self.assertFalse(tk.check_support(header)) config_desc.min_price = 10.0 tk.change_config(config_desc) self.assertTrue(tk.check_support(header)) header.fixed_header.min_version = "120" self.assertFalse(tk.check_support(header)) header.fixed_header.min_version = tk.app_version self.assertTrue(tk.check_support(header)) header.fixed_header.min_version = "abc" with self.assertLogs(logger=logger, level='WARNING'): self.assertFalse(tk.check_support(header))
def __setup_handshake_server_test(self, send_mock) -> message.base.Hello: self.peer_session.conn.server.node = node = p2p_factories.Node() self.peer_session.conn.server.node_name = node_name = node.node_name self.peer_session.conn.server.keys_auth.key_id = \ key_id = 'server_key_id' self.peer_session.conn.server.key_difficulty = 2 self.peer_session.conn.server.cur_port = port = random.randint(1, 50000) self.peer_session.conn_type = self.peer_session.CONN_TYPE_SERVER self.peer_session.start() self.assertEqual(1, send_mock.call_count) expected = message.base.Hello( challenge=None, client_key_id=key_id, client_ver=golem.__version__, difficulty=None, node_info=node.to_dict(), node_name=node_name, port=port, proto_id=PROTOCOL_CONST.ID, rand_val=self.peer_session.rand_val, solve_challenge=False, metadata={}, ) self.assertEqual(send_mock.call_args[0][1].slots(), expected.slots()) def find_peer(key): if key == key_id: return self.peer_session return None self.peer_session.p2p_service.find_peer = find_peer self.peer_session.p2p_service.enough_peers = lambda: False client_peer_info = p2p_factories.Node() client_hello = message.base.Hello( port=1, node_name='client', rand_val=random.random(), client_key_id=client_peer_info.key, node_info=client_peer_info.to_dict(), proto_id=PROTOCOL_CONST.ID) fill_slots(client_hello) return client_hello
def test_get_owner(self): tk = TaskHeaderKeeper(environments_manager=EnvironmentsManager(), node=p2p.Node(), min_price=10) header = get_task_header() owner = header.task_owner.key key_id = header.task_id tk.add_task_header(header) assert tk.get_owner(key_id) == owner assert tk.get_owner("UNKNOWN") is None
def test_task_limit(frozen_time, self): # pylint: disable=no-self-argument tk = TaskHeaderKeeper(environments_manager=EnvironmentsManager(), node=p2p.Node(), min_price=10) limit = tk.max_tasks_per_requestor thd = get_task_header("ta") thd.fixed_header.deadline = timeout_to_deadline(0.1) tk.add_task_header(thd) ids = [thd.task_id] for i in range(1, limit): thd = get_task_header("ta") ids.append(thd.task_id) tk.add_task_header(thd) last_add_time = time.time() for id_ in ids: self.assertIn(id_, tk.task_headers) thd = get_task_header("tb0") tb_id = thd.task_id tk.add_task_header(thd) for id_ in ids: self.assertIn(id_, tk.task_headers) self.assertIn(tb_id, tk.task_headers) while time.time() == last_add_time: frozen_time.tick( # pylint: disable=no-member delta=timedelta(milliseconds=100)) thd = get_task_header("ta") new_task_id = thd.task_id tk.add_task_header(thd) self.assertNotIn(new_task_id, tk.task_headers) for id_ in ids: self.assertIn(id_, tk.task_headers) self.assertIn(tb_id, tk.task_headers) frozen_time.tick( # pylint: disable=no-member delta=timedelta(milliseconds=100)) tk.remove_old_tasks() thd = get_task_header("ta") new_task_id = thd.task_id tk.add_task_header(thd) self.assertIn(new_task_id, tk.task_headers) self.assertNotIn(ids[0], tk.task_headers) for i in range(1, limit): self.assertIn(ids[i], tk.task_headers) self.assertIn(tb_id, tk.task_headers)
def test_check_max_tasks_per_owner(self): tk = TaskHeaderKeeper(environments_manager=EnvironmentsManager(), node=p2p.Node(), min_price=10, max_tasks_per_requestor=10) limit = tk.max_tasks_per_requestor new_limit = 3 ids = [] for i in range(new_limit): thd = get_task_header("ta") ids.append(thd.task_id) tk.add_task_header(thd) last_add_time = time.time() thd = get_task_header("tb0") tb0_id = thd.task_id tk.add_task_header(thd) for id_ in ids: self.assertIn(id_, tk.task_headers) self.assertIn(tb0_id, tk.task_headers) while time.time() == last_add_time: time.sleep(0.1) new_ids = [] for i in range(new_limit, limit): thd = get_task_header("ta") new_ids.append(thd.task_id) tk.add_task_header(thd) for id_ in ids + new_ids: self.assertIn(id_, tk.task_headers) self.assertIn(tb0_id, tk.task_headers) self.assertEqual(limit + 1, len(tk.task_headers)) # shouldn't remove any tasks tk.check_max_tasks_per_owner(thd.task_owner.key) for id_ in ids + new_ids: self.assertIn(id_, tk.task_headers) self.assertIn(tb0_id, tk.task_headers) self.assertEqual(limit + 1, len(tk.task_headers)) tk.max_tasks_per_requestor = new_limit # should remove ta{3..9} tk.check_max_tasks_per_owner(thd.task_owner.key) for id_ in ids: self.assertIn(id_, tk.task_headers) self.assertIn(tb0_id, tk.task_headers) self.assertEqual(new_limit + 1, len(tk.task_headers))
def test_react_to_peers(self, add_peer_mock): node = p2p_factories.Node() peers = [ { 'address': node.prv_addr, 'port': node.prv_port, 'node_name': node.node_name, 'node': node.to_dict(), }, ] msg = message.p2p.Peers(peers=copy.deepcopy(peers)) self.peer_session._react_to_peers(msg) peers[0]['node'] = Node.from_dict(peers[0]['node']) add_peer_mock.assert_called_once_with(peers[0])
def test_change_config(self, tar): tk = TaskHeaderKeeper(environments_manager=EnvironmentsManager(), node=p2p.Node(), min_price=10.0, task_archiver=tar) e = Environment() e.accept_tasks = True tk.environments_manager.add_environment(e) task_header = get_task_header() task_id = task_header.task_id task_header.fixed_header.max_price = 9.0 tk.add_task_header(task_header) self.assertNotIn(task_id, tk.supported_tasks) self.assertIn(task_id, tk.task_headers) task_header = get_task_header("abc") task_id2 = task_header.task_id task_header.fixed_header.max_price = 10.0 tk.add_task_header(task_header) self.assertIn(task_id2, tk.supported_tasks) self.assertIn(task_id2, tk.task_headers) config_desc = mock.Mock() config_desc.min_price = 10.0 tk.change_config(config_desc) self.assertNotIn(task_id, tk.supported_tasks) self.assertIn(task_id2, tk.supported_tasks) config_desc.min_price = 8.0 tk.change_config(config_desc) self.assertIn(task_id, tk.supported_tasks) self.assertIn(task_id2, tk.supported_tasks) config_desc.min_price = 11.0 tk.change_config(config_desc) self.assertNotIn(task_id, tk.supported_tasks) self.assertNotIn(task_id2, tk.supported_tasks) # Make sure the tasks stats are properly archived tar.reset_mock() config_desc.min_price = 9.5 tk.change_config(config_desc) self.assertNotIn(task_id, tk.supported_tasks) self.assertIn(task_id2, tk.supported_tasks) tar.add_support_status.assert_any_call( task_id, SupportStatus(False, {UnsupportReason.MAX_PRICE: 9.0})) tar.add_support_status.assert_any_call(task_id2, SupportStatus(True, {}))
def test_send_peers(self, send_mock, find_mock): node = p2p_factories.Node() find_mock.return_value = [ { 'address': node.prv_addr, 'port': node.prv_port, 'node_name': node.node_name, 'node': node, }, ] self.peer_session._send_peers() find_mock.assert_called_once_with( node_key_id=None, alpha=ANY, ) send_mock.assert_called_once_with(ANY) msg = send_mock.call_args[0][0] self.assertEqual(msg.peers[0]['node'], node.to_dict())
def test_check_version_compatibility(self): tk = TaskHeaderKeeper(environments_manager=EnvironmentsManager(), node=p2p.Node(), min_price=10.0) tk.app_version = '0.4.5-dev+232.138018' for v in ['', '0', '1.5', '0.4-alpha+build.2004.01.01', '0.4-alpha']: with self.assertRaises(ValueError, msg=v): tk.check_version_compatibility(v) for v in ['1.5.0', '1.4.0', '0.5.0', '0.3.0']: self.assertFalse(tk.check_version_compatibility(v), msg=v) for v in [ '0.4.5', '0.4.1', '0.4.0', '0.4.0-alpha', '0.4.0-alpha+build', '0.4.0-alpha+build.2010', '0.4.6' ]: self.assertTrue(tk.check_version_compatibility(v), msg=v)
def test_drop_set_task(self, load_mock): with freeze_time("2017-01-14 10:30:20") as frozen_datetime: node = p2p_factories.Node() msg = message.p2p.SetTaskSession( key_id=None, node_info=node.to_dict(), conn_id=None, super_node_info=None) data = msg.serialize() packed_data = struct.pack("!L", len(data)) + data load_mock.return_value = msg for _ in range(0, 100): self.protocol.dataReceived(packed_data) self.protocol.session.interpret.assert_called_once_with(msg) frozen_datetime.move_to("2017-01-14 10:30:45") self.protocol.session.interpret.reset_mock() self.protocol.dataReceived(packed_data) self.protocol.session.interpret.assert_called_once_with(msg)
def setUp(self): super().setUp() random.seed() self.peer_session = PeerSession(MagicMock()) node = p2p_factories.Node() keys_auth = KeysAuth(self.path, 'priv_key', 'password') self.peer_session.conn.server = \ self.peer_session.p2p_service = P2PService( node=node, config_desc=clientconfigdescriptor.ClientConfigDescriptor(), keys_auth=keys_auth, connect_to_known_hosts=False, ) client = MagicMock() client.datadir = self.path with patch( 'golem.network.concent.handlers_library.HandlersLibrary' '.register_handler',): self.peer_session.p2p_service.task_server = \ task_server_factory.TaskServer(client=client)
def test_get_task(self): em = EnvironmentsManager() em.environments = {} em.support_statuses = {} tk = TaskHeaderKeeper(environments_manager=em, node=p2p.Node(), min_price=10) self.assertIsNone(tk.get_task()) task_header = get_task_header("uvw") self.assertTrue(tk.add_task_header(task_header)) self.assertIsNone(tk.get_task()) e = Environment() e.accept_tasks = True tk.environments_manager.add_environment(e) task_header2 = get_task_header("xyz") self.assertTrue(tk.add_task_header(task_header2)) th = tk.get_task() assert isinstance(th.task_owner, Node) self.assertEqual(task_header2.to_dict(), th.to_dict())
def test_task_header_update_stats(self, tar): e = Environment() e.accept_tasks = True tk = TaskHeaderKeeper(environments_manager=EnvironmentsManager(), node=p2p.Node(), min_price=10, task_archiver=tar) tk.environments_manager.add_environment(e) task_header = get_task_header("good") assert tk.add_task_header(task_header) tar.add_task.assert_called_with(mock.ANY) task_id = task_header.task_id tar.add_support_status.assert_any_call(task_id, SupportStatus(True, {})) tar.reset_mock() task_header2 = get_task_header("bad") task_id2 = task_header2.task_id task_header2.fixed_header.max_price = 1.0 assert tk.add_task_header(task_header2) tar.add_task.assert_called_with(mock.ANY) tar.add_support_status.assert_any_call( task_id2, SupportStatus(False, {UnsupportReason.MAX_PRICE: 1.0}))
def test_init(self): tk = TaskHeaderKeeper(environments_manager=EnvironmentsManager(), node=p2p.Node(), min_price=10.0) self.assertIsInstance(tk, TaskHeaderKeeper)
def test_get_unsupport_reasons(self): tk = TaskHeaderKeeper(environments_manager=EnvironmentsManager(), node=p2p.Node(), min_price=10) e = Environment() e.accept_tasks = True tk.environments_manager.add_environment(e) # Supported task thd = get_task_header("good") tk.add_task_header(thd) # Wrong version thd = get_task_header("wrong version") thd.fixed_header.min_version = "42.0.17" tk.add_task_header(thd) # Wrong environment thd = get_task_header("wrong env") thd.fixed_header.environment = "UNKNOWN" tk.add_task_header(thd) # Wrong price thd = get_task_header("wrong price") thd.fixed_header.max_price = 1 tk.add_task_header(thd) # Wrong price and version thd = get_task_header("wrong price and version") thd.fixed_header.min_version = "42.0.17" thd.fixed_header.max_price = 1 tk.add_task_header(thd) # And one more with wrong version thd = get_task_header("wrong version 2") thd.fixed_header.min_version = "42.0.44" tk.add_task_header(thd) reasons = tk.get_unsupport_reasons() # 3 tasks with wrong version self.assertIn( { 'avg': golem.__version__, 'reason': 'app_version', 'ntasks': 3 }, reasons) # 2 tasks with wrong price self.assertIn({'avg': 7, 'reason': 'max_price', 'ntasks': 2}, reasons) # 1 task with wrong environment self.assertIn( { 'avg': None, 'reason': 'environment_missing', 'ntasks': 1 }, reasons) self.assertIn( { 'avg': None, 'reason': 'environment_not_accepting_tasks', 'ntasks': 1 }, reasons)