Refactoring the LibvirtComputingResource

- Adding LibvirtGetHosStatsCommandWrapper
  - 1 unit test added
  - KVM hypervisor with 10.5% coverage

Tests are a bit limited on this one becuause of the current implementation. Would clean it up later in a separate branch
This commit is contained in:
wilderrodrigues 2015-04-23 10:30:13 +02:00
parent 7a90c018fb
commit 6e568125fc
4 changed files with 104 additions and 68 deletions

View File

@ -113,13 +113,10 @@ import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
import com.cloud.agent.api.DeleteStoragePoolCommand;
import com.cloud.agent.api.FenceAnswer;
import com.cloud.agent.api.FenceCommand;
import com.cloud.agent.api.GetHostStatsAnswer;
import com.cloud.agent.api.GetHostStatsCommand;
import com.cloud.agent.api.GetStorageStatsAnswer;
import com.cloud.agent.api.GetStorageStatsCommand;
import com.cloud.agent.api.GetVncPortAnswer;
import com.cloud.agent.api.GetVncPortCommand;
import com.cloud.agent.api.HostStatsEntry;
import com.cloud.agent.api.HostVmStateReportEntry;
import com.cloud.agent.api.MaintainAnswer;
import com.cloud.agent.api.MaintainCommand;
@ -397,6 +394,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return _virtRouterResource;
}
public String getPublicBridgeName() {
return _publicBridgeName;
}
private static final class KeyValueInterpreter extends OutputInterpreter {
private final Map<String, String> map = new HashMap<String, String>();
@ -1299,9 +1300,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
}
try {
if (cmd instanceof GetHostStatsCommand) {
return execute((GetHostStatsCommand)cmd);
} else if (cmd instanceof CheckStateCommand) {
if (cmd instanceof CheckStateCommand) {
return executeRequest(cmd);
} else if (cmd instanceof CheckHealthCommand) {
return execute((CheckHealthCommand)cmd);
@ -3265,48 +3264,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return new CheckHealthAnswer(cmd, true);
}
private Answer execute(final GetHostStatsCommand cmd) {
final Script cpuScript = new Script("/bin/bash", s_logger);
cpuScript.add("-c");
cpuScript.add("idle=$(top -b -n 1| awk -F, '/^[%]*[Cc]pu/{$0=$4; gsub(/[^0-9.,]+/,\"\"); print }'); echo $idle");
final OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser();
String result = cpuScript.execute(parser);
if (result != null) {
s_logger.debug("Unable to get the host CPU state: " + result);
return new Answer(cmd, false, result);
}
final double cpuUtil = 100.0D - Double.parseDouble(parser.getLine());
long freeMem = 0;
final Script memScript = new Script("/bin/bash", s_logger);
memScript.add("-c");
memScript.add("freeMem=$(free|grep cache:|awk '{print $4}');echo $freeMem");
final OutputInterpreter.OneLineParser Memparser = new OutputInterpreter.OneLineParser();
result = memScript.execute(Memparser);
if (result != null) {
s_logger.debug("Unable to get the host Mem state: " + result);
return new Answer(cmd, false, result);
}
freeMem = Long.parseLong(Memparser.getLine());
final Script totalMem = new Script("/bin/bash", s_logger);
totalMem.add("-c");
totalMem.add("free|grep Mem:|awk '{print $2}'");
final OutputInterpreter.OneLineParser totMemparser = new OutputInterpreter.OneLineParser();
result = totalMem.execute(totMemparser);
if (result != null) {
s_logger.debug("Unable to get the host Mem state: " + result);
return new Answer(cmd, false, result);
}
final long totMem = Long.parseLong(totMemparser.getLine());
final Pair<Double, Double> nicStats = getNicStats(_publicBridgeName);
final HostStatsEntry hostStats = new HostStatsEntry(cmd.getHostId(), cpuUtil, nicStats.first() / 1024, nicStats.second() / 1024, "host", totMem, freeMem, 0, 0);
return new GetHostStatsAnswer(cmd, hostStats);
}
public String networkUsage(final String privateIpAddress, final String option, final String vif) {
final Script getUsage = new Script(_routerProxyPath, s_logger);
getUsage.add("netusage.sh");
@ -5120,7 +5077,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
}
}
static Pair<Double, Double> getNicStats(final String nicName) {
public Pair<Double, Double> getNicStats(final String nicName) {
return new Pair<Double, Double>(readDouble(nicName, "rx_bytes"), readDouble(nicName, "tx_bytes"));
}

View File

@ -0,0 +1,80 @@
//
// 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.wrapper;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.GetHostStatsAnswer;
import com.cloud.agent.api.GetHostStatsCommand;
import com.cloud.agent.api.HostStatsEntry;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
import com.cloud.utils.Pair;
import com.cloud.utils.script.OutputInterpreter;
import com.cloud.utils.script.Script;
public final class LibvirtGetHostStatsCommandWrapper extends CommandWrapper<GetHostStatsCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtGetHostStatsCommandWrapper.class);
@Override
public Answer execute(final GetHostStatsCommand command, final LibvirtComputingResource libvirtComputingResource) {
final Script cpuScript = new Script("/bin/bash", s_logger);
cpuScript.add("-c");
cpuScript.add("idle=$(top -b -n 1| awk -F, '/^[%]*[Cc]pu/{$0=$4; gsub(/[^0-9.,]+/,\"\"); print }'); echo $idle");
final OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser();
String result = cpuScript.execute(parser);
if (result != null) {
s_logger.debug("Unable to get the host CPU state: " + result);
return new Answer(command, false, result);
}
final double cpuUtil = 100.0D - Double.parseDouble(parser.getLine());
long freeMem = 0;
final Script memScript = new Script("/bin/bash", s_logger);
memScript.add("-c");
memScript.add("freeMem=$(free|grep cache:|awk '{print $4}');echo $freeMem");
final OutputInterpreter.OneLineParser Memparser = new OutputInterpreter.OneLineParser();
result = memScript.execute(Memparser);
if (result != null) {
s_logger.debug("Unable to get the host Mem state: " + result);
return new Answer(command, false, result);
}
freeMem = Long.parseLong(Memparser.getLine());
final Script totalMem = new Script("/bin/bash", s_logger);
totalMem.add("-c");
totalMem.add("free|grep Mem:|awk '{print $2}'");
final OutputInterpreter.OneLineParser totMemparser = new OutputInterpreter.OneLineParser();
result = totalMem.execute(totMemparser);
if (result != null) {
s_logger.debug("Unable to get the host Mem state: " + result);
return new Answer(command, false, result);
}
final long totMem = Long.parseLong(totMemparser.getLine());
final Pair<Double, Double> nicStats = libvirtComputingResource.getNicStats(libvirtComputingResource.getPublicBridgeName());
final HostStatsEntry hostStats = new HostStatsEntry(command.getHostId(), cpuUtil, nicStats.first() / 1024, nicStats.second() / 1024, "host", totMem, freeMem, 0, 0);
return new GetHostStatsAnswer(command, hostStats);
}
}

