diff options
author | Pascal Rapicault | 2009-04-23 18:33:44 +0000 |
---|---|---|
committer | Pascal Rapicault | 2009-04-23 18:33:44 +0000 |
commit | 9fcfced640aa4e4e24f51c88aadd2d6787a07c13 (patch) | |
tree | 81cc2fe29b3a4504e616b695f32e963bd3bd27ef | |
parent | f4183426a566f3c3d9be31c08bd60e4ebf660f1a (diff) | |
download | rt.equinox.p2-9fcfced640aa4e4e24f51c88aadd2d6787a07c13.tar.gz rt.equinox.p2-9fcfced640aa4e4e24f51c88aadd2d6787a07c13.tar.xz rt.equinox.p2-9fcfced640aa4e4e24f51c88aadd2d6787a07c13.zip |
Bug 265550 - Review Ant task consistency
30 files changed, 4864 insertions, 235 deletions
diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.repository.tools/META-INF/MANIFEST.MF index c99890bb5..c8c402de2 100644 --- a/bundles/org.eclipse.equinox.p2.repository.tools/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.p2.repository.tools/META-INF/MANIFEST.MF @@ -12,6 +12,7 @@ Import-Package: org.apache.tools.ant, org.eclipse.equinox.app;version="1.0.0", org.eclipse.equinox.internal.p2.artifact.mirror, org.eclipse.equinox.internal.p2.artifact.repository, + org.eclipse.equinox.internal.p2.artifact.repository.ant, org.eclipse.equinox.internal.p2.artifact.repository.simple, org.eclipse.equinox.internal.p2.core.helpers, org.eclipse.equinox.internal.p2.director, diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/plugin.xml b/bundles/org.eclipse.equinox.p2.repository.tools/plugin.xml index 77627fb6a..ec94e97b7 100644 --- a/bundles/org.eclipse.equinox.p2.repository.tools/plugin.xml +++ b/bundles/org.eclipse.equinox.p2.repository.tools/plugin.xml @@ -15,6 +15,12 @@ library="lib/repository-tools-ant.jar" name="p2.mirror"> </antTask> + + <antTask + class="org.eclipse.equinox.p2.internal.repository.tools.tasks.CompositeRepositoryTask" + library="lib/repository-tools-ant.jar" + name="p2.composite.repository"> + </antTask> <antTask library="lib/repository-tools-ant.jar" diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/AbstractApplication.java b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/AbstractApplication.java index f640754c4..d02c1b4ce 100644 --- a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/AbstractApplication.java +++ b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/AbstractApplication.java @@ -10,10 +10,10 @@ *******************************************************************************/ package org.eclipse.equinox.p2.internal.repository.tools; -import java.net.URI; -import java.net.URISyntaxException; +import java.net.*; import java.util.*; -import org.eclipse.core.runtime.*; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; import org.eclipse.equinox.internal.p2.artifact.repository.CompositeArtifactRepository; import org.eclipse.equinox.internal.p2.metadata.repository.CompositeMetadataRepository; import org.eclipse.equinox.internal.p2.repository.helpers.RepositoryHelper; @@ -22,13 +22,13 @@ import org.eclipse.equinox.internal.provisional.p2.artifact.repository.IArtifact import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException; import org.eclipse.equinox.internal.provisional.p2.metadata.repository.IMetadataRepository; import org.eclipse.equinox.internal.provisional.p2.metadata.repository.IMetadataRepositoryManager; -import org.eclipse.equinox.internal.provisional.p2.repository.IRepository; -import org.eclipse.equinox.internal.provisional.p2.repository.IRepositoryManager; +import org.eclipse.equinox.internal.provisional.p2.repository.*; +import org.eclipse.osgi.util.NLS; public abstract class AbstractApplication { + protected boolean removeAddedRepositories = true; - protected List sourceArtifactRepositories = new ArrayList(); - protected List sourceMetadataRepositories = new ArrayList(); + protected List sourceRepositories = new ArrayList(); //List of repository descriptors protected List artifactReposToRemove = new ArrayList(); protected List metadataReposToRemove = new ArrayList(); protected List sourceIUs = new ArrayList(); @@ -40,92 +40,89 @@ public abstract class AbstractApplication { private CompositeMetadataRepository compositeMetadataRepository = null; private CompositeArtifactRepository compositeArtifactRepository = null; - public void addSourceMetadataRepository(String location) { - URI uri = Activator.getURI(location); - if (uri != null) - sourceMetadataRepositories.add(RepositoryHelper.localRepoURIHelper(uri)); - } - - public void addSourceMetadataRepository(URI location) { - if (location != null) - sourceMetadataRepositories.add(RepositoryHelper.localRepoURIHelper(location)); - } - - public List getSourceMetadataRepositories() { - return sourceMetadataRepositories; - } - - public void addSourceArtifactRepository(String location) { - URI uri = Activator.getURI(location); - if (uri != null) - sourceArtifactRepositories.add(RepositoryHelper.localRepoURIHelper(uri)); - } - - public void addSourceArtifactRepository(URI location) { - if (location != null) - sourceArtifactRepositories.add(RepositoryHelper.localRepoURIHelper(location)); - } - public void setSourceIUs(List ius) { sourceIUs = ius; } protected void finalizeRepositories() throws ProvisionException { - IArtifactRepositoryManager artifactRepositoryManager = Activator.getArtifactRepositoryManager(); - for (Iterator iter = artifactReposToRemove.iterator(); iter.hasNext();) - artifactRepositoryManager.removeRepository((URI) iter.next()); - IMetadataRepositoryManager metadataRepositoryManager = Activator.getMetadataRepositoryManager(); - for (Iterator iter = metadataReposToRemove.iterator(); iter.hasNext();) - metadataRepositoryManager.removeRepository((URI) iter.next()); + if (removeAddedRepositories) { + IArtifactRepositoryManager artifactRepositoryManager = Activator.getArtifactRepositoryManager(); + for (Iterator iter = artifactReposToRemove.iterator(); iter.hasNext();) + artifactRepositoryManager.removeRepository((URI) iter.next()); + IMetadataRepositoryManager metadataRepositoryManager = Activator.getMetadataRepositoryManager(); + for (Iterator iter = metadataReposToRemove.iterator(); iter.hasNext();) + metadataRepositoryManager.removeRepository((URI) iter.next()); + } } public void initializeRepos(IProgressMonitor progress) throws ProvisionException { IArtifactRepositoryManager artifactRepositoryManager = Activator.getArtifactRepositoryManager(); - if (sourceArtifactRepositories != null && !sourceArtifactRepositories.isEmpty()) { - for (Iterator iter = sourceArtifactRepositories.iterator(); iter.hasNext();) { - URI repoLocation = (URI) iter.next(); - if (!artifactRepositoryManager.contains(repoLocation)) - artifactReposToRemove.add(repoLocation); - artifactRepositoryManager.loadRepository(repoLocation, 0, progress); - } - } - IMetadataRepositoryManager metadataRepositoryManager = Activator.getMetadataRepositoryManager(); - if (sourceMetadataRepositories != null && !sourceMetadataRepositories.isEmpty()) { - for (Iterator iter = sourceMetadataRepositories.iterator(); iter.hasNext();) { - URI repoLocation = (URI) iter.next(); - if (!metadataRepositoryManager.contains(repoLocation)) - metadataReposToRemove.add(repoLocation); - metadataRepositoryManager.loadRepository(repoLocation, 0, progress); + URI curLocation = null; + try { + for (Iterator iter = sourceRepositories.iterator(); iter.hasNext();) { + RepositoryDescriptor repo = (RepositoryDescriptor) iter.next(); + curLocation = repo.getRepoLocation(); + if (repo.isBoth()) { + addRepository(artifactRepositoryManager, curLocation, 0, progress); + addRepository(metadataRepositoryManager, curLocation, 0, progress); + } else if (repo.isArtifact()) + addRepository(artifactRepositoryManager, curLocation, 0, progress); + else if (repo.isMetadata()) + addRepository(metadataRepositoryManager, curLocation, 0, progress); + else + throw new ProvisionException(NLS.bind(Messages.unknown_repository_type, repo.getRepoLocation())); } + } catch (ProvisionException e) { + if (e.getCause() instanceof MalformedURLException) { + throw new ProvisionException(NLS.bind(Messages.exception_invalidSource, curLocation), e); + } + throw e; } - processDestinationRepos(artifactRepositoryManager, metadataRepositoryManager); + } + + //Helper to add a repository. It takes care of adding the repos to the deletion list and loading it + protected IMetadataRepository addRepository(IMetadataRepositoryManager manager, URI location, int flags, IProgressMonitor monitor) throws ProvisionException { + if (!manager.contains(location)) + metadataReposToRemove.add(location); + return manager.loadRepository(location, flags, monitor); + } + //Helper to add a repository. It takes care of adding the repos to the deletion list and loading it + protected IArtifactRepository addRepository(IArtifactRepositoryManager manager, URI location, int flags, IProgressMonitor monitor) throws ProvisionException { + if (!manager.contains(location)) + artifactReposToRemove.add(location); + return manager.loadRepository(location, flags, monitor); } private void processDestinationRepos(IArtifactRepositoryManager artifactRepositoryManager, IMetadataRepositoryManager metadataRepositoryManager) throws ProvisionException { - if (destinationRepos.size() != 2) { - throw new ProvisionException("Too many or too few destination repositories."); + RepositoryDescriptor artifactRepoDescriptor = null; + RepositoryDescriptor metadataRepoDescriptor = null; + + Iterator iter = destinationRepos.iterator(); + while (iter.hasNext() && (artifactRepoDescriptor == null || metadataRepoDescriptor == null)) { + RepositoryDescriptor repo = (RepositoryDescriptor) iter.next(); + if (repo.isArtifact() && artifactRepoDescriptor == null) + artifactRepoDescriptor = repo; + if (repo.isMetadata() && metadataRepoDescriptor == null) + metadataRepoDescriptor = repo; } - RepositoryDescriptor artifactRepoDescriptor = ((RepositoryDescriptor) destinationRepos.get(0)).getKind() == IRepository.TYPE_ARTIFACT ? ((RepositoryDescriptor) destinationRepos.get(0)) : ((RepositoryDescriptor) destinationRepos.get(1)); - RepositoryDescriptor metadataRepoDescriptor = ((RepositoryDescriptor) destinationRepos.get(0)).getKind() == IRepository.TYPE_METADATA ? ((RepositoryDescriptor) destinationRepos.get(0)) : ((RepositoryDescriptor) destinationRepos.get(1)); - destinationArtifactRepository = initializeDestination(artifactRepoDescriptor, artifactRepositoryManager); - destinationMetadataRepository = initializeDestination(metadataRepoDescriptor, metadataRepositoryManager); + + if (artifactRepoDescriptor != null) + destinationArtifactRepository = initializeDestination(artifactRepoDescriptor, artifactRepositoryManager); + if (metadataRepoDescriptor != null) + destinationMetadataRepository = initializeDestination(metadataRepoDescriptor, metadataRepositoryManager); + + if (destinationMetadataRepository == null && destinationArtifactRepository == null) + throw new ProvisionException(Messages.AbstractApplication_no_valid_destinations); } - private IMetadataRepository initializeDestination(RepositoryDescriptor toInit, IMetadataRepositoryManager mgr) throws ProvisionException { + protected IMetadataRepository initializeDestination(RepositoryDescriptor toInit, IMetadataRepositoryManager mgr) throws ProvisionException { try { - if (!mgr.contains(toInit.getRepoLocation())) - metadataReposToRemove.add(toInit.getRepoLocation()); - IMetadataRepository repository = mgr.loadRepository(toInit.getRepoLocation(), IRepositoryManager.REPOSITORY_HINT_MODIFIABLE, null); - if (repository != null && repository.isModifiable()) { - if (toInit.getName() != null) - repository.setName(toInit.getName()); - if (!toInit.isAppend()) - repository.removeAll(); + IMetadataRepository repository = addRepository(mgr, toInit.getRepoLocation(), IRepositoryManager.REPOSITORY_HINT_MODIFIABLE, null); + if (initDestinationRepository(repository, toInit)) return repository; - } } catch (ProvisionException e) { //fall through and create a new repository below } @@ -133,51 +130,63 @@ public abstract class AbstractApplication { IMetadataRepository source = null; try { if (toInit.getFormat() != null) - source = mgr.loadRepository(URIUtil.fromString(toInit.getFormat()), 0, null); + source = mgr.loadRepository(toInit.getFormat(), 0, null); } catch (ProvisionException e) { //Ignore. - } catch (URISyntaxException e) { - //Ignore } //This code assumes source has been successfully loaded before this point //No existing repository; create a new repository at destinationLocation but with source's attributes. - IMetadataRepository result = mgr.createRepository(toInit.getRepoLocation(), toInit.getName() != null ? toInit.getName() : (source != null ? source.getName() : toInit.getRepoLocation().toString()), IMetadataRepositoryManager.TYPE_SIMPLE_REPOSITORY, source != null ? source.getProperties() : null); - if (toInit.isCompressed() && !result.getProperties().containsKey(IRepository.PROP_COMPRESSED)) - result.setProperty(IRepository.PROP_COMPRESSED, "true"); //$NON-NLS-1$ - return (IMetadataRepository) RepositoryHelper.validDestinationRepository(result); + try { + IMetadataRepository result = mgr.createRepository(toInit.getRepoLocation(), toInit.getName() != null ? toInit.getName() : (source != null ? source.getName() : toInit.getRepoLocation().toString()), IMetadataRepositoryManager.TYPE_SIMPLE_REPOSITORY, source != null ? source.getProperties() : null); + if (toInit.isCompressed() && !result.getProperties().containsKey(IRepository.PROP_COMPRESSED)) + result.setProperty(IRepository.PROP_COMPRESSED, "true"); //$NON-NLS-1$ + return (IMetadataRepository) RepositoryHelper.validDestinationRepository(result); + } catch (UnsupportedOperationException e) { + throw new ProvisionException(NLS.bind(Messages.exception_invalidDestination, toInit.getRepoLocation()), e.getCause()); + } } - private IArtifactRepository initializeDestination(RepositoryDescriptor toInit, IArtifactRepositoryManager mgr) throws ProvisionException { + protected IArtifactRepository initializeDestination(RepositoryDescriptor toInit, IArtifactRepositoryManager mgr) throws ProvisionException { try { - if (!mgr.contains(toInit.getRepoLocation())) - artifactReposToRemove.add(toInit.getRepoLocation()); - IArtifactRepository repository = mgr.loadRepository(toInit.getRepoLocation(), IRepositoryManager.REPOSITORY_HINT_MODIFIABLE, null); - if (repository != null && repository.isModifiable()) { - if (toInit.getName() != null) - repository.setName(toInit.getName()); - if (!toInit.isAppend()) - repository.removeAll(); + IArtifactRepository repository = addRepository(mgr, toInit.getRepoLocation(), IRepositoryManager.REPOSITORY_HINT_MODIFIABLE, null); + if (initDestinationRepository(repository, toInit)) return repository; - } } catch (ProvisionException e) { //fall through and create a new repository below } IArtifactRepository source = null; try { if (toInit.getFormat() != null) - source = mgr.loadRepository(URIUtil.fromString(toInit.getFormat()), 0, null); + source = mgr.loadRepository(toInit.getFormat(), 0, null); } catch (ProvisionException e) { //Ignore. - } catch (URISyntaxException e) { - //Ignore } //This code assumes source has been successfully loaded before this point //No existing repository; create a new repository at destinationLocation but with source's attributes. // TODO for now create a Simple repo by default. - IArtifactRepository result = mgr.createRepository(toInit.getRepoLocation(), toInit.getName() != null ? toInit.getName() : (source != null ? source.getName() : toInit.getRepoLocation().toString()), IArtifactRepositoryManager.TYPE_SIMPLE_REPOSITORY, source != null ? source.getProperties() : null); - if (toInit.isCompressed() && !result.getProperties().containsKey(IRepository.PROP_COMPRESSED)) - result.setProperty(IRepository.PROP_COMPRESSED, "true"); //$NON-NLS-1$ - return (IArtifactRepository) RepositoryHelper.validDestinationRepository(result); + try { + IArtifactRepository result = mgr.createRepository(toInit.getRepoLocation(), toInit.getName() != null ? toInit.getName() : (source != null ? source.getName() : toInit.getRepoLocation().toString()), IArtifactRepositoryManager.TYPE_SIMPLE_REPOSITORY, source != null ? source.getProperties() : null); + if (toInit.isCompressed() && !result.getProperties().containsKey(IRepository.PROP_COMPRESSED)) + result.setProperty(IRepository.PROP_COMPRESSED, "true"); //$NON-NLS-1$ + return (IArtifactRepository) RepositoryHelper.validDestinationRepository(result); + } catch (UnsupportedOperationException e) { + throw new ProvisionException(NLS.bind(Messages.exception_invalidDestination, toInit.getRepoLocation()), e.getCause()); + } + } + + protected boolean initDestinationRepository(IRepository repository, RepositoryDescriptor descriptor) { + if (repository != null && repository.isModifiable()) { + if (descriptor.getName() != null) + repository.setName(descriptor.getName()); + if (repository instanceof ICompositeRepository && !descriptor.isAppend()) + ((ICompositeRepository) repository).removeAllChildren(); + else if (repository instanceof IMetadataRepository && !descriptor.isAppend()) + ((IMetadataRepository) repository).removeAll(); + else if (repository instanceof IArtifactRepository && !descriptor.isAppend()) + ((IArtifactRepository) repository).removeAll(); + return true; + } + return false; } public IMetadataRepository getCompositeMetadataRepository() { @@ -187,8 +196,10 @@ public abstract class AbstractApplication { } catch (URISyntaxException e) { //Can't happen } - for (Iterator iter = sourceMetadataRepositories.iterator(); iter.hasNext();) { - compositeMetadataRepository.addChild((URI) iter.next()); + for (Iterator iter = sourceRepositories.iterator(); iter.hasNext();) { + RepositoryDescriptor repo = (RepositoryDescriptor) iter.next(); + if (repo.isMetadata()) + compositeMetadataRepository.addChild(repo.getRepoLocation()); } } return compositeMetadataRepository; @@ -197,20 +208,34 @@ public abstract class AbstractApplication { public IArtifactRepository getCompositeArtifactRepository() { if (compositeArtifactRepository == null) { try { - compositeArtifactRepository = new CompositeArtifactRepository(new URI("memory:/composite"), "parent metadata repo", null);//$NON-NLS-1$ //$NON-NLS-2$ + compositeArtifactRepository = new CompositeArtifactRepository(new URI("memory:/composite"), "parent artifact repo", null);//$NON-NLS-1$ //$NON-NLS-2$ } catch (URISyntaxException e) { //Can't happen } - for (Iterator iter = sourceArtifactRepositories.iterator(); iter.hasNext();) { - compositeArtifactRepository.addChild((URI) iter.next()); + for (Iterator iter = sourceRepositories.iterator(); iter.hasNext();) { + RepositoryDescriptor repo = (RepositoryDescriptor) iter.next(); + if (repo.isArtifact()) + compositeArtifactRepository.addChild(repo.getRepoLocation()); } } return compositeArtifactRepository; } + public boolean hasArtifactSources() { + return ((ICompositeRepository) getCompositeArtifactRepository()).getChildren().size() > 0; + } + + public boolean hasMetadataSources() { + return ((ICompositeRepository) getCompositeMetadataRepository()).getChildren().size() > 0; + } + public abstract IStatus run(IProgressMonitor monitor) throws ProvisionException; public void addDestination(RepositoryDescriptor descriptor) { destinationRepos.add(descriptor); } + + public void addSource(RepositoryDescriptor repo) { + sourceRepositories.add(repo); + } }
\ No newline at end of file diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/Activator.java b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/Activator.java index 9270600e9..5c101ea89 100644 --- a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/Activator.java +++ b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/Activator.java @@ -19,6 +19,7 @@ import org.eclipse.equinox.internal.provisional.p2.artifact.repository.IArtifact import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException; import org.eclipse.equinox.internal.provisional.p2.engine.IProfileRegistry; import org.eclipse.equinox.internal.provisional.p2.metadata.repository.IMetadataRepositoryManager; +import org.eclipse.osgi.util.NLS; import org.osgi.framework.*; import org.osgi.service.packageadmin.PackageAdmin; @@ -43,7 +44,7 @@ public class Activator implements BundleActivator { // TODO needed to do this to ensure the profile registry was registered Bundle bundle = getBundle("org.eclipse.equinox.p2.exemplarysetup"); //$NON-NLS-1$ if (bundle == null) - throw new ProvisionException("Unable to start exemplarysetup bundle."); + throw new ProvisionException(Messages.unable_to_start_exemplarysetup); bundle.start(Bundle.START_TRANSIENT); } @@ -64,7 +65,7 @@ public class Activator implements BundleActivator { try { return URIUtil.fromString(spec); } catch (URISyntaxException e) { - LogHelper.log(new Status(IStatus.WARNING, ID, "Unable to process as URI: " + spec, e)); + LogHelper.log(new Status(IStatus.WARNING, ID, NLS.bind(Messages.unable_to_process_uri, spec), e)); } return null; } @@ -75,7 +76,7 @@ public class Activator implements BundleActivator { public static IArtifactRepositoryManager getArtifactRepositoryManager() throws ProvisionException { IArtifactRepositoryManager manager = (IArtifactRepositoryManager) ServiceHelper.getService(getBundleContext(), IArtifactRepositoryManager.class.getName()); if (manager == null) - throw new ProvisionException("Unable to acquire artifact repository manager service."); + throw new ProvisionException(Messages.no_artifactRepo_manager); return manager; } @@ -85,7 +86,7 @@ public class Activator implements BundleActivator { static IProfileRegistry getProfileRegistry() throws ProvisionException { IProfileRegistry registry = (IProfileRegistry) ServiceHelper.getService(getBundleContext(), IProfileRegistry.class.getName()); if (registry == null) - throw new ProvisionException("Unable to acquire profile registry service."); + throw new ProvisionException(Messages.no_profile_registry); return registry; } @@ -95,7 +96,7 @@ public class Activator implements BundleActivator { public static synchronized Bundle getBundle(String symbolicName) throws ProvisionException { PackageAdmin packageAdmin = (PackageAdmin) ServiceHelper.getService(getBundleContext(), PackageAdmin.class.getName()); if (packageAdmin == null) - throw new ProvisionException("Unable to acquire package admin service."); + throw new ProvisionException(Messages.no_package_admin); Bundle[] bundles = packageAdmin.getBundles(symbolicName, null); if (bundles == null) return null; @@ -113,7 +114,7 @@ public class Activator implements BundleActivator { public static IMetadataRepositoryManager getMetadataRepositoryManager() throws ProvisionException { IMetadataRepositoryManager manager = (IMetadataRepositoryManager) ServiceHelper.getService(getBundleContext(), IMetadataRepositoryManager.class.getName()); if (manager == null) - throw new ProvisionException("Unable to acquire metadata repository manager service."); + throw new ProvisionException(Messages.no_metadataRepo_manager); return manager; } } diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/CompositeRepositoryApplication.java b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/CompositeRepositoryApplication.java new file mode 100644 index 000000000..dd5fa9fe8 --- /dev/null +++ b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/CompositeRepositoryApplication.java @@ -0,0 +1,173 @@ +/******************************************************************************* + * Copyright (c) 2009 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.equinox.p2.internal.repository.tools; + +import java.net.MalformedURLException; +import java.util.*; +import org.eclipse.core.runtime.*; +import org.eclipse.equinox.internal.p2.repository.helpers.RepositoryHelper; +import org.eclipse.equinox.internal.provisional.p2.artifact.repository.IArtifactRepository; +import org.eclipse.equinox.internal.provisional.p2.artifact.repository.IArtifactRepositoryManager; +import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException; +import org.eclipse.equinox.internal.provisional.p2.metadata.repository.IMetadataRepository; +import org.eclipse.equinox.internal.provisional.p2.metadata.repository.IMetadataRepositoryManager; +import org.eclipse.equinox.internal.provisional.p2.repository.ICompositeRepository; +import org.eclipse.equinox.internal.provisional.p2.repository.IRepository; +import org.eclipse.osgi.util.NLS; + +public class CompositeRepositoryApplication extends AbstractApplication { + private List childrenToAdd = new ArrayList(); + private List childrenToRemove = new ArrayList(); + private boolean failOnExists = false; + + public IStatus run(IProgressMonitor monitor) throws ProvisionException { + try { + initializeRepos(new NullProgressMonitor()); + // load repository + ICompositeRepository metadataRepo = (ICompositeRepository) destinationMetadataRepository; + ICompositeRepository artifactRepo = (ICompositeRepository) destinationArtifactRepository; + + // Remove children from the Composite Repositories + for (Iterator iterator = childrenToRemove.iterator(); iterator.hasNext();) { + RepositoryDescriptor child = (RepositoryDescriptor) iterator.next(); + if (child.isArtifact() && artifactRepo != null) + artifactRepo.removeChild(child.getRepoLocation()); + if (child.isMetadata() && metadataRepo != null) + metadataRepo.removeChild(child.getRepoLocation()); + } + + // Add children to the Composite Repositories + for (Iterator iterator = childrenToAdd.iterator(); iterator.hasNext();) { + RepositoryDescriptor child = (RepositoryDescriptor) iterator.next(); + if (child.isArtifact() && artifactRepo != null) + artifactRepo.addChild(child.getRepoLocation()); + if (child.isMetadata() && metadataRepo != null) + metadataRepo.addChild(child.getRepoLocation()); + } + return Status.OK_STATUS; + } finally { + finalizeRepositories(); + } + } + + public void addChild(RepositoryDescriptor child) { + childrenToAdd.add(child); + } + + public void removeChild(RepositoryDescriptor child) { + childrenToRemove.add(child); + } + + public void setFailOnExists(boolean value) { + failOnExists = value; + } + + protected IArtifactRepository initializeDestination(RepositoryDescriptor toInit, IArtifactRepositoryManager mgr) throws ProvisionException { + // remove the repo first. + mgr.removeRepository(toInit.getRepoLocation()); + + // first try and load to see if one already exists at that location. + try { + IArtifactRepository repository = mgr.loadRepository(toInit.getRepoLocation(), null); + if (validRepositoryLocation(repository) && initDestinationRepository(repository, toInit)) + return repository; + throw new ProvisionException(new Status(IStatus.INFO, Activator.ID, NLS.bind(Messages.CompositeRepository_composite_repository_exists, toInit.getRepoLocation()))); + } catch (ProvisionException e) { + // re-throw the exception if we got anything other than "repo not found" + if (e.getStatus().getCode() != ProvisionException.REPOSITORY_NOT_FOUND) { + if (e.getCause() instanceof MalformedURLException) + throw new ProvisionException(NLS.bind(Messages.exception_invalidDestination, toInit.getRepoLocation()), e.getCause()); + throw e; + } + } + + IArtifactRepository source = null; + try { + if (toInit.getFormat() != null) + source = mgr.loadRepository(toInit.getFormat(), 0, null); + } catch (ProvisionException e) { + //Ignore. + } + //This code assumes source has been successfully loaded before this point + try { + //No existing repository; create a new repository at destinationLocation but with source's attributes. + IArtifactRepository repo = mgr.createRepository(toInit.getRepoLocation(), toInit.getName() != null ? toInit.getName() : (source != null ? source.getName() : Messages.CompositeRepository_default_artifactRepo_name), IArtifactRepositoryManager.TYPE_COMPOSITE_REPOSITORY, source != null ? source.getProperties() : null); + initRepository(repo, toInit); + return repo; + } catch (IllegalStateException e) { + mgr.removeRepository(toInit.getRepoLocation()); + throw e; + } + } + + protected IMetadataRepository initializeDestination(RepositoryDescriptor toInit, IMetadataRepositoryManager mgr) throws ProvisionException { + // remove the repo first. + mgr.removeRepository(toInit.getRepoLocation()); + + // first try and load to see if one already exists at that location. + try { + IMetadataRepository repository = mgr.loadRepository(toInit.getRepoLocation(), null); + if (!validRepositoryLocation(repository) && initDestinationRepository(repository, toInit)) + throw new ProvisionException(new Status(IStatus.INFO, Activator.ID, NLS.bind(Messages.CompositeRepository_composite_repository_exists, toInit.getRepoLocation()))); + return repository; + } catch (ProvisionException e) { + // re-throw the exception if we got anything other than "repo not found" + if (e.getStatus().getCode() != ProvisionException.REPOSITORY_NOT_FOUND) { + if (e.getCause() instanceof MalformedURLException) + throw new ProvisionException(NLS.bind(Messages.exception_invalidDestination, toInit.getRepoLocation()), e.getCause()); + throw e; + } + } + + IMetadataRepository source = null; + try { + if (toInit.getFormat() != null) + source = mgr.loadRepository(toInit.getFormat(), 0, null); + } catch (ProvisionException e) { + //Ignore + } + //This code assumes source has been successfully loaded before this point + try { + //No existing repository; create a new repository at destinationLocation but with source's attributes. + IMetadataRepository repo = mgr.createRepository(toInit.getRepoLocation(), toInit.getName() != null ? toInit.getName() : (source != null ? source.getName() : Messages.CompositeRepository_default_metadataRepo_name), IMetadataRepositoryManager.TYPE_COMPOSITE_REPOSITORY, source != null ? source.getProperties() : null); + initRepository(repo, toInit); + return repo; + } catch (IllegalStateException e) { + mgr.removeRepository(toInit.getRepoLocation()); + throw e; + } + } + + /* + * Determine if the repository is valid for this operation + */ + private boolean validRepositoryLocation(IRepository repository) throws ProvisionException { + if (repository instanceof ICompositeRepository) { + // if we have an already existing repository at that location, then throw an error + // if the user told us to + if (failOnExists) + throw new ProvisionException(NLS.bind(Messages.CompositeRepository_composite_repository_exists, repository.getLocation())); + RepositoryHelper.validDestinationRepository(repository); + return true; + } + // we have a non-composite repo at this location. that is ok because we can co-exist. + return true; + } + + /* + * Initialize a new repository + */ + private void initRepository(IRepository repository, RepositoryDescriptor desc) { + RepositoryHelper.validDestinationRepository(repository); + if (desc.isCompressed() && !repository.getProperties().containsKey(IRepository.PROP_COMPRESSED)) + repository.setProperty(IRepository.PROP_COMPRESSED, String.valueOf(true)); + } +} diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/Messages.java b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/Messages.java index 43e2f1374..e708b52c0 100644 --- a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/Messages.java +++ b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/Messages.java @@ -20,6 +20,41 @@ public class Messages extends NLS { public static String exception_noEngineService; public static String exception_needIUsOrNonEmptyRepo; public static String exception_needDestinationRepo; + public static String exception_onlyOneComparator; + + public static String AbstractApplication_no_valid_destinations; + + public static String AbstractRepositoryTask_unableToFind; + + public static String CompositeRepository_composite_repository_exists; + public static String CompositeRepository_create_colocated_composite_repos; + public static String CompositeRepository_creating_composite_repositories; + public static String CompositeRepository_default_artifactRepo_name; + public static String CompositeRepository_default_metadataRepo_name; + + public static String no_valid_IUs; + public static String no_artifactRepo_manager; + public static String no_metadataRepo_manager; + public static String no_package_admin; + public static String no_profile_registry; + public static String unable_to_process_uri; + public static String unable_to_start_exemplarysetup; + public static String unknown_repository_type; + + public static String MirrorApplication_no_IUs; + public static String MirrorApplication_set_source_repositories; + + public static String ProcessRepo_location_not_url; + public static String ProcessRepo_must_be_local; + + public static String Repo2Runnable_no_destination_repository; + public static String Repo2Runnable_no_engine; + + public static String Repo2RunnableTask_error_transforming_repository; + + public static String SlicingOption_invalid_platform; + public static String exception_invalidDestination; + public static String exception_invalidSource; static { // initialize resource bundles diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/MirrorApplication.java b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/MirrorApplication.java index bea81c67d..d02323a81 100644 --- a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/MirrorApplication.java +++ b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/MirrorApplication.java @@ -10,45 +10,73 @@ *******************************************************************************/ package org.eclipse.equinox.p2.internal.repository.tools; +import java.io.File; +import java.net.URI; import java.util.ArrayList; import java.util.Iterator; import org.eclipse.core.runtime.*; import org.eclipse.equinox.app.IApplication; import org.eclipse.equinox.app.IApplicationContext; -import org.eclipse.equinox.internal.p2.artifact.mirror.Mirroring; +import org.eclipse.equinox.internal.p2.artifact.mirror.*; +import org.eclipse.equinox.internal.p2.core.helpers.LogHelper; import org.eclipse.equinox.internal.p2.director.PermissiveSlicer; +import org.eclipse.equinox.internal.provisional.p2.artifact.repository.IArtifactRepository; import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException; import org.eclipse.equinox.internal.provisional.p2.metadata.IArtifactKey; import org.eclipse.equinox.internal.provisional.p2.metadata.IInstallableUnit; import org.eclipse.equinox.internal.provisional.p2.metadata.query.InstallableUnitQuery; +import org.eclipse.equinox.internal.provisional.p2.metadata.repository.IMetadataRepository; import org.eclipse.equinox.internal.provisional.p2.query.Collector; import org.eclipse.equinox.internal.provisional.p2.query.IQueryable; public class MirrorApplication extends AbstractApplication { + private static final String LOG_ROOT = "p2.mirror"; //$NON-NLS-1$ + protected SlicingOptions slicingOptions = new SlicingOptions(); + private URI baseline; + private String comparatorID; + private boolean compare = false; + private boolean failOnError = true; + private boolean raw = true; + private boolean verbose = false; + private boolean validate = false; + + private File mirrorLogFile; // file to log mirror output to (optional) + private File comparatorLogFile; // file to comparator output to (optional) + private IArtifactMirrorLog mirrorLog; + private IArtifactMirrorLog comparatorLog; + public Object start(IApplicationContext context) throws Exception { run(null); return IApplication.EXIT_OK; } public IStatus run(IProgressMonitor monitor) throws ProvisionException { + IStatus mirrorStatus = Status.OK_STATUS; try { validate(); initializeRepos(new NullProgressMonitor()); + initializeIUs(); IQueryable slice = slice(new NullProgressMonitor()); - IStatus mirrorStatus = mirrorArtifacts(slice, new NullProgressMonitor()); - if (mirrorStatus.getSeverity() == IStatus.ERROR) { - return mirrorStatus; + if (destinationArtifactRepository != null) { + initializeLogs(); + mirrorStatus = mirrorArtifacts(slice, new NullProgressMonitor()); + if (mirrorStatus.getSeverity() == IStatus.ERROR) + return mirrorStatus; } - mirrorMetadata(slice, new NullProgressMonitor()); + if (destinationMetadataRepository != null) + mirrorMetadata(slice, new NullProgressMonitor()); } finally { finalizeRepositories(); + finalizeLogs(); } - return Status.OK_STATUS; + if (mirrorStatus.isOK()) + return Status.OK_STATUS; + return mirrorStatus; } - private IStatus mirrorArtifacts(IQueryable slice, IProgressMonitor monitor) { + private IStatus mirrorArtifacts(IQueryable slice, IProgressMonitor monitor) throws ProvisionException { Collector ius = slice.query(InstallableUnitQuery.ANY, new Collector(), monitor); ArrayList keys = new ArrayList(ius.size()); for (Iterator iterator = ius.iterator(); iterator.hasNext();) { @@ -58,9 +86,33 @@ public class MirrorApplication extends AbstractApplication { keys.add(iuKeys[i]); } } - Mirroring mirror = new Mirroring(getCompositeArtifactRepository(), destinationArtifactRepository, true); - mirror.setArtifactKeys((IArtifactKey[]) keys.toArray(new IArtifactKey[keys.size()])); - return mirror.run(true, false); + Mirroring mirror = new Mirroring(getCompositeArtifactRepository(), destinationArtifactRepository, raw); + + mirror.setCompare(compare); + mirror.setComparatorId(comparatorID); + mirror.setBaseline(initializeBaseline()); + mirror.setValidate(validate); + + // If IUs have been specified then only they should be mirrored, otherwise mirror everything. + if (keys.size() > 0) + mirror.setArtifactKeys((IArtifactKey[]) keys.toArray(new IArtifactKey[keys.size()])); + + if (comparatorLog != null) + mirror.setComparatorLog(comparatorLog); + + IStatus result = mirror.run(failOnError, verbose); + + if (mirrorLog != null) + mirrorLog.log(result); + else + LogHelper.log(result); + return result; + } + + private IArtifactRepository initializeBaseline() throws ProvisionException { + if (baseline == null) + return null; + return addRepository(Activator.getArtifactRepositoryManager(), baseline, 0, null); } private void mirrorMetadata(IQueryable slice, IProgressMonitor monitor) { @@ -75,21 +127,145 @@ public class MirrorApplication extends AbstractApplication { * to add more if they wish) */ private void validate() throws ProvisionException { - if (sourceMetadataRepositories == null) - throw new ProvisionException("Need to set the source metadata repository location."); - if (sourceIUs == null) - throw new ProvisionException("Mirroring root needs to be specified."); - //TODO Check that the IU is in repo + if (sourceRepositories.isEmpty()) + throw new ProvisionException(Messages.MirrorApplication_set_source_repositories); + } + + /* + * If no IUs have been specified we want to mirror them all + */ + private void initializeIUs() throws ProvisionException { + if (sourceIUs == null || sourceIUs.isEmpty()) { + sourceIUs = new ArrayList(); + IMetadataRepository metadataRepo = getCompositeMetadataRepository(); + Collector collector = metadataRepo.query(InstallableUnitQuery.ANY, new Collector(), null); + + for (Iterator iter = collector.iterator(); iter.hasNext();) { + IInstallableUnit iu = (IInstallableUnit) iter.next(); + sourceIUs.add(iu); + } + + if (collector.size() == 0 && destinationMetadataRepository != null) { + throw new ProvisionException(Messages.MirrorApplication_no_IUs); + } + } else { + //TODO Check that the IU is in repo + } + } + + /* + * Initialize logs, if applicable + */ + private void initializeLogs() { + if (compare && comparatorLogFile != null) + comparatorLog = getLog(comparatorLogFile, comparatorID); + if (mirrorLog == null && mirrorLogFile != null) + mirrorLog = getLog(mirrorLogFile, LOG_ROOT); + } + + /* + * Finalize logs, if applicable + */ + private void finalizeLogs() { + if (comparatorLog != null) + comparatorLog.close(); + if (mirrorLog != null) + mirrorLog.close(); } - private IQueryable slice(IProgressMonitor monitor) { + /* + * Get the log for a location + */ + private IArtifactMirrorLog getLog(File location, String root) { + String absolutePath = location.getAbsolutePath(); + if (absolutePath.toLowerCase().endsWith(".xml")) //$NON-NLS-1$ + return new XMLMirrorLog(absolutePath, 0, root); + return new FileMirrorLog(absolutePath, 0, root); + } + + private IQueryable slice(IProgressMonitor monitor) throws ProvisionException { if (slicingOptions == null) slicingOptions = new SlicingOptions(); PermissiveSlicer slicer = new PermissiveSlicer(getCompositeMetadataRepository(), slicingOptions.getFilter(), slicingOptions.includeOptionalDependencies(), slicingOptions.isEverythingGreedy(), slicingOptions.forceFilterTo(), slicingOptions.considerStrictDependencyOnly()); - return slicer.slice((IInstallableUnit[]) sourceIUs.toArray(new IInstallableUnit[sourceIUs.size()]), monitor); + IQueryable slice = slicer.slice((IInstallableUnit[]) sourceIUs.toArray(new IInstallableUnit[sourceIUs.size()]), monitor); + if (slice == null) + throw new ProvisionException(slicer.getStatus()); + return slice; } public void setSlicingOptions(SlicingOptions options) { slicingOptions = options; } + + /* + * Set the location of the baseline repository. (used in comparison) + */ + public void setBaseline(URI baseline) { + this.baseline = baseline; + compare = true; + } + + /* + * Set the identifier of the comparator to use. + */ + public void setComparatorID(String value) { + comparatorID = value; + compare = true; + } + + /* + * Set whether or not the application should be calling a comparator when mirroring. + */ + public void setCompare(boolean value) { + compare = value; + } + + /* + * Set whether or not we should ignore errors when running the mirror application. + */ + public void setIgnoreErrors(boolean value) { + failOnError = !value; + } + + /* + * Set whether or not the the artifacts are raw. + */ + public void setRaw(boolean value) { + raw = value; + } + + /* + * Set whether or not the mirror application should be run in verbose mode. + */ + public void setVerbose(boolean value) { + verbose = value; + } + + /* + * Set the location of the log for comparator output + */ + public void setComparatorLog(File comparatorLog) { + this.comparatorLogFile = comparatorLog; + } + + /* + * Set the location of the log for mirroring. + */ + public void setLog(File mirrorLog) { + this.mirrorLogFile = mirrorLog; + } + + /* + * Set the ArtifactMirror log + */ + public void setLog(IArtifactMirrorLog log) { + mirrorLog = log; + } + + /* + * Set if the artifact mirror should be validated + */ + public void setValidate(boolean value) { + validate = value; + } } diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/Repo2Runnable.java b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/Repo2Runnable.java index 5c77f1d76..b04f3ff7a 100644 --- a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/Repo2Runnable.java +++ b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/Repo2Runnable.java @@ -10,7 +10,6 @@ *******************************************************************************/ package org.eclipse.equinox.p2.internal.repository.tools; -import java.net.URI; import java.net.URISyntaxException; import java.util.*; import org.eclipse.core.runtime.*; @@ -27,7 +26,6 @@ import org.eclipse.equinox.internal.provisional.p2.metadata.IArtifactKey; import org.eclipse.equinox.internal.provisional.p2.metadata.IInstallableUnit; import org.eclipse.equinox.internal.provisional.p2.metadata.query.InstallableUnitQuery; import org.eclipse.equinox.internal.provisional.p2.metadata.repository.IMetadataRepository; -import org.eclipse.equinox.internal.provisional.p2.metadata.repository.IMetadataRepositoryManager; import org.eclipse.equinox.internal.provisional.p2.query.Collector; /** @@ -165,11 +163,11 @@ public class Repo2Runnable extends AbstractApplication implements IApplication { return; } // get all IUs from the repos - if (sourceMetadataRepositories == null || sourceMetadataRepositories.isEmpty()) + if (!hasMetadataSources()) throw new ProvisionException(Messages.exception_needIUsOrNonEmptyRepo); - for (Iterator iter = sourceMetadataRepositories.iterator(); iter.hasNext();) { - processedIUs.addAll(getAllIUs((URI) iter.next(), monitor).toCollection()); - } + + processedIUs.addAll(getAllIUs(getCompositeMetadataRepository(), monitor).toCollection()); + if (processedIUs.isEmpty()) throw new ProvisionException(Messages.exception_needIUsOrNonEmptyRepo); } @@ -188,15 +186,13 @@ public class Repo2Runnable extends AbstractApplication implements IApplication { /* * Return a collector over all the IUs contained in the given repository. */ - private Collector getAllIUs(URI location, IProgressMonitor monitor) throws ProvisionException { + private Collector getAllIUs(IMetadataRepository repository, IProgressMonitor monitor) { SubMonitor progress = SubMonitor.convert(monitor, 2); - IMetadataRepositoryManager manager = Activator.getMetadataRepositoryManager(); - if (!manager.contains(location)) - metadataReposToRemove.add(location); - IMetadataRepository repository = manager.loadRepository(location, progress.newChild(1)); - Collector result = new Collector(); - repository.query(InstallableUnitQuery.ANY, result, progress.newChild(1)).iterator(); - return result; + try { + return repository.query(InstallableUnitQuery.ANY, new Collector(), progress.newChild(1)); + } finally { + progress.done(); + } } /* @@ -242,19 +238,15 @@ public class Repo2Runnable extends AbstractApplication implements IApplication { String arg = args[++i]; if (option.equalsIgnoreCase("-source")) { //$NON-NLS-1$ - addSourceArtifactRepository(arg); - addSourceMetadataRepository(arg); + RepositoryDescriptor source = new RepositoryDescriptor(); + source.setLocation(URIUtil.fromString(arg)); + addSource(source); } if (option.equalsIgnoreCase("-destination")) { //$NON-NLS-1$ - RepositoryDescriptor artifact = new RepositoryDescriptor(); - artifact.setLocation(URIUtil.fromString(arg)); - artifact.setKind("A"); //$NON-NLS-1$ - addDestination(artifact); - RepositoryDescriptor metadata = new RepositoryDescriptor(); - metadata.setLocation(URIUtil.fromString(arg)); - metadata.setKind("M"); //$NON-NLS-1$ - addDestination(metadata); + RepositoryDescriptor destination = new RepositoryDescriptor(); + destination.setLocation(URIUtil.fromString(arg)); + addDestination(destination); } } } @@ -266,7 +258,7 @@ public class Repo2Runnable extends AbstractApplication implements IApplication { * to add more if they wish) */ private void validate() throws ProvisionException { - if (sourceMetadataRepositories == null && sourceIUs == null) + if (!hasMetadataSources() && sourceIUs == null) throw new ProvisionException(Messages.exception_needIUsOrNonEmptyRepo); if (destinationArtifactRepository == null) throw new ProvisionException(Messages.exception_needDestinationRepo); diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/RepositoryDescriptor.java b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/RepositoryDescriptor.java index a93f05f85..0ae76a135 100644 --- a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/RepositoryDescriptor.java +++ b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/RepositoryDescriptor.java @@ -10,18 +10,23 @@ *******************************************************************************/ package org.eclipse.equinox.p2.internal.repository.tools; -import org.eclipse.equinox.internal.provisional.p2.repository.IRepository; - import java.net.URI; +import org.eclipse.equinox.internal.p2.repository.helpers.RepositoryHelper; +import org.eclipse.equinox.internal.provisional.p2.repository.IRepository; +import org.eclipse.osgi.util.NLS; public class RepositoryDescriptor { + public static final int TYPE_BOTH = -1; + public static final String KIND_ARTIFACT = "A"; //$NON-NLS-1$ + public static final String KIND_METADATA = "M"; //$NON-NLS-1$ + private boolean compressed = true; private boolean append = true; private String name = null; private URI location = null; - private String format = null; - private int kind; + private URI format = null; + private int kind = TYPE_BOTH; public void setCompressed(boolean compress) { compressed = compress; @@ -32,11 +37,11 @@ public class RepositoryDescriptor { } public void setLocation(URI repoLocation) { - location = repoLocation; + location = RepositoryHelper.localRepoURIHelper(repoLocation); } - public void setFormat(String format) { - this.format = format; + public void setFormat(URI format) { + this.format = RepositoryHelper.localRepoURIHelper(format); } public void setAppend(boolean appendMode) { @@ -59,7 +64,7 @@ public class RepositoryDescriptor { return location; } - public String getFormat() { + public URI getFormat() { return format; } @@ -67,11 +72,38 @@ public class RepositoryDescriptor { return kind; } + public boolean isBoth() { + return kind == TYPE_BOTH; + } + + public boolean isArtifact() { + return kind == TYPE_BOTH || kind == IRepository.TYPE_ARTIFACT; + } + + public boolean isMetadata() { + return kind == TYPE_BOTH || kind == IRepository.TYPE_METADATA; + } + public void setKind(String repoKind) { - if (repoKind.startsWith("m") || repoKind.startsWith("M")) //$NON-NLS-1$//$NON-NLS-2$ - kind = IRepository.TYPE_METADATA; + kind = determineKind(repoKind); + } + + /* + * Determine the repository type + */ + public static int determineKind(String repoKind) { + if (kindMatches(repoKind, KIND_METADATA)) + return IRepository.TYPE_METADATA; + else if (kindMatches(repoKind, KIND_ARTIFACT)) + return IRepository.TYPE_ARTIFACT; + + throw new IllegalArgumentException(NLS.bind(Messages.unknown_repository_type, repoKind)); + } - if (repoKind.startsWith("a") || repoKind.startsWith("A")) //$NON-NLS-1$//$NON-NLS-2$ - kind = IRepository.TYPE_ARTIFACT; + /* + * Determine if the repository kind matches the identifier kind + */ + public static boolean kindMatches(String repoKind, String kindIdentifier) { + return repoKind.startsWith(kindIdentifier) || repoKind.startsWith(kindIdentifier.toLowerCase()); } } diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/messages.properties b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/messages.properties index 111d5931e..0e0a8162d 100644 --- a/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/messages.properties +++ b/bundles/org.eclipse.equinox.p2.repository.tools/src/org/eclipse/equinox/p2/internal/repository/tools/messages.properties @@ -8,10 +8,38 @@ # Contributors: # IBM Corporation - initial API and implementation ############################################################################### -exception_destinationNotModifiable = The destination repository must be modifiable: {0}. +AbstractApplication_no_valid_destinations=Unable to locate a valid destination repository. +AbstractRepositoryTask_unableToFind=Unable to find: {0} + +CompositeRepository_default_metadataRepo_name=Composite Metadata Repository +CompositeRepository_default_artifactRepo_name=Composite Artifact Repository +CompositeRepository_create_colocated_composite_repos=Creating co-located composite repositories. +CompositeRepository_composite_repository_exists=Composite repository already exists at location: {0} +CompositeRepository_creating_composite_repositories=Creating Composite Repositories +CompositeRepository_default_artifactRepo_name=Composite Artifact Repository +CompositeRepository_default_metadataRepo_name=Composite Artifact Repository + +no_valid_IUs=Need to specify either a non-empty source metadata repository or a valid list of IUs. +no_artifactRepo_manager=Unable to acquire artifact repository manager service. +no_metadataRepo_manager=Unable to acquire metadata repository manager service. +no_package_admin=Unable to acquire package admin service. +no_profile_registry=Unable to acquire profile registry service. +unable_to_process_uri=Unable to process as URI: {0} +unable_to_start_exemplarysetup=Unable to start exemplarysetup bundle. +unknown_repository_type=Repository is of an unknown type: {0} +MirrorApplication_no_IUs=No IUs specified and no IUs obtained from metadata repositories. +MirrorApplication_set_source_repositories=Need to set the source repository location(s). +ProcessRepo_location_not_url=Repository location {0} must be a URL. +ProcessRepo_must_be_local=Repository must be local: {0} + +SlicingOption_invalid_platform=Invalid platform filter format: {0}. +exception_destinationNotModifiable = The destination repository must be modifiable: {0}. +exception_invalidDestination=Invalid destination repository location: {0}. +exception_invalidSource=Invalid source repository location: {0}. exception_unableToRemoveRepo=Unable to remove artifact repository file: {0}. exception_notLocalFileRepo= {0} is not a local file based repository. exception_noEngineService=Unable to acquire engine service. exception_needIUsOrNonEmptyRepo=Need to specify either a non-empty source metadata repository or a valid list of IUs. -exception_needDestinationRepo=Need to set the destination artifact repository location.
\ No newline at end of file +exception_needDestinationRepo=Need to set the destination artifact repository location. +exception_onlyOneComparator=Only one comparator should be defined.
\ No newline at end of file diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/AbstractRepositoryTask.java b/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/AbstractRepositoryTask.java index 149cb7a56..59f8a2f46 100644 --- a/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/AbstractRepositoryTask.java +++ b/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/AbstractRepositoryTask.java @@ -16,12 +16,14 @@ import java.net.URISyntaxException; import java.util.*; import org.apache.tools.ant.*; import org.apache.tools.ant.types.FileSet; -import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.URIUtil; +import org.eclipse.equinox.internal.p2.artifact.repository.ant.AntMirrorLog; import org.eclipse.equinox.internal.provisional.p2.metadata.repository.IMetadataRepository; import org.eclipse.equinox.internal.provisional.p2.query.Collector; import org.eclipse.equinox.internal.provisional.p2.query.Query; -import org.eclipse.equinox.p2.internal.repository.tools.AbstractApplication; +import org.eclipse.equinox.p2.internal.repository.tools.*; +import org.eclipse.osgi.util.NLS; public abstract class AbstractRepositoryTask extends Task { protected static final String ANT_PREFIX = "${"; //$NON-NLS-1$ @@ -30,21 +32,18 @@ public abstract class AbstractRepositoryTask extends Task { protected List sourceRepos = new ArrayList(); protected List destinations = new ArrayList(); - /* - * Create a special file set since the user specified a "source" sub-element. - */ - public FileSet createSource() { - MyFileSet set = new MyFileSet(); - sourceRepos.add(set); - return set; - } - protected void addMetadataSourceRepository(URI repoLocation) { - application.addSourceMetadataRepository(repoLocation); + RepositoryDescriptor source = new RepositoryDescriptor(); + source.setLocation(repoLocation); + source.setKind(RepositoryDescriptor.KIND_METADATA); + application.addSource(source); } protected void addArtifactSourceRepository(URI repoLocation) { - application.addSourceArtifactRepository(repoLocation); + RepositoryDescriptor source = new RepositoryDescriptor(); + source.setLocation(repoLocation); + source.setKind(RepositoryDescriptor.KIND_ARTIFACT); + application.addSource(source); } /* @@ -61,8 +60,13 @@ public abstract class AbstractRepositoryTask extends Task { * argument to specify both the artifact and metadata repositories. */ public void setSource(String location) { - application.addSourceArtifactRepository(location); - application.addSourceMetadataRepository(location); + RepositoryDescriptor source = new RepositoryDescriptor(); + try { + source.setLocation(URIUtil.fromString(location)); + application.addSource(source); + } catch (URISyntaxException e) { + throw new BuildException(e); + } } /* @@ -70,20 +74,15 @@ public abstract class AbstractRepositoryTask extends Task { * argument to specify both the artifact and metadata repositories. */ public void setDestination(String location) { - DestinationRepository metadata = new DestinationRepository(); - metadata.setLocation(URIUtil.toUnencodedString(new Path(location).toFile().toURI())); - metadata.setKind("metadata"); //$NON-NLS-1$ - application.addDestination(metadata.getDescriptor()); - destinations.add(metadata); - - DestinationRepository artifact = new DestinationRepository(); - artifact.setLocation(URIUtil.toUnencodedString(new Path(location).toFile().toURI())); - metadata.setKind("artifact"); //$NON-NLS-1$ - application.addDestination(artifact.getDescriptor()); - destinations.add(artifact); + // TODO depreciate + DestinationRepository dest = new DestinationRepository(); + dest.setLocation(location); + destinations.add(dest); + application.addDestination(dest.getDescriptor()); } public DestinationRepository createDestination() { + // TODO depreciate DestinationRepository destination = new DestinationRepository(); destinations.add(destination); application.addDestination(destination.getDescriptor()); @@ -91,17 +90,28 @@ public abstract class AbstractRepositoryTask extends Task { } /* - * New FileSet subclass which adds an optional "location" attribute. + * Add a repository to mirror into */ - public class MyFileSet extends FileSet { - String location; + public DestinationRepository createRepository() { + DestinationRepository destination = new DestinationRepository(); + destinations.add(destination); + application.addDestination(destination.getDescriptor()); + return destination; + } - public MyFileSet() { - super(); + /* + * Add source repositories to mirror from + */ + public void addConfiguredSource(RepositoryList sourceList) { + for (Iterator iter = sourceList.getRepositoryList().iterator(); iter.hasNext();) { + DestinationRepository repo = (DestinationRepository) iter.next(); + application.addSource(repo.getDescriptor()); } - public void setLocation(String value) { - this.location = value; + for (Iterator iter = sourceList.getFileSetList().iterator(); iter.hasNext();) { + FileSet fileSet = (FileSet) iter.next(); + sourceRepos.add(fileSet); + // Added to the application later through prepareSourceRepos } } @@ -113,38 +123,39 @@ public abstract class AbstractRepositoryTask extends Task { if (sourceRepos == null || sourceRepos.isEmpty()) return; for (Iterator iter = sourceRepos.iterator(); iter.hasNext();) { - Object next = iter.next(); - if (next instanceof MyFileSet) { - MyFileSet fileset = (MyFileSet) next; - // determine if the user set a "location" attribute or used a fileset - if (fileset.location == null) { - DirectoryScanner scanner = fileset.getDirectoryScanner(getProject()); - String[][] elements = new String[][] {scanner.getIncludedDirectories(), scanner.getIncludedFiles()}; - for (int i = 0; i < 2; i++) { - for (int j = 0; j < elements[i].length; j++) { - File file = new File(fileset.getDir(), elements[i][j]); - URI uri = file.toURI(); - - if (file.isFile() && file.getName().endsWith(".zip")) { //$NON-NLS-1$ - try { - uri = new URI("jar:" + uri.toString() + "!/"); //$NON-NLS-1$ //$NON-NLS-2$ - } catch (URISyntaxException e) { - //? - continue; - } - } - application.addSourceArtifactRepository(uri); - application.addSourceMetadataRepository(uri); + RepositoryFileSet fileset = (RepositoryFileSet) iter.next(); + + if (fileset.getRepoLocation() != null) { + //TODO depreciate + if (!fileset.getRepoLocation().startsWith(ANT_PREFIX)) { + addArtifactSourceRepository(fileset.getRepoLocationURI()); + addMetadataSourceRepository(fileset.getRepoLocationURI()); + } + } else if (fileset.getDir() != null) { + DirectoryScanner scanner = fileset.getDirectoryScanner(getProject()); + String[][] elements = new String[][] {scanner.getIncludedDirectories(), scanner.getIncludedFiles()}; + for (int i = 0; i < 2; i++) { + for (int j = 0; j < elements[i].length; j++) { + File file = new File(fileset.getDir(), elements[i][j]); + URI uri = file.toURI(); + + if (file.isFile() && file.getName().endsWith(".zip")) { //$NON-NLS-1$ + uri = URIUtil.toJarURI(uri, null); } - } - } else { - if (!fileset.location.startsWith(ANT_PREFIX)) { - application.addSourceArtifactRepository(fileset.location); - application.addSourceMetadataRepository(fileset.location); + if (fileset.isBoth()) { + addArtifactSourceRepository(uri); + addMetadataSourceRepository(uri); + } else if (fileset.isArtifact()) + addArtifactSourceRepository(uri); + else if (fileset.isMetadata()) + addMetadataSourceRepository(uri); + else + throw new BuildException(NLS.bind(Messages.unknown_repository_type, uri)); } } } } + sourceRepos.clear(); } protected List prepareIUs() { @@ -161,9 +172,17 @@ public abstract class AbstractRepositoryTask extends Task { repository.query(iuQuery, collector, null); if (iu.isRequired() && collector.isEmpty()) - throw new BuildException("Unable to find: " + iu.toString()); //$NON-NLS-1$ + throw new BuildException(NLS.bind(Messages.AbstractRepositoryTask_unableToFind, iu.toString())); result.addAll(collector.toCollection()); } return result; } + + protected void log(IStatus status) { + try { + new AntMirrorLog(this).log(status); + } catch (NoSuchMethodException e) { + // Shouldn't occur + } + } } diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/ComparatorDescription.java b/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/ComparatorDescription.java new file mode 100644 index 000000000..9ec3fc38b --- /dev/null +++ b/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/ComparatorDescription.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2009 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.equinox.p2.internal.repository.tools.tasks; + +import java.io.File; +import org.apache.tools.ant.types.DataType; + +public class ComparatorDescription extends DataType { + + DestinationRepository baseline; + String comparatorId; + File comparatorLog; + + /* + * Set the baseline repository to compare to + */ + public void addRepository(DestinationRepository value) { + this.baseline = value; + } + + /* + * Set the comparator to use + */ + public void setComparator(String value) { + comparatorId = value; + } + + /* + * Set the log location for the comparator + */ + public void setComparatorLog(File value) { + comparatorLog = value; + } + + public DestinationRepository getBaseline() { + return baseline; + } + + public String getComparator() { + return comparatorId; + } + + public File getComparatorLog() { + return comparatorLog; + } +} diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/CompositeRepositoryTask.java b/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/CompositeRepositoryTask.java new file mode 100644 index 000000000..ec674dcc4 --- /dev/null +++ b/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/CompositeRepositoryTask.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2009 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.equinox.p2.internal.repository.tools.tasks; + +import java.util.Iterator; +import org.apache.tools.ant.BuildException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException; +import org.eclipse.equinox.p2.internal.repository.tools.CompositeRepositoryApplication; + +public class CompositeRepositoryTask extends AbstractRepositoryTask { + + public CompositeRepositoryTask() { + application = new CompositeRepositoryApplication(); + } + + /* (non-Javadoc) + * @see org.apache.tools.ant.Task#execute() + */ + public void execute() throws BuildException { + try { + IStatus result = application.run(null); + if (result.matches(IStatus.ERROR)) { + throw new BuildException(TaskHelper.statusToString(result, null).toString()); + } + } catch (ProvisionException e) { + throw new BuildException(e); + } + } + + /* + * Add the listed repositories to the composite repository + */ + public void addConfiguredAdd(RepositoryList list) { + for (Iterator iter = list.getRepositoryList().iterator(); iter.hasNext();) { + DestinationRepository repo = (DestinationRepository) iter.next(); + ((CompositeRepositoryApplication) application).addChild(repo.getDescriptor()); + } + } + + /* + * Remove the listed repositories from the composite repository + */ + public void addConfiguredRemove(RepositoryList list) { + for (Iterator iter = list.getRepositoryList().iterator(); iter.hasNext();) { + DestinationRepository repo = (DestinationRepository) iter.next(); + ((CompositeRepositoryApplication) application).removeChild(repo.getDescriptor()); + } + } + + /* + * Set whether the task should fail if the repository already exists + */ + public void setFailOnExists(boolean value) { + ((CompositeRepositoryApplication) application).setFailOnExists(value); + } +} diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/DestinationRepository.java b/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/DestinationRepository.java index 351529930..71602d595 100644 --- a/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/DestinationRepository.java +++ b/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/DestinationRepository.java @@ -36,8 +36,12 @@ public class DestinationRepository extends DataType { } } - public void setFormat(String format) { - descriptor.setFormat(format); + public void setFormat(String formatLocation) { + try { + descriptor.setFormat(URIUtil.fromString(formatLocation)); + } catch (URISyntaxException e) { + throw new BuildException(e); + } } public void setAppend(boolean appendMode) { diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/MirrorTask.java b/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/MirrorTask.java index 06699c1a5..fceaaf32a 100644 --- a/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/MirrorTask.java +++ b/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/MirrorTask.java @@ -10,32 +10,57 @@ *******************************************************************************/ package org.eclipse.equinox.p2.internal.repository.tools.tasks; +import java.io.File; import java.util.List; import org.apache.tools.ant.BuildException; import org.eclipse.core.runtime.IStatus; +import org.eclipse.equinox.internal.p2.artifact.repository.ant.AntMirrorLog; import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException; +import org.eclipse.equinox.p2.internal.repository.tools.Messages; import org.eclipse.equinox.p2.internal.repository.tools.MirrorApplication; public class MirrorTask extends AbstractRepositoryTask { + private File mirrorLog; // file to log mirror output to (optional) + private ComparatorDescription comparator; + public MirrorTask() { application = new MirrorApplication(); } public void execute() throws BuildException { try { + if (mirrorLog != null) + ((MirrorApplication) application).setLog(mirrorLog); + else + ((MirrorApplication) application).setLog(new AntMirrorLog(this)); + + if (comparator != null) { + // Enable comparison + ((MirrorApplication) application).setCompare(true); + // Set baseline location + if (comparator.getBaseline() != null) + ((MirrorApplication) application).setBaseline(comparator.getBaseline().getDescriptor().getRepoLocation()); + // Set comparator to use + if (comparator.getComparator() != null) + ((MirrorApplication) application).setComparatorID(comparator.getComparator()); + // Set comparator log + if (comparator.getComparatorLog() != null) + ((MirrorApplication) application).setComparatorLog(comparator.getComparatorLog()); + } + prepareSourceRepos(); application.initializeRepos(null); List ius = prepareIUs(); - if (ius == null || ius.size() == 0) - throw new BuildException("Need to specify one or more IUs to mirror."); application.setSourceIUs(ius); IStatus result = application.run(null); - if (result.matches(IStatus.ERROR)) { + if (result.matches(IStatus.ERROR)) throw new BuildException(TaskHelper.statusToString(result, null).toString()); - } } catch (ProvisionException e) { throw new BuildException(e); + } catch (NoSuchMethodException e) { + // Should not occur + throw new BuildException(e); } } @@ -44,4 +69,46 @@ public class MirrorTask extends AbstractRepositoryTask { ((MirrorApplication) application).setSlicingOptions(options.getOptions()); return options; } + + /* + * Set the comparison information + */ + public ComparatorDescription createComparator() { + if (comparator != null) + throw new BuildException(Messages.exception_onlyOneComparator); + comparator = new ComparatorDescription(); + return comparator; + } + + /* + * Set the location of the mirror log + */ + public void setLog(String value) { + mirrorLog = new File(value); + } + + /* + * Set whether or not we should ignore errors when running the mirror application. + */ + public void setIgnoreErrors(boolean value) { + ((MirrorApplication) application).setIgnoreErrors(value); + } + + /* + * Set whether or not the the artifacts are raw. + */ + public void setRaw(boolean value) { + ((MirrorApplication) application).setRaw(value); + } + + /* + * Set whether or not the mirror application should be run in verbose mode. + */ + public void setVerbose(boolean value) { + ((MirrorApplication) application).setVerbose(value); + } + + public void setValidate(boolean value) { + ((MirrorApplication) application).setValidate(value); + } } diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/ProcessRepoTask.java b/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/ProcessRepoTask.java index 9415092c5..9e8947335 100644 --- a/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/ProcessRepoTask.java +++ b/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/ProcessRepoTask.java @@ -21,8 +21,8 @@ import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.URIUtil; import org.eclipse.equinox.internal.p2.jarprocessor.ant.JarProcessorTask; import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException; -import org.eclipse.equinox.p2.internal.repository.tools.RecreateRepositoryApplication; -import org.eclipse.equinox.p2.internal.repository.tools.RepositoryDescriptor; +import org.eclipse.equinox.p2.internal.repository.tools.*; +import org.eclipse.osgi.util.NLS; public class ProcessRepoTask extends Task { @@ -64,7 +64,7 @@ public class ProcessRepoTask extends Task { public void execute() throws BuildException { File file = URIUtil.toFile(repository); if (file == null || !file.exists()) { - throw new BuildException("Repository must be local: " + repository.toString()); //$NON-NLS-1$ + throw new BuildException(NLS.bind(Messages.ProcessRepo_must_be_local, repository.toString())); } if (pack | repack | signing != null) { if (jarProcessor == null) @@ -113,7 +113,7 @@ public class ProcessRepoTask extends Task { try { this.repository = URIUtil.fromString(repository); } catch (URISyntaxException e) { - throw new IllegalArgumentException("Repository location (" + repository + ") must be a URL."); //$NON-NLS-1$ //$NON-NLS-2$ + throw new IllegalArgumentException(NLS.bind(Messages.ProcessRepo_location_not_url, repository)); } } diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/Repo2RunnableTask.java b/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/Repo2RunnableTask.java index 5c84ff036..d3fb10cdb 100644 --- a/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/Repo2RunnableTask.java +++ b/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/Repo2RunnableTask.java @@ -44,7 +44,7 @@ public class Repo2RunnableTask extends AbstractRepositoryTask { prepareSourceRepos(); application.initializeRepos(null); List ius = prepareIUs(); - if ((ius == null || ius.size() == 0) && (sourceRepos == null || sourceRepos.isEmpty())) + if ((ius == null || ius.size() == 0) && !(application.hasArtifactSources() || application.hasMetadataSources())) throw new BuildException("Need to specify either a non-empty source metadata repository or a valid list of IUs."); application.setSourceIUs(ius); IStatus result = application.run(null); diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/RepositoryFileSet.java b/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/RepositoryFileSet.java new file mode 100644 index 000000000..c7e88ddf4 --- /dev/null +++ b/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/RepositoryFileSet.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2009 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.equinox.p2.internal.repository.tools.tasks; + +import java.net.URI; +import java.net.URISyntaxException; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.types.FileSet; +import org.eclipse.core.runtime.URIUtil; +import org.eclipse.equinox.internal.p2.repository.helpers.RepositoryHelper; +import org.eclipse.equinox.internal.provisional.p2.repository.IRepository; +import org.eclipse.equinox.p2.internal.repository.tools.RepositoryDescriptor; + +public class RepositoryFileSet extends FileSet { + public final static int TYPE_ARTIFACT = IRepository.TYPE_ARTIFACT; + public final static int TYPE_METADATA = IRepository.TYPE_METADATA; + + private int kind = RepositoryDescriptor.TYPE_BOTH; + protected String myLocation = null; + + public void setKind(String repoKind) { + kind = RepositoryDescriptor.determineKind(repoKind); + } + + public int getKind() { + return kind; + } + + public boolean isBoth() { + return kind == RepositoryDescriptor.TYPE_BOTH; + } + + public boolean isArtifact() { + return kind == RepositoryDescriptor.TYPE_BOTH || kind == IRepository.TYPE_ARTIFACT; + } + + public boolean isMetadata() { + return kind == RepositoryDescriptor.TYPE_BOTH || kind == IRepository.TYPE_METADATA; + } + + public void setLocation(String value) { + // TODO depreciate + myLocation = value; + } + + public String getRepoLocation() { + // TODO depreciate + return myLocation; + } + + public URI getRepoLocationURI() { + // TODO depreciate + try { + return RepositoryHelper.localRepoURIHelper(URIUtil.fromString(getRepoLocation())); + } catch (URISyntaxException e) { + throw new BuildException(e); + } + } +} diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/RepositoryList.java b/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/RepositoryList.java new file mode 100644 index 000000000..a76d3218d --- /dev/null +++ b/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/RepositoryList.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2009 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.equinox.p2.internal.repository.tools.tasks; + +import java.util.ArrayList; +import java.util.List; + +public class RepositoryList extends RepositoryFileSet { + // TODO this class should extend DataType, currently RepoFileSet to support <source location="xxx" /> + List repositories = new ArrayList(); + List sourceFileSets = new ArrayList(); + + public DestinationRepository createRepository() { + DestinationRepository repo = new DestinationRepository(); + repositories.add(repo); + return repo; + } + + public RepositoryFileSet createFileSet() { + RepositoryFileSet fileSet = new RepositoryFileSet(); + sourceFileSets.add(fileSet); + return fileSet; + } + + public List getRepositoryList() { + return repositories; + } + + public List getFileSetList() { + //TODO this should eventually be removed + sourceFileSets.add(this); + return sourceFileSets; + } +} diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/SlicingOption.java b/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/SlicingOption.java index 50b1eb035..37d5f9089 100644 --- a/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/SlicingOption.java +++ b/bundles/org.eclipse.equinox.p2.repository.tools/src_ant/org/eclipse/equinox/p2/internal/repository/tools/tasks/SlicingOption.java @@ -13,7 +13,9 @@ package org.eclipse.equinox.p2.internal.repository.tools.tasks; import java.util.*; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; +import org.eclipse.equinox.p2.internal.repository.tools.Messages; import org.eclipse.equinox.p2.internal.repository.tools.SlicingOptions; +import org.eclipse.osgi.util.NLS; public class SlicingOption extends Task { @@ -51,7 +53,7 @@ public class SlicingOption extends Task { } StringTokenizer tok = new StringTokenizer(platformFilter, ","); //$NON-NLS-1$ if (tok.countTokens() != 3) - throw new BuildException("Invalid platform filter format: " + platformFilter + "."); + throw new BuildException(NLS.bind(Messages.SlicingOption_invalid_platform, platformFilter)); Dictionary filter = options.getFilter(); if (filter == null) filter = new Properties(); diff --git a/bundles/org.eclipse.equinox.p2.tests/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.tests/META-INF/MANIFEST.MF index d8d16c60b..eef4bcdac 100644 --- a/bundles/org.eclipse.equinox.p2.tests/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.p2.tests/META-INF/MANIFEST.MF @@ -6,6 +6,7 @@ Bundle-Vendor: %providerName Bundle-Localization: plugin Bundle-Version: 1.1.0.qualifier Import-Package: javax.xml.parsers, + org.eclipse.ant.core, org.eclipse.ecf.filetransfer, org.eclipse.equinox.internal.p2.artifact.mirror, org.eclipse.equinox.internal.p2.artifact.processors.md5, @@ -50,6 +51,7 @@ Import-Package: javax.xml.parsers, org.eclipse.equinox.internal.provisional.spi.p2.artifact.repository, org.eclipse.equinox.internal.provisional.spi.p2.metadata.repository, org.eclipse.equinox.internal.provisional.spi.p2.repository, + org.eclipse.equinox.p2.internal.repository.tools, org.eclipse.equinox.spi.p2.publisher, org.eclipse.internal.provisional.equinox.p2.jarprocessor, org.eclipse.osgi.service.datalocation, diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/AbstractAntProvisioningTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/AbstractAntProvisioningTest.java new file mode 100644 index 000000000..8cb4a2353 --- /dev/null +++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/AbstractAntProvisioningTest.java @@ -0,0 +1,263 @@ +/******************************************************************************* + * Copyright (c) 2009 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.equinox.p2.tests; + +import java.io.File; +import java.io.FileOutputStream; +import java.net.URI; +import java.util.*; +import org.eclipse.ant.core.AntRunner; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.URIUtil; +import org.eclipse.equinox.internal.p2.metadata.InstallableUnit; +import org.eclipse.equinox.internal.p2.persistence.XMLWriter; +import org.eclipse.equinox.internal.provisional.p2.artifact.repository.IArtifactRepository; +import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException; +import org.eclipse.equinox.internal.provisional.p2.metadata.IInstallableUnit; +import org.eclipse.equinox.internal.provisional.p2.metadata.query.InstallableUnitQuery; +import org.eclipse.equinox.internal.provisional.p2.query.Collector; +import org.eclipse.equinox.internal.provisional.p2.query.IQueryable; + +public class AbstractAntProvisioningTest extends AbstractProvisioningTest { + protected static final String TYPE_ARTIFACT = "A"; + protected static final String TYPE_METADATA = "M"; + protected static final String TYPE_BOTH = null; + + private static final String TARGET = "target"; + private static final String ROOT = "project"; + private static final String NAME = "name"; + private static final String DEFAULT_TARGET = "default"; + private static final String DEFAULT_NAME = "default"; + + AntTaskElement root, target; + File buildScript, logLocation; + + public void setUp() throws Exception { + super.setUp(); + buildScript = new File(getTempFolder(), getUniqueString()); + logLocation = new File(getTempFolder(), getUniqueString()); + createBuildScript(); + } + + public void tearDown() throws Exception { + // Delete the build script + delete(buildScript.getParentFile()); + delete(logLocation.getParentFile()); + super.tearDown(); + } + + /* + * Run the specified buildscript + */ + protected void runAntTask(File buildFile) { + try { + runAntTaskWithExceptions(buildFile); + } catch (CoreException e) { + fail(rootCause(e)); + } + } + + private void runAntTaskWithExceptions(File buildFile) throws CoreException { + AntRunner ant = new AntRunner(); + ant.setArguments("-logfile \"" + logLocation + "\""); + ant.setBuildFileLocation(buildFile.getAbsolutePath()); + ant.addBuildLogger("org.apache.tools.ant.XmlLogger"); + ant.run(); + } + + /* + * Run the build script described programmatically + */ + protected void runAntTask() { + try { + runAntTaskWithExceptions(); + } catch (CoreException e) { + fail(rootCause(e)); + } + } + + protected void runAntTaskWithExceptions() throws CoreException { + try { + writeBuildScript(); + } catch (Exception e) { + fail("Error writing build script", e); + } + runAntTaskWithExceptions(buildScript); + } + + /* + * Adds an Ant Task to the build script + */ + protected void addTask(AntTaskElement task) { + target.addElement(task); + } + + /* + * Create and return an repository element for this address and type + */ + protected AntTaskElement getRepositoryElement(URI address, String kind) { + return getRepositoryElement(address, kind, null, null, null, null); + } + + protected AntTaskElement getRepositoryElement(URI address, String kind, String name, String format, Boolean compressed, Boolean append) { + AntTaskElement repo = new AntTaskElement("repository"); + repo.addAttributes(new String[] {"location", URIUtil.toUnencodedString(address)}); + if (kind != null) + repo.addAttributes(new String[] {"kind", kind}); + if (name != null) + repo.addAttributes(new String[] {"name", name}); + if (format != null) + repo.addAttributes(new String[] {"format", format}); + if (compressed != null) + repo.addAttributes(new String[] {"compressed", compressed.toString()}); + if (append != null) + repo.addAttributes(new String[] {"append", append.toString()}); + return repo; + } + + /* + * Create the base elements of the build script + */ + private void createBuildScript() { + root = new AntTaskElement(ROOT); + root.addAttributes(new String[] {NAME, ROOT, DEFAULT_TARGET, DEFAULT_NAME}); + target = new AntTaskElement(TARGET); + target.addAttributes(new String[] {NAME, DEFAULT_NAME}); + root.addElement(target); + } + + /* + * Write the build script to disk + */ + private void writeBuildScript() throws Exception { + FileOutputStream outputStream = null; + try { + outputStream = new FileOutputStream(buildScript); + XMLWriter writer = new XMLWriter(outputStream, null); + writeElement(writer, root); + writer.flush(); + } finally { + if (outputStream != null) + outputStream.close(); + } + } + + /* + * Write an element to the buildscript + */ + private void writeElement(XMLWriter writer, AntTaskElement task) { + // Properties ought to occur in key-value pairs + assertTrue("Task " + task + " should have an even number of properties", (task.attributes.size() % 2) == 0); + + // Start tag + writer.start(task.name); + + // write properties + for (Iterator iter = task.attributes.iterator(); iter.hasNext();) + writer.attribute((String) iter.next(), (String) iter.next()); + + // write sub elements if applicable + for (Iterator iter = task.elements.iterator(); iter.hasNext();) + writeElement(writer, (AntTaskElement) iter.next()); + + // close tag + writer.end(); + } + + // Class which can be used to represent elements in a task + protected class AntTaskElement { + public String name; + public List attributes = new ArrayList(); + public List elements = new ArrayList(); + + public AntTaskElement(String name) { + this.name = name; + } + + public void addAttribute(String attribute, String value) { + attributes.add(attribute); + attributes.add(value); + } + + public void addAttributes(String[] propertyArray) { + attributes.addAll(Arrays.asList(propertyArray)); + } + + public void addElement(AntTaskElement element) { + elements.add(element); + } + + public String toString() { + return name; + } + } + + protected static Throwable rootCause(Throwable e) { + if (e.getCause() != null) + return rootCause(e.getCause()); + return e; + } + + protected static void fail(Throwable e) { + fail("An exception occurred while running the task", e); + } + + protected void assertLogContains(String content) { + try { + assertLogContainsLine(logLocation, content); + } catch (Exception e) { + fail("Error asserting log contents.", e); + } + } + + protected static void assertIUContentEquals(String message, IQueryable source, IQueryable destination) { + assertContains(message, source, destination); + assertContains(message, destination, source); + } + + protected static void assertArtifactKeyContentEquals(String message, Collector ius, URI artifactRepositoryLocation) { + try { + IArtifactRepository repo = getArtifactRepositoryManager().loadRepository(artifactRepositoryLocation, null); + List fromIUs = getArtifactKeys(ius); + List fromRepo = Arrays.asList(repo.getArtifactKeys()); + assertContains(message, fromIUs, fromRepo); + assertContains(message, fromRepo, fromIUs); + } catch (ProvisionException e) { + fail("Failed to load repository", e); + } + + } + + protected static void assertContains(String message, IQueryable source, IQueryable destination) { + Collector sourceCollector = source.query(InstallableUnitQuery.ANY, new Collector(), null); + Iterator it = sourceCollector.iterator(); + + while (it.hasNext()) { + IInstallableUnit sourceIU = (IInstallableUnit) it.next(); + Collector destinationCollector = destination.query(new InstallableUnitQuery(sourceIU.getId(), sourceIU.getVersion()), new Collector(), null); + assertEquals(message, 1, destinationCollector.size()); + assertTrue(message, sourceIU.equals(destinationCollector.iterator().next())); + } + } + + protected static void assertContains(String message, List fromIUs, List fromRepo) { + for (Iterator iter = fromIUs.iterator(); iter.hasNext();) + assertTrue(message, fromRepo.contains(iter.next())); + } + + protected static List getArtifactKeys(Collector ius) { + List keys = new ArrayList(ius.size()); + + for (Iterator iter = ius.iterator(); iter.hasNext();) + keys.addAll(Arrays.asList(((InstallableUnit) iter.next()).getArtifacts())); + return keys; + } +} diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/AutomatedTests.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/AutomatedTests.java index 416e85847..513bbeaa1 100644 --- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/AutomatedTests.java +++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/AutomatedTests.java @@ -22,6 +22,7 @@ public class AutomatedTests extends TestCase { public static Test suite() { TestSuite suite = new TestSuite(AutomatedTests.class.getName()); suite.addTest(org.eclipse.equinox.frameworkadmin.tests.AllTests.suite()); + suite.addTest(org.eclipse.equinox.p2.tests.ant.AllTests.suite()); suite.addTest(org.eclipse.equinox.p2.tests.artifact.processors.AllTests.suite()); suite.addTest(org.eclipse.equinox.p2.tests.artifact.repository.AllTests.suite()); suite.addTest(org.eclipse.equinox.p2.tests.artifact.repository.processing.AllTests.suite()); diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ant/AllTests.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ant/AllTests.java new file mode 100644 index 000000000..f0f81bc0b --- /dev/null +++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ant/AllTests.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2009 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.equinox.p2.tests.ant; + +import junit.framework.*; + +/** + * Performs all automated artifact repository tests. + */ +public class AllTests extends TestCase { + + public static Test suite() { + TestSuite suite = new TestSuite(AllTests.class.getName()); + suite.addTestSuite(CompositeRepositoryTaskTest.class); + suite.addTestSuite(MirrorTaskTest.class); + return suite; + } + +}
\ No newline at end of file diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ant/CompositeRepositoryTaskTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ant/CompositeRepositoryTaskTest.java new file mode 100644 index 000000000..0127f5869 --- /dev/null +++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ant/CompositeRepositoryTaskTest.java @@ -0,0 +1,455 @@ +/******************************************************************************* + * Copyright (c) 2009 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.equinox.p2.tests.ant; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URI; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.URIUtil; +import org.eclipse.equinox.internal.p2.artifact.repository.CompositeArtifactRepository; +import org.eclipse.equinox.internal.p2.metadata.repository.CompositeMetadataRepository; +import org.eclipse.equinox.internal.p2.repository.helpers.RepositoryHelper; +import org.eclipse.equinox.internal.provisional.p2.artifact.repository.IArtifactRepository; +import org.eclipse.equinox.internal.provisional.p2.artifact.repository.IArtifactRepositoryManager; +import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException; +import org.eclipse.equinox.internal.provisional.p2.metadata.repository.IMetadataRepositoryManager; +import org.eclipse.equinox.internal.provisional.p2.repository.ICompositeRepository; +import org.eclipse.equinox.internal.provisional.p2.repository.IRepository; +import org.eclipse.equinox.p2.tests.AbstractAntProvisioningTest; + +public class CompositeRepositoryTaskTest extends AbstractAntProvisioningTest { + private static final String ADD_ELEMENT = "add"; + private static final String REMOVE_ELEMENT = "remove"; + private URI compositeSite; + private URI childSite, childSite2; + + public void setUp() throws Exception { + super.setUp(); + // Get a random location to create a repository + compositeSite = (new File(getTempFolder(), getUniqueString())).toURI(); + childSite = getTestData("Loading test data", "testData/testRepos/simple.1").toURI(); + childSite2 = new URI("memory:/in/memory"); + } + + public void tearDown() throws Exception { + // Remove repository manager references + getArtifactRepositoryManager().removeRepository(compositeSite); + getMetadataRepositoryManager().removeRepository(compositeSite); + + getArtifactRepositoryManager().removeRepository(childSite); + getMetadataRepositoryManager().removeRepository(childSite); + getArtifactRepositoryManager().removeRepository(childSite2); + getMetadataRepositoryManager().removeRepository(childSite2); + + // Cleanup disk + delete(new File(compositeSite)); + super.tearDown(); + } + + /* + * Test adding a child to an existing artifact repository + */ + public void testAddChildToExistingArtifactRepository() throws Exception { + // Create repository + createCompositeRepository(TYPE_ARTIFACT); + // Create the modify repository task + AntTaskElement modify = createCompositeRepositoryTaskElement(TYPE_ARTIFACT); + addTask(modify); + + // Create the Add element + AntTaskElement add = new AntTaskElement(ADD_ELEMENT); + add.addElement(getRepositoryElement(childSite, TYPE_ARTIFACT)); + modify.addElement(add); + + // Run the task + runAntTask(); + + CompositeArtifactRepository repo = (CompositeArtifactRepository) getCompositeRepository(TYPE_ARTIFACT); + assertTrue("Repository does not contain child", repo.getChildren().contains(childSite)); + } + + /* + * Test what occurs when no children are added to the newly created Composite repository + */ + public void testCreateNoChidlren() { + AntTaskElement modify = createCompositeRepositoryTaskElement(TYPE_BOTH); + addTask(modify); + runAntTask(); + + if (getArtifactRepositoryManager().contains(compositeSite)) + getArtifactRepositoryManager().removeRepository(compositeSite); + if (getMetadataRepositoryManager().contains(compositeSite)) + getMetadataRepositoryManager().removeRepository(compositeSite); + + ICompositeRepository artifact = null; + ICompositeRepository metadata = null; + try { + artifact = (ICompositeRepository) getArtifactRepositoryManager().loadRepository(compositeSite, null); + metadata = (ICompositeRepository) getMetadataRepositoryManager().loadRepository(compositeSite, null); + } catch (ProvisionException e) { + fail("Failed to load repositories", e); + } + assertTrue("Artifact Repository contains children", artifact.getChildren().isEmpty()); + assertTrue("Metadata Repository contains children", metadata.getChildren().isEmpty()); + } + + /* + * Test adding a child to an existing metadata repository + */ + public void testAddChildToExistingMetadataRepository() { + // Create repository + createCompositeRepository(TYPE_METADATA); + // Create the modify repository task + AntTaskElement modify = createCompositeRepositoryTaskElement(TYPE_METADATA); + addTask(modify); + + // Create the Add element + AntTaskElement add = new AntTaskElement(ADD_ELEMENT); + add.addElement(getRepositoryElement(childSite, TYPE_METADATA)); + modify.addElement(add); + + // Run the task + runAntTask(); + + CompositeMetadataRepository repo = (CompositeMetadataRepository) getCompositeRepository(TYPE_METADATA); + assertTrue("Repository does not contain child", repo.getChildren().contains(childSite)); + } + + /* + * Test adding a child to both types of repositories (which already exist) + */ + public void testAddChildToExistingRepositories() { + // Create repository + createCompositeRepository(null); + // Create the modify repository task + AntTaskElement modify = createCompositeRepositoryTaskElement(null); + addTask(modify); + + // Create the Add element + modify.addElement(createAddElement(null, new URI[] {childSite})); + + // Run the task + runAntTask(); + + CompositeArtifactRepository artifactRepo = (CompositeArtifactRepository) getCompositeRepository(TYPE_ARTIFACT); + assertTrue("Repository does not contain child", artifactRepo.getChildren().contains(childSite)); + + CompositeMetadataRepository metadataRepo = (CompositeMetadataRepository) getCompositeRepository(TYPE_METADATA); + assertTrue("Repository does not contain child", metadataRepo.getChildren().contains(childSite)); + } + + /* + * Test the ability to remove all children + */ + public void testRemoveAllChildren() { + // Create repository + ICompositeRepository parent = createCompositeRepository(TYPE_ARTIFACT); + parent.addChild(childSite); + + // Create the modify repository task + AntTaskElement modify = new AntTaskElement("p2.composite.repository"); + AntTaskElement destination = getRepositoryElement(compositeSite, TYPE_ARTIFACT); + destination.addAttribute("append", String.valueOf(false)); + modify.addElement(destination); + addTask(modify); + + // Run the task + runAntTask(); + + CompositeArtifactRepository artifactRepo = (CompositeArtifactRepository) getCompositeRepository(TYPE_ARTIFACT); + assertTrue("Children not removed", artifactRepo.getChildren().isEmpty()); + + } + + /* + * Test the removal of specified children + */ + public void testRemoveChild() { + ICompositeRepository repo = createCompositeRepository(TYPE_ARTIFACT); + try { + getArtifactRepositoryManager().loadRepository(childSite, null); + getArtifactRepositoryManager().createRepository(childSite2, "Child site", IArtifactRepositoryManager.TYPE_COMPOSITE_REPOSITORY, null); + + repo.addChild(childSite); + repo.addChild(childSite2); + } catch (ProvisionException e) { + fail("Failed to create child repositories"); + } + getArtifactRepositoryManager().removeRepository(compositeSite); + + AntTaskElement modify = createCompositeRepositoryTaskElement(TYPE_ARTIFACT); + modify.addElement(createRemoveElement(TYPE_ARTIFACT, new URI[] {childSite})); + addTask(modify); + + runAntTask(); + + repo = getCompositeRepository(TYPE_ARTIFACT); + + assertFalse(repo.getChildren().contains(childSite)); + assertTrue(repo.getChildren().contains(childSite2)); + } + + /* + * Test creating a CompositeArtifactRepository + */ + public void testCreateCompositeArtifactRepository() throws Exception { + // Create Composite Repository Task + AntTaskElement createCompositeTask = createCompositeRepositoryTaskElement(TYPE_ARTIFACT); + addTask(createCompositeTask); + + runAntTask(); + + assertTrue(getArtifactRepositoryManager().contains(compositeSite)); + assertTrue(getArtifactRepositoryManager().loadRepository(compositeSite, null) instanceof CompositeArtifactRepository); + assertFalse("Metadata repository does not exists", getMetadataRepositoryManager().contains(compositeSite)); + } + + /* + * Test creating a CompositeMetadataRepository + */ + public void testCreateCompositeMetadataRepository() throws Exception { + // Create Composite Repository Task + AntTaskElement createCompositeTask = createCompositeRepositoryTaskElement(TYPE_METADATA); + addTask(createCompositeTask); + + runAntTask(); + + assertTrue("Metadata repository does not exists", getMetadataRepositoryManager().contains(compositeSite)); + assertTrue("Metadata repository is not a CompositeRepository", getMetadataRepositoryManager().loadRepository(compositeSite, null) instanceof CompositeMetadataRepository); + assertFalse("Artifact repository also exists", getArtifactRepositoryManager().contains(compositeSite)); + } + + /* + * Tests the ability to create both Artifact & Metadata repositories at once. + */ + public void testCreateCombinedCompositeRepository() throws Exception { + // Create Composite Repository Task + AntTaskElement createCompositeTask = createCompositeRepositoryTaskElement(null); + addTask(createCompositeTask); + + runAntTask(); + + assertTrue("Metadata repository does not exists", getMetadataRepositoryManager().contains(compositeSite)); + assertTrue("Artifact repository does not exists", getArtifactRepositoryManager().contains(compositeSite)); + assertTrue("Metadata repository is not a CompositeRepository", getMetadataRepositoryManager().loadRepository(compositeSite, null) instanceof CompositeMetadataRepository); + assertTrue("Artifact repository is not a CompositeRepository", getArtifactRepositoryManager().loadRepository(compositeSite, null) instanceof CompositeArtifactRepository); + } + + /* + * Test that failOnExists attribute is honoured + */ + public void testFailOnExists() throws Exception { + // Create Composite Repository Task + AntTaskElement createCompositeTask = createCompositeRepositoryTaskElement(TYPE_ARTIFACT); + addTask(createCompositeTask); + runAntTask(); + + // Set failOnExists + createCompositeTask.addAttributes(new String[] {"failOnExists", String.valueOf(true)}); + + Throwable exception = null; + try { + runAntTaskWithExceptions(); + } catch (CoreException e) { + exception = rootCause(e); + } + if (!exception.getMessage().contains("exists")) + fail("Unexpected exception: ", exception); + } + + /* + * Test that not-compressed attribute is honoured + */ + public void testNotCompressed() throws Exception { + // Create Composite Repository Task + AntTaskElement createCompositeTask = createCompositeRepositoryTaskElement(TYPE_ARTIFACT); + addTask(createCompositeTask); + // Set the compressed attribute to false + ((AntTaskElement) createCompositeTask.elements.get(0)).addAttributes(new String[] {"compressed", String.valueOf(false)}); + runAntTask(); + + ICompositeRepository repo = getCompositeRepository(TYPE_ARTIFACT); + assertTrue(repo instanceof CompositeArtifactRepository); + assertFalse("The repository is compressed", Boolean.valueOf((String) repo.getProperties().get(IRepository.PROP_COMPRESSED))); + } + + /* + * Test that the name is properly set on a newly created repository + */ + public void testName() { + String repoName = "My Test Repository"; + // Create Composite Repository Task + AntTaskElement createCompositeTask = createCompositeRepositoryTaskElement(TYPE_ARTIFACT); + addTask(createCompositeTask); + // Set the repository name + ((AntTaskElement) createCompositeTask.elements.get(0)).addAttributes(new String[] {"name", repoName}); + + runAntTask(); + + try { + IArtifactRepository repo = getArtifactRepositoryManager().loadRepository(compositeSite, null); + assertTrue(repo instanceof CompositeArtifactRepository); + assertEquals(repoName, repo.getName()); + } catch (ProvisionException e) { + fail("Failed to load repository", e); + } + } + + /* + * Test adding a child to a new artifact repository + */ + public void testAddChildToNewArtifactRepository() { + // Create Composite Repository Task + AntTaskElement createCompositeTask = createCompositeRepositoryTaskElement(TYPE_ARTIFACT); + addTask(createCompositeTask); + + // Create add element + AntTaskElement addElement = new AntTaskElement("add"); + // Add a repository + addElement.addElement(getRepositoryElement(childSite, TYPE_ARTIFACT)); + createCompositeTask.addElement(addElement); + + runAntTask(); + + try { + CompositeArtifactRepository repo = (CompositeArtifactRepository) getArtifactRepositoryManager().loadRepository(compositeSite, null); + assertTrue(repo.getChildren().contains(childSite)); + assertEquals("More than one child present", 1, repo.getChildren().size()); + } catch (ProvisionException e) { + fail("Failed to load repository", e); + } + } + + /* + * Test adding a child to a new metadata repository + */ + public void testAddChildToNewMetadataRepository() { + // Create Composite Repository Task + AntTaskElement createCompositeTask = createCompositeRepositoryTaskElement(TYPE_METADATA); + addTask(createCompositeTask); + + // Create add element + AntTaskElement addElement = new AntTaskElement("add"); + // Add a repository + addElement.addElement(getRepositoryElement(childSite, TYPE_METADATA)); + createCompositeTask.addElement(addElement); + + runAntTask(); + + try { + ICompositeRepository repo = (ICompositeRepository) getMetadataRepositoryManager().loadRepository(compositeSite, null); + assertTrue(repo.getChildren().contains(childSite)); + assertEquals("More than one child present", 1, repo.getChildren().size()); + } catch (ProvisionException e) { + fail("Failed to load repository", e); + } + } + + /* + * Test how the task behaves with an invalid location + */ + public void testInvalidLocation() throws Exception { + URI location = URIUtil.fromString("scheme:/location"); + AntTaskElement createCompositeTask = new AntTaskElement("p2.composite.repository"); + createCompositeTask.addElement(getRepositoryElement(location, TYPE_ARTIFACT)); + addTask(createCompositeTask); + + Exception exception = null; + try { + runAntTaskWithExceptions(); + } catch (CoreException e) { + exception = e; + if (!(rootCause(e) instanceof MalformedURLException)) + fail("Expected MalformedURLException.", e); + else { + try { + getArtifactRepositoryManager().loadRepository(location, null); + fail("Repository with invalid location loaded."); + } catch (ProvisionException e2) { + // This is a success + } + } + } + if (exception == null) + fail("No exception thrown"); + } + + /* + * Get the composite repository at the default location + */ + protected ICompositeRepository getCompositeRepository(String type) { + try { + if (type == TYPE_ARTIFACT) { + return (ICompositeRepository) getArtifactRepositoryManager().loadRepository(compositeSite, null); + } else if (type == TYPE_METADATA) + return (ICompositeRepository) getMetadataRepositoryManager().loadRepository(compositeSite, null); + else + fail("No type specified"); + } catch (ProvisionException e) { + fail("Failed to load repository", e); + } catch (ClassCastException e) { + fail("Repository is not composite", e); + } + // Will not occur + return null; + } + + /* + * Create an "remove" AntTaskElement for the specified addresses + */ + protected AntTaskElement createRemoveElement(String type, URI[] addresses) { + AntTaskElement add = new AntTaskElement(REMOVE_ELEMENT); + for (int i = 0; i < addresses.length; i++) + add.addElement(getRepositoryElement(addresses[i], type)); + return add; + } + + /* + * Create an "add" AntTaskElement for the specified addresses + */ + protected AntTaskElement createAddElement(String type, URI[] addresses) { + AntTaskElement add = new AntTaskElement(ADD_ELEMENT); + for (int i = 0; i < addresses.length; i++) + add.addElement(getRepositoryElement(addresses[i], type)); + return add; + } + + /* + * Create an AntTaskElement representing a p2 composite repository task with the default repo location specified + */ + protected AntTaskElement createCompositeRepositoryTaskElement(String type) { + AntTaskElement compositeTask = new AntTaskElement("p2.composite.repository"); + compositeTask.addElement(getRepositoryElement(compositeSite, type)); + + return compositeTask; + } + + /* + * Create a composite repository at the default location of the specified type(s) + */ + protected ICompositeRepository createCompositeRepository(String type) { + ICompositeRepository repo = null; + try { + if (TYPE_ARTIFACT.equals(type) || type == null) { + repo = (ICompositeRepository) RepositoryHelper.validDestinationRepository(getArtifactRepositoryManager().createRepository(compositeSite, "Test Composite Repo", IArtifactRepositoryManager.TYPE_COMPOSITE_REPOSITORY, null)); + } + if (TYPE_METADATA.equals(type) || type == null) { + repo = (ICompositeRepository) RepositoryHelper.validDestinationRepository(getMetadataRepositoryManager().createRepository(compositeSite, "Test Composite Repo", IMetadataRepositoryManager.TYPE_COMPOSITE_REPOSITORY, null)); + } + } catch (ProvisionException e) { + fail("Failed to create composite repository", e); + } catch (IllegalStateException e) { + fail("failed to create writeable composite repository", e); + } + return repo; + } +} diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ant/MirrorTaskTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ant/MirrorTaskTest.java new file mode 100644 index 000000000..3f3b625af --- /dev/null +++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/ant/MirrorTaskTest.java @@ -0,0 +1,656 @@ +/******************************************************************************* + * Copyright (c) 2009 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.equinox.p2.tests.ant; + +import java.io.*; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Iterator; +import java.util.Properties; +import org.eclipse.core.runtime.*; +import org.eclipse.equinox.internal.p2.artifact.processors.md5.Messages; +import org.eclipse.equinox.internal.p2.director.PermissiveSlicer; +import org.eclipse.equinox.internal.p2.metadata.InstallableUnit; +import org.eclipse.equinox.internal.provisional.p2.artifact.repository.*; +import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException; +import org.eclipse.equinox.internal.provisional.p2.core.Version; +import org.eclipse.equinox.internal.provisional.p2.metadata.IArtifactKey; +import org.eclipse.equinox.internal.provisional.p2.metadata.IInstallableUnit; +import org.eclipse.equinox.internal.provisional.p2.metadata.query.InstallableUnitQuery; +import org.eclipse.equinox.internal.provisional.p2.metadata.repository.IMetadataRepository; +import org.eclipse.equinox.internal.provisional.p2.metadata.repository.IMetadataRepositoryManager; +import org.eclipse.equinox.internal.provisional.p2.query.Collector; +import org.eclipse.equinox.internal.provisional.p2.query.IQueryable; +import org.eclipse.equinox.p2.tests.AbstractAntProvisioningTest; +import org.eclipse.equinox.p2.tests.AbstractProvisioningTest; +import org.eclipse.equinox.spi.p2.publisher.PublisherHelper; +import org.eclipse.osgi.util.NLS; + +public class MirrorTaskTest extends AbstractAntProvisioningTest { + private static final String MIRROR_TASK = "p2.mirror"; + private URI destinationRepo; + private URI artifactRepo, sliceArtifactRepo, sliceRepo, sourceRepo2, zipRepo; + + public void setUp() throws Exception { + super.setUp(); + // Get a random location to create a repository + destinationRepo = (new File(getTempFolder(), getUniqueString())).toURI(); + artifactRepo = getTestData("error loading data", "testData/mirror/mirrorPackedRepo").toURI(); + sourceRepo2 = getTestData("error loading data", "testData/mirror/mirrorSourceRepo2").toURI(); + sliceRepo = getTestData("error loading data", "testData/permissiveSlicer").toURI(); + sliceArtifactRepo = getTestData("error loading data", "testData/testRepos/updateSite").toURI(); + zipRepo = getTestData("error loading data", "/testData/mirror/zippedRepo.zip").toURI(); + } + + public void tearDown() throws Exception { + // Remove repository manager references + getArtifactRepositoryManager().removeRepository(destinationRepo); + getMetadataRepositoryManager().removeRepository(destinationRepo); + getArtifactRepositoryManager().removeRepository(sliceRepo); + getMetadataRepositoryManager().removeRepository(sliceRepo); + getArtifactRepositoryManager().removeRepository(sourceRepo2); + getMetadataRepositoryManager().removeRepository(sourceRepo2); + getArtifactRepositoryManager().removeRepository(zipRepo); + getMetadataRepositoryManager().removeRepository(zipRepo); + // Cleanup disk + delete(new File(destinationRepo).getParentFile()); + super.tearDown(); + } + + /* + * Test that it is possible to mirror by only specifying an Artifact repository + */ + public void testMirrorArtifactOnly() { + AntTaskElement mirror = createMirrorTask(TYPE_ARTIFACT); + mirror.addElement(createSourceElement(artifactRepo, null)); + runAntTask(); + + assertEquals("Different number of Artifact Keys", getArtifactKeyCount(artifactRepo), getArtifactKeyCount(destinationRepo)); + assertEquals("Different number of ArtifactDescriptors", getArtifactDescriptorCount(artifactRepo), getArtifactDescriptorCount(destinationRepo)); + } + + /* + * Test that it is possible to mirror when only specifying a Metadata repository + */ + public void testMirrorMetadataOnly() { + AntTaskElement mirror = createMirrorTask(TYPE_METADATA); + mirror.addElement(createSourceElement(null, sourceRepo2)); + runAntTask(); + + assertEquals("Different number of IUs", getIUCount(sourceRepo2), getIUCount(destinationRepo)); + } + + /* + * Test we can mirror from a zipped repository + */ + public void testMirrorFromZip() { + URI localAddress = null; + try { + localAddress = URIUtil.fromString(new File(zipRepo).toString()); + } catch (URISyntaxException e) { + fail("failed to convert zip repo location"); + } + AntTaskElement mirror = createMirrorTask(TYPE_BOTH); + mirror.addElement(createSourceElement(localAddress, localAddress)); + runAntTask(); + + assertEquals("Wrong number of ArtifactKeys", getArtifactKeyCount(URIUtil.toJarURI(zipRepo, null)), getArtifactKeyCount(destinationRepo)); + assertEquals("Wrong number of ArtifactDescriptors", getArtifactDescriptorCount(URIUtil.toJarURI(zipRepo, null)), getArtifactDescriptorCount(destinationRepo)); + assertEquals("Different number of IUs", getIUCount(sourceRepo2), getIUCount(destinationRepo)); + } + + /* + * Test that all IUs can be mirrored + */ + public void testMirrorAllIUSpecified() throws ProvisionException { + AntTaskElement mirror = createMirrorTask(TYPE_BOTH); + mirror.addElement(createSourceElement(sourceRepo2, sourceRepo2)); + addAllIUs(mirror, getMetadataRepositoryManager().loadRepository(sourceRepo2, null)); + runAntTask(); + + assertEquals("Different number of Artifact Keys", getArtifactKeyCount(sourceRepo2), getArtifactKeyCount(destinationRepo)); + assertContentEquals("IUs differ", getMetadataRepositoryManager().loadRepository(sourceRepo2, null), getMetadataRepositoryManager().loadRepository(destinationRepo, null)); + assertEquals("Different number of IUs", getIUCount(sourceRepo2), getIUCount(destinationRepo)); + assertContentEquals("Artifacts differ", getArtifactRepositoryManager().loadRepository(sourceRepo2, null), getArtifactRepositoryManager().loadRepository(destinationRepo, null)); + } + + /* + * Test that we only mirror specified IUs & Artifacts + */ + public void testMirrorSomeIUSpecified() { + AntTaskElement mirror = createMirrorTask(TYPE_BOTH); + mirror.addElement(createSourceElement(sourceRepo2, sourceRepo2)); + mirror.addElement(createIUElement("anotherplugin", "1.0.0")); + + runAntTask(); + + assertEquals("Wrong number of ArtifactKeys", 1, getArtifactKeyCount(destinationRepo)); + assertEquals("Wrong number of IUs", 1, getIUCount(destinationRepo)); + } + + /* + * Test that the proper exception is thrown when no IU is provided + */ + public void testMirrorNoIUNoRepo() { + AntTaskElement mirror = createMirrorTask(TYPE_BOTH); + mirror.addElement(createSourceElement(sourceRepo2, null)); + + Exception exception = null; + try { + runAntTaskWithExceptions(); + } catch (CoreException e) { + exception = e; + } + if (exception == null) + fail("No exception thrown"); + if (!(rootCause(exception) instanceof ProvisionException) && !rootCause(exception).getMessage().contains("No IUs")) + fail("Exception is of an unexpected type or message", rootCause(exception)); + + } + + /* + * Test that all IUs are mirrored when none are specified + */ + public void testMirrorNoIUSpecified() { + AntTaskElement mirror = createMirrorTask(TYPE_BOTH); + mirror.addElement(createSourceElement(sourceRepo2, sourceRepo2)); + + runAntTask(); + + try { + assertEquals("Different number of Artifact Keys", getArtifactKeyCount(sourceRepo2), getArtifactKeyCount(destinationRepo)); + assertContentEquals("Artifacts differ", getArtifactRepositoryManager().loadRepository(sourceRepo2, null), getArtifactRepositoryManager().loadRepository(destinationRepo, null)); + assertEquals("Different number of IUs", getIUCount(sourceRepo2), getIUCount(destinationRepo)); + assertContentEquals("IUs differ", getMetadataRepositoryManager().loadRepository(sourceRepo2, null), getMetadataRepositoryManager().loadRepository(destinationRepo, null)); + } catch (ProvisionException e) { + fail("Failed to compare results", e); + } + } + + /* + * Test the handling of invalid destinations with the mirror task + */ + public void testMirrorWithInvalidDestination() throws URISyntaxException { + URI location = new URI("invalid:/scheme"); + + AntTaskElement mirror = new AntTaskElement(MIRROR_TASK); + mirror.addElement(getRepositoryElement(location, TYPE_BOTH)); + mirror.addElement(createSourceElement(sourceRepo2, sourceRepo2)); + addTask(mirror); + + Throwable exception = null; + try { + runAntTaskWithExceptions(); + } catch (Exception e) { + exception = e; + } + if (exception == null) + fail("No Exception thrown"); + + while (exception.getCause() != null && !(exception instanceof ProvisionException)) + exception = exception.getCause(); + assertTrue("Unexpected error", NLS.bind(org.eclipse.equinox.p2.internal.repository.tools.Messages.exception_invalidDestination, location).equals(exception.getMessage())); + } + + /* + * Test the handling of invalid destinations with the mirror task + */ + public void testMirrorWithInvalidSource() throws URISyntaxException { + URI location = new URI("invalid:/scheme2"); + + AntTaskElement mirror = createMirrorTask(TYPE_BOTH); + mirror.addElement(createSourceElement(location, location)); + addTask(mirror); + + Throwable exception = null; + try { + runAntTaskWithExceptions(); + } catch (Exception e) { + exception = e; + } + if (exception == null) + fail("No Exception thrown"); + + while (exception.getCause() != null && !(exception instanceof ProvisionException)) + exception = exception.getCause(); + assertTrue("Unexpected error", NLS.bind(org.eclipse.equinox.p2.internal.repository.tools.Messages.exception_invalidSource, location).equals(exception.getMessage())); + } + + /* + * Test slicing options + */ + public void testSlicingFollowStrict() { + IMetadataRepository repo = null; + try { + repo = loadMetadataRepository(sliceRepo); + } catch (ProvisionException e) { + fail("Loading repository failed", e); + } + Collector c = repo.query(new InstallableUnitQuery("org.eclipse.rcp.feature.group"), new Collector(), new NullProgressMonitor()); + IInstallableUnit iu = (IInstallableUnit) c.iterator().next(); + + AntTaskElement mirror = createMirrorTask(TYPE_METADATA); + mirror.addElement(createSourceElement(null, sliceRepo)); + mirror.addElement(createSlicingOption(null, null, true, null, "win32,win32,x86")); + mirror.addElement(createIUElement(iu.getId(), iu.getVersion().toString())); + + runAntTask(); + + Properties p = getSliceProperties(); + p.setProperty("org.eclipse.update.install.features", String.valueOf(true)); + PermissiveSlicer slicer = new PermissiveSlicer(repo, p, true, true, true, true); + IQueryable result = slicer.slice(new IInstallableUnit[] {iu}, new NullProgressMonitor()); + assertEquals("Different number of IUs", result.query(InstallableUnitQuery.ANY, new Collector(), new NullProgressMonitor()).size(), getIUCount(destinationRepo)); + + try { + assertIUContentEquals("IUs differ", result, getMetadataRepositoryManager().loadRepository(destinationRepo, null)); + } catch (ProvisionException e) { + fail("Failed to compare contents", e); + } + } + + public void testSlicingIncludeNonGreedy() { + IMetadataRepository repo = null; + try { + repo = loadMetadataRepository(sliceRepo); + } catch (ProvisionException e) { + fail("Loading repository failed", e); + } + Collector c = repo.query(new InstallableUnitQuery("org.eclipse.rcp.feature.group"), new Collector(), new NullProgressMonitor()); + IInstallableUnit iu = (IInstallableUnit) c.iterator().next(); + + AntTaskElement mirror = createMirrorTask(TYPE_METADATA); + mirror.addElement(createSourceElement(null, sliceRepo)); + mirror.addElement(createSlicingOption(null, false, null, null, null)); + mirror.addElement(createIUElement(iu.getId(), iu.getVersion().toString())); + + runAntTask(); + + PermissiveSlicer slicer = new PermissiveSlicer(repo, new Properties(), true, false, true, false); + IQueryable result = slicer.slice(new IInstallableUnit[] {iu}, new NullProgressMonitor()); + + assertEquals("Different number of IUs", result.query(InstallableUnitQuery.ANY, new Collector(), new NullProgressMonitor()).size(), getIUCount(destinationRepo)); + try { + assertIUContentEquals("IUs differ", result, getMetadataRepositoryManager().loadRepository(destinationRepo, null)); + } catch (ProvisionException e) { + fail("Failed to compare contents", e); + } + } + + public void testSlicingIncludeOptionalDependencies() { + IMetadataRepository repo = null; + try { + repo = loadMetadataRepository(sliceRepo); + } catch (ProvisionException e) { + fail("Loading repository failed", e); + } + Collector c = repo.query(new InstallableUnitQuery("org.eclipse.rcp.feature.group"), new Collector(), new NullProgressMonitor()); + IInstallableUnit iu = (IInstallableUnit) c.iterator().next(); + + AntTaskElement mirror = createMirrorTask(TYPE_METADATA); + mirror.addElement(createSourceElement(null, sliceRepo)); + mirror.addElement(createSlicingOption(false, null, null, null, "win32,win32,x86")); + mirror.addElement(createIUElement(iu.getId(), iu.getVersion().toString())); + + runAntTask(); + + Properties p = getSliceProperties(); + p.setProperty("org.eclipse.update.install.features", String.valueOf(true)); + PermissiveSlicer slicer = new PermissiveSlicer(repo, p, false, true, true, false); + IQueryable result = slicer.slice(new IInstallableUnit[] {iu}, new NullProgressMonitor()); + assertEquals("Different number of IUs", result.query(InstallableUnitQuery.ANY, new Collector(), new NullProgressMonitor()).size(), getIUCount(destinationRepo)); + try { + assertIUContentEquals("IUs differ", result, getMetadataRepositoryManager().loadRepository(destinationRepo, null)); + } catch (ProvisionException e) { + fail("Failed to compare contents", e); + } + } + + /* + * Test the platform filter + */ + public void testSlicingPlatformFilter() { + IMetadataRepository repo = null; + try { + repo = loadMetadataRepository(sliceRepo); + } catch (ProvisionException e) { + fail("Loading repository failed", e); + } + Collector c = repo.query(new InstallableUnitQuery("org.eclipse.rcp.feature.group"), new Collector(), new NullProgressMonitor()); + IInstallableUnit iu = (IInstallableUnit) c.iterator().next(); + + AntTaskElement mirror = createMirrorTask(TYPE_METADATA); + mirror.addElement(createSourceElement(null, sliceRepo)); + mirror.addElement(createSlicingOption(null, null, null, null, "win32,win32,x86")); + mirror.addElement(createIUElement(iu.getId(), iu.getVersion().toString())); + + runAntTask(); + + Properties p = getSliceProperties(); + p.setProperty("org.eclipse.update.install.features", String.valueOf(true)); + PermissiveSlicer slicer = new PermissiveSlicer(repo, p, true, true, true, false); + IQueryable result = slicer.slice(new IInstallableUnit[] {iu}, new NullProgressMonitor()); + assertEquals("Different number of IUs", result.query(InstallableUnitQuery.ANY, new Collector(), new NullProgressMonitor()).size(), getIUCount(destinationRepo)); + try { + assertIUContentEquals("IUs differ", result, getMetadataRepositoryManager().loadRepository(destinationRepo, null)); + } catch (ProvisionException e) { + fail("Failed to compare contents", e); + } + } + + /* + * Test disabling includeFeatures for SlicingOptions + */ + public void testSlicingIncludeFeaturesFalse() { + IMetadataRepository repo = null; + try { + repo = loadMetadataRepository(sliceRepo); + } catch (ProvisionException e) { + fail("Loading repository failed", e); + } + Collector c = repo.query(new InstallableUnitQuery("org.eclipse.rcp.feature.group"), new Collector(), new NullProgressMonitor()); + IInstallableUnit iu = (IInstallableUnit) c.iterator().next(); + + // Create task + AntTaskElement mirror = createMirrorTask(TYPE_METADATA); + mirror.addElement(createSourceElement(null, sliceRepo)); + mirror.addElement(createSlicingOption(null, null, null, false, "win32,win32,x86")); + mirror.addElement(createIUElement(iu.getId(), iu.getVersion().toString())); + + runAntTask(); + + Properties p = getSliceProperties(); + PermissiveSlicer slicer = new PermissiveSlicer(repo, p, true, true, true, false); + IQueryable result = slicer.slice(new IInstallableUnit[] {iu}, new NullProgressMonitor()); + assertEquals("Different number of IUs", result.query(InstallableUnitQuery.ANY, new Collector(), new NullProgressMonitor()).size(), getIUCount(destinationRepo)); + try { + assertIUContentEquals("IUs differ", result, getMetadataRepositoryManager().loadRepository(destinationRepo, null)); + } catch (ProvisionException e) { + fail("Failed to compare contents", e); + } + } + + /* + * Tests the results of a slice are used to mirror artifacts + */ + public void testSlicingArtifactsMirrored() { + IMetadataRepository repo = null; + try { + repo = loadMetadataRepository(sliceArtifactRepo); + } catch (ProvisionException e) { + fail("Loading repository failed", e); + } + Collector c = repo.query(new InstallableUnitQuery("test.feature.feature.group"), new Collector(), new NullProgressMonitor()); + IInstallableUnit iu = (IInstallableUnit) c.iterator().next(); + + // Create task + AntTaskElement mirror = createMirrorTask(TYPE_BOTH); + mirror.addElement(createSourceElement(sliceArtifactRepo, sliceArtifactRepo)); + mirror.addElement(createSlicingOption(null, null, null, false, "win32,win32,x86")); + mirror.addElement(createIUElement(iu.getId(), iu.getVersion().toString())); + + runAntTask(); + + Properties p = getSliceProperties(); + PermissiveSlicer slicer = new PermissiveSlicer(repo, p, true, true, true, false); + IQueryable result = slicer.slice(new IInstallableUnit[] {iu}, new NullProgressMonitor()); + + assertEquals("Different number of IUs", result.query(InstallableUnitQuery.ANY, new Collector(), new NullProgressMonitor()).size(), getIUCount(destinationRepo)); + assertEquals("Different number of ArtifactKeys", getArtifactKeyCount(result.query(InstallableUnitQuery.ANY, new Collector(), new NullProgressMonitor())), getArtifactKeyCount(destinationRepo)); + try { + assertArtifactKeyContentEquals("Different ArtifactKeys", result.query(InstallableUnitQuery.ANY, new Collector(), new NullProgressMonitor()), destinationRepo); + assertIUContentEquals("IUs differ", result, getMetadataRepositoryManager().loadRepository(destinationRepo, null)); + } catch (ProvisionException e) { + fail("Failed to compare contents", e); + } + + } + + /* + * Test the result of a slice which results in no IUs + */ + public void testSlicingInvalid() { + AntTaskElement mirror = createMirrorTask(TYPE_METADATA); + mirror.addElement(createSourceElement(null, sliceRepo)); + mirror.addElement(createSlicingOption(null, null, null, null, "win32,win32,x86")); + + Exception exception = null; + try { + runAntTaskWithExceptions(); + } catch (Exception e) { + exception = e; + } + + if (exception == null || !(rootCause(exception) instanceof ProvisionException)) { + fail("Unexpected exception type", exception); + } + } + + /* + * Modified from org.eclipse.equinox.p2.tests.mirror.ArtifactMirrorApplicationTest + */ + public void testBaselineCompareUsingMD5Comparator() { + //Setup create descriptors with different md5 values + IArtifactKey dupKey = PublisherHelper.createBinaryArtifactKey("testKeyId", new Version("1.2.3")); + File artifact1 = getTestData("0.0", "/testData/mirror/mirrorSourceRepo1 with space/content.xml"); + File artifact2 = getTestData("0.0", "/testData/mirror/mirrorSourceRepo2/content.xml"); + + //Setup Copy the file to the baseline + File repoLocation = getTestFolder(getUniqueString()); + File baselineLocation = getTestFolder(getUniqueString()); + File baselineBinaryDirectory = new File(baselineLocation, "binary"); + baselineBinaryDirectory.mkdir(); + File baselineContentLocation = new File(baselineBinaryDirectory, "testKeyId_1.2.3"); + AbstractProvisioningTest.copy("Copying File to baseline", artifact2, baselineContentLocation); + + IArtifactDescriptor descriptor1 = PublisherHelper.createArtifactDescriptor(dupKey, artifact1); + IArtifactDescriptor descriptor2 = PublisherHelper.createArtifactDescriptor(dupKey, baselineContentLocation); + + assertEquals("Ensuring Descriptors are the same", descriptor1, descriptor2); + assertNotSame("Ensuring MD5 values are different", descriptor1.getProperty(IArtifactDescriptor.DOWNLOAD_MD5), descriptor2.getProperty(IArtifactDescriptor.DOWNLOAD_MD5)); + + //Setup make repositories + IArtifactRepository repo = null; + IArtifactRepository baseline = null; + try { + repo = createRepositoryWithIU(repoLocation.toURI(), descriptor1); + baseline = createRepositoryWithIU(baselineLocation.toURI(), descriptor2); + } catch (ProvisionException e) { + fail("Error creating repositories", e); + } + + //Comparator prints to stderr, redirect that to a file + PrintStream oldErr = System.err; + PrintStream newErr = null; + PrintStream oldOut = System.out; + PrintStream newOut = null; + try { + (new File(destinationRepo)).mkdir(); + newErr = new PrintStream(new FileOutputStream(new File(new File(destinationRepo), "sys.err"))); + newOut = new PrintStream(new FileOutputStream(new File(new File(destinationRepo), "sys.out"))); + } catch (FileNotFoundException e) { + fail("Error redirecting outputs", e); + } + + try { + System.setErr(newErr); + System.setOut(newOut); + + // Create task + AntTaskElement mirror = createMirrorTask(TYPE_BOTH); + // Add source + mirror.addElement(createSourceElement(repoLocation.toURI(), repoLocation.toURI())); + // set verbose + mirror.addAttribute("verbose", String.valueOf(true)); + + // Create a comparator element + AntTaskElement comparator = new AntTaskElement("comparator"); + comparator.addElement(getRepositoryElement(baselineLocation.toURI(), null)); + mirror.addElement(comparator); + + runAntTaskWithExceptions(); + } catch (Exception e) { + fail("Running mirror application with baseline compare", rootCause(e)); + } finally { + System.setErr(oldErr); + newErr.close(); + System.setOut(oldOut); + newOut.close(); + } + + IArtifactRepository destination = null; + try { + destination = getArtifactRepositoryManager().loadRepository(destinationRepo, null); + } catch (ProvisionException e) { + fail("Error loading destination", e); + } + + IArtifactDescriptor[] destDescriptors = destination.getArtifactDescriptors(descriptor2.getArtifactKey()); + assertEquals("Ensuring destination has correct number of descriptors", 1, destDescriptors.length); + assertEquals("Ensuring destination contains the descriptor from the baseline", descriptor2.getProperty(IArtifactDescriptor.DOWNLOAD_MD5), destDescriptors[0].getProperty(IArtifactDescriptor.DOWNLOAD_MD5)); + String msg = NLS.bind(Messages.warning_differentMD5, new Object[] {URIUtil.toUnencodedString(baseline.getLocation()), URIUtil.toUnencodedString(repo.getLocation()), descriptor1}); + + assertLogContains(msg); + } + + private Properties getSliceProperties() { + Properties p = new Properties(); + p.setProperty("osgi.os", "win32"); + p.setProperty("osgi.ws", "win32"); + p.setProperty("osgi.arch", "x86"); + return p; + } + + protected AntTaskElement createSlicingOption(Boolean includeOptional, Boolean includeNonGreedy, Boolean followStrict, Boolean includeFeatures, String platformFilter) { + AntTaskElement slicing = new AntTaskElement("slicingoptions"); + if (followStrict != null) + slicing.addAttribute("followstrict", followStrict.toString()); + if (includeFeatures != null) + slicing.addAttribute("includefeatures", includeFeatures.toString()); + if (includeNonGreedy != null) + slicing.addAttribute("includenongreedy", includeNonGreedy.toString()); + if (includeOptional != null) + slicing.addAttribute("includeoptional", includeOptional.toString()); + if (platformFilter != null) + slicing.addAttribute("platformfilter", platformFilter); + return slicing; + } + + /* + * Create an IU for a descriptor and the IU+descriptor to the specified repo + */ + protected IArtifactRepository createRepositoryWithIU(URI repoLocation, IArtifactDescriptor descriptor) throws ProvisionException { + IArtifactRepository artifactRepository = getArtifactRepositoryManager().createRepository(repoLocation, "Repo 1", IArtifactRepositoryManager.TYPE_SIMPLE_REPOSITORY, null); + artifactRepository.addDescriptor(descriptor); + + IMetadataRepository metaRepo = getMetadataRepositoryManager().createRepository(repoLocation, "Repo", IMetadataRepositoryManager.TYPE_SIMPLE_REPOSITORY, null); + InstallableUnit iu = new InstallableUnit(); + iu.setId(descriptor.getArtifactKey().getId() + "IU"); + iu.setVersion(descriptor.getArtifactKey().getVersion()); + iu.setArtifacts(new IArtifactKey[] {descriptor.getArtifactKey()}); + metaRepo.addInstallableUnits(new IInstallableUnit[] {iu}); + + return artifactRepository; + } + + /* + * Get the number of ArtifactKeys in a repository + */ + protected int getArtifactKeyCount(URI location) { + try { + return getArtifactRepositoryManager().loadRepository(location, null).getArtifactKeys().length; + } catch (ProvisionException e) { + fail("Failed to load repository " + URIUtil.toUnencodedString(location) + " for ArtifactDescriptor count"); + return -1; + } + } + + /* + * Get the number of ArtifactKeys in a repository + */ + protected int getArtifactKeyCount(Collector ius) { + int count = 0; + for (Iterator iter = ius.iterator(); iter.hasNext();) + count += ((InstallableUnit) iter.next()).getArtifacts().length; + return count; + } + + /* + * Get the number of ArtifactDescriptors in a repository + */ + protected int getArtifactDescriptorCount(URI location) { + int count = 0; + try { + IArtifactRepository repo = getArtifactRepositoryManager().loadRepository(location, null); + IArtifactKey[] keys = repo.getArtifactKeys(); + for (int i = 0; i < keys.length; i++) + count += repo.getArtifactDescriptors(keys[i]).length; + } catch (ProvisionException e) { + fail("Failed to load repository " + URIUtil.toUnencodedString(location) + " for ArtifactDescriptor count"); + } + return count; + } + + /* + * Get the number of IUs in a repository + */ + protected int getIUCount(URI location) { + try { + return getMetadataRepositoryManager().loadRepository(location, null).query(InstallableUnitQuery.ANY, new Collector(), null).size(); + } catch (ProvisionException e) { + fail("Failed to load repository " + URIUtil.toUnencodedString(location) + " for ArtifactDescriptor count"); + return -1; + } + } + + /* + * Add all IUs to the parent element + */ + protected void addAllIUs(AntTaskElement parent, IMetadataRepository repo) { + Collector collector = repo.query(InstallableUnitQuery.ANY, new Collector(), null); + + for (Iterator iter = collector.iterator(); iter.hasNext();) { + IInstallableUnit iu = (IInstallableUnit) iter.next(); + parent.addElement(createIUElement(iu.getId(), iu.getVersion().toString())); + } + } + + /* + * Create an element from the specified information + */ + protected AntTaskElement createIUElement(String id, String version) { + AntTaskElement iu = new AntTaskElement("iu"); + iu.addAttributes(new String[] {"id", id, "version", version}); + return iu; + } + + /* + * Create the base mirror task & add it to the script + */ + protected AntTaskElement createMirrorTask(String type) { + AntTaskElement mirror = new AntTaskElement(MIRROR_TASK); + mirror.addElement(getRepositoryElement(destinationRepo, type)); + addTask(mirror); + return mirror; + } + + /* + * Create a source element with the specified repositories + */ + protected AntTaskElement createSourceElement(URI artifact, URI metadata) { + AntTaskElement source = new AntTaskElement("source"); + if (artifact != null) + source.addElement(getRepositoryElement(artifact, AbstractAntProvisioningTest.TYPE_ARTIFACT)); + if (metadata != null) + source.addElement(getRepositoryElement(metadata, AbstractAntProvisioningTest.TYPE_METADATA)); + return source; + } +} diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/mirror/AllTests.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/mirror/AllTests.java index aec986d1c..d965a31df 100644 --- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/mirror/AllTests.java +++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/mirror/AllTests.java @@ -23,6 +23,8 @@ public class AllTests extends TestCase { suite.addTestSuite(MetadataMirrorApplicationTest.class); suite.addTestSuite(ArtifactRepositoryCleanupTest.class); suite.addTestSuite(MetadataRepositoryCleanupTest.class); + suite.addTestSuite(NewMirrorApplicationArtifactTest.class); + suite.addTestSuite(NewMirrorApplicationMetadataTest.class); return suite; } diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/mirror/NewMirrorApplicationArtifactTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/mirror/NewMirrorApplicationArtifactTest.java new file mode 100644 index 000000000..28d52ecc0 --- /dev/null +++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/mirror/NewMirrorApplicationArtifactTest.java @@ -0,0 +1,1467 @@ +/******************************************************************************* + * Copyright (c) 2008, 2009 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.equinox.p2.tests.mirror; + +import java.io.*; +import java.net.MalformedURLException; +import java.net.URI; +import java.util.*; +import org.eclipse.core.runtime.*; +import org.eclipse.equinox.internal.p2.artifact.processors.md5.Messages; +import org.eclipse.equinox.internal.p2.artifact.repository.*; +import org.eclipse.equinox.internal.p2.artifact.repository.simple.SimpleArtifactRepository; +import org.eclipse.equinox.internal.p2.core.helpers.OrderedProperties; +import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper; +import org.eclipse.equinox.internal.provisional.p2.artifact.repository.*; +import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException; +import org.eclipse.equinox.internal.provisional.p2.core.Version; +import org.eclipse.equinox.internal.provisional.p2.metadata.IArtifactKey; +import org.eclipse.equinox.internal.provisional.p2.repository.IRepository; +import org.eclipse.equinox.p2.internal.repository.tools.MirrorApplication; +import org.eclipse.equinox.p2.internal.repository.tools.RepositoryDescriptor; +import org.eclipse.equinox.p2.tests.AbstractProvisioningTest; +import org.eclipse.equinox.p2.tests.TestActivator; +import org.eclipse.equinox.spi.p2.publisher.PublisherHelper; +import org.eclipse.osgi.framework.log.FrameworkLog; +import org.eclipse.osgi.util.NLS; + +/* + * Modified from ArtifactMirrorApplicationTest + */ +public class NewMirrorApplicationArtifactTest extends AbstractProvisioningTest { + protected File destRepoLocation; + protected File sourceRepoLocation; //helloworldfeature + protected File sourceRepo2Location; //anotherfeature + protected File sourceRepo3Location; //helloworldfeature + yetanotherfeature + protected File sourceRepo4Location; //helloworldfeature v1.0.1 + + /* (non-Javadoc) + * @see org.eclipse.equinox.p2.tests.AbstractProvisioningTest#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + //load all the repositories + sourceRepoLocation = getTestData("0.0", "/testData/mirror/mirrorSourceRepo1 with space"); + sourceRepo2Location = getTestData("0.1", "/testData/mirror/mirrorSourceRepo2"); + sourceRepo3Location = getTestData("0.2", "/testData/mirror/mirrorSourceRepo3"); + sourceRepo4Location = getTestData("0.3", "/testData/mirror/mirrorSourceRepo4"); + + //create destination location + destRepoLocation = new File(getTempFolder(), "BasicMirrorApplicationTest"); + delete(destRepoLocation); + } + + /* (non-Javadoc) + * @see org.eclipse.equinox.p2.tests.AbstractProvisioningTest#tearDown() + */ + protected void tearDown() throws Exception { + //remove all the repositories + getArtifactRepositoryManager().removeRepository(destRepoLocation.toURI()); + getArtifactRepositoryManager().removeRepository(sourceRepoLocation.toURI()); + getArtifactRepositoryManager().removeRepository(sourceRepo2Location.toURI()); + getArtifactRepositoryManager().removeRepository(sourceRepo3Location.toURI()); + getArtifactRepositoryManager().removeRepository(sourceRepo4Location.toURI()); + //delete the destination location (no left over files for the next test) + delete(destRepoLocation); + super.tearDown(); + } + + private void basicRunMirrorApplication(String message, URI source, URI destination, Boolean append, Boolean formatDestination, String destName) throws Exception { + MirrorApplication app = new MirrorApplication(); + + if (destination != null) { + RepositoryDescriptor dest = null; + if (formatDestination != null && formatDestination) + dest = createRepositoryDescriptor(destination, append, source, destName); + else + dest = createRepositoryDescriptor(destination, append, null, destName); + app.addDestination(dest); + } + + if (source != null) { + RepositoryDescriptor src = createRepositoryDescriptor(source, null, null, null); + app.addSource(src); + } + app.run(null); + } + + private void basicRunMirrorApplication(String message, URI source, URI destination, Boolean append, Boolean formatDestination) throws Exception { + basicRunMirrorApplication(message, source, destination, append, formatDestination, null); + } + + private void basicRunMirrorApplication(String message, URI source, URI destination) throws Exception { + basicRunMirrorApplication(message, source, destination, null, null, null); + } + + private RepositoryDescriptor createRepositoryDescriptor(URI location, Boolean append, URI format, String name) { + RepositoryDescriptor descriptor = new RepositoryDescriptor(); + descriptor.setLocation(location); + descriptor.setKind("artifact"); + if (append != null) + descriptor.setAppend(append); + if (format != null) + descriptor.setFormat(format); + if (name != null) + descriptor.setName(name); + return descriptor; + } + + /** + * just a wrapper method for compatibility + */ + private void runMirrorApplication(String message, File source, File destination, boolean append) { + try { + basicRunMirrorApplication(message, source.toURI(), destination.toURI(), append, false); + } catch (Exception e) { + fail(message, e); + } + } + + /** + * Tests mirroring all artifacts in a repository to an empty repository + * Source contains A, B + * Target contains + */ + private void artifactMirrorToEmpty(String message, boolean append, boolean format) { + try { + //destination repo is created blank + basicRunMirrorApplication(message, sourceRepoLocation.toURI(), destRepoLocation.toURI(), append, format); + } catch (Exception e) { + fail(message, e); + } + } + + /** + * Tests mirroring all artifacts in a repository to a repository populated with non-duplicate entries + * Source contains A, B + * Target contains C, D + */ + private void artifactMirrorToPopulated(String message, boolean append) { + //Setup: populate destination with non-duplicate artifacts + runMirrorApplication(message + ".0", sourceRepo2Location, destRepoLocation, false); //value of append should not matter + + try { + //Setup ensure setup completes successfully + assertContentEquals(message + ".1", getArtifactRepositoryManager().loadRepository(sourceRepo2Location.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail(message + ".2", e); + } + + //mirror test data + runMirrorApplication(message + ".4", sourceRepoLocation, destRepoLocation, append); + } + + /** + * Tests mirroring all artifacts in a repository to a repository populated with exact duplicate data + * Source contains A, B + * Target contains A, B + */ + private void artifactMirrorToFullDuplicate(String message, boolean append) { + //Setup: populate destination with duplicate artifacts + runMirrorApplication(message + ".0", sourceRepoLocation, destRepoLocation, false); //value of append should not matter + + try { + //Setup: verify contents + assertContentEquals(message + ".1", getArtifactRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail(message + ".2", e); + } + + //mirror test data + runMirrorApplication(message + ".4", sourceRepoLocation, destRepoLocation, append); + } + + /** + * Tests mirroring all artifacts in a repository to a repository populated with partially duplicate data + * Source contains A, B, C, D + * Target contains A, B + */ + private void artifactMirrorToPartialDuplicate(String message, boolean append) { + //Setup: populate destination with duplicate artifacts + runMirrorApplication(message + ".0", sourceRepoLocation, destRepoLocation, false); + + try { + //Setup: verify contents + assertContentEquals(message + ".1", getArtifactRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail(message + ".2", e); + } + + //mirror test data + runMirrorApplication(message + ".4", sourceRepo3Location, destRepoLocation, append); + } + + /** + * Tests mirroring all artifacts in a repository to a repository populated with both full duplicate and non-duplicate data + * Source contains A, B + * Target contains A, B, C, D + */ + private void artifactMirrorToPopulatedWithFullDuplicate(String message, boolean append) { + //Setup: populate destination with non-duplicate artifacts + runMirrorApplication(message + ".0", sourceRepo3Location, destRepoLocation, false); //value of append should not matter + + try { + //Setup: verify + assertContentEquals(message + ".1", getArtifactRepositoryManager().loadRepository(sourceRepo3Location.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail(message + ".2", e); + } + + //mirror duplicate data + runMirrorApplication(message + ".4", sourceRepoLocation, destRepoLocation, append); + } + + /** + * Tests mirroring all artifacts in a repository to a repository populated with both partial duplicate and non-duplicate data + * Source contains A, B, C, D + * Target contains A, B, E, F + */ + private void artifactMirrorToPopulatedWithPartialDuplicate(String message, boolean append) { + //Setup: populate destination with non-duplicate artifacts + runMirrorApplication(message + ".0", sourceRepo2Location, destRepoLocation, false); //value of append should not matter + + try { + //Setup: verify + assertContentEquals(message + ".1", getArtifactRepositoryManager().loadRepository(sourceRepo2Location.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail(message + ".2", e); + } + + //Setup: populate destination with duplicate artifacts + runMirrorApplication(message + ".4", sourceRepoLocation, destRepoLocation, true); + + try { + //Setup: verify + assertContains(message + ".5", getArtifactRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + assertContains(message + ".6", getArtifactRepositoryManager().loadRepository(sourceRepo2Location.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail(message + ".7", e); + } + + //mirror duplicate data + runMirrorApplication(message + ".9", sourceRepo3Location, destRepoLocation, append); + } + + /** + * Tests mirroring all artifacts from an empty repository + * Source contains + */ + private File artifactMirrorEmpty(String message, boolean append) { + //Setup: Create an empty repository + File emptyRepository = new File(getTempFolder(), getUniqueString()); + //Setup: remove repository if it exists + getArtifactRepositoryManager().removeRepository(emptyRepository.toURI()); + //Setup: delete any data that may be in the folder + delete(emptyRepository); + try { + getArtifactRepositoryManager().createRepository(emptyRepository.toURI(), "Empty Repository", IArtifactRepositoryManager.TYPE_SIMPLE_REPOSITORY, null); + } catch (ProvisionException e) { + fail(message + ".1", e); + } + + runMirrorApplication(message + ".0", emptyRepository, destRepoLocation, append); + return emptyRepository; //return the repository for use in verification + } + + /** + * Tests mirroring all artifacts from an empty repository + * Source contains + */ + private File artifactMirrorEmptyToPopulated(String message, boolean append) { + //Setup: Populate the repository + runMirrorApplication(message + ".0", sourceRepoLocation, destRepoLocation, false); + + return artifactMirrorEmpty(message + ".1", append); //create the empty repository, perform the mirror, pass the result back + } + + /** + * Runs mirror app on source with missing artifact with "-ignoreErrors" + */ + private void mirrorWithError(boolean verbose) { + File errorSourceLocation = getTestData("loading error data", "testData/mirror/mirrorErrorSourceRepo"); + //repo contains an artifact entry for a file that does not exist on disk. this should throw a file not found exception + try { + MirrorApplication app = new MirrorApplication(); + app.addSource(createRepositoryDescriptor(errorSourceLocation.toURI(), null, null, null)); + app.addDestination(createRepositoryDescriptor(destRepoLocation.toURI(), null, null, null)); + //Set ignoreErrors flag. Set verbose flag if verbose == true + app.setVerbose(verbose); + app.setIgnoreErrors(true); + //run the mirror application + app.run(null); + } catch (Exception e) { + fail("Running mirror application with errored source failed", e); + } + } + + /** + * ensures that all files with entries in the repo have corresponding files on disk. + * Not Biconditional. + */ + private void assertFileSizes(String message, SimpleArtifactRepository expected, SimpleArtifactRepository actual) { + IArtifactKey[] expectedKeys = expected.getArtifactKeys(); + + for (int i = 0; i < expectedKeys.length; i++) { + IArtifactDescriptor[] expectedDescriptors = expected.getArtifactDescriptors(expectedKeys[i]); + IArtifactDescriptor[] actualDescriptors = actual.getArtifactDescriptors(expectedKeys[i]); + + if (expectedDescriptors == null || actualDescriptors == null) + if (!(expectedDescriptors == null && actualDescriptors == null)) + fail(message + " missing key " + expectedKeys[i]); + + top: for (int j = 0; j < expectedDescriptors.length; j++) { + for (int k = 0; k < actualDescriptors.length; k++) { + if (Arrays.equals(expectedDescriptors[j].getProcessingSteps(), actualDescriptors[k].getProcessingSteps())) { + File expectedFile = expected.getArtifactFile(expectedDescriptors[j]); + File actualFile = actual.getArtifactFile(actualDescriptors[k]); + if (expectedFile == null || actualFile == null) + fail(message + " descriptor mismatch"); + if (!(expectedFile.exists() && actualFile.exists())) + fail(message + " file does not exist"); + assertTrue(expectedFile.length() == actualFile.length()); + continue top; + } + } + fail(message + "Missing expected descriptor" + expectedDescriptors[j]); + } + } + } + + /** + * Tests mirroring all artifacts in a repository to an empty repository + * Source contains A, B + * Target contains + * Expected is A, B + */ + public void testArtifactMirrorToEmpty() { + artifactMirrorToEmpty("1.0", true, false); // run the test with append set to true + + try { + //verify destination's content + assertContentEquals("1.1", getArtifactRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("1.2", e); + } + } + + /** + * Tests mirroring all artifacts in a repository to an empty repository with "-writeMode clean" + * Source contains A, B + * Target contains + * Expected is A, B + */ + public void testArtifactMirrorToEmptyWithClean() { + artifactMirrorToEmpty("2.0", false, false); + + try { + //verify destination's content + assertContentEquals("2.1", getArtifactRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("2.2", e); + } + } + + /** + * Tests mirroring all artifacts in a repository to a repository populated with exact duplicate data + * Source contains A, B + * Target contains A, B + * Expected is A, B + */ + public void testArtifactMirrorToFullDuplicate() { + artifactMirrorToFullDuplicate("3.0", true); //run the test with append set to true + + try { + //verify destination's content + assertContentEquals("3.1", getArtifactRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("3.2", e); + } + } + + /** + * Tests mirroring all artifacts in a repository to a repository populated with exact duplicate data with "-writeMode clean" + * Source contains A, B + * Target contains A, B + * Expected is A, B + */ + public void testArtifactMirrorToFullDuplicateWithClean() { + artifactMirrorToFullDuplicate("4.0", false); + + try { + //verify destination's content + assertContentEquals("4.1", getArtifactRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("4.2", e); + } + } + + /** + * Tests mirroring all artifacts in a repository to a repository populated with non-duplicate entries + * Source contains A, B + * Target contains C, D + * Expected is A, B, C, D + */ + public void testArtifactMirrorToPopulated() { + artifactMirrorToPopulated("5.0", true); //run the test with append set to true + + try { + //verify destination's content + assertContains("5.1", getArtifactRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + assertContains("5.2", getArtifactRepositoryManager().loadRepository(sourceRepo2Location.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + //checks that the destination has the correct number of keys (no extras) + assertEquals("5.3", getArtifactRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null).getArtifactKeys().length + getArtifactRepositoryManager().loadRepository(sourceRepo2Location.toURI(), null).getArtifactKeys().length, getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null).getArtifactKeys().length); + } catch (ProvisionException e) { + fail("5.4", e); + } + } + + /** + * Tests mirroring all artifacts in a repository to a repository populated with non-duplicate entries with "-writeMode clean" + * Source contains A, B + * Target contains C, D + * Expected is A, B + */ + public void testArtifactMirrorToPopulatedWithClean() { + artifactMirrorToPopulated("6.0", false); + + try { + //verify destination's content + assertContentEquals("6.1", getArtifactRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("6.2", e); + } + } + + /** + * Tests mirroring all artifacts in a repository to a repository populated with partially duplicate data + * Source contains A, B, C, D + * Target contains A, B + * Expected is A, B, C, D + */ + public void testArtifactMirrorToPartialDuplicate() { + artifactMirrorToPartialDuplicate("7.0", true); //run the test with append set to true + + try { + //verify destination's content + assertContentEquals("7.1", getArtifactRepositoryManager().loadRepository(sourceRepo3Location.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("7.2", e); + } + } + + /** + * Tests mirroring all artifacts in a repository to a repository populated with partially duplicate data with "-writeMode clean" + * Source contains A, B, C, D + * Target contains A, B + * Expected is A, B, C, D + */ + public void testArtifactMirrorToPartialDuplicateWithClean() { + artifactMirrorToPartialDuplicate("8.0", false); + + try { + //verify destination's content + assertContentEquals("8.1", getArtifactRepositoryManager().loadRepository(sourceRepo3Location.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("8.2", e); + } + } + + /** + * Tests mirroring all artifacts in a repository to a repository populated with both full duplicate and non-duplicate data + * Source contains A, B + * Target contains A, B, C, D + * Expected is A, B, C, D + */ + public void testArtifactMirrorToPopulatedWithFullDuplicate() { + artifactMirrorToPopulatedWithFullDuplicate("9.0", true); //run the test with append set to true + + try { + //verify destination's content + assertContentEquals("9.1", getArtifactRepositoryManager().loadRepository(sourceRepo3Location.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("9.2", e); + } + } + + /** + * Tests mirroring all artifacts in a repository to a repository populated with both full duplicate and non-duplicate data with "-writeMode clean" + * Source contains A, B + * Target contains A, B, C, D + * Expected is A, B + */ + public void testArtifactMirrorToPopulatedWithFullDuplicateWithClean() { + artifactMirrorToPopulatedWithFullDuplicate("10.0", false); + + try { + //verify destination's content + assertContentEquals("10.1", getArtifactRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("10.2", e); + } + } + + /** + * Tests mirroring all artifacts in a repository to a repository populated with both partial duplicate and non-duplicate data + * Source contains A, B, C, D + * Target contains A, B, E, F + * Expected is A, B, C, D, E, F + */ + public void testArtifactMirrorToPopulatedWithPartialDuplicate() { + artifactMirrorToPopulatedWithPartialDuplicate("11.0", true); //run the test with append set to true + + try { + //verify destination's content + assertContains("11.1", getArtifactRepositoryManager().loadRepository(sourceRepo3Location.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + assertContains("11.2", getArtifactRepositoryManager().loadRepository(sourceRepo2Location.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + //checks that the destination has the correct number of keys (no extras) + assertEquals("11.3", getArtifactRepositoryManager().loadRepository(sourceRepo2Location.toURI(), null).getArtifactKeys().length + getArtifactRepositoryManager().loadRepository(sourceRepo3Location.toURI(), null).getArtifactKeys().length, getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null).getArtifactKeys().length); + } catch (ProvisionException e) { + fail("11.4", e); + } + } + + /** + * Tests mirroring all artifacts in a repository to a repository populated with both partial duplicate and non-duplicate data with "-writeMode clean" + * Source contains A, B, C, D + * Target contains A, B, E, F + * Expected is A, B, C, D + */ + public void testArtifactMirrorToPopulatedWithPartialDuplicateWithClean() { + artifactMirrorToPopulatedWithPartialDuplicate("12.0", false); + + try { + //verify destination's content + assertContentEquals("12.1", getArtifactRepositoryManager().loadRepository(sourceRepo3Location.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("12.2", e); + } + } + + /** + * Tests MirrorApplication's behaviour when given an invalid source repository + */ + public void testArtifactMirrorFromInvalid() { + File invalidRepository = new File(getTempFolder(), getUniqueString()); + delete(invalidRepository); + + try { + basicRunMirrorApplication("13.1", invalidRepository.toURI(), destRepoLocation.toURI(), true, false); + //we expect a provision exception to be thrown. We should never get here. + fail("13.0 ProvisionExpection not thrown"); + } catch (ProvisionException e) { + return; //correct type of exception has been thrown + } catch (Exception e) { + fail("13.2", e); + } + } + + /** + * Tests MirrorApplication's behaviour when given an invalid destination repository + */ + public void testArtifactMirrorToInvalid() { + URI invalidDestRepository = null; + try { + //Setup: create a URI pointing to an unmodifiable place + invalidDestRepository = new URI("http://foobar.com/abcdefg"); + + //run the application with the modifiable destination + basicRunMirrorApplication("14.1", sourceRepoLocation.toURI(), invalidDestRepository, true, false); + //we're expecting an UnsupportedOperationException so we should never get here + fail("14.0 UnsupportedOperationException not thrown"); + } catch (ProvisionException e) { + assertEquals("Unexpected error message", NLS.bind(org.eclipse.equinox.p2.internal.repository.tools.Messages.exception_invalidDestination, URIUtil.toUnencodedString(invalidDestRepository)), e.getMessage()); + return; //correct type of exception has been thrown + } catch (Exception e) { + fail("14.2", e); + } finally { + if (invalidDestRepository != null) + getArtifactRepositoryManager().removeRepository(invalidDestRepository); + } + } + + /** + * Tests MirrorApplication's behaviour when given both an invalid source and an invalid destination repository + */ + public void testArtifactMirrorBothInvalid() { + //Setup: create a file that is not a valid repository + File invalidRepository = new File(getTempFolder(), getUniqueString()); + //Setup: delete any leftover data + delete(invalidRepository); + + try { + //Setup: create a URI pointing to an unmodifiable place + URI invalidDestRepository = new URI("http://foobar.com/abcdefg"); + basicRunMirrorApplication("15.1", invalidRepository.toURI(), invalidDestRepository, true, false); + //We expect the ProvisionException to be thrown + fail("15.0 ProvisionException not thrown"); + } catch (ProvisionException e) { + return; //correct type of exception was thrown + } catch (Exception e) { + fail("15.2", e); + } + } + + /** + * Tests mirroring an empty repository to another empty repository + * Source contains + * Target contains + * Expected is + */ + public void testArtifactMirrorEmptyToEmpty() { + File emptyRepository = artifactMirrorEmpty("16.0", true); + + try { + //verify destination's content + assertContentEquals("16.1", getArtifactRepositoryManager().loadRepository(emptyRepository.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("16.2", e); + } + + //remove the emptyRepository + getArtifactRepositoryManager().removeRepository(emptyRepository.toURI()); + //delete any left over data + delete(emptyRepository); + } + + /** + * Tests mirroring an empty repository to a populated repository + * Source contains + * Target contains A, B + * Expected is A, B + */ + public void testArtifactMirrorEmptyToPopulated() { + File emptyRepository = artifactMirrorEmptyToPopulated("17.0", true); + + try { + //verify destination's content + assertContains("17.1", getArtifactRepositoryManager().loadRepository(emptyRepository.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + assertContentEquals("17.2", getArtifactRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("17.3", e); + } + + //remove the empty repository + getArtifactRepositoryManager().removeRepository(emptyRepository.toURI()); + //remove any leftover data + delete(emptyRepository); + } + + /** + * Tests mirroring an empty repository to a populated repository with "-writeMode clean" + * Source contains + * Target contains A, B + * Expected is + */ + public void testArtifactMirrorEmptyToPopulatedWithClean() { + File emptyRepository = artifactMirrorEmptyToPopulated("18.0", false); + + try { + //verify destination's content + assertContentEquals("18.1", getArtifactRepositoryManager().loadRepository(emptyRepository.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("18.2", e); + } + + //remove the empty repository + getArtifactRepositoryManager().removeRepository(emptyRepository.toURI()); + //delete any leftover data + delete(emptyRepository); + } + + /** + * Tests mirroring a repository to itself + * Source contains A, B + * Target contains A, B + * Expected is A, B + */ + public void testArtifactMirrorSourceIsDestination() { + //Setup: Populate the repository + runMirrorApplication("19.0", sourceRepoLocation, destRepoLocation, false); + + //run the application with the source and destination specified to the same place + runMirrorApplication("19.1", destRepoLocation, destRepoLocation, true); + + try { + //verify destination's content + assertContentEquals("19.2", getArtifactRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("19.3", e); + } + } + + /** + * Tests mirroring a repository with a different version of the same package + * Source contains A, B (v1.0.1) + * Target contains A, B (v1.0.0) + * Expected is A, B (v1.0.0) and A, B (v1.0.1) + */ + public void testArtifactMirrorDifferentVersions() { + //Setup: Populate the repository + runMirrorApplication("20.0", sourceRepoLocation, destRepoLocation, false); + + //run the application with the source and destination specified to the same place + runMirrorApplication("20.1", sourceRepo4Location, destRepoLocation, true); + + try { + //verify destination's content + assertContains("20.2", getArtifactRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + assertContains("20.3", getArtifactRepositoryManager().loadRepository(sourceRepo4Location.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + //checks that the destination has the correct number of keys (no extras) + assertEquals("20.4", getArtifactRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null).getArtifactKeys().length + getArtifactRepositoryManager().loadRepository(sourceRepo4Location.toURI(), null).getArtifactKeys().length, getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null).getArtifactKeys().length); + } catch (ProvisionException e) { + fail("20.5", e); + } + } + + /** + * Tests how mirror application handles an unspecified source + */ + public void testArtifactMirrorNullSource() { + try { + basicRunMirrorApplication("21.1", null, destRepoLocation.toURI()); + //We expect the ProvisionException to be thrown + fail("21.3 ProvisionException not thrown"); + } catch (ProvisionException e) { + return; //expected type of exception has been thrown + } catch (Exception e) { + fail("21.2", e); + } + } + + /** + * Tests how mirror application handles an unspecified destination + */ + public void testArtifactMirrorNullDestination() { + try { + basicRunMirrorApplication("22.1", sourceRepoLocation.toURI(), null); + //We expect the ProvisionException to be thrown + fail("22.3 ProvisionException not thrown"); + } catch (ProvisionException e) { + return; //expected type of exception has been thrown + } catch (Exception e) { + fail("22.2", e); + } + } + + /** + * Tests how mirror application handles both an unspecified source and an unspecified destination + */ + public void testArtifactMirrorNullBoth() { + try { + basicRunMirrorApplication("23.0", null, null); + //We expect the ProvisionException to be thrown + fail("23.2 ProvisionException not thrown"); + } catch (ProvisionException e) { + return; //expected type of exception has been thrown + } catch (Exception e) { + fail("23.1", e); + } + } + + /** + * Ensures that a repository created by the mirror application is a copy of the source + */ + public void testNewArtifactRepoProperties() { + //run mirror application with source not preexisting + artifactMirrorToEmpty("24.0", true, true); + + try { + IArtifactRepository sourceRepository = getArtifactRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null); + IArtifactRepository destinationRepository = getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null); + assertEquals("24.1", sourceRepository.getName(), destinationRepository.getName()); + assertRepositoryProperties("24.2", sourceRepository.getProperties(), destinationRepository.getProperties()); + } catch (ProvisionException e) { + fail("24.3", e); + } + } + + /** + * Ensures that a repository created before the mirror application is run does not have its properties changed + */ + public void testExistingArtifactRepoProperties() { + //Setup: create the destination + String name = "Destination Name"; + Map properties = null; //default properties + try { + //create the repository and get the resulting properties + properties = getArtifactRepositoryManager().createRepository(destRepoLocation.toURI(), name, IArtifactRepositoryManager.TYPE_SIMPLE_REPOSITORY, properties).getProperties(); + } catch (ProvisionException e) { + fail("25.0", e); + } + + //run the mirror application + artifactMirrorToEmpty("25.2", true, false); + + try { + IArtifactRepository repository = getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null); + assertEquals("25.3", name, repository.getName()); + assertRepositoryProperties("25.4", properties, repository.getProperties()); + } catch (ProvisionException e) { + fail("25.5", e); + } + } + + /** + * * Ensures that a repository created by the mirror application has specified name + * For Bug 256909 + */ + public void testNewArtifactRepoWithNewName() { + String name = "Bug 256909 test - new"; + try { + basicRunMirrorApplication("Bug 256909 Test", sourceRepoLocation.toURI(), destRepoLocation.toURI(), true, false, name); + } catch (MalformedURLException e) { + fail("Error creating URLs for Source/Detination", e); + } catch (Exception e) { + fail("Error running mirror application", e); + } + + try { + assertEquals("Assert name was set correct", name, getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null).getName()); + } catch (ProvisionException e) { + fail("Cannot obtain destination", e); + } + } + + /** + * Ensures that an existing destination used by the mirror application is given specified name + * For Bug 256909 + */ + public void testExistingArtifactRepoWithNewName() { + String oldName = "The original naem for Bug 256909 test - existing"; + String newName = "Bug 256909 test - existing"; + //Setup create the repository + IArtifactRepository destinationRepo = null; + try { + destinationRepo = getArtifactRepositoryManager().createRepository(destRepoLocation.toURI(), oldName, IArtifactRepositoryManager.TYPE_SIMPLE_REPOSITORY, null); + } catch (ProvisionException e) { + fail("Error creating repo at destination", e); + } + assertEquals("Assert name is set correctly before mirror", oldName, destinationRepo.getName()); + + try { + MirrorApplication app = new MirrorApplication(); + app.addSource(createRepositoryDescriptor(sourceRepoLocation.toURI(), null, null, null)); + app.addDestination(createRepositoryDescriptor(destRepoLocation.toURI(), null, null, newName)); + //run the mirror application + app.run(null); + + } catch (Exception e) { + fail("Error running mirror application", e); + } + + try { + assertEquals("Assert name is set correctly after mirror", newName, getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null).getName()); + } catch (ProvisionException e) { + fail("Error loading destination", e); + } + } + + /** + * Verifies that the mirror application copies files (including packed files) correctly + */ + public void testArtifactFileCopying() { + //Setup: load the repository containing packed data + File packedRepoLocation = getTestData("26.0", "/testData/mirror/mirrorPackedRepo"); + + try { + basicRunMirrorApplication("26.1", packedRepoLocation.toURI(), destRepoLocation.toURI(), false, false); + } catch (Exception e) { + fail("26.3", e); + } + + try { + //Verify Contents + assertContentEquals("26.4", getArtifactRepositoryManager().loadRepository(packedRepoLocation.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + //Verify files on disk + assertFileSizes("26.5", (SimpleArtifactRepository) getArtifactRepositoryManager().loadRepository(packedRepoLocation.toURI(), null), (SimpleArtifactRepository) getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("26.6", e); + } + } + + /** + * Verifies that the mirror application executes processing steps correctly + */ + public void testArtifactProcessingSteps() { + //Setup: load the repository containing packed data + File packedRepoLocation = getTestData("27.0", "/testData/mirror/mirrorPackedRepo"); + IArtifactRepository packedRepo = null; + IArtifactRepository destinationRepo = null; + + try { + packedRepo = getArtifactRepositoryManager().loadRepository(packedRepoLocation.toURI(), null); + destinationRepo = getArtifactRepositoryManager().createRepository(destRepoLocation.toURI(), "Test Repo", IArtifactRepositoryManager.TYPE_SIMPLE_REPOSITORY, null); + } catch (ProvisionException e1) { + fail(""); + } + + IArtifactKey[] keys = packedRepo.getArtifactKeys(); + + for (int i = 0; i < keys.length; i++) { + IArtifactDescriptor[] srcDescriptors = packedRepo.getArtifactDescriptors(keys[i]); + + for (int j = 0; j < srcDescriptors.length; j++) { + if (!(srcDescriptors[j].getProperty(IArtifactDescriptor.FORMAT) == null) && srcDescriptors[j].getProperty(IArtifactDescriptor.FORMAT).equals("packed")) { + //if we have a packed artifact + IArtifactDescriptor newDescriptor = new ArtifactDescriptor(keys[i]); + Map properties = new OrderedProperties(); + properties.putAll(srcDescriptors[j].getProperties()); + properties.remove(IArtifactDescriptor.FORMAT); + ((ArtifactDescriptor) newDescriptor).addProperties(properties); + //create appropriate descriptor + try { + OutputStream repositoryStream = null; + try { + //System.out.println("Mirroring: " + srcDescriptors[j].getArtifactKey() + " (Descriptor: " + srcDescriptors[j] + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + repositoryStream = destinationRepo.getOutputStream(newDescriptor); + if (repositoryStream == null) + return; + // TODO Is that ok to ignore the result? + //TODO MAKE THIS WORK PROPERLY + packedRepo.getArtifact(srcDescriptors[j], repositoryStream, new NullProgressMonitor()); + } finally { + if (repositoryStream != null) + repositoryStream.close(); + } + } catch (ProvisionException e) { + fail("27.1", e); + } catch (IOException e) { + fail("27.2", e); + } + //corresponding key should now be in the destination + IArtifactDescriptor[] destDescriptors = destinationRepo.getArtifactDescriptors(keys[i]); + boolean canonicalFound = false; + for (int l = 0; !canonicalFound && (l < destDescriptors.length); l++) { + //No processing steps mean item is canonical + if (destDescriptors[l].getProcessingSteps().length == 0) + canonicalFound = true; + } + if (!canonicalFound) + fail("27.3 no canonical found for " + keys[i].toString()); + + //ensure the canonical matches that in the expected + assertFileSizes("27.3", (SimpleArtifactRepository) destinationRepo, (SimpleArtifactRepository) packedRepo); + } + } + } + } + + //for Bug 235683 + public void testMirrorCompressedSource() { + File compressedSource = getTestData("0", "/testData/mirror/mirrorCompressedRepo"); + + //Setup: get the artifacts.jar file + File compressedArtifactsXML = new File(compressedSource.getAbsoluteFile() + "/artifacts.jar"); + //Setup: make sure artifacts.jar exists + assertTrue("1", compressedArtifactsXML.exists()); + + try { + basicRunMirrorApplication("2", compressedSource.toURI(), destRepoLocation.toURI(), false, false); + } catch (MalformedURLException e) { + fail("3", e); + } catch (Exception e) { + fail("4", e); + } + + //get the artifacts.jar file + File destArtifactsXML = new File(destRepoLocation.getAbsolutePath() + "/artifacts.jar"); + //make sure artifacts.jar exists + assertTrue("5", destArtifactsXML.exists()); + } + + //for Bug 235683 + public void testMirrorCompressedSourcetoUncompressedDestination() { + File compressedSource = getTestData("0", "/testData/mirror/mirrorCompressedRepo"); + + //Setup: get the artifacts.jar file + File compressedArtifactsXML = new File(compressedSource.getAbsoluteFile() + "/artifacts.jar"); + //Setup: make sure artifacts.jar exists + assertTrue("1", compressedArtifactsXML.exists()); + + //Setup: create the destination + try { + String name = "Destination Name " + destRepoLocation; + getArtifactRepositoryManager().createRepository(destRepoLocation.toURI(), name, IArtifactRepositoryManager.TYPE_SIMPLE_REPOSITORY, null); + } catch (ProvisionException e) { + fail("2", e); + } + + assertTrue("2.1", new File(destRepoLocation, "artifacts.xml").exists()); + try { + basicRunMirrorApplication("3", compressedSource.toURI(), destRepoLocation.toURI(), false, false); + } catch (MalformedURLException e) { + fail("4", e); + } catch (Exception e) { + fail("5", e); + } + + //get the artifacts.jar file + File destArtifactsXML = new File(destRepoLocation.getAbsolutePath() + "/artifacts.jar"); + //make sure artifacts.jar does not exist + assertFalse("6", destArtifactsXML.exists()); + //get the artifacts.xml file + destArtifactsXML = new File(destRepoLocation.getAbsolutePath() + "/artifacts.xml"); + //make sure artifacts.xml exists + assertTrue("7", destArtifactsXML.exists()); + } + + //for Bug 235683 + public void testMirrorUncompressedSourceToCompressedDestination() { + File uncompressedSource = getTestData("0", "/testData/mirror/mirrorPackedRepo"); + + //Setup: get the artifacts.xml file + File artifactsXML = new File(uncompressedSource.getAbsoluteFile() + "/artifacts.xml"); + //Setup: make sure artifacts.xml exists + assertTrue("1", artifactsXML.exists()); + + //Setup: create the destination + try { + String name = "Destination Name " + destRepoLocation; + Map property = new HashMap(); + property.put(IRepository.PROP_COMPRESSED, "true"); + getArtifactRepositoryManager().createRepository(destRepoLocation.toURI(), name, IArtifactRepositoryManager.TYPE_SIMPLE_REPOSITORY, property); + } catch (ProvisionException e) { + fail("2", e); + } + + assertTrue("2.1", new File(destRepoLocation, "artifacts.jar").exists()); + try { + basicRunMirrorApplication("3", uncompressedSource.toURI(), destRepoLocation.toURI(), false, false); + } catch (MalformedURLException e) { + fail("4", e); + } catch (Exception e) { + fail("5", e); + } + + //get the artifacts.jar file + File destArtifactsXML = new File(destRepoLocation.getAbsolutePath() + "/artifacts.jar"); + //make sure artifacts.jar does exist + assertTrue("6", destArtifactsXML.exists()); + //get the artifacts.xml file + destArtifactsXML = new File(destRepoLocation.getAbsolutePath() + "/artifacts.xml"); + //make sure artifacts.xml does not exist + assertFalse("7", destArtifactsXML.exists()); + } + + public void testMirrorApplicationWithCompositeSource() { + //Setup Make composite repository + File repoLocation = new File(getTempFolder(), "CompositeArtifactMirrorTest"); + AbstractProvisioningTest.delete(repoLocation); + IArtifactRepository repo = null; + try { + repo = getArtifactRepositoryManager().createRepository(repoLocation.toURI(), "artifact name", IArtifactRepositoryManager.TYPE_COMPOSITE_REPOSITORY, null); + } catch (ProvisionException e) { + fail("Could not create repository"); + } + //ensure proper type of repository has been created + if (!(repo instanceof CompositeArtifactRepository)) + fail("Repository is not a CompositeArtifactRepository"); + //Populate source + File child1 = getTestData("1", "/testData/mirror/mirrorSourceRepo1 with space"); + File child2 = getTestData("2", "/testData/mirror/mirrorSourceRepo2"); + ((CompositeArtifactRepository) repo).addChild(child1.toURI()); + ((CompositeArtifactRepository) repo).addChild(child2.toURI()); + + runMirrorApplication("Mirroring from Composite Source", repoLocation, destRepoLocation, false); + + try { + assertContentEquals("Verifying contents", repo, getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + + //Verify that result is the same as mirroring from the 2 repositories separately + assertContains("3", getArtifactRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + assertContains("4", getArtifactRepositoryManager().loadRepository(sourceRepo2Location.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + //checks that the destination has the correct number of keys (no extras) + assertEquals("5", getArtifactRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null).getArtifactKeys().length + getArtifactRepositoryManager().loadRepository(sourceRepo2Location.toURI(), null).getArtifactKeys().length, getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null).getArtifactKeys().length); + } catch (ProvisionException e) { + fail("Could not load destination", e); + } + } + + //for Bug 250527 + public void testIgnoreErrorsArgument() { + //Error prints to stderr, redirect that to a file + PrintStream oldErr = System.err; + PrintStream newErr = null; + try { + destRepoLocation.mkdir(); + newErr = new PrintStream(new FileOutputStream(new File(destRepoLocation, "sys.err"))); + } catch (FileNotFoundException e) { + fail("Error redirecting outputs", e); + } + System.setErr(newErr); + + //run test without verbose + mirrorWithError(false); + + System.setErr(oldErr); + newErr.close(); + + try { + assertEquals("Verifying correct number of Keys", 1, getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null).getArtifactKeys().length); + //Because only 1 of the artifacts exists on disk, the number of artifacts in the destination should only be 1. + //Order in which mirror application mirrors artifacts is random. + } catch (ProvisionException e) { + fail("Error laoding destiantion repo", e); + } + } + + public void testCompareUsingMD5Comparator() { + //Setup create descriptors with different md5 values + IArtifactKey dupKey = PublisherHelper.createBinaryArtifactKey("testKeyId", new Version("1.2.3")); + File artifact1 = getTestData("0.0", "/testData/mirror/mirrorSourceRepo1 with space/artifacts.xml"); + File artifact2 = getTestData("0.0", "/testData/mirror/mirrorSourceRepo2/artifacts.xml"); + IArtifactDescriptor descriptor1 = PublisherHelper.createArtifactDescriptor(dupKey, artifact1); + IArtifactDescriptor descriptor2 = PublisherHelper.createArtifactDescriptor(dupKey, artifact2); + + assertEquals("Ensuring Descriptors are the same", descriptor1, descriptor2); + assertNotSame("Ensuring MD5 values are different", descriptor1.getProperty(IArtifactDescriptor.DOWNLOAD_MD5), descriptor2.getProperty(IArtifactDescriptor.DOWNLOAD_MD5)); + + //Setup make repositories + File repo1Location = getTestFolder(getUniqueString()); + File repo2Location = getTestFolder(getUniqueString()); + IArtifactRepository repo1 = null; + IArtifactRepository repo2 = null; + try { + repo1 = getArtifactRepositoryManager().createRepository(repo1Location.toURI(), "Repo 1", IArtifactRepositoryManager.TYPE_SIMPLE_REPOSITORY, null); + repo1.addDescriptor(descriptor1); + repo2 = getArtifactRepositoryManager().createRepository(repo2Location.toURI(), "Repo 2", IArtifactRepositoryManager.TYPE_SIMPLE_REPOSITORY, null); + repo2.addDescriptor(descriptor2); + } catch (ProvisionException e) { + fail("Error creating repositories", e); + } + + //Comparator prints to stderr, redirect that to a file + PrintStream oldErr = System.err; + PrintStream newErr = null; + PrintStream oldOut = System.out; + PrintStream newOut = null; + try { + newErr = new PrintStream(new FileOutputStream(new File(repo2Location, "sys.err"))); + newOut = new PrintStream(new FileOutputStream(new File(repo2Location, "sys.out"))); + } catch (FileNotFoundException e) { + fail("Error redirecting outputs", e); + } + System.setErr(newErr); + System.setOut(newOut); + MirrorApplication app = null; + try { + app = new MirrorApplication(); + app.addSource(createRepositoryDescriptor(repo1Location.toURI(), null, null, null)); + app.addDestination(createRepositoryDescriptor(repo2Location.toURI(), null, null, null)); + app.setVerbose(true); + //Set compare flag. + app.setCompare(true); + //run the mirror application + app.run(null); + } catch (Exception e) { + fail("Running mirror application with duplicate descriptors with different md5 values failed", e); + } + System.setErr(oldErr); + newErr.close(); + System.setOut(oldOut); + newOut.close(); + + IArtifactDescriptor[] destDescriptors = repo2.getArtifactDescriptors(descriptor2.getArtifactKey()); + assertEquals("Ensuring destination has correct number of descriptors", 1, destDescriptors.length); + assertEquals("Ensuring proper descriptor exists in destination", descriptor2.getProperty(IArtifactDescriptor.DOWNLOAD_MD5), destDescriptors[0].getProperty(IArtifactDescriptor.DOWNLOAD_MD5)); + String msg = NLS.bind(Messages.warning_differentMD5, new Object[] {URIUtil.toUnencodedString(repo1.getLocation()), URIUtil.toUnencodedString(repo2.getLocation()), descriptor1}); + try { + assertLogContainsLine(TestActivator.getLogFile(), msg); + } catch (Exception e) { + fail("error verifying output", e); + } + } + + public void testBaselineCompareUsingMD5Comparator() { + //Setup create descriptors with different md5 values + IArtifactKey dupKey = PublisherHelper.createBinaryArtifactKey("testKeyId", new Version("1.2.3")); + File artifact1 = getTestData("0.0", "/testData/mirror/mirrorSourceRepo1 with space/content.xml"); + File artifact2 = getTestData("0.0", "/testData/mirror/mirrorSourceRepo2/content.xml"); + + //Setup Copy the file to the baseline + File repoLocation = getTestFolder(getUniqueString()); + File baselineLocation = getTestFolder(getUniqueString()); + File baselineBinaryDirectory = new File(baselineLocation, "binary"); + baselineBinaryDirectory.mkdir(); + File baselineContentLocation = new File(baselineBinaryDirectory, "testKeyId_1.2.3"); + AbstractProvisioningTest.copy("Copying File to baseline", artifact2, baselineContentLocation); + + IArtifactDescriptor descriptor1 = PublisherHelper.createArtifactDescriptor(dupKey, artifact1); + IArtifactDescriptor descriptor2 = PublisherHelper.createArtifactDescriptor(dupKey, baselineContentLocation); + + assertEquals("Ensuring Descriptors are the same", descriptor1, descriptor2); + assertNotSame("Ensuring MD5 values are different", descriptor1.getProperty(IArtifactDescriptor.DOWNLOAD_MD5), descriptor2.getProperty(IArtifactDescriptor.DOWNLOAD_MD5)); + + //Setup make repositories + IArtifactRepository repo = null; + IArtifactRepository baseline = null; + try { + repo = getArtifactRepositoryManager().createRepository(repoLocation.toURI(), "Repo 1", IArtifactRepositoryManager.TYPE_SIMPLE_REPOSITORY, null); + repo.addDescriptor(descriptor1); + baseline = getArtifactRepositoryManager().createRepository(baselineLocation.toURI(), "Repo 2", IArtifactRepositoryManager.TYPE_SIMPLE_REPOSITORY, null); + baseline.addDescriptor(descriptor2); + } catch (ProvisionException e) { + fail("Error creating repositories", e); + } + + //Comparator prints to stderr, redirect that to a file + PrintStream oldErr = System.err; + PrintStream newErr = null; + PrintStream oldOut = System.out; + PrintStream newOut = null; + try { + destRepoLocation.mkdir(); + newErr = new PrintStream(new FileOutputStream(new File(destRepoLocation, "sys.err"))); + newOut = new PrintStream(new FileOutputStream(new File(destRepoLocation, "sys.out"))); + } catch (FileNotFoundException e) { + fail("Error redirecting outputs", e); + } + System.setErr(newErr); + System.setOut(newOut); + MirrorApplication app = null; + try { + app = new MirrorApplication(); + app.addSource(createRepositoryDescriptor(repoLocation.toURI(), null, null, null)); + app.addDestination(createRepositoryDescriptor(destRepoLocation.toURI(), null, null, null)); + //Set baseline + app.setBaseline(baselineLocation.toURI()); + app.setVerbose(true); + //Set compare flag. + app.setCompare(true); + //run the mirror application + app.run(null); + } catch (Exception e) { + fail("Running mirror application with baseline compare", e); + } + System.setErr(oldErr); + newErr.close(); + System.setOut(oldOut); + newOut.close(); + + IArtifactRepository destination = null; + try { + destination = getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null); + } catch (ProvisionException e) { + fail("Error loading destination", e); + } + + IArtifactDescriptor[] destDescriptors = destination.getArtifactDescriptors(descriptor2.getArtifactKey()); + assertEquals("Ensuring destination has correct number of descriptors", 1, destDescriptors.length); + assertEquals("Ensuring destination contains the descriptor from the baseline", descriptor2.getProperty(IArtifactDescriptor.DOWNLOAD_MD5), destDescriptors[0].getProperty(IArtifactDescriptor.DOWNLOAD_MD5)); + String msg = NLS.bind(Messages.warning_differentMD5, new Object[] {URIUtil.toUnencodedString(baseline.getLocation()), URIUtil.toUnencodedString(repo.getLocation()), descriptor1}); + try { + assertLogContainsLine(TestActivator.getLogFile(), msg); + } catch (Exception e) { + fail("error verifying output", e); + } + } + + //for Bug 259111 + public void testDownloadRetry() { + //repository that is known to force a retry + class TestRetryArtifactRepository extends SimpleArtifactRepository { + public boolean firstAttempt = true; + IArtifactRepository source; + + public TestRetryArtifactRepository(String repositoryName, URI location, URI srcLocation, Map properties, IArtifactRepositoryManager manager) { + super(repositoryName, location, properties); + + //initialize + try { + source = manager.loadRepository(srcLocation, null); + } catch (ProvisionException e) { + fail("Unable to load source for wrapping", e); + } + manager.removeRepository(srcLocation); + } + + public synchronized IArtifactKey[] getArtifactKeys() { + return source.getArtifactKeys(); + } + + public synchronized IArtifactDescriptor[] getArtifactDescriptors(IArtifactKey key) { + return source.getArtifactDescriptors(key); + } + + public IStatus getRawArtifact(IArtifactDescriptor descriptor, OutputStream destination, IProgressMonitor monitor) { + if (firstAttempt) { + firstAttempt = false; + return new Status(IStatus.ERROR, Activator.ID, IArtifactRepository.CODE_RETRY, "Forcing Retry", new ProvisionException("Forcing retry")); + } + + return source.getRawArtifact(descriptor, destination, monitor); + } + + public synchronized boolean contains(IArtifactDescriptor descriptor) { + return source.contains(descriptor); + } + } + + //set up test repository + File retryRepoLoaction = new File(getTempFolder(), "259111 Repo"); + IArtifactRepository retryRepo = new TestRetryArtifactRepository("Test Repo", retryRepoLoaction.toURI(), sourceRepoLocation.toURI(), null, getArtifactRepositoryManager()); + ((ArtifactRepositoryManager) getArtifactRepositoryManager()).addRepository(retryRepo); + + try { + basicRunMirrorApplication("Forcing Retry", retryRepo.getLocation(), destRepoLocation.toURI()); + } catch (MalformedURLException e) { + fail("Error creating arguments", e); + } catch (Exception e) { + fail("Error while running Mirror Application and forcing retry", e); + } + + //ensure error was resulted + assertFalse(((TestRetryArtifactRepository) retryRepo).firstAttempt); + try { + //verify destination's content + assertContentEquals("Verifying content", getArtifactRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("Failure while verifying destination", e); + } + } + + //for Bug 259112 + public void testErrorLoggingNoVerbose() { + //initialize log file + FrameworkLog log = (FrameworkLog) ServiceHelper.getService(Activator.getContext(), FrameworkLog.class.getName()); + assertNotNull("Assert log file is not null", log); + assertTrue("Clearing log file", log.getFile().delete()); + + //Comparator prints to stderr, redirect that to a file + PrintStream oldErr = System.err; + PrintStream newErr = null; + try { + destRepoLocation.mkdir(); + newErr = new PrintStream(new FileOutputStream(new File(destRepoLocation, "sys.err"))); + } catch (FileNotFoundException e) { + fail("Error redirecting outputs", e); + } + System.setErr(newErr); + + //run test without verbose resulting in error + mirrorWithError(false); + + System.setErr(oldErr); + newErr.close(); + + //verify log + try { + String[] parts = new String[] {"java.io.FileNotFoundException: ", "helloworld_1.0.0.jar"}; + assertLogContainsLine(log.getFile(), parts); + } catch (Exception e) { + fail("error verifying output", e); + } + + //run without verbose + artifactMirrorToFullDuplicate("Generating INFO entries", true); + + IArtifactRepository sourceRepository = null; + try { + sourceRepository = getArtifactRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null); + } catch (ProvisionException e) { + fail("Error loading source repository for verification", e); + } + + try { + //Mirroring full duplicate, so any key will do. + IArtifactDescriptor[] descriptors = sourceRepository.getArtifactDescriptors(sourceRepository.getArtifactKeys()[0]); + //Mirroring full duplicate, so any descriptor will do. + String message = NLS.bind(org.eclipse.equinox.internal.p2.artifact.repository.Messages.mirror_alreadyExists, descriptors[0], destRepoLocation.toURI()); + assertLogDoesNotContainLine(log.getFile(), message); + } catch (Exception e) { + fail("Error verifying log", e); + } + } + + //for Bug 259112 + public void testErrorLoggingWithVerbose() { + //initialize log file + FrameworkLog log = (FrameworkLog) ServiceHelper.getService(Activator.getContext(), FrameworkLog.class.getName()); + assertNotNull("Assert log file is not null", log); + assertTrue("Clearing log file", log.getFile().exists() && log.getFile().delete()); + + //Comparator prints to stdout, redirect that to a file + PrintStream oldOut = System.out; + PrintStream newOut = null; + PrintStream oldErr = System.err; + PrintStream newErr = null; + try { + destRepoLocation.mkdir(); + newOut = new PrintStream(new FileOutputStream(new File(destRepoLocation, "sys.out"))); + newErr = new PrintStream(new FileOutputStream(new File(destRepoLocation, "sys.err"))); + } catch (FileNotFoundException e) { + fail("Error redirecting output", e); + } + System.setOut(newOut); + System.setErr(newErr); + + //run test with verbose, results in error + mirrorWithError(true); + + //verify log + try { + String[] parts = new String[] {"java.io.FileNotFoundException: ", "helloworld_1.0.0.jar"}; + assertLogContainsLine(log.getFile(), parts); + } catch (Exception e) { + fail("error verifying output", e); + } + + //run with verbose + //populate destination with duplicate artifacts. We assume this works + runMirrorApplication("Initializing Destiantion", sourceRepoLocation, destRepoLocation, false); //value of append should not matter + + try { + MirrorApplication app = new MirrorApplication(); + app.addSource(createRepositoryDescriptor(sourceRepoLocation.toURI(), null, null, null)); + app.addDestination(createRepositoryDescriptor(destRepoLocation.toURI(), null, null, null)); + //set the arguments with verbose + app.setVerbose(true); + //run the mirror application + app.run(null); + } catch (Exception e) { + fail("Error running mirror application to generate INFO items", e); + } + + System.setOut(oldOut); + newOut.close(); + System.setErr(oldErr); + newErr.close(); + + IArtifactRepository sourceRepository = null; + try { + sourceRepository = getArtifactRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null); + } catch (ProvisionException e) { + fail("Error loading source repository for verification", e); + } + + try { + //Mirroring full duplicate, so any key will do. + IArtifactDescriptor[] descriptors = sourceRepository.getArtifactDescriptors(sourceRepository.getArtifactKeys()[0]); + //Mirroring full duplicate, so any descriptor will do. + String message = NLS.bind(org.eclipse.equinox.internal.p2.artifact.repository.Messages.mirror_alreadyExists, descriptors[0], destRepoLocation.toURI()); + assertLogContainsLine(log.getFile(), message); + } catch (Exception e) { + fail("Error verifying log", e); + } + } + + /** + * Test how the mirror application handles a repository specified as a local path + */ + public void testArtifactMirrorNonURIDest() { + try { + basicRunMirrorApplication("Mirroring", sourceRepoLocation.toURI(), destRepoLocation.toURI()); + assertContentEquals("2.1", getArtifactRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getArtifactRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (Exception e) { + fail("Error mirroring", e); + } + } +}
\ No newline at end of file diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/mirror/NewMirrorApplicationMetadataTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/mirror/NewMirrorApplicationMetadataTest.java new file mode 100644 index 000000000..1a291027c --- /dev/null +++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/mirror/NewMirrorApplicationMetadataTest.java @@ -0,0 +1,967 @@ +/******************************************************************************* + * Copyright (c) 2008, 2009 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.equinox.p2.tests.mirror; + +import java.io.File; +import java.net.*; +import java.util.HashMap; +import java.util.Map; +import org.eclipse.equinox.internal.p2.metadata.repository.CompositeMetadataRepository; +import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException; +import org.eclipse.equinox.internal.provisional.p2.metadata.IInstallableUnit; +import org.eclipse.equinox.internal.provisional.p2.metadata.query.InstallableUnitQuery; +import org.eclipse.equinox.internal.provisional.p2.metadata.repository.IMetadataRepository; +import org.eclipse.equinox.internal.provisional.p2.metadata.repository.IMetadataRepositoryManager; +import org.eclipse.equinox.internal.provisional.p2.query.Collector; +import org.eclipse.equinox.internal.provisional.p2.repository.IRepository; +import org.eclipse.equinox.internal.simpleconfigurator.utils.URIUtil; +import org.eclipse.equinox.p2.internal.repository.tools.MirrorApplication; +import org.eclipse.equinox.p2.internal.repository.tools.RepositoryDescriptor; +import org.eclipse.equinox.p2.tests.AbstractProvisioningTest; +import org.eclipse.osgi.util.NLS; + +/* + * Modified from MetadataMirrorApplicationTest + */ +public class NewMirrorApplicationMetadataTest extends AbstractProvisioningTest { + protected File destRepoLocation; + protected File sourceRepoLocation; //helloworldfeature + protected File sourceRepo2Location; //anotherfeature + protected File sourceRepo3Location; //helloworldfeature + yetanotherfeature + protected File sourceRepo4Location; //helloworldfeature v1.0.1 + + protected Exception exception = null; + + /* (non-Javadoc) + * @see org.eclipse.equinox.p2.tests.AbstractProvisioningTest#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + //load all the repositories + sourceRepoLocation = getTestData("0.0", "/testData/mirror/mirrorSourceRepo1 with space"); + sourceRepo2Location = getTestData("0.1", "/testData/mirror/mirrorSourceRepo2"); + sourceRepo3Location = getTestData("0.2", "/testData/mirror/mirrorSourceRepo3"); + sourceRepo4Location = getTestData("0.3", "/testData/mirror/mirrorSourceRepo4"); + + //create destination location + destRepoLocation = new File(getTempFolder(), "BasicMirrorApplicationTest"); + AbstractProvisioningTest.delete(destRepoLocation); + } + + /* (non-Javadoc) + * @see org.eclipse.equinox.p2.tests.AbstractProvisioningTest#tearDown() + */ + protected void tearDown() throws Exception { + //remove all the repositories + getMetadataRepositoryManager().removeRepository(destRepoLocation.toURI()); + getMetadataRepositoryManager().removeRepository(sourceRepoLocation.toURI()); + getMetadataRepositoryManager().removeRepository(sourceRepo2Location.toURI()); + getMetadataRepositoryManager().removeRepository(sourceRepo3Location.toURI()); + getMetadataRepositoryManager().removeRepository(sourceRepo4Location.toURI()); + exception = null; + //delete the destination location (no left over files for the next test) + delete(destRepoLocation); + super.tearDown(); + } + + /** + * Runs mirror application with default arguments. source is the source repo, + * destination is the destination repo, append is if the "-writeMode clean" argument should be excluded + * + * Note: We use URL here because command line applications traffic in unencoded URLs, + * so we can't use java.net.URI which will always use the encoded form + */ + private void basicRunMirrorApplication(String message, URL source, URL destination, boolean append) throws Exception { + MirrorApplication app = new MirrorApplication(); + + if (destination != null) { + RepositoryDescriptor dest = new RepositoryDescriptor(); + dest.setLocation(URIUtil.fromString(destination.toExternalForm())); + dest.setAppend(append); + dest.setKind("metadata"); + app.addDestination(dest); + } + + if (source != null) { + RepositoryDescriptor src = new RepositoryDescriptor(); + src.setLocation(URIUtil.fromString(source.toExternalForm())); + src.setKind("metadata"); + app.addSource(src); + } + app.run(null); + } + + private void basicRunMirrorApplication(String message, URL source, URL destination, boolean append, String name) throws Exception { + MirrorApplication app = new MirrorApplication(); + + if (destination != null) { + RepositoryDescriptor dest = new RepositoryDescriptor(); + dest.setLocation(URIUtil.fromString(destination.toExternalForm())); + dest.setAppend(append); + dest.setKind("metadata"); + dest.setName(name); + app.addDestination(dest); + } + + if (source != null) { + RepositoryDescriptor src = new RepositoryDescriptor(); + src.setLocation(URIUtil.fromString(source.toExternalForm())); + src.setKind("metadata"); + app.addSource(src); + } + app.run(null); + } + + /** + * just a wrapper method for compatibility + */ + private void runMirrorApplication(String message, File source, File destination, boolean append) { + try { + basicRunMirrorApplication(message, source.toURL(), destination.toURL(), append); + } catch (Exception e) { + fail(message, e); + } + } + + /** + * Takes 2 collectors, compares them, and returns the number of unique keys + * Needed to verify that only the appropriate number of files have been transfered by the mirror application + */ + private int getNumUnique(Collector c1, Collector c2) { + Object[] repo1 = c1.toCollection().toArray(); + Object[] repo2 = c2.toCollection().toArray(); + + //initialize to the size of both collectors + int numKeys = repo1.length + repo2.length; + + for (int i = 0; i < repo1.length; i++) { + for (int j = 0; j < repo2.length; j++) { + if (isEqual((IInstallableUnit) repo1[i], (IInstallableUnit) repo2[j])) + numKeys--; + //identical keys has bee found, therefore the number of unique keys is one less than previously thought + } + } + return numKeys; + } + + /** + * Tests mirroring all metadata in a repository to an empty repository + * Source contains A, B + * Target contains + */ + private void metadataMirrorToEmpty(String message, boolean append) { + //destination repo is created blank + runMirrorApplication(message + ".0", sourceRepoLocation, destRepoLocation, append); //do not append + } + + /** + * Tests mirroring all metadata in a repository to a repository populated with non-duplicate entries + * Source contains A, B + * Target contains C, D + */ + private void metadataMirrorToPopulated(String message, boolean append) { + //Setup: populate destination with non-duplicate metadata + runMirrorApplication(message + ".0", sourceRepo2Location, destRepoLocation, false); //value of append does not matter + + try { + //Setup: ensure setup completed successfully + assertContentEquals(message + ".1", getMetadataRepositoryManager().loadRepository(sourceRepo2Location.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail(message + ".2", e); + } + + //mirror test data + runMirrorApplication(message + ".4", sourceRepoLocation, destRepoLocation, append); + } + + /** + * Tests mirroring all metadata in a repository to a repository populated with exact duplicate data + * @throws Exception + * Source contains A, B + * Target contains A, B + */ + private void metadataMirrorToFullDuplicate(String message, boolean append) { + //Setup: populate destination with duplicate metadata + runMirrorApplication(message + ".0", sourceRepoLocation, destRepoLocation, false); //value of append does not matter + + try { + //Setup: verify contents + assertContentEquals(message + ".1", getMetadataRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail(message + ".2", e); + } + + //mirror test data + runMirrorApplication(message + ".4", sourceRepoLocation, destRepoLocation, append); + } + + /** + * Tests mirroring all metadata in a repository to a repository populated with partially duplicate data + * Source contains A, B, C, D + * Target contains A, B + */ + private void metadataMirrorToPartialDuplicate(String message, boolean append) { + //Setup: populate destination with duplicate metadata + runMirrorApplication(message + ".0", sourceRepoLocation, destRepoLocation, false); //value of append does not matter + + try { + //Setup: verify contents + assertContentEquals(message + ".1", getMetadataRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail(message + ".2", e); + } + + //mirror test data + runMirrorApplication(message + ".4", sourceRepo3Location, destRepoLocation, append); + } + + /** + * Tests mirroring all metadata in a repository to a repository populated with both full duplicate and non-duplicate data + * Source contains A, B + * Target contains A, B, C, D + */ + private void metadataMirrorToPopulatedWithFullDuplicate(String message, boolean append) { + //Setup: populate destination with non-duplicate metadata + runMirrorApplication(message + ".0", sourceRepo3Location, destRepoLocation, false); //value of append does not matter + + try { + //Setup: verify + assertContentEquals(message + ".1", getMetadataRepositoryManager().loadRepository(sourceRepo3Location.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail(message + ".2", e); + } + + //mirror duplicate data + runMirrorApplication(message + ".4", sourceRepoLocation, destRepoLocation, append); + } + + /** + * Tests mirroring all metadata in a repository to a repository populated with both partial duplicate and non-duplicate data + * Source contains A, B, C, D + * Target contains A, B, E, F + */ + private void metadataMirrorToPopulatedWithPartialDuplicate(String message, boolean append) { + //Setup: populate destination with non-duplicate metadata + runMirrorApplication(message + ".0", sourceRepo2Location, destRepoLocation, false); //value of append does not matter + + try { + //Setup: verify + assertContentEquals(message + ".1", getMetadataRepositoryManager().loadRepository(sourceRepo2Location.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail(message + ".2", e); + } + + //Setup: populate destination with duplicate metadata + runMirrorApplication(message + ".4", sourceRepoLocation, destRepoLocation, true); + + try { + //Setup: verify + assertContains(message + ".5", getMetadataRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + assertContains(message + ".6", getMetadataRepositoryManager().loadRepository(sourceRepo2Location.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail(message + ".7", e); + } + + //mirror duplicate data + runMirrorApplication(message + ".7", sourceRepo3Location, destRepoLocation, append); + } + + /** + * Tests mirroring all artifacts in a repository to an empty repository + * Source contains A, B + * Target contains + */ + private File metadataMirrorEmpty(String message, boolean append) { + //Setup: Create an empty repository + File emptyRepository = new File(getTempFolder(), getUniqueString()); + //Setup: remove repository if it exists + getMetadataRepositoryManager().removeRepository(emptyRepository.toURI()); + //Setup: delete any data that may be in the folder + AbstractProvisioningTest.delete(emptyRepository); + try { + getMetadataRepositoryManager().createRepository(emptyRepository.toURI(), "Empty Repository", IMetadataRepositoryManager.TYPE_SIMPLE_REPOSITORY, null); + } catch (ProvisionException e) { + fail(message + ".1", e); + } + + try { + basicRunMirrorApplication(message + ".0", emptyRepository.toURL(), destRepoLocation.toURL(), append); + } catch (Exception e) { + exception = e; + } + + return emptyRepository; //return the repository for use in verification + } + + /** + * Tests mirroring all metadata from an empty repository + * Source contains + */ + private File metadataMirrorEmptyToPopulated(String message, boolean append) { + //Setup: Populate the repository + runMirrorApplication(message + ".0", sourceRepoLocation, destRepoLocation, false); + + return metadataMirrorEmpty(message + ".1", append); //create the empty repository, perform the mirror, pass the result back + } + + /** + * Tests mirroring all metadata in a repository to an empty repository + * Source contains A, B + * Target contains + * Expected is A, B + */ + public void testMetadataMirrorToEmpty() { + metadataMirrorToEmpty("1.0", true); //run the test with append set to true + + try { + //verify destination's content + assertContentEquals("1.1", getMetadataRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("1.2", e); + } + } + + /** + * Tests mirroring all metadata in a repository to an empty repository with "-writeMode clean" + * Source contains A, B + * Target contains + * Expected is A, B + */ + public void testMetadataMirrorToEmptyWithClean() { + metadataMirrorToEmpty("2.0", false); //run the test with append set to false + + try { + //verify destination's content + assertContentEquals("2.1", getMetadataRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("2.2", e); + } + } + + /** + * Tests mirroring all metadata in a repository to a repository populated with exact duplicate data + * Source contains A, B + * Target contains A, B + * Expected is A, B + */ + public void testMetadataMirrorToFullDuplicate() { + metadataMirrorToFullDuplicate("3.0", true); //run the test with append set to true + + try { + //verify destination's content + assertContentEquals("3.1", getMetadataRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("3.2", e); + } + } + + /** + * Tests mirroring all metadata in a repository to a repository populated with exact duplicate data with "-writeMode clean" + * Source contains A, B + * Target contains A, B + * Expected is A, B + */ + public void testMetadataMirrorToFullDuplicateWithClean() { + metadataMirrorToFullDuplicate("4.0", false); //run the test with append set to false + + try { + //verify destination's content + assertContentEquals("4.1", getMetadataRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("4.2", e); + } + } + + /** + * Tests mirroring all metadata in a repository to a repository populated with non-duplicate entries + * Source contains A, B + * Target contains C, D + * Expected is A, B, C, D + */ + public void testMetadataMirrorToPopulated() { + metadataMirrorToPopulated("5.0", true); //run the test with append set to true + + try { + //verify destination's content + assertContains("5.1", getMetadataRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + assertContains("5.2", getMetadataRepositoryManager().loadRepository(sourceRepo2Location.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + //checks that the destination has the correct number of keys (no extras) + assertEquals("5.3", getNumUnique(getMetadataRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null).query(InstallableUnitQuery.ANY, new Collector(), null), getMetadataRepositoryManager().loadRepository(sourceRepo2Location.toURI(), null).query(InstallableUnitQuery.ANY, new Collector(), null)), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null).query(InstallableUnitQuery.ANY, new Collector(), null).size()); + } catch (ProvisionException e) { + fail("5.4", e); + } + } + + /** + * Tests mirroring all metadata in a repository to a repository populated with non-duplicate entries with "-writeMode clean" + * Source contains A, B + * Target contains C, D + * Expected is A, B + */ + public void testMetadataMirrorToPopulatedWithClean() { + metadataMirrorToPopulated("6.0", false); //run the test with append set to false + + try { + //verify destination's content + assertContentEquals("6.1", getMetadataRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("6.2", e); + } + } + + /** + * Tests mirroring all metadata in a repository to a repository populated with partially duplicate data + * Source contains A, B, C, D + * Target contains A, B + * Expected is A, B, C, D + */ + public void testMetadataMirrorToPartialDuplicate() { + metadataMirrorToPartialDuplicate("7.0", true); //run the test with append set to true + + try { + //verify destination's content + assertContentEquals("7.1", getMetadataRepositoryManager().loadRepository(sourceRepo3Location.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("7.2", e); + } + } + + /** + * Tests mirroring all metadata in a repository to a repository populated with partially duplicate data with "-writeMode clean" + * Source contains A, B, C, D + * Target contains A, B + * Expected is A, B, C, D + */ + public void testMetadataMirrorToPartialDuplicateWithClean() { + metadataMirrorToPartialDuplicate("8.0", false); //run the test with append set to false + + try { + //verify destination's content + assertContentEquals("8.1", getMetadataRepositoryManager().loadRepository(sourceRepo3Location.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("8.2", e); + } + } + + /** + * Tests mirroring all metadata in a repository to a repository populated with both full duplicate and non-duplicate data + * Source contains A, B + * Target contains A, B, C, D + * Expected is A, B, C, D + */ + public void testMetadataMirrorToPopulatedWithFullDuplicate() { + metadataMirrorToPopulatedWithFullDuplicate("9.0", true); //run the test with append set to true + + try { + //verify destination's content + assertContentEquals("9.1", getMetadataRepositoryManager().loadRepository(sourceRepo3Location.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("9.2", e); + } + } + + /** + * Tests mirroring all metadata in a repository to a repository populated with both full duplicate and non-duplicate data with "-writeMode clean" + * Source contains A, B + * Target contains A, B, C, D + * Expected is A, B + */ + public void testMetadataMirrorToPopulatedWithFullDuplicateWithClean() { + metadataMirrorToPopulatedWithFullDuplicate("10.0", false); //run the test with append set to false + + try { + //verify destination's content + assertContentEquals("10.1", getMetadataRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("10.2", e); + } + } + + /** + * Tests mirroring all metadata in a repository to a repository populated with both partial duplicate and non-duplicate data + * Source contains A, B, C, D + * Target contains A, B, E, F + * Expected is A, B, C, D, E, F + */ + public void testMetadataMirrorToPopulatedWithPartialDuplicate() { + metadataMirrorToPopulatedWithPartialDuplicate("11.0", true); //run the test with append set to true + + try { + //verify destination's content + assertContains("11.1", getMetadataRepositoryManager().loadRepository(sourceRepo3Location.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + assertContains("11.2", getMetadataRepositoryManager().loadRepository(sourceRepo2Location.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + //checks that the destination has the correct number of keys (no extras) + assertEquals("11.3", getNumUnique(getMetadataRepositoryManager().loadRepository(sourceRepo2Location.toURI(), null).query(InstallableUnitQuery.ANY, new Collector(), null), getMetadataRepositoryManager().loadRepository(sourceRepo3Location.toURI(), null).query(InstallableUnitQuery.ANY, new Collector(), null)), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null).query(InstallableUnitQuery.ANY, new Collector(), null).size()); + } catch (ProvisionException e) { + fail("11.4", e); + } + } + + /** + * Tests mirroring all metadata in a repository to a repository populated with both partial duplicate and non-duplicate data with "-writeMode clean" + * Source contains A, B, C, D + * Target contains A, B, E, F + * Expected is A, B, C, D + */ + public void testMetadataMirrorToPopulatedWithPartialDuplicateWithClean() { + metadataMirrorToPopulatedWithPartialDuplicate("12.0", false); //run the test with append set to false + + try { + //verify destination's content + assertContentEquals("12.1", getMetadataRepositoryManager().loadRepository(sourceRepo3Location.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("12.2", e); + } + } + + /** + * Tests MirrorApplication's behaviour when given an invalid source repository + */ + public void testMetadataMirrorFromInvalid() { + //get a temp folder + File invalidRepository = new File(getTempFolder(), getUniqueString()); + //delete any data that may exist in that temp folder + delete(invalidRepository); + + try { + basicRunMirrorApplication("13.1", invalidRepository.toURL(), destRepoLocation.toURL(), true); + //we expect a provisioning exception to be thrown and should never get here + fail("13.0 ProvisionExpection not thrown"); + } catch (ProvisionException e) { + return; //correct type of exception has been received + } catch (Exception e) { + fail("13.2", e); + } + } + + /** + * Tests MirrorApplication's behaviour when given an invalid destination repository + */ + public void testMetadataMirrorToInvalid() { + URI invalidDestRepository = null; + try { + invalidDestRepository = new URI("http://foobar.com/abcdefg"); + basicRunMirrorApplication("14.1", sourceRepoLocation.toURL(), invalidDestRepository.toURL(), true); + //we expect an illegal state exception to be thrown and should never get here + fail("14.0 IllegalStateExpection not thrown"); + } catch (ProvisionException e) { + assertEquals("Unexpected error message", NLS.bind(org.eclipse.equinox.p2.internal.repository.tools.Messages.exception_invalidDestination, URIUtil.toUnencodedString(invalidDestRepository)), e.getMessage()); + return; //correct type of exception has been thrown + } catch (Exception e) { + fail("14.1", e); + } finally { + if (invalidDestRepository != null) + getArtifactRepositoryManager().removeRepository(invalidDestRepository); + } + } + + /** + * Tests MirrorApplication's behaviour when given both an invalid source and an invalid destination repository + */ + public void testMetadataMirrorBothInvalid() { + File invalidRepository = new File(getTempFolder(), getUniqueString()); + delete(invalidRepository); + + try { + URI invalidDestRepository = new URI("http://foobar.com/abcdefg"); + basicRunMirrorApplication("15.1", invalidRepository.toURL(), invalidDestRepository.toURL(), true); + //we expect a provisioning exception to be thrown and should never get here + fail("15.0 ProvisionExpection not thrown"); + } catch (ProvisionException e) { + return; //correct type of exception has been thrown + } catch (Exception e) { + fail("15.2", e); + } + } + + /** + * Tests mirroring an empty repository to another empty repository + * Source contains + * Target contains + * Expected is + */ + public void testMetadataMirrorEmptyToEmpty() { + File emptyRepository = null; + try { + emptyRepository = metadataMirrorEmptyToPopulated("19.0", false); + assertTrue("Unexpected exception type", exception instanceof ProvisionException); + + try { + //verify destination's content + assertContentEquals("16.1", getMetadataRepositoryManager().loadRepository(emptyRepository.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("16.2", e); + } + } finally { + if (emptyRepository != null) { + //remove the empty repository + getMetadataRepositoryManager().removeRepository(emptyRepository.toURI()); + //delete any leftover data + delete(emptyRepository); + } + } + } + + /** + * Tests mirroring an empty repository to a populated repository + * Source contains + * Target contains A, B + * Expected is A, B + */ + public void testArtifactMirrorEmptyToPopulated() { + File emptyRepository = null; + try { + emptyRepository = metadataMirrorEmptyToPopulated("17.0", true); + assertTrue("Unexpected exception type", exception instanceof ProvisionException); + + try { + //verify destination's content + assertContains("17.1", getMetadataRepositoryManager().loadRepository(emptyRepository.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + assertContentEquals("17.2", getMetadataRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("17.3", e); + } + } finally { + if (emptyRepository != null) { + //remove the empty repository + getMetadataRepositoryManager().removeRepository(emptyRepository.toURI()); + //delete any leftover data + delete(emptyRepository); + } + } + } + + /** + * Tests mirroring an empty repository to a populated repository with "-writeMode clean" + * Source contains + * Target contains A, B + * Expected is + */ + public void testArtifactMirrorEmptyToPopulatedWithClean() { + File emptyRepository = null; + try { + emptyRepository = metadataMirrorEmptyToPopulated("18.0", false); + assertTrue("Unexpected exception type", exception instanceof ProvisionException); + + try { + //verify destination's content + assertContentEquals("18.1", getMetadataRepositoryManager().loadRepository(emptyRepository.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("18.2", e); + } + } finally { + //remove the empty repository + getMetadataRepositoryManager().removeRepository(emptyRepository.toURI()); + //delete any leftover data + delete(emptyRepository); + } + } + + /** + * Tests mirroring a repository to itself + * Source contains A, B + * Target contains A, B + * Expected is A, B + */ + public void testArtifactMirrorSourceIsDestination() { + //Setup: Populate the repository + runMirrorApplication("19.0", sourceRepoLocation, destRepoLocation, false); + + //run the mirror application with the source being the same as the destination + runMirrorApplication("19.1", destRepoLocation, destRepoLocation, true); + + try { + //verify destination's content + assertContentEquals("19.2", getMetadataRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + } catch (ProvisionException e) { + fail("19.3", e); + } + } + + /** + * Tests mirroring a repository with a different version of the same package + * Source contains A, B (v1.0.1) + * Target contains A, B (v1.0.0) + * Expected is A, B (v1.0.0) and A, B (v1.0.1) + */ + public void testArtifactMirrorDifferentVersions() { + //Setup: Populate the repository + runMirrorApplication("20.0", sourceRepoLocation, destRepoLocation, false); + + //start a mirror application where the source contains the same artifacts but with a different version compared to the destination + runMirrorApplication("20.1", sourceRepo4Location, destRepoLocation, true); + + try { + //verify destination's content + assertContains("20.2", getMetadataRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + assertContains("20.3", getMetadataRepositoryManager().loadRepository(sourceRepo4Location.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + //checks that the destination has the correct number of keys (no extras) + assertEquals("20.4", getNumUnique(getMetadataRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null).query(InstallableUnitQuery.ANY, new Collector(), null), getMetadataRepositoryManager().loadRepository(sourceRepo4Location.toURI(), null).query(InstallableUnitQuery.ANY, new Collector(), null)), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null).query(InstallableUnitQuery.ANY, new Collector(), null).size()); + } catch (ProvisionException e) { + fail("20.5", e); + } + } + + /** + * Tests how mirror application handles an unspecified source + */ + public void testArtifactMirrorNullSource() { + try { + basicRunMirrorApplication("21.1", null, destRepoLocation.toURL(), true); + //We expect the IllegalStateException to be thrown + fail("21.3 IllegalStateException not thrown"); + } catch (ProvisionException e) { + return; //expected type of exception has been thrown + } catch (Exception e) { + fail("21.2", e); + } + } + + /** + * Tests how mirror application handles an unspecified destination + */ + public void testArtifactMirrorNullDestination() { + try { + basicRunMirrorApplication("21.1", sourceRepoLocation.toURL(), null, true); + //We expect the IllegalStateException to be thrown + fail("22.3 IllegalStateException not thrown"); + } catch (ProvisionException e) { + return; //expected type of exception has been thrown + } catch (Exception e) { + fail("22.2", e); + } + } + + /** + * Tests how mirror application handles both an unspecified source and an unspecified destination + */ + public void testArtifactMirrorNullBoth() { + try { + basicRunMirrorApplication("23.0", null, null, true); + //We expect the IllegalStateException to be thrown + fail("23.2 IllegalStateException not thrown"); + } catch (ProvisionException e) { + return; //expected type of exception has been thrown + } catch (Exception e) { + fail("23.1", e); + } + } + + /** + * Ensures that a repository created before the mirror application is run does not have its properties changed + */ + public void testExistingArtifactRepoProperties() { + //Setup: create the destination + String name = "Destination Name"; + Map properties = null; //default properties + try { + //create the repository and get the resulting properties + properties = getMetadataRepositoryManager().createRepository(destRepoLocation.toURI(), name, IMetadataRepositoryManager.TYPE_SIMPLE_REPOSITORY, properties).getProperties(); + } catch (ProvisionException e) { + fail("25.0", e); + } + + //run the mirror application + metadataMirrorToEmpty("25.2", true); + + try { + IMetadataRepository repository = getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null); + assertEquals("25.3", name, repository.getName()); + assertRepositoryProperties("25.4", properties, repository.getProperties()); + } catch (ProvisionException e) { + fail("25.5", e); + } + } + + /** + * Ensures that a repository created by the mirror application has specified name + * For Bug 256909 + */ + public void testNewArtifactRepoWithNewName() { + String name = "Bug 256909 test - new"; + try { + //set the arguments + //run the mirror application + basicRunMirrorApplication("Bug 256909 Test", sourceRepoLocation.toURL(), destRepoLocation.toURL(), false, name); + } catch (MalformedURLException e) { + fail("Error creating URLs for Source/Detination", e); + } catch (Exception e) { + fail("Error running mirror application", e); + } + + try { + assertEquals("Assert name was set correct", name, getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null).getName()); + } catch (ProvisionException e) { + fail("Cannot obtain destination", e); + } + } + + /** + * Ensures that an existing destination used by the mirror application is given specified name + * For Bug 256909 + */ + public void testExistingArtifactRepoWithNewName() { + String oldName = "The original naem for Bug 256909 test - existing"; + String newName = "Bug 256909 test - existing"; + //Setup create the repository + IMetadataRepository destinationRepo = null; + try { + destinationRepo = getMetadataRepositoryManager().createRepository(destRepoLocation.toURI(), oldName, IMetadataRepositoryManager.TYPE_SIMPLE_REPOSITORY, null); + assertTrue(destinationRepo.isModifiable()); + } catch (ProvisionException e) { + fail("Error creating repo at destination", e); + } + assertEquals("Assert name is set correctly before mirror", oldName, destinationRepo.getName()); + + try { + basicRunMirrorApplication("Bug 256809 Test", sourceRepoLocation.toURL(), destRepoLocation.toURL(), true, newName); + } catch (MalformedURLException e) { + fail("Error creating URLs for Source/Detination", e); + } catch (Exception e) { + fail("Error running mirror application", e); + } + + try { + assertEquals("Assert name is set correctly after mirror", newName, getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null).getName()); + } catch (ProvisionException e) { + fail("Error loading destination", e); + } + } + + //for Bug 235683 + public void testMirrorCompressedSource() { + File compressedSource = getTestData("0", "/testData/mirror/mirrorCompressedRepo"); + + //Setup: get the content.jar file + File compressedMetadataXML = new File(compressedSource.getAbsoluteFile() + "/content.jar"); + //Setup: make sure content.jar exists + assertTrue("1", compressedMetadataXML.exists()); + + try { + basicRunMirrorApplication("2", compressedSource.toURL(), destRepoLocation.toURL(), false); + } catch (MalformedURLException e) { + fail("3", e); + } catch (Exception e) { + fail("4", e); + } + + //get the content.jar file + File destMetadataXML = new File(destRepoLocation.getAbsolutePath() + "/content.jar"); + //make sure content.jar exists + assertTrue("5", destMetadataXML.exists()); + } + + //for Bug 235683 + public void testMirrorCompressedSourcetoUncompressedDestination() { + File compressedSource = getTestData("0", "/testData/mirror/mirrorCompressedRepo"); + + //Setup: get the content.jar file + File compressedMetadataXML = new File(compressedSource.getAbsoluteFile() + "/content.jar"); + //Setup: make sure content.jar exists + assertTrue("1", compressedMetadataXML.exists()); + + //Setup: create the destination + try { + String name = "Destination Name " + destRepoLocation; + getMetadataRepositoryManager().createRepository(destRepoLocation.toURI(), name, IMetadataRepositoryManager.TYPE_SIMPLE_REPOSITORY, null); + } catch (ProvisionException e) { + fail("2", e); + } + + try { + basicRunMirrorApplication("3", compressedSource.toURL(), destRepoLocation.toURL(), false); + } catch (MalformedURLException e) { + fail("4", e); + } catch (Exception e) { + fail("5", e); + } + + //get the content.jar file + File destMetadataXML = new File(destRepoLocation.getAbsolutePath() + "/content.jar"); + //make sure content.jar does not exist + assertFalse("6", destMetadataXML.exists()); + //get the content.xml file + destMetadataXML = new File(destRepoLocation.getAbsolutePath() + "/content.xml"); + //make sure content.xml exists + assertTrue("7", destMetadataXML.exists()); + } + + public void testMirrorUncompressedSourceToCompressedDestination() { + File uncompressedSource = getTestData("0", "/testData/mirror/mirrorSourceRepo3"); + + //Setup: get the content.xml file + File uncompressedContentXML = new File(uncompressedSource.getAbsoluteFile() + "/content.xml"); + //Setup: make sure content.xml exists + assertTrue("1", uncompressedContentXML.exists()); + + //Setup: create the destination + try { + String name = "Destination Name " + destRepoLocation; + Map property = new HashMap(); + property.put(IRepository.PROP_COMPRESSED, "true"); + getMetadataRepositoryManager().createRepository(destRepoLocation.toURI(), name, IMetadataRepositoryManager.TYPE_SIMPLE_REPOSITORY, property); + } catch (ProvisionException e) { + fail("2", e); + } + + assertTrue("2.1", new File(destRepoLocation, "content.jar").exists()); + try { + basicRunMirrorApplication("3", uncompressedSource.toURL(), destRepoLocation.toURL(), false); + } catch (MalformedURLException e) { + fail("4", e); + } catch (Exception e) { + fail("5", e); + } + + //get the content.jar file + File destMetadataXML = new File(destRepoLocation.getAbsolutePath() + "/content.jar"); + //make sure content.jar does exist + assertTrue("6", destMetadataXML.exists()); + //get the content.xml file + destMetadataXML = new File(destRepoLocation.getAbsolutePath() + "/content.xml"); + //make sure content.xml exists + assertFalse("7", destMetadataXML.exists()); + } + + public void testMirrorApplicationWithCompositeSource() { + //Setup Make composite repository + File repoLocation = new File(getTempFolder(), "CompositeMetadataMirrorTest"); + AbstractProvisioningTest.delete(repoLocation); + IMetadataRepository repo = null; + try { + repo = getMetadataRepositoryManager().createRepository(repoLocation.toURI(), "metadata name", IMetadataRepositoryManager.TYPE_COMPOSITE_REPOSITORY, null); + } catch (ProvisionException e) { + fail("Could not create repository"); + } + //ensure proper type of repository has been created + if (!(repo instanceof CompositeMetadataRepository)) + fail("Repository is not a CompositeMetadataRepository"); + //Populate source + File child1 = getTestData("1", "/testData/mirror/mirrorSourceRepo1 with space"); + File child2 = getTestData("2", "/testData/mirror/mirrorSourceRepo2"); + ((CompositeMetadataRepository) repo).addChild(child1.toURI()); + ((CompositeMetadataRepository) repo).addChild(child2.toURI()); + + runMirrorApplication("Mirroring from Composite Source", repoLocation, destRepoLocation, false); + + try { + assertContentEquals("Verifying contents", repo, getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + + //Verify that result is the same as mirroring from the 2 repositories seperately + assertContains("3", getMetadataRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + assertContains("4", getMetadataRepositoryManager().loadRepository(sourceRepo2Location.toURI(), null), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null)); + //checks that the destination has the correct number of keys (no extras) + assertEquals("5", getNumUnique(getMetadataRepositoryManager().loadRepository(sourceRepoLocation.toURI(), null).query(InstallableUnitQuery.ANY, new Collector(), null), getMetadataRepositoryManager().loadRepository(sourceRepo2Location.toURI(), null).query(InstallableUnitQuery.ANY, new Collector(), null)), getMetadataRepositoryManager().loadRepository(destRepoLocation.toURI(), null).query(InstallableUnitQuery.ANY, new Collector(), null).size()); + } catch (ProvisionException e) { + fail("Could not load destination", e); + } + } +} diff --git a/bundles/org.eclipse.equinox.p2.tests/testData/mirror/zippedRepo.zip b/bundles/org.eclipse.equinox.p2.tests/testData/mirror/zippedRepo.zip Binary files differnew file mode 100644 index 000000000..c47050897 --- /dev/null +++ b/bundles/org.eclipse.equinox.p2.tests/testData/mirror/zippedRepo.zip |