/*
* RHQ Management Platform
* Copyright (C) 2009 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, version 2, as
* published by the Free Software Foundation, and/or the GNU Lesser
* General Public License, version 2.1, also as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License and the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* and the GNU Lesser General Public License along with this program;
* if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.rhq.enterprise.server.plugin.pc.content;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.transaction.TransactionManager;
import org.testng.annotations.Test;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.content.ContentSource;
import org.rhq.core.domain.content.ContentSourceType;
import org.rhq.core.domain.content.Distribution;
import org.rhq.core.domain.content.DistributionFile;
import org.rhq.core.domain.content.DownloadMode;
import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.content.Repo;
import org.rhq.core.domain.content.RepoDistribution;
import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.enterprise.server.auth.SubjectManagerLocal;
import org.rhq.enterprise.server.content.ContentManagerLocal;
import org.rhq.enterprise.server.content.ContentSourceManagerLocal;
import org.rhq.enterprise.server.content.DistributionManagerLocal;
import org.rhq.enterprise.server.content.RepoManagerLocal;
import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal;
import org.rhq.enterprise.server.test.AbstractEJB3Test;
import org.rhq.enterprise.server.util.LookupUtil;
/**
* @author Jason Dobies
*/
public class ContentProviderManagerSyncRepoTest extends AbstractEJB3Test {
private static final boolean TESTS_ENABLED = true;
private TestContentServerPluginService pluginService;
private TestContentProvider contentProvider1 = new TestContentProvider();
private TestContentProvider contentProvider2 = new TestContentProvider();
// The following variables need to be cleaned up at the end of the test
private ContentSourceType contentSourceType;
private PackageType packageType;
private ResourceType resourceType;
private List<ContentSource> repoContentSources = new ArrayList<ContentSource>();
private Repo repoToSync;
@Override
protected void beforeMethod() throws Exception {
// Plugin service setup
prepareScheduler();
pluginService = new TestContentServerPluginService(this);
TransactionManager tx = getTransactionManager();
try {
tx.begin();
EntityManager entityManager = getEntityManager();
ContentManagerLocal contentManager = LookupUtil.getContentManager();
ContentSourceManagerLocal contentSourceManager = LookupUtil.getContentSourceManager();
RepoManagerLocal repoManager = LookupUtil.getRepoManagerLocal();
ResourceTypeManagerLocal resourceTypeManager = LookupUtil.getResourceTypeManager();
SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
Subject overlord = subjectManager.getOverlord();
// protect if it aleady exists due to a failed run
contentSourceType = contentSourceManager.getContentSourceType("testType");
if (null == contentSourceType) {
// Create a sample content source type that will be used in this test
contentSourceType = new ContentSourceType("testType");
entityManager.persist(contentSourceType);
entityManager.flush();
}
// protect if it aleady exists due to a failed run
ContentSource cs1 = contentSourceManager.getContentSourceByNameAndType(overlord, "contentSource1",
"testType");
if (null == cs1) {
// A repo sync will query all providers for that repo, so add multiple providers
cs1 = new ContentSource("contentSource1", contentSourceType);
cs1.setDownloadMode(DownloadMode.DATABASE);
cs1 = contentSourceManager.simpleCreateContentSource(overlord, cs1);
}
ContentSource cs2 = contentSourceManager.getContentSourceByNameAndType(overlord, "contentSource2",
"testType");
if (null == cs2) {
cs2 = new ContentSource("contentSource2", contentSourceType);
cs2.setDownloadMode(DownloadMode.DATABASE);
cs2 = contentSourceManager.simpleCreateContentSource(overlord, cs2);
}
pluginService.associateContentProvider(cs1, contentProvider1);
pluginService.associateContentProvider(cs2, contentProvider2);
repoContentSources.add(cs1);
repoContentSources.add(cs2);
// Create the package type packages will be created against
resourceType = resourceTypeManager.getResourceTypeByNameAndPlugin(TestContentProvider.RESOURCE_TYPE_NAME,
TestContentProvider.RESOURCE_TYPE_PLUGIN_NAME);
if (null == resourceType) {
resourceType = new ResourceType(TestContentProvider.RESOURCE_TYPE_NAME,
TestContentProvider.RESOURCE_TYPE_PLUGIN_NAME, ResourceCategory.PLATFORM, null);
entityManager.persist(resourceType);
entityManager.flush();
}
List<PackageType> packageTypes = contentManager.findPackageTypes(overlord,
TestContentProvider.RESOURCE_TYPE_NAME, TestContentProvider.RESOURCE_TYPE_PLUGIN_NAME);
if (!packageTypes.isEmpty()) {
packageType = packageTypes.get(0);
} else {
packageType = new PackageType(TestContentProvider.PACKAGE_TYPE_NAME, resourceType);
entityManager.persist(packageType);
}
// Create the repo to be synced
List<Repo> repos = repoManager.getRepoByName(TestContentProvider.REPO_WITH_PACKAGES);
if (!repos.isEmpty()) {
repoToSync = repos.get(0);
} else {
Repo repo = new Repo(TestContentProvider.REPO_WITH_PACKAGES);
repo.addContentSource(cs1);
// repo.addContentSource(cs2); Disabled until we implement a second test content source to return new stuff
repoToSync = repoManager.createRepo(overlord, repo);
}
tx.commit();
} catch (Throwable t) {
tx.rollback();
// rethrow because if we swallow the exception then tests proceed to execute when they probably should not
throw new RuntimeException(t);
}
}
@Override
protected void afterMethod() throws Exception {
try {
TransactionManager tx = getTransactionManager();
tx.begin();
EntityManager entityManager = getEntityManager();
Query query;
ContentSourceManagerLocal contentSourceManagerLocal = LookupUtil.getContentSourceManager();
RepoManagerLocal repoManager = LookupUtil.getRepoManagerLocal();
DistributionManagerLocal distroManager = LookupUtil.getDistributionManagerLocal();
SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
Subject overlord = subjectManager.getOverlord();
// Delete all distributions
distroManager.deleteDistributionMappingsForRepo(overlord, repoToSync.getId());
for (String distroLabel : TestContentProvider.DISTRIBUTIONS.keySet()) {
Distribution distro = distroManager.getDistributionByLabel(distroLabel);
if (distro != null) {
// Delete the files
query = entityManager.createNamedQuery(DistributionFile.DELETE_BY_DIST_ID);
query.setParameter("distId", distro.getId());
query.executeUpdate();
// Delete the actual distro
distroManager.deleteDistributionByDistId(overlord, distro.getId());
}
}
// Delete all package version <-> content source mappings
for (ContentSource source : repoContentSources) {
contentSourceManagerLocal.deleteContentSource(overlord, source.getId());
}
repoContentSources.clear();
// Delete the repo
repoManager.deleteRepo(overlord, repoToSync.getId());
// Delete any packages that were created
for (ContentProviderPackageDetails details : TestContentProvider.PACKAGES.values()) {
String packageName = details.getContentProviderPackageDetailsKey().getName();
query = entityManager.createNamedQuery(Package.QUERY_FIND_BY_NAME_PKG_TYPE_ID);
query.setParameter("name", packageName);
query.setParameter("packageTypeId", packageType.getId());
Package p = (Package) query.getSingleResult();
entityManager.remove(p);
}
// Delete the package type
packageType = entityManager.find(PackageType.class, packageType.getId());
entityManager.remove(packageType);
resourceType = entityManager.find(ResourceType.class, resourceType.getId());
entityManager.remove(resourceType);
// Delete the content source type
contentSourceType = entityManager.find(ContentSourceType.class, contentSourceType.getId());
entityManager.remove(contentSourceType);
tx.commit();
// Cleanup providers between tests
contentProvider1.reset();
contentProvider2.reset();
} finally {
// Plugin service teardown
unprepareServerPluginService();
unprepareScheduler();
}
}
@Test(enabled = TESTS_ENABLED)
@SuppressWarnings("unchecked")
public void synchronizeRepo() throws Exception {
// Test
// --------------------------------------------
boolean completed = pluginService.getContentProviderManager().synchronizeRepo(repoToSync.getId());
assert completed;
// Verify
// --------------------------------------------
// Make sure the proper calls were made into the provider
assert contentProvider1.getLogSynchronizePackagesRepos().size() == 1 : "Expected: 1, Found: "
+ contentProvider1.getLogSynchronizePackagesRepos().size();
// Need to add in distro packages being syncced
assert contentProvider1.getLogGetInputStreamLocations().size() == TestContentProvider.PACKAGE_COUNT_FOR_BITS : "Expected: "
+ TestContentProvider.PACKAGE_COUNT_FOR_BITS
+ ", Found: "
+ contentProvider1.getLogGetInputStreamLocations().size();
// Make sure all of the packages were added
TransactionManager tx = getTransactionManager();
tx.begin();
EntityManager entityManager = getEntityManager();
Query query = entityManager.createNamedQuery(PackageVersion.QUERY_FIND_BY_REPO_ID);
query.setParameter("repoId", repoToSync.getId());
List<PackageVersion> repoPackages = query.getResultList();
assert repoPackages.size() == TestContentProvider.PACKAGES.size() : "Expected: "
+ TestContentProvider.PACKAGES.size() + ", Found: " + repoPackages.size();
// Make sure all of the distributions were added
query = entityManager.createNamedQuery(RepoDistribution.QUERY_FIND_BY_REPO_ID);
query.setParameter("repoId", repoToSync.getId());
List<RepoDistribution> repoDistributions = query.getResultList();
assert repoDistributions.size() == TestContentProvider.DISTRIBUTIONS.size() : "Expected: "
+ TestContentProvider.DISTRIBUTIONS.size() + ", Found: " + repoDistributions.size();
// Make sure each distribution has the correct files associated
int distro1FileCount = countDistroFiles(entityManager, TestContentProvider.DISTRIBUTION_1_LABEL);
assert distro1FileCount == 2 : "Expected: 2, Found: " + distro1FileCount;
int distro2FileCount = countDistroFiles(entityManager, TestContentProvider.DISTRIBUTION_2_LABEL);
assert distro2FileCount == 1 : "Expected: 1, Found: " + distro1FileCount;
tx.rollback();
}
private int countDistroFiles(EntityManager entityManager, String label) {
Query query = entityManager.createNamedQuery(Distribution.QUERY_FIND_BY_DIST_LABEL);
query.setParameter("label", label);
Distribution distro = (Distribution) query.getSingleResult();
query = entityManager.createNamedQuery(DistributionFile.SELECT_BY_DIST_ID);
query.setParameter("distId", distro.getId());
List distroFiles = query.getResultList();
if (distroFiles == null) {
return 0;
} else {
return distroFiles.size();
}
}
}