/**
* NOTE: This copyright does *not* cover user programs that use HQ
* program services by normal system calls through the application
* program interfaces provided as part of the Hyperic Plug-in Development
* Kit or the Hyperic Client Development Kit - this is merely considered
* normal use of the program, and does *not* fall under the heading of
* "derived work".
*
* Copyright (C) [2010], VMware, Inc.
* This file is part of HQ.
*
* HQ is free software; you can redistribute it and/or modify
* it under the terms version 2 of the GNU General Public License as
* published by the Free Software Foundation. This program is distributed
* in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
*/
package org.hyperic.hq.plugin.vsphere;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.easymock.classextension.EasyMock;
import org.hyperic.hq.hqapi1.AgentApi;
import org.hyperic.hq.hqapi1.HQApi;
import org.hyperic.hq.hqapi1.ResourceApi;
import org.hyperic.hq.hqapi1.ResourceEdgeApi;
import org.hyperic.hq.hqapi1.types.Agent;
import org.hyperic.hq.hqapi1.types.AgentResponse;
import org.hyperic.hq.hqapi1.types.Resource;
import org.hyperic.hq.hqapi1.types.ResourceConfig;
import org.hyperic.hq.hqapi1.types.ResourceEdge;
import org.hyperic.hq.hqapi1.types.ResourceFrom;
import org.hyperic.hq.hqapi1.types.ResourcePrototype;
import org.hyperic.hq.hqapi1.types.ResourcePrototypeResponse;
import org.hyperic.hq.hqapi1.types.ResourceTo;
import org.hyperic.hq.hqapi1.types.ResourcesResponse;
import org.hyperic.hq.hqapi1.types.ResponseStatus;
import org.hyperic.hq.hqapi1.types.StatusResponse;
import org.hyperic.hq.product.PluginException;
import org.hyperic.hq.product.ProductPlugin;
import org.hyperic.util.ReflectionEqualsArgumentMatcher;
import org.hyperic.util.config.ConfigResponse;
import org.junit.Before;
import org.junit.Test;
import com.vmware.vim25.AboutInfo;
import com.vmware.vim25.DatastoreInfo;
import com.vmware.vim25.GuestInfo;
import com.vmware.vim25.GuestNicInfo;
import com.vmware.vim25.HostConfigInfo;
import com.vmware.vim25.HostDnsConfig;
import com.vmware.vim25.HostHardwareSummary;
import com.vmware.vim25.HostIpConfig;
import com.vmware.vim25.HostIpRouteConfig;
import com.vmware.vim25.HostListSummary;
import com.vmware.vim25.HostNetworkInfo;
import com.vmware.vim25.HostRuntimeInfo;
import com.vmware.vim25.HostSystemPowerState;
import com.vmware.vim25.HostVirtualNic;
import com.vmware.vim25.HostVirtualNicSpec;
import com.vmware.vim25.InvalidProperty;
import com.vmware.vim25.RuntimeFault;
import com.vmware.vim25.ToolsConfigInfo;
import com.vmware.vim25.VirtualHardware;
import com.vmware.vim25.VirtualMachineConfigInfo;
import com.vmware.vim25.VirtualMachineFileInfo;
import com.vmware.vim25.VirtualMachinePowerState;
import com.vmware.vim25.VirtualMachineRuntimeInfo;
import com.vmware.vim25.mo.Datastore;
import com.vmware.vim25.mo.HostSystem;
import com.vmware.vim25.mo.ManagedEntity;
import com.vmware.vim25.mo.ResourcePool;
import com.vmware.vim25.mo.VirtualMachine;
/**
* Unit test of the {@link VMAndHostVCenterPlatformDetector}
* TODO Add tests for deleting removed hosts and VMs from inventory
* @author jhickey
*
*/
public class VMAndHostVCenterPlatformDetectorTest {
private HQApi hqApi;
private ResourceApi resourceApi;
private AgentApi agentApi;
private ResourceEdgeApi resourceEdgeApi;
private static final String PROP_PROVIDER_URL = "covalent.CAMProviderURL";
private static final String PROP_AGENT_TOKEN = "covalent.CAMAgentToken";
private static final String AGENT_TOKEN = "someAgentTokenString";
private static final String VCENTER_URL = "url";
private static final String VCENTER_UNAME = "uname";
private static final String VCENTER_PW = "pass";
private VSphereUtil vim;
private VMAndHostVCenterPlatformDetector detector;
private Properties props = new Properties();
private HostSystem host;
private ManagedEntity dataCenter;
private ManagedEntity dataCenters;
private VirtualMachine vm;
private Datastore ds;
private DatastoreInfo dsInfo;
private ResourcePool resourcePool;
@Before
public void setUp() throws Exception {
props.put(PROP_PROVIDER_URL, "http://localhost:8080/lather");
props.put(PROP_AGENT_TOKEN, AGENT_TOKEN);
props.put(VSphereUtil.PROP_URL, VCENTER_URL);
props.put(VSphereUtil.PROP_USERNAME, VCENTER_UNAME);
props.put(VSphereUtil.PROP_PASSWORD, VCENTER_PW);
this.hqApi = EasyMock.createMock(HQApi.class);
this.resourceApi = EasyMock.createMock(ResourceApi.class);
this.agentApi = EasyMock.createMock(AgentApi.class);
this.resourceEdgeApi = EasyMock.createMock(ResourceEdgeApi.class);
this.vim = EasyMock.createMock(VSphereUtil.class);
this.host = EasyMock.createMock(HostSystem.class);
this.dataCenter = EasyMock.createMock(ManagedEntity.class);
this.dataCenters = EasyMock.createMock(ManagedEntity.class);
this.vm = EasyMock.createMock(VirtualMachine.class);
this.ds = EasyMock.createMock(Datastore.class);
this.dsInfo = EasyMock.createMock(DatastoreInfo.class);
this.resourcePool = EasyMock.createMock(ResourcePool.class);
this.detector = new VMAndHostVCenterPlatformDetector();
}
//@Test
public void testDiscoverPlatforms() throws Exception {
EasyMock.expect(hqApi.getResourceApi()).andReturn(resourceApi).times(13);
ResourcePrototypeResponse protoResponse = new ResourcePrototypeResponse();
protoResponse.setStatus(ResponseStatus.SUCCESS);
ResourcePrototype vcType = new ResourcePrototype();
vcType.setName(VMAndHostVCenterPlatformDetector.VC_TYPE);
protoResponse.setResourcePrototype(vcType);
EasyMock.expect(resourceApi.getResourcePrototype(VMAndHostVCenterPlatformDetector.VC_TYPE))
.andReturn(protoResponse).times(2);
ResourcesResponse vCenterResponse = getVCenterServerResourceResponse(vcType);
EasyMock.expect(resourceApi.getResources(vcType, true, false)).andReturn(vCenterResponse)
.times(2);
EasyMock.expect(hqApi.getAgentApi()).andReturn(agentApi);
AgentResponse agentResponse = new AgentResponse();
agentResponse.setStatus(ResponseStatus.SUCCESS);
Agent agent = new Agent();
agentResponse.setAgent(agent);
EasyMock.expect(agentApi.getAgent(AGENT_TOKEN)).andReturn(agentResponse);
ResourcePrototypeResponse hostProtoResponse = new ResourcePrototypeResponse();
hostProtoResponse.setStatus(ResponseStatus.SUCCESS);
ResourcePrototype hostType = new ResourcePrototype();
hostType.setName(VMAndHostVCenterPlatformDetector.HOST_TYPE);
hostProtoResponse.setResourcePrototype(hostType);
EasyMock.expect(
resourceApi.getResourcePrototype(VMAndHostVCenterPlatformDetector.HOST_TYPE))
.andReturn(hostProtoResponse).times(2);
createHost();
createVM();
ResourcePrototypeResponse vmDsProtoResponse = new ResourcePrototypeResponse();
vmDsProtoResponse.setStatus(ResponseStatus.SUCCESS);
ResourcePrototype vmDsType = new ResourcePrototype();
vmDsType.setName(VMAndHostVCenterPlatformDetector.VM_DS_TYPE);
vmDsProtoResponse.setResourcePrototype(vmDsType);
EasyMock.expect(resourceApi.getResourcePrototype(VMAndHostVCenterPlatformDetector.VM_DS_TYPE))
.andReturn(vmDsProtoResponse).times(1);
ResourcePrototypeResponse hostDsProtoResponse = new ResourcePrototypeResponse();
hostDsProtoResponse.setStatus(ResponseStatus.SUCCESS);
ResourcePrototype hostDSType = new ResourcePrototype();
hostDSType.setName(VMAndHostVCenterPlatformDetector.HOST_DS_TYPE);
hostDsProtoResponse.setResourcePrototype(hostDSType);
EasyMock.expect(resourceApi.getResourcePrototype(VMAndHostVCenterPlatformDetector.HOST_DS_TYPE))
.andReturn(hostDsProtoResponse).times(1);
ResourcePrototypeResponse vmProtoResponse = new ResourcePrototypeResponse();
vmProtoResponse.setStatus(ResponseStatus.SUCCESS);
ResourcePrototype vmType = new ResourcePrototype();
vmType.setName(VMAndHostVCenterPlatformDetector.VM_TYPE);
vmProtoResponse.setResourcePrototype(vmType);
EasyMock.expect(resourceApi.getResourcePrototype(VMAndHostVCenterPlatformDetector.VM_TYPE))
.andReturn(vmProtoResponse).times(2);
StatusResponse genericSuccess = new StatusResponse();
genericSuccess.setStatus(ResponseStatus.SUCCESS);
List<Resource> expectedVMs = new ArrayList<Resource>();
VSphereResource expectedVM = getExpectedVM(vmType, agent);
expectedVMs.add(expectedVM);
EasyMock.expect(
resourceApi.syncResources(ReflectionEqualsArgumentMatcher.eqObject(expectedVMs)))
.andReturn(genericSuccess);
List<Resource> expectedResources = new ArrayList<Resource>();
VSphereHostResource expectedHost = getExpectedHost(hostType, vmType, agent);
expectedResources.add(expectedHost);
EasyMock.expect(
resourceApi.syncResources(ReflectionEqualsArgumentMatcher.eqObject(expectedResources)))
.andReturn(genericSuccess);
EasyMock.expect(hqApi.getResourceEdgeApi()).andReturn(resourceEdgeApi).times(2);
ResourcesResponse esxHostResponse = getEsxHostResourceResponse(hostType, vmType, agent);
EasyMock.expect(resourceApi.getResources(hostType, true, false)).andReturn(esxHostResponse);
List<ResourceEdge> expectedVCenterToHostEdges = new ArrayList<ResourceEdge>();
expectedVCenterToHostEdges.add(getExpectedVirtualEdge(vCenterResponse.getResource().get(0),
expectedHost));
EasyMock.expect(
resourceEdgeApi.syncResourceEdges(ReflectionEqualsArgumentMatcher
.eqObject(expectedVCenterToHostEdges))).andReturn(genericSuccess);
List<ResourceEdge> expectedHostToVMEdges = new ArrayList<ResourceEdge>();
expectedHostToVMEdges.add(getExpectedVirtualEdge(expectedHost, expectedHost
.getVirtualMachines().get(0)));
EasyMock.expect(
resourceEdgeApi.syncResourceEdges(ReflectionEqualsArgumentMatcher
.eqObject(expectedHostToVMEdges))).andReturn(genericSuccess);
ResourcesResponse vmResponse = getVMResourceResponse(vmType, agent);
EasyMock.expect(resourceApi.getResources(vmType, true, false)).andReturn(vmResponse);
replay();
detector.discoverPlatforms(props, hqApi, vim);
verify();
}
private ResourcesResponse getVCenterServerResourceResponse(ResourcePrototype vcType) {
Resource resource = new Resource();
ResourceConfig resourceConfig = new ResourceConfig();
resourceConfig.setKey(VSphereUtil.PROP_URL);
resourceConfig.setValue(VCENTER_URL);
resource.getResourceConfig().add(resourceConfig);
resource.setResourcePrototype(vcType);
ResourcesResponse response = new ResourcesResponse();
response.getResource().add(resource);
response.setStatus(ResponseStatus.SUCCESS);
return response;
}
private ResourcesResponse getEsxHostResourceResponse(ResourcePrototype hostType,
ResourcePrototype vmType, Agent agent) {
ResourcesResponse response = new ResourcesResponse();
response.getResource().add(getExpectedHost(hostType, vmType, agent));
response.setStatus(ResponseStatus.SUCCESS);
return response;
}
private ResourcesResponse getVMResourceResponse(ResourcePrototype vmType, Agent agent) {
ResourcesResponse response = new ResourcesResponse();
response.getResource().add(getExpectedVM(vmType, agent));
response.setStatus(ResponseStatus.SUCCESS);
return response;
}
private void createHost() throws PluginException, InvalidProperty, RuntimeFault, RemoteException {
EasyMock.expect(vim.find(VSphereUtil.HOST_SYSTEM)).andReturn(new ManagedEntity[] { host });
HostRuntimeInfo hostInfo = new HostRuntimeInfo();
hostInfo.setPowerState(HostSystemPowerState.poweredOn);
EasyMock.expect(host.getRuntime()).andReturn(hostInfo);
HostConfigInfo hostConfig = new HostConfigInfo();
HostNetworkInfo networkInfo = new HostNetworkInfo();
HostIpRouteConfig ipRouteConfig = new HostIpRouteConfig();
ipRouteConfig.setDefaultGateway("1.2.3.4");
networkInfo.setIpRouteConfig(ipRouteConfig);
HostDnsConfig dnsConfig = new HostDnsConfig();
networkInfo.setDnsConfig(dnsConfig);
HostVirtualNic nic = new HostVirtualNic();
HostVirtualNicSpec nicSpec = new HostVirtualNicSpec();
nic.setSpec(nicSpec);
HostIpConfig ipConfig = new HostIpConfig();
ipConfig.setIpAddress("10.0.1.123");
ipConfig.setSubnetMask("10.0.1.0");
nicSpec.setIp(ipConfig);
nicSpec.setMac("65.7.8.9");
networkInfo.setVnic(new HostVirtualNic[] { nic });
AboutInfo aboutInfo = new AboutInfo();
aboutInfo.setFullName("ESX Host 4.1");
aboutInfo.setVersion("4.1");
aboutInfo.setBuild("5322");
hostConfig.setNetwork(networkInfo);
hostConfig.setProduct(aboutInfo);
HostListSummary hostListSummary = new HostListSummary();
HostHardwareSummary hardware = new HostHardwareSummary();
hardware.setUuid("1234-5678-9012-34");
hardware.setNumCpuCores((short) 4);
hardware.setNumCpuPkgs((short) 2);
hardware.setVendor("Home Depot");
hardware.setModel("3G67");
hardware.setCpuModel("Intel");
hostListSummary.setHardware(hardware);
EasyMock.expect(host.getConfig()).andReturn(hostConfig);
EasyMock.expect(host.getSummary()).andReturn(hostListSummary);
EasyMock.expect(host.getName()).andReturn("esxHost123").times(2);
EasyMock.expect(host.getParent()).andReturn(dataCenter);
EasyMock.expect(dataCenter.getName()).andReturn("Test DataCenter").times(2);
EasyMock.expect(dataCenter.getParent()).andReturn(dataCenters);
EasyMock.expect(dataCenters.getName()).andReturn("Datacenters");
EasyMock.expect(dataCenters.getParent()).andReturn(null);
EasyMock.expect(ds.getName()).andReturn("ds1").anyTimes();
EasyMock.expect(ds.getInfo()).andReturn(dsInfo).anyTimes();
EasyMock.expect(dsInfo.getUrl()).andReturn("ds://vmfs/volumes/4e9c6624-e4950d68-3b10-f4ce46bfd1c3/").anyTimes();
EasyMock.expect(host.getDatastores()).andReturn(new Datastore[]{ ds });
}
private void createVM() throws InvalidProperty, RuntimeFault, RemoteException {
EasyMock.expect(host.getVms()).andReturn(new VirtualMachine[] { vm });
VirtualMachineConfigInfo config = new VirtualMachineConfigInfo();
config.setTemplate(false);
config.setUuid("4206c445-7eb4-a72f-38c8-d865c4c374f2");
config.setName("Test VM");
config.setGuestFullName("Linux OS");
config.setVersion("8.1");
VirtualMachineFileInfo fileInfo = new VirtualMachineFileInfo();
fileInfo.setVmPathName("/pathto/vm");
config.setFiles(fileInfo);
VirtualHardware hardware = new VirtualHardware();
hardware.setNumCPU(4);
hardware.setMemoryMB(1000);
config.setHardware(hardware);
ToolsConfigInfo toolsConfig = new ToolsConfigInfo();
toolsConfig.setToolsVersion(4);
config.setTools(toolsConfig);
EasyMock.expect(resourcePool.getPropertyByPath("name")).andReturn("Test vApp");
VirtualMachineRuntimeInfo runtime = new VirtualMachineRuntimeInfo();
runtime.setPowerState(VirtualMachinePowerState.poweredOn);
GuestInfo guestInfo = new GuestInfo();
guestInfo.setHostName("leela.local");
GuestNicInfo nic = new GuestNicInfo();
nic.setMacAddress("123.456.789");
nic.setIpAddress(new String[] {"10.150.21.34"});
guestInfo.setNet(new GuestNicInfo[] {nic});
EasyMock.expect(vm.getConfig()).andReturn(config);
EasyMock.expect(vm.getRuntime()).andReturn(runtime);
EasyMock.expect(vm.getGuest()).andReturn(guestInfo);
EasyMock.expect(vm.getResourcePool()).andReturn(resourcePool);
EasyMock.expect(vm.getDatastores()).andReturn(new Datastore[]{ ds });
}
private VSphereHostResource getExpectedHost(ResourcePrototype hostPrototype,
ResourcePrototype vmType, Agent agent) {
VSphereHostResource expectedHost = new VSphereHostResource();
expectedHost.setName("esxHost123 {1234-5678-9012-34}");
expectedHost.setDescription("ESX Host 4.1");
expectedHost.setFqdn("1234-5678-9012-34");
expectedHost.addIp("10.0.1.123", "10.0.1.0", "65.7.8.9");
expectedHost.addConfig(VSphereUtil.PROP_HOSTNAME, "esxHost123");
expectedHost.addConfig(VSphereCollector.PROP_UUID, "1234-5678-9012-34");
ConfigResponse cprops = new ConfigResponse();
cprops.setValue("version", "4.1");
cprops.setValue("build", "5322");
cprops.setValue("ip", "10.0.1.123");
cprops.setValue("defaultGateway", "1.2.3.4");
cprops.setValue("hwVendor", "Home Depot");
cprops.setValue("hwModel", "3G67");
cprops.setValue("hwCpu", "Intel");
cprops.setValue("hwSockets", "2");
cprops.setValue("hwCores", "2");
cprops.setValue("parent", "Test DataCenter");
expectedHost.addProperties(cprops);
expectedHost.setResourcePrototype(hostPrototype);
expectedHost.setAgent(agent);
expectedHost.addConfig(VSphereUtil.PROP_URL, VCENTER_URL);
expectedHost.addConfig(VSphereUtil.PROP_USERNAME, VCENTER_UNAME);
expectedHost.addConfig(VSphereUtil.PROP_PASSWORD, VCENTER_PW);
expectedHost.getVirtualMachines().add(getExpectedVM(vmType, agent));
return expectedHost;
}
private VSphereResource getExpectedVM(ResourcePrototype vmType, Agent agent) {
VSphereResource expectedVm = new VSphereResource();
expectedVm.setName("Test VM {4206c445-7eb4-a72f-38c8-d865c4c374f2}");
expectedVm.setFqdn("4206c445-7eb4-a72f-38c8-d865c4c374f2");
expectedVm.setDescription("Linux OS");
ConfigResponse config = new ConfigResponse();
config.setValue(VSphereVmCollector.PROP_VM, "Test VM");
config.setValue(VSphereCollector.PROP_UUID, "4206c445-7eb4-a72f-38c8-d865c4c374f2");
expectedVm.addConfig(config);
ConfigResponse cprops = new ConfigResponse();
cprops.setValue(ProductPlugin.PROP_INSTALLPATH, "/pathto/vm");
cprops.setValue("guestOS", "Linux OS");
cprops.setValue("version", "8.1");
cprops.setValue("numvcpus", 4);
cprops.setValue("memsize", 1000);
cprops.setValue("toolsVersion", "4");
cprops.setValue("pool", "Test vApp");
cprops.setValue("hostName", "leela.local");
expectedVm.addProperties(cprops);
expectedVm.setResourcePrototype(vmType);
expectedVm.setAgent(agent);
expectedVm.addConfig(VSphereUtil.PROP_URL, VCENTER_URL);
expectedVm.addConfig(VSphereUtil.PROP_USERNAME, VCENTER_UNAME);
expectedVm.addConfig(VSphereUtil.PROP_PASSWORD, VCENTER_PW);
return expectedVm;
}
private ResourceEdge getExpectedVirtualEdge(Resource parent, Resource child) {
ResourceEdge edge = new ResourceEdge();
ResourceFrom from = new ResourceFrom();
from.setResource(parent);
ResourceTo to = new ResourceTo();
to.getResource().add(child);
edge.setRelation("virtual");
edge.setResourceFrom(from);
edge.setResourceTo(to);
return edge;
}
private void replay() {
EasyMock.replay(hqApi, resourceApi, agentApi, resourceEdgeApi, vim, host, dataCenter,
dataCenters, vm, resourcePool, ds, dsInfo);
}
private void verify() {
EasyMock.verify(hqApi, resourceApi, agentApi, resourceEdgeApi, vim, host, dataCenter,
dataCenters, vm, resourcePool, ds, dsInfo);
}
}