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)
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)
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)
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)
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
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
def resume_session(self, storage): return SessionManager.load_session( self._get_all_units(), storage, flags=self.ns.flag)