def test_no_draining(self): """ Doesnt fetch feeds if all nodes are ENABLED """ seq = [ lb_req('loadbalancers', True, {'loadBalancers': [{ 'id': 1 }, { 'id': 2 }]}), parallel_sequence([[nodes_req(1, [node('11', 'a11')])], [nodes_req(2, [node('21', 'a21')])], [lb_hm_req(1, {})], [lb_hm_req(2, {})]]), parallel_sequence([]) # No nodes to fetch ] make_desc = partial(CLBDescription, port=20, weight=2, condition=CLBNodeCondition.ENABLED, type=CLBNodeType.PRIMARY) eff = get_clb_contents() self.assertEqual(perform_sequence(seq, eff), ([ CLBNode( node_id='11', address='a11', description=make_desc(lb_id='1')), CLBNode( node_id='21', address='a21', description=make_desc(lb_id='2')) ], { '1': CLB(False), '2': CLB(False) }))
def test_success(self): """ The data is returned as a tuple of ([NovaServer], [CLBNode/RCv3Node]). """ clb_nodes = [CLBNode(node_id='node1', address='ip1', description=CLBDescription(lb_id='lb1', port=80))] rcv3_nodes = [RCv3Node(node_id='node2', cloud_server_id='a', description=RCv3Description(lb_id='lb2'))] eff = get_all_launch_server_data( 'tid', 'gid', self.now, get_scaling_group_servers=_constant_as_eff( ('tid', 'gid', self.now), self.servers), get_clb_contents=_constant_as_eff((), clb_nodes), get_rcv3_contents=_constant_as_eff((), rcv3_nodes)) expected_servers = [ server('a', ServerState.ACTIVE, servicenet_address='10.0.0.1', links=freeze([{'href': 'link1', 'rel': 'self'}]), json=freeze(self.servers[0])), server('b', ServerState.ACTIVE, created=1, servicenet_address='10.0.0.2', links=freeze([{'href': 'link2', 'rel': 'self'}]), json=freeze(self.servers[1])) ] self.assertEqual(resolve_stubs(eff), {'servers': expected_servers, 'lb_nodes': clb_nodes + rcv3_nodes})
def test_active_if_node_is_draining(self): """ If the node is DRAINING, :func:`CLBNode.is_active` returns `True`. """ node = CLBNode(node_id='1234', description=self.drain_desc, address='10.1.1.1', drained_at=0.0, connections=1) self.assertTrue(node.is_active())
def test_current_draining_false_if_description_not_draining(self): """ :func:`CLBNode.currently_draining` returns `False` if `CLBNode.description.condition` is not :obj:`CLBNodeCondition.DRAINING` """ node = CLBNode(node_id='1234', description=self.desc, address='10.1.1.1') self.assertFalse(node.currently_draining())
def test_lb_disappeared_during_node_fetch(self): """ If a load balancer gets deleted while fetching nodes, no nodes will be returned for it. """ seq = [ lb_req('loadbalancers', True, {'loadBalancers': [{ 'id': 1 }, { 'id': 2 }]}), parallel_sequence([[nodes_req(1, [node('11', 'a11')])], [ lb_req('loadbalancers/2/nodes', True, CLBNotFoundError(lb_id=u'2')) ], [lb_hm_req(1, {"type": "CONNECT"})], [ lb_req('loadbalancers/2/healthmonitor', True, CLBNotFoundError(lb_id=u'2')) ]]), parallel_sequence([]) # No node feeds to fetch ] make_desc = partial(CLBDescription, port=20, weight=2, condition=CLBNodeCondition.ENABLED, type=CLBNodeType.PRIMARY) eff = get_clb_contents() self.assertEqual(perform_sequence(seq, eff), ([ CLBNode( node_id='11', address='a11', description=make_desc(lb_id='1')) ], { '1': CLB(True) }))
def test_done_draining_before_timeout_if_there_are_no_connections(self): """ If there are zero connections, but the node has been in draining less than the timeout, :func:`CLBNode.is_done_draining` returns `True`. """ node = CLBNode(node_id='1234', description=self.drain_desc, address='10.1.1.1', drained_at=0.0, connections=0) self.assertTrue(node.is_done_draining(now=15, timeout=30))
def test_done_draining_past_timeout_even_if_there_are_connections(self): """ If there are still connections, but the node has been in draining past the timeout, :func:`CLBNode.is_done_draining` returns `True`. """ node = CLBNode(node_id='1234', description=self.drain_desc, address='10.1.1.1', drained_at=0.0, connections=1) self.assertTrue(node.is_done_draining(now=30, timeout=15))
def test_current_draining_true_if_description_is_draining(self): """ :func:`CLBNode.currently_draining` returns `True` if `CLBNode.description.condition` is :obj:`CLBNodeCondition.DRAINING` """ node = CLBNode(node_id='1234', description=self.drain_desc, address='10.1.1.1') self.assertTrue(node.currently_draining())
def test_provides_ILBDescription_and_IDrainable(self): """ An instance of :class:`CLBNode` provides :class:`ILBNode` and :class:`IDrainable`. """ node = CLBNode(node_id='1234', description=self.desc, address='10.1.1.1') self.assertTrue(ILBNode.providedBy(node)) self.assertTrue(IDrainable.providedBy(node))
def test_not_done_draining_before_timeout_if_no_connection_info(self): """ If connection information is not provided, and the node has been in draining less than the timeout, :func:`CLBNode.is_done_draining` returns `False`. """ node = CLBNode(node_id='1234', description=self.drain_desc, address='10.1.1.1', drained_at=0.0) self.assertFalse(node.is_done_draining(now=15, timeout=30))
def test_done_draining_past_timeout_even_if_no_connection_info(self): """ If connection information is not provided, and the node has been in draining past the timeout, :func:`CLBNode.is_done_draining` returns `True`. """ node = CLBNode(node_id='1234', description=self.drain_desc, address='10.1.1.1', drained_at=0.0) self.assertTrue(node.is_done_draining(now=30, timeout=15))
def test_matches_only_works_with_NovaServers(self): """ :func:`CLBNode.matches` returns false if the server is not an instance of :class:`NovaServer`. """ node = CLBNode(node_id='1234', description=self.desc, address='10.1.1.1') self.assertFalse( node.matches(DummyServer(servicenet_address="10.1.1.1")))
def test_inactive_if_node_is_disabled(self): """ If the node is DRAINING, :func:`CLBNode.is_active` returns `True`. """ node = CLBNode(node_id='1234', description=CLBDescription( lb_id='12345', port=80, condition=CLBNodeCondition.DISABLED), address='10.1.1.1', drained_at=0.0, connections=1) self.assertFalse(node.is_active())
def test_matches_only_if_server_address_matches_node_address(self): """ :func:`CLBNode.matches` returns True only if the :class:`NovaServer` has the same ServiceNet address as the node address """ node = CLBNode(node_id='1234', description=self.desc, address='10.1.1.1') self.assertFalse(node.matches( NovaServer(id='1', state=ServerState.ACTIVE, created=0.0, servicenet_address="10.1.1.2", image_id='image', flavor_id='flavor'))) self.assertTrue(node.matches( NovaServer(id='1', state=ServerState.ACTIVE, created=0.0, servicenet_address="10.1.1.1", image_id='image', flavor_id='flavor')))
def test_from_node_json_no_weight(self): """ A node's JSON representation can be parsed to a :obj:`CLBNode` object with a `CLBDescription`. When weight is not specified it defaults to 1. """ node_json = {'id': 'node1', 'address': '1.2.3.4', 'port': 20, 'condition': 'DRAINING', 'type': 'SECONDARY'} node = CLBNode.from_node_json(123, node_json) self.assertEqual( node, CLBNode(node_id='node1', address='1.2.3.4', connections=None, drained_at=0.0, description=CLBDescription( lb_id='123', port=20, weight=1, condition=CLBNodeCondition.DRAINING, type=CLBNodeType.SECONDARY)))