def test_process_job_restores_jobs(self): """ verify that _process_job() recreates generated jobs """ # Set the stage for testing. Setup a session with a known # local job, representation of the job (checksum) # and representation of a single result, which has a single line # that defines a 'name': 'generated' job. job_name = 'local' job = make_job(name=job_name, plugin='local') jobs_repr = { job_name: job.get_checksum() } results_repr = { job_name: [{ 'outcome': None, 'comments': None, 'execution_duration': None, 'return_code': None, 'io_log': [ [0.0, 'stdout', base64.standard_b64encode( b'name: generated' ).decode('ASCII')] ], }] } helper = SessionResumeHelper([job]) session = SessionState([job]) # Ensure that the 'generated' job was not there initially self.assertNotIn('generated', session.job_state_map) self.assertEqual(session.job_list, [job]) # Process the representation data defined above helper._process_job(session, jobs_repr, results_repr, job_name) # Ensure that we now have the 'generated' job in the job_state_map self.assertIn('generated', session.job_state_map) # And that it looks right self.assertEqual( session.job_state_map['generated'].job.name, 'generated') self.assertIn( session.job_state_map['generated'].job, session.job_list)
def test_process_job_restores_resources(self): """ verify that _process_job() recreates resources """ # Set the stage for testing. Setup a session with a known # resource job, representation of the job (checksum) # and representation of a single result, which has a single line # that defines a 'key': 'value' resource record. job_name = 'resource' job = make_job(name=job_name, plugin='resource') jobs_repr = { job_name: job.get_checksum() } results_repr = { job_name: [{ 'outcome': None, 'comments': None, 'execution_duration': None, 'return_code': None, 'io_log': [ # A bit convoluted but this is how we encode each chunk # of IOLogRecord [0.0, 'stdout', base64.standard_b64encode( b'key: value' ).decode('ASCII')] ], }] } helper = SessionResumeHelper([job]) session = SessionState([job]) # Ensure that the resource was not there initially self.assertNotIn(job_name, session.resource_map) # Process the representation data defined above helper._process_job(session, jobs_repr, results_repr, job_name) # Ensure that we now have the resource in the resource map self.assertIn(job_name, session.resource_map) # And that it looks right self.assertEqual( session.resource_map[job_name], [Resource({'key': 'value'})])
class ProcessJobTests(TestCase): """ Tests for :class:`~plainbox.impl.session.resume.SessionResumeHelper` and how it handles processing jobs using _process_job() method """ def setUp(self): self.job_name = 'job' self.job = make_job(name=self.job_name) self.jobs_repr = { self.job_name: self.job.get_checksum() } self.results_repr = { self.job_name: [{ 'outcome': 'fail', 'comments': None, 'execution_duration': None, 'return_code': None, 'io_log': [], }] } self.helper = SessionResumeHelper([self.job]) # This object is artificial and would be constructed internally # by the helper but having it here makes testing easier as we # can reliably test a single method in isolation. self.session = SessionState([self.job]) def test_process_job_checks_type_of_job_name(self): """ verify that _process_job() checks the type of ``job_name`` """ with self.assertRaises(CorruptedSessionError) as boom: # Pass a job name of the wrong type job_name = 1 self.helper._process_job( self.session, self.jobs_repr, self.results_repr, job_name) self.assertEqual( str(boom.exception), "Value of object is of incorrect type int") def test_process_job_checks_for_missing_checksum(self): """ verify that _process_job() checks if ``checksum`` is missing """ with self.assertRaises(CorruptedSessionError) as boom: # Pass a jobs_repr that has no checksums (for any job) jobs_repr = {} self.helper._process_job( self.session, jobs_repr, self.results_repr, self.job_name) self.assertEqual(str(boom.exception), "Missing value for key 'job'") def test_process_job_checks_if_job_is_known(self): """ verify that _process_job() checks if job is known or raises KeyError """ with self.assertRaises(KeyError) as boom: # Pass a session that does not know about any jobs session = SessionState([]) self.helper._process_job( session, self.jobs_repr, self.results_repr, self.job_name) self.assertEqual(boom.exception.args[0], 'job') def test_process_job_checks_if_job_checksum_matches(self): """ verify that _process_job() checks if job checksum matches the checksum of a job with the same name that was passed to the helper. """ with self.assertRaises(IncompatibleJobError) as boom: # Pass a jobs_repr with a bad checksum jobs_repr = {self.job_name: 'bad-checksum'} self.helper._process_job( self.session, jobs_repr, self.results_repr, self.job_name) self.assertEqual( str(boom.exception), "Definition of job 'job' has changed") def test_process_job_handles_ignores_empty_results(self): """ verify that _process_job() does not crash if we have no results for a particular job """ self.assertEqual( self.session.job_state_map[self.job_name].result.outcome, None) results_repr = { self.job_name: [] } self.helper._process_job( self.session, self.jobs_repr, results_repr, self.job_name) self.assertEqual( self.session.job_state_map[self.job_name].result.outcome, None) def test_process_job_handles_only_result_back_to_the_session(self): """ verify that _process_job() passes the only result to the session """ self.assertEqual( self.session.job_state_map[self.job_name].result.outcome, None) self.helper._process_job( self.session, self.jobs_repr, self.results_repr, self.job_name) # The result in self.results_repr is a failure so we should see it here self.assertEqual( self.session.job_state_map[self.job_name].result.outcome, "fail") def test_process_job_handles_last_result_back_to_the_session(self): """ verify that _process_job() passes last of the results to the session """ self.assertEqual( self.session.job_state_map[self.job_name].result.outcome, None) results_repr = { self.job_name: [{ 'outcome': 'fail', 'comments': None, 'execution_duration': None, 'return_code': None, 'io_log': [], }, { 'outcome': 'pass', 'comments': None, 'execution_duration': None, 'return_code': None, 'io_log': [], }] } self.helper._process_job( self.session, self.jobs_repr, results_repr, self.job_name) # results_repr has two entries: [fail, pass] so we should see # the passing entry only self.assertEqual( self.session.job_state_map[self.job_name].result.outcome, "pass") def test_process_job_checks_results_repr_is_a_list(self): """ verify that _process_job() checks if results_repr is a dictionary of lists. """ with self.assertRaises(CorruptedSessionError) as boom: results_repr = {self.job_name: 1} self.helper._process_job( self.session, self.jobs_repr, results_repr, self.job_name) self.assertEqual( str(boom.exception), "Value of key 'job' is of incorrect type int") def test_process_job_checks_results_repr_values_are_dicts(self): """ verify that _process_job() checks if results_repr is a dictionary of lists, each of which holds a dictionary. """ with self.assertRaises(CorruptedSessionError) as boom: results_repr = {self.job_name: [1]} self.helper._process_job( self.session, self.jobs_repr, results_repr, self.job_name) self.assertEqual( str(boom.exception), "Value of object is of incorrect type int")