| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| package com.cloud.network.lb; |
| |
| import com.cloud.exception.ResourceUnavailableException; |
| import com.cloud.network.Network; |
| import com.cloud.network.NetworkModel; |
| import com.cloud.network.dao.LoadBalancerCertMapDao; |
| import com.cloud.network.dao.LoadBalancerCertMapVO; |
| import com.cloud.network.dao.LoadBalancerDao; |
| import com.cloud.network.dao.LoadBalancerVO; |
| import com.cloud.network.dao.NetworkDao; |
| import com.cloud.network.dao.NetworkVO; |
| import com.cloud.network.dao.SslCertVO; |
| import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; |
| import com.cloud.user.Account; |
| import com.cloud.user.AccountManager; |
| import com.cloud.user.AccountVO; |
| import com.cloud.user.User; |
| import com.cloud.user.UserVO; |
| import com.cloud.utils.db.EntityManager; |
| import com.cloud.utils.exception.CloudRuntimeException; |
| import com.cloud.utils.net.NetUtils; |
| import org.apache.cloudstack.acl.SecurityChecker; |
| import org.apache.cloudstack.api.ApiConstants; |
| import org.apache.cloudstack.api.ServerApiException; |
| import org.apache.cloudstack.api.command.user.loadbalancer.UpdateLoadBalancerRuleCmd; |
| import org.apache.cloudstack.context.CallContext; |
| import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; |
| import org.junit.Assert; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.mockito.InjectMocks; |
| import org.mockito.Mock; |
| import org.mockito.Mockito; |
| import org.mockito.Spy; |
| import org.mockito.junit.MockitoJUnitRunner; |
| import org.springframework.test.util.ReflectionTestUtils; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.List; |
| import java.util.UUID; |
| |
| import static org.mockito.ArgumentMatchers.anyLong; |
| import static org.mockito.Mockito.never; |
| import static org.mockito.Mockito.times; |
| import static org.mockito.Mockito.when; |
| |
| @RunWith(MockitoJUnitRunner.class) |
| public class LoadBalancingRulesManagerImplTest{ |
| |
| @Mock |
| NetworkDao _networkDao; |
| |
| @Mock |
| NetworkOrchestrationService _networkMgr; |
| |
| @Mock |
| LoadBalancerDao _lbDao; |
| |
| @Mock |
| EntityManager _entityMgr; |
| |
| @Mock |
| AccountManager _accountMgr; |
| |
| @Mock |
| NetworkModel _networkModel; |
| |
| @Mock |
| LoadBalancerCertMapDao _lbCertMapDao; |
| |
| @Mock |
| NetworkOfferingServiceMapDao _networkOfferingServiceDao; |
| |
| @Spy |
| @InjectMocks |
| LoadBalancingRulesManagerImpl lbr = new LoadBalancingRulesManagerImpl(); |
| |
| @Mock |
| NetworkVO networkMock; |
| |
| @Mock |
| LoadBalancerVO loadBalancerMock; |
| |
| private long accountId = 10L; |
| private long lbRuleId = 2L; |
| private long certMapRuleId = 3L; |
| private long networkId = 4L; |
| |
| @Test |
| public void generateCidrStringTestNullCidrList() { |
| String result = lbr.generateCidrString(null); |
| Assert.assertNull(result); |
| } |
| |
| @Test |
| public void generateCidrStringTestWithCidrList() { |
| List<String> cidrList = new ArrayList<>(); |
| cidrList.add("1.1.1.1"); |
| cidrList.add("2.2.2.2/24"); |
| String result = lbr.generateCidrString(cidrList); |
| Assert.assertEquals("1.1.1.1 2.2.2.2/24", result); |
| } |
| |
| @Test (expected = ServerApiException.class) |
| public void generateCidrStringTestWithInvalidCidrList() { |
| List<String> cidrList = new ArrayList<>(); |
| cidrList.add("1.1"); |
| cidrList.add("2.2.2.2/24"); |
| String result = lbr.generateCidrString(cidrList); |
| Assert.assertEquals("1.1.1.1 2.2.2.2/24", result); |
| } |
| |
| @Test |
| public void testGetLoadBalancerServiceProvider() { |
| LoadBalancerVO loadBalancerMock = Mockito.mock(LoadBalancerVO.class); |
| NetworkVO networkMock = Mockito.mock(NetworkVO.class); |
| List<Network.Provider> providers = Arrays.asList(Network.Provider.VirtualRouter); |
| |
| when(loadBalancerMock.getNetworkId()).thenReturn(10L); |
| when(_networkDao.findById(anyLong())).thenReturn(networkMock); |
| when(_networkMgr.getProvidersForServiceInNetwork(networkMock, Network.Service.Lb)).thenReturn(providers); |
| |
| Network.Provider provider = lbr.getLoadBalancerServiceProvider(loadBalancerMock); |
| |
| Assert.assertEquals(Network.Provider.VirtualRouter, provider); |
| } |
| |
| @Test(expected = CloudRuntimeException.class) |
| public void testGetLoadBalancerServiceProviderFail() { |
| LoadBalancerVO loadBalancerMock = Mockito.mock(LoadBalancerVO.class); |
| NetworkVO networkMock = Mockito.mock(NetworkVO.class); |
| |
| when(_networkDao.findById(Mockito.any())).thenReturn(networkMock); |
| when(_networkMgr.getProvidersForServiceInNetwork(networkMock, Network.Service.Lb)).thenReturn(new ArrayList<>()); |
| |
| Network.Provider provider = lbr.getLoadBalancerServiceProvider(loadBalancerMock); |
| } |
| |
| @Test |
| public void testAssignCertToLoadBalancer() throws Exception { |
| long accountId = 10L; |
| long lbRuleId = 2L; |
| long certId = 3L; |
| long networkId = 4L; |
| |
| AccountVO account = new AccountVO("testaccount", 1L, "networkdomain", Account.Type.NORMAL, "uuid"); |
| account.setId(accountId); |
| UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", |
| UUID.randomUUID().toString(), User.Source.UNKNOWN); |
| CallContext.register(user, account); |
| |
| LoadBalancerVO loadBalancerMock = Mockito.mock(LoadBalancerVO.class); |
| when(_lbDao.findById(lbRuleId)).thenReturn(loadBalancerMock); |
| when(loadBalancerMock.getId()).thenReturn(lbRuleId); |
| when(loadBalancerMock.getAccountId()).thenReturn(accountId); |
| when(loadBalancerMock.getNetworkId()).thenReturn(networkId); |
| when(loadBalancerMock.getLbProtocol()).thenReturn(NetUtils.SSL_PROTO); |
| |
| SslCertVO certVO = Mockito.mock(SslCertVO.class); |
| when(_entityMgr.findById(SslCertVO.class, certId)).thenReturn(certVO); |
| when(certVO.getAccountId()).thenReturn(accountId); |
| |
| LoadBalancerCertMapVO certMapRule = Mockito.mock(LoadBalancerCertMapVO.class); |
| when(_lbCertMapDao.findByLbRuleId(lbRuleId)).thenReturn(certMapRule); |
| |
| Mockito.doNothing().when(_accountMgr).checkAccess(Mockito.any(Account.class), Mockito.isNull(SecurityChecker.AccessType.class), Mockito.eq(true), Mockito.any(LoadBalancerVO.class)); |
| |
| Mockito.doReturn("LB").when(lbr).getLBCapability(networkId, Network.Capability.SslTermination.getName()); |
| Mockito.doReturn(true).when(lbr).applyLoadBalancerConfig(lbRuleId); |
| |
| lbr.assignCertToLoadBalancer(lbRuleId, certId, true); |
| |
| Mockito.verify(lbr, times(2)).applyLoadBalancerConfig(lbRuleId); |
| } |
| |
| private void setupUpdateLoadBalancerRule() throws Exception{ |
| AccountVO account = new AccountVO("testaccount", 1L, "networkdomain", Account.Type.NORMAL, "uuid"); |
| account.setId(accountId); |
| UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", |
| UUID.randomUUID().toString(), User.Source.UNKNOWN); |
| CallContext.register(user, account); |
| |
| when(_lbDao.findById(lbRuleId)).thenReturn(loadBalancerMock); |
| when(loadBalancerMock.getId()).thenReturn(lbRuleId); |
| when(loadBalancerMock.getNetworkId()).thenReturn(networkId); |
| |
| when(_networkDao.findById(networkId)).thenReturn(networkMock); |
| |
| Mockito.doNothing().when(_accountMgr).checkAccess(Mockito.any(Account.class), Mockito.isNull(SecurityChecker.AccessType.class), Mockito.eq(true), Mockito.any(LoadBalancerVO.class)); |
| |
| LoadBalancingRule loadBalancingRule = Mockito.mock(LoadBalancingRule.class); |
| Mockito.doReturn(loadBalancingRule).when(lbr).getLoadBalancerRuleToApply(loadBalancerMock); |
| Mockito.doReturn(true).when(lbr).validateLbRule(loadBalancingRule); |
| Mockito.doReturn(true).when(lbr).applyLoadBalancerConfig(lbRuleId); |
| |
| when(_lbDao.update(lbRuleId, loadBalancerMock)).thenReturn(true); |
| |
| LoadBalancerCertMapVO certMapRule = Mockito.mock(LoadBalancerCertMapVO.class); |
| when(_lbCertMapDao.findByLbRuleId(lbRuleId)).thenReturn(certMapRule); |
| when(certMapRule.getId()).thenReturn(certMapRuleId); |
| } |
| |
| @Test |
| public void testUpdateLoadBalancerRule1() throws Exception { |
| setupUpdateLoadBalancerRule(); |
| |
| // Update protocol from TCP to SSL |
| UpdateLoadBalancerRuleCmd cmd = new UpdateLoadBalancerRuleCmd(); |
| ReflectionTestUtils.setField(cmd, ApiConstants.ID, lbRuleId); |
| ReflectionTestUtils.setField(cmd, "lbProtocol", NetUtils.SSL_PROTO); |
| when(loadBalancerMock.getLbProtocol()).thenReturn(NetUtils.TCP_PROTO).thenReturn(NetUtils.SSL_PROTO); |
| |
| lbr.updateLoadBalancerRule(cmd); |
| |
| Mockito.verify(lbr, times(1)).applyLoadBalancerConfig(lbRuleId); |
| Mockito.verify(_lbCertMapDao, never()).remove(anyLong()); |
| } |
| |
| @Test |
| public void testUpdateLoadBalancerRule2() throws Exception { |
| setupUpdateLoadBalancerRule(); |
| |
| // Update protocol from SSL to TCP |
| UpdateLoadBalancerRuleCmd cmd = new UpdateLoadBalancerRuleCmd(); |
| ReflectionTestUtils.setField(cmd, ApiConstants.ID, lbRuleId); |
| ReflectionTestUtils.setField(cmd, "lbProtocol", NetUtils.TCP_PROTO); |
| when(loadBalancerMock.getLbProtocol()).thenReturn(NetUtils.SSL_PROTO).thenReturn(NetUtils.TCP_PROTO); |
| |
| lbr.updateLoadBalancerRule(cmd); |
| |
| Mockito.verify(_lbCertMapDao, times(1)).remove(anyLong()); |
| Mockito.verify(lbr, times(1)).applyLoadBalancerConfig(lbRuleId); |
| } |
| |
| @Test |
| public void testUpdateLoadBalancerRule3() throws Exception { |
| setupUpdateLoadBalancerRule(); |
| |
| // Update algorithm from source to roundrobin, lb protocol is same |
| UpdateLoadBalancerRuleCmd cmd = new UpdateLoadBalancerRuleCmd(); |
| ReflectionTestUtils.setField(cmd, ApiConstants.ID, lbRuleId); |
| ReflectionTestUtils.setField(cmd, "algorithm", "roundrobin"); |
| ReflectionTestUtils.setField(cmd, "lbProtocol", NetUtils.SSL_PROTO); |
| when(loadBalancerMock.getAlgorithm()).thenReturn("source"); |
| when(loadBalancerMock.getLbProtocol()).thenReturn(NetUtils.SSL_PROTO); |
| |
| lbr.updateLoadBalancerRule(cmd); |
| |
| Mockito.verify(lbr, times(1)).applyLoadBalancerConfig(lbRuleId); |
| Mockito.verify(_lbCertMapDao, never()).remove(anyLong()); |
| } |
| |
| @Test |
| public void testUpdateLoadBalancerRule4() throws Exception { |
| setupUpdateLoadBalancerRule(); |
| |
| // Update with same algorithm and protocol |
| UpdateLoadBalancerRuleCmd cmd = new UpdateLoadBalancerRuleCmd(); |
| ReflectionTestUtils.setField(cmd, ApiConstants.ID, lbRuleId); |
| ReflectionTestUtils.setField(cmd, "algorithm", "roundrobin"); |
| ReflectionTestUtils.setField(cmd, "lbProtocol", NetUtils.SSL_PROTO); |
| when(loadBalancerMock.getAlgorithm()).thenReturn("roundrobin"); |
| when(loadBalancerMock.getLbProtocol()).thenReturn(NetUtils.SSL_PROTO); |
| |
| lbr.updateLoadBalancerRule(cmd); |
| |
| Mockito.verify(lbr, never()).applyLoadBalancerConfig(lbRuleId); |
| Mockito.verify(_lbCertMapDao, never()).remove(anyLong()); |
| } |
| |
| @Test(expected = CloudRuntimeException.class) |
| public void testUpdateLoadBalancerRule5() throws Exception { |
| setupUpdateLoadBalancerRule(); |
| |
| // Update protocol from SSL to TCP, throws an exception |
| UpdateLoadBalancerRuleCmd cmd = new UpdateLoadBalancerRuleCmd(); |
| ReflectionTestUtils.setField(cmd, ApiConstants.ID, lbRuleId); |
| ReflectionTestUtils.setField(cmd, "lbProtocol", NetUtils.TCP_PROTO); |
| when(loadBalancerMock.getLbProtocol()).thenReturn(NetUtils.SSL_PROTO).thenReturn(NetUtils.TCP_PROTO); |
| Mockito.doThrow(ResourceUnavailableException.class).when(lbr).applyLoadBalancerConfig(lbRuleId); |
| |
| List<Network.Provider> providers = Arrays.asList(Network.Provider.VirtualRouter); |
| when(_networkDao.findById(anyLong())).thenReturn(networkMock); |
| when(_networkMgr.getProvidersForServiceInNetwork(networkMock, Network.Service.Lb)).thenReturn(providers); |
| |
| lbr.updateLoadBalancerRule(cmd); |
| |
| Mockito.verify(_lbCertMapDao, never()).remove(anyLong()); |
| Mockito.verify(lbr, times(1)).applyLoadBalancerConfig(lbRuleId); |
| Mockito.verify(loadBalancerMock, times(1)).setLbProtocol(NetUtils.TCP_PROTO); |
| Mockito.verify(loadBalancerMock, times(1)).setLbProtocol(NetUtils.SSL_PROTO); |
| } |
| } |