Example #1
0
 def test_load_session(self):
     """
     verify that SessionManager.load_session() correctly delegates the task
     to various other objects
     """
     job = mock.Mock(name='job', spec_set=JobDefinition)
     unit_list = [job]
     flags = None
     helper_name = "plainbox.impl.session.manager.SessionResumeHelper"
     with mock.patch(helper_name) as helper_cls:
         resumed_state = mock.Mock(spec_set=SessionState)
         resumed_state.unit_list = unit_list
         helper_cls().resume.return_value = resumed_state
         # NOTE: mock away _propagate_test_plans() so that we don't get
         # unwanted side effects we're not testing here.
         with mock.patch.object(SessionManager, '_propagate_test_plans'):
             manager = SessionManager.load_session(unit_list, self.storage)
     # Ensure that the storage object was used to load the session snapshot
     self.storage.load_checkpoint.assert_called_with()
     # Ensure that the helper was instantiated with the unit list, flags and
     # location
     helper_cls.assert_called_with(unit_list, flags, self.storage.location)
     # Ensure that the helper instance was asked to recreate session state
     helper_cls().resume.assert_called_with(self.storage.load_checkpoint(),
                                            None)
     # Ensure that the resulting manager has correct data inside
     self.assertEqual(manager.state, helper_cls().resume())
     self.assertEqual(manager.storage, self.storage)
Example #2
0
 def export_session(self):
     if self.ns.output_format == _('?'):
         self._print_output_format_list()
         return 0
     elif self.ns.output_options == _('?'):
         self._print_output_option_list()
         return 0
     storage = self._lookup_storage(self.ns.session_id)
     if storage is None:
         print(_("No such session: {0}").format(self.ns.session_id))
     else:
         print(_("Exporting session..."))
         manager = SessionManager.load_session(
             self._get_all_units(), storage, flags=self.ns.flag)
         exporter = self._create_exporter(manager)
         # Get a stream with exported session data.
         exported_stream = io.BytesIO()
         exporter.dump_from_session_manager(manager, exported_stream)
         exported_stream.seek(0)  # Need to rewind the file, puagh
         # Write the stream to file if requested
         if self.ns.output_file is sys.stdout:
             # This requires a bit more finesse, as exporters output bytes
             # and stdout needs a string.
             translating_stream = ByteStringStreamTranslator(
                 self.ns.output_file, "utf-8")
             copyfileobj(exported_stream, translating_stream)
         else:
             print(_("Saving results to {}").format(
                 self.ns.output_file.name))
             copyfileobj(exported_stream, self.ns.output_file)
         if self.ns.output_file is not sys.stdout:
             self.ns.output_file.close()
    def create_manager(self, storage):
        """
        Create or resume a session that handles most of the stuff needed to run
        jobs.

        This sets the attr:`_manager` which enables :meth:`manager`,
        :meth:`state` and :meth:`storage` properties.

        The created session state has the on_job_added signal connected to
        :meth:`on_job_added()`.

        :raises SessionResumeError:
            If the session cannot be resumed for any reason.
        """
        all_units = list(
            itertools.chain(*[p.unit_list for p in self.provider_list]))
        try:
            if storage is not None:
                self._manager = SessionManager.load_session(all_units, storage)
            else:
                self._manager = SessionManager.create_with_unit_list(all_units)
        except DependencyDuplicateError as exc:
            # Handle possible DependencyDuplicateError that can happen if
            # someone is using plainbox for job development.
            print(
                self.C.RED(
                    _("The job database you are currently using is broken")))
            print(
                self.C.RED(
                    _("At least two jobs contend for the id {0}").format(
                        exc.job.id)))
            print(
                self.C.RED(
                    _("First job defined in: {0}").format(exc.job.origin)))
            print(
                self.C.RED(
                    _("Second job defined in: {0}").format(
                        exc.duplicate_job.origin)))
            raise SystemExit(exc)
        except SessionResumeError as exc:
            print(self.C.RED(exc))
            print(self.C.RED(_("This session cannot be resumed")))
            raise
        else:
            # Connect the on_job_added signal. We use it to mark the test loop
            # for re-execution and to update the list of desired jobs.
            self.state.on_job_added.connect(self.on_job_added)
Example #4
0
 def test_load_session(self):
     """
     verify that SessionManager.load_session() correctly delegates the task
     to various other objects
     """
     # Mock SessionState and job list
     storage = mock.Mock(name="storage", spec=SessionStorage)
     job_list = mock.Mock(name='job_list')
     helper_name = "plainbox.impl.session.manager.SessionResumeHelper"
     with mock.patch(helper_name) as helper_cls:
         helper_cls().resume.return_value = mock.Mock(
             name="state", spec=SessionState)
         manager = SessionManager.load_session(job_list, storage)
     # Ensure that the storage object was used to load the session snapshot
     storage.load_checkpoint.assert_called_with()
     # Ensure that the helper was instantiated with the job list
     helper_cls.assert_called_with(job_list)
     # Ensure that the helper instance was asked to recreate session state
     helper_cls().resume.assert_called_with(storage.load_checkpoint(), None)
     # Ensure that the resulting manager has correct data inside
     self.assertEqual(manager.state, helper_cls().resume())
     self.assertEqual(manager.storage, storage)
