/*
* RHQ Management Platform
* Copyright (C) 2005-2008 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License.
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.rhq.enterprise.server.content.test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
import javax.persistence.Query;
import org.testng.annotations.Test;
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.agent.content.ContentAgentService;
import org.rhq.core.clientapi.server.content.ContentDiscoveryReport;
import org.rhq.core.clientapi.server.content.DeletePackagesRequest;
import org.rhq.core.clientapi.server.content.DeployPackagesRequest;
import org.rhq.core.clientapi.server.content.RetrievePackageBitsRequest;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.content.Architecture;
import org.rhq.core.domain.content.ContentRequestStatus;
import org.rhq.core.domain.content.ContentRequestType;
import org.rhq.core.domain.content.ContentServiceRequest;
import org.rhq.core.domain.content.InstalledPackage;
import org.rhq.core.domain.content.InstalledPackageHistory;
import org.rhq.core.domain.content.InstalledPackageHistoryStatus;
import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageCategory;
import org.rhq.core.domain.content.PackageDetailsKey;
import org.rhq.core.domain.content.PackageInstallationStep;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.content.transfer.ContentResponseResult;
import org.rhq.core.domain.content.transfer.DeployIndividualPackageResponse;
import org.rhq.core.domain.content.transfer.DeployPackageStep;
import org.rhq.core.domain.content.transfer.DeployPackagesResponse;
import org.rhq.core.domain.content.transfer.RemoveIndividualPackageResponse;
import org.rhq.core.domain.content.transfer.RemovePackagesResponse;
import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
import org.rhq.core.domain.criteria.InstalledPackageCriteria;
import org.rhq.core.domain.criteria.PackageVersionCriteria;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.auth.SubjectManagerLocal;
import org.rhq.enterprise.server.content.ContentManagerLocal;
import org.rhq.enterprise.server.test.AbstractEJB3Test;
import org.rhq.enterprise.server.test.TestServerCommunicationsService;
import org.rhq.enterprise.server.util.LookupUtil;
import org.rhq.enterprise.server.util.ResourceTreeHelper;
@Test
public class ContentManagerBeanTest extends AbstractEJB3Test {
// Attributes --------------------------------------------
private static final boolean ENABLE_TESTS = true;
/**
* ContentAgentService method implementations should synchronize on this to allow the test method to pause before
* the reponse is sent and check the state of the server.
*/
private static final Object responseLock = new Object();
private ContentManagerLocal contentManager;
private SubjectManagerLocal subjectManager;
private MockContentAgentService contentAgentService = new MockContentAgentService();
private PackageType packageType1;
private PackageType packageType2;
private PackageType packageType3;
private PackageType packageType4;
/**
* Type: packageType1 Versions: 2
*/
private Package package1;
/**
* Type: packageType2 Versions: 2
*/
private Package package2;
/**
* Type: packageType3 Versions: 1
*/
private Package package3;
/**
* Type: packageType4 Versions: 2 Installed: Version 1
*/
private Package package4;
/**
* Type: packageType4 Versions: 1 Installed: Version 1
*/
private Package package5;
private InstalledPackage installedPackage1;
private InstalledPackage installedPackage2;
/**
* Architecture used in the creation of all sample package versions.
*/
private Architecture architecture1;
/**
* Extra architecture used in tests.
*/
private Architecture architecture2;
private List<DeployPackageStep> stepResults;
private ResourceType resourceType1;
private Resource resource1;
// Setup --------------------------------------------
//@BeforeClass don't use BeforeClass as Arquillian 1.0.2 invokes it on every test method
protected void beforeClass() throws Exception {
contentManager = LookupUtil.getContentManager();
subjectManager = LookupUtil.getSubjectManager();
populateResponseSteps();
}
@Override
protected void beforeMethod() throws Exception {
beforeClass();
setupTestEnvironment();
}
@Override
protected void afterMethod() throws Exception {
tearDownTestEnvironment();
}
// Test Cases --------------------------------------------
@Test(enabled = ENABLE_TESTS)
public void testPersistSafely() throws Throwable {
final String pkgName = "testPersistSafelyPackage";
final String pvName = "testPersistSafelyPackageVersion version";
final PackageType pkgType = packageType1;
final Architecture arch = architecture1;
// these will not have any JPA stubs inside them (i.e. no lazy exceptions will occur with these)
Package pkgPojo = new Package(pkgName, pkgType);
PackageVersion pvPojo = new PackageVersion(pkgPojo, pvName, arch);
Configuration configPojo = new Configuration();
configPojo.put(new PropertySimple("one", "two"));
pvPojo.setExtraProperties(configPojo);
Package persistedPkg = null;
PackageVersion persistedPV = null;
try {
// create the entities that we will pass to the persist methods - these will get altered
Package pkg = new Package(pkgName, pkgType);
PackageVersion pv = new PackageVersion(pkg, pvName, arch);
pv.setExtraProperties(configPojo);
persistedPkg = this.contentManager.persistOrMergePackageSafely(pkg);
assert persistedPkg != null;
assert persistedPkg.getId() > 0;
assert persistedPkg.equals(pkgPojo) : "not equal: " + persistedPkg + "<>" + pkgPojo;
persistedPV = this.contentManager.persistOrMergePackageVersionSafely(pv);
assert persistedPV != null;
assert persistedPV.getId() > 0;
assert persistedPV.equals(pvPojo) : "not equal: " + persistedPV + "<>" + pvPojo;
assert persistedPV.getExtraProperties() != null;
assert persistedPV.getExtraProperties().getId() > 0;
assert persistedPV.getExtraProperties().getSimple("one").getStringValue().equals("two");
// remember their new IDs - we want to make sure the same IDs are reused later
int pkgId = persistedPkg.getId();
int pvId = persistedPV.getId();
int configId = persistedPV.getExtraProperties().getId();
int propId = persistedPV.getExtraProperties().getSimple("one").getId();
// we've persisted them, let's make sure our "safely" methods still work
// create new entities that we will pass to the persist methods - these will get altered
pkg = new Package(pkgName, pkgType);
pv = new PackageVersion(pkg, pvName, arch);
pv.setExtraProperties(configPojo);
persistedPkg = this.contentManager.persistOrMergePackageSafely(pkg);
assert persistedPkg != null;
assert persistedPkg.getId() > 0;
assert persistedPkg.equals(pkgPojo) : "not equal: " + persistedPkg + "<>" + pkgPojo;
persistedPV = this.contentManager.persistOrMergePackageVersionSafely(pv);
assert persistedPV != null;
assert persistedPV.getId() > 0;
assert persistedPV.equals(pvPojo) : "not equal: " + persistedPV + "<>" + pvPojo;
assert persistedPV.getExtraProperties() != null;
assert persistedPV.getExtraProperties().getId() > 0;
assert persistedPV.getExtraProperties().getSimple("one").getStringValue().equals("two");
// make sure we merged the existing entities - we should not have created new ones
assert pkgId == persistedPkg.getId();
assert pvId == persistedPV.getId();
assert configId == persistedPV.getExtraProperties().getId();
assert propId == persistedPV.getExtraProperties().getSimple("one").getId();
// now pass in existing entities with non-zero IDs
pkg = new Package(pkgName, pkgType);
pv = new PackageVersion(pkg, pvName, arch);
pv.setExtraProperties(configPojo);
pkg.setId(persistedPkg.getId());
pv.setId(persistedPV.getId());
persistedPkg = this.contentManager.persistOrMergePackageSafely(pkg);
assert persistedPkg != null;
assert persistedPkg.getId() > 0;
assert persistedPkg.equals(pkgPojo) : "not equal: " + persistedPkg + "<>" + pkgPojo;
persistedPV = this.contentManager.persistOrMergePackageVersionSafely(pv);
assert persistedPV != null;
assert persistedPV.getId() > 0;
assert persistedPV.equals(pvPojo) : "not equal: " + persistedPV + "<>" + pvPojo;
assert persistedPV.getExtraProperties() != null;
assert persistedPV.getExtraProperties().getId() > 0;
assert persistedPV.getExtraProperties().getSimple("one").getStringValue().equals("two");
// make sure we merged the existing entities - we should not have created new ones
assert pkgId == persistedPkg.getId();
assert pvId == persistedPV.getId();
assert configId == persistedPV.getExtraProperties().getId();
assert propId == persistedPV.getExtraProperties().getSimple("one").getId();
} catch (Throwable t) {
t.printStackTrace();
throw t;
} finally {
getTransactionManager().begin();
try {
if (persistedPV != null && persistedPV.getId() > 0) {
persistedPV = em.find(PackageVersion.class, persistedPV.getId());
em.remove(persistedPV);
}
if (persistedPkg != null && persistedPkg.getId() > 0) {
persistedPkg = em.find(Package.class, persistedPkg.getId());
em.remove(persistedPkg);
}
} finally {
getTransactionManager().commit();
}
}
}
@SuppressWarnings("unchecked")
@Test(enabled = ENABLE_TESTS)
public void testInventoryMerge() throws Exception {
// Setup --------------------------------------------
ContentDiscoveryReport report = new ContentDiscoveryReport();
report.setResourceId(resource1.getId());
// Package version that exists
PackageDetailsKey key1 = new PackageDetailsKey(package1.getName(), "2.0.0",
package1.getPackageType().getName(), architecture1.getName());
ResourcePackageDetails package1 = new ResourcePackageDetails(key1);
report.addDeployedPackage(package1);
// Package version number that doesn't exist
PackageDetailsKey key2 = new PackageDetailsKey(package2.getName(), "3.0.0", this.package2.getPackageType()
.getName(), architecture1.getName());
ResourcePackageDetails package2 = new ResourcePackageDetails(key2);
report.addDeployedPackage(package2);
// Package with same version number but different architecture
PackageDetailsKey key3 = new PackageDetailsKey(package3.getName(), "1.0.0", this.package3.getPackageType()
.getName(), architecture2.getName());
ResourcePackageDetails package3 = new ResourcePackageDetails(key3);
report.addDeployedPackage(package3);
// Package where entire package does not exist
PackageDetailsKey key4 = new PackageDetailsKey("PackageX", "1.0.0", packageType4.getName(),
architecture1.getName());
ResourcePackageDetails package4 = new ResourcePackageDetails(key4);
// Fully populate this version to make sure the translation from details -> domain model works
// Don't need to do this on all packages
package4.setClassification("Package X1 Category");
package4.setDisplayName("Package X1 Display Name");
package4.setDisplayVersion("Package X1 Display Version");
package4.setFileCreatedDate(System.currentTimeMillis());
package4.setFileName("package4.tar.gz");
package4.setFileSize(1000L);
package4.setLicenseName("GPL");
package4.setLicenseVersion("2");
package4.setLongDescription("Package X1 Long Description");
package4.setMD5("7bf1adec93fdb899aeca248a38603d58");
package4.setSHA256("935f051cab5240b979bba87ce58183d50f592a962202ca683f12a7966414fe6c");
package4.setShortDescription("Package X1 Short Description");
String package4Metadata = "Package X1 Metadata";
package4.setMetadata(package4Metadata.getBytes());
Configuration package4DeploymentConfiguration = new Configuration();
package4DeploymentConfiguration.put(new PropertySimple("property1", "value1"));
package4.setDeploymentTimeConfiguration(package4DeploymentConfiguration);
Configuration package4ExtraProperties = new Configuration();
package4ExtraProperties.put(new PropertySimple("property2", "value2"));
package4.setExtraProperties(package4ExtraProperties);
report.addDeployedPackage(package4);
// Upgraded package to package version known to the system
PackageDetailsKey key5 = new PackageDetailsKey("Package4", "2.0.0", this.package4.getPackageType().getName(),
architecture1.getName());
ResourcePackageDetails package5 = new ResourcePackageDetails(key5);
report.addDeployedPackage(package5);
// In most cases, the same package report will come back from the agent (i.e. no changes). This is a simple way
// of testing that to ensure we're not messing up and adding multiple installed packages.
for (int ii = 0; ii < 2; ii++) {
// Test --------------------------------------------
contentManager.mergeDiscoveredPackages(report);
// Verify --------------------------------------------
getTransactionManager().begin();
try {
// Simple count checks
Query installedPackageQuery = em.createNamedQuery(InstalledPackage.QUERY_FIND_BY_RESOURCE_ID);
installedPackageQuery.setParameter("resourceId", resource1.getId());
List<InstalledPackage> installedPackages = installedPackageQuery.getResultList();
assert installedPackages.size() == 5 : "Incorrect number of packages discovered. Expected 5, Found "
+ installedPackages.size();
// PackageX didn't already exist in the system, so ensure it was created and populated correctly from our
// discovered package
Query packageXQuery = em.createNamedQuery(Package.QUERY_FIND_BY_NAME_PKG_TYPE_ID);
packageXQuery.setParameter("name", "PackageX");
packageXQuery.setParameter("packageTypeId", packageType4.getId());
Package packageX = (Package) packageXQuery.getSingleResult();
assert packageX.getName().equals("PackageX") : "Package name not specified on created package";
assert packageX.getPackageType().equals(packageType4) : "Package type incorrect on created package. Expected: "
+ packageType4 + ", Found: " + packageX.getPackageType();
Query packageVersionQuery = em.createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_ID);
packageVersionQuery.setParameter("packageId", packageX.getId());
List<PackageVersion> packageVersions = packageVersionQuery.getResultList();
assert packageVersions.size() == 1 : "Incorrect number of versions for package. Expected: 1, Found: "
+ packageVersions.size();
PackageVersion packageVersionX = packageVersions.get(0);
assert packageVersionX.getArchitecture().equals(architecture1) : "Incorrect architecture on package version. Expected: "
+ architecture1 + ", Found: " + packageVersionX.getArchitecture();
assert packageVersionX.getDisplayName().equals(package4.getDisplayName()) : "Incorrect display name on package version. Expected: "
+ package4.getDisplayName() + ", Found: " + packageVersionX.getDisplayName();
assert packageVersionX.getDisplayVersion().equals(package4.getDisplayVersion()) : "Incorrect display version on package version. Expected: "
+ package4.getDisplayVersion() + ", Found: " + packageVersionX.getDisplayVersion();
// assert packageVersionX.getFileCreatedDate().equals(package4.getFileCreatedDate()) : "Incorrect file created date on package version. Expected: " + package4.getFileCreatedDate() + ", Found: " + packageVersionX.getFileCreatedDate();
assert packageVersionX.getFileName().equals(package4.getFileName()) : "Incorrect file name on package version. Expected: "
+ package4.getFileName() + ", Found: " + packageVersionX.getFileName();
assert packageVersionX.getFileSize().equals(package4.getFileSize()) : "Incorrect file size on package version. Expected: "
+ package4.getFileSize() + ", Found: " + packageVersionX.getFileSize();
assert packageVersionX.getLicenseName().equals(package4.getLicenseName()) : "Incorrect license name on package version. Expected: "
+ package4.getLicenseName() + ", Found: " + packageVersionX.getLicenseName();
assert packageVersionX.getLicenseVersion().equals(package4.getLicenseVersion()) : "Incorrect license version on package version. Expected: "
+ package4.getLicenseVersion() + ", Found: " + packageVersionX.getLicenseVersion();
assert packageVersionX.getLongDescription().equals(package4.getLongDescription()) : "Incorrect long description on package version. Expected: "
+ package4.getLongDescription() + ", Found: " + packageVersionX.getLongDescription();
assert packageVersionX.getMD5().equals(package4.getMD5()) : "Incorrect MD5 on package version. Expected: "
+ package4.getMD5() + ", Found: " + packageVersionX.getMD5();
assert Arrays.equals(packageVersionX.getMetadata(), package4.getMetadata()) : "Incorrect metadata on package version.";
assert packageVersionX.getPackageBits() == null : "Non-null package bits specified for package version: "
+ packageVersionX.getPackageBits();
assert packageVersionX.getSHA256().equals(package4.getSHA256()) : "Incorrect SHA256 for package version. Expected: "
+ package4.getSHA256() + ", Found: " + packageVersionX.getSHA256();
assert packageVersionX.getShortDescription().equals(package4.getShortDescription()) : "Incorrect short description. Expected: "
+ package4.getShortDescription() + ", Found: " + packageVersionX.getShortDescription();
assert packageVersionX.getVersion().equals(package4.getVersion()) : "Incorrect version. Expected: "
+ package4.getVersion() + ", Found: " + packageVersionX.getVersion();
Configuration extraProperties = packageVersionX.getExtraProperties();
assert extraProperties != null : "Package version extra properties not persisted.";
assert extraProperties.getSimple("property2") != null : "Properties inside of extra properties were missing";
assert extraProperties.getSimple("property2").getStringValue().equals("value2") : "Incorrect value of property2";
// Load the installed package for the above package to check for the rest of the properties
Query packageXInstalledPackageQuery = em
.createNamedQuery(InstalledPackage.QUERY_FIND_BY_RESOURCE_ID_AND_PKG_VER_ID);
packageXInstalledPackageQuery.setParameter("resourceId", resource1.getId());
packageXInstalledPackageQuery.setParameter("packageVersionId", packageVersionX.getId());
InstalledPackage packageXInstalledPackage = (InstalledPackage) packageXInstalledPackageQuery
.getSingleResult();
assert packageXInstalledPackage != null;
} finally {
getTransactionManager().rollback();
}
}
}
@Test(enabled = ENABLE_TESTS)
public void testSuccessfulDeployPackages() throws Exception {
// Setup --------------------------------------------
Subject overlord = subjectManager.getOverlord();
Set<ResourcePackageDetails> installUs = new HashSet<ResourcePackageDetails>(2);
// Package 1, Version 2 with configuration values
PackageVersion packageVersion1 = package1.getVersions().get(0);
Configuration deploymentConfiguration1 = new Configuration();
deploymentConfiguration1.put(new PropertySimple("property1", "value1"));
PackageDetailsKey key1 = new PackageDetailsKey(package1.getName(), packageVersion1.getVersion(), package1
.getPackageType().getName(), packageVersion1.getArchitecture().getName());
ResourcePackageDetails packageDetails1 = new ResourcePackageDetails(key1);
packageDetails1.setDeploymentTimeConfiguration(deploymentConfiguration1);
installUs.add(packageDetails1);
// Package 2, Version 1 (intentionally older version) with no configuration values
PackageVersion packageVersion2 = package2.getVersions().get(0);
PackageDetailsKey key2 = new PackageDetailsKey(package2.getName(), packageVersion2.getVersion(), package2
.getPackageType().getName(), packageVersion2.getArchitecture().getName());
ResourcePackageDetails packageDetails2 = new ResourcePackageDetails(key2);
installUs.add(packageDetails2);
// Make sure the mock is configured to return a success
this.contentAgentService.setResponseReturnStatus(ContentResponseResult.SUCCESS);
this.contentAgentService.setThrowError(false);
this.contentAgentService.setReturnIndividualResponses(true);
String notes = "Test package deployment";
// Test --------------------------------------------
// Perform the deploy while locking the agent service. This allows us to check the state after the request
// is sent to the agent but before the agent has replied.
synchronized (responseLock) {
contentManager.deployPackages(overlord, resource1.getId(), installUs, notes);
// Check to see if the request and installed package were created and have the right status
getTransactionManager().begin();
try {
// Content request
Query query = em.createNamedQuery(ContentServiceRequest.QUERY_FIND_BY_RESOURCE);
query.setParameter("resourceId", resource1.getId());
List<?> results = query.getResultList();
assert results.size() == 1 : "Incorrect number of content service requests. Expected: 1, Found: "
+ results.size();
ContentServiceRequest request = (ContentServiceRequest) results.get(0);
assert request.getContentRequestType() == ContentRequestType.DEPLOY : "Request type incorrect. Expected: DEPLOY, Found: "
+ request.getContentRequestType();
assert request.getStatus() == ContentRequestStatus.IN_PROGRESS : "Request status incorrect. Expected: IN_PROGRESS, Found: "
+ request.getStatus();
assert request.getInstalledPackageHistory().size() == 2 : "Incorrect number of installed packages attached to request. Expected: 2, Found: "
+ request.getInstalledPackageHistory().size();
assert request.getNotes() != null : "Null notes found";
assert request.getNotes().equals(notes) : "Incorrect notes found: " + request.getNotes();
// Verify a history entry has been added for each package in the request
Set<InstalledPackageHistory> history = request.getInstalledPackageHistory();
assert history.size() == 2 : "Incorrect number of history entries on request. Expected: 2, Found: "
+ history.size();
for (InstalledPackageHistory historyEntry : history) {
assert historyEntry.getStatus() == InstalledPackageHistoryStatus.BEING_INSTALLED : "Incorrect state on history entity. Expected: BEING_INSTALLED, Found: "
+ historyEntry.getStatus();
}
// Ensure the installed package has not been added to the resource yet
// Package 1, Version 2
query = em.createNamedQuery(InstalledPackage.QUERY_FIND_BY_RESOURCE_ID_AND_PKG_VER_ID);
query.setParameter("resourceId", resource1.getId());
query.setParameter("packageVersionId", packageVersion1.getId());
results = query.getResultList();
assert results.size() == 0 : "Incorrect number of installed packages for package 1, version 2. Expected: 0, Found: "
+ results.size();
// Check status of audit trail
query = em.createNamedQuery(InstalledPackageHistory.QUERY_FIND_BY_CSR_ID_AND_PKG_VER_ID);
query.setParameter("contentServiceRequestId", request.getId());
query.setParameter("packageVersionId", packageVersion1.getId());
results = query.getResultList();
assert results.size() == 1 : "Incorrect number of audit trail entries. Expected: 1, Found: "
+ results.size();
InstalledPackageHistory historyEntity = (InstalledPackageHistory) results.get(0);
assert historyEntity.getStatus() == InstalledPackageHistoryStatus.BEING_INSTALLED : "Incorrect status on first entity. Expected: BEING_INSTALLED, Found: "
+ historyEntity.getStatus();
// Package 2, Version 1
query = em.createNamedQuery(InstalledPackage.QUERY_FIND_BY_RESOURCE_ID_AND_PKG_VER_ID);
query.setParameter("resourceId", resource1.getId());
query.setParameter("packageVersionId", packageVersion2.getId());
results = query.getResultList();
assert results.size() == 0 : "Incorrect number of installed packages for package 2, version 1. Expected: 0, Found: "
+ results.size();
// Check status of audit trail
query = em.createNamedQuery(InstalledPackageHistory.QUERY_FIND_BY_CSR_ID_AND_PKG_VER_ID);
query.setParameter("contentServiceRequestId", request.getId());
query.setParameter("packageVersionId", packageVersion2.getId());
results = query.getResultList();
assert results.size() == 1 : "Incorrect number of audit trail entries. Expected: 1, Found: "
+ results.size();
historyEntity = (InstalledPackageHistory) results.get(0);
assert historyEntity.getStatus() == InstalledPackageHistoryStatus.BEING_INSTALLED : "Incorrect status on second entity. Expected: BEING_INSTALLED, Found: "
+ historyEntity.getStatus();
} finally {
responseLock.notifyAll();
getTransactionManager().rollback();
}
}
// Verify --------------------------------------------
// Give the agent service a second to make sure it finishes out its call
Thread.sleep(1000);
getTransactionManager().begin();
try {
// Content request
Query query = em.createNamedQuery(ContentServiceRequest.QUERY_FIND_BY_RESOURCE);
query.setParameter("resourceId", resource1.getId());
List<?> results = query.getResultList();
assert results.size() == 1 : "Incorrect number of content service requests. Expected: 1, Found: "
+ results.size();
ContentServiceRequest request = (ContentServiceRequest) results.get(0);
assert request.getStatus() == ContentRequestStatus.SUCCESS : "Request status incorrect. Expected: SUCCESS, Found: "
+ request.getStatus();
// Verify a history entry has been added for the completion of the request per package
Set<InstalledPackageHistory> history = request.getInstalledPackageHistory();
assert history.size() == 4 : "Incorrect number of history entries on request. Expected: 4, Found: "
+ history.size();
// Check for Package 1
query = em.createNamedQuery(InstalledPackageHistory.QUERY_FIND_BY_CSR_ID_AND_PKG_VER_ID);
query.setParameter("contentServiceRequestId", request.getId());
query.setParameter("packageVersionId", packageVersion1.getId());
results = query.getResultList();
assert results.size() == 2 : "Incorrect number of history entries. Expected: 2, Found: " + results.size();
InstalledPackageHistory historyEntity = (InstalledPackageHistory) results.get(0);
assert historyEntity.getStatus() == InstalledPackageHistoryStatus.INSTALLED : "Incorrect status on first entity. Expected: INSTALLED, Found: "
+ historyEntity.getStatus();
historyEntity = (InstalledPackageHistory) results.get(1);
assert historyEntity.getStatus() == InstalledPackageHistoryStatus.BEING_INSTALLED : "Incorrect status on first entity. Expected: BEING_INSTALLED, Found: "
+ historyEntity.getStatus();
// Check for Package 2
query = em.createNamedQuery(InstalledPackageHistory.QUERY_FIND_BY_CSR_ID_AND_PKG_VER_ID);
query.setParameter("contentServiceRequestId", request.getId());
query.setParameter("packageVersionId", packageVersion2.getId());
results = query.getResultList();
assert results.size() == 2 : "Incorrect number of history entries. Expected: 2, Found: " + results.size();
historyEntity = (InstalledPackageHistory) results.get(0);
assert historyEntity.getStatus() == InstalledPackageHistoryStatus.INSTALLED : "Incorrect status on first entity. Expected: INSTALLED, Found: "
+ historyEntity.getStatus();
historyEntity = (InstalledPackageHistory) results.get(1);
assert historyEntity.getStatus() == InstalledPackageHistoryStatus.BEING_INSTALLED : "Incorrect status on first entity. Expected: BEING_INSTALLED, Found: "
+ historyEntity.getStatus();
// Add a few tests for the new Criteria Search feature
PackageVersionCriteria criteria = new PackageVersionCriteria();
criteria.addFilterResourceId(resource1.getId());
PageList<PackageVersion> pageList = contentManager.findPackageVersionsByCriteria(overlord, criteria);
assertNotNull(pageList);
ArrayList<PackageVersion> pvs = pageList.getValues();
assertEquals(2, pvs.size());
PackageVersion pv0 = pvs.get(0);
criteria.addFilterPackageTypeId(pv0.getGeneralPackage().getPackageType().getId());
pageList = contentManager.findPackageVersionsByCriteria(overlord, criteria);
assertNotNull(pageList);
pvs = pageList.getValues();
assertEquals(1, pvs.size());
assertEquals(pv0.getId(), pvs.get(0).getId());
// there is no repo assignment, any valid ID should eliminate all PVs
criteria.addFilterRepoId(38465);
pageList = contentManager.findPackageVersionsByCriteria(overlord, criteria);
assertNotNull(pageList);
pvs = pageList.getValues();
assertEquals(0, pvs.size());
} finally {
getTransactionManager().rollback();
}
}
@Test(enabled = ENABLE_TESTS)
public void testDeployWithSteps() throws Exception {
// Setup --------------------------------------------
Subject overlord = subjectManager.getOverlord();
Set<ResourcePackageDetails> installUs = new HashSet<ResourcePackageDetails>(2);
// Package 1, Version 2 with configuration values
PackageVersion packageVersion1 = package1.getVersions().get(0);
Configuration deploymentConfiguration1 = new Configuration();
deploymentConfiguration1.put(new PropertySimple("property1", "value1"));
PackageDetailsKey key1 = new PackageDetailsKey(package1.getName(), packageVersion1.getVersion(), package1
.getPackageType().getName(), packageVersion1.getArchitecture().getName());
ResourcePackageDetails packageDetails1 = new ResourcePackageDetails(key1);
packageDetails1.setDeploymentTimeConfiguration(deploymentConfiguration1);
installUs.add(packageDetails1);
// Make sure the mock is configured to return a success
this.contentAgentService.setResponseReturnStatus(ContentResponseResult.SUCCESS);
this.contentAgentService.setThrowError(false);
this.contentAgentService.setReturnIndividualResponses(true);
this.contentAgentService.setDeployPackageSteps(stepResults);
String notes = "Test deploy notes";
// Test --------------------------------------------
// Perform the deploy while locking the agent service. This allows us to check the state after the request
// is sent to the agent but before the agent has replied.
synchronized (responseLock) {
contentManager.deployPackages(overlord, resource1.getId(), installUs, notes);
// Check to see if the request and installed package were created and have the right status
getTransactionManager().begin();
try {
// Content request
Query query = em.createNamedQuery(ContentServiceRequest.QUERY_FIND_BY_RESOURCE);
query.setParameter("resourceId", resource1.getId());
List<?> results = query.getResultList();
assert results.size() == 1 : "Incorrect number of content service requests. Expected: 1, Found: "
+ results.size();
ContentServiceRequest request = (ContentServiceRequest) results.get(0);
assert request.getContentRequestType() == ContentRequestType.DEPLOY : "Request type incorrect. Expected: DEPLOY, Found: "
+ request.getContentRequestType();
assert request.getStatus() == ContentRequestStatus.IN_PROGRESS : "Request status incorrect. Expected: IN_PROGRESS, Found: "
+ request.getStatus();
assert request.getInstalledPackageHistory().size() == 1 : "Incorrect number of installed packages attached to request. Expected: 1, Found: "
+ request.getInstalledPackageHistory().size();
assert request.getNotes() != null : "Null notes found";
assert request.getNotes().equals(notes) : "Incorrect notes found: " + request.getNotes();
// Verify a history entry has been added for each package in the request
Set<InstalledPackageHistory> history = request.getInstalledPackageHistory();
assert history.size() == 1 : "Incorrect number of history entries on request. Expected: 2, Found: "
+ history.size();
for (InstalledPackageHistory historyEntry : history) {
assert historyEntry.getStatus() == InstalledPackageHistoryStatus.BEING_INSTALLED : "Incorrect state on history entity. Expected: BEING_INSTALLED, Found: "
+ historyEntry.getStatus();
}
} finally {
responseLock.notifyAll();
getTransactionManager().rollback();
}
}
// Verify --------------------------------------------
// Give the agent service a second to make sure it finishes out its call
Thread.sleep(1000);
getTransactionManager().begin();
try {
// Content request
Query query = em.createNamedQuery(ContentServiceRequest.QUERY_FIND_BY_RESOURCE);
query.setParameter("resourceId", resource1.getId());
List<?> results = query.getResultList();
assert results.size() == 1 : "Incorrect number of content service requests. Expected: 1, Found: "
+ results.size();
ContentServiceRequest request = (ContentServiceRequest) results.get(0);
assert request.getStatus() == ContentRequestStatus.SUCCESS : "Request status incorrect. Expected: SUCCESS, Found: "
+ request.getStatus();
// Verify a history entry has been added for the completion of the request per package
Set<InstalledPackageHistory> history = request.getInstalledPackageHistory();
assert history.size() == 2 : "Incorrect number of history entries on request. Expected: 2, Found: "
+ history.size();
// Check for Package 1
query = em.createNamedQuery(InstalledPackageHistory.QUERY_FIND_BY_CSR_ID_AND_PKG_VER_ID);
query.setParameter("contentServiceRequestId", request.getId());
query.setParameter("packageVersionId", packageVersion1.getId());
results = query.getResultList();
assert results.size() == 2 : "Incorrect number of history entries. Expected: 2, Found: " + results.size();
InstalledPackageHistory historyEntity = (InstalledPackageHistory) results.get(0);
assert historyEntity.getStatus() == InstalledPackageHistoryStatus.INSTALLED : "Incorrect status on first entity. Expected: INSTALLED, Found: "
+ historyEntity.getStatus();
// The installed entry should contain the steps that were done in the installation
List<PackageInstallationStep> installationSteps = historyEntity.getInstallationSteps();
assert installationSteps != null : "Installation steps were null";
assert installationSteps.size() == 3 : "Incorrect number of installation steps. Expected: 3, Found: "
+ installationSteps.size();
PackageInstallationStep step = installationSteps.get(0);
assert step.getOrder() == 0 : "Incorrect order applied for step";
assert step.getDescription() != null : "Description not saved";
assert step.getResult() == ContentResponseResult.SUCCESS : "Incorrect status on step. Expected: SUCCESS, Found: "
+ step.getResult();
assert step.getErrorMessage() == null : "Error message found on successful step";
assert step.getInstalledPackageHistory() != null : "Relationship to packge history isn't established";
step = installationSteps.get(1);
assert step.getOrder() == 1 : "Incorrect order applied for step";
assert step.getDescription() != null : "Description not saved";
assert step.getResult() == ContentResponseResult.NOT_PERFORMED : "Incorrect status on step. Expected: NOT_PERFORMED, Found: "
+ step.getResult();
assert step.getErrorMessage() == null : "Error message found on skipped step";
assert step.getInstalledPackageHistory() != null : "Relationship to packge history isn't established";
step = installationSteps.get(2);
assert step.getOrder() == 2 : "Incorrect order applied for step";
assert step.getDescription() != null : "Description not saved";
assert step.getResult() == ContentResponseResult.FAILURE : "Incorrect status on step. Expected: FAILURE, Found: "
+ step.getResult();
assert step.getErrorMessage() != null : "Null error message found on error step";
assert step.getInstalledPackageHistory() != null : "Relationship to packge history isn't established";
historyEntity = (InstalledPackageHistory) results.get(1);
assert historyEntity.getStatus() == InstalledPackageHistoryStatus.BEING_INSTALLED : "Incorrect status on first entity. Expected: BEING_INSTALLED, Found: "
+ historyEntity.getStatus();
} finally {
getTransactionManager().rollback();
}
}
@Test(enabled = ENABLE_TESTS)
public void testFailedDeployPackages() throws Exception {
// Setup --------------------------------------------
Subject overlord = subjectManager.getOverlord();
Set<ResourcePackageDetails> installUs = new HashSet<ResourcePackageDetails>(1);
// Package 1, Version 2 with configuration values
Configuration deploymentConfiguration1 = new Configuration();
deploymentConfiguration1.put(new PropertySimple("property1", "value1"));
PackageVersion packageVersion1 = package1.getVersions().get(1);
PackageDetailsKey key1 = new PackageDetailsKey(package1.getName(), packageVersion1.getVersion(), package1
.getPackageType().getName(), packageVersion1.getArchitecture().getName());
ResourcePackageDetails packageDetails1 = new ResourcePackageDetails(key1);
packageDetails1.setDeploymentTimeConfiguration(deploymentConfiguration1);
installUs.add(packageDetails1);
// Make sure the mock is configured to return a failure
this.contentAgentService.setResponseReturnStatus(ContentResponseResult.FAILURE);
this.contentAgentService.setThrowError(false);
this.contentAgentService.setReturnIndividualResponses(true);
String notes = "Test deploy notes";
// Test --------------------------------------------
contentManager.deployPackages(overlord, resource1.getId(), installUs, notes);
// Verify --------------------------------------------
// Give the agent service a second to make sure it finishes out its call
Thread.sleep(1000);
getTransactionManager().begin();
try {
// Content request
Query query = em.createNamedQuery(ContentServiceRequest.QUERY_FIND_BY_RESOURCE);
query.setParameter("resourceId", resource1.getId());
List<?> results = query.getResultList();
assert results.size() == 1 : "Incorrect number of content service requests. Expected: 1, Found: "
+ results.size();
ContentServiceRequest request = (ContentServiceRequest) results.get(0);
assert request.getStatus() == ContentRequestStatus.FAILURE : "Request status incorrect. Expected: IN_PROGRESS, Found: "
+ request.getStatus();
assert request.getNotes() != null : "Null notes found";
assert request.getNotes().equals(notes) : "Incorrect notes found: " + request.getNotes();
// Check for Package 1
query = em.createNamedQuery(InstalledPackageHistory.QUERY_FIND_BY_CSR_ID_AND_PKG_VER_ID);
query.setParameter("contentServiceRequestId", request.getId());
query.setParameter("packageVersionId", packageVersion1.getId());
results = query.getResultList();
assert results.size() == 2 : "Incorrect number of history entries. Expected: 2, Found: " + results.size();
InstalledPackageHistory historyEntity = (InstalledPackageHistory) results.get(0);
assert historyEntity.getStatus() == InstalledPackageHistoryStatus.FAILED : "Incorrect status on first entity. Expected: FAILED, Found: "
+ historyEntity.getStatus();
historyEntity = (InstalledPackageHistory) results.get(1);
assert historyEntity.getStatus() == InstalledPackageHistoryStatus.BEING_INSTALLED : "Incorrect status on first entity. Expected: BEING_INSTALLED, Found: "
+ historyEntity.getStatus();
} finally {
getTransactionManager().rollback();
}
}
@Test(enabled = ENABLE_TESTS)
public void testDeployPackageFailToContactAgent() throws Exception {
// Setup --------------------------------------------
Subject overlord = subjectManager.getOverlord();
Set<ResourcePackageDetails> installUs = new HashSet<ResourcePackageDetails>(1);
// Package 1, Version 2 with configuration values
Configuration deploymentConfiguration1 = new Configuration();
deploymentConfiguration1.put(new PropertySimple("property1", "value1"));
PackageVersion packageVersion1 = package1.getVersions().get(1);
PackageDetailsKey key1 = new PackageDetailsKey(package1.getName(), packageVersion1.getVersion(), package1
.getPackageType().getName(), packageVersion1.getArchitecture().getName());
ResourcePackageDetails packageDetails1 = new ResourcePackageDetails(key1);
packageDetails1.setDeploymentTimeConfiguration(deploymentConfiguration1);
installUs.add(packageDetails1);
// Make sure the mock is configured to return a failure
this.contentAgentService.setResponseReturnStatus(ContentResponseResult.FAILURE);
this.contentAgentService.setThrowError(true);
this.contentAgentService.setReturnIndividualResponses(false);
String notes = "Test deploy notes";
// Test --------------------------------------------
try {
contentManager.deployPackages(overlord, resource1.getId(), installUs, notes);
assert false : "No exception thrown from deploy call";
} catch (Exception e) {
// Expected
}
// Verify --------------------------------------------
getTransactionManager().begin();
try {
// Content request
Query query = em.createNamedQuery(ContentServiceRequest.QUERY_FIND_BY_RESOURCE);
query.setParameter("resourceId", resource1.getId());
List<?> results = query.getResultList();
assert results.size() == 1 : "Incorrect number of content service requests. Expected: 1, Found: "
+ results.size();
ContentServiceRequest request = (ContentServiceRequest) results.get(0);
assert request.getStatus() == ContentRequestStatus.FAILURE : "Request status incorrect. Expected: IN_PROGRESS, Found: "
+ request.getStatus();
assert request.getNotes() != null : "Null notes found";
assert request.getNotes().equals(notes) : "Incorrect notes found: " + request.getNotes();
// Check for Package 1
query = em.createNamedQuery(InstalledPackageHistory.QUERY_FIND_BY_CSR_ID_AND_PKG_VER_ID);
query.setParameter("contentServiceRequestId", request.getId());
query.setParameter("packageVersionId", packageVersion1.getId());
results = query.getResultList();
assert results.size() == 2 : "Incorrect number of history entries. Expected: 2, Found: " + results.size();
InstalledPackageHistory historyEntity = (InstalledPackageHistory) results.get(0);
assert historyEntity.getStatus() == InstalledPackageHistoryStatus.FAILED : "Incorrect status on first entity. Expected: FAILED, Found: "
+ historyEntity.getStatus();
historyEntity = (InstalledPackageHistory) results.get(1);
assert historyEntity.getStatus() == InstalledPackageHistoryStatus.BEING_INSTALLED : "Incorrect status on first entity. Expected: BEING_INSTALLED, Found: "
+ historyEntity.getStatus();
} finally {
getTransactionManager().rollback();
}
}
@Test(enabled = ENABLE_TESTS)
public void testDeployPackagesNoIndividualResponses() throws Exception {
// Setup --------------------------------------------
Subject overlord = subjectManager.getOverlord();
Set<ResourcePackageDetails> installUs = new HashSet<ResourcePackageDetails>(1);
// Package 1, Version 2 with configuration values
Configuration deploymentConfiguration1 = new Configuration();
deploymentConfiguration1.put(new PropertySimple("property1", "value1"));
PackageVersion packageVersion1 = package1.getVersions().get(1);
PackageDetailsKey key1 = new PackageDetailsKey(package1.getName(), packageVersion1.getVersion(), package1
.getPackageType().getName(), packageVersion1.getArchitecture().getName());
ResourcePackageDetails packageDetails1 = new ResourcePackageDetails(key1);
packageDetails1.setDeploymentTimeConfiguration(deploymentConfiguration1);
installUs.add(packageDetails1);
// Make sure the mock is configured to return a failure
this.contentAgentService.setResponseReturnStatus(ContentResponseResult.FAILURE);
this.contentAgentService.setThrowError(false);
this.contentAgentService.setReturnIndividualResponses(false);
String notes = "Test deploy notes";
// Test --------------------------------------------
contentManager.deployPackages(overlord, resource1.getId(), installUs, notes);
// Give the agent service a second to make sure it finishes out its call
Thread.sleep(1000);
// Verify --------------------------------------------
getTransactionManager().begin();
try {
// Content request
Query query = em.createNamedQuery(ContentServiceRequest.QUERY_FIND_BY_RESOURCE);
query.setParameter("resourceId", resource1.getId());
List<?> results = query.getResultList();
assert results.size() == 1 : "Incorrect number of content service requests. Expected: 1, Found: "
+ results.size();
ContentServiceRequest request = (ContentServiceRequest) results.get(0);
assert request.getStatus() == ContentRequestStatus.FAILURE : "Request status incorrect. Expected: FAILURE, Found: "
+ request.getStatus();
assert request.getNotes() != null : "Null notes found";
assert request.getNotes().equals(notes) : "Incorrect notes found: " + request.getNotes();
// Check for Package 1
query = em.createNamedQuery(InstalledPackageHistory.QUERY_FIND_BY_CSR_ID_AND_PKG_VER_ID);
query.setParameter("contentServiceRequestId", request.getId());
query.setParameter("packageVersionId", packageVersion1.getId());
results = query.getResultList();
assert results.size() == 2 : "Incorrect number of history entries. Expected: 2, Found: " + results.size();
InstalledPackageHistory historyEntity = (InstalledPackageHistory) results.get(0);
assert historyEntity.getStatus() == InstalledPackageHistoryStatus.FAILED : "Incorrect status on first entity. Expected: FAILED, Found: "
+ historyEntity.getStatus();
historyEntity = (InstalledPackageHistory) results.get(1);
assert historyEntity.getStatus() == InstalledPackageHistoryStatus.BEING_INSTALLED : "Incorrect status on first entity. Expected: BEING_INSTALLED, Found: "
+ historyEntity.getStatus();
} finally {
getTransactionManager().rollback();
}
}
@SuppressWarnings("unchecked")
@Test(enabled = ENABLE_TESTS)
public void testLoadDependencies() throws Exception {
// Setup --------------------------------------------
Set<PackageDetailsKey> loadUs = new HashSet<PackageDetailsKey>(3);
// Package 1, Version 2
PackageVersion packageVersion1 = package1.getVersions().get(1);
PackageDetailsKey packageKey1 = new PackageDetailsKey(package1.getName(), packageVersion1.getVersion(),
package1.getPackageType().getName(), packageVersion1.getArchitecture().getName());
loadUs.add(packageKey1);
// Package 2, Version 2
PackageVersion packageVersion2 = package2.getVersions().get(1);
PackageDetailsKey packageKey2 = new PackageDetailsKey(package2.getName(), packageVersion2.getVersion(),
package2.getPackageType().getName(), packageVersion2.getArchitecture().getName());
loadUs.add(packageKey2);
// Package that does not exist in the server
PackageDetailsKey packageKey3 = new PackageDetailsKey("foo", "1.0.0", "fooType", "fooArch");
loadUs.add(packageKey3);
// Need to create a content service request off of which to hang the dependencies as new installed package requests
getTransactionManager().begin();
ContentServiceRequest request = null;
try {
resource1 = em.find(Resource.class, resource1.getId());
Subject overlord = subjectManager.getOverlord();
PackageVersion packageVersion = em.find(PackageVersion.class, package3.getVersions().get(0).getId());
request = new ContentServiceRequest(resource1, overlord.getName(), ContentRequestType.DEPLOY);
InstalledPackageHistory originalRequestedPackage = new InstalledPackageHistory();
originalRequestedPackage.setContentServiceRequest(request);
originalRequestedPackage.setPackageVersion(packageVersion);
originalRequestedPackage.setStatus(InstalledPackageHistoryStatus.BEING_INSTALLED);
originalRequestedPackage.setTimestamp(System.currentTimeMillis());
originalRequestedPackage.setResource(resource1);
request.addInstalledPackageHistory(originalRequestedPackage);
em.persist(request);
getTransactionManager().commit();
} catch (Throwable t) {
getTransactionManager().rollback();
assert false : "Error during setup: " + t;
}
// Test --------------------------------------------
contentManager.loadDependencies(request.getId(), loadUs);
// Verify --------------------------------------------
// Verify installed packages were created for the two dependency packages
getTransactionManager().begin();
try {
// Overall package count on the request
Query query = em.createNamedQuery(ContentServiceRequest.QUERY_FIND_BY_ID);
query.setParameter("id", request.getId());
List<ContentServiceRequest> resultList = query.getResultList();
assert resultList.size() == 1 : "Incorrect number of requests loaded. Expected: 1, Found: "
+ resultList.size();
request = resultList.get(0);
assert request.getInstalledPackageHistory().size() == 3 : "Incorrect number of being installed packages on request. Expected: 3, Found: "
+ resultList.size();
// Quick check for the status of each
query = em.createNamedQuery(InstalledPackageHistory.QUERY_FIND_BY_CSR_ID);
query.setParameter("contentServiceRequestId", request.getId());
List<InstalledPackageHistory> historyEntries = query.getResultList();
for (InstalledPackageHistory historyEntry : historyEntries) {
assert historyEntry.getContentServiceRequest().equals(request) : "ContentServiceRequest relationship not set up correctly for package history";
assert historyEntry.getStatus() == InstalledPackageHistoryStatus.BEING_INSTALLED : "Incorrect status on installed package history. Expected: BEING_INSTALLED, Found: "
+ historyEntry.getStatus();
}
} finally {
getTransactionManager().rollback();
}
}
@Test(enabled = ENABLE_TESTS)
public void testSuccessfullyDeletePackages() throws Exception {
// Setup --------------------------------------------
Subject overlord = subjectManager.getOverlord();
// Delete installed package for package4
int[] deleteUs = new int[] { installedPackage1.getId() };
// Leave package5 installed
// Make sure the mock is configured to return a success
this.contentAgentService.setResponseReturnStatus(ContentResponseResult.SUCCESS);
this.contentAgentService.setThrowError(false);
this.contentAgentService.setReturnIndividualResponses(true);
String notes = "Test delete notes";
// Test --------------------------------------------
// Perform the deploy while locking the agent service. This allows us to check the state after the request
// is sent to the agent but before the agent has replied.
synchronized (responseLock) {
contentManager.deletePackages(overlord, resource1.getId(), deleteUs, notes);
getTransactionManager().begin();
try {
// Content request
Query query = em.createNamedQuery(ContentServiceRequest.QUERY_FIND_BY_RESOURCE);
query.setParameter("resourceId", resource1.getId());
List<?> results = query.getResultList();
assert results.size() == 1 : "Incorrect number of content service requests. Expected: 1, Found: "
+ results.size();
ContentServiceRequest request = (ContentServiceRequest) results.get(0);
assert request.getStatus() == ContentRequestStatus.IN_PROGRESS : "Request status incorrect. Expected: IN_PROGRESS, Found: "
+ request.getStatus();
assert request.getNotes() != null : "Null notes found";
assert request.getNotes().equals(notes) : "Incorrect notes found: " + request.getNotes();
// Verify a history entry has been added for each package in the request
Set<InstalledPackageHistory> history = request.getInstalledPackageHistory();
assert history.size() == 1 : "Incorrect number of history entries on request. Expected: 1, Found: "
+ history.size();
for (InstalledPackageHistory historyEntry : history) {
assert historyEntry.getStatus() == InstalledPackageHistoryStatus.BEING_DELETED : "Incorrect state on history entity. Expected: BEING_DELETED, Found: "
+ historyEntry.getStatus();
}
} finally {
getTransactionManager().rollback();
}
}
// Verify --------------------------------------------
// Give the agent service a second to make sure it finishes out its call
Thread.sleep(1000);
getTransactionManager().begin();
try {
// Content request
Query query = em.createNamedQuery(ContentServiceRequest.QUERY_FIND_BY_RESOURCE);
query.setParameter("resourceId", resource1.getId());
List<?> results = query.getResultList();
assert results.size() == 1 : "Incorrect number of content service requests. Expected: 1, Found: "
+ results.size();
ContentServiceRequest request = (ContentServiceRequest) results.get(0);
assert request.getStatus() == ContentRequestStatus.SUCCESS : "Request status incorrect. Expected: SUCCESS, Found: "
+ request.getStatus();
// Verify history entries
query = em.createNamedQuery(InstalledPackageHistory.QUERY_FIND_BY_CSR_ID_AND_PKG_VER_ID);
query.setParameter("contentServiceRequestId", request.getId());
query.setParameter("packageVersionId", installedPackage1.getPackageVersion().getId());
results = query.getResultList();
assert results.size() == 2 : "Incorrect number of history entries. Expected: 2, Found: " + results.size();
InstalledPackageHistory historyEntity = (InstalledPackageHistory) results.get(0);
assert historyEntity.getStatus() == InstalledPackageHistoryStatus.DELETED : "Incorrect status on first entity. Expected: DELETED, Found: "
+ historyEntity.getStatus();
historyEntity = (InstalledPackageHistory) results.get(1);
assert historyEntity.getStatus() == InstalledPackageHistoryStatus.BEING_DELETED : "Incorrect status on first entity. Expected: BEING_DELETED, Found: "
+ historyEntity.getStatus();
// Package 4, Version 2
query = em.createNamedQuery(InstalledPackage.QUERY_FIND_BY_RESOURCE_ID_AND_PKG_VER_ID);
query.setParameter("resourceId", resource1.getId());
query.setParameter("packageVersionId", installedPackage1.getPackageVersion().getId());
results = query.getResultList();
assert results.size() == 1 : "Incorrect number of installed packages for package 1, version 2. Expected: 0, Found: "
+ results.size();
// Package 2, Version 1
query = em.createNamedQuery(InstalledPackage.QUERY_FIND_BY_RESOURCE_ID_AND_PKG_VER_ID);
query.setParameter("resourceId", resource1.getId());
query.setParameter("packageVersionId", package5.getVersions().get(0).getId());
results = query.getResultList();
assert results.size() == 1 : "Incorrect number of installed packages for package 2, version 1. Expected: 1, Found: "
+ results.size();
} finally {
getTransactionManager().rollback();
}
}
@Test(enabled = ENABLE_TESTS)
public void testDeletePackagesNoIndividualResponses() throws Exception {
// Setup --------------------------------------------
Subject overlord = subjectManager.getOverlord();
// Delete installed package for package4
int[] deleteUs = new int[] { installedPackage1.getId() };
// Leave package5 installed
// Make sure the mock is configured to return a success
this.contentAgentService.setResponseReturnStatus(ContentResponseResult.FAILURE);
this.contentAgentService.setThrowError(false);
this.contentAgentService.setReturnIndividualResponses(false);
String notes = "Test delete notes";
// Test --------------------------------------------
// Perform the deploy while locking the agent service. This allows us to check the state after the request
// is sent to the agent but before the agent has replied.
synchronized (responseLock) {
contentManager.deletePackages(overlord, resource1.getId(), deleteUs, notes);
getTransactionManager().begin();
try {
// Content request
Query query = em.createNamedQuery(ContentServiceRequest.QUERY_FIND_BY_RESOURCE);
query.setParameter("resourceId", resource1.getId());
List<?> results = query.getResultList();
assert results.size() == 1 : "Incorrect number of content service requests. Expected: 1, Found: "
+ results.size();
ContentServiceRequest request = (ContentServiceRequest) results.get(0);
assert request.getStatus() == ContentRequestStatus.IN_PROGRESS : "Request status incorrect. Expected: IN_PROGRESS, Found: "
+ request.getStatus();
assert request.getNotes() != null : "Null notes found";
assert request.getNotes().equals(notes) : "Incorrect notes found: " + request.getNotes();
// Verify a history entry has been added for each package in the request
Set<InstalledPackageHistory> history = request.getInstalledPackageHistory();
assert history.size() == 1 : "Incorrect number of history entries on request. Expected: 1, Found: "
+ history.size();
for (InstalledPackageHistory historyEntry : history) {
assert historyEntry.getStatus() == InstalledPackageHistoryStatus.BEING_DELETED : "Incorrect state on history entity. Expected: BEING_DELETED, Found: "
+ historyEntry.getStatus();
}
} finally {
getTransactionManager().rollback();
}
}
// Verify --------------------------------------------
// Give the agent service a second to make sure it finishes out its call
Thread.sleep(1000);
getTransactionManager().begin();
try {
// Content request
Query query = em.createNamedQuery(ContentServiceRequest.QUERY_FIND_BY_RESOURCE);
query.setParameter("resourceId", resource1.getId());
List<?> results = query.getResultList();
assert results.size() == 1 : "Incorrect number of content service requests. Expected: 1, Found: "
+ results.size();
ContentServiceRequest request = (ContentServiceRequest) results.get(0);
assert request.getStatus() == ContentRequestStatus.FAILURE : "Request status incorrect. Expected: FAILURE, Found: "
+ request.getStatus();
// Verify history entries
query = em.createNamedQuery(InstalledPackageHistory.QUERY_FIND_BY_CSR_ID_AND_PKG_VER_ID);
query.setParameter("contentServiceRequestId", request.getId());
query.setParameter("packageVersionId", installedPackage1.getPackageVersion().getId());
results = query.getResultList();
assert results.size() == 2 : "Incorrect number of history entries. Expected: 2, Found: " + results.size();
InstalledPackageHistory historyEntity = (InstalledPackageHistory) results.get(0);
assert historyEntity.getStatus() == InstalledPackageHistoryStatus.FAILED : "Incorrect status on first entity. Expected: FAILED, Found: "
+ historyEntity.getStatus();
historyEntity = (InstalledPackageHistory) results.get(1);
assert historyEntity.getStatus() == InstalledPackageHistoryStatus.BEING_DELETED : "Incorrect status on first entity. Expected: BEING_DELETED, Found: "
+ historyEntity.getStatus();
// Package 4, Version 2
query = em.createNamedQuery(InstalledPackage.QUERY_FIND_BY_RESOURCE_ID_AND_PKG_VER_ID);
query.setParameter("resourceId", resource1.getId());
query.setParameter("packageVersionId", installedPackage1.getPackageVersion().getId());
results = query.getResultList();
assert results.size() == 1 : "Incorrect number of installed packages for package 1, version 2. Expected: 0, Found: "
+ results.size();
// Package 2, Version 1
query = em.createNamedQuery(InstalledPackage.QUERY_FIND_BY_RESOURCE_ID_AND_PKG_VER_ID);
query.setParameter("resourceId", resource1.getId());
query.setParameter("packageVersionId", package5.getVersions().get(0).getId());
results = query.getResultList();
assert results.size() == 1 : "Incorrect number of installed packages for package 2, version 1. Expected: 1, Found: "
+ results.size();
} finally {
getTransactionManager().rollback();
}
}
@Test(enabled = ENABLE_TESTS)
public void testInventoryMergePerf() throws Exception {
// remove existing packages
InstalledPackageCriteria criteria = new InstalledPackageCriteria();
criteria.addFilterResourceId(resource1.getId());
criteria.clearPaging();
List<InstalledPackage> installedPackages = contentManager.findInstalledPackagesByCriteria(
subjectManager.getOverlord(), criteria);
if (!installedPackages.isEmpty()) {
int[] ids = new int[installedPackages.size()];
int i = 0;
for (InstalledPackage ip : installedPackages) {
ids[i++] = ip.getId();
}
// send empty report to remove the existing IPs
ContentDiscoveryReport report = new ContentDiscoveryReport();
report.setResourceId(resource1.getId());
contentManager.mergeDiscoveredPackages(report);
installedPackages = contentManager.findInstalledPackagesByCriteria(subjectManager.getOverlord(), criteria);
assert (installedPackages.isEmpty());
}
// Report a bunch of discovered packages
int numPackages = 500;
ContentDiscoveryReport report = new ContentDiscoveryReport();
report.setResourceId(resource1.getId());
for (Integer i = 0; i < numPackages; ++i) {
PackageDetailsKey key = new PackageDetailsKey(this.getClass().getSimpleName() + "-" + i, i.toString(),
package1.getPackageType().getName(), architecture1.getName());
ResourcePackageDetails pd = new ResourcePackageDetails(key);
report.addDeployedPackage(pd);
}
long start = System.currentTimeMillis();
contentManager.mergeDiscoveredPackages(report);
System.out.println("PERF: testInventoryMergePerf merge-1=" + (System.currentTimeMillis() - start) + "ms");
installedPackages = contentManager.findInstalledPackagesByCriteria(subjectManager.getOverlord(), criteria);
assertEquals(numPackages, installedPackages.size());
// Remove the first 100 and add 200 more
int startPackage = 100;
int endPackage = numPackages + 200;
report = new ContentDiscoveryReport();
report.setResourceId(resource1.getId());
for (Integer i = startPackage; i < endPackage; ++i) {
PackageDetailsKey key = new PackageDetailsKey(this.getClass().getSimpleName() + "-" + i, i.toString(),
package1.getPackageType().getName(), architecture1.getName());
ResourcePackageDetails pd = new ResourcePackageDetails(key);
report.addDeployedPackage(pd);
}
start = System.currentTimeMillis();
contentManager.mergeDiscoveredPackages(report);
System.out.println("PERF: testInventoryMergePerf merge-2=" + (System.currentTimeMillis() - start) + "ms");
installedPackages = contentManager.findInstalledPackagesByCriteria(subjectManager.getOverlord(), criteria);
assertEquals(numPackages + 100, installedPackages.size());
}
// Private --------------------------------------------
private void setupTestEnvironment() throws Exception {
TestServerCommunicationsService agentServiceContainer = prepareForTestAgents();
agentServiceContainer.contentService = contentAgentService;
getTransactionManager().begin();
try {
architecture1 = em.find(Architecture.class, 1);
architecture2 = em.find(Architecture.class, 2);
resourceType1 = new ResourceType("resourcetype-" + System.currentTimeMillis(), "TestPlugin",
ResourceCategory.PLATFORM, null);
em.persist(resourceType1);
// Add package types to resource type
packageType1 = new PackageType();
packageType1.setName("package1-" + System.currentTimeMillis());
packageType1.setDescription("");
packageType1.setCategory(PackageCategory.DEPLOYABLE);
packageType1.setDisplayName("TestResourcePackage");
packageType1.setCreationData(true);
packageType1.setResourceType(resourceType1);
em.persist(packageType1);
packageType2 = new PackageType();
packageType2.setName("package2-" + System.currentTimeMillis());
packageType2.setDescription("");
packageType2.setCategory(PackageCategory.DEPLOYABLE);
packageType2.setDisplayName("TestResourcePackage2");
packageType2.setCreationData(true);
packageType2.setResourceType(resourceType1);
em.persist(packageType2);
packageType3 = new PackageType();
packageType3.setName("package3-" + System.currentTimeMillis());
packageType3.setDescription("");
packageType3.setCategory(PackageCategory.DEPLOYABLE);
packageType3.setDisplayName("TestResourcePackage3");
packageType3.setCreationData(true);
packageType3.setResourceType(resourceType1);
em.persist(packageType3);
packageType4 = new PackageType();
packageType4.setName("package4-" + System.currentTimeMillis());
packageType4.setDescription("");
packageType4.setCategory(PackageCategory.DEPLOYABLE);
packageType4.setDisplayName("TestResourcePackage4");
packageType4.setCreationData(true);
packageType4.setResourceType(resourceType1);
em.persist(packageType4);
resourceType1.addPackageType(packageType1);
resourceType1.addPackageType(packageType2);
resourceType1.addPackageType(packageType3);
// Package 1 - Contains 2 versions
package1 = new Package("Package1", packageType1);
package1.addVersion(new PackageVersion(package1, "1.0.0", architecture1));
package1.addVersion(new PackageVersion(package1, "2.0.0", architecture1));
em.persist(package1);
// Package 2 - Contains 2 versions
package2 = new Package("Package2", packageType2);
package2.addVersion(new PackageVersion(package2, "1.0.0", architecture1));
package2.addVersion(new PackageVersion(package2, "2.0.0", architecture1));
em.persist(package2);
// Package 3 - Contains 1 version
package3 = new Package("Package3", packageType3);
package3.addVersion(new PackageVersion(package3, "1.0.0", architecture1));
em.persist(package3);
// Package 4 - Contains 2 versions, the first is installed
package4 = new Package("Package4", packageType4);
PackageVersion package4Installed = new PackageVersion(package4, "1.0.0", architecture1);
package4.addVersion(package4Installed);
package4.addVersion(new PackageVersion(package4, "2.0.0", architecture1));
em.persist(package4);
// Package 5 - Contains 1 version, it is installed
package5 = new Package("Package5", packageType3);
PackageVersion package5Installed = new PackageVersion(package5, "1.0.0", architecture1);
package5.addVersion(package5Installed);
em.persist(package5);
// Create resource against which we'll merge the discovery report
resource1 = new Resource("parent" + System.currentTimeMillis(), "name", resourceType1);
resource1.setUuid("" + new Random().nextInt());
resource1.setInventoryStatus(InventoryStatus.COMMITTED);
em.persist(resource1);
// Install packages on the resource
installedPackage1 = new InstalledPackage();
installedPackage1.setResource(resource1);
installedPackage1.setPackageVersion(package4Installed);
resource1.addInstalledPackage(installedPackage1);
installedPackage2 = new InstalledPackage();
installedPackage2.setResource(resource1);
installedPackage2.setPackageVersion(package5Installed);
resource1.addInstalledPackage(installedPackage2);
installedPackage1.setResource(resource1);
installedPackage2.setResource(resource1);
getTransactionManager().commit();
} catch (Exception e) {
e.printStackTrace();
getTransactionManager().rollback();
throw e;
}
}
private void tearDownTestEnvironment() throws Exception {
getTransactionManager().begin();
try {
try {
resource1 = em.find(Resource.class, resource1.getId());
for (InstalledPackage ip : resource1.getInstalledPackages()) {
em.remove(ip);
}
for (InstalledPackageHistory history : resource1.getInstalledPackageHistory()) {
em.remove(history);
}
for (ContentServiceRequest request : resource1.getContentServiceRequests()) {
em.remove(request);
}
package1 = em.find(Package.class, package1.getId());
em.remove(package1);
package2 = em.find(Package.class, package2.getId());
em.remove(package2);
package3 = em.find(Package.class, package3.getId());
em.remove(package3);
package4 = em.find(Package.class, package4.getId());
em.remove(package4);
package5 = em.find(Package.class, package5.getId());
em.remove(package5);
packageType1 = em.find(PackageType.class, packageType1.getId());
em.remove(packageType1);
packageType2 = em.find(PackageType.class, packageType2.getId());
em.remove(packageType2);
packageType3 = em.find(PackageType.class, packageType3.getId());
em.remove(packageType3);
packageType4 = em.find(PackageType.class, packageType4.getId());
em.remove(packageType4);
ResourceTreeHelper.deleteResource(em, resource1);
resourceType1 = em.find(ResourceType.class, resourceType1.getId());
em.remove(resourceType1);
getTransactionManager().commit();
} catch (Exception e) {
e.printStackTrace();
getTransactionManager().rollback();
throw e;
}
} finally {
unprepareForTestAgents();
}
}
private void populateResponseSteps() {
stepResults = new ArrayList<DeployPackageStep>(3);
DeployPackageStep step1 = new DeployPackageStep("Step1", "First step");
step1.setStepResult(ContentResponseResult.SUCCESS);
DeployPackageStep step2 = new DeployPackageStep("Step2", "Second step");
step2.setStepResult(ContentResponseResult.NOT_PERFORMED);
DeployPackageStep step3 = new DeployPackageStep("Step3", "Third step");
step3.setStepResult(ContentResponseResult.FAILURE);
step3.setStepErrorMessage("Error executing the third step");
stepResults.add(step1);
stepResults.add(step2);
stepResults.add(step3);
}
// Inner Classes --------------------------------------------
private class MockContentAgentService implements ContentAgentService {
// Attributes --------------------------------------------
private ContentResponseResult responseReturnStatus;
private boolean throwError;
private boolean returnIndividualResponses = true;
private List<DeployPackageStep> deployPackageSteps;
// Public --------------------------------------------
/**
* The value set in this method will be the status of the response object sent back to the EJB.
*
* @param responseReturnStatus status to use for all response objects
*/
public void setResponseReturnStatus(ContentResponseResult responseReturnStatus) {
this.responseReturnStatus = responseReturnStatus;
}
/**
* If this is set to <code>true</code>, calls into this mock will trigger a <code>RuntimeException</code>.
*
* @param throwError flag indicating if an error should be thrown
*/
public void setThrowError(boolean throwError) {
this.throwError = throwError;
}
/**
* Calls to deploy will include this list for all packages in the deployment request.
*
* @param deployPackageSteps indicates if deployed package responses should have steps attached to them
*/
public void setDeployPackageSteps(List<DeployPackageStep> deployPackageSteps) {
this.deployPackageSteps = deployPackageSteps;
}
/**
* If this is set to <code>true</code> the response will include an entry for each package requested.
*
* @param returnIndividualResponses flag indicating if individual package results should be returned
*/
public void setReturnIndividualResponses(boolean returnIndividualResponses) {
this.returnIndividualResponses = returnIndividualResponses;
}
// ContentAgentService Implementation --------------------------------------------
public Set<ResourcePackageDetails> getLastDiscoveredResourcePackages(int resourceId) {
return null;
}
public ContentDiscoveryReport executeResourcePackageDiscoveryImmediately(int resourceId, String packageTypeName)
throws PluginContainerException {
return null;
}
public List<DeployPackageStep> translateInstallationSteps(int resourceId, ResourcePackageDetails packageDetails) {
return null;
}
public void deployPackages(final DeployPackagesRequest request) {
if (throwError) {
throw new RuntimeException("Mock exception - This is expected");
}
Runnable responseRunner = new Runnable() {
public void run() {
synchronized (responseLock) {
DeployPackagesResponse response = new DeployPackagesResponse(responseReturnStatus);
// This setting of the ID will be done by the plugin container; we're not relying on the plugin
// to do it. Since I'm skipping the PC entirely for this test, I'll do it here.
response.setRequestId(request.getRequestId());
if (returnIndividualResponses) {
for (ResourcePackageDetails packageDetails : request.getPackages()) {
DeployIndividualPackageResponse individualResponse = new DeployIndividualPackageResponse(
packageDetails.getKey(), responseReturnStatus);
individualResponse.setDeploymentSteps(deployPackageSteps);
response.addPackageResponse(individualResponse);
}
}
ContentManagerBeanTest.this.contentManager.completeDeployPackageRequest(response);
}
}
};
Thread runner = new Thread(responseRunner);
runner.start();
}
public void deletePackages(final DeletePackagesRequest request) {
if (throwError) {
throw new RuntimeException("Mock exception - This is expected");
}
Runnable responseRunner = new Runnable() {
public void run() {
synchronized (responseLock) {
RemovePackagesResponse response = new RemovePackagesResponse(responseReturnStatus);
// This setting of the ID will be done by the plugin container; we're not relying on the plugin
// to do it. Since I'm skipping the PC entirely for this test, I'll do it here.
response.setRequestId(request.getRequestId());
if (returnIndividualResponses) {
for (ResourcePackageDetails packageDetails : request.getPackages()) {
RemoveIndividualPackageResponse individualResponse = new RemoveIndividualPackageResponse(
packageDetails.getKey(), responseReturnStatus);
response.addPackageResponse(individualResponse);
}
}
ContentManagerBeanTest.this.contentManager.completeDeletePackageRequest(response);
}
}
};
Thread runner = new Thread(responseRunner);
runner.start();
}
public void retrievePackageBits(RetrievePackageBitsRequest request) {
}
}
}