Exemple #1
0
    def test_is_available_by_id(self):
        # img = DockerImage(self.TEST_REPOSITORY, image_id=self.TEST_IMAGE_ID)
        # self.assertTrue(img.is_available)
        # self._is_test_image(img)

        nimg = DockerImage(self.TEST_REPOSITORY, image_id="deadface")
        self.assertFalse(nimg.is_available())
Exemple #2
0
    def __init__(self, tag=BLENDER_DOCKER_TAG, image_id=None):
        image = DockerImage(image_id=id) if image_id \
            else DockerImage(self.BLENDER_DOCKER_IMAGE, tag=tag)
        DockerEnvironment.__init__(self, [image])

        self.short_description = "Blender (www.blender.org)"
        self.main_program_file = find_task_script(self.APP_DIR, self.SCRIPT_NAME)
Exemple #3
0
    def test_is_available_by_repo(self):
        # img = DockerImage(repository=self.TEST_REPOSITORY, tag=self.TEST_TAG)
        # self.assertTrue(img.is_available())
        # self.assertEqual(img.name, "{}:{}".format(self.TEST_REPOSITORY, self.TEST_TAG))

        nimg = DockerImage("imapp/xzy")
        self.assertFalse(nimg.is_available())
Exemple #4
0
    def test_is_available_by_id_and_tag(self):
        img = DockerImage(self.TEST_REPOSITORY, tag=self.TEST_TAG,
                          image_id=self.TEST_ENV_ID)
        self.assertTrue(img.is_available())

        nimg = DockerImage(self.TEST_REPOSITORY, tag="bogus",
                           image_id=self.TEST_ENV_ID)
        self.assertFalse(nimg.is_available())

        nimg2 = DockerImage(self.TEST_REPOSITORY, tag=self.TEST_TAG,
                            image_id="deadface")
        self.assertFalse(nimg2.is_available())
Exemple #5
0
 def test_wrong_image_repository_specified(self):
     task = self._create_test_task()
     task.header.docker_images = [DockerImage("%$#@!!!")]
     task_thread, error_msg, out_dir = self._run_docker_task(task)
     if task_thread:
         assert not task_thread.result
     assert isinstance(error_msg, str)
Exemple #6
0
    def __init__(self, subtask_id: str,  # pylint: disable=too-many-arguments
                 docker_images: List[Union[DockerImage, Dict, Tuple]],
                 src_code: str,
                 extra_data: Dict,
                 dir_mapping: DockerDirMapping,
                 timeout: int,
                 check_mem: bool = False) -> None:

        if not docker_images:
            raise AttributeError("docker images is None")
        super(DockerTaskThread, self).__init__(
            subtask_id=subtask_id,
            src_code=src_code,
            extra_data=extra_data,
            res_path=str(dir_mapping.resources),
            tmp_path=str(dir_mapping.temporary),
            timeout=timeout
        )

        # Find available image
        self.image = None
        logger.debug("Checking docker images %s", docker_images)
        for img in docker_images:
            img = DockerImage.build(img)
            if img.is_available():
                self.image = img
                break

        self.job: Optional[DockerJob] = None
        self.check_mem = check_mem
        self.dir_mapping = dir_mapping
Exemple #7
0
 def __init__(self) -> None:
     super().__init__(additional_images=[
         DockerImage(
             repository=BlenderEnvironment.DOCKER_IMAGE,
             tag=BlenderEnvironment.DOCKER_TAG,
         )
     ])
Exemple #8
0
 def test_wrong_image_repository_specified(self):
     task = self._get_test_task()
     task.docker_images = [DockerImage("%$#@!!!")]
     task_thread = self._run_task(task)
     if task_thread:
         self.assertFalse(task_thread.result)
     self.assertIsInstance(task_thread.error_msg, str)
     self.assertTrue(task_thread.error_msg)
 def test_docker_environment(self):
     with self.assertRaises(AttributeError):
         DockerEnvironment(None)
     de = DockerEnvironment(
         [DockerImage("golemfactory/blender", tag="1.3")])
     self.assertTrue(de.supported())
     self.assertTrue(de.description().startswith(
         'Default environment for generic tasks without any additional requirements.'
     ))
     self.assertTrue(de.check_docker_images())
    def test_docker_environment(self):
        with self.assertRaises(TypeError):
            DockerEnvironment(None)

        with self.assertRaises(RuntimeTypeError):
            DockerEnvironmentMock(additional_images=["aaa"])

        de = DockerEnvironmentMock(
            additional_images=[DockerImage("golemfactory/blender", tag="1.4")])
        self.assertTrue(de.check_support())
        self.assertTrue(de.check_docker_images())
