blob: c76fbbf14291dc9116614207eda4accc8d31601b [file] [log] [blame]
/*
* 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.hypervisor.kvm.resource;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.anyMap;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import java.util.HashMap;
import java.util.Map;
import javax.naming.ConfigurationException;
import org.junit.Before;
import org.junit.Test;
import com.cloud.agent.properties.AgentProperties;
import com.cloud.agent.properties.AgentPropertiesFileHandler;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource.BridgeType;
import com.cloud.network.Networks.TrafficType;
import org.junit.runner.RunWith;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class LibvirtVifDriverTest {
private LibvirtComputingResource res;
private Map<TrafficType, VifDriver> assertions;
final String LibVirtVifDriver = "libvirt.vif.driver";
final String FakeVifDriverClassName = "com.cloud.hypervisor.kvm.resource.FakeVifDriver";
final String NonExistentVifDriverClassName = "com.cloud.hypervisor.kvm.resource.NonExistentVifDriver";
private VifDriver fakeVifDriver, bridgeVifDriver, ovsVifDriver, tungstenVifDriver;
final String memInfo = "MemTotal: 5830236 kB\n" +
"MemFree: 156752 kB\n" +
"Buffers: 326836 kB\n" +
"Cached: 2606764 kB\n" +
"SwapCached: 0 kB\n" +
"Active: 4260808 kB\n" +
"Inactive: 949392 kB\n";
@Before
public void setUp() throws Exception {
// Use a spy because we only want to override getVifDriverClass
LibvirtComputingResource resReal = new LibvirtComputingResource();
res = spy(resReal);
try {
bridgeVifDriver = (VifDriver)Class.forName(LibvirtComputingResource.DEFAULT_BRIDGE_VIF_DRIVER_CLASS_NAME).newInstance();
ovsVifDriver = (VifDriver)Class.forName(LibvirtComputingResource.DEFAULT_OVS_VIF_DRIVER_CLASS_NAME).newInstance();
tungstenVifDriver = (VifDriver)Class.forName(LibvirtComputingResource.DEFAULT_TUNGSTEN_VIF_DRIVER_CLASS_NAME).newInstance();
// Instantiating bridge vif driver again as the fake vif driver
// is good enough, as this is a separate instance
fakeVifDriver = (VifDriver)Class.forName(LibvirtComputingResource.DEFAULT_BRIDGE_VIF_DRIVER_CLASS_NAME).newInstance();
doReturn(bridgeVifDriver).when(res).getVifDriverClass(eq(LibvirtComputingResource.DEFAULT_BRIDGE_VIF_DRIVER_CLASS_NAME), anyMap());
doReturn(ovsVifDriver).when(res).getVifDriverClass(eq(LibvirtComputingResource.DEFAULT_OVS_VIF_DRIVER_CLASS_NAME), anyMap());
doReturn(tungstenVifDriver).when(res).getVifDriverClass(eq(LibvirtComputingResource.DEFAULT_TUNGSTEN_VIF_DRIVER_CLASS_NAME), anyMap());
doReturn(fakeVifDriver).when(res).getVifDriverClass(eq(FakeVifDriverClassName), anyMap());
} catch (final ConfigurationException ex) {
fail("Unexpected ConfigurationException while configuring VIF drivers: " + ex.getMessage());
} catch (final Exception ex) {
fail("Unexpected Exception while configuring VIF drivers");
}
assertions = new HashMap<TrafficType, VifDriver>();
}
// Helper function
// Configure LibvirtComputingResource using params
private void configure(Map<String, Object> params) throws ConfigurationException {
res.configureVifDrivers(params);
}
// Helper function
private void checkAssertions() {
// Check the defined assertions
for (Map.Entry<TrafficType, VifDriver> assertion : assertions.entrySet()) {
assertEquals(res.getVifDriver(assertion.getKey()), assertion.getValue());
}
}
// Helper when all answers should be the same
private void checkAllSame(VifDriver vifDriver) throws ConfigurationException {
for (TrafficType trafficType : TrafficType.values()) {
assertions.put(trafficType, vifDriver);
}
checkAssertions();
}
@Test
public void testDefaults() throws ConfigurationException {
// If no special vif driver settings, all traffic types should
// map to the default vif driver for the bridge type
Map<String, Object> params = new HashMap<String, Object>();
res.bridgeType = BridgeType.NATIVE;
configure(params);
checkAllSame(bridgeVifDriver);
res.bridgeType = BridgeType.OPENVSWITCH;
configure(params);
checkAllSame(ovsVifDriver);
}
@Test
public void configureVifDriversTestWhenSetEqualToDefault() throws Exception {
try (MockedStatic<AgentPropertiesFileHandler> agentPropertiesFileHandlerMockedStatic = Mockito.mockStatic(
AgentPropertiesFileHandler.class)) {
Mockito.when(AgentPropertiesFileHandler.getPropertyValue(AgentProperties.LIBVIRT_VIF_DRIVER)).thenReturn(
LibvirtComputingResource.DEFAULT_BRIDGE_VIF_DRIVER_CLASS_NAME,
LibvirtComputingResource.DEFAULT_OVS_VIF_DRIVER_CLASS_NAME);
Map<String, Object> params = new HashMap<String, Object>();
// Switch res' bridge type for test purposes
res.bridgeType = BridgeType.NATIVE;
configure(params);
checkAllSame(bridgeVifDriver);
res.bridgeType = BridgeType.OPENVSWITCH;
configure(params);
checkAllSame(ovsVifDriver);
agentPropertiesFileHandlerMockedStatic.verify(
() -> AgentPropertiesFileHandler.getPropertyValue(AgentProperties.LIBVIRT_VIF_DRIVER),
Mockito.times(2));
}
}
@Test
public void configureVifDriversTestWhenSetDifferentFromDefault() throws Exception {
try (MockedStatic<AgentPropertiesFileHandler> agentPropertiesFileHandlerMockedStatic = Mockito.mockStatic(
AgentPropertiesFileHandler.class)) {
Mockito.when(AgentPropertiesFileHandler.getPropertyValue(AgentProperties.LIBVIRT_VIF_DRIVER))
.thenReturn(LibvirtComputingResource.DEFAULT_OVS_VIF_DRIVER_CLASS_NAME,
LibvirtComputingResource.DEFAULT_BRIDGE_VIF_DRIVER_CLASS_NAME);
// Tests when explicitly set vif driver to OVS when using regular bridges and vice versa
Map<String, Object> params = new HashMap<String, Object>();
// Switch res' bridge type for test purposes
res.bridgeType = BridgeType.NATIVE;
configure(params);
checkAllSame(ovsVifDriver);
res.bridgeType = BridgeType.OPENVSWITCH;
configure(params);
checkAllSame(bridgeVifDriver);
agentPropertiesFileHandlerMockedStatic.verify(() -> AgentPropertiesFileHandler.getPropertyValue(
AgentProperties.LIBVIRT_VIF_DRIVER), Mockito.times(2));
}
}
@Test
public void testOverrideSomeTrafficTypes() throws ConfigurationException {
Map<String, Object> params = new HashMap<String, Object>();
params.put(LibVirtVifDriver + "." + "Public", FakeVifDriverClassName);
params.put(LibVirtVifDriver + "." + "Guest", LibvirtComputingResource.DEFAULT_OVS_VIF_DRIVER_CLASS_NAME);
res.bridgeType = BridgeType.NATIVE;
configure(params);
// Initially, set all traffic types to use default
for (TrafficType trafficType : TrafficType.values()) {
assertions.put(trafficType, bridgeVifDriver);
}
assertions.put(TrafficType.Public, fakeVifDriver);
assertions.put(TrafficType.Guest, ovsVifDriver);
checkAssertions();
}
@Test
public void testBadTrafficType() throws ConfigurationException {
Map<String, Object> params = new HashMap<String, Object>();
params.put(LibVirtVifDriver + "." + "NonExistentTrafficType", FakeVifDriverClassName);
res.bridgeType = BridgeType.NATIVE;
configure(params);
// Set all traffic types to use default, because bad traffic type should be ignored
for (TrafficType trafficType : TrafficType.values()) {
assertions.put(trafficType, bridgeVifDriver);
}
checkAssertions();
}
@Test
public void testEmptyTrafficType() throws ConfigurationException {
Map<String, Object> params = new HashMap<String, Object>();
params.put(LibVirtVifDriver + ".", FakeVifDriverClassName);
res.bridgeType = BridgeType.NATIVE;
configure(params);
// Set all traffic types to use default, because bad traffic type should be ignored
for (TrafficType trafficType : TrafficType.values()) {
assertions.put(trafficType, bridgeVifDriver);
}
checkAssertions();
}
@Test(expected = ConfigurationException.class)
public void testBadVifDriverClassName() throws ConfigurationException {
Map<String, Object> params = new HashMap<String, Object>();
params.put(LibVirtVifDriver + "." + "Public", NonExistentVifDriverClassName);
res.bridgeType = BridgeType.NATIVE;
configure(params);
}
}