| /******************************************************************************* |
| * Copyright (c) 2012 Wind River 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: |
| * Wind River - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.equinox.p2.tests.engine; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.File; |
| import java.net.URI; |
| import java.util.*; |
| import java.util.concurrent.CountDownLatch; |
| import java.util.concurrent.TimeUnit; |
| import org.eclipse.core.internal.registry.ExtensionRegistry; |
| import org.eclipse.core.runtime.*; |
| import org.eclipse.core.runtime.spi.RegistryContributor; |
| import org.eclipse.equinox.internal.p2.artifact.repository.MirrorEvent; |
| import org.eclipse.equinox.internal.p2.engine.*; |
| import org.eclipse.equinox.internal.p2.metadata.TouchpointData; |
| import org.eclipse.equinox.internal.p2.metadata.TouchpointInstruction; |
| import org.eclipse.equinox.internal.p2.touchpoint.eclipse.Util; |
| import org.eclipse.equinox.internal.p2.touchpoint.eclipse.actions.ActionConstants; |
| import org.eclipse.equinox.internal.p2.touchpoint.eclipse.actions.RemoveRepositoryAction; |
| import org.eclipse.equinox.internal.provisional.p2.core.eventbus.ProvisioningListener; |
| import org.eclipse.equinox.p2.core.ProvisionException; |
| import org.eclipse.equinox.p2.engine.*; |
| import org.eclipse.equinox.p2.engine.spi.ProvisioningAction; |
| import org.eclipse.equinox.p2.metadata.*; |
| import org.eclipse.equinox.p2.query.IQueryResult; |
| import org.eclipse.equinox.p2.query.QueryUtil; |
| import org.eclipse.equinox.p2.repository.IRepository; |
| import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository; |
| import org.eclipse.equinox.p2.repository.artifact.IArtifactRequest; |
| import org.eclipse.equinox.p2.tests.AbstractProvisioningTest; |
| import org.eclipse.equinox.p2.tests.TestActivator; |
| import org.junit.*; |
| |
| public class ProvisioningEventTest extends AbstractProvisioningTest { |
| private IEngine engine; |
| private File testProvisioning; |
| |
| @Before |
| public void setUp() throws Exception { |
| engine = getEngine(); |
| testProvisioning = new File(System.getProperty("java.io.tmpdir"), "testProvisioning"); |
| delete(testProvisioning); |
| testProvisioning.mkdir(); |
| } |
| |
| @After |
| public void tearDown() throws Exception { |
| engine = null; |
| delete(testProvisioning); |
| } |
| |
| @Test |
| public void testCollectEvent() throws ProvisionException, OperationCanceledException, InterruptedException { |
| class ProvTestListener implements ProvisioningListener { |
| int requestsNumber = 0; |
| boolean called = false; |
| boolean mirrorEevent = false; |
| CountDownLatch latch = new CountDownLatch(1); |
| |
| public void notify(EventObject o) { |
| if (o instanceof CollectEvent) { |
| if (((CollectEvent) o).getType() == CollectEvent.TYPE_OVERALL_START && ((CollectEvent) o).getRepository() == null) { |
| called = true; |
| IArtifactRequest[] requests = ((CollectEvent) o).getDownloadRequests(); |
| requestsNumber = requests.length; |
| } |
| } else if (o instanceof MirrorEvent) { |
| mirrorEevent = true; |
| System.out.println(((MirrorEvent) o).getDownloadStatus()); |
| } else if (o instanceof CommitOperationEvent || o instanceof RollbackOperationEvent) |
| latch.countDown(); |
| } |
| } |
| final ProvTestListener listener = new ProvTestListener(); |
| getEventBus().addListener(listener); |
| try { |
| URI repoLoc = getTestData("Load test data.", "/testData/testRepos/updateSite").toURI(); |
| IProfile profile = createProfile("test"); |
| // clean possible cached artifacts |
| IArtifactRepository bundlePool = Util.getBundlePoolRepository(getAgent(), profile); |
| bundlePool.removeAll(new NullProgressMonitor()); |
| ProvisioningContext context = new ProvisioningContext(getAgent()); |
| context.setArtifactRepositories(new URI[] {repoLoc}); |
| context.setMetadataRepositories(new URI[] {repoLoc}); |
| IProvisioningPlan plan = engine.createPlan(profile, context); |
| IQueryResult<IInstallableUnit> allIUs = getMetadataRepositoryManager().loadRepository(repoLoc, null).query(QueryUtil.ALL_UNITS, null); |
| for (IInstallableUnit iu : allIUs.toSet()) { |
| plan.addInstallableUnit(iu); |
| } |
| IStatus status = engine.perform(plan, new NullProgressMonitor()); |
| assertTrue("Provisioning was failed.", status.isOK()); |
| // // make sure the listener handles all event already that are dispatched asynchronously |
| listener.latch.await(10, TimeUnit.SECONDS); |
| assertTrue("Collect event wasn't dispatched.", listener.called); |
| assertEquals("Collect event didn't report expected artifacts to be downloaded.", 19, listener.requestsNumber); |
| assertTrue("Mirror event wasn't dispatched.", listener.mirrorEevent); |
| } finally { |
| getEventBus().removeListener(listener); |
| } |
| } |
| |
| @Test |
| public void testPhaseEvent() throws ProvisionException, OperationCanceledException, InterruptedException { |
| final String[] phaseSets = new String[] {PhaseSetFactory.PHASE_COLLECT, PhaseSetFactory.PHASE_CHECK_TRUST, PhaseSetFactory.PHASE_INSTALL, PhaseSetFactory.PHASE_CONFIGURE}; |
| |
| class ProvTestListener implements ProvisioningListener { |
| String publishUnWantedPhaseEvent = null; |
| int publishUnWantedPhaseType = 0; |
| List<String> phaseStartEventToBePublised = new ArrayList<String>(Arrays.asList(phaseSets)); |
| List<String> phaseEndEventToBePublised = new ArrayList<String>(Arrays.asList(phaseSets)); |
| CountDownLatch latch = new CountDownLatch(1); |
| |
| public void notify(EventObject o) { |
| if (o instanceof PhaseEvent) { |
| PhaseEvent event = (PhaseEvent) o; |
| if (event.getType() == PhaseEvent.TYPE_START) { |
| if (!phaseStartEventToBePublised.remove(event.getPhaseId())) |
| publishUnWantedPhaseEvent = event.getPhaseId(); |
| } else if (event.getType() == PhaseEvent.TYPE_END) { |
| if (!phaseEndEventToBePublised.remove(event.getPhaseId())) |
| publishUnWantedPhaseEvent = event.getPhaseId(); |
| } else |
| publishUnWantedPhaseType = event.getType(); |
| } else if (o instanceof CommitOperationEvent || o instanceof RollbackOperationEvent) |
| latch.countDown(); |
| } |
| } |
| final ProvTestListener listener = new ProvTestListener(); |
| getEventBus().addListener(listener); |
| try { |
| URI repoLoc = getTestData("Load test data.", "/testData/testRepos/updateSite").toURI(); |
| IProfile profile = createProfile("test"); |
| ProvisioningContext context = new ProvisioningContext(getAgent()); |
| context.setArtifactRepositories(new URI[] {repoLoc}); |
| context.setMetadataRepositories(new URI[] {repoLoc}); |
| IProvisioningPlan plan = engine.createPlan(profile, context); |
| IQueryResult<IInstallableUnit> allIUs = getMetadataRepositoryManager().loadRepository(repoLoc, null).query(QueryUtil.ALL_UNITS, null); |
| for (IInstallableUnit iu : allIUs.toSet()) { |
| plan.addInstallableUnit(iu); |
| } |
| IStatus status = engine.perform(plan, PhaseSetFactory.createPhaseSetIncluding(phaseSets), new NullProgressMonitor()); |
| assertTrue("Provisioning was failed.", status.isOK()); |
| // make sure the listener handles all event already that are dispatched asynchronously |
| listener.latch.await(10, TimeUnit.SECONDS); |
| assertNull("Published phase event with unwanted phase id.", listener.publishUnWantedPhaseEvent); |
| assertEquals("Published unwanted type of phase event.", 0, listener.publishUnWantedPhaseType); |
| assertEquals("Expected Phase start event is not published.", new ArrayList<String>(0), listener.phaseStartEventToBePublised); |
| assertEquals("Expected Phase end event is not published.", new ArrayList<String>(0), listener.phaseEndEventToBePublised); |
| } finally { |
| getEventBus().removeListener(listener); |
| } |
| } |
| |
| @Test |
| public void testConfigureUnConfigureEvent() throws InterruptedException { |
| final String iuId = "test"; |
| class ProvTestListener implements ProvisioningListener { |
| int preConfigureEvent = 0; |
| int postConfigureEvent = 0; |
| int preUnConfigureEvent = 0; |
| int postUnConfigureEvent = 0; |
| CountDownLatch latch = new CountDownLatch(2); |
| |
| public void notify(EventObject o) { |
| if (o instanceof InstallableUnitEvent) { |
| InstallableUnitEvent event = (InstallableUnitEvent) o; |
| if (event.getPhase().equals(PhaseSetFactory.PHASE_CONFIGURE) && event.isConfigure() && event.getInstallableUnit().getId().equals(iuId)) { |
| if (event.isPre()) |
| preConfigureEvent++; |
| else if (event.isPost()) |
| postConfigureEvent++; |
| } else if (event.getPhase().equals(PhaseSetFactory.PHASE_UNCONFIGURE) && event.isUnConfigure() && event.getInstallableUnit().getId().equals(iuId)) { |
| if (event.isPre()) |
| preUnConfigureEvent++; |
| else if (event.isPost()) |
| postUnConfigureEvent++; |
| } |
| } else if (o instanceof CommitOperationEvent || o instanceof RollbackOperationEvent) |
| latch.countDown(); |
| } |
| } |
| final ProvTestListener listener = new ProvTestListener(); |
| getEventBus().addListener(listener); |
| |
| try { |
| IProfile profile = createProfile("testConfigureEvent"); |
| IProvisioningPlan plan = engine.createPlan(profile, null); |
| |
| final String testLocation = "http://download.eclipse.org/releases/juno"; |
| // remove the existing location in case it has |
| Map args = new HashMap(); |
| args.put(ActionConstants.PARM_AGENT, getAgent()); |
| args.put("location", testLocation); |
| args.put("type", Integer.toString(IRepository.TYPE_ARTIFACT)); |
| args.put("enabled", "true"); |
| new RemoveRepositoryAction().execute(args); |
| |
| Map<String, ITouchpointInstruction> data = new HashMap<String, ITouchpointInstruction>(); |
| Map<String, String> parameters = new HashMap<String, String>(); |
| parameters.put("location", testLocation); |
| parameters.put("type", Integer.toString(IRepository.TYPE_ARTIFACT)); |
| parameters.put("name", "Juno"); |
| parameters.put("enabled", "true"); |
| data.put(PhaseSetFactory.PHASE_CONFIGURE, new TouchpointInstruction(TouchpointInstruction.encodeAction("addRepository", parameters), null)); |
| IInstallableUnit testIU = createResolvedIU(createEclipseIU(iuId, Version.create("1.0.0"), new IRequirement[0], new TouchpointData(data))); |
| plan.addInstallableUnit(testIU); |
| IStatus result = engine.perform(plan, PhaseSetFactory.createDefaultPhaseSet(), new NullProgressMonitor()); |
| assertTrue("0.2", result.isOK()); |
| Set<IInstallableUnit> installedIUs = profile.available(QueryUtil.ALL_UNITS, null).toUnmodifiableSet(); |
| assertEquals("0.3", 1, installedIUs.size()); |
| plan = engine.createPlan(profile, null); |
| plan.removeInstallableUnit(testIU); |
| result = engine.perform(plan, PhaseSetFactory.createDefaultPhaseSet(), new NullProgressMonitor()); |
| assertTrue("0.4", result.isOK()); |
| // make sure the listener handles all event already that are dispatched asynchronously |
| listener.latch.await(10, TimeUnit.SECONDS); |
| assertEquals("0.5", 1, listener.preConfigureEvent); |
| assertEquals("0.6", 1, listener.postConfigureEvent); |
| assertEquals("0.7", 1, listener.preUnConfigureEvent); |
| assertEquals("0.8", 1, listener.postUnConfigureEvent); |
| } finally { |
| getEventBus().removeListener(listener); |
| } |
| } |
| |
| public static class AlwaysFail extends ProvisioningAction { |
| |
| @Override |
| public IStatus execute(Map<String, Object> parameters) { |
| int a = 1; |
| if (a == 1) |
| throw new NullPointerException("no reason"); |
| return null; |
| } |
| |
| @Override |
| public IStatus undo(Map<String, Object> parameters) { |
| return null; |
| } |
| |
| } |
| |
| @Test |
| public void testConfigureUndoEvent() throws InterruptedException { |
| final String iuId = "test"; |
| final String failureIU = "alwaysFail"; |
| class ProvTestListener implements ProvisioningListener { |
| int preConfigureEvent = 0; |
| int postConfigureEvent = 0; |
| int preUnConfigureEventForUndo = 0; |
| int postUnConfigureEventForUndo = 0; |
| CountDownLatch latch = new CountDownLatch(1); |
| |
| public void notify(EventObject o) { |
| if (o instanceof InstallableUnitEvent) { |
| InstallableUnitEvent event = (InstallableUnitEvent) o; |
| if (event.getPhase().equals(PhaseSetFactory.PHASE_CONFIGURE) && event.getInstallableUnit().getId().equals(iuId)) { |
| if (event.isConfigure() && event.isPre()) |
| preConfigureEvent++; |
| else if (event.isConfigure() && event.isPost()) |
| postConfigureEvent++; |
| else if (event.isUnConfigure() && event.isPre()) |
| preUnConfigureEventForUndo++; |
| else if (event.isUnConfigure() && event.isPost()) |
| postUnConfigureEventForUndo++; |
| } else if (event.getPhase().equals(PhaseSetFactory.PHASE_CONFIGURE) && event.getInstallableUnit().getId().equals(failureIU)) { |
| if (event.isConfigure() && event.isPre()) { |
| preConfigureEvent++; |
| } else if (event.isConfigure() && event.isPost()) |
| postConfigureEvent++; |
| else if (event.isUnConfigure() && event.isPre()) |
| preUnConfigureEventForUndo++; |
| else if (event.isUnConfigure() && event.isPost()) |
| postUnConfigureEventForUndo++; |
| } |
| } else if (o instanceof CommitOperationEvent || o instanceof RollbackOperationEvent) |
| latch.countDown(); |
| } |
| } |
| final ProvTestListener listener = new ProvTestListener(); |
| getEventBus().addListener(listener); |
| |
| try { |
| final String customTouchPoint = "<extension point=\"org.eclipse.equinox.p2.engine.actions\"> <action class=\"org.eclipse.equinox.p2.tests.engine.ProvisioningEventTest.AlwaysFail\" name=\"alwaysFail\" touchpointType=\"org.eclipse.equinox.p2.osgi\" touchpointVersion=\"1.0.0\" version=\"1.0.0\"></action></extension>"; |
| ByteArrayInputStream input = new ByteArrayInputStream(customTouchPoint.getBytes()); |
| IExtensionRegistry registry = Platform.getExtensionRegistry(); |
| registry.addContribution(input, new RegistryContributor(TestActivator.PI_PROV_TESTS, "p2 tests", null, null), false, "Always Fail TouchPoint Action", null, ((ExtensionRegistry) registry).getTemporaryUserToken()); |
| |
| IProfile profile = createProfile("testConfigureEvent"); |
| IProvisioningPlan plan = engine.createPlan(profile, null); |
| Map<String, ITouchpointInstruction> data = new HashMap<String, ITouchpointInstruction>(); |
| data.put(PhaseSetFactory.PHASE_CONFIGURE, MetadataFactory.createTouchpointInstruction("instructionparsertest.goodAction()", null)); |
| IInstallableUnit testIU = createResolvedIU(createIU(iuId, Version.create("1.0.0"), null, new IRequirement[0], BUNDLE_CAPABILITY, NO_PROPERTIES, ITouchpointType.NONE, new TouchpointData(data), false)); |
| plan.addInstallableUnit(testIU); |
| data = new HashMap<String, ITouchpointInstruction>(1); |
| data.put(PhaseSetFactory.PHASE_CONFIGURE, new TouchpointInstruction("alwaysFail();", null)); |
| plan.addInstallableUnit(createResolvedIU(createEclipseIU(failureIU, Version.create("1.0.0"), new IRequirement[0], new TouchpointData(data)))); |
| IStatus result = engine.perform(plan, PhaseSetFactory.createDefaultPhaseSet(), new NullProgressMonitor()); |
| assertFalse(result.isOK()); |
| // make sure the listener handles all event already that are dispatched asynchronously |
| listener.latch.await(10, TimeUnit.SECONDS); |
| assertEquals("0.5", 2, listener.preConfigureEvent); |
| assertEquals("0.6", 1, listener.postConfigureEvent); |
| assertEquals("0.7", 1, listener.preUnConfigureEventForUndo); |
| assertEquals("0.8", 2, listener.postUnConfigureEventForUndo); |
| } finally { |
| getEventBus().removeListener(listener); |
| } |
| } |
| } |