package org.libvirt; import org.libvirt.event.*; import java.nio.ByteBuffer; import java.nio.channels.ClosedChannelException; import java.util.Arrays; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.UUID; import java.util.regex.Pattern; import junit.framework.TestCase; public final class TestJavaBindings extends TestCase { final int UUIDArray[] = { Integer.decode("0x00"), Integer.decode("0x4b"), Integer.decode("0x96"), Integer.decode("0xe1"), Integer.decode("0x2d"), Integer.decode("0x78"), Integer.decode("0xc3"), Integer.decode("0x0f"), Integer.decode("0x5a"), Integer.decode("0xa5"), Integer.decode("0xf0"), Integer.decode("0x3c"), Integer.decode("0x87"), Integer.decode("0xd2"), Integer.decode("0x1e"), Integer.decode("0x67") }; private Connect conn; static { // do this once for each JVM instance, before connecting try { Library.initEventLoop(); } catch (LibvirtException e) { // XXX warn } } protected void setUp() throws LibvirtException { conn = new Connect("test:///default", false); } protected void tearDown() throws LibvirtException { conn.close(); conn = null; } public void testConnectionErrorCallback() throws LibvirtException { DummyErrorCallback cb = new DummyErrorCallback(); conn.setConnectionErrorCallback(cb); try { conn.domainDefineXML("fail, miserably"); fail("LibvirtException expected"); } catch (LibvirtException e) {} // ignore assertTrue("Error callback was not called", cb.error); } public void testConnection() throws Exception { assertEquals("conn.getType()", "TEST", conn.getType()); assertEquals("conn.getURI()", "test:///default", conn.getURI()); assertEquals("conn.getMaxVcpus(xen)", 32, conn.getMaxVcpus("xen")); assertNotNull("conn.getHostName()", conn.getHostName()); assertNotNull("conn.getCapabilities()", conn.getCapabilities()); assertTrue("conn.getLibVersion() > 6000", conn.getLibVersion() > 6000); assertEquals("conn.getVersion()", 2, conn.getVersion()); assertTrue("conn.isAlive", conn.isAlive()); assertTrue("conn.isEncrypted", conn.isEncrypted() == 0); assertTrue("conn.isSecure", conn.isSecure() == 1); } /* * Excercise the listCapabilities method of the Device class. */ public void testDeviceListCapabilities() throws Exception { Device dev = this.conn.deviceLookupByName("computer"); String[] caps = dev.listCapabilities(); // check that all caps are non-empty strings for (String c: caps) { assertNotNull("capability is null", c); assertFalse("capability is empty", c.isEmpty()); } } public void testNodeInfo() throws Exception { NodeInfo nodeInfo = conn.nodeInfo(); assertEquals("nodeInfo.model", "i686", nodeInfo.model); assertEquals("nodeInfo.memory", 3145728, nodeInfo.memory); assertEquals("nodeInfo.cpus", 16, nodeInfo.cpus); assertEquals("nodeInfo.nodes", 2, nodeInfo.nodes); assertEquals("nodeInfo.sockets", 2, nodeInfo.sockets); assertEquals("nodeInfo.cores", 2, nodeInfo.cores); assertEquals("nodeInfo.threads", 2, nodeInfo.threads); // These are basically no-exception tests assertTrue("conn.getCellsFreeMemory", conn.getCellsFreeMemory(0, 10) > 0); assertTrue("conn.isConnectd", conn.isConnected()); // Test Hypervisor does not support this. // assertTrue("conn.getFreeMemory", conn.getFreeMemory() > 0); } public void testNetworkCreate() throws Exception { Network network1 = conn.networkCreateXML("" + " createst" + " 004b96e1-2d78-c30f-5aa5-f03c87d21e68" + " " + " " + " " + " " + " " + " " + " " + ""); Network network2 = conn.networkDefineXML("" + " deftest" + " 004b96e1-2d78-c30f-5aa5-f03c87d21e67" + " " + " " + " " + " " + " " + " " + " " + ""); assertEquals("Number of networks", 2, conn.numOfNetworks()); assertEquals("Number of listed networks", 2, conn.listNetworks().length); assertEquals("Number of defined networks", 1, conn.numOfDefinedNetworks()); assertEquals("Number of listed defined networks", 1, conn.listDefinedNetworks().length); assertTrue("Network1 should not be persistent", network1.isPersistent() == 0); assertTrue("Network1 should not be active", network1.isActive() == 1); assertTrue("Network2 should be active", network2.isActive() == 0); this.validateNetworkData(network2); this.validateNetworkData(conn.networkLookupByName("deftest")); this.validateNetworkData(conn.networkLookupByUUID(UUIDArray)); this.validateNetworkData(conn.networkLookupByUUIDString("004b96e1-2d78-c30f-5aa5-f03c87d21e67")); this.validateNetworkData(conn.networkLookupByUUID(UUID.fromString("004b96e1-2d78-c30f-5aa5-f03c87d21e67"))); // this should throw an exception try { network1.create(); fail("LibvirtException expected"); } catch (LibvirtException e) { // eat it } } public void validateNetworkData(Network network) throws Exception { assertEquals("network.getName()", "deftest", network.getName()); assertEquals("network.getBridgeName()", "deftest", network.getBridgeName()); assertEquals("network.getUUIDString()", "004b96e1-2d78-c30f-5aa5-f03c87d21e67", network.getUUIDString()); assertFalse("network.getAutostart()", network.getAutostart()); assertNotNull("network.getConnect()", network.getConnect()); assertNotNull("network.getUUID()", network.getUUID()); assertNotNull("network.getXMLDesc()", network.getXMLDesc(0)); // TODO Figure out why this crashes in Eclipse. // assertNotNull(Connect.connectionForNetwork(network)); // assertTrue(Connect.connectionForNetwork(network) != // network.getConnect()); } public void testDomainCreate() throws Exception { Domain dom1 = conn.domainDefineXML("" + " deftest" + " 004b96e1-2d78-c30f-5aa5-f03c87d21e70" + " 8388608" + " 2" + " hvm" + " restart" + " destroy" + " restart" + ""); Domain dom2 = conn.domainCreateLinux("" + " createst" + " 004b96e1-2d78-c30f-5aa5-f03c87d21e67" + " 8388608" + " 2" + " hvm" + " restart" + " destroy" + " restart" + "", 0); UUID dom2UUID = UUID.fromString("004b96e1-2d78-c30f-5aa5-f03c87d21e67"); assertEquals("Number of domains", 2, conn.numOfDomains()); assertEquals("Number of listed domains", 2, conn.listDomains().length); assertEquals("Number of defined domains", 1, conn.numOfDefinedDomains()); assertEquals("Number of listed defined domains", 1, conn.listDefinedDomains().length); assertTrue("Domain1 should be persistent", dom1.isPersistent() == 1); assertTrue("Domain1 should not be active", dom1.isActive() == 0); assertTrue("Domain2 should be active", dom2.isActive() == 1); this.validateDomainData(dom2); this.validateDomainData(conn.domainLookupByName("createst")); this.validateDomainData(conn.domainLookupByUUID(UUIDArray)); this.validateDomainData(conn.domainLookupByUUIDString("004b96e1-2d78-c30f-5aa5-f03c87d21e67")); this.validateDomainData(conn.domainLookupByUUID(UUID.fromString("004b96e1-2d78-c30f-5aa5-f03c87d21e67"))); assertEquals("Domain is not equal to Domain retrieved by lookup", dom2, conn.domainLookupByUUID(dom2.getUUID())); } private void validateDomainData(Domain dom) throws Exception { assertEquals("dom.getName()", "createst", dom.getName()); assertEquals("dom.getMaxMemory()", 8388608, dom.getMaxMemory()); // Not supported by the test driver // assertEquals("dom.getMaxVcpus()", 2, dom2.getMaxVcpus()) ; assertEquals("dom.getOSType()", "linux", dom.getOSType()); assertEquals("dom.getUUIDString()", "004b96e1-2d78-c30f-5aa5-f03c87d21e67", dom.getUUIDString()); assertFalse("dom.getAutostart()", dom.getAutostart()); assertNotNull("dom.getConnect()", dom.getConnect()); assertNotNull("dom.getUUID()", dom.getUUID()); assertNotNull("dom.getXMLDesc()", dom.getXMLDesc(0)); assertNotNull("dom.getID()", dom.getID()); // Execute the code Iterate over the parameters the easy way for (SchedParameter c : dom.getSchedulerParameters()) { System.out.println(c.getTypeAsString() + ":" + c.field + ":" + c.getValueAsString()); } dom.getSchedulerParameters() ; SchedUintParameter[] pars = new SchedUintParameter[1]; pars[0] = new SchedUintParameter(); pars[0].field = "weight"; pars[0].value = 100; dom.setSchedulerParameters(pars); dom.getSchedulerParameters() ; } public void testInterfaces() throws Exception { assertEquals("numOfInterfaces:", 1, conn.numOfInterfaces()); assertEquals("numOfInterfaces:", 0, conn.numOfDefinedInterfaces()); assertEquals("listDefinedInterfaces:", "eth1", conn.listInterfaces()[0]); Interface virtInt = conn.interfaceLookupByName("eth1"); assertNotNull(virtInt); assertEquals("virtInterfaceGetName", "eth1", virtInt.getName()); assertEquals("virtInterfaceGetMACString", "aa:bb:cc:dd:ee:ff", virtInt.getMACString()); assertNotNull("virtInterfaceGetXMLDesc", virtInt.getXMLDescription(0)); assertTrue("virInterfaceIsActive", virtInt.isActive() == 1); System.out.println(virtInt.getXMLDescription(0)); String newXML = "" + "" + "" + "" + "" + "" + "" + "" + ""; Interface virtInt2 = conn.interfaceDefineXML(newXML); assertNotNull(virtInt2); assertEquals("virtInterfaceGetName", "eth2", virtInt2.getName()); assertEquals("virtInterfaceGetMACString", "aa:bb:cc:dd:ee:fa", virtInt2.getMACString()); assertNotNull("virtInterfaceGetXMLDesc", virtInt2.getXMLDescription(0)); virtInt2.undefine(); virtInt2.free(); } public void testAccessAfterClose() throws Exception { conn.close(); assertTrue("conn.isConnected should be false", !conn.isConnected()); LibvirtException virException = null; try { conn.getHostName(); } catch (LibvirtException e) { virException = e; } assertNotNull(virException); } public void testStoragePool() throws Exception { StoragePool pool1 = conn.storagePoolDefineXML("" + " pool1" + " " + " /pool1" + " " + " 004c96e1-2d78-c30f-5aa5-f03c87d21e67" + "", 0) ; StoragePool defaultPool = conn.storagePoolLookupByName("default-pool"); assertEquals("numOfStoragePools:", 1, conn.numOfStoragePools()); assertEquals("numOfDefinedStoragePools:", 1, conn.numOfDefinedStoragePools()); assertNotNull("The pool should not be null", pool1); assertNotNull("The default pool should not be null", defaultPool); assertEquals("The names should match", defaultPool.getName(), "default-pool"); assertEquals("The uids should match", pool1.getUUIDString(), "004c96e1-2d78-c30f-5aa5-f03c87d21e67"); assertTrue("pool1 should be persistent", pool1.isPersistent() == 1); assertTrue("pool1 should not be active", pool1.isActive() == 0); assertTrue("Domain2 should be active", defaultPool.isActive() == 1); } public void testDomainEvents() throws Exception { final List events = new ArrayList(); final Thread t = new Thread() { @Override public void run() { try { Library.runEventLoop(); } catch (LibvirtException e) { fail("LibvirtException was thrown: " + e); } catch (InterruptedException e) { } } }; t.setDaemon(true); t.start(); LifecycleListener listener = new LifecycleListener() { @Override public int onLifecycleChange(Domain d, DomainEvent e) { events.add(e.getType()); return 0; } }; try { conn.addLifecycleListener(listener); Domain dom = conn.domainDefineXML("" + " deftest" + " 004b96e1-2d78-c30f-5aa5-f03c87d21e70" + " 8388608" + " 2" + " hvm" + " restart" + " destroy" + " restart" + ""); dom.create(); dom.suspend(); dom.resume(); dom.destroy(); dom.undefine(); // wait until (presumably) all events have been processed Thread.sleep(300); assertEquals(Arrays.asList(DomainEventType.DEFINED, DomainEventType.STARTED, DomainEventType.SUSPENDED, DomainEventType.RESUMED, DomainEventType.STOPPED, DomainEventType.UNDEFINED), events); } finally { conn.removeLifecycleListener(listener); Library.stopEventLoop(); } } public void testDomainScreenshot() throws Exception { long version = Library.getVersion(); // virDomainScreenshot works since version 1.0.5 on test:// // connections if (version < 1000005) { System.err.format("testDomainScreenshot skipped (libvirt version %d.%d.%d < 1.0.5)\n", version / 1000000, version / 1000 % 1000, version % 1000); return; } Stream str = this.conn.streamNew(0); Domain dom = this.conn.domainLookupByName("test"); assertFalse("Domain \"test\" not found", dom == null); String mimetype; try { mimetype = dom.screenshot(str, 0); } catch (LibvirtException ex) { if (ex.getMessage().contains("test-screenshot.png': No such file or directory")) { System.err.format("testDomainScreenshot skipped (missing png file)"); return; } throw ex; } ByteBuffer bb = ByteBuffer.allocateDirect(8192); while (str.read(bb) != -1) // consume data bb.clear(); // ensure that read() repeatedly returns -1 after EOF assertEquals("Stream is at EOF (1)", -1, str.read(bb)); assertEquals("Stream is at EOF (2)", -1, str.read(bb)); assertEquals("Stream is at EOF (3)", -1, str.read(bb)); // ensure that a ClosedChannelException gets thrown when // trying to read() after closing the stream str.close(); try { str.read(bb); fail("ClosedChannelException expected calling read() on a closed stream"); } catch (ClosedChannelException expected) { } } public void testDomainMetadata() throws LibvirtException { Domain dom = conn.domainDefineXML("" + " metatest" + " 004b96e1-2d78-c30f-5aa5-f03c87d21e70" + " 8388608" + " 2" + " hvm" + " restart" + " destroy" + " restart" + ""); dom.setMetadata(Domain.MetadataType.DESCRIPTION, "a description", null, null, Domain.ModificationImpact.CURRENT); dom.setMetadata(Domain.MetadataType.TITLE, "a title", null, null, Domain.ModificationImpact.CURRENT); String xml1 = "value"; Pattern pattern1 = Pattern.compile("\\s*value\\s*"); String uri1 = "https://libvirt.org/test.rng"; dom.setMetadata(Domain.MetadataType.ELEMENT, xml1, "pfx", uri1, Domain.ModificationImpact.CURRENT); String xml2 = "value2"; Pattern pattern2 = Pattern.compile("\\s*value2\\s*"); String uri2 = "https://libvirt.org/othertest.rng"; dom.setMetadata(Domain.MetadataType.ELEMENT, xml2, "pfx", uri2, Domain.ModificationImpact.CURRENT); assertEquals("a description", dom.getMetadata(Domain.MetadataType.DESCRIPTION, null, Domain.ModificationImpact.CURRENT)); assertEquals("a title", dom.getMetadata(Domain.MetadataType.TITLE, null, Domain.ModificationImpact.CURRENT)); assertTrue(pattern1.matcher(dom.getMetadata(Domain.MetadataType.ELEMENT, uri1, Domain.ModificationImpact.CURRENT)).matches()); assertTrue(pattern2.matcher(dom.getMetadata(Domain.MetadataType.ELEMENT, uri2, Domain.ModificationImpact.CURRENT)).matches()); } public void testDomainInterfaceAddresses() throws LibvirtException { if (conn.getLibVersion() < 5004000) { return; } // earlier versions do not support the call Domain dom = conn.domainDefineXML("" + " ifacetest" + " 7814e417-b628-4e6b-bbd3-a82cb15483f2" + " 8388608" + " 2" + " hvm" + " restart" + " destroy" + " restart" + ""); dom.create(); try { Collection ifaces = dom.interfaceAddresses(Domain.InterfaceAddressesSource.VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE, 0); assertNotNull(ifaces); assertTrue(ifaces.isEmpty()); // Can't really test this without a live network inside the guest. :-( } finally { dom.destroy(); dom.undefine(); } } }