/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.aries.subsystem.itests;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import org.apache.aries.subsystem.core.internal.BasicSubsystem;
import org.apache.aries.subsystem.itests.util.Utils;
import org.apache.aries.unittest.fixture.ArchiveFixture;
import org.apache.aries.unittest.fixture.ArchiveFixture.ZipFixture;
import org.apache.aries.util.filesystem.FileSystem;
import org.apache.aries.util.filesystem.IDirectory;
import org.apache.aries.util.io.IOUtils;
import org.junit.Test;
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
import org.ops4j.pax.exam.spi.reactors.PerMethod;
import org.osgi.framework.Bundle;
import org.osgi.framework.Version;
import org.osgi.service.subsystem.Subsystem;
import org.osgi.service.subsystem.SubsystemConstants;
import org.osgi.service.subsystem.SubsystemException;
@ExamReactorStrategy(PerMethod.class)
public class InstallTest extends SubsystemTest {
public InputStream getResourceAsStream(String path) {
return SubsystemTest.class.getClassLoader().getResourceAsStream(path);
}
@Override
public void createApplications() throws Exception {
createCompositeDirEsa();
createApplication("feature3", "tb3.jar");
createApplication("feature2", "tb3.jar", "tb2.jar");
createBundleA();
createBundleB();
createApplicationA();
createCompositeA();
createFeatureA();
}
private void createCompositeDirEsa() throws IOException,
FileNotFoundException {
ZipFixture feature = ArchiveFixture
.newZip()
.binary("OSGI-INF/SUBSYSTEM.MF", getResourceAsStream("compositeDir" + "/OSGI-INF/SUBSYSTEM.MF"))
.binary("a.jar/META-INF/MANIFEST.MF", getResourceAsStream("compositeDir" + "/a.jar/META-INF/MANIFEST.MF"))
.binary("a.jar/a/A.class", getResourceAsStream("a/A.class"))
.binary("applicationDir.esa/OSGI-INF/SUBSYSTEM.MF", getResourceAsStream("compositeDir" + "/applicationDir/OSGI-INF/SUBSYSTEM.MF"))
.binary("applicationDir.esa/b.jar/META-INF/MANIFEST.MF", getResourceAsStream("compositeDir" + "/applicationDir/b.jar/META-INF/MANIFEST.MF"))
.binary("applicationDir.esa/b.jar/b/B.class", getResourceAsStream("b/B.class"))
.binary("applicationDir.esa/featureDir.esa/OSGI-INF/SUBSYSTEM.MF", getResourceAsStream(
"compositeDir" + "/applicationDir/featureDir/OSGI-INF/SUBSYSTEM.MF"))
.binary("applicationDir.esa/featureDir.esa/a.jar/META-INF/MANIFEST.MF", getResourceAsStream(
"compositeDir" + "/applicationDir/featureDir/a.jar/META-INF/MANIFEST.MF"))
.binary("applicationDir.esa/featureDir.esa/a.jar/a/A.class", getResourceAsStream("a/A.class"))
.binary("applicationDir.esa/featureDir.esa/b.jar/META-INF/MANIFEST.MF", getResourceAsStream(
"compositeDir" + "/applicationDir/featureDir/b.jar/META-INF/MANIFEST.MF"))
.binary("applicationDir.esa/featureDir.esa/b.jar/b/B.class", getResourceAsStream("b/B.class"));
feature.end();
FileOutputStream fos = new FileOutputStream("compositeDir" + ".esa");
try {
feature.writeOut(fos);
} finally {
Utils.closeQuietly(fos);
}
File userDir = new File(System.getProperty("user.dir"));
IDirectory idir = FileSystem.getFSRoot(userDir);
File compositeDir = new File(userDir, "compositeDir");
compositeDir.mkdir();
IOUtils.unpackZip(idir.getFile("compositeDir.esa"), compositeDir);
}
@Test
public void testReturnExistingSubsystemWithSameLocation() throws Exception {
Subsystem subsystem1 = installSubsystemFromFile("feature3.esa");
try {
Subsystem subsystem2 = subsystem1.install(subsystem1.getLocation());
assertSame(subsystem1, subsystem2);
}
finally {
uninstallSubsystemSilently(subsystem1);
}
}
/*
* Install a subsystem using a location string and a null input stream. The
* location string is a file URL pointing to a subsystem directory
* containing nested subsystem and bundle directories.
*/
@Test
public void testLocationAsDirectoryUrl() throws Exception {
File file = new File("compositeDir");
try {
Subsystem subsystem = installSubsystem(getRootSubsystem(), file.toURI().toString(), null, (Boolean[]) null);
try {
assertSymbolicName("org.apache.aries.subsystem.itests.composite.dir", subsystem);
assertConstituents(3, subsystem);
assertConstituent(subsystem, "org.apache.aries.subsystem.itests.composite.dir.bundle.a");
Bundle b = getConstituentAsBundle(
subsystem,
"org.apache.aries.subsystem.itests.composite.dir.bundle.a",
null, null);
assertLocation(subsystem.getLocation() + "!/" + "a.jar", b.getLocation());
assertClassLoadable("a.A", b);
assertChildren(1, subsystem);
Subsystem child = subsystem.getChildren().iterator().next();
assertSymbolicName(
"org.apache.aries.subsystem.itests.application.dir",
child);
assertConstituent(child, "org.apache.aries.subsystem.itests.composite.dir.bundle.b");
b = getConstituentAsBundle(
child,
"org.apache.aries.subsystem.itests.composite.dir.bundle.b",
null, null);
assertLocation(child.getLocation() + "!/" + "b.jar", b.getLocation());
assertClassLoadable("b.B", b);
assertChildren(1, child);
child = child.getChildren().iterator().next();
assertSymbolicName(
"org.apache.aries.subsystem.itests.feature.dir",
child);
assertConstituent(subsystem, "org.apache.aries.subsystem.itests.composite.dir.bundle.a");
b = getConstituentAsBundle(
child,
"org.apache.aries.subsystem.itests.composite.dir.bundle.a",
null, null);
assertLocation(child.getLocation() + "!/" + "a.jar", b.getLocation());
assertClassLoadable("a.A", b);
assertConstituent(child, "org.apache.aries.subsystem.itests.composite.dir.bundle.b", Version.parseVersion("1"));
b = getConstituentAsBundle(
child,
"org.apache.aries.subsystem.itests.composite.dir.bundle.b",
Version.parseVersion("1"), null);
assertLocation(child.getLocation() + "!/" + "b.jar", b.getLocation());
assertClassLoadable("b.B", b);
}
finally {
uninstallSubsystemSilently(subsystem);
}
}
catch (Exception e) {
e.printStackTrace();
fail("Subsystem installation using directory URL as location failed");
}
}
/*
* Bundle-SymbolicName: bundle.a.jar
*/
private static final String BUNDLE_A = "bundle.a.jar";
private void createBundleA() throws IOException {
createBundle(name(BUNDLE_A));
}
/*
* No symbolic name. No manifest.
*/
private static final String APPLICATION_A = "application.a.esa";
private void createApplicationA() throws IOException {
createApplicationAManifest();
createSubsystem(APPLICATION_A, BUNDLE_A);
}
private void createApplicationAManifest() throws IOException {
File manifest = new File(APPLICATION_A + ".mf");
if (manifest.exists())
assertTrue("Could not delete manifest", manifest.delete());
}
@Test
public void testGeneratedSymbolicNameWithoutManifest() throws Exception {
String expected = "org.apache.aries.subsystem.1";
Subsystem a = installSubsystemFromFile(APPLICATION_A);
try {
assertSymbolicName(expected, a);
assertSymbolicName(expected, a.getSubsystemHeaders(null).get(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME));
}
finally {
uninstallSubsystemSilently(a);
}
}
/*
* Manifest with no symbolic name header.
*/
private static final String COMPOSITE_A = "composite.a.esa";
private static void createCompositeA() throws IOException {
createCompositeAManifest();
createSubsystem(COMPOSITE_A);
}
private static void createCompositeAManifest() throws IOException {
Map<String, String> attributes = new HashMap<String, String>();
attributes.put(SubsystemConstants.SUBSYSTEM_TYPE, SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE);
createManifest(COMPOSITE_A + ".mf", attributes);
}
@Test
public void testGeneratedSymbolicNameWithManifest() throws Exception {
String expected = "org.apache.aries.subsystem.1";
Subsystem a = installSubsystemFromFile(COMPOSITE_A);
try {
assertSymbolicName(expected, a);
assertSymbolicName(expected, a.getSubsystemHeaders(null).get(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME));
}
finally {
uninstallSubsystemSilently(a);
}
}
/*
* A bundle whose file extension does not end with ".jar".
*
* Bundle-SymbolicName: bundle.b.war
*/
private static final String BUNDLE_B = "bundle.b.war";
private void createBundleB() throws IOException {
createBundle(name(BUNDLE_B));
}
/*
* Subsystem-SymbolicName: feature.a.esa
* Subsystem-Type: osgi.subsystem.feature
* Subsystem-Content: bundle.b.war
*/
private static final String FEATURE_A = "feature.a.esa";
private static void createFeatureA() throws IOException {
createFeatureAManifest();
createSubsystem(FEATURE_A, BUNDLE_B);
}
private static void createFeatureAManifest() throws IOException {
Map<String, String> attributes = new HashMap<String, String>();
attributes.put(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME, FEATURE_A);
attributes.put(SubsystemConstants.SUBSYSTEM_TYPE, SubsystemConstants.SUBSYSTEM_TYPE_FEATURE);
createManifest(FEATURE_A + ".mf", attributes);
}
@Test
public void testSupportBundleResourcesNotEndingWithJar() throws Exception {
Subsystem featureA = installSubsystemFromFile(FEATURE_A);
try {
assertConstituents(1, featureA);
assertConstituent(featureA, BUNDLE_B);
}
finally {
uninstallSubsystemSilently(featureA);
}
}
@Test
public void testLocationAsEmptyString() throws Exception {
try {
Subsystem a = installSubsystemFromFile(getRootSubsystem(), new File(APPLICATION_A), "");
try {
BasicSubsystem basic = (BasicSubsystem)a;
String location = basic.getLocation();
assertEquals("Location value should be an empty string", "", location);
}
finally {
uninstallSubsystemSilently(a);
}
}
catch (SubsystemException e) {
e.printStackTrace();
fail("Subsystem should have installed");
}
}
}