def test_post_op_del_nodes_not_in_pool(self, m_cluster_get, m_node_load, m_extract, m_load, m_conn): cluster_id = 'CLUSTER_ID' node1 = mock.Mock() node2 = mock.Mock() node1.data = {} node2.data = {'lb_member': 'MEMBER2_ID'} action = mock.Mock() action.outputs = {'nodes_removed': ['NODE1_ID', 'NODE2_ID']} action.context = 'action_context' action.action = consts.CLUSTER_RESIZE self.lb_driver.member_remove.return_value = True m_node_load.side_effect = [node1, node2] m_extract.return_value = { 'loadbalancer': 'LB_ID', 'listener': 'LISTENER_ID', 'pool': 'POOL_ID', 'healthmonitor': 'HM_ID' } policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) res = policy.post_op(cluster_id, action) self.assertIsNone(res) self.lb_driver.member_remove.assert_called_once_with( 'LB_ID', 'POOL_ID', 'MEMBER2_ID')
def test_post_op_add_nodes(self, m_get, m_remove, m_add, m_cluster_get, m_candidates, m_load): cid = 'CLUSTER_ID' cluster = mock.Mock(user='******', project='project1') m_cluster_get.return_value = cluster action = mock.Mock( context='action_context', action=consts.CLUSTER_RESIZE, data={'creation': { 'nodes': ['NODE1_ID', 'NODE2_ID'] }}) candidates = ['NODE1_ID', 'NODE2_ID'] m_get.return_value = candidates cp = mock.Mock() m_load.return_value = cp policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) policy._lbaasclient = self.lb_driver # do it res = policy.post_op(cid, action) # assertions self.assertIsNone(res) m_get.assert_called_once_with(action) m_cluster_get.assert_called_once_with('action_context', 'CLUSTER_ID') m_load.assert_called_once_with('action_context', cid, policy.id) m_add.assert_called_once_with(candidates, cp, action, self.lb_driver) self.assertFalse(m_remove.called)
def test_pre_op_del_nodes_failed(self, m_cluster_get, m_node_load, m_extract, m_load): cluster_id = 'CLUSTER_ID' node1 = mock.Mock() node1.data = {'lb_member': 'MEMBER1_ID'} action = mock.Mock(action=consts.CLUSTER_RESIZE, context='action_context', data={'deletion': { 'candidates': ['NODE1_ID'] }}) self.lb_driver.member_remove.return_value = False m_node_load.side_effect = [node1] m_extract.return_value = { 'loadbalancer': 'LB_ID', 'listener': 'LISTENER_ID', 'pool': 'POOL_ID', 'healthmonitor': 'HM_ID' } policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) policy._lbaasclient = self.lb_driver res = policy.pre_op(cluster_id, action) self.assertIsNone(res) self.assertEqual(policy_base.CHECK_ERROR, action.data['status']) self.assertEqual('Failed in removing deleted node(s) from lb pool.', action.data['reason']) self.lb_driver.member_remove.assert_called_once_with( 'LB_ID', 'POOL_ID', 'MEMBER1_ID')
def test_get_delete_candidates_deletion_no_candidates( self, m_nodes_random): self.context = utils.dummy_context() node1 = mock.Mock(id='node1') node2 = mock.Mock(id='node2') node3 = mock.Mock(id='node3') cluster = mock.Mock(id='cluster1') cluster.nodes = [node1, node2, node3] action = mock.Mock(action=consts.CLUSTER_RESIZE, data={}) action.entity = cluster action.data = {'deletion': {'count': 1}} m_nodes_random.return_value = ['node2'] policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) res = policy._get_delete_candidates('CLUSTERID', action) m_nodes_random.assert_called_once_with([node1, node2, node3], 1) self.assertEqual(['node2'], res) self.assertEqual({'deletion': { 'count': 1, 'candidates': ['node2'] }}, action.data)
def test_loadbalancer_value(self): spec = { 'type': 'senlin.policy.loadbalance', 'version': '1.0', 'properties': { 'loadbalancer': 'LB_ID', 'pool': { 'id': 'POOL_ID', 'subnet': 'internal-subnet' }, 'vip': { 'address': '192.168.1.100', 'subnet': 'external-subnet' }, 'health_monitor': { 'id': 'HM_ID' } } } self.spec['properties']['pool']['id'] = 'POOL_ID' self.spec['properties']['health_monitor']['id'] = 'HM_ID' self.spec['properties']['loadbalancer'] = 'LB_ID' self.spec['properties']['pool']['session_persistence'] = {} self.spec['properties']['vip']['connection_limit'] = -1 policy = lb_policy.LoadBalancingPolicy('test-policy', spec) self.assertIsNone(policy.id) self.assertEqual('test-policy', policy.name) self.assertEqual('senlin.policy.loadbalance-1.0', policy.type) self.assertEqual(self.spec['properties']['pool'], policy.pool_spec) self.assertEqual(self.spec['properties']['vip'], policy.vip_spec) self.assertEqual(self.spec['properties']['loadbalancer'], policy.lb)
def test_post_op_node_replace(self, m_get, m_remove, m_add, m_candidates, m_load): ctx = mock.Mock() cid = 'CLUSTER_ID' cluster = mock.Mock(user='******', project='project1') action = mock.Mock(data={}, context=ctx, action=consts.CLUSTER_REPLACE_NODES, inputs={'candidates': { 'OLD_NODE_ID': 'NEW_NODE_ID'}}) action.entity = cluster cp = mock.Mock() m_load.return_value = cp m_add.return_value = [] m_get.return_value = ['NEW_NODE_ID'] policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) policy._lbaasclient = self.lb_driver # do it res = policy.post_op(cid, action) # assertion self.assertIsNone(res) m_get.assert_called_once_with(action) m_load.assert_called_once_with(ctx, cid, policy.id) m_add.assert_called_once_with(ctx, ['NEW_NODE_ID'], cp, self.lb_driver) self.assertFalse(m_remove.called)
def test_get_delete_candidates_no_deletion_data_resize( self, m_nodes_random, m_parse_param): def _parse_param(action, cluster, current): action.data = {'deletion': {'count': 2}} self.context = utils.dummy_context() node1 = mock.Mock(id='node1') node2 = mock.Mock(id='node2') node3 = mock.Mock(id='node3') cluster = mock.Mock(id='cluster1') cluster.nodes = [node1, node2, node3] action = mock.Mock(action=consts.CLUSTER_RESIZE, data={}) action.entity = cluster m_parse_param.side_effect = _parse_param m_nodes_random.return_value = ['node1', 'node3'] policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) res = policy._get_delete_candidates('CLUSTERID', action) m_parse_param.assert_called_once_with(action, cluster, 3) m_nodes_random.assert_called_once_with([node1, node2, node3], 2) self.assertEqual(['node1', 'node3'], res)
def test_post_op_node_recover(self, m_get, m_recovery, m_add, m_candidates, m_load): cid = 'CLUSTER_ID' node = mock.Mock(user='******', project='project1', id='NODE1') action = mock.Mock(context='action_context', action=consts.NODE_RECOVER, data={}, outputs={}, inputs={'action_result': 'OK'}) action.entity = node m_recovery.return_value = ['NODE1'] m_get.return_value = ['NODE1'] cp = mock.Mock() m_load.return_value = cp policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) policy._lbaasclient = self.lb_driver # do it res = policy.post_op(cid, action) # assertions self.assertIsNone(res) m_get.assert_called_once_with(action) m_load.assert_called_once_with('action_context', cid, policy.id) m_add.assert_called_once_with(action.context, ['NODE1'], cp, self.lb_driver) m_recovery.assert_called_once_with(['NODE1'], cp, self.lb_driver, action)
def test_post_op_node_recover(self, m_get, m_remove, m_add, m_cluster_get, m_candidates, m_load): cid = 'CLUSTER_ID' cluster = mock.Mock(user='******', project='project1') m_cluster_get.return_value = cluster action = mock.Mock(context='action_context', action=consts.NODE_RECOVER, data={}, outputs={ 'recovery': { 'action': consts.RECOVER_RECREATE, 'node': ['NODE1'] } }) m_get.return_value = ['NODE1'] cp = mock.Mock() m_load.return_value = cp policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) policy._lbaasclient = self.lb_driver # do it res = policy.post_op(cid, action) # assertions self.assertIsNone(res) m_get.assert_called_once_with(action) m_cluster_get.assert_called_once_with('action_context', 'CLUSTER_ID') m_load.assert_called_once_with('action_context', cid, policy.id) m_add.assert_called_once_with(['NODE1'], cp, action, self.lb_driver) m_remove.assert_called_once_with(['NODE1'], cp, action, self.lb_driver, handle_err=False)
def test_attach_succeeded(self, m_conn, m_attach, m_load, m_build): cluster = mock.Mock() cluster.id = 'CLUSTER_ID' node1 = mock.Mock() node2 = mock.Mock() m_attach.return_value = (True, None) m_load.return_value = [node1, node2] m_build.return_value = 'policy_data' data = {'loadbalancer': 'LB_ID', 'pool': 'POOL_ID'} policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) self.lb_driver.lb_create.return_value = (True, data) self.lb_driver.member_add.side_effect = ['MEMBER1_ID', 'MEMBER2_ID'] res, data = policy.attach(cluster) self.assertTrue(res) self.assertEqual('policy_data', data) self.lb_driver.lb_create.assert_called_once_with( policy.vip_spec, policy.pool_spec) m_load.assert_called_once_with(mock.ANY, cluster_id=cluster.id) member_add_calls = [ mock.call(node1, 'LB_ID', 'POOL_ID', 80, 'test-subnet'), mock.call(node2, 'LB_ID', 'POOL_ID', 80, 'test-subnet') ] self.lb_driver.member_add.assert_has_calls(member_add_calls) node1.data.update.assert_called_once_with({'lb_member': 'MEMBER1_ID'}) node2.data.update.assert_called_once_with({'lb_member': 'MEMBER2_ID'}) node1.store.assert_called_once_with(mock.ANY) node2.store.assert_called_once_with(mock.ANY)
def test_post_op_add_nodes_failed(self, m_cluster_get, m_node_load, m_extract, m_load): cluster_id = 'CLUSTER_ID' node1 = mock.Mock(data={}) action = mock.Mock(data={'creation': { 'nodes': ['NODE1_ID'] }}, context='action_context', action=consts.CLUSTER_RESIZE) self.lb_driver.member_add.return_value = None m_node_load.side_effect = [node1] m_extract.return_value = { 'loadbalancer': 'LB_ID', 'listener': 'LISTENER_ID', 'pool': 'POOL_ID', 'healthmonitor': 'HM_ID' } policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) policy._lbaasclient = self.lb_driver res = policy.post_op(cluster_id, action) self.assertIsNone(res) self.assertEqual(policy_base.CHECK_ERROR, action.data['status']) self.assertEqual('Failed in adding new node(s) into lb pool.', action.data['reason']) self.lb_driver.member_add.assert_called_once_with( node1, 'LB_ID', 'POOL_ID', 80, 'test-subnet')
def test_post_op_clusterresize_failed(self, m_get, m_remove, m_add, m_cluster_get, m_candidates, m_load): cluster_id = 'CLUSTER_ID' action = mock.Mock(data={'creation': { 'nodes': ['NODE1_ID'] }}, context='action_context', action=consts.CLUSTER_RESIZE) cp = mock.Mock() m_load.return_value = cp m_get.return_value = ['NODE1_ID'] m_add.return_value = ['NODE1_ID'] policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) policy._lbaasclient = self.lb_driver res = policy.post_op(cluster_id, action) self.assertIsNone(res) self.assertEqual(policy_base.CHECK_ERROR, action.data['status']) self.assertEqual( "Failed in adding nodes into lb pool: " "['NODE1_ID']", action.data['reason']) m_get.assert_called_once_with(action) m_add.assert_called_once_with(['NODE1_ID'], cp, action, self.lb_driver) self.assertFalse(m_remove.called)
def test_post_op_add_nodes_in_pool(self, m_cluster_get, m_node_load, m_extract, m_load): cluster_id = 'CLUSTER_ID' node1 = mock.Mock(data={'lb_member': 'MEMBER1_ID'}) node2 = mock.Mock(data={}) action = mock.Mock( action=consts.CLUSTER_RESIZE, context='action_context', data={'creation': { 'nodes': ['NODE1_ID', 'NODE2_ID'] }}) policy_data = { 'loadbalancer': 'LB_ID', 'listener': 'LISTENER_ID', 'pool': 'POOL_ID', 'healthmonitor': 'HM_ID' } self.lb_driver.member_add.side_effect = ['MEMBER2_ID'] m_node_load.side_effect = [node1, node2] m_extract.return_value = policy_data policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) policy._lbaasclient = self.lb_driver res = policy.post_op(cluster_id, action) self.assertIsNone(res) self.lb_driver.member_add.assert_called_once_with( node2, 'LB_ID', 'POOL_ID', 80, 'test-subnet')
def test_pre_op_del_nodes_not_in_pool(self, m_cluster_get, m_node_load, m_extract, m_load): cluster_id = 'CLUSTER_ID' node1 = mock.Mock(data={}) node2 = mock.Mock(data={'lb_member': 'MEMBER2_ID'}) action = mock.Mock( action=consts.CLUSTER_RESIZE, context='action_context', data={'deletion': { 'candidates': ['NODE1_ID', 'NODE2_ID'] }}) self.lb_driver.member_remove.return_value = True m_node_load.side_effect = [node1, node2] m_extract.return_value = { 'loadbalancer': 'LB_ID', 'listener': 'LISTENER_ID', 'pool': 'POOL_ID', 'healthmonitor': 'HM_ID' } policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) policy._lbaasclient = self.lb_driver res = policy.pre_op(cluster_id, action) self.assertIsNone(res) self.lb_driver.member_remove.assert_called_once_with( 'LB_ID', 'POOL_ID', 'MEMBER2_ID')
def test_pre_op_del_nodes_ok(self, m_remove, m_cluster_get, m_candidates, m_load): cluster_id = 'CLUSTER_ID' cluster = mock.Mock(user='******', project='project1') m_cluster_get.return_value = cluster action = mock.Mock(context='action_context', action=consts.CLUSTER_DEL_NODES, data={ 'deletion': { 'count': 2, 'candidates': ['NODE1_ID', 'NODE2_ID'] } }) m_candidates.return_value = ['NODE1_ID', 'NODE2_ID'] cp = mock.Mock() m_load.return_value = cp m_remove.return_value = [] policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) policy._lbaasclient = self.lb_driver res = policy.pre_op(cluster_id, action) self.assertIsNone(res) m_cluster_get.assert_called_once_with('action_context', 'CLUSTER_ID') m_load.assert_called_once_with('action_context', cluster_id, policy.id) expected_data = { 'deletion': { 'candidates': ['NODE1_ID', 'NODE2_ID'], 'count': 2 } } self.assertEqual(expected_data, action.data)
def test_detach_succeeded(self, m_extract, m_load, m_conn): cluster = mock.Mock() cluster.id = 'CLUSTER_ID' cp = mock.Mock() policy_data = { 'loadbalancer': 'LB_ID', 'listener': 'LISTENER_ID', 'pool': 'POOL_ID', 'healthmonitor': 'HM_ID' } cp_data = { 'LoadBalancingPolicy': { 'version': '1.0', 'data': policy_data } } cp.data = cp_data m_load.return_value = cp m_extract.return_value = policy_data self.lb_driver.lb_delete.return_value = (True, 'lb_delete succeeded.') policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) res, data = policy.detach(cluster) self.assertTrue(res) self.assertEqual('lb_delete succeeded.', data) m_load.assert_called_once_with(mock.ANY, cluster.id, policy.id) m_extract.assert_called_once_with(cp_data) self.lb_driver.lb_delete.assert_called_once_with(**policy_data)
def test_post_op_node_create(self, m_get, m_remove, m_add, m_cluster_get, m_candidates, m_load): ctx = mock.Mock() cid = 'CLUSTER_ID' cluster = mock.Mock(user='******', project='project1') m_cluster_get.return_value = cluster action = mock.Mock(data={}, context=ctx, action=consts.NODE_CREATE, node=mock.Mock(id='NODE_ID')) cp = mock.Mock() m_load.return_value = cp m_add.return_value = [] m_get.return_value = ['NODE_ID'] policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) policy._lbaasclient = self.lb_driver # do it res = policy.post_op(cid, action) # assertion self.assertIsNone(res) m_get.assert_called_once_with(action) m_cluster_get.assert_called_once_with(ctx, 'CLUSTER_ID') m_load.assert_called_once_with(ctx, cid, policy.id) m_add.assert_called_once_with(['NODE_ID'], cp, action, self.lb_driver) self.assertFalse(m_remove.called)
def test_post_candidates_node_recover_empty(self): action = mock.Mock(action=consts.NODE_RECOVER, outputs={}) policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) candidates = policy._get_post_candidates(action) self.assertEqual([], candidates)
def test_pre_op_del_nodes_ok(self, m_cluster_get, m_node_load, m_extract, m_load): cluster_id = 'CLUSTER_ID' cluster = mock.Mock(user='******', project='project1') m_cluster_get.return_value = cluster node1 = mock.Mock(data={'lb_member': 'MEMBER1_ID'}) node2 = mock.Mock(data={'lb_member': 'MEMBER2_ID'}) action = mock.Mock(context='action_context', action=consts.CLUSTER_DEL_NODES, data={ 'deletion': { 'count': 2, 'candidates': ['NODE1_ID', 'NODE2_ID'] } }) cp = mock.Mock() policy_data = { 'loadbalancer': 'LB_ID', 'listener': 'LISTENER_ID', 'pool': 'POOL_ID', 'healthmonitor': 'HM_ID' } cp_data = { 'LoadBalancingPolicy': { 'version': '1.0', 'data': policy_data } } cp.data = cp_data self.lb_driver.member_remove.return_value = True m_node_load.side_effect = [node1, node2] m_load.return_value = cp m_extract.return_value = policy_data policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) policy._lbaasclient = self.lb_driver res = policy.pre_op(cluster_id, action) self.assertIsNone(res) m_cluster_get.assert_called_once_with('action_context', 'CLUSTER_ID') m_load.assert_called_once_with('action_context', cluster_id, policy.id) m_extract.assert_called_once_with(cp_data) calls_node_load = [ mock.call(mock.ANY, node_id='NODE1_ID'), mock.call(mock.ANY, node_id='NODE2_ID') ] m_node_load.assert_has_calls(calls_node_load) calls_member_del = [ mock.call('LB_ID', 'POOL_ID', 'MEMBER1_ID'), mock.call('LB_ID', 'POOL_ID', 'MEMBER2_ID') ] self.lb_driver.member_remove.assert_has_calls(calls_member_del) expected_data = { 'deletion': { 'candidates': ['NODE1_ID', 'NODE2_ID'], 'count': 2 } } self.assertEqual(expected_data, action.data)
def test_post_op_no_nodes(self, m_extract, m_load): action = mock.Mock(data={}) policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) res = policy.post_op('FAKE_ID', action) self.assertIsNone(res)
def test_get_delete_candidates_deletion_with_candidates(self): action = mock.Mock() action.data = {'deletion': {'count': 1, 'candidates': ['node3']}} policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) res = policy._get_delete_candidates('CLUSTERID', action) self.assertEqual(['node3'], res)
def test_get_delete_candidates_deletion_count_is_zero(self): self.context = utils.dummy_context() action = mock.Mock(data={'deletion': {'number': 3}}) policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) res = policy._get_delete_candidates('CLUSTERID', action) self.assertEqual([], res)
def test_validate_shallow(self, mock_validate): policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) ctx = mock.Mock() res = policy.validate(ctx, False) self.assertTrue(res) mock_validate.assert_called_with(ctx, False)
def test_get_delete_candidates_no_deletion_data_del_nodes(self): action = mock.Mock(action=consts.CLUSTER_DEL_NODES, data={}, inputs={'candidates': ['node1', 'node2']}) policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) res = policy._get_delete_candidates('CLUSTERID', action) self.assertEqual(['node1', 'node2'], res)
def test_get_post_candidates_node_create(self): action = mock.Mock(action=consts.NODE_CREATE, node=mock.Mock(id='NODE')) policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) candidates = policy._get_post_candidates(action) self.assertEqual(['NODE'], candidates)
def test_get_delete_candidates_for_node_delete(self): action = mock.Mock(action=consts.NODE_DELETE, inputs={}, data={}, entity=mock.Mock(id='NODE_ID')) policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) res = policy._get_delete_candidates('CLUSTERID', action) self.assertEqual(['NODE_ID'], res)
def test_detach_no_policy_data(self, m_extract, m_load, m_conn): cluster = mock.Mock() m_extract.return_value = None policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) res, data = policy.detach(cluster) self.assertTrue(res) self.assertEqual('LB resources deletion succeeded.', data)
def test_init(self, mock_validate): policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) self.assertIsNone(policy.id) self.assertEqual('test-policy', policy.name) self.assertEqual('senlin.policy.loadbalance-1.0', policy.type) self.assertEqual(self.spec['properties']['pool'], policy.pool_spec) self.assertEqual(self.spec['properties']['vip'], policy.vip_spec) self.assertIsNone(policy.lb)
def test_attach_failed_base_return_false(self, mock_attach): cluster = mock.Mock() policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) mock_attach.return_value = (False, 'data') res, data = policy.attach(cluster) self.assertFalse(res) self.assertEqual('data', data)
def test_detach_failed_lb_delete(self, m_extract, m_load, m_conn): cluster = mock.Mock() self.lb_driver.lb_delete.return_value = (False, 'lb_delete failed.') policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec) res, data = policy.detach(cluster) self.assertFalse(res) self.assertEqual('lb_delete failed.', data)