View File

@ -22,6 +22,7 @@ import java.util.Hashtable;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.GetHostStatsCommand;
import com.cloud.agent.api.GetVmDiskStatsCommand;
import com.cloud.agent.api.GetVmStatsCommand;
import com.cloud.agent.api.RebootCommand;
@ -54,6 +55,8 @@ public class LibvirtRequestWrapper extends RequestWrapper {
linbvirtCommands.put(GetVmDiskStatsCommand.class, new LibvirtGetVmDiskStatsCommandWrapper());
linbvirtCommands.put(RebootRouterCommand.class, new LibvirtRebootRouterCommandWrapper());
linbvirtCommands.put(RebootCommand.class, new LibvirtRebootCommandWrapper());
linbvirtCommands.put(GetHostStatsCommand.class, new LibvirtGetHostStatsCommandWrapper());
resources.put(LibvirtComputingResource.class, linbvirtCommands);
}

View File

@ -62,6 +62,7 @@ import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.GetHostStatsCommand;
import com.cloud.agent.api.GetVmDiskStatsCommand;
import com.cloud.agent.api.GetVmStatsCommand;
import com.cloud.agent.api.RebootCommand;
@ -289,7 +290,8 @@ public class LibvirtComputingResourceTest {
//this test is only working on linux because of the loopback interface name
//also the tested code seems to work only on linux
Assume.assumeTrue(SystemUtils.IS_OS_LINUX);
final Pair<Double, Double> stats = LibvirtComputingResource.getNicStats("lo");
final LibvirtComputingResource libvirtComputingResource = new LibvirtComputingResource();
final Pair<Double, Double> stats = libvirtComputingResource.getNicStats("lo");
assertNotNull(stats);
}
@ -395,9 +397,6 @@ public class LibvirtComputingResourceTest {
@Test
public void testStopCommandNoCheck() {
// We cannot do much here due to the Native libraries and Static methods used by the LibvirtConnection we need
// a better way to mock stuff!
final Connect conn = Mockito.mock(Connect.class);
final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class);
@ -428,9 +427,6 @@ public class LibvirtComputingResourceTest {
@Test
public void testStopCommandCheck() {
// We cannot do much here due to the Native libraries and Static methods used by the LibvirtConnection we need
// a better way to mock stuff!
final Connect conn = Mockito.mock(Connect.class);
final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class);
final Domain domain = Mockito.mock(Domain.class);
@ -463,9 +459,6 @@ public class LibvirtComputingResourceTest {
@Test
public void testGetVmStatsCommand() {
// We cannot do much here due to the Native libraries and Static methods used by the LibvirtConnection we need
// a better way to mock stuff!
final Connect conn = Mockito.mock(Connect.class);
final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class);
@ -499,9 +492,6 @@ public class LibvirtComputingResourceTest {
@Test
public void testGetVmDiskStatsCommand() {
// We cannot do much here due to the Native libraries and Static methods used by the LibvirtConnection we need
// a better way to mock stuff!
final Connect conn = Mockito.mock(Connect.class);
final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class);
@ -535,9 +525,6 @@ public class LibvirtComputingResourceTest {
@Test
public void testRebootCommand() {
// We cannot do much here due to the Native libraries and Static methods used by the LibvirtConnection we need
// a better way to mock stuff!
final Connect conn = Mockito.mock(Connect.class);
final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class);
@ -567,9 +554,6 @@ public class LibvirtComputingResourceTest {
@Test
public void testRebootRouterCommand() {
// We cannot do much here due to the Native libraries and Static methods used by the LibvirtConnection we need
// a better way to mock stuff!
final VirtualRoutingResource routingResource = Mockito.mock(VirtualRoutingResource.class);
final Connect conn = Mockito.mock(Connect.class);
final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class);
@ -600,4 +584,16 @@ public class LibvirtComputingResourceTest {
fail(e.getMessage());
}
}
@Test(expected = NumberFormatException.class)
public void testGetHostStatsCommand() {
final String uuid = "e8d6b4d0-bc6d-4613-b8bb-cb9e0600f3c6";
final GetHostStatsCommand command = new GetHostStatsCommand(uuid, "summer", 1l);
final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
assertNotNull(wrapper);
final Answer answer = wrapper.execute(command, libvirtComputingResource);
assertFalse(answer.getResult());
}
}