Exemple #11
0
    def __init__(self,
                 tag=None,
                 image_id=None,
                 additional_images: List[DockerImage] = None):

        if tag is None:
            tag = self.DOCKER_TAG

        image = DockerImage(image_id=image_id) if image_id \
            else DockerImage(self.DOCKER_IMAGE, tag=tag)
        Environment.__init__(self)

        self.main_program_file = find_task_script(self.APP_DIR,
                                                  self.SCRIPT_NAME)

        self.docker_images = [image]
        if additional_images:
            self.docker_images += additional_images

        if self.SHORT_DESCRIPTION:
            self.short_description = self.SHORT_DESCRIPTION
Exemple #12
0
    def test_is_available_by_repo_and_tag(self):
        img = DockerImage(self.TEST_REPOSITORY, tag=self.TEST_TAG)
        self.assertTrue(img.is_available())
        self._is_test_image(img)

        nimg = DockerImage(self.TEST_REPOSITORY, tag="bogus")
        self.assertFalse(nimg.is_available())
    def test_termination(self):
        script = "import time\ntime.sleep(20)"

        task_server = Mock()
        task_server.config_desc = ClientConfigDescriptor()
        task_server.client.datadir = self.test_dir
        task_server.benchmark_manager = Mock()
        task_server.benchmark_manager.benchmarks_needed.return_value = False
        task_server.client.get_node_name.return_value = "test_node"
        task_server.get_task_computer_root.return_value = \
            task_server.client.datadir
        task_computer = TaskComputer(task_server,
                                     use_docker_manager=False)
        image = DockerImage("golemfactory/base", tag="1.2")

        with self.assertRaises(AttributeError):
            dir_mapping = DockerTaskThread.generate_dir_mapping(
                self.resources_dir, self.output_dir)
            DockerTaskThread("subtask_id", None,
                             script, None,
                             dir_mapping, timeout=30)

        def test():
            dir_mapping = DockerTaskThread.generate_dir_mapping(
                self.resources_dir, self.output_dir)
            tt = DockerTaskThread("subtask_id", [image],
                                  script, None,
                                  "test task thread", dir_mapping, timeout=30)
            task_computer.counting_thread = tt
            task_computer.counting_task = True
            tt.setDaemon(True)
            tt.start()
            time.sleep(1)

        started = time.time()
        parent_thread = Thread(target=test)
        parent_thread.start()
        time.sleep(1)

        ct = task_computer.counting_thread

        while ct and ct.is_alive():
            task_computer.run()

            if time.time() - started > 15:
                self.fail("Job timed out")
            else:
                ct = task_computer.counting_thread

            time.sleep(1)
    def setUp(self):
        main_dir = get_local_datadir('tests-' + str(uuid.uuid4()))
        if not os.path.exists(main_dir):
            os.makedirs(main_dir)

        self.test_dir = tempfile.mkdtemp(dir=main_dir)
        self.work_dir = tempfile.mkdtemp(prefix="golem-", dir=self.test_dir)
        self.resources_dir = tempfile.mkdtemp(prefix="golem-", dir=self.test_dir)
        self.output_dir = tempfile.mkdtemp(prefix="golem-", dir=self.test_dir)

        if not is_windows():
            os.chmod(self.test_dir, 0770)

        self.image = DockerImage(self._get_test_repository(), tag=self._get_test_tag())
        self.test_job = None
