blob: 963a5c0cb2a9897d8171ff3cf9dd706fe39e3f1c [file] [log] [blame]
/*******************************************************************************
* 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);
}
}
}