def get_dict_task_header(key_id_seed="kkk"): key_id = str.encode(key_id_seed) return { 'fixed_header': { "task_id": idgenerator.generate_id(key_id), "task_owner": { "node_name": "Bob's node", "key": encode_hex(key_id)[2:], "pub_addr": "10.10.10.10", "pub_port": 10101 }, "environment": "DEFAULT", "last_checking": time.time(), "deadline": timeout_to_deadline(1201), "subtask_timeout": 120, "max_price": 10, "min_version": golem.__version__, "resource_size": 0, "estimated_memory": 0, }, 'mask': { 'byte_repr': Mask().to_bytes() }, 'timestamp': 0, 'signature': None }
def from_dict(dictionary: dict) -> 'TaskHeader': th: TaskHeader = DictSerializer.load(dictionary, as_class=TaskHeader) if isinstance(th.fixed_header, dict): th.fixed_header = TaskFixedHeader.from_dict(th.fixed_header) if isinstance(th.mask, dict): th.mask = Mask.from_dict(th.mask) return th
def __init__(self, mask: Optional[Mask] = None, timestamp: Optional[float] = None, signature: Optional[bytes] = None, *args, **kwargs) -> None: self.fixed_header = TaskFixedHeader(*args, **kwargs) self.mask = mask or Mask() self.timestamp = timestamp or get_timestamp_utc() self.signature = signature
def get_example_task_header(key_id): return { "fixed_header": { "task_id": idgenerator.generate_id(key_id), "environment": "DEFAULT", "task_owner": dict(key=encode_hex(key_id)[2:], node_name="ABC", prv_port=40103, prv_addr='10.0.0.10', pub_port=40103, pub_addr='1.2.3.4'), "deadline": timeout_to_deadline(1201), "subtask_timeout": 120, "max_price": 20, "resource_size": 2 * 1024, "estimated_memory": 3 * 1024, "signature": None, "min_version": golem.__version__, "subtasks_count": 21, "concent_enabled": False, }, "mask": { "byte_repr": Mask().to_bytes() }, "timestamp": 0, }
def test_increase(self): mask = Mask() for i in range(Mask.MASK_LEN): self.assertEqual(mask.num_bits, i) mask.increase()
def _check(num_subtasks, exp_num_bits): mask = Mask.get_mask_for_task(num_subtasks, self.NETWORK_SIZE) self.assertEqual(mask.num_bits, exp_num_bits)
def _check(num_bits, exp_num_nodes): mask = Mask.generate(num_bits) avg_nodes = sum( sum(mask.matches(addr) for addr in self._get_test_network()) for _ in range(1000)) / 1000 self.assertAlmostEqual(avg_nodes, exp_num_nodes, delta=1)
def test_decrease_below_limit(self): mask = Mask(b'\xff' * Mask.MASK_BYTES) with self.assertRaises(ValueError): mask.decrease(-1)
def test_get_mask_for_task_zero_network_size(self): mask = Mask.get_mask_for_task(10, 0) self.assertEqual(mask.num_bits, 0)
def test_decrease(self): mask = Mask(b'\xff' * Mask.MASK_BYTES) for i in range(Mask.MASK_LEN): self.assertEqual(mask.num_bits, Mask.MASK_LEN - i) mask.decrease()
def test_decrease_above_limit(self): mask = Mask(b'\xff' * Mask.MASK_BYTES) mask.decrease(Mask.MASK_LEN + 1) self.assertEqual(mask.num_bits, 0)
def test_increase_above_limit(self): mask = Mask() mask.increase(Mask.MASK_LEN + 1) self.assertEqual(mask.num_bits, Mask.MASK_LEN)
def test_increase_below_limit(self): mask = Mask() with self.assertRaises(ValueError): mask.increase(-1)
def test_to_int(self, random): random.sample.return_value = range(8) self.assertEqual(Mask.generate(8).to_int(), 255) random.sample.return_value = [10] self.assertEqual(Mask.generate(1).to_int(), 1024)
def test_should_accept_provider(self, *_): # given ts = self.ts task = get_mock_task() node_id = "0xdeadbeef" node_name = "deadbeef" task_id = task.header.task_id ts.task_manager.tasks[task_id] = task task.should_accept_client.return_value = AcceptClientVerdict.ACCEPTED min_accepted_perf = 77 env = Mock() env.get_min_accepted_performance.return_value = min_accepted_perf ts.get_environment_by_id = Mock(return_value=env) node_name_id = node_info_str(node_name, node_id) ids = 'provider={}, task_id={}'.format(node_name_id, task_id) def _assert_log_msg(logger_mock, msg): self.assertEqual(len(logger_mock.output), 1) self.assertEqual(logger_mock.output[0].strip(), msg) # then with self.assertLogs(logger, level='INFO') as cm: assert not ts.should_accept_provider(node_id, node_name, 'tid', 27.18, 1, 1, 7) _assert_log_msg( cm, f'INFO:{logger.name}:Cannot find task in my tasks: ' f'provider={node_name_id}, task_id=tid') with self.assertLogs(logger, level='INFO') as cm: assert not ts.should_accept_provider(node_id, node_name, task_id, 27.18, 1, 1, 7) _assert_log_msg( cm, f'INFO:{logger.name}:insufficient provider performance: ' f'27.18 < {min_accepted_perf}; {ids}') with self.assertLogs(logger, level='INFO') as cm: assert not ts.should_accept_provider(node_id, node_name, task_id, 99, 1.72, 1, 4) _assert_log_msg( cm, f'INFO:{logger.name}:insufficient provider disk size:' f' 1.72 KiB; {ids}') with self.assertLogs(logger, level='INFO') as cm: assert not ts.should_accept_provider(node_id, node_name, task_id, 999, 3, 2.7, 1) _assert_log_msg( cm, f'INFO:{logger.name}:insufficient provider memory size:' f' 2.7 KiB; {ids}') # given self.client.get_computing_trust = Mock(return_value=0.4) ts.config_desc.computing_trust = 0.2 # then assert ts.should_accept_provider(node_id, node_name, task_id, 99, 3, 4, 5) # given ts.config_desc.computing_trust = 0.4 # then assert ts.should_accept_provider(node_id, node_name, task_id, 99, 3, 4, 5) # given ts.config_desc.computing_trust = 0.5 # then with self.assertLogs(logger, level='INFO') as cm: assert not ts.should_accept_provider(node_id, node_name, task_id, 99, 3, 4, 5) _assert_log_msg( cm, f'INFO:{logger.name}:insufficient provider trust level:' f' 0.4; {ids}') # given ts.config_desc.computing_trust = 0.2 # then assert ts.should_accept_provider(node_id, node_name, task_id, 99, 3, 4, 5) task.header.mask = Mask(b'\xff' * Mask.MASK_BYTES) with self.assertLogs(logger, level='INFO') as cm: assert not ts.should_accept_provider(node_id, node_name, task_id, 99, 3, 4, 5) _assert_log_msg( cm, f'INFO:{logger.name}:network mask mismatch: {ids}') # given task.header.mask = Mask() task.should_accept_client.return_value = AcceptClientVerdict.REJECTED # then with self.assertLogs(logger, level='INFO') as cm: assert not ts.should_accept_provider(node_id, node_name, task_id, 99, 3, 4, 5) _assert_log_msg( cm, f'INFO:{logger.name}:provider {node_id}' f' is not allowed for this task at this moment ' f'(either waiting for results or previously failed)') # given task.header.mask = Mask() ts.acl.disallow(node_id) # then with self.assertLogs(logger, level='INFO') as cm: assert not ts.should_accept_provider(node_id, node_name, task_id, 99, 3, 4, 5) _assert_log_msg( cm, f'INFO:{logger.name}:provider node is blacklisted; {ids}')
def test_to_bytes(self, random): random.sample.return_value = range(8) self.assertEqual(Mask.generate(8).to_bytes(), b'\x00\x00\x00\xff') random.sample.return_value = [10] self.assertEqual(Mask.generate(1).to_bytes(), b'\x00\x00\x04\x00')
def test_to_bin(self): for i in range(Mask.MASK_LEN): bin_repr = Mask.generate(i).to_bin() bits_num = sum(x == '1' for x in bin_repr) self.assertEqual(bits_num, i)
def test_bits_num(self): for i in range(Mask.MASK_LEN): mask = Mask.generate(num_bits=i) self.assertEqual(mask.num_bits, i)
def test_generate_num_bits_above_limit(self): mask = Mask.generate(num_bits=Mask.MASK_LEN + 1) self.assertEqual(mask.num_bits, Mask.MASK_LEN)
def test_generate_negative_bits_num(self): with self.assertRaises(ValueError): Mask.generate(num_bits=-1)