Example #1
0
    def _create_client(self, task_id, postfix):
        directory = os.path.join(self.tempdir, 'node' + postfix)
        dir_manager = DirManager(directory)

        cls = self._resource_manager_class
        resource_manager = cls.__new__(cls)
        resource_manager.__init__(dir_manager)

        database = Database(
            db,
            fields=DB_FIELDS,
            models=DB_MODELS,
            db_dir=directory)

        with mock.patch('golem.client.node_info_str'):
            client = Client(datadir=dir_manager.root_path,
                            app_config=mock.Mock(),
                            config_desc=ClientConfigDescriptor(),
                            keys_auth=mock.Mock(),
                            database=database,
                            transaction_system=mock.Mock(),
                            connect_to_known_hosts=False,
                            use_docker_manager=False,
                            use_monitor=False)

        client.resource_server = BaseResourceServer(resource_manager,
                                                    dir_manager,
                                                    mock.Mock(), client)
        with mock.patch(
                "golem.network.concent.handlers_library"
                ".HandlersLibrary"
                ".register_handler"):
            client.task_server = TaskServer(
                node=Node(prv_addr='127.0.0.1', hyperdrive_prv_port=3282),
                config_desc=mock.Mock(),
                client=client,
                use_docker_manager=False,
            )

        client.start = mock.Mock()
        client.start_network = mock.Mock()
        client.task_server.sync_network = mock.Mock()
        client.task_server.start_accepting = mock.Mock()
        client.task_server.task_computer = mock.Mock()

        get_peer = mock.Mock(return_value=mock.Mock(host='127.0.0.1',
                                                    port='3282'))
        transport = mock.Mock(getPeer=get_peer)

        task_session = TaskSession(mock.Mock(server=client.task_server,
                                             transport=transport))
        task_session.task_id = task_id

        resource_dir = resource_manager.storage.get_dir(task_id)
        return client, resource_dir, task_session
Example #2
0
    def test_decrypt(self):
        ts = TaskSession(Mock())
        data = "ABC"

        res = ts.decrypt(data)
        ts.task_server.decrypt.assert_called_with(data)
        self.assertIsNotNone(res)

        ts.task_server.decrypt = Mock(
            side_effect=AssertionError("Encrypt error"))
        with self.assertLogs(logger, level=1) as l:
            res = ts.decrypt(data)
        self.assertTrue(
            any("maybe it's not encrypted?" in log for log in l.output))
        self.assertFalse(any("Encrypt error" in log for log in l.output))
        self.assertEqual(res, data)

        ts.task_server.decrypt = Mock(
            side_effect=ValueError("Different error"))
        with self.assertLogs(logger, level=1) as l:
            res = ts.decrypt(data)
        self.assertTrue(any("Different error" in log for log in l.output))
        self.assertIsNone(res)

        ts.task_server = None
        data = "ABC"
        with self.assertLogs(logger, level=1):
            self.assertEqual(ts.encrypt(data), data)
Example #3
0
    def test_react_to_task_result_hash(self):
        def create_pull_package(result):
            def pull_package(multihash, task_id, subtask_id, secret, success,
                             error, *args, **kwargs):
                if result:
                    success(Mock())
                else:
                    error(Exception('Pull failed'))

            return pull_package

        conn = Mock()
        ts = TaskSession(conn)
        ts.result_received = Mock()
        ts.task_manager.subtask2task_mapping = dict()

        subtask_id = 'xxyyzz'
        secret = 'pass'
        multihash = 'multihash'

        ts.task_manager.subtask2task_mapping[subtask_id] = 'xyz'

        msg = MessageTaskResultHash(subtask_id=subtask_id,
                                    secret=secret,
                                    multihash=multihash,
                                    options=Mock())

        ts.task_manager.task_result_manager.pull_package = create_pull_package(
            True)
        ts._react_to_task_result_hash(msg)
        assert ts.result_received.called

        ts.task_manager.task_result_manager.pull_package = create_pull_package(
            False)
        ts._react_to_task_result_hash(msg)
        assert ts.task_server.reject_result.called
        assert ts.task_manager.task_computation_failure.called

        msg.subtask_id = "UNKNOWN"
        with self.assertLogs(logger, level="ERROR"):
            ts._react_to_task_result_hash(msg)
Example #4
0
    def test_encrypt(self):
        ts = TaskSession(Mock())
        data = "ABC"

        ts.key_id = "123"
        res = ts.encrypt(data)
        ts.task_server.encrypt.assert_called_with(data, "123")

        ts.task_server = None
        with self.assertLogs(logger, level=1):
            self.assertEqual(ts.encrypt(data), data)
Example #5
0
    def test_verify(self):
        keys_auth = EllipticalKeysAuth(self.path)
        conn = Mock()
        ts = TaskSession(conn)
        ts.task_server = Mock()
        ts.task_server.verify_sig = keys_auth.verify

        msg = message.MessageRemoveTask()
        assert not ts.verify(msg)
        msg.sig = keys_auth.sign(msg.get_short_hash())
        ts.key_id = keys_auth.get_key_id()
        assert ts.verify(msg)
Example #6
0
    def test_get_resource(self):
        conn = BasicProtocol()
        conn.transport = Mock()
        conn.server = Mock()

        db = DataBuffer()

        sess = TaskSession(conn)
        sess.send = lambda m: db.append_string(m.serialize())
        sess._can_send = lambda *_: True
        sess.request_resource(str(uuid.uuid4()), TaskResourceHeader("tmp"))

        assert Message.deserialize_message(db.buffered_data)