Example #5
0
 def test_load_session(self):
     """
     verify that SessionManager.load_session() correctly delegates the task
     to various other objects
     """
     # Mock SessionState and job list
     storage = mock.Mock(name="storage", spec=SessionStorage)
     job_list = mock.Mock(name='job_list')
     helper_name = "plainbox.impl.session.manager.SessionResumeHelper"
     with mock.patch(helper_name) as helper_cls:
         helper_cls().resume.return_value = mock.Mock(name="state",
                                                      spec=SessionState)
         manager = SessionManager.load_session(job_list, storage)
     # Ensure that the storage object was used to load the session snapshot
     storage.load_checkpoint.assert_called_with()
     # Ensure that the helper was instantiated with the job list
     helper_cls.assert_called_with(job_list)
     # Ensure that the helper instance was asked to recreate session state
     helper_cls().resume.assert_called_with(storage.load_checkpoint(), None)
     # Ensure that the resulting manager has correct data inside
     self.assertEqual(manager.state, helper_cls().resume())
     self.assertEqual(manager.storage, storage)
Example #6
0
    def run(self):
        ns = self.ns
        job_list = self.get_job_list(ns)
        previous_session_file = SessionStorageRepository().get_last_storage()
        resume_in_progress = False
        if previous_session_file:
            if self.is_interactive:
                if self.ask_for_resume():
                    resume_in_progress = True
                    manager = SessionManager.load_session(
                        job_list, previous_session_file)
                    self._maybe_skip_last_job_after_resume(manager)
            else:
                resume_in_progress = True
                manager = SessionManager.load_session(job_list,
                                                      previous_session_file)
        if not resume_in_progress:
            # Create a session that handles most of the stuff needed to run
            # jobs
            try:
                manager = SessionManager.create_with_job_list(job_list,
                                                              legacy_mode=True)
            except DependencyDuplicateError as exc:
                # Handle possible DependencyDuplicateError that can happen if
                # someone is using plainbox for job development.
                print("The job database you are currently using is broken")
                print("At least two jobs contend for the name {0}".format(
                    exc.job.id))
                print("First job defined in: {0}".format(exc.job.origin))
                print("Second job defined in: {0}".format(
                    exc.duplicate_job.origin))
                raise SystemExit(exc)
            manager.state.metadata.title = " ".join(sys.argv)
            if self.is_interactive:
                if self.display is None:
                    self.display = get_display()
                if self.settings['welcome_text']:
                    self.display.run(ShowWelcome(
                        self.settings['welcome_text']))
                if not self.whitelists:
                    whitelists = []
                    for p in self.provider_list:
                        if p.name in self.settings['default_providers']:
                            whitelists.extend(
                                [w.name for w in p.get_builtin_whitelists()])
                    selection = self.display.run(
                        ShowMenu("Suite selection", whitelists))
                    if not selection:
                        raise SystemExit('No whitelists selected, aborting...')
                    for s in selection:
                        self.whitelists.append(
                            get_whitelist_by_name(self.provider_list,
                                                  whitelists[s]))
            else:
                self.whitelists.append(
                    get_whitelist_by_name(self.provider_list,
                                          self.settings['default_whitelist']))
        manager.checkpoint()

        if self.is_interactive and not resume_in_progress:
            # Pre-run all local jobs
            desired_job_list = select_jobs(manager.state.job_list, [
                CompositeQualifier(self.whitelists +
                                   [NonLocalJobQualifier(inclusive=False)])
            ])
            self._update_desired_job_list(manager, desired_job_list)
            # Ask the password before anything else in order to run local jobs
            # requiring privileges
            if self._auth_warmup_needed(manager):
                print("[ Authentication ]".center(80, '='))
                return_code = authenticate_warmup()
                if return_code:
                    raise SystemExit(return_code)
            self._local_only = True
            self._run_jobs(ns, manager)
            self._local_only = False

        if not resume_in_progress:
            # Run the rest of the desired jobs
            desired_job_list = select_jobs(manager.state.job_list,
                                           self.whitelists)
            self._update_desired_job_list(manager, desired_job_list)
            if self.is_interactive:
                # Ask the password before anything else in order to run jobs
                # requiring privileges
                if self._auth_warmup_needed(manager):
                    print("[ Authentication ]".center(80, '='))
                    return_code = authenticate_warmup()
                    if return_code:
                        raise SystemExit(return_code)
                tree = SelectableJobTreeNode.create_tree(
                    manager.state.run_list, legacy_mode=True)
                title = 'Choose tests to run on your system:'
                if self.display is None:
                    self.display = get_display()
                self.display.run(ScrollableTreeNode(tree, title))
                self._update_desired_job_list(manager, tree.selection)
                estimated_duration_auto, estimated_duration_manual = \
                    manager.state.get_estimated_duration()
                if estimated_duration_auto:
                    print(
                        "Estimated duration is {:.2f} "
                        "for automated jobs.".format(estimated_duration_auto))
                else:
                    print("Estimated duration cannot be "
                          "determined for automated jobs.")
                if estimated_duration_manual:
                    print("Estimated duration is {:.2f} "
                          "for manual jobs.".format(estimated_duration_manual))
                else:
                    print("Estimated duration cannot be "
                          "determined for manual jobs.")
        self._run_jobs(ns, manager)
        manager.destroy()

        # FIXME: sensible return value
        return 0