Exemple #15
0
    def test_cmp_name_and_tag(self):
        img = DockerImage(self.TEST_REPOSITORY,
                          tag=self.TEST_TAG,
                          image_id=self.TEST_IMAGE_ID)
        img2 = DockerImage(self.TEST_REPOSITORY, tag=self.TEST_TAG)
        assert img.cmp_name_and_tag(img2)
        assert img2.cmp_name_and_tag(img)

        img3 = DockerImage(self.TEST_REPOSITORY,
                           tag="bogus",
                           image_id=self.TEST_IMAGE_ID)
        assert not img.cmp_name_and_tag(img3)
        assert not img3.cmp_name_and_tag(img)

        img4 = DockerImage("golemfactory/xyz",
                           tag=self.TEST_TAG,
                           image_id=self.TEST_IMAGE_ID)
        assert not img.cmp_name_and_tag(img4)
        assert not img4.cmp_name_and_tag(img)
Exemple #16
0
    def __compute_task(self, subtask_id, docker_images,
                       src_code, extra_data, subtask_deadline):
        task_id = self.assigned_subtask['task_id']
        task_header = self.task_server.task_keeper.task_headers.get(task_id)

        if not task_header:
            logger.warning("Subtask '%s' of task '%s' cannot be computed: "
                           "task header has been unexpectedly removed",
                           subtask_id, task_id)
            return self.session_closed()

        deadline = min(task_header.deadline, subtask_deadline)
        task_timeout = deadline_to_timeout(deadline)

        unique_str = str(uuid.uuid4())

        logger.info("Starting computation of subtask %r (task: %r, deadline: "
                    "%r, docker images: %r)", subtask_id, task_id, deadline,
                    docker_images)

        self.reset(counting_task=task_id)

        with self.dir_lock:
            resource_dir = self.resource_manager.get_resource_dir(task_id)
            temp_dir = os.path.join(
                self.resource_manager.get_temporary_dir(task_id), unique_str)
            # self.dir_manager.clear_temporary(task_id)

            if not os.path.exists(temp_dir):
                os.makedirs(temp_dir)

        if docker_images:
            docker_images = [DockerImage(**did) for did in docker_images]
            dir_mapping = DockerTaskThread.generate_dir_mapping(resource_dir,
                                                                temp_dir)
            tt = DockerTaskThread(subtask_id, docker_images,
                                  src_code, extra_data,
                                  dir_mapping, task_timeout)
        elif self.support_direct_computation:
            tt = PyTaskThread(subtask_id, src_code,
                              extra_data, resource_dir, temp_dir,
                              task_timeout)
        else:
            logger.error("Cannot run PyTaskThread in this version")
            subtask = self.assigned_subtask
            self.assigned_subtask = None
            self.task_server.send_task_failed(
                subtask_id,
                subtask['task_id'],
                "Host direct task not supported",
            )
            self.counting_task = None
            if self.finished_cb:
                self.finished_cb()

            return

        with self.lock:
            self.counting_thread = tt

        tt.start().addBoth(lambda _: self.task_computed(tt))
    def test_termination(self):
        script = "import time\ntime.sleep(20)"

        task_server = Mock()
        task_server.config_desc = ClientConfigDescriptor()
        task_server.config_desc.estimated_blender_performance = 2000.0
        task_server.config_desc.estimated_lux_performance = 2000.0
        task_server.client.datadir = self.test_dir
        task_server.client.get_node_name.return_value = "test_node"
        task_server.get_task_computer_root.return_value = task_server.client.datadir
        task_computer = TaskComputer("node",
                                     task_server,
                                     use_docker_machine_manager=False)
        image = DockerImage("golemfactory/base", tag="1.2")

        with self.assertRaises(AttributeError):
            DockerTaskThread(task_computer,
                             "subtask_id",
                             None,
                             self.work_dir,
                             script,
                             None,
                             "test task thread",
                             self.resources_dir,
                             self.output_dir,
                             timeout=30)

        def test():
            tt = DockerTaskThread(task_computer,
                                  "subtask_id", [image],
                                  self.work_dir,
                                  script,
                                  None,
                                  "test task thread",
                                  self.resources_dir,
                                  self.output_dir,
                                  timeout=30)
            task_computer.current_computations.append(tt)
            task_computer.counting_task = True
            tt.setDaemon(True)
            tt.start()
            time.sleep(1)

        started = time.time()
        parent_thread = Thread(target=test)
        parent_thread.start()
        time.sleep(1)

        ct = task_computer.current_computations[0]

        while ct and ct.is_alive():
            task_computer.run()

            if time.time() - started > 15:
                self.fail("Job timed out")
            elif task_computer.current_computations:
                ct = task_computer.current_computations[0]
            else:
                ct = None

            time.sleep(1)