Example #7
0
    def setUp(self):
        conn = Mock()
        ts = TaskSession(conn)
        ts.dropped = Mock()
        ts.result_received = Mock()
        ts.send = Mock()
        ts.task_manager = Mock()

        subtask_id = 'xxyyzz'

        res = Mock()
        res.subtask_id = subtask_id
        ts.task_server.get_waiting_task_result.return_value = res

        msg = MessageGetTaskResult(subtask_id=subtask_id)

        self.subtask_id = subtask_id
        self.ts = ts
        self.msg = msg
Example #8
0
 def setUp(self):
     super(TestTaskSession, self).setUp()
     random.seed()
     self.task_session = TaskSession(Mock())
Example #9
0
 def test_new_connection(self, *_):
     ts = self.ts
     tss = TaskSession(Mock())
     ts.new_connection(tss)
     assert len(ts.task_sessions_incoming) == 1
     assert ts.task_sessions_incoming.pop() == tss
Example #10
0
class TestTaskSession(LogTestCase, TempDirFixture, PEP8MixIn):
    PEP8_FILES = [
        'golem/task/tasksession.py',
    ]

    def setUp(self):
        super(TestTaskSession, self).setUp()
        random.seed()
        self.task_session = TaskSession(Mock())

    @patch('golem.task.tasksession.TaskSession.send')
    def test_hello(self, send_mock):
        self.task_session.conn.server.get_key_id.return_value = key_id = 'key id%d' % (
            random.random() * 1000, )
        self.task_session.send_hello()
        expected = {
            u'CHALLENGE': None,
            u'CLIENT_KEY_ID': key_id,
            u'CLI_VER': 0,
            u'DIFFICULTY': 0,
            u'METADATA': None,
            u'NODE_INFO': None,
            u'NODE_NAME': None,
            u'PORT': 0,
            u'PROTO_ID': TASK_PROTOCOL_ID,
            u'RAND_VAL': self.task_session.rand_val,
            u'SOLVE_CHALLENGE': False,
        }
        msg = send_mock.call_args[0][0]
        self.assertEquals(msg.dict_repr(), expected)

    def test_encrypt(self):
        ts = TaskSession(Mock())
        data = "ABC"

        ts.key_id = "123"
        res = ts.encrypt(data)
        ts.task_server.encrypt.assert_called_with(data, "123")

        ts.task_server = None
        with self.assertLogs(logger, level=1):
            self.assertEqual(ts.encrypt(data), data)

    def test_decrypt(self):
        ts = TaskSession(Mock())
        data = "ABC"

        res = ts.decrypt(data)
        ts.task_server.decrypt.assert_called_with(data)
        self.assertIsNotNone(res)

        ts.task_server.decrypt = Mock(
            side_effect=AssertionError("Encrypt error"))
        with self.assertLogs(logger, level=1) as l:
            res = ts.decrypt(data)
        self.assertTrue(
            any("maybe it's not encrypted?" in log for log in l.output))
        self.assertFalse(any("Encrypt error" in log for log in l.output))
        self.assertEqual(res, data)

        ts.task_server.decrypt = Mock(
            side_effect=ValueError("Different error"))
        with self.assertLogs(logger, level=1) as l:
            res = ts.decrypt(data)
        self.assertTrue(any("Different error" in log for log in l.output))
        self.assertIsNone(res)

        ts.task_server = None
        data = "ABC"
        with self.assertLogs(logger, level=1):
            self.assertEqual(ts.encrypt(data), data)

    def test_request_task(self):
        ts = TaskSession(Mock())
        ts.verified = True
        ts.request_task("ABC", "xyz", 1030, 30, 3, 1, 8)
        mt = ts.conn.send_message.call_args[0][0]
        self.assertIsInstance(mt, MessageWantToComputeTask)
        self.assertEqual(mt.node_name, "ABC")
        self.assertEqual(mt.task_id, "xyz")
        self.assertEqual(mt.perf_index, 1030)
        self.assertEqual(mt.price, 30)
        self.assertEqual(mt.max_resource_size, 3)
        self.assertEqual(mt.max_memory_size, 1)
        self.assertEqual(mt.num_cores, 8)
        ts2 = TaskSession(Mock())
        ts2.verified = True
        ts2.key_id = "DEF"
        ts2.can_be_not_encrypted.append(mt.TYPE)
        ts2.can_be_unsigned.append(mt.TYPE)
        ts2.task_server.should_accept_provider.return_value = False
        ts2.task_server.config_desc.max_price = 100
        ts2.task_manager.get_next_subtask.return_value = ("CTD", False, False)
        ts2.interpret(mt)
        ms = ts2.conn.send_message.call_args[0][0]
        self.assertIsInstance(ms, MessageCannotAssignTask)
        self.assertEqual(ms.task_id, mt.task_id)
        ts2.task_server.should_accept_provider.return_value = True
        ts2.interpret(mt)
        ms = ts2.conn.send_message.call_args[0][0]
        self.assertIsInstance(ms, MessageTaskToCompute)
        ts2.task_manager.get_next_subtask.return_value = ("CTD", True, False)
        ts2.interpret(mt)
        ms = ts2.conn.send_message.call_args[0][0]
        self.assertIsInstance(ms, MessageCannotAssignTask)
        self.assertEqual(ms.task_id, mt.task_id)
        ts2.task_manager.get_node_id_for_subtask.return_value = "DEF"
        ts2._react_to_cannot_compute_task(MessageCannotComputeTask("CTD"))
        assert ts2.task_manager.task_computation_failure.called
        ts2.task_manager.task_computation_failure.called = False
        ts2.task_manager.get_node_id_for_subtask.return_value = "___"
        ts2._react_to_cannot_compute_task(MessageCannotComputeTask("CTD"))
        assert not ts2.task_manager.task_computation_failure.called

    def test_send_report_computed_task(self):
        ts = TaskSession(Mock())
        ts.verified = True
        ts.task_server.get_node_name.return_value = "ABC"
        n = Node()
        wtr = WaitingTaskResult("xyz", "xxyyzz", "result",
                                result_types["data"], 13190, 10, 0,
                                "10.10.10.10", 30102, "key1", n)

        ts.send_report_computed_task(wtr, "10.10.10.10", 30102, "0x00", n)
        ms = ts.conn.send_message.call_args[0][0]
        self.assertIsInstance(ms, MessageReportComputedTask)
        self.assertEqual(ms.subtask_id, "xxyyzz")
        self.assertEqual(ms.result_type, 0)
        self.assertEqual(ms.computation_time, 13190)
        self.assertEqual(ms.node_name, "ABC")
        self.assertEqual(ms.address, "10.10.10.10")
        self.assertEqual(ms.port, 30102)
        self.assertEqual(ms.eth_account, "0x00")
        self.assertEqual(ms.extra_data, [])
        self.assertEqual(ms.node_info, n)
        ts2 = TaskSession(Mock())
        ts2.verified = True
        ts2.key_id = "DEF"
        ts2.can_be_not_encrypted.append(ms.TYPE)
        ts2.can_be_unsigned.append(ms.TYPE)
        ts2.task_manager.subtask2task_mapping = {"xxyyzz": "xyz"}
        ts2.interpret(ms)
        ts2.task_server.receive_subtask_computation_time.assert_called_with(
            "xxyyzz", 13190)
        wtr.result_type = "UNKNOWN"
        with self.assertLogs(logger, level="ERROR"):
            ts.send_report_computed_task(wtr, "10.10.10.10", 30102, "0x00", n)

    def test_react_to_hello(self):
        conn = MagicMock()

        node = Node(node_name='node', key='ffffffff')
        keys_auth = KeysAuth(self.path)
        keys_auth.key = node.key
        keys_auth.key_id = node.key

        ts = TaskSession(conn)
        ts.task_server = Mock()
        ts.disconnect = Mock()
        ts.send = Mock()

        def create_verify(value):
            def verify(*args):
                return value

            return verify

        key_id = 'deadbeef'
        peer_info = MagicMock()
        peer_info.key = key_id
        msg = MessageHello(port=1,
                           node_name='node2',
                           client_key_id=key_id,
                           node_info=peer_info,
                           proto_id=-1)

        ts.verify = create_verify(False)
        ts._react_to_hello(msg)
        ts.disconnect.assert_called_with(TaskSession.DCRUnverified)

        ts.verify = create_verify(True)
        ts._react_to_hello(msg)
        ts.disconnect.assert_called_with(TaskSession.DCRProtocolVersion)

        msg.proto_id = TASK_PROTOCOL_ID

        ts._react_to_hello(msg)
        assert ts.send.called

    def test_result_received(self):
        conn = Mock()
        ts = TaskSession(conn)
        ts.task_server = Mock()
        ts.task_manager = Mock()
        ts.task_manager.verify_subtask.return_value = True

        extra_data = dict(
            # the result is explicitly serialized using cPickle
            result=cPickle.dumps({'stdout': 'xyz'}),
            result_type=None,
            subtask_id='xxyyzz')

        ts.result_received(extra_data, decrypt=False)

        assert ts.msgs_to_send
        assert isinstance(ts.msgs_to_send[0], MessageSubtaskResultRejected)
        assert conn.close.called

        extra_data.update(dict(result_type=result_types['data'], ))
        conn.close.called = False
        ts.msgs_to_send = []

        ts.result_received(extra_data, decrypt=False)

        assert ts.msgs_to_send
        assert ts.msgs_to_send[0].__class__ == MessageSubtaskResultAccepted
        assert conn.close.called

        extra_data.update(dict(subtask_id=None, ))
        conn.close.called = False
        ts.msgs_to_send = []

        ts.result_received(extra_data, decrypt=False)

        assert not ts.msgs_to_send
        assert conn.close.called

    def test_react_to_task_result_hash(self):
        def create_pull_package(result):
            def pull_package(multihash, task_id, subtask_id, secret, success,
                             error, *args, **kwargs):
                if result:
                    success(Mock())
                else:
                    error(Exception('Pull failed'))

            return pull_package

        conn = Mock()
        ts = TaskSession(conn)
        ts.result_received = Mock()
        ts.task_manager.subtask2task_mapping = dict()

        subtask_id = 'xxyyzz'
        secret = 'pass'
        multihash = 'multihash'

        ts.task_manager.subtask2task_mapping[subtask_id] = 'xyz'

        msg = MessageTaskResultHash(subtask_id=subtask_id,
                                    secret=secret,
                                    multihash=multihash,
                                    options=Mock())

        ts.task_manager.task_result_manager.pull_package = create_pull_package(
            True)
        ts._react_to_task_result_hash(msg)
        assert ts.result_received.called

        ts.task_manager.task_result_manager.pull_package = create_pull_package(
            False)
        ts._react_to_task_result_hash(msg)
        assert ts.task_server.reject_result.called
        assert ts.task_manager.task_computation_failure.called

        msg.subtask_id = "UNKNOWN"
        with self.assertLogs(logger, level="ERROR"):
            ts._react_to_task_result_hash(msg)

    def test_react_to_task_to_compute(self):
        conn = Mock()
        ts = TaskSession(conn)
        ts.key_id = "KEY_ID"
        ts.task_manager = Mock()
        ts.task_computer = Mock()
        ts.task_server = Mock()
        ts.task_server.get_subtask_ttl.return_value = 31313

        env = Mock()
        env.docker_images = [DockerImage("dockerix/xii", tag="323")]
        env.allow_custom_main_program_file = False
        env.get_source_code.return_value = None
        ts.task_server.get_environment_by_id.return_value = env

        def __reset_mocks():
            ts.task_manager.reset_mock()
            ts.task_computer.reset_mock()
            conn.reset_mock()

        # msg.ctd is None -> failure
        msg = MessageTaskToCompute()
        with self.assertLogs(logger, level="WARNING"):
            ts._react_to_task_to_compute(msg)
        ts.task_manager.comp_task_keeper.receive_subtask.assert_not_called()
        ts.task_computer.session_closed.assert_called_with()
        assert conn.close.called

        # No source code in the local environment -> failure
        __reset_mocks()
        ctd = ComputeTaskDef()
        ctd.key_id = "KEY_ID"
        ctd.subtask_id = "SUBTASKID"
        ctd.task_owner = Node()
        ctd.task_owner.key = "KEY_ID"
        ctd.return_address = "10.10.10.10"
        ctd.return_port = 1112
        ctd.docker_images = [DockerImage("dockerix/xiii", tag="323")]
        msg = MessageTaskToCompute(ctd)
        ts._react_to_task_to_compute(msg)
        ts.task_manager.comp_task_keeper.receive_subtask.assert_not_called()
        ts.task_computer.session_closed.assert_called_with()
        assert conn.close.called

        # Source code from local environment -> proper execution
        __reset_mocks()
        env.get_source_code.return_value = "print 'Hello world'"
        ts._react_to_task_to_compute(msg)
        ts.task_manager.comp_task_keeper.receive_subtask.assert_called_with(
            ctd)
        ts.task_computer.session_closed.assert_not_called()
        ts.task_server.add_task_session.assert_called_with("SUBTASKID", ts)
        ts.task_computer.task_given.assert_called_with(ctd)
        conn.close.assert_not_called()

        # Wrong key id -> failure
        __reset_mocks()
        ctd.key_id = "KEY_ID2"
        ts._react_to_task_to_compute(MessageTaskToCompute(ctd))
        ts.task_manager.comp_task_keeper.receive_subtask.assert_not_called()
        ts.task_computer.session_closed.assert_called_with()
        assert conn.close.called

        # Wrong task owner key id -> failure
        __reset_mocks()
        ctd.key_id = "KEY_ID"
        ctd.task_owner.key = "KEY_ID2"
        ts._react_to_task_to_compute(MessageTaskToCompute(ctd))
        ts.task_manager.comp_task_keeper.receive_subtask.assert_not_called()
        ts.task_computer.session_closed.assert_called_with()
        assert conn.close.called

        # Wrong return port -> failure
        __reset_mocks()
        ctd.task_owner.key = "KEY_ID"
        ctd.return_port = 0
        ts._react_to_task_to_compute(MessageTaskToCompute(ctd))
        ts.task_manager.comp_task_keeper.receive_subtask.assert_not_called()
        ts.task_computer.session_closed.assert_called_with()
        assert conn.close.called

        # Proper port and key -> proper execution
        __reset_mocks()
        ctd.task_owner.key = "KEY_ID"
        ctd.return_port = 1319
        ts._react_to_task_to_compute(MessageTaskToCompute(ctd))
        conn.close.assert_not_called()

        # Allow custom code / no code in ComputeTaskDef -> failure
        __reset_mocks()
        env.allow_custom_main_program_file = True
        ctd.src_code = ""
        ts._react_to_task_to_compute(MessageTaskToCompute(ctd))
        ts.task_manager.comp_task_keeper.receive_subtask.assert_not_called()
        ts.task_computer.session_closed.assert_called_with()
        assert conn.close.called

        # Allow custom code / code in ComputerTaskDef -> proper execution
        __reset_mocks()
        ctd.src_code = "print 'Hello world!'"
        ts._react_to_task_to_compute(MessageTaskToCompute(ctd))
        ts.task_computer.session_closed.assert_not_called()
        ts.task_server.add_task_session.assert_called_with("SUBTASKID", ts)
        ts.task_computer.task_given.assert_called_with(ctd)
        conn.close.assert_not_called()

        # No environment available -> failure
        __reset_mocks()
        ts.task_server.get_environment_by_id.return_value = None
        ts._react_to_task_to_compute(MessageTaskToCompute(ctd))
        assert ts.err_msg.startswith("Wrong environment")
        ts.task_manager.comp_task_keeper.receive_subtask.assert_not_called()
        ts.task_computer.session_closed.assert_called_with()
        assert conn.close.called

        # Envrionment is Docker environment but with different images -> failure
        __reset_mocks()
        ts.task_server.get_environment_by_id.return_value = \
            DockerEnvironment([DockerImage("dockerix/xii", tag="323"),
                               DockerImage("dockerix/xiii", tag="325"),
                               DockerImage("dockerix/xiii")])
        ts._react_to_task_to_compute(MessageTaskToCompute(ctd))
        assert ts.err_msg.startswith("Wrong docker images")
        ts.task_manager.comp_task_keeper.receive_subtask.assert_not_called()
        ts.task_computer.session_closed.assert_called_with()
        assert conn.close.called

        # Envrionment is Docker environment with proper images, but no srouce code -> failure
        __reset_mocks()
        de = DockerEnvironment([
            DockerImage("dockerix/xii", tag="323"),
            DockerImage("dockerix/xiii", tag="325"),
            DockerImage("dockerix/xiii", tag="323")
        ])
        ts.task_server.get_environment_by_id.return_value = de
        ts._react_to_task_to_compute(MessageTaskToCompute(ctd))
        assert ts.err_msg.startswith("No source code")
        ts.task_manager.comp_task_keeper.receive_subtask.assert_not_called()
        ts.task_computer.session_closed.assert_called_with()
        assert conn.close.called

        # Proper Docker environment with source code
        __reset_mocks()
        file_name = os.path.join(self.path, "main_program_file")
        with open(file_name, 'w') as f:
            f.write("Hello world!")
        de.main_program_file = file_name
        ts._react_to_task_to_compute(MessageTaskToCompute(ctd))
        ts.task_server.add_task_session.assert_called_with("SUBTASKID", ts)
        ts.task_computer.task_given.assert_called_with(ctd)
        conn.close.assert_not_called()

    def test_get_resource(self):
        conn = BasicProtocol()
        conn.transport = Mock()
        conn.server = Mock()

        db = DataBuffer()

        sess = TaskSession(conn)
        sess.send = lambda m: db.append_string(m.serialize())
        sess._can_send = lambda *_: True
        sess.request_resource(str(uuid.uuid4()), TaskResourceHeader("tmp"))

        assert Message.deserialize_message(db.buffered_data)

    def test_verify(self):
        keys_auth = EllipticalKeysAuth(self.path)
        conn = Mock()
        ts = TaskSession(conn)
        ts.task_server = Mock()
        ts.task_server.verify_sig = keys_auth.verify

        msg = message.MessageRemoveTask()
        assert not ts.verify(msg)
        msg.sig = keys_auth.sign(msg.get_short_hash())
        ts.key_id = keys_auth.get_key_id()
        assert ts.verify(msg)
