def test_del_active_servers_not_called(self): """ ``delete_active_servers`` is not called when pending jobs are enough """ self.find_pending_jobs_to_cancel.return_value = ["5", "2", "3"] supervisor.exec_scale_down(self.log, "tid", self.fake_state, "g", 3) self.assertFalse(self.del_active_servers.called)
def test_del_active_servers_called(self): """ ``delete_active_servers`` is called with correct arguments """ self.find_pending_jobs_to_cancel.return_value = self.pending.keys() supervisor.exec_scale_down(self.log, "tid", self.fake_state, "g", 7) self.del_active_servers.assert_called_once_with(self.log, "tid", "g", 2, self.fake_state)
def test_pending_jobs_removed(self): """ Pending jobs are removed from state """ exp_pending_jobs = ["5", "2", "3"] self.find_pending_jobs_to_cancel.return_value = exp_pending_jobs supervisor.exec_scale_down(self.log, "tid", self.fake_state, "g", 3) for job_id in exp_pending_jobs: self.assertNotIn(job_id, self.fake_state.pending)
def test_pending_jobs_removed(self): """ Pending jobs are removed from state """ exp_pending_jobs = ['5', '2', '3'] self.find_pending_jobs_to_cancel.return_value = exp_pending_jobs supervisor.exec_scale_down(self.log, 'tid', self.fake_state, 'g', 3) for job_id in exp_pending_jobs: self.assertNotIn(job_id, self.fake_state.pending)
def converge(log, transaction_id, config, scaling_group, state, launch_config, policy, config_value=config_value): """ Apply a policy's change to a scaling group, and attempt to make the resulting state a reality. This does no cooldown checking. This is done by dispatching to the appropriate orchestration backend for the scaling group; currently only direct nova interaction is supported. :param log: A bound log for logging :param str transaction_id: the transaction id :param dict config: the scaling group config :param otter.models.interface.IScalingGroup scaling_group: the scaling group object :param otter.models.interface.GroupState state: the group state :param dict launch_config: the scaling group launch config :param dict policy: the policy configuration dictionary :return: a ``Deferred`` that fires with the updated :class:`otter.models.interface.GroupState` if successful. If no changes are to be made to the group, None will synchronously be returned. """ if tenant_is_enabled(scaling_group.tenant_id, config_value): # For convergence tenants, find delta based on group's desired # capacity delta = apply_delta(log, state.desired, state, config, policy) if delta == 0: # No change in servers. Return None synchronously return None else: return defer.succeed(state) # For non-convergence tenants, the value used for desired-capacity is # the sum of active+pending, which is 0, so the delta ends up being # the min entities due to constraint calculation. delta = calculate_delta(log, state, config, policy) execute_log = log.bind(server_delta=delta) if delta == 0: execute_log.msg("no change in servers") return None elif delta > 0: execute_log.msg("executing launch configs") deferred = execute_launch_config(execute_log, transaction_id, state, launch_config, scaling_group, delta) else: # delta < 0 (scale down) execute_log.msg("scaling down") deferred = exec_scale_down(execute_log, transaction_id, state, scaling_group, -delta) deferred.addCallback(_do_convergence_audit_log, log, delta, state) return deferred
def converge(log, transaction_id, config, scaling_group, state, launch_config, policy, config_value=config_value): """ Apply a policy's change to a scaling group, and attempt to make the resulting state a reality. This does no cooldown checking. This is done by dispatching to the appropriate orchestration backend for the scaling group; currently only direct nova interaction is supported. :param log: A bound log for logging :param str transaction_id: the transaction id :param dict config: the scaling group config :param otter.models.interface.IScalingGroup scaling_group: the scaling group object :param otter.models.interface.GroupState state: the group state :param dict launch_config: the scaling group launch config :param dict policy: the policy configuration dictionary :return: a ``Deferred`` that fires with the updated :class:`otter.models.interface.GroupState` if successful. If no changes are to be made to the group, None will synchronously be returned. """ if tenant_is_enabled(scaling_group.tenant_id, config_value): # For convergence tenants, find delta based on group's desired # capacity delta = apply_delta(log, state.desired, state, config, policy) if delta == 0: # No change in servers. Return None synchronously return None else: return defer.succeed(state) # For non-convergence tenants, the value used for desired-capacity is # the sum of active+pending, which is 0, so the delta ends up being # the min entities due to constraint calculation. delta = calculate_delta(log, state, config, policy) execute_log = log.bind(server_delta=delta) if delta == 0: execute_log.msg("no change in servers") return None elif delta > 0: execute_log.msg("executing launch configs") deferred = execute_launch_config( execute_log, transaction_id, state, launch_config, scaling_group, delta) else: # delta < 0 (scale down) execute_log.msg("scaling down") deferred = exec_scale_down(execute_log, transaction_id, state, scaling_group, -delta) deferred.addCallback(_do_convergence_audit_log, log, delta, state) return deferred
def converge(log, transaction_id, config, scaling_group, state, launch_config, policy): """ Apply a policy's change to a scaling group, and attempt to make the resulting state a reality. This does no cooldown checking. This is done by dispatching to the appropriate orchestration backend for the scaling group; currently only direct nova interaction is supported. :param log: A bound log for logging :param str transaction_id: the transaction id :param dict config: the scaling group config :param otter.models.interface.IScalingGroup scaling_group: the scaling group object :param otter.models.interface.GroupState state: the group state :param dict launch_config: the scaling group launch config :param dict policy: the policy configuration dictionary :return: a ``Deferred`` that fires with the updated :class:`otter.models.interface.GroupState` if successful. If no changes are to be made to the group, None will synchronously be returned. """ delta = calculate_delta(log, state, config, policy) execute_log = log.bind(server_delta=delta) if delta == 0: execute_log.msg("no change in servers") return None elif delta > 0: execute_log.msg("executing launch configs") deferred = execute_launch_config(execute_log, transaction_id, state, launch_config, scaling_group, delta) else: # delta < 0 (scale down) execute_log.msg("scaling down") deferred = exec_scale_down(execute_log, transaction_id, state, scaling_group, -delta) deferred.addCallback(_do_convergence_audit_log, log, delta, state) return deferred