def test_no_scaling(self): """ No scaling is happening. Node instances are in terminal states. """ node_instances = { 'n.1': NodeInstance({ NodeDecorator.NODE_INSTANCE_NAME_KEY: 'n.1', NodeDecorator.SCALE_STATE_KEY: CloudWrapper.SCALE_STATE_OPERATIONAL }), 'm.1': NodeInstance({ NodeDecorator.NODE_INSTANCE_NAME_KEY: 'm.1', NodeDecorator.SCALE_STATE_KEY: CloudWrapper.SCALE_STATE_GONE }) } cw = CloudWrapper(self.config_holder) cw._get_nodes_instances = Mock(return_value=node_instances) assert {} == cw._get_effective_scale_states() assert None == cw._get_global_scale_state() assert False == cw.is_vertical_scaling() node_and_instances = cw.get_scaling_node_and_instance_names() assert '' == node_and_instances[0] assert [] == node_and_instances[1]
def test_consistent_scale_state_consistent_scaling_nodes(self): """ Consistent scale state: different scaling actions at a time are not allowed. In case node instance is not in a terminal state (as set on the NodeInstance object), we check the state directly on the Run (via CloudWrapper._get_runtime_parameter()). Consistent scaling nodes: only one node type at a time is allowed to be scaled. """ def _get_runtime_parameter(key): if key.endswith(NodeDecorator.NODE_PROPERTY_SEPARATOR + NodeDecorator.SCALE_STATE_KEY): return CloudWrapper.SCALE_STATE_RESIZING else: return 'unknown' node_instances = { 'n.1': NodeInstance({NodeDecorator.NODE_INSTANCE_NAME_KEY: 'n.1', NodeDecorator.NODE_NAME_KEY: 'n', NodeDecorator.SCALE_STATE_KEY: 'not terminal'}), 'n.2': NodeInstance({NodeDecorator.NODE_INSTANCE_NAME_KEY: 'n.2', NodeDecorator.NODE_NAME_KEY: 'n', NodeDecorator.SCALE_STATE_KEY: 'not terminal'}), 'm.1': NodeInstance({NodeDecorator.NODE_INSTANCE_NAME_KEY: 'm.1', NodeDecorator.NODE_NAME_KEY: 'm', NodeDecorator.SCALE_STATE_KEY: CloudWrapper.SCALE_STATE_OPERATIONAL}) } cw = CloudWrapper(self.config_holder) cw._get_runtime_parameter = Mock(side_effect=_get_runtime_parameter) cw._get_nodes_instances = Mock(return_value=node_instances) scale_states = cw._get_effective_scale_states() assert 1 == len(scale_states) assert CloudWrapper.SCALE_STATE_RESIZING in scale_states assert 2 == len(scale_states[CloudWrapper.SCALE_STATE_RESIZING]) assert ['n.1', 'n.2'] == sorted(scale_states[CloudWrapper.SCALE_STATE_RESIZING]) assert CloudWrapper.SCALE_STATE_RESIZING == cw._get_global_scale_state() try: cw.check_scale_state_consistency() except InconsistentScaleStateError as ex: self.fail('Should not have failed with: %s' % str(ex)) node_and_instances = cw.get_scaling_node_and_instance_names() assert 'n' == node_and_instances[0] assert ['n.1', 'n.2'] == sorted(node_and_instances[1])
def test_consistent_scale_state_inconsistent_scaling_nodes(self): """ Consistent scale state: only one scaling action at a time on different node instances. In case node instance is not in a terminal state (as set on the NodeInstance object), we check the state directly on the Run (via CloudWrapper._get_runtime_parameter()). Inconsistent scaling nodes: only one node type at a time is allowed to be scaled. """ def _get_runtime_parameter(key): if key.endswith(NodeDecorator.NODE_PROPERTY_SEPARATOR + NodeDecorator.SCALE_STATE_KEY): return CloudWrapper.SCALE_STATE_RESIZING else: return 'unknown' node_instances = { 'n.1': NodeInstance({NodeDecorator.NODE_INSTANCE_NAME_KEY: 'n.1', NodeDecorator.NODE_NAME_KEY: 'n', NodeDecorator.SCALE_STATE_KEY: 'not terminal'}), 'n.2': NodeInstance({NodeDecorator.NODE_INSTANCE_NAME_KEY: 'n.2', NodeDecorator.NODE_NAME_KEY: 'n', NodeDecorator.SCALE_STATE_KEY: CloudWrapper.SCALE_STATE_OPERATIONAL}), 'm.1': NodeInstance({NodeDecorator.NODE_INSTANCE_NAME_KEY: 'm.1', NodeDecorator.NODE_NAME_KEY: 'm', NodeDecorator.SCALE_STATE_KEY: 'not terminal'}), 'm.2': NodeInstance({NodeDecorator.NODE_INSTANCE_NAME_KEY: 'm.2', NodeDecorator.NODE_NAME_KEY: 'm', NodeDecorator.SCALE_STATE_KEY: CloudWrapper.SCALE_STATE_GONE}), } cw = CloudWrapper(self.config_holder) cw._get_runtime_parameter = Mock(side_effect=_get_runtime_parameter) cw._get_nodes_instances = Mock(return_value=node_instances) scale_states = cw._get_effective_scale_states() assert 1 == len(scale_states) assert CloudWrapper.SCALE_STATE_RESIZING in scale_states assert 2 == len(scale_states[CloudWrapper.SCALE_STATE_RESIZING]) assert ['m.1', 'n.1'] == sorted(scale_states[CloudWrapper.SCALE_STATE_RESIZING]) assert CloudWrapper.SCALE_STATE_RESIZING == cw._get_global_scale_state() assert True == cw.is_vertical_scaling() self.failUnlessRaises(InconsistentScalingNodesError, cw.get_scaling_node_and_instance_names)
def test_no_scaling(self): """ No scaling is happening. Node instances are in terminal states. """ node_instances = { 'n.1': NodeInstance({NodeDecorator.NODE_INSTANCE_NAME_KEY: 'n.1', NodeDecorator.SCALE_STATE_KEY: CloudWrapper.SCALE_STATE_OPERATIONAL}), 'm.1': NodeInstance({NodeDecorator.NODE_INSTANCE_NAME_KEY: 'm.1', NodeDecorator.SCALE_STATE_KEY: CloudWrapper.SCALE_STATE_GONE}) } cw = CloudWrapper(self.config_holder) cw._get_nodes_instances = Mock(return_value=node_instances) assert {} == cw._get_effective_scale_states() assert None == cw._get_global_scale_state() assert False == cw.is_vertical_scaling() node_and_instances = cw.get_scaling_node_and_instance_names() assert '' == node_and_instances[0] assert [] == node_and_instances[1]
def test_consistent_scale_state_consistent_scaling_nodes(self): """ Consistent scale state: different scaling actions at a time are not allowed. In case node instance is not in a terminal state (as set on the NodeInstance object), we check the state directly on the Run (via CloudWrapper._get_runtime_parameter()). Consistent scaling nodes: only one node type at a time is allowed to be scaled. """ def _get_runtime_parameter(key): if key.endswith(NodeDecorator.NODE_PROPERTY_SEPARATOR + NodeDecorator.SCALE_STATE_KEY): return CloudWrapper.SCALE_STATE_RESIZING else: return 'unknown' node_instances = { 'n.1': NodeInstance({ NodeDecorator.NODE_INSTANCE_NAME_KEY: 'n.1', NodeDecorator.NODE_NAME_KEY: 'n', NodeDecorator.SCALE_STATE_KEY: 'not terminal' }), 'n.2': NodeInstance({ NodeDecorator.NODE_INSTANCE_NAME_KEY: 'n.2', NodeDecorator.NODE_NAME_KEY: 'n', NodeDecorator.SCALE_STATE_KEY: 'not terminal' }), 'm.1': NodeInstance({ NodeDecorator.NODE_INSTANCE_NAME_KEY: 'm.1', NodeDecorator.NODE_NAME_KEY: 'm', NodeDecorator.SCALE_STATE_KEY: CloudWrapper.SCALE_STATE_OPERATIONAL }) } cw = CloudWrapper(self.config_holder) cw._get_runtime_parameter = Mock(side_effect=_get_runtime_parameter) cw._get_nodes_instances = Mock(return_value=node_instances) scale_states = cw._get_effective_scale_states() assert 1 == len(scale_states) assert CloudWrapper.SCALE_STATE_RESIZING in scale_states assert 2 == len(scale_states[CloudWrapper.SCALE_STATE_RESIZING]) assert ['n.1', 'n.2' ] == sorted(scale_states[CloudWrapper.SCALE_STATE_RESIZING]) assert CloudWrapper.SCALE_STATE_RESIZING == cw._get_global_scale_state( ) try: cw.check_scale_state_consistency() except InconsistentScaleStateError as ex: self.fail('Should not have failed with: %s' % str(ex)) node_and_instances = cw.get_scaling_node_and_instance_names() assert 'n' == node_and_instances[0] assert ['n.1', 'n.2'] == sorted(node_and_instances[1])
def test_consistent_scale_state_inconsistent_scaling_nodes(self): """ Consistent scale state: only one scaling action at a time on different node instances. In case node instance is not in a terminal state (as set on the NodeInstance object), we check the state directly on the Run (via CloudWrapper._get_runtime_parameter()). Inconsistent scaling nodes: only one node type at a time is allowed to be scaled. """ def _get_runtime_parameter(key): if key.endswith(NodeDecorator.NODE_PROPERTY_SEPARATOR + NodeDecorator.SCALE_STATE_KEY): return CloudWrapper.SCALE_STATE_RESIZING else: return 'unknown' node_instances = { 'n.1': NodeInstance({ NodeDecorator.NODE_INSTANCE_NAME_KEY: 'n.1', NodeDecorator.NODE_NAME_KEY: 'n', NodeDecorator.SCALE_STATE_KEY: 'not terminal' }), 'n.2': NodeInstance({ NodeDecorator.NODE_INSTANCE_NAME_KEY: 'n.2', NodeDecorator.NODE_NAME_KEY: 'n', NodeDecorator.SCALE_STATE_KEY: CloudWrapper.SCALE_STATE_OPERATIONAL }), 'm.1': NodeInstance({ NodeDecorator.NODE_INSTANCE_NAME_KEY: 'm.1', NodeDecorator.NODE_NAME_KEY: 'm', NodeDecorator.SCALE_STATE_KEY: 'not terminal' }), 'm.2': NodeInstance({ NodeDecorator.NODE_INSTANCE_NAME_KEY: 'm.2', NodeDecorator.NODE_NAME_KEY: 'm', NodeDecorator.SCALE_STATE_KEY: CloudWrapper.SCALE_STATE_GONE }), } cw = CloudWrapper(self.config_holder) cw._get_runtime_parameter = Mock(side_effect=_get_runtime_parameter) cw._get_nodes_instances = Mock(return_value=node_instances) scale_states = cw._get_effective_scale_states() assert 1 == len(scale_states) assert CloudWrapper.SCALE_STATE_RESIZING in scale_states assert 2 == len(scale_states[CloudWrapper.SCALE_STATE_RESIZING]) assert ['m.1', 'n.1' ] == sorted(scale_states[CloudWrapper.SCALE_STATE_RESIZING]) assert CloudWrapper.SCALE_STATE_RESIZING == cw._get_global_scale_state( ) assert True == cw.is_vertical_scaling() self.failUnlessRaises(InconsistentScalingNodesError, cw.get_scaling_node_and_instance_names)