Example #11
0
    def test_result_received(self):
        conn = Mock()
        ts = TaskSession(conn)
        ts.task_server = Mock()
        ts.task_manager = Mock()
        ts.task_manager.verify_subtask.return_value = True

        extra_data = dict(
            # the result is explicitly serialized using cPickle
            result=cPickle.dumps({'stdout': 'xyz'}),
            result_type=None,
            subtask_id='xxyyzz')

        ts.result_received(extra_data, decrypt=False)

        assert ts.msgs_to_send
        assert isinstance(ts.msgs_to_send[0], MessageSubtaskResultRejected)
        assert conn.close.called

        extra_data.update(dict(result_type=result_types['data'], ))
        conn.close.called = False
        ts.msgs_to_send = []

        ts.result_received(extra_data, decrypt=False)

        assert ts.msgs_to_send
        assert ts.msgs_to_send[0].__class__ == MessageSubtaskResultAccepted
        assert conn.close.called

        extra_data.update(dict(subtask_id=None, ))
        conn.close.called = False
        ts.msgs_to_send = []

        ts.result_received(extra_data, decrypt=False)

        assert not ts.msgs_to_send
        assert conn.close.called
Example #12
0
    def test_react_to_hello(self):
        conn = MagicMock()

        node = Node(node_name='node', key='ffffffff')
        keys_auth = KeysAuth(self.path)
        keys_auth.key = node.key
        keys_auth.key_id = node.key

        ts = TaskSession(conn)
        ts.task_server = Mock()
        ts.disconnect = Mock()
        ts.send = Mock()

        def create_verify(value):
            def verify(*args):
                return value

            return verify

        key_id = 'deadbeef'
        peer_info = MagicMock()
        peer_info.key = key_id
        msg = MessageHello(port=1,
                           node_name='node2',
                           client_key_id=key_id,
                           node_info=peer_info,
                           proto_id=-1)

        ts.verify = create_verify(False)
        ts._react_to_hello(msg)
        ts.disconnect.assert_called_with(TaskSession.DCRUnverified)

        ts.verify = create_verify(True)
        ts._react_to_hello(msg)
        ts.disconnect.assert_called_with(TaskSession.DCRProtocolVersion)

        msg.proto_id = TASK_PROTOCOL_ID

        ts._react_to_hello(msg)
        assert ts.send.called