Example #7
0
    def run(self):
        ns = self.ns
        job_list = self.get_job_list(ns)
        previous_session_file = SessionStorageRepository().get_last_storage()
        resume_in_progress = False
        if previous_session_file:
            if self.is_interactive:
                if self.ask_for_resume():
                    resume_in_progress = True
                    manager = SessionManager.load_session(
                        job_list, previous_session_file)
                    self._maybe_skip_last_job_after_resume(manager)
            else:
                resume_in_progress = True
                manager = SessionManager.load_session(
                    job_list, previous_session_file)
        if not resume_in_progress:
            # Create a session that handles most of the stuff needed to run
            # jobs
            try:
                manager = SessionManager.create_with_job_list(
                    job_list, legacy_mode=True)
            except DependencyDuplicateError as exc:
                # Handle possible DependencyDuplicateError that can happen if
                # someone is using plainbox for job development.
                print("The job database you are currently using is broken")
                print("At least two jobs contend for the name {0}".format(
                    exc.job.id))
                print("First job defined in: {0}".format(exc.job.origin))
                print("Second job defined in: {0}".format(
                    exc.duplicate_job.origin))
                raise SystemExit(exc)
            manager.state.metadata.title = " ".join(sys.argv)
            if self.is_interactive:
                if self.display is None:
                    self.display = get_display()
                if self.settings['welcome_text']:
                    self.display.run(
                        ShowWelcome(self.settings['welcome_text']))
                if not self.whitelists:
                    whitelists = []
                    for p in self.provider_list:
                        if p.name in self.settings['default_providers']:
                            whitelists.extend(
                                [w.name for w in p.get_builtin_whitelists()])
                    selection = self.display.run(ShowMenu("Suite selection",
                                                          whitelists))
                    if not selection:
                        raise SystemExit('No whitelists selected, aborting...')
                    for s in selection:
                        self.whitelists.append(
                            get_whitelist_by_name(self.provider_list,
                                                  whitelists[s]))
            else:
                self.whitelists.append(
                    get_whitelist_by_name(
                        self.provider_list,
                        self.settings['default_whitelist']))
        manager.checkpoint()

        if self.is_interactive and not resume_in_progress:
            # Pre-run all local jobs
            desired_job_list = select_jobs(
                manager.state.job_list,
                [CompositeQualifier(
                    self.whitelists +
                    [NonLocalJobQualifier(inclusive=False)]
                )])
            self._update_desired_job_list(manager, desired_job_list)
            # Ask the password before anything else in order to run local jobs
            # requiring privileges
            if self._auth_warmup_needed(manager):
                print("[ Authentication ]".center(80, '='))
                return_code = authenticate_warmup()
                if return_code:
                    raise SystemExit(return_code)
            self._local_only = True
            self._run_jobs(ns, manager)
            self._local_only = False

        if not resume_in_progress:
            # Run the rest of the desired jobs
            desired_job_list = select_jobs(manager.state.job_list,
                                           self.whitelists)
            self._update_desired_job_list(manager, desired_job_list)
            if self.is_interactive:
                # Ask the password before anything else in order to run jobs
                # requiring privileges
                if self._auth_warmup_needed(manager):
                    print("[ Authentication ]".center(80, '='))
                    return_code = authenticate_warmup()
                    if return_code:
                        raise SystemExit(return_code)
                tree = SelectableJobTreeNode.create_tree(
                    manager.state.run_list,
                    legacy_mode=True)
                title = 'Choose tests to run on your system:'
                if self.display is None:
                    self.display = get_display()
                self.display.run(ScrollableTreeNode(tree, title))
                self._update_desired_job_list(manager, tree.selection)
                estimated_duration_auto, estimated_duration_manual = \
                    manager.state.get_estimated_duration()
                if estimated_duration_auto:
                    print(
                        "Estimated duration is {:.2f} "
                        "for automated jobs.".format(estimated_duration_auto))
                else:
                    print(
                        "Estimated duration cannot be "
                        "determined for automated jobs.")
                if estimated_duration_manual:
                    print(
                        "Estimated duration is {:.2f} "
                        "for manual jobs.".format(estimated_duration_manual))
                else:
                    print(
                        "Estimated duration cannot be "
                        "determined for manual jobs.")
        self._run_jobs(ns, manager)
        manager.destroy()

        # FIXME: sensible return value
        return 0
Example #8
0
 def resume_session(self, storage):
     return SessionManager.load_session(
         self._get_all_units(), storage, flags=self.ns.flag)