示例#1
0
    def query_extra_data(self, perf_index, num_cores=1, node_id=None, node_name=None):
        """Returns data for the next subtask.
        :param int perf_index:
        :param int num_cores:
        :param str | None node_id:
        :param str | None node_name:
        :rtype: ComputeTaskDef"""

        # create new subtask_id
        subtask_id = uuid.uuid4().get_hex()

        with self._lock:
            # check if a task has been assigned to this node
            if node_id in self.assigned_nodes:
                return self.ExtraData(should_wait=True)
            # assign a task
            self.assigned_nodes[node_id] = subtask_id
            self.assigned_subtasks[subtask_id] = node_id

        # create subtask-specific data, 4 bits go for one char (hex digit)
        data = random.getrandbits(self.task_params.subtask_data_size * 4)
        self.subtask_ids.append(subtask_id)
        self.subtask_data[subtask_id] = '%x' % data

        subtask_def = ComputeTaskDef()
        subtask_def.task_id = self.task_id
        subtask_def.subtask_id = subtask_id
        subtask_def.src_code = self.src_code
        subtask_def.task_owner = self.header.task_owner
        subtask_def.environment = self.header.environment
        subtask_def.return_address = self.header.task_owner_address
        subtask_def.return_port = self.header.task_owner_port
        subtask_def.deadline = timeout_to_deadline(5 * 60)
        subtask_def.extra_data = {
            'data_file': self.shared_data_file,
            'subtask_data': self.subtask_data[subtask_id],
            'difficulty': self.task_params.difficulty,
            'result_size': self.task_params.result_size,
            'result_file': 'result.' + subtask_id[0:6]
        }

        return self.ExtraData(ctd=subtask_def)
示例#2
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()
示例#3
0
    def test_computation(self):
        task_server = mock.MagicMock()
        task_server.get_task_computer_root.return_value = self.path
        task_server.config_desc = config_desc()
        tc = TaskComputer("ABC", task_server, use_docker_machine_manager=False)

        ctd = ComputeTaskDef()
        ctd.task_id = "xyz"
        ctd.subtask_id = "xxyyzz"
        ctd.return_address = "10.10.10.10"
        ctd.return_port = 10203
        ctd.key_id = "key"
        ctd.task_owner = "owner"
        ctd.src_code = "cnt=0\nfor i in range(10000):\n\tcnt += 1\noutput={'data': cnt, 'result_type': 0}"
        ctd.extra_data = {}
        ctd.short_description = "add cnt"
        ctd.deadline = timeout_to_deadline(10)
        self.assertEqual(len(tc.assigned_subtasks), 0)
        tc.task_given(ctd)
        self.assertEqual(tc.assigned_subtasks["xxyyzz"], ctd)
        self.assertLessEqual(tc.assigned_subtasks["xxyyzz"].deadline,
                             timeout_to_deadline(10))
        self.assertEqual(tc.task_to_subtask_mapping["xyz"], "xxyyzz")
        tc.task_server.request_resource.assert_called_with(
            "xyz", tc.resource_manager.get_resource_header("xyz"),
            "10.10.10.10", 10203, "key", "owner")
        assert tc.task_resource_collected("xyz")
        tc.task_server.unpack_delta.assert_called_with(
            tc.dir_manager.get_task_resource_dir("xyz"), None, "xyz")
        assert len(tc.current_computations) == 0
        assert tc.assigned_subtasks.get("xxyyzz") is None
        task_server.send_task_failed.assert_called_with(
            "xxyyzz", "xyz", "Host direct task not supported", "10.10.10.10",
            10203, "key", "owner", "ABC")

        tc.support_direct_computation = True
        tc.task_given(ctd)
        assert tc.task_resource_collected("xyz")
        assert not tc.waiting_for_task
        assert len(tc.current_computations) == 1
        self.__wait_for_tasks(tc)

        prev_task_failed_count = task_server.send_task_failed.call_count
        self.assertFalse(tc.counting_task)
        self.assertEqual(len(tc.current_computations), 0)
        self.assertIsNone(tc.assigned_subtasks.get("xxyyzz"))
        assert task_server.send_task_failed.call_count == prev_task_failed_count
        self.assertTrue(task_server.send_results.called)
        args = task_server.send_results.call_args[0]
        self.assertEqual(args[0], "xxyyzz")
        self.assertEqual(args[1], "xyz")
        self.assertEqual(args[2]["data"], 10000)
        self.assertGreater(args[3], 0)
        self.assertLess(args[3], 10)
        self.assertEqual(args[4], "10.10.10.10")
        self.assertEqual(args[5], 10203)
        self.assertEqual(args[6], "key")
        self.assertEqual(args[7], "owner")
        self.assertEqual(args[8], "ABC")

        ctd.subtask_id = "aabbcc"
        ctd.src_code = "raise Exception('some exception')"
        ctd.deadline = timeout_to_deadline(5)
        tc.task_given(ctd)
        self.assertEqual(tc.assigned_subtasks["aabbcc"], ctd)
        self.assertLessEqual(tc.assigned_subtasks["aabbcc"].deadline,
                             timeout_to_deadline(5))
        self.assertEqual(tc.task_to_subtask_mapping["xyz"], "aabbcc")
        tc.task_server.request_resource.assert_called_with(
            "xyz", tc.resource_manager.get_resource_header("xyz"),
            "10.10.10.10", 10203, "key", "owner")
        self.assertTrue(tc.task_resource_collected("xyz"))
        self.__wait_for_tasks(tc)

        self.assertFalse(tc.counting_task)
        self.assertEqual(len(tc.current_computations), 0)
        self.assertIsNone(tc.assigned_subtasks.get("aabbcc"))
        task_server.send_task_failed.assert_called_with(
            "aabbcc", "xyz", 'some exception', "10.10.10.10", 10203, "key",
            "owner", "ABC")

        ctd.subtask_id = "aabbcc2"
        ctd.src_code = "print 'Hello world'"
        ctd.timeout = timeout_to_deadline(5)
        tc.task_given(ctd)
        self.assertTrue(tc.task_resource_collected("xyz"))
        self.__wait_for_tasks(tc)

        task_server.send_task_failed.assert_called_with(
            "aabbcc2", "xyz", "Wrong result format", "10.10.10.10", 10203,
            "key", "owner", "ABC")

        ctd.subtask_id = "xxyyzz2"
        ctd.timeout = timeout_to_deadline(1)
        tc.task_given(ctd)
        self.assertTrue(tc.task_resource_collected("xyz"))
        tt = tc.current_computations[0]
        tc.task_computed(tc.current_computations[0])
        self.assertEqual(len(tc.current_computations), 0)
        task_server.send_task_failed.assert_called_with(
            "xxyyzz2", "xyz", "Wrong result format", "10.10.10.10", 10203,
            "key", "owner", "ABC")
        tt.end_comp()
        time.sleep(0.5)
        if tt.is_alive():
            tt.join(timeout=5)