Example #13
0
    def test_send_report_computed_task(self):
        ts = TaskSession(Mock())
        ts.verified = True
        ts.task_server.get_node_name.return_value = "ABC"
        n = Node()
        wtr = WaitingTaskResult("xyz", "xxyyzz", "result",
                                result_types["data"], 13190, 10, 0,
                                "10.10.10.10", 30102, "key1", n)

        ts.send_report_computed_task(wtr, "10.10.10.10", 30102, "0x00", n)
        ms = ts.conn.send_message.call_args[0][0]
        self.assertIsInstance(ms, MessageReportComputedTask)
        self.assertEqual(ms.subtask_id, "xxyyzz")
        self.assertEqual(ms.result_type, 0)
        self.assertEqual(ms.computation_time, 13190)
        self.assertEqual(ms.node_name, "ABC")
        self.assertEqual(ms.address, "10.10.10.10")
        self.assertEqual(ms.port, 30102)
        self.assertEqual(ms.eth_account, "0x00")
        self.assertEqual(ms.extra_data, [])
        self.assertEqual(ms.node_info, n)
        ts2 = TaskSession(Mock())
        ts2.verified = True
        ts2.key_id = "DEF"
        ts2.can_be_not_encrypted.append(ms.TYPE)
        ts2.can_be_unsigned.append(ms.TYPE)
        ts2.task_manager.subtask2task_mapping = {"xxyyzz": "xyz"}
        ts2.interpret(ms)
        ts2.task_server.receive_subtask_computation_time.assert_called_with(
            "xxyyzz", 13190)
        wtr.result_type = "UNKNOWN"
        with self.assertLogs(logger, level="ERROR"):
            ts.send_report_computed_task(wtr, "10.10.10.10", 30102, "0x00", n)
