/** * Copyright (C) 2008 Progress Software, Inc. All rights reserved. * http://fusesource.com * * The software in this package is published under the terms of the AGPL license * a copy of which has been included with this distribution in the license.txt file. */ package org.fusesource.cloudmix.agent; import java.io.File; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import junit.framework.TestCase; import org.easymock.EasyMock; import org.fusesource.cloudmix.common.GridClient; import org.fusesource.cloudmix.common.dto.AgentCfgUpdate; import org.fusesource.cloudmix.common.dto.AgentDetails; import org.fusesource.cloudmix.common.dto.ConfigurationUpdate; import org.fusesource.cloudmix.common.dto.ProvisioningAction; import org.fusesource.cloudmix.common.dto.ProvisioningHistory; import org.fusesource.cloudmix.common.util.FileUtils; public class AbstractInstallerAgentTest extends TestCase { class TestInstaller extends InstallerAgent { private Set<String> installedNames; private Set<String> installedURIs; private boolean validated; private String featureList; public TestInstaller() { super(); installedNames = new HashSet<String>(); installedURIs = new HashSet<String>(); } public String[] getInstalledNames() { return (String[])installedNames.toArray(new String[installedNames.size()]); } public String[] getInstalledURIs() { return (String[])installedURIs.toArray(new String[installedURIs.size()]); } public boolean wasValidated() { return validated; } public String getFeatureListDoc() { return featureList; } @Override protected void installFeature(Feature feature, List<ConfigurationUpdate> cfg) throws Exception { super.installFeature(feature, cfg); featureList = feature.getFeatureList().toString(); } @Override protected boolean installBundle(Feature feature, Bundle bundle) { if (bundle.getUri().startsWith("https")) { return false; } installedURIs.add(bundle.getUri()); installedNames.add(bundle.getName()); return true; } @Override protected boolean uninstallBundle(Feature feature, Bundle bundle) { installedURIs.remove(bundle.getUri()); installedNames.remove(bundle.getName()); return true; } @Override protected boolean validateAgent() { validated = true; return true; } } private GridClient cl; private ProvisioningHistory ph; private TestInstaller installer; @Override protected void setUp() throws Exception { cl = EasyMock.createNiceMock(GridClient.class); EasyMock.replay(cl); File tmpWorkDirectory = new File("tmp.work.dir"); FileUtils.deleteDirectory(tmpWorkDirectory); if (tmpWorkDirectory.exists()) { System.out.println("\n\nWARNING: directory " + tmpWorkDirectory + " still exists\n\n"); } installer = new TestInstaller(); installer.setClient(cl); installer.setWorkDirectory(tmpWorkDirectory); installer.init(); ph = new ProvisioningHistory(); } @Override protected void tearDown() { File tmpWorkDirectory = new File("tmp.work.dir"); FileUtils.deleteDirectory(tmpWorkDirectory); } public void testInstallNothing() throws Exception { assertNothingInstalled(); AgentDetails details = installer.getAgentDetails(); assertEquals("default", details.getProfile()); assertEquals(0, details.getCurrentFeatures().size()); assertEquals(null, details.getAgentLink()); assertEquals(null, details.getContainerType()); assertEquals(0, details.getSupportPackageTypes().length); details.setAgentLink("http://localhost:9999/stuff"); details.setContainerType("Test"); String [] supportPackageTypes = {"horse", "cart"}; details.setSupportPackageTypes(supportPackageTypes); assertEquals("http://localhost:9999/stuff", details.getAgentLink()); assertEquals("Test", details.getContainerType()); assertEquals(2, details.getSupportPackageTypes().length); assertEquals("horse", details.getSupportPackageTypes()[0]); assertEquals("cart", details.getSupportPackageTypes()[1]); installer.onProvisioningHistoryChanged(ph); assertTrue(installer.wasValidated()); assertNothingInstalled(); details = installer.getAgentDetails(); assertEquals("default", details.getProfile()); assertEquals(0, details.getCurrentFeatures().size()); } public void testInstallSimple() throws Exception { assertNothingInstalled(); ph.addAction(createInstallAction("f1", "/features_1.xml")); AgentDetails details = installer.getAgentDetails(); assertEquals("default", details.getProfile()); assertEquals(0, details.getCurrentFeatures().size()); installer.onProvisioningHistoryChanged(ph); assertInstalledNames("r_1.txt"); assertInstalled("http://example.com/r1.txt"); details = installer.getAgentDetails(); assertEquals(1, details.getCurrentFeatures().size()); assertContains(details.getCurrentFeatures(), "f1"); } protected <T> void assertContains(Collection<T> collection, T element) { assertTrue("collection " + collection + " does not contain " + element, collection.contains(element)); } // TODO: Enable when CM-2 is fixed. /* public void testInstallRestart() throws Exception { testInstallSimple(); installer.init(); assertNothingInstalled(); AgentDetails details = installer.getAgentDetails(); assertEquals(0, details.getCurrentFeatures().size()); } */ public void testInstallSimpleAsync() throws Exception { assertNothingInstalled(); ph.addAction(createInstallAction("f1", "/features_1.xml")); AgentDetails details = installer.getAgentDetails(); assertEquals("default", details.getProfile()); assertEquals(0, details.getCurrentFeatures().size()); installer.asyncOnProvisioningHistoryChanged(ph); // Let the provisioning thread run. Thread.sleep(2000); assertInstalledNames("r_1.txt"); assertInstalled("http://example.com/r1.txt"); details = installer.getAgentDetails(); assertEquals(1, details.getCurrentFeatures().size()); assertContains(details.getCurrentFeatures(), "f1"); } public void testInstallMultipleBundles() throws Exception { assertNothingInstalled(); ph.addAction(createInstallAction("f2", "/features_2.xml")); AgentDetails details = installer.getAgentDetails(); assertEquals("default", details.getProfile()); assertEquals(0, details.getCurrentFeatures().size()); installer.onProvisioningHistoryChanged(ph); assertInstalledNames("r2.txt"); assertInstalled("http://example.com/r2.txt", "http://example.com/r3.txt", "http://example.com/r4.txt"); details = installer.getAgentDetails(); assertEquals(1, details.getCurrentFeatures().size()); assertContains(details.getCurrentFeatures(), "f2"); } public void testInstallMultipleFeatures() throws Exception { assertNothingInstalled(); ph.addAction(createInstallAction("f1", "/features_1.xml")); ph.addAction(createInstallAction("f2", "/features_2.xml")); AgentDetails details = installer.getAgentDetails(); assertEquals("default", details.getProfile()); assertEquals(0, details.getCurrentFeatures().size()); installer.onProvisioningHistoryChanged(ph); assertInstalled("http://example.com/r1.txt", "http://example.com/r2.txt", "http://example.com/r3.txt", "http://example.com/r4.txt"); details = installer.getAgentDetails(); assertEquals(2, details.getCurrentFeatures().size()); assertTrue(contains("f1", details.getCurrentFeatures())); assertTrue(contains("f2", details.getCurrentFeatures())); } public void testInstallUninstall() throws Exception { assertNothingInstalled(); ph.addAction(createInstallAction("f1", "/features_1.xml")); ph.addAction(createInstallAction("f2", "/features_2.xml")); ph.addAction(createUninstallAction("f3")); AgentDetails details = installer.getAgentDetails(); assertEquals(0, details.getCurrentFeatures().size()); installer.onProvisioningHistoryChanged(ph); assertInstalled("http://example.com/r1.txt", "http://example.com/r2.txt", "http://example.com/r3.txt", "http://example.com/r4.txt"); details = installer.getAgentDetails(); assertEquals(2, details.getCurrentFeatures().size()); assertTrue(contains("f1", details.getCurrentFeatures())); assertTrue(contains("f2", details.getCurrentFeatures())); assertTrue(!contains("f3", details.getCurrentFeatures())); // Run same history again. installer.onProvisioningHistoryChanged(ph); assertInstalled("http://example.com/r1.txt", "http://example.com/r2.txt", "http://example.com/r3.txt", "http://example.com/r4.txt"); details = installer.getAgentDetails(); assertEquals(2, details.getCurrentFeatures().size()); assertTrue(contains("f1", details.getCurrentFeatures())); assertTrue(contains("f2", details.getCurrentFeatures())); assertTrue(!contains("f3", details.getCurrentFeatures())); // Uninstall a feature. ph.addAction(createUninstallAction("f1")); installer.onProvisioningHistoryChanged(ph); assertNotInstalled("http://example.com/r1.txt"); assertInstalled("http://example.com/r2.txt", "http://example.com/r3.txt", "http://example.com/r4.txt"); details = installer.getAgentDetails(); assertEquals(1, details.getCurrentFeatures().size()); assertTrue(!contains("f1", details.getCurrentFeatures())); assertTrue(contains("f2", details.getCurrentFeatures())); assertTrue(!contains("f3", details.getCurrentFeatures())); // This is an updated feature list - what should happen here? ph.addAction(createInstallAction("f2", "/features_2a.xml")); installer.onProvisioningHistoryChanged(ph); assertNotInstalled("http://example.com/r1.txt", "http://example.com/r3.txt", "http://example.com/r4.txt"); assertInstalled("http://example.com/r2.txt"); // TODO more here. } public void testInstallBadFeature() throws Exception { assertNothingInstalled(); ph.addAction(createInstallAction("f3", "/features_3.xml")); AgentDetails details = installer.getAgentDetails(); assertEquals(0, details.getCurrentFeatures().size()); installer.onProvisioningHistoryChanged(ph); assertInstalled(); details = installer.getAgentDetails(); assertEquals(0, details.getCurrentFeatures().size()); } public void testInstallBadBundles() throws Exception { assertNothingInstalled(); ph.addAction(createInstallAction("f4", "/features_4.xml")); AgentDetails details = installer.getAgentDetails(); assertEquals("default", details.getProfile()); assertEquals(0, details.getCurrentFeatures().size()); installer.onProvisioningHistoryChanged(ph); assertNotInstalled("https://example.com/r2.txt", "https://example.com/r4.txt"); assertInstalled("http://example.com/r1.txt", "http://example.com/r3.txt"); details = installer.getAgentDetails(); assertEquals(1, details.getCurrentFeatures().size()); assertContains(details.getCurrentFeatures(), "f4"); } public void testUpdateConfiguration() throws Exception { assertNothingInstalled(); ph.addCfgUpdate(new AgentCfgUpdate(AgentCfgUpdate.PROPERTY_AGENT_NAME, "bob")); ph.addCfgUpdate(new AgentCfgUpdate(AgentCfgUpdate.PROPERTY_PROFILE_ID, "umberProfile")); AgentDetails details = installer.getAgentDetails(); String initialAgentId = installer.getAgentId(); assertEquals("default", details.getProfile()); assertEquals(0, details.getCurrentFeatures().size()); installer.onProvisioningHistoryChanged(ph); assertEquals("bob", details.getName()); assertEquals("umberProfile", details.getProfile()); assertEquals(initialAgentId, installer.getAgentId()); assertEquals(initialAgentId, details.getId()); } public void testSetApplicationProperties() throws Exception { assertNothingInstalled(); ph.addAction(createInstallAction("f6", "/features_6.xml")); AgentDetails details = installer.getAgentDetails(); assertEquals("default", details.getProfile()); assertEquals(0, details.getCurrentFeatures().size()); installer.onProvisioningHistoryChanged(ph); assertEquals("Application cfg 1", System.getProperty("appProp1")); assertEquals("appCfg2", System.getProperty("appProp2")); assertEquals("3", System.getProperty("app_Prop_3")); } public void testSetApplicationPropertyOverrides() throws Exception { assertNothingInstalled(); ProvisioningAction installAction = createInstallAction("f6", "/features_6.xml"); installAction.addCfgOverride(new ConfigurationUpdate("appCfg2", "has been Overridden")); ph.addAction(installAction); AgentDetails details = installer.getAgentDetails(); assertEquals("default", details.getProfile()); assertEquals(0, details.getCurrentFeatures().size()); installer.onProvisioningHistoryChanged(ph); assertEquals("Application cfg 1", System.getProperty("appProp1")); assertEquals("has been Overridden", System.getProperty("appCfg2")); assertEquals("3", System.getProperty("app_Prop_3")); } private ProvisioningAction createInstallAction(String feature, String resource) { String url = this.getClass().getResource(resource).toString(); return new ProvisioningAction(ProvisioningAction.INSTALL_COMMAND, feature, url); } private ProvisioningAction createUninstallAction(String feature) { return new ProvisioningAction(ProvisioningAction.UNINSTALL_COMMAND, feature, null); } private void assertNothingInstalled() { assertEquals("Nothing deployed", 0, installer.getInstalledNames().length); } private void assertInstalled(String... names) { assertListsMatch(installer.getInstalledURIs(), names); } private void assertInstalledNames(String... names) { assertListsMatch(installer.getInstalledNames(), names); } private void assertNotInstalled(String... names) { String[] installedURIs = installer.getInstalledURIs(); int count = 0; for (String n : names) { boolean found = false; for (String s : installedURIs) { if (n.equals(s)) { count++; found = true; } } if (found) { fail("Bundle " + n + " is installed, but should not be"); } } assertEquals(0, count); } private void assertListsMatch(String[] list, String... names) { int count = 0; for (String n : names) { boolean found = false; for (String s : list) { if (n.equals(s)) { count++; found = true; } } if (!found) { fail("Bundle " + n + " is not installed"); } } assertEquals(names.length, count); } protected <T> boolean contains(T element, Collection<T> collection) { return collection.contains(element); } }