Skip to content

FELIX-6781 ResolverImpl should start all deployed resources (if START flag used) #425

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -533,14 +533,15 @@ public synchronized void deploy(int flags)
// resources being deployed.
if ((localResource != null) &&
isResourceUpdatable(localResource, deployResource, deployResources)) {
// Track if we need to start the bundle
boolean doStartBundle = (flags & START) != 0;
// Only update if it is a different version.
if (!localResource.equals(deployResource)) {
// Update the installed bundle.
try {
// stop the bundle before updating to prevent
// the bundle update from throwing due to not yet
// resolved dependencies
boolean doStartBundle = (flags & START) != 0;
if (localResource.getBundle().getState() == Bundle.ACTIVE) {
doStartBundle = true;
localResource.getBundle().stop();
Expand All @@ -552,9 +553,7 @@ public synchronized void deploy(int flags)
// started later.
if (doStartBundle) {
Bundle bundle = localResource.getBundle();
if (!isFragmentBundle(bundle)) {
startList.add(bundle);
}
startList.add(bundle);
}
} catch (Exception ex) {
m_logger.log(
Expand All @@ -564,6 +563,13 @@ public synchronized void deploy(int flags)
return;
}
}
else if (doStartBundle) {
// If necessary, save the updated bundle to be started later.
int state = localResource.getBundle().getState();
if (state == Bundle.INSTALLED || state == Bundle.RESOLVED) {
startList.add(localResource.getBundle());
}
}
} else {
// Install the bundle.
try {
Expand All @@ -581,9 +587,7 @@ public synchronized void deploy(int flags)
// If necessary, save the installed bundle to be
// started later.
if ((flags & START) != 0) {
if (!isFragmentBundle(bundle)) {
startList.add(bundle);
}
startList.add(bundle);
}
} catch (Exception ex) {
m_logger.log(
Expand All @@ -597,7 +601,9 @@ public synchronized void deploy(int flags)

for (Bundle aStartList : startList) {
try {
aStartList.start();
if (!isFragmentBundle(aStartList)) {
aStartList.start();
}
} catch (BundleException ex) {
m_logger.log(
Logger.LOG_ERROR,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ public void testSpec2() throws Exception

resolver.add(discoverResources[0]);
assertTrue("Resolver could not resolve", resolver.resolve());

EasyMock.verify(resource, resource2);
}

public void testSpecBundleNamespace() throws Exception
Expand Down Expand Up @@ -224,10 +226,86 @@ public void testMandatoryPackages() throws Exception
}

public void testFindUpdatableLocalResource() throws Exception {
Bundle mockBundle = EasyMock.createMock(Bundle.class);
EasyMock.expect(mockBundle.getState()).andReturn(Bundle.ACTIVE).anyTimes();
EasyMock.expect(mockBundle.getHeaders()).andReturn(new Hashtable<>()).anyTimes();

mockBundle.stop();
EasyMock.expectLastCall().once();
mockBundle.update(EasyMock.anyObject());
EasyMock.expectLastCall().once();
mockBundle.start();
EasyMock.expectLastCall().once();

// In the implementation of ResolverImpl the static method FileUtil.openURL is used.
// EasyMock doesn't have static method testing, Mockito doesn't have it in the currently used version.
// So for now reference a local file which we know exists to be loaded.
String uri = getClass().getResource("ResolverImplTest.class").toURI().toString();

LocalResource resource = EasyMock.createMock(LocalResource.class);
EasyMock.expect(resource.getSymbolicName()).andReturn("com.test.bundleA").anyTimes();
EasyMock.expect(resource.getRequirements()).andReturn(null).anyTimes();
EasyMock.expect(resource.getCapabilities()).andReturn(null).anyTimes();
EasyMock.expect(resource.getBundle()).andReturn(mockBundle).anyTimes();
EasyMock.expect(resource.getURI()).andReturn(uri).anyTimes();
EasyMock.expect(resource.isLocal()).andReturn(true).anyTimes();

// Ensure the resource to deploy is different that the local resource, thus triggering an update
LocalResource resourceToDeploy = EasyMock.createMock(LocalResource.class);
EasyMock.expect(resourceToDeploy.getSymbolicName()).andReturn("com.test.bundleA").anyTimes();
EasyMock.expect(resourceToDeploy.getRequirements()).andReturn(null).anyTimes();
EasyMock.expect(resourceToDeploy.getCapabilities()).andReturn(null).anyTimes();
EasyMock.expect(resourceToDeploy.getBundle()).andReturn(mockBundle).anyTimes();
EasyMock.expect(resourceToDeploy.getURI()).andReturn(uri).anyTimes();
EasyMock.expect(resourceToDeploy.isLocal()).andReturn(true).anyTimes();

Repository localRepo = EasyMock.createMock(Repository.class);

Repository[] localRepos = { localRepo };
final LocalResource[] localResources = { resource };

EasyMock.expect(localRepo.getResources()).andReturn(localResources).anyTimes();
EasyMock.expect(localRepo.getURI()).andReturn(Repository.LOCAL).anyTimes();
EasyMock.expect(localRepo.getLastModified()).andReturn(System.currentTimeMillis()).anyTimes();

BundleContext bundleContext = EasyMock.createMock(BundleContext.class);

EasyMock.replay(resource, resourceToDeploy, mockBundle, localRepo);

ResolverImpl resolver = new ResolverImpl(bundleContext, localRepos, new Logger(bundleContext)) {
@Override
public LocalResource[] getLocalResources() {
return localResources;
}
};

resolver.add(resourceToDeploy);

boolean exceptionThrown = false;
try {
resolver.resolve();
resolver.deploy(Resolver.START);
} catch (Exception e) {
e.printStackTrace();
exceptionThrown = true;
}
assertFalse(exceptionThrown);

EasyMock.verify(resource, resourceToDeploy, mockBundle, localRepo);
}

public void testDeployFragmentBundle() throws Exception {
Bundle mockBundle = EasyMock.createMock(Bundle.class);
EasyMock.expect(mockBundle.getState()).andReturn(Bundle.ACTIVE).anyTimes();
Hashtable<String, String> bundleHeaders = new Hashtable<>();
bundleHeaders.put(Constants.FRAGMENT_HOST, "com.test.bundleA");
EasyMock.expect(mockBundle.getHeaders()).andReturn(bundleHeaders).anyTimes();

LocalResource resource = EasyMock.createMock(LocalResource.class);
EasyMock.expect(resource.getSymbolicName()).andReturn("com.test.bundleA").anyTimes();
EasyMock.expect(resource.getRequirements()).andReturn(null).anyTimes();
EasyMock.expect(resource.getCapabilities()).andReturn(null).anyTimes();
EasyMock.expect(resource.getBundle()).andReturn(mockBundle).anyTimes();
EasyMock.expect(resource.getURI()).andReturn("http://test.com").anyTimes();
EasyMock.expect(resource.isLocal()).andReturn(true).anyTimes();

Expand All @@ -242,7 +320,7 @@ public void testFindUpdatableLocalResource() throws Exception {

BundleContext bundleContext = EasyMock.createMock(BundleContext.class);

EasyMock.replay(resource, localRepo);
EasyMock.replay(resource, mockBundle, localRepo);

ResolverImpl resolver = new ResolverImpl(bundleContext, localRepos, new Logger(bundleContext)) {
@Override
Expand All @@ -262,6 +340,8 @@ public LocalResource[] getLocalResources() {
exceptionThrown = true;
}
assertFalse(exceptionThrown);

EasyMock.verify(resource, mockBundle, localRepo);
}

public static void main(String[] args) throws Exception
Expand Down