Example #14
0
 def test_request_task(self):
     ts = TaskSession(Mock())
     ts.verified = True
     ts.request_task("ABC", "xyz", 1030, 30, 3, 1, 8)
     mt = ts.conn.send_message.call_args[0][0]
     self.assertIsInstance(mt, MessageWantToComputeTask)
     self.assertEqual(mt.node_name, "ABC")
     self.assertEqual(mt.task_id, "xyz")
     self.assertEqual(mt.perf_index, 1030)
     self.assertEqual(mt.price, 30)
     self.assertEqual(mt.max_resource_size, 3)
     self.assertEqual(mt.max_memory_size, 1)
     self.assertEqual(mt.num_cores, 8)
     ts2 = TaskSession(Mock())
     ts2.verified = True
     ts2.key_id = "DEF"
     ts2.can_be_not_encrypted.append(mt.TYPE)
     ts2.can_be_unsigned.append(mt.TYPE)
     ts2.task_server.should_accept_provider.return_value = False
     ts2.task_server.config_desc.max_price = 100
     ts2.task_manager.get_next_subtask.return_value = ("CTD", False, False)
     ts2.interpret(mt)
     ms = ts2.conn.send_message.call_args[0][0]
     self.assertIsInstance(ms, MessageCannotAssignTask)
     self.assertEqual(ms.task_id, mt.task_id)
     ts2.task_server.should_accept_provider.return_value = True
     ts2.interpret(mt)
     ms = ts2.conn.send_message.call_args[0][0]
     self.assertIsInstance(ms, MessageTaskToCompute)
     ts2.task_manager.get_next_subtask.return_value = ("CTD", True, False)
     ts2.interpret(mt)
     ms = ts2.conn.send_message.call_args[0][0]
     self.assertIsInstance(ms, MessageCannotAssignTask)
     self.assertEqual(ms.task_id, mt.task_id)
     ts2.task_manager.get_node_id_for_subtask.return_value = "DEF"
     ts2._react_to_cannot_compute_task(MessageCannotComputeTask("CTD"))
     assert ts2.task_manager.task_computation_failure.called
     ts2.task_manager.task_computation_failure.called = False
     ts2.task_manager.get_node_id_for_subtask.return_value = "___"
     ts2._react_to_cannot_compute_task(MessageCannotComputeTask("CTD"))
     assert not ts2.task_manager.task_computation_failure.called