Exemple #18
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()
Exemple #19
0
    def setUp(self):
        # pylint: disable=R0915
        super().setUp()
        dm = DockerTaskThread.docker_manager = DockerManager.install()
        dm.update_config(status_callback=mock.Mock(),
                         done_callback=mock.Mock(),
                         work_dir=self.new_path,
                         in_background=True)
        self.blender_reference_generator = BlenderReferenceGenerator()
        self.golem_dir = get_golem_path()
        self.resources = [
            'tests/apps/blender/verification/test_data/bmw.blend'
        ]
        self.computer = ComputerAdapter()

        self.subtask_info = dict()
        self.subtask_info['res_x'] = 150
        self.subtask_info['res_y'] = 150
        self.subtask_info['samples'] = 35
        self.subtask_info['use_frames'] = False
        self.subtask_info['end_task'] = 1
        self.subtask_info['total_tasks'] = 1
        self.subtask_info['node_id'] = 'deadbeef'
        self.subtask_info['frames'] = [1]
        self.subtask_info['start_task'] = 1
        self.subtask_info[
            'subtask_id'] = '250771152547690738285326338136457465'
        self.subtask_info['crop_window'] = (0.0, 1.0, 0.0, 1.0)
        self.subtask_info['output_format'] = 'PNG'
        self.subtask_info['all_frames'] = [1]
        self.subtask_info['script_src'] = ''
        self.subtask_info['tmp_dir'] = self.tempdir
        self.subtask_info['subtask_timeout'] = 600
        self.subtask_info['scene_file'] = '/golem/resources/bmw.blend'
        self.subtask_info['path_root'] = os.path.dirname(self.resources[0])
        self.subtask_info['parts'] = 1
        self.subtask_info['outfilebasename'] = 'GolemTask'
        self.subtask_info['owner'] = "deadbeef"
        self.subtask_info['ctd'] = dict()
        self.subtask_info['ctd']['deadline'] = time.time() + 3600
        self.subtask_info['ctd']['docker_images'] = [
            DockerImage('golemfactory/blender', tag='1.4').to_dict()
        ]
        self.subtask_info['ctd']['extra_data'] = dict()
        self.subtask_info['ctd']['extra_data']['end_task'] = \
            self.subtask_info['end_task']
        self.subtask_info['ctd']['extra_data']['frames'] = \
            self.subtask_info['frames']
        self.subtask_info['ctd']['extra_data']['outfilebasename'] = \
            self.subtask_info['outfilebasename']
        self.subtask_info['ctd']['extra_data']['output_format'] = \
            self.subtask_info['output_format']
        self.subtask_info['ctd']['extra_data']['path_root'] = \
            self.subtask_info['path_root']
        self.subtask_info['ctd']['extra_data']['scene_file'] = \
            self.subtask_info['scene_file']
        self.subtask_info['ctd']['extra_data']['script_src'] = \
            self.subtask_info['script_src']
        self.subtask_info['ctd']['extra_data']['start_task'] = \
            self.subtask_info['start_task']
        self.subtask_info['ctd']['extra_data']['total_tasks'] = \
            self.subtask_info['total_tasks']
        self.subtask_info['ctd']['short_description'] = ''
        self.subtask_info['ctd']['src_code'] = open(
            os.path.join(
                self.golem_dir,
                'apps/blender/resources/scripts/docker_blendertask.py'),
            'r').read()
        self.subtask_info['ctd']['subtask_id'] = self.subtask_info[
            'subtask_id']