You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by gh...@apache.org on 2018/08/31 07:03:11 UTC
[sling-org-apache-sling-installer-provider-installhook] 04/05:
SLING-7790 JUnit Tests
This is an automated email from the ASF dual-hosted git repository.
ghenzler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-installer-provider-installhook.git
commit a373a922b7fa773bf3c2c188eb9c514b3319d173
Author: Georg Henzler <ge...@netcentric.biz>
AuthorDate: Wed Aug 22 20:25:14 2018 +0200
SLING-7790 JUnit Tests
---
pom.xml | 19 ++-
.../provider/installhook/OsgiInstallerHook.java | 61 +++++-----
.../installhook/OsgiInstallerListener.java | 6 +-
.../installhook/OsgiInstallerHookTest.java | 129 +++++++++++++++++++++
.../installhook/OsgiInstallerListenerTest.java | 72 ++++++++++++
5 files changed, 249 insertions(+), 38 deletions(-)
diff --git a/pom.xml b/pom.xml
index 533af9b..7dc69c3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -102,7 +102,22 @@
<artifactId>osgi.cmpn</artifactId>
<scope>provided</scope>
</dependency>
-
- </dependencies>
+
+ <!-- Basic dependencies for Unit Tests -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>2.13.0</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
</project>
diff --git a/src/main/java/org/apache/sling/installer/provider/installhook/OsgiInstallerHook.java b/src/main/java/org/apache/sling/installer/provider/installhook/OsgiInstallerHook.java
index 362ae6e..a8d910b 100644
--- a/src/main/java/org/apache/sling/installer/provider/installhook/OsgiInstallerHook.java
+++ b/src/main/java/org/apache/sling/installer/provider/installhook/OsgiInstallerHook.java
@@ -34,7 +34,6 @@ import java.util.jar.JarInputStream;
import java.util.jar.Manifest;
import javax.jcr.Node;
-import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
@@ -68,26 +67,27 @@ public class OsgiInstallerHook implements InstallHook {
private static final Logger LOG = LoggerFactory.getLogger(OsgiInstallerHook.class);
private static final String PACKAGE_PROPERTY_MAX_WAIT_IN_SEC = "maxWaitForOsgiInstallerInSec";
- private static final int DEFAULT_MAX_WAIT_IN_SEC = 120;
+ private static final String PACKAGE_PROP_INSTALL_PATH_REGEX = "installPathRegex";
- private static final String MANIFEST_BUNDLE_SYMBOLIC_NAME = "Bundle-SymbolicName";
- private static final String MANIFEST_BUNDLE_VERSION = "Bundle-Version";
-
- private static final String JCR_CONTENT = "jcr:content";
- private static final String JCR_CONTENT_DATA = JCR_CONTENT + "/jcr:data";
- private static final String JCR_LAST_MODIFIED = "jcr:lastModified";
- private static final String JCR_CONTENT_LAST_MODIFIED = JCR_CONTENT + "/" + JCR_LAST_MODIFIED;
+ public static final int DEFAULT_PRIORITY_INSTALL_HOOK = 2000;
+ private static final int DEFAULT_MAX_WAIT_IN_SEC = 60;
public static final String URL_SCHEME = "jcrinstall";
public static final String CONFIG_SUFFIX = ".config";
public static final String JAR_SUFFIX = ".jar";
- public static final String PACKAGE_PROP_INSTALL_PATH_REGEX = "installPathRegex";
+ private static final String MANIFEST_BUNDLE_SYMBOLIC_NAME = "Bundle-SymbolicName";
+ private static final String MANIFEST_BUNDLE_VERSION = "Bundle-Version";
+ private static final String FOLDER_META_INF = "META-INF";
+
+ static final String JCR_CONTENT = "jcr:content";
+ static final String JCR_CONTENT_DATA = JCR_CONTENT + "/jcr:data";
+ static final String JCR_LAST_MODIFIED = "jcr:lastModified";
+ static final String JCR_CONTENT_LAST_MODIFIED = JCR_CONTENT + "/" + JCR_LAST_MODIFIED;
public static final String DOT = ".";
- public static final int PRIORITY_INSTALL_HOOK = 2000;
- private InstallHookLogger logger = new InstallHookLogger();
+ InstallHookLogger logger = new InstallHookLogger();
@Override
public void execute(InstallContext context) throws PackageException {
@@ -210,7 +210,7 @@ public class OsgiInstallerHook implements InstallHook {
private Set<String> getConfigPidsToInstall(List<String> configResourcePaths, Session session,
List<InstallableResource> installableResources, ConfigurationAdmin confAdmin)
- throws IOException, InvalidSyntaxException, PathNotFoundException, RepositoryException {
+ throws IOException, InvalidSyntaxException, RepositoryException {
Set<String> configIdsToInstall = new HashSet<>();
for (String configResourcePath : configResourcePaths) {
boolean needsInstallation = false;
@@ -247,8 +247,7 @@ public class OsgiInstallerHook implements InstallHook {
private Set<String> getBundlesToInstall(List<BundleInPackage> bundleResources,
Map<String, String> bundleVersionsBySymbolicId, Session session,
- List<InstallableResource> installableResources)
- throws PathNotFoundException, RepositoryException, IOException {
+ List<InstallableResource> installableResources) throws RepositoryException, IOException {
Set<String> bundleSymbolicNamesToInstall = new HashSet<>();
Iterator<BundleInPackage> bundlesIt = bundleResources.iterator();
while (bundlesIt.hasNext()) {
@@ -278,37 +277,35 @@ public class OsgiInstallerHook implements InstallHook {
return bundleSymbolicNamesToInstall;
}
- private void collectResources(Archive archive, Entry entry, String dirPath, List<BundleInPackage> bundleResources,
+ void collectResources(Archive archive, Entry entry, String dirPath, List<BundleInPackage> bundleResources,
List<String> configResources, String installPathRegex, Set<String> actualRunmodes) {
String entryName = entry.getName();
- if(entryName.equals("META-INF")) {
+ if (entryName.equals(FOLDER_META_INF)) {
return;
- }
+ }
String dirPathWithoutJcrRoot = StringUtils.substringAfter(dirPath, "/jcr_root");
String entryPath = dirPathWithoutJcrRoot + entryName;
String dirPathWithoutSlash = StringUtils.chomp(dirPathWithoutJcrRoot, "/");
- String dirPathWithoutRunmodes;
boolean runmodesMatch;
if (dirPathWithoutSlash.contains(DOT)) {
- String[] bits = dirPathWithoutSlash.split("\\"+DOT, 2);
- dirPathWithoutRunmodes = bits[0];
- List<String> runmodesOfResource = Arrays.asList(bits[1].split("\\"+DOT));
+ String[] bits = dirPathWithoutSlash.split("\\" + DOT, 2);
+ List<String> runmodesOfResource = Arrays.asList(bits[1].split("\\" + DOT));
Set<String> matchingRunmodes = new HashSet<String>(runmodesOfResource);
matchingRunmodes.retainAll(actualRunmodes);
- LOG.debug("Entry with runmode(s): entryPath={} runmodesOfResource={} actualRunmodes={} matchingRunmodes={}", entryPath, runmodesOfResource, actualRunmodes, matchingRunmodes);
+ LOG.debug("Entry with runmode(s): entryPath={} runmodesOfResource={} actualRunmodes={} matchingRunmodes={}",
+ entryPath, runmodesOfResource, actualRunmodes, matchingRunmodes);
runmodesMatch = matchingRunmodes.size() == runmodesOfResource.size();
if (!runmodesMatch) {
logger.log("Skipping installation of " + entryPath
+ " because the path is not matching all actual runmodes " + actualRunmodes);
}
} else {
- dirPathWithoutRunmodes = dirPathWithoutSlash;
runmodesMatch = true;
}
- if (dirPathWithoutRunmodes.matches(installPathRegex) && runmodesMatch) {
+ if (entryPath.matches(installPathRegex) && runmodesMatch) {
if (entryName.endsWith(CONFIG_SUFFIX)) {
configResources.add(entryPath);
@@ -334,18 +331,18 @@ public class OsgiInstallerHook implements InstallHook {
}
}
- private InstallableResource convert(final Node node, final String path) throws IOException, RepositoryException {
+ InstallableResource convert(final Node node, final String path) throws IOException, RepositoryException {
logger.log("Converting " + node + " at path " + path);
final String digest = String.valueOf(node.getProperty(JCR_CONTENT_LAST_MODIFIED).getDate().getTimeInMillis());
final InputStream is = node.getProperty(JCR_CONTENT_DATA).getStream();
final Dictionary<String, Object> dict = new Hashtable<String, Object>();
dict.put(InstallableResource.INSTALLATION_HINT, node.getParent().getName());
- return new InstallableResource(path, is, dict, digest, null, PRIORITY_INSTALL_HOOK);
+ return new InstallableResource(path, is, dict, digest, null, DEFAULT_PRIORITY_INSTALL_HOOK);
}
// always get fresh bundle context to avoid "Dynamic class loader has already
// been deactivated" exceptions
- public BundleContext getBundleContext() {
+ private BundleContext getBundleContext() {
// use the vault bundle to hook into the OSGi world
Bundle currentBundle = FrameworkUtil.getBundle(InstallHook.class);
if (currentBundle == null) {
@@ -378,16 +375,15 @@ public class OsgiInstallerHook implements InstallHook {
}
- class InstallHookLogger {
+ static class InstallHookLogger {
- private ImportOptions options;
+ private ProgressTrackerListener listener;
public void setOptions(ImportOptions options) {
- this.options = options;
+ this.listener = options.getListener();
}
public void logError(Logger logger, String message, Throwable throwable) {
- ProgressTrackerListener listener = options.getListener();
if (listener != null) {
listener.onMessage(ProgressTrackerListener.Mode.TEXT, "ERROR: " + message, "");
}
@@ -399,7 +395,6 @@ public class OsgiInstallerHook implements InstallHook {
}
public void log(Logger logger, String message) {
- ProgressTrackerListener listener = options.getListener();
if (listener != null) {
listener.onMessage(ProgressTrackerListener.Mode.TEXT, message, "");
logger.debug(message);
diff --git a/src/main/java/org/apache/sling/installer/provider/installhook/OsgiInstallerListener.java b/src/main/java/org/apache/sling/installer/provider/installhook/OsgiInstallerListener.java
index ae15a24..c0b1ace 100644
--- a/src/main/java/org/apache/sling/installer/provider/installhook/OsgiInstallerListener.java
+++ b/src/main/java/org/apache/sling/installer/provider/installhook/OsgiInstallerListener.java
@@ -33,8 +33,8 @@ public class OsgiInstallerListener implements InstallationListener {
private static final Logger LOG = LoggerFactory.getLogger(OsgiInstallerListener.class);
- private static final String ENTITY_ID_PREFIX_BUNDLE = "bundle:";
- private static final String ENTITY_ID_PREFIX_CONFIG = "config:";
+ static final String ENTITY_ID_PREFIX_BUNDLE = "bundle:";
+ static final String ENTITY_ID_PREFIX_CONFIG = "config:";
private final Set<String> requiredBundleSymbolicNames;
private final Set<String> requiredConfigPids;
@@ -78,7 +78,7 @@ public class OsgiInstallerListener implements InstallationListener {
LOG.trace("requiredConfigPids: {}", requiredConfigPids);
LOG.trace("installedConfigPids: {}", installedConfigPids);
HashSet<String> configsLeftToInstall = new HashSet<String>(requiredConfigPids);
- requiredConfigPids.removeAll(installedConfigPids);
+ configsLeftToInstall.removeAll(installedConfigPids);
LOG.debug("configsLeftToInstall: {}", configsLeftToInstall);
return bundlesLeftToInstall.isEmpty() && configsLeftToInstall.isEmpty();
diff --git a/src/test/java/org/apache/sling/installer/provider/installhook/OsgiInstallerHookTest.java b/src/test/java/org/apache/sling/installer/provider/installhook/OsgiInstallerHookTest.java
new file mode 100644
index 0000000..7d347d1
--- /dev/null
+++ b/src/test/java/org/apache/sling/installer/provider/installhook/OsgiInstallerHookTest.java
@@ -0,0 +1,129 @@
+/*
+ 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.sling.installer.provider.installhook;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.HashSet;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+
+import org.apache.jackrabbit.vault.fs.io.Archive;
+import org.apache.jackrabbit.vault.fs.io.Archive.Entry;
+import org.apache.sling.installer.api.InstallableResource;
+import org.apache.sling.installer.provider.installhook.OsgiInstallerHook.BundleInPackage;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class OsgiInstallerHookTest {
+
+ OsgiInstallerHook osgiInstallerHook;
+
+ @Mock
+ Node node;
+
+ @Mock
+ Node parentNode;
+
+ @Mock
+ Property lastModifiedProperty;
+
+ @Mock
+ Property contentDataProperty;
+
+ @Mock
+ Archive archive;
+
+ @Mock
+ Entry entry;
+
+ Calendar now;
+
+ @Before
+ public void setup() throws RepositoryException {
+ osgiInstallerHook = new OsgiInstallerHook();
+
+ now = Calendar.getInstance();
+ when(node.getProperty(OsgiInstallerHook.JCR_CONTENT_LAST_MODIFIED)).thenReturn(lastModifiedProperty);
+ when(lastModifiedProperty.getDate()).thenReturn(now);
+ when(node.getProperty(OsgiInstallerHook.JCR_CONTENT_DATA)).thenReturn(contentDataProperty);
+ when(node.getParent()).thenReturn(parentNode);
+
+ }
+
+ @Test
+ public void testConvert() throws IOException, RepositoryException {
+
+ File pathToTest = new File("/apps/myproj/install/mybundle.jar");
+ when(parentNode.getName()).thenReturn(pathToTest.getParentFile().getName());
+
+ InstallableResource installableResource = osgiInstallerHook.convert(node, pathToTest.getAbsolutePath());
+
+ assertEquals(String.valueOf(now.getTimeInMillis()), installableResource.getDigest());
+ assertEquals(pathToTest.getParentFile().getName(), installableResource.getDictionary().get(InstallableResource.INSTALLATION_HINT));
+
+ }
+
+ public void testCollectResources() throws IOException, RepositoryException {
+
+ File pathToTest = new File("/apps/myproj/install.author/myconfig.config");
+ String dirPath = "/jcr_root" + pathToTest.getParentFile().getPath() + "/";
+
+ when(entry.getName()).thenReturn(pathToTest.getName());
+
+ List<BundleInPackage> bundleResources = new ArrayList<BundleInPackage>();
+ List<String> configResources = new ArrayList<String>();
+
+ osgiInstallerHook.collectResources(archive, entry, dirPath, bundleResources, configResources,
+ "/apps/other.*", new HashSet<String>(Arrays.asList("author", "dev")));
+
+ assertTrue(bundleResources.isEmpty());
+ assertTrue(configResources.isEmpty());
+
+ osgiInstallerHook.collectResources(archive, entry, dirPath, bundleResources, configResources,
+ "/apps/myproj.*", new HashSet<String>(Arrays.asList("publish", "dev")));
+
+ assertTrue(bundleResources.isEmpty());
+ assertTrue(configResources.isEmpty());
+
+
+ osgiInstallerHook.collectResources(archive, entry, dirPath, bundleResources, configResources,
+ "/apps/myproj.*", new HashSet<String>(Arrays.asList("author", "dev")));
+
+ assertTrue(bundleResources.isEmpty());
+ assertEquals(1, configResources.size());
+ assertEquals(pathToTest.getAbsolutePath(), configResources.get(0));
+
+ }
+
+}
diff --git a/src/test/java/org/apache/sling/installer/provider/installhook/OsgiInstallerListenerTest.java b/src/test/java/org/apache/sling/installer/provider/installhook/OsgiInstallerListenerTest.java
new file mode 100644
index 0000000..6cd02ea
--- /dev/null
+++ b/src/test/java/org/apache/sling/installer/provider/installhook/OsgiInstallerListenerTest.java
@@ -0,0 +1,72 @@
+/*
+ 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.sling.installer.provider.installhook;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.sling.installer.api.event.InstallationEvent;
+import org.apache.sling.installer.api.event.InstallationEvent.TYPE;
+import org.apache.sling.installer.api.tasks.TaskResource;
+import org.junit.Test;
+
+public class OsgiInstallerListenerTest {
+
+ private OsgiInstallerListener osgiInstallerListener;
+
+ @Test
+ public void testOsgiInstallerListener() {
+
+ String bundleSymbolicId1 = "org.prj.bundle1";
+ String bundleSymbolicId2 = "org.prj.bundle2";
+ Set<String> requiredBundleSymbolicNames = new HashSet<String>(Arrays.asList(bundleSymbolicId1, bundleSymbolicId2));
+ String configPid1 = "org.prj.config1";
+ String configPid2 = "org.prj.config2";
+ Set<String> requiredConfigPids = new HashSet<String>(Arrays.asList(configPid1, configPid2));
+
+ osgiInstallerListener = new OsgiInstallerListener(requiredBundleSymbolicNames, requiredConfigPids);
+
+ assertFalse(osgiInstallerListener.isDone());
+ osgiInstallerListener.onEvent(getInstallationEventMock(OsgiInstallerListener.ENTITY_ID_PREFIX_BUNDLE + bundleSymbolicId1));
+ assertFalse(osgiInstallerListener.isDone());
+ osgiInstallerListener.onEvent(getInstallationEventMock(OsgiInstallerListener.ENTITY_ID_PREFIX_BUNDLE + bundleSymbolicId2));
+ assertFalse(osgiInstallerListener.isDone());
+ osgiInstallerListener.onEvent(getInstallationEventMock(OsgiInstallerListener.ENTITY_ID_PREFIX_CONFIG + configPid1));
+ assertFalse(osgiInstallerListener.isDone());
+ osgiInstallerListener.onEvent(getInstallationEventMock(OsgiInstallerListener.ENTITY_ID_PREFIX_CONFIG + configPid2));
+ assertTrue(osgiInstallerListener.isDone());
+
+ }
+
+ public InstallationEvent getInstallationEventMock(String entityId) {
+ InstallationEvent event = mock(InstallationEvent.class);
+ when(event.getType()).thenReturn(TYPE.PROCESSED);
+ TaskResource taskResource = mock(TaskResource.class);
+ when(event.getSource()).thenReturn(taskResource);
+ when(taskResource.getEntityId()).thenReturn(entityId);
+ return event;
+ }
+
+}