Example #15
0
class AddGetResources(TempDirFixture, LogTestCase):

    __test__ = False
    _resource_manager_class = None

    @staticmethod
    def _create_resources(resource_dir):

        resources_relative = [
            'resource_1',
            os.path.join('dir_1', 'resource_2'),
            os.path.join('dir_1', 'resource_3'),
            os.path.join('dir_2', 'subdir', 'resource_4')
        ]

        resources = [os.path.join(resource_dir, r) for r in resources_relative]

        for resource in resources:
            d = os.path.dirname(resource)
            if not os.path.exists(d):
                os.makedirs(d)

            with open(resource, 'wb') as f:
                f.write(str(uuid.uuid4()) * 256)

        return resources_relative, resources

    def setUp(self):
        TempDirFixture.setUp(self)

        self.task_id = str(uuid.uuid4())

        self.datadir_1 = os.path.join(self.path, 'node_1')
        self.datadir_2 = os.path.join(self.path, 'node_2')

        self.dir_manager_1 = DirManager(self.datadir_1)
        self.dir_manager_2 = DirManager(self.datadir_2)

        self.resource_manager_1 = self._resource_manager_class(
            self.dir_manager_1)
        self.resource_manager_2 = self._resource_manager_class(
            self.dir_manager_2)

        self.client_1 = Client(datadir=self.datadir_1,
                               connect_to_known_hosts=False,
                               use_docker_machine_manager=False,
                               use_monitor=False)
        self.client_2 = Client(datadir=self.datadir_2,
                               connect_to_known_hosts=False,
                               use_docker_machine_manager=False,
                               use_monitor=False)
        self.client_1.start = self.client_2.start = Mock()

        self.resource_server_1 = BaseResourceServer(self.resource_manager_1,
                                                    self.dir_manager_1, Mock(),
                                                    self.client_1)
        self.resource_server_2 = BaseResourceServer(self.resource_manager_2,
                                                    self.dir_manager_2, Mock(),
                                                    self.client_2)
        self.resource_server_1.client.resource_server = self.resource_server_1
        self.resource_server_2.client.resource_server = self.resource_server_2

        task_server_1 = TaskServer.__new__(TaskServer, Mock(), Mock(), Mock(),
                                           self.client_1)
        task_server_2 = TaskServer.__new__(TaskServer, Mock(), Mock(), Mock(),
                                           self.client_2)
        task_server_1.client = self.client_1
        task_server_2.client = self.client_2
        task_server_1.keys_auth = self.client_1.keys_auth
        task_server_2.keys_auth = self.client_2.keys_auth
        task_server_1.sync_network = task_server_2.sync_network = Mock()
        task_server_1.start_accepting = task_server_2.start_accepting = Mock()
        task_server_1.task_computer = task_server_2.task_computer = Mock()

        self.client_1.task_server = task_server_1
        self.client_2.task_server = task_server_2

        self.task_session_1 = TaskSession(Mock())
        self.task_session_2 = TaskSession(Mock())
        self.task_session_1.task_server = task_server_1
        self.task_session_2.task_server = task_server_2
        self.task_session_1.task_id = self.task_session_2.task_id = self.task_id

        self.resource_dir_1 = self.resource_manager_1.storage.get_dir(
            self.task_id)
        self.resource_dir_2 = self.resource_manager_2.storage.get_dir(
            self.task_id)

        client_options = self.resource_manager_1.build_client_options(
            task_server_1.get_key_id())

        self.resources_relative, self.resources = self._create_resources(
            self.resource_dir_1)
        self.resource_manager_1._add_task(self.resources,
                                          self.task_id,
                                          client_options=client_options)

    def tearDown(self):
        self.client_1.quit()
        self.client_2.quit()
        TempDirFixture.tearDown(self)

    def test(self):

        send_buf_1 = []
        send_buf_2 = []

        self.task_session_1.send = lambda x: send_buf_1.append(x)
        self.task_session_2.send = lambda x: send_buf_2.append(x)

        msg_get_resource = MessageGetResource(task_id=self.task_id)
        msg = MessageGetResource.deserialize_message(
            msg_get_resource.serialize())
        assert msg

        self.task_session_1._react_to_get_resource(msg)

        msg_resource_list = send_buf_1.pop()
        msg = MessageResourceList.deserialize_message(
            msg_resource_list.serialize())
        assert msg

        self.task_session_2._react_to_resource_list(msg)
        self.resource_server_2._download_resources(async=False)

        for r in self.resources_relative:
            location_1 = os.path.join(self.resource_dir_1, r)
            location_2 = os.path.join(self.resource_dir_2, r)

            assert os.path.exists(location_1)
            assert os.path.exists(location_2)

            sha_256_1 = file_sha_256(location_1)
            sha_256_2 = file_sha_256(location_2)
            assert sha_256_1 == sha_256_2, '{} != {}'.format(
                sha_256_1.encode('hex'), sha_256_2.encode('hex'))
