/** * Copyright (c) 2014 SUSE LLC * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ /** * Copyright (c) 2014 Red Hat, Inc. */ package com.redhat.rhn.frontend.xmlrpc.chain.test; import com.redhat.rhn.common.db.datasource.DataResult; import com.redhat.rhn.domain.action.ActionChain; import com.redhat.rhn.domain.action.ActionChainFactory; import com.redhat.rhn.domain.action.ActionFactory; import com.redhat.rhn.domain.channel.Channel; import com.redhat.rhn.domain.channel.test.ChannelFactoryTest; import com.redhat.rhn.domain.errata.Errata; import com.redhat.rhn.domain.errata.ErrataFactory; import com.redhat.rhn.domain.errata.test.ErrataFactoryTest; import com.redhat.rhn.domain.rhnpackage.test.PackageTest; import com.redhat.rhn.domain.server.Network; import com.redhat.rhn.domain.rhnpackage.Package; import com.redhat.rhn.domain.server.InstalledPackage; import com.redhat.rhn.domain.server.Server; import com.redhat.rhn.domain.server.ServerFactory; import com.redhat.rhn.domain.server.test.ServerFactoryTest; import com.redhat.rhn.domain.session.InvalidSessionIdException; import com.redhat.rhn.frontend.dto.PackageListItem; import com.redhat.rhn.frontend.xmlrpc.BaseHandler; import com.redhat.rhn.frontend.xmlrpc.InvalidPackageException; import com.redhat.rhn.frontend.xmlrpc.InvalidParameterException; import com.redhat.rhn.frontend.xmlrpc.NoSuchActionChainException; import com.redhat.rhn.frontend.xmlrpc.NoSuchActionException; import com.redhat.rhn.frontend.xmlrpc.chain.ActionChainHandler; import com.redhat.rhn.frontend.xmlrpc.test.BaseHandlerTestCase; import com.redhat.rhn.manager.errata.cache.test.ErrataCacheManagerTest; import com.redhat.rhn.manager.rhnpackage.PackageManager; import com.redhat.rhn.manager.system.SystemManager; import com.redhat.rhn.manager.system.test.SystemManagerTest; import com.redhat.rhn.testing.ConfigTestUtils; import com.redhat.rhn.testing.TestUtils; import java.net.InetAddress; import java.text.DateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; /** * Test cases for the Action Chain XML-RPC API */ public class ActionChainHandlerTest extends BaseHandlerTestCase { private ActionChainHandler ach; private static final String CHAIN_LABEL = "Quick Brown Fox"; private static final String SCRIPT_SAMPLE = "#!/bin/bash\nexit 0;"; private Server server; private Package pkg; private Package channelPackage; private Errata errata; private ActionChain actionChain; private static final String UNAUTHORIZED_EXCEPTION_EXPECTED = "Expected an exception of type " + InvalidSessionIdException.class.getCanonicalName(); /** * {@inheritDoc} */ @SuppressWarnings("deprecation") @Override public void setUp() throws Exception { super.setUp(); this.server = ServerFactoryTest.createTestServer(this.admin, true); // Network Network net = new Network(); net.setHostname(InetAddress.getLocalHost().getHostName()); net.setIpaddr(InetAddress.getLocalHost().getHostAddress()); this.server.addNetwork(net); // Add capabilities SystemManagerTest.giveCapability(this.server.getId(), "script.run", new Long(1)); SystemManagerTest.giveCapability(this.server.getId(), SystemManager.CAP_CONFIGFILES_DEPLOY, new Long(2)); // Channels this.pkg = PackageTest.createTestPackage(this.admin.getOrg()); Channel channel = ChannelFactoryTest.createBaseChannel(this.admin); channel.addPackage(this.pkg); // Add package, available to the installation this.channelPackage = PackageTest.createTestPackage(this.admin.getOrg()); channel.addPackage(this.channelPackage); this.server.addChannel(channel); // Add errata available to the installation this.errata = ErrataFactoryTest.createTestPublishedErrata( this.admin.getOrg().getId()); // Install one package on the server InstalledPackage ipkg = new InstalledPackage(); ipkg.setArch(this.pkg.getPackageArch()); ipkg.setEvr(this.pkg.getPackageEvr()); ipkg.setName(this.pkg.getPackageName()); ipkg.setServer(this.server); Set<InstalledPackage> serverPkgs = new HashSet<InstalledPackage>(); serverPkgs.add(ipkg); this.server.setPackages(serverPkgs); ServerFactory.save(this.server); this.server = (Server) ActionChainHandlerTest.reload(this.server); ach = new ActionChainHandler(); actionChain = ActionChainFactory.createActionChain(CHAIN_LABEL, admin); } /** * {@inheritDoc} */ @Override protected void tearDown() throws Exception { super.tearDown(); ServerFactory.delete(this.server); } /** * Test action chain create. * @throws Exception if something bad happens */ public void testAcCreateActionChain() throws Exception { String chainName = TestUtils.randomString(); Integer chainId = this.ach.createChain(this.admin, chainName); ActionChain newActionChain = ActionChainFactory.getActionChain(admin, chainName); assertNotNull(newActionChain); assertEquals(newActionChain.getId().longValue(), chainId.longValue()); } /** * Test creating an action chain failure on an empty chain name. * @throws Exception if something bad happens */ public void testAcCreateActionChainFailureOnEmptyName() throws Exception { try { this.ach.createChain(this.admin, ""); fail("Expected exception: " + InvalidParameterException.class.getCanonicalName()); } catch (InvalidParameterException ex) { // expected } } /** * Test system reboot command schedule. * @throws Exception if something bad happens */ public void testAcAddSystemReboot() throws Exception { assertEquals(true, this.ach.addSystemReboot(this.admin, this.server.getId().intValue(), CHAIN_LABEL) > 0); assertEquals(1, actionChain.getEntries().size()); assertEquals(ActionFactory.TYPE_REBOOT, actionChain.getEntries().iterator().next() .getAction().getActionType()); } /** * Test Errata update command schedule. * @throws Exception if something bad happens */ public void testAcAddErrataUpdate() throws Exception { List<Integer> errataIds = new ArrayList<Integer>(); errataIds.add(this.errata.getId().intValue()); assertEquals(true, this.ach.addErrataUpdate(this.admin, this.server.getId().intValue(), errataIds, CHAIN_LABEL) > 0); assertEquals(1, actionChain.getEntries().size()); assertEquals(ActionFactory.TYPE_ERRATA, actionChain.getEntries().iterator().next() .getAction().getActionType()); } /** * Test package installation schedule. * @throws Exception if something bad happens */ public void testAcPackageInstallation() throws Exception { List<Integer> packages = new ArrayList<Integer>(); packages.add(this.channelPackage.getId().intValue()); assertEquals(true, this.ach.addPackageInstall(this.admin, this.server.getId().intValue(), packages, CHAIN_LABEL) > 0); assertEquals(1, actionChain.getEntries().size()); assertEquals(ActionFactory.TYPE_PACKAGES_UPDATE, actionChain.getEntries().iterator().next() .getAction().getActionType()); } /** * Test package installation schedule. * @throws Exception if something bad happens */ public void testAcPackageInstallationFailed() throws Exception { List<Integer> packages = new ArrayList<Integer>(); packages.add(0); try { this.ach.addPackageInstall(this.admin, this.server.getId().intValue(), packages, CHAIN_LABEL); fail("Expected exception: " + InvalidPackageException.class.getCanonicalName()); } catch (InvalidPackageException ex) { assertTrue(actionChain.getEntries().isEmpty()); } } /** * Test package removal. * @throws Exception if something bad happens */ public void testAcPackageRemoval() throws Exception { List<Integer> packagesToRemove = new ArrayList<Integer>(); packagesToRemove.add(this.pkg.getId().intValue()); assertEquals(true, this.ach.addPackageRemoval(this.admin, this.server.getId().intValue(), packagesToRemove, CHAIN_LABEL) > 0); assertEquals(1, actionChain.getEntries().size()); assertEquals(ActionFactory.TYPE_PACKAGES_REMOVE, actionChain.getEntries().iterator().next() .getAction().getActionType()); } /** * Test package removal failure when empty list of packages is passed. * @throws Exception if something bad happens */ public void testAcPackageRemovalFailureOnEmpty() throws Exception { try { assertEquals(true, this.ach.addPackageRemoval( this.admin, this.server.getId().intValue(), new ArrayList<Integer>(), CHAIN_LABEL) > 0); fail("Expected exception: " + InvalidParameterException.class.getCanonicalName()); } catch (InvalidParameterException ex) { assertEquals(0, actionChain.getEntries().size()); } } /** * Test package removal failure when list of unknown packages is passed. * @throws Exception if something bad happens */ public void testAcPackageRemovalFailureOnUnknownPackages() throws Exception { List<Integer> packagesToRemove = new ArrayList<Integer>(); packagesToRemove.add(0); try { assertEquals(true, this.ach.addPackageRemoval(this.admin, this.server.getId().intValue(), packagesToRemove, CHAIN_LABEL) > 0); fail("Expected exception: " + InvalidPackageException.class.getCanonicalName()); } catch (InvalidPackageException ex) { assertEquals(0, actionChain.getEntries().size()); } } /** * Test list chains. */ public void testAcListChains() { String[] labels = new String[]{ TestUtils.randomString(), TestUtils.randomString(), TestUtils.randomString() }; int previousChains = ActionChainFactory.getActionChains(this.admin).size(); for (String label : labels) { ActionChainFactory.createActionChain(label, admin); } List<Map<String, Object>> chains = this.ach.listChains(this.admin); assertEquals(labels.length, chains.size() - previousChains); for (String label : labels) { ActionChain chain = ActionChainFactory.getActionChain(this.admin, label); assertEquals(0, chain.getEntries().size()); } } /** * Test chain actions content. */ public void testAcChainActionsContent() { assertEquals(true, this.ach.addSystemReboot(this.admin, this.server.getId().intValue(), CHAIN_LABEL) > 0); for (Map<String, Object> action : this.ach.listChainActions(this.admin, CHAIN_LABEL)) { assertEquals("System reboot", action.get("label")); assertEquals("System reboot", action.get("type")); assertEquals(DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT) .format((Date) action.get("created")), DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT) .format((Date) action.get("earliest"))); } } /** * Test chains removal. */ public void testAcRemoveChain() { int previousChainCount = this.ach.listChains(this.admin).size(); this.ach.deleteChain(this.admin, actionChain.getLabel()); assertEquals(1, previousChainCount - this.ach.listChains(this.admin).size()); } /** * Test chains removal failure when empty chain is passed. */ public void testAcRemoveChainsFailureOnEmpty() { int previousChainCount = this.ach.listChains(this.admin).size(); try { this.ach.deleteChain(this.admin, ""); fail("Expected exception: " + NoSuchActionChainException.class.getCanonicalName()); } catch (NoSuchActionChainException ex) { assertEquals(0, previousChainCount - this.ach.listChains(this.admin).size()); } } /** * Test chains removal failure when unknown chain is passed. */ public void testAcRemoveChainsFailureOnUnknown() { int previousChainCount = this.ach.listChains(this.admin).size(); try { this.ach.deleteChain(this.admin, TestUtils.randomString()); fail("Expected exception: " + NoSuchActionChainException.class.getCanonicalName()); } catch (NoSuchActionChainException ex) { assertEquals(0, previousChainCount - this.ach.listChains(this.admin).size()); } } /** * Test actions removal. */ public void testAcRemoveActions() { assertEquals(true, this.ach.addSystemReboot(this.admin, this.server.getId().intValue(), CHAIN_LABEL) > 0); assertEquals(false, this.ach.listChainActions( this.admin, CHAIN_LABEL).isEmpty()); assertEquals(true, this.ach.removeAction( this.admin, CHAIN_LABEL, ((Long) ((Map) this.ach.listChainActions(this.admin, CHAIN_LABEL).get(0)) .get("id")).intValue()) > 0); assertEquals(true, this.ach.listChainActions(this.admin, CHAIN_LABEL).isEmpty()); } /** * Test empty list does not remove any actions, schedule does not happening. */ public void testAcRemoveActionsEmpty() { assertEquals(true, this.ach.addSystemReboot(this.admin, this.server.getId().intValue(), CHAIN_LABEL) > 0); try { this.ach.removeAction(this.admin, CHAIN_LABEL, 0); fail("Expected exception: " + NoSuchActionException.class.getCanonicalName()); } catch (NoSuchActionException ex) { assertEquals(false, this.ach.listChainActions(this.admin, CHAIN_LABEL).isEmpty()); } } /** * Test removal of the actions on the unknown chain. */ public void testAcRemoveActionsUnknownChain() { assertEquals(true, this.ach.addSystemReboot(this.admin, this.server.getId().intValue(), CHAIN_LABEL) > 0); try { this.ach.removeAction(this.admin, "", 0); fail("Expected exception: " + NoSuchActionChainException.class.getCanonicalName()); } catch (NoSuchActionChainException ex) { assertEquals(false, this.ach.listChainActions( this.admin, CHAIN_LABEL).isEmpty()); } } /** * Test unknown list of actions on certain chain does not remove anything * and schedule should not happen. */ public void testAcRemoveActionsUnknownChainActions() { assertEquals(true, this.ach.addSystemReboot(this.admin, this.server.getId().intValue(), CHAIN_LABEL) > 0); try { this.ach.removeAction(this.admin, CHAIN_LABEL, 0); fail("Expected exception: " + NoSuchActionException.class.getCanonicalName()); } catch (NoSuchActionException ex) { assertEquals(false, this.ach.listChainActions( this.admin, CHAIN_LABEL).isEmpty()); } } /** * Test package upgrade. * @throws Exception if something bad happens */ @SuppressWarnings("unchecked") public void testAcPackageUpgrade() throws Exception { Map<String, Object> info = ErrataCacheManagerTest.createServerNeededPackageCache(this.admin, ErrataFactory.ERRATA_TYPE_BUG); List<Integer> upgradePackages = new ArrayList<Integer>(); Server system = (Server) info.get("server"); upgradePackages.add(this.pkg.getId().intValue()); assertEquals(true, this.ach.addPackageUpgrade(this.admin, system.getId().intValue(), upgradePackages, CHAIN_LABEL) > 0); assertEquals(false, this.ach.listChains(this.admin).isEmpty()); assertEquals(false, this.ach.listChainActions(this.admin, CHAIN_LABEL).isEmpty()); assertEquals(1, actionChain.getEntries().size()); assertEquals(ActionFactory.TYPE_PACKAGES_UPDATE, actionChain.getEntries() .iterator().next().getAction().getActionType()); } /** * Test package upgrade with an empty list. */ public void testAcPackageUpgradeOnEmpty() { List<Integer> upgradePackages = new ArrayList<Integer>(); try { this.ach.addPackageUpgrade(this.admin, this.server.getId().intValue(), upgradePackages, CHAIN_LABEL); fail("Expected exception: " + InvalidParameterException.class.getCanonicalName()); } catch (InvalidParameterException ex) { assertEquals(0, actionChain.getEntries().size()); } } /** * Test package upgrade with an empty list. */ public void testAcPackageUpgradeOnUnknown() { List<Integer> upgradePackages = new ArrayList<Integer>(); upgradePackages.add(0); try { this.ach.addPackageUpgrade(this.admin, this.server.getId().intValue(), upgradePackages, CHAIN_LABEL); fail("Expected exception: " + InvalidPackageException.class.getCanonicalName()); } catch (InvalidPackageException ex) { assertTrue(actionChain.getEntries().isEmpty()); } } /** * Test package verification. */ @SuppressWarnings("unchecked") public void testAcPackageVerify() { DataResult<PackageListItem> packageListItems = PackageManager.systemPackageList(this.server.getId(), null); List<Integer> packages = new ArrayList<Integer>(); for (PackageListItem packageListItem : packageListItems) { packages.add(packageListItem.getPackageId().intValue()); } assertEquals(true, this.ach.addPackageVerify(this.admin, this.server.getId().intValue(), packages, CHAIN_LABEL) > 0); assertEquals(1, actionChain.getEntries().size()); assertEquals(ActionFactory.TYPE_PACKAGES_VERIFY, actionChain.getEntries() .iterator().next().getAction().getActionType()); } /** * Test package verification failure when empty list is passed. */ public void testAcPackageVerifyFailureOnEmpty() { try { this.ach.addPackageVerify(this.admin, this.server.getId().intValue(), new ArrayList<Integer>(), CHAIN_LABEL); fail("Expected exception: " + InvalidParameterException.class.getCanonicalName()); } catch (InvalidParameterException ex) { assertEquals(0, actionChain.getEntries().size()); } } /** * Test package verification failure when unknown package is verified. */ public void testAcPackageVerifyFailureOnUnknown() { List<Integer> packages = new ArrayList<Integer>(); packages.add(0); try { this.ach.addPackageVerify(this.admin, this.server.getId().intValue(), packages, CHAIN_LABEL); fail("Expected exception: " + InvalidPackageException.class.getCanonicalName()); } catch (InvalidPackageException ex) { assertEquals(0, actionChain.getEntries().size()); } } /** * Test schedule remote command. */ public void testAcRemoteCommand() { assertEquals(true, this.ach.addScriptRun(this.admin, this.server.getId().intValue(), CHAIN_LABEL, "root", "root", 300, ActionChainHandlerTest.SCRIPT_SAMPLE) > 0); assertEquals(1, actionChain.getEntries().size()); assertEquals(ActionFactory.TYPE_SCRIPT_RUN, actionChain.getEntries() .iterator().next().getAction().getActionType()); } /** * Test schedule on precise time. */ public void testAcScheduleOnTime() { assertEquals(new Integer(1), this.ach.scheduleChain(this.admin, CHAIN_LABEL, new Date())); } /** * Test schedule on precise time. */ public void testAcScheduleOnTimeFailureNoChain() { try { this.ach.scheduleChain(this.admin, "", new Date()); fail("Expected exception: " + NoSuchActionChainException.class.getCanonicalName()); } catch (NoSuchActionChainException ex) { //expected } } /** * Deploy configuration. */ public void testAcDeployConfiguration() { List<Integer> revisions = new ArrayList<Integer>(); revisions.add(ConfigTestUtils.createConfigRevision( this.admin.getOrg()).getId().intValue()); assertEquals(new Integer(BaseHandler.VALID), this.ach.addConfigurationDeployment(this.admin, CHAIN_LABEL, this.server.getId().intValue(), revisions)); } /** * Deploy configuration should fail if no chain label has been passed. */ public void testAcDeployConfigurationFailureNoChain() { List<Integer> revisions = new ArrayList<Integer>(); revisions.add(ConfigTestUtils.createConfigRevision( this.admin.getOrg()).getId().intValue()); try { this.ach.addConfigurationDeployment(this.admin, "", this.server.getId().intValue(), revisions); fail("Expected exception: " + NoSuchActionChainException.class.getCanonicalName()); } catch (NoSuchActionChainException ex) { //expected } } /** * Rename an action chain. */ public void testAcRenameActionChain() { assertEquals(true, actionChain.getLabel().equals(CHAIN_LABEL)); assertEquals(new Integer(1), this.ach.renameChain( this.admin, CHAIN_LABEL, TestUtils.randomString())); assertEquals(false, actionChain.getLabel().equals(CHAIN_LABEL)); } /** * Rename an action chain should fail when renaming to the same label. */ public void testAcRenameActionChainFailureOnSameLabel() { assertEquals(true, actionChain.getLabel().equals(CHAIN_LABEL)); try { assertEquals(new Integer(1), this.ach.renameChain(this.admin, CHAIN_LABEL, CHAIN_LABEL)); fail("Expected exception: " + InvalidParameterException.class.getCanonicalName()); } catch (InvalidParameterException ex) { assertEquals(true, actionChain.getLabel().equals(CHAIN_LABEL)); } } /** * Rename an action chain should fail when previous label is missing. */ public void testAcRenameActionChainFailureOnEmptyPreviousLabel() { assertEquals(true, actionChain.getLabel().equals(CHAIN_LABEL)); try { assertEquals(new Integer(1), this.ach.renameChain(this.admin, "", CHAIN_LABEL)); fail("Expected exception: " + InvalidParameterException.class.getCanonicalName()); } catch (InvalidParameterException ex) { assertEquals(true, actionChain.getLabel().equals(CHAIN_LABEL)); } } /** * Rename an action chain should fail when new label is missing. */ public void testAcRenameActionChainFailureOnEmptyNewLabel() { assertEquals(true, actionChain.getLabel().equals(CHAIN_LABEL)); try { assertEquals(new Integer(1), this.ach.renameChain(this.admin, CHAIN_LABEL, "")); fail("Expected exception: " + InvalidParameterException.class.getCanonicalName()); } catch (InvalidParameterException ex) { assertEquals(true, actionChain.getLabel().equals(CHAIN_LABEL)); } } }