def test_ensure_coverage_changes_status(self): """Verify that processing an item that has a preexisting CoverageRecord can change the status of that CoverageRecord. """ always = AlwaysSuccessfulCoverageProvider("Always successful", self.input_identifier_types, self.output_source) persistent = NeverSuccessfulCoverageProvider( "Persistent failures", self.input_identifier_types, self.output_source) transient = TransientFailureCoverageProvider( "Persistent failures", self.input_identifier_types, self.output_source) # Cover the same identifier multiple times, simulating all # possible states of a CoverageRecord. The same CoverageRecord # is used every time and the status is changed appropriately # after every run. c1 = persistent.ensure_coverage(self.identifier, force=True) eq_(CoverageRecord.PERSISTENT_FAILURE, c1.status) c2 = transient.ensure_coverage(self.identifier, force=True) eq_(c2, c1) eq_(CoverageRecord.TRANSIENT_FAILURE, c1.status) c3 = always.ensure_coverage(self.identifier, force=True) eq_(c3, c1) eq_(CoverageRecord.SUCCESS, c1.status) c4 = persistent.ensure_coverage(self.identifier, force=True) eq_(c4, c1) eq_(CoverageRecord.PERSISTENT_FAILURE, c1.status)
def test_ensure_coverage_transient_coverage_failure(self): provider = TransientFailureCoverageProvider( "Transient failure", self.input_identifier_types, self.output_source) failure = provider.ensure_coverage(self.identifier) eq_([failure], self.identifier.coverage_records) eq_(CoverageRecord.TRANSIENT_FAILURE, failure.status) eq_("Oops!", failure.exception) # Timestamp was not updated. eq_([], self._db.query(Timestamp).all())
def test_transient_failure(self): # We start with no CoverageRecords and no Timestamp. eq_([], self._db.query(CoverageRecord).all()) eq_([], self._db.query(Timestamp).all()) provider = TransientFailureCoverageProvider( "Transient failure", self.input_identifier_types, self.output_source) provider.run() # We have a CoverageRecord representing the transient failure. [failure] = self.identifier.coverage_records eq_(CoverageRecord.TRANSIENT_FAILURE, failure.status) # The timestamp was set. [timestamp] = self._db.query(Timestamp).all() eq_("Transient failure", timestamp.service)
def test_process_batch_and_handle_results(self): e1, p1 = self._edition(with_license_pool=True) i1 = e1.primary_identifier e2, p2 = self._edition(with_license_pool=True) i2 = e2.primary_identifier success_provider = AlwaysSuccessfulCoverageProvider( "Success", self.input_identifier_types, self.output_source, operation="i succeed") batch = [i1, i2] counts, successes = success_provider.process_batch_and_handle_results( batch) # Two successes. eq_((2, 0, 0), counts) # Each represented with a CoverageRecord with status='success' assert all(isinstance(x, CoverageRecord) for x in successes) eq_([CoverageRecord.SUCCESS] * 2, [x.status for x in successes]) # Each associated with one of the identifiers... eq_(set([i1, i2]), set([x.identifier for x in successes])) # ...and with the coverage provider's operation. eq_(['i succeed'] * 2, [x.operation for x in successes]) # Now try a different CoverageProvider which creates transient # failures. transient_failure_provider = TransientFailureCoverageProvider( "Transient failure", self.input_identifier_types, self.output_source, operation="i fail transiently") counts, failures = transient_failure_provider.process_batch_and_handle_results( batch) # Two transient failures. eq_((0, 2, 0), counts) # New coverage records were added to track the transient # failures. eq_([CoverageRecord.TRANSIENT_FAILURE] * 2, [x.status for x in failures]) eq_(["i fail transiently"] * 2, [x.operation for x in failures]) # Another way of getting transient failures is to just ignore every # item you're told to process. task_ignoring_provider = TaskIgnoringCoverageProvider( "Ignores all tasks", self.input_identifier_types, self.output_source, operation="i ignore") counts, records = task_ignoring_provider.process_batch_and_handle_results( batch) eq_((0, 2, 0), counts) eq_([CoverageRecord.TRANSIENT_FAILURE] * 2, [x.status for x in records]) eq_(["i ignore"] * 2, [x.operation for x in records]) # Or you can go really bad and have persistent failures. persistent_failure_provider = NeverSuccessfulCoverageProvider( "Persistent failure", self.input_identifier_types, self.output_source, operation="i will always fail") counts, results = persistent_failure_provider.process_batch_and_handle_results( batch) # Two persistent failures. eq_((0, 0, 2), counts) assert all([isinstance(x, CoverageRecord) for x in results]) eq_(["What did you expect?", "What did you expect?"], [x.exception for x in results]) eq_([CoverageRecord.PERSISTENT_FAILURE] * 2, [x.status for x in results]) eq_(["i will always fail"] * 2, [x.operation for x in results])