Example #16
0
    def setUp(self):
        TempDirFixture.setUp(self)

        self.task_id = str(uuid.uuid4())

        self.datadir_1 = os.path.join(self.path, 'node_1')
        self.datadir_2 = os.path.join(self.path, 'node_2')

        self.dir_manager_1 = DirManager(self.datadir_1)
        self.dir_manager_2 = DirManager(self.datadir_2)

        self.resource_manager_1 = self._resource_manager_class(
            self.dir_manager_1)
        self.resource_manager_2 = self._resource_manager_class(
            self.dir_manager_2)

        self.client_1 = Client(datadir=self.datadir_1,
                               connect_to_known_hosts=False,
                               use_docker_machine_manager=False,
                               use_monitor=False)
        self.client_2 = Client(datadir=self.datadir_2,
                               connect_to_known_hosts=False,
                               use_docker_machine_manager=False,
                               use_monitor=False)
        self.client_1.start = self.client_2.start = Mock()

        self.resource_server_1 = BaseResourceServer(self.resource_manager_1,
                                                    self.dir_manager_1, Mock(),
                                                    self.client_1)
        self.resource_server_2 = BaseResourceServer(self.resource_manager_2,
                                                    self.dir_manager_2, Mock(),
                                                    self.client_2)
        self.resource_server_1.client.resource_server = self.resource_server_1
        self.resource_server_2.client.resource_server = self.resource_server_2

        task_server_1 = TaskServer.__new__(TaskServer, Mock(), Mock(), Mock(),
                                           self.client_1)
        task_server_2 = TaskServer.__new__(TaskServer, Mock(), Mock(), Mock(),
                                           self.client_2)
        task_server_1.client = self.client_1
        task_server_2.client = self.client_2
        task_server_1.keys_auth = self.client_1.keys_auth
        task_server_2.keys_auth = self.client_2.keys_auth
        task_server_1.sync_network = task_server_2.sync_network = Mock()
        task_server_1.start_accepting = task_server_2.start_accepting = Mock()
        task_server_1.task_computer = task_server_2.task_computer = Mock()

        self.client_1.task_server = task_server_1
        self.client_2.task_server = task_server_2

        self.task_session_1 = TaskSession(Mock())
        self.task_session_2 = TaskSession(Mock())
        self.task_session_1.task_server = task_server_1
        self.task_session_2.task_server = task_server_2
        self.task_session_1.task_id = self.task_session_2.task_id = self.task_id

        self.resource_dir_1 = self.resource_manager_1.storage.get_dir(
            self.task_id)
        self.resource_dir_2 = self.resource_manager_2.storage.get_dir(
            self.task_id)

        client_options = self.resource_manager_1.build_client_options(
            task_server_1.get_key_id())

        self.resources_relative, self.resources = self._create_resources(
            self.resource_dir_1)
        self.resource_manager_1._add_task(self.resources,
                                          self.task_id,
                                          client_options=client_options)
