def test_dont_filter_out_non_recently_converged(self): """ If a group was converged in the past but not recently, it will be cleaned from the ``recently_converged`` map, and it will be converged. """ # g1: converged a while ago; divergent -> removed and converged # g2: converged recently; not divergent -> not converged # g3: converged a while ago; not divergent -> removed and not converged eff = self._converge_all_groups(['00_g1']) sequence = [ (ReadReference(ref=self.currently_converging), lambda i: pset([])), (Log('converge-all-groups', dict(group_infos=[self.group_infos[0]], currently_converging=[])), noop), (ReadReference(ref=self.recently_converged), lambda i: pmap({'g1': 4, 'g2': 10, 'g3': 0})), (Func(time.time), lambda i: 20), (ModifyReference(self.recently_converged, match_func("literally anything", pmap({'g2': 10}))), noop), parallel_sequence([[self._expect_group_converged('00', 'g1')]]) ] self.assertEqual(perform_sequence(sequence, eff), ['converged g1!'])
def test_record_recently_converged(self): """ After converging, the group is added to ``recently_converged`` -- but *before* being removed from ``currently_converging``, to avoid race conditions. """ currently = Reference(pset()) recently = Reference(pmap()) remove_from_currently = match_func(pset([self.group_id]), pset([])) sequence = [ (ReadReference(currently), lambda i: pset()), add_to_currently(currently, self.group_id), (('ec', self.tenant_id, self.group_id, 3600), lambda i: (StepResult.SUCCESS, ScalingGroupStatus.ACTIVE)), (Func(time.time), lambda i: 100), add_to_recently(recently, self.group_id, 100), (ModifyReference(currently, remove_from_currently), noop), (DeleteNode(path='/groups/divergent/tenant-id_g1', version=self.version), noop), (Log('mark-clean-success', {}), noop) ] eff = converge_one_group( currently, recently, self.tenant_id, self.group_id, self.version, 3600, execute_convergence=self._execute_convergence) perform_sequence(sequence, eff)
def test_unexpected_errors(self): """ Unexpected exceptions log a non-fatal error and don't clean up the dirty flag. """ converging = Reference(pset()) recent = Reference(pmap()) expected_error = RuntimeError('oh no!') sequence = [ (ReadReference(converging), lambda i: pset()), add_to_currently(converging, self.group_id), (('ec', self.tenant_id, self.group_id, 3600), lambda i: raise_(expected_error)), (Func(time.time), lambda i: 100), add_to_recently(recent, self.group_id, 100), (ModifyReference(converging, match_func(pset([self.group_id]), pset())), noop), (LogErr(CheckFailureValue(expected_error), 'converge-non-fatal-error', {}), noop), ] self._verify_sequence(sequence, converging=converging, recent=recent, allow_refs=False)
def add_to_currently(currently, group_id): return (ModifyReference(currently, match_func(pset(), pset([group_id]))), noop)
def add_to_recently(recently, group_id, cvg_time): return (ModifyReference(recently, match_func(pmap(), pmap({group_id: cvg_time}))), noop)