Example #17
0
    def test_react_to_task_to_compute(self):
        conn = Mock()
        ts = TaskSession(conn)
        ts.key_id = "KEY_ID"
        ts.task_manager = Mock()
        ts.task_computer = Mock()
        ts.task_server = Mock()
        ts.task_server.get_subtask_ttl.return_value = 31313

        env = Mock()
        env.docker_images = [DockerImage("dockerix/xii", tag="323")]
        env.allow_custom_main_program_file = False
        env.get_source_code.return_value = None
        ts.task_server.get_environment_by_id.return_value = env

        def __reset_mocks():
            ts.task_manager.reset_mock()
            ts.task_computer.reset_mock()
            conn.reset_mock()

        # msg.ctd is None -> failure
        msg = MessageTaskToCompute()
        with self.assertLogs(logger, level="WARNING"):
            ts._react_to_task_to_compute(msg)
        ts.task_manager.comp_task_keeper.receive_subtask.assert_not_called()
        ts.task_computer.session_closed.assert_called_with()
        assert conn.close.called

        # No source code in the local environment -> failure
        __reset_mocks()
        ctd = ComputeTaskDef()
        ctd.key_id = "KEY_ID"
        ctd.subtask_id = "SUBTASKID"
        ctd.task_owner = Node()
        ctd.task_owner.key = "KEY_ID"
        ctd.return_address = "10.10.10.10"
        ctd.return_port = 1112
        ctd.docker_images = [DockerImage("dockerix/xiii", tag="323")]
        msg = MessageTaskToCompute(ctd)
        ts._react_to_task_to_compute(msg)
        ts.task_manager.comp_task_keeper.receive_subtask.assert_not_called()
        ts.task_computer.session_closed.assert_called_with()
        assert conn.close.called

        # Source code from local environment -> proper execution
        __reset_mocks()
        env.get_source_code.return_value = "print 'Hello world'"
        ts._react_to_task_to_compute(msg)
        ts.task_manager.comp_task_keeper.receive_subtask.assert_called_with(
            ctd)
        ts.task_computer.session_closed.assert_not_called()
        ts.task_server.add_task_session.assert_called_with("SUBTASKID", ts)
        ts.task_computer.task_given.assert_called_with(ctd)
        conn.close.assert_not_called()

        # Wrong key id -> failure
        __reset_mocks()
        ctd.key_id = "KEY_ID2"
        ts._react_to_task_to_compute(MessageTaskToCompute(ctd))
        ts.task_manager.comp_task_keeper.receive_subtask.assert_not_called()
        ts.task_computer.session_closed.assert_called_with()
        assert conn.close.called

        # Wrong task owner key id -> failure
        __reset_mocks()
        ctd.key_id = "KEY_ID"
        ctd.task_owner.key = "KEY_ID2"
        ts._react_to_task_to_compute(MessageTaskToCompute(ctd))
        ts.task_manager.comp_task_keeper.receive_subtask.assert_not_called()
        ts.task_computer.session_closed.assert_called_with()
        assert conn.close.called

        # Wrong return port -> failure
        __reset_mocks()
        ctd.task_owner.key = "KEY_ID"
        ctd.return_port = 0
        ts._react_to_task_to_compute(MessageTaskToCompute(ctd))
        ts.task_manager.comp_task_keeper.receive_subtask.assert_not_called()
        ts.task_computer.session_closed.assert_called_with()
        assert conn.close.called

        # Proper port and key -> proper execution
        __reset_mocks()
        ctd.task_owner.key = "KEY_ID"
        ctd.return_port = 1319
        ts._react_to_task_to_compute(MessageTaskToCompute(ctd))
        conn.close.assert_not_called()

        # Allow custom code / no code in ComputeTaskDef -> failure
        __reset_mocks()
        env.allow_custom_main_program_file = True
        ctd.src_code = ""
        ts._react_to_task_to_compute(MessageTaskToCompute(ctd))
        ts.task_manager.comp_task_keeper.receive_subtask.assert_not_called()
        ts.task_computer.session_closed.assert_called_with()
        assert conn.close.called

        # Allow custom code / code in ComputerTaskDef -> proper execution
        __reset_mocks()
        ctd.src_code = "print 'Hello world!'"
        ts._react_to_task_to_compute(MessageTaskToCompute(ctd))
        ts.task_computer.session_closed.assert_not_called()
        ts.task_server.add_task_session.assert_called_with("SUBTASKID", ts)
        ts.task_computer.task_given.assert_called_with(ctd)
        conn.close.assert_not_called()

        # No environment available -> failure
        __reset_mocks()
        ts.task_server.get_environment_by_id.return_value = None
        ts._react_to_task_to_compute(MessageTaskToCompute(ctd))
        assert ts.err_msg.startswith("Wrong environment")
        ts.task_manager.comp_task_keeper.receive_subtask.assert_not_called()
        ts.task_computer.session_closed.assert_called_with()
        assert conn.close.called

        # Envrionment is Docker environment but with different images -> failure
        __reset_mocks()
        ts.task_server.get_environment_by_id.return_value = \
            DockerEnvironment([DockerImage("dockerix/xii", tag="323"),
                               DockerImage("dockerix/xiii", tag="325"),
                               DockerImage("dockerix/xiii")])
        ts._react_to_task_to_compute(MessageTaskToCompute(ctd))
        assert ts.err_msg.startswith("Wrong docker images")
        ts.task_manager.comp_task_keeper.receive_subtask.assert_not_called()
        ts.task_computer.session_closed.assert_called_with()
        assert conn.close.called

        # Envrionment is Docker environment with proper images, but no srouce code -> failure
        __reset_mocks()
        de = DockerEnvironment([
            DockerImage("dockerix/xii", tag="323"),
            DockerImage("dockerix/xiii", tag="325"),
            DockerImage("dockerix/xiii", tag="323")
        ])
        ts.task_server.get_environment_by_id.return_value = de
        ts._react_to_task_to_compute(MessageTaskToCompute(ctd))
        assert ts.err_msg.startswith("No source code")
        ts.task_manager.comp_task_keeper.receive_subtask.assert_not_called()
        ts.task_computer.session_closed.assert_called_with()
        assert conn.close.called

        # Proper Docker environment with source code
        __reset_mocks()
        file_name = os.path.join(self.path, "main_program_file")
        with open(file_name, 'w') as f:
            f.write("Hello world!")
        de.main_program_file = file_name
        ts._react_to_task_to_compute(MessageTaskToCompute(ctd))
        ts.task_server.add_task_session.assert_called_with("SUBTASKID", ts)
        ts.task_computer.task_given.assert_called_with(ctd)
        conn.close.assert_not_called()