You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ol...@apache.org on 2022/07/25 21:05:09 UTC

[sling-org-apache-sling-installer-hc] branch master updated (190e79b -> 72eed12)

This is an automated email from the ASF dual-hosted git repository.

olli pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-installer-hc.git


    from 190e79b  [maven-release-plugin] prepare for next development iteration
     new e8bd7fa  make configuration external and increase coverage
     new 72eed12  add initial integration test

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 pom.xml                                            |  99 ++++++++++++
 .../installer/hc/OsgiInstallerHealthCheck.java     |  40 ++---
 .../hc/OsgiInstallerHealthCheckConfiguration.java  |  68 ++++++++
 .../installer/hc/OsgiInstallerHealthCheckTest.java |  18 ++-
 .../hc/it/InstallerHealthCheckTestSupport.java     |  67 ++++++++
 .../org/apache/sling/installer/hc/it/app/Foo.java  |  27 ++++
 .../hc/it/tests/OsgiInstallerHealthCheckIT.java    | 179 +++++++++++++++++++++
 .../org.apache.sling.installer.hc.it.app.Bar.cfg   |   2 +
 .../org.apache.sling.installer.hc.it.app.Foo.cfg   |   2 +
 .../org.apache.sling.installer.hc.it.app-1.0.0.jar | Bin 0 -> 2566 bytes
 10 files changed, 468 insertions(+), 34 deletions(-)
 create mode 100644 src/main/java/org/apache/sling/installer/hc/OsgiInstallerHealthCheckConfiguration.java
 create mode 100644 src/test/java/org/apache/sling/installer/hc/it/InstallerHealthCheckTestSupport.java
 create mode 100644 src/test/java/org/apache/sling/installer/hc/it/app/Foo.java
 create mode 100644 src/test/java/org/apache/sling/installer/hc/it/tests/OsgiInstallerHealthCheckIT.java
 create mode 100644 src/test/resources/initial-content/apps/test/config/org.apache.sling.installer.hc.it.app.Bar.cfg
 create mode 100644 src/test/resources/initial-content/apps/test/config/org.apache.sling.installer.hc.it.app.Foo.cfg
 create mode 100644 src/test/resources/initial-content/apps/test/install/org.apache.sling.installer.hc.it.app-1.0.0.jar


[sling-org-apache-sling-installer-hc] 01/02: make configuration external and increase coverage

Posted by ol...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

olli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-installer-hc.git

commit e8bd7fa88b87e56c45d45f76da229a9968918504
Author: Oliver Lietz <ol...@apache.org>
AuthorDate: Sat Jul 23 21:08:32 2022 +0200

    make configuration external and increase coverage
---
 pom.xml                                            | 13 +++++
 .../installer/hc/OsgiInstallerHealthCheck.java     | 40 ++++---------
 .../hc/OsgiInstallerHealthCheckConfiguration.java  | 68 ++++++++++++++++++++++
 .../installer/hc/OsgiInstallerHealthCheckTest.java | 18 ++++--
 4 files changed, 105 insertions(+), 34 deletions(-)

diff --git a/pom.xml b/pom.xml
index d243545..e68c618 100644
--- a/pom.xml
+++ b/pom.xml
@@ -86,6 +86,13 @@
       <artifactId>org.osgi.service.metatype.annotations</artifactId>
       <scope>provided</scope>
     </dependency>
+    <!-- Apache Commons -->
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-lang3</artifactId>
+      <version>3.12.0</version>
+      <scope>test</scope>
+    </dependency>
     <!-- Apache Felix -->
     <dependency>
       <groupId>org.apache.felix</groupId>
@@ -124,6 +131,12 @@
       <version>2.2</version>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <version>4.6.1</version>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
 </project>
diff --git a/src/main/java/org/apache/sling/installer/hc/OsgiInstallerHealthCheck.java b/src/main/java/org/apache/sling/installer/hc/OsgiInstallerHealthCheck.java
index f656573..0baf551 100644
--- a/src/main/java/org/apache/sling/installer/hc/OsgiInstallerHealthCheck.java
+++ b/src/main/java/org/apache/sling/installer/hc/OsgiInstallerHealthCheck.java
@@ -32,21 +32,24 @@ import org.apache.sling.installer.api.info.InfoProvider;
 import org.apache.sling.installer.api.info.InstallationState;
 import org.apache.sling.installer.api.info.Resource;
 import org.apache.sling.installer.api.info.ResourceGroup;
-import org.apache.sling.installer.hc.OsgiInstallerHealthCheck.Configuration;
 import org.osgi.framework.Version;
 import org.osgi.service.cm.ConfigurationAdmin;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Modified;
 import org.osgi.service.component.annotations.Reference;
-import org.osgi.service.metatype.annotations.AttributeDefinition;
 import org.osgi.service.metatype.annotations.Designate;
-import org.osgi.service.metatype.annotations.ObjectClassDefinition;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@Component(property={ HealthCheck.NAME+"="+OsgiInstallerHealthCheck.HC_NAME })
-@Designate(ocd=Configuration.class)
+@Component(
+    property = {
+        HealthCheck.NAME + "=" + OsgiInstallerHealthCheck.HC_NAME
+    }
+)
+@Designate(
+    ocd = OsgiInstallerHealthCheckConfiguration.class
+)
 public class OsgiInstallerHealthCheck implements HealthCheck {
     protected static final String HC_NAME = "OSGi Installer Health Check";
 
@@ -55,7 +58,7 @@ public class OsgiInstallerHealthCheck implements HealthCheck {
 
     private static final Logger LOG = LoggerFactory.getLogger(OsgiInstallerHealthCheck.class);
 
-    private Configuration configuration;
+    private OsgiInstallerHealthCheckConfiguration configuration;
     private Map<String, List<Version>> skipEntityIdsWithVersions;
     
     private static final String DOCUMENTATION_URL = "https://sling.apache.org/documentation/bundles/osgi-installer.html#health-check";
@@ -63,32 +66,9 @@ public class OsgiInstallerHealthCheck implements HealthCheck {
     @Reference
     private ConfigurationAdmin configurationAdmin;
     
-    @ObjectClassDefinition(name = HC_NAME, 
-            description="Checks that all OSGi configurations/bundles are successfully installed by the OSGi Installer (and are not skipped for some reason).")
-    protected static @interface Configuration {
-        @AttributeDefinition(name="Tags", description="Tags with which this healthcheck is associated")
-        @SuppressWarnings("java:S100")
-        String[] hc_tags() default {"installer", "osgi"};
-        
-        @AttributeDefinition(name="URL Prefixes to consider", description = "Only those OSGi configurations/bundles whose location are starting with one of the given URL prefixes are checked (whether they are installed correctly). Open /system/console/osgi-installer for a list of valid prefixes.")
-        String[] urlPrefixes() default "jcrinstall:/apps/";
-        
-        @AttributeDefinition(name="Check Bundles", description = "If enabled bundles are checked (restricted to the ones matching one of the prefixes)")
-        boolean checkBundles() default true;
-        
-        @AttributeDefinition(name="Check Configurations", description = "If enabled configurations are checked (restricted to the ones matching one of the prefixes)")
-        boolean checkConfigurations() default true;
-        
-        @AttributeDefinition(name="Allow ignored artifacts in a group", description = "If true there is no warning reported for not installed artifacts if at least one artifact in the same group (i.e. with the same entity id) is installed matching one of the configured URL prefixes. Otherwise there is a warning for every ignored artifact.")
-        boolean allowIgnoredArtifactsInGroup() default false;
-        
-        @AttributeDefinition(name="Skip entity ids", description = "The given entity ids should be skipped for the health check. Each entry has the format '<entity id> [<version>]'.")
-        String[] skipEntityIds();
-    }
-
     @Activate
     @Modified
-    protected void configure(Configuration configuration) {
+    protected void configure(OsgiInstallerHealthCheckConfiguration configuration) {
         this.configuration = configuration;
         try {
             skipEntityIdsWithVersions = parseEntityIdsWithVersions(configuration.skipEntityIds());
diff --git a/src/main/java/org/apache/sling/installer/hc/OsgiInstallerHealthCheckConfiguration.java b/src/main/java/org/apache/sling/installer/hc/OsgiInstallerHealthCheckConfiguration.java
new file mode 100644
index 0000000..0527f7b
--- /dev/null
+++ b/src/main/java/org/apache/sling/installer/hc/OsgiInstallerHealthCheckConfiguration.java
@@ -0,0 +1,68 @@
+/*
+ * 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 SF 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.hc;
+
+import org.osgi.service.metatype.annotations.AttributeDefinition;
+import org.osgi.service.metatype.annotations.ObjectClassDefinition;
+
+import static org.apache.sling.installer.hc.OsgiInstallerHealthCheck.HC_NAME;
+
+@ObjectClassDefinition(
+    name = HC_NAME,
+    description = "Checks that all OSGi configurations/bundles are successfully installed by the OSGi Installer (and are not skipped for some reason)."
+)
+@interface OsgiInstallerHealthCheckConfiguration {
+
+    @AttributeDefinition(
+        name = "Tags",
+        description = "Tags with which this healthcheck is associated"
+    )
+    @SuppressWarnings("java:S100")
+    String[] hc_tags() default {"installer", "osgi"};
+
+    @AttributeDefinition(
+        name = "URL Prefixes to consider",
+        description = "Only those OSGi configurations/bundles whose location are starting with one of the given URL prefixes are checked (whether they are installed correctly). Open /system/console/osgi-installer for a list of valid prefixes."
+    )
+    String[] urlPrefixes() default "jcrinstall:/apps/";
+
+    @AttributeDefinition(
+        name = "Check Bundles",
+        description = "If enabled bundles are checked (restricted to the ones matching one of the prefixes)"
+    )
+    boolean checkBundles() default true;
+
+    @AttributeDefinition(
+        name = "Check Configurations",
+        description = "If enabled configurations are checked (restricted to the ones matching one of the prefixes)"
+    )
+    boolean checkConfigurations() default true;
+
+    @AttributeDefinition(
+        name = "Allow ignored artifacts in a group",
+        description = "If true there is no warning reported for not installed artifacts if at least one artifact in the same group (i.e. with the same entity id) is installed matching one of the configured URL prefixes. Otherwise there is a warning for every ignored artifact."
+    )
+    boolean allowIgnoredArtifactsInGroup() default false;
+
+    @AttributeDefinition(
+        name = "Skip entity ids",
+        description = "The given entity ids should be skipped for the health check. Each entry has the format '<entity id> [<version>]'."
+    )
+    String[] skipEntityIds();
+
+}
diff --git a/src/test/java/org/apache/sling/installer/hc/OsgiInstallerHealthCheckTest.java b/src/test/java/org/apache/sling/installer/hc/OsgiInstallerHealthCheckTest.java
index e1789ec..e8d6a9c 100644
--- a/src/test/java/org/apache/sling/installer/hc/OsgiInstallerHealthCheckTest.java
+++ b/src/test/java/org/apache/sling/installer/hc/OsgiInstallerHealthCheckTest.java
@@ -21,27 +21,37 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.commons.lang3.reflect.FieldUtils;
 import org.hamcrest.Matchers;
 import org.junit.Test;
 import org.osgi.framework.Version;
 
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 public class OsgiInstallerHealthCheckTest {
 
     @Test
-    public void testParseEntityIdsWithVersions() {
+    public void testParseEntityIdsWithVersions() throws IllegalAccessException {
         String[] entityIdsAndVersions = new String[] { "idA 1.0.0", "idA 2.0.0", "idB" };
-        Map<String, List<Version>> map = OsgiInstallerHealthCheck.parseEntityIdsWithVersions(entityIdsAndVersions);
+        final OsgiInstallerHealthCheckConfiguration configuration = mock(OsgiInstallerHealthCheckConfiguration.class);
+        when(configuration.skipEntityIds()).thenReturn(entityIdsAndVersions);
+        final OsgiInstallerHealthCheck healthCheck = new OsgiInstallerHealthCheck();
+        healthCheck.configure(configuration);
+        Map<String, List<Version>> map = (Map<String, List<Version>>) FieldUtils.readDeclaredField(healthCheck, "skipEntityIdsWithVersions", true);
         assertThat(map, Matchers.allOf(
                 Matchers.aMapWithSize(2),
                 Matchers.hasEntry("idA", Arrays.asList(new Version("1.0.0"), new Version("2.0.0"))),
                 Matchers.hasEntry("idB", null)));
     }
 
-    @Test(expected=IllegalArgumentException.class)
+    @Test(expected=IllegalStateException.class)
     public void testParseEntityIdsWithVersionsAndConflictingVersions() {
         String[] entityIdsAndVersions = new String[] { "idA", "idA 2.0.0", "idB" };
-        OsgiInstallerHealthCheck.parseEntityIdsWithVersions(entityIdsAndVersions);
+        final OsgiInstallerHealthCheckConfiguration configuration = mock(OsgiInstallerHealthCheckConfiguration.class);
+        when(configuration.skipEntityIds()).thenReturn(entityIdsAndVersions);
+        final OsgiInstallerHealthCheck healthCheck = new OsgiInstallerHealthCheck();
+        healthCheck.configure(configuration);
     }
 }


[sling-org-apache-sling-installer-hc] 02/02: add initial integration test

Posted by ol...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

olli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-installer-hc.git

commit 72eed1208a98c578242171d25e3158c52d14cc5d
Author: Oliver Lietz <ol...@apache.org>
AuthorDate: Mon Jul 25 23:04:29 2022 +0200

    add initial integration test
---
 pom.xml                                            |  86 ++++++++++
 .../hc/it/InstallerHealthCheckTestSupport.java     |  67 ++++++++
 .../org/apache/sling/installer/hc/it/app/Foo.java  |  27 ++++
 .../hc/it/tests/OsgiInstallerHealthCheckIT.java    | 179 +++++++++++++++++++++
 .../org.apache.sling.installer.hc.it.app.Bar.cfg   |   2 +
 .../org.apache.sling.installer.hc.it.app.Foo.cfg   |   2 +
 .../org.apache.sling.installer.hc.it.app-1.0.0.jar | Bin 0 -> 2566 bytes
 7 files changed, 363 insertions(+)

diff --git a/pom.xml b/pom.xml
index e68c618..a775326 100644
--- a/pom.xml
+++ b/pom.xml
@@ -44,10 +44,24 @@
   <properties>
     <project.build.outputTimestamp>2022-07-18T21:48:29Z</project.build.outputTimestamp>
     <sling.java.version>8</sling.java.version>
+    <org.ops4j.pax.exam.version>4.13.3</org.ops4j.pax.exam.version>
   </properties>
 
   <build>
     <plugins>
+      <plugin>
+        <groupId>org.apache.rat</groupId>
+        <artifactId>apache-rat-plugin</artifactId>
+        <configuration>
+          <excludes>
+            <exclude>src/test/resources/initial-content/apps/test/config/*</exclude>
+          </excludes>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.servicemix.tooling</groupId>
+        <artifactId>depends-maven-plugin</artifactId>
+      </plugin>
       <plugin>
         <groupId>biz.aQute.bnd</groupId>
         <artifactId>bnd-maven-plugin</artifactId>
@@ -56,10 +70,34 @@
         <groupId>biz.aQute.bnd</groupId>
         <artifactId>bnd-baseline-maven-plugin</artifactId>
       </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-failsafe-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>integration-test</goal>
+              <goal>verify</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <redirectTestOutputToFile>true</redirectTestOutputToFile>
+          <systemPropertyVariables combine.children="append">
+            <bundle.filename>${basedir}/target/${project.build.finalName}.jar</bundle.filename>
+          </systemPropertyVariables>
+        </configuration>
+      </plugin>
     </plugins>
   </build>
 
   <dependencies>
+    <!-- javax/jakarta -->
+    <dependency>
+      <groupId>javax.inject</groupId>
+      <artifactId>javax.inject</artifactId>
+      <scope>test</scope>
+    </dependency>
     <!-- OSGi -->
     <dependency>
       <groupId>org.osgi</groupId>
@@ -94,6 +132,12 @@
       <scope>test</scope>
     </dependency>
     <!-- Apache Felix -->
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.framework</artifactId>
+      <version>7.0.5</version>
+      <scope>test</scope>
+    </dependency>
     <dependency>
       <groupId>org.apache.felix</groupId>
       <artifactId>org.apache.felix.healthcheck.api</artifactId>
@@ -113,6 +157,12 @@
       <version>1.0.0</version>
       <scope>provided</scope>
     </dependency>
+    <dependency>
+      <groupId>org.apache.sling</groupId>
+      <artifactId>org.apache.sling.testing.paxexam</artifactId>
+      <version>4.0.0-SNAPSHOT</version>
+      <scope>test</scope>
+    </dependency>
     <!-- logging -->
     <dependency>
       <groupId>org.slf4j</groupId>
@@ -125,6 +175,12 @@
       <artifactId>junit</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.awaitility</groupId>
+      <artifactId>awaitility</artifactId>
+      <version>4.2.0</version>
+      <scope>test</scope>
+    </dependency>
     <dependency>
       <groupId>org.hamcrest</groupId>
       <artifactId>hamcrest</artifactId>
@@ -137,6 +193,36 @@
       <version>4.6.1</version>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.ops4j.pax.exam</groupId>
+      <artifactId>pax-exam</artifactId>
+      <version>${org.ops4j.pax.exam.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.ops4j.pax.exam</groupId>
+      <artifactId>pax-exam-cm</artifactId>
+      <version>${org.ops4j.pax.exam.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.ops4j.pax.exam</groupId>
+      <artifactId>pax-exam-container-forked</artifactId>
+      <version>${org.ops4j.pax.exam.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.ops4j.pax.exam</groupId>
+      <artifactId>pax-exam-junit4</artifactId>
+      <version>${org.ops4j.pax.exam.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.ops4j.pax.exam</groupId>
+      <artifactId>pax-exam-link-mvn</artifactId>
+      <version>${org.ops4j.pax.exam.version}</version>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
 </project>
diff --git a/src/test/java/org/apache/sling/installer/hc/it/InstallerHealthCheckTestSupport.java b/src/test/java/org/apache/sling/installer/hc/it/InstallerHealthCheckTestSupport.java
new file mode 100644
index 0000000..e93a999
--- /dev/null
+++ b/src/test/java/org/apache/sling/installer/hc/it/InstallerHealthCheckTestSupport.java
@@ -0,0 +1,67 @@
+/*
+ * 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 SF 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.hc.it;
+
+import javax.inject.Inject;
+
+import org.apache.sling.testing.paxexam.TestSupport;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.options.ModifiableCompositeOption;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+import static org.apache.sling.testing.paxexam.SlingOptions.awaitility;
+import static org.apache.sling.testing.paxexam.SlingOptions.felixHealthcheck;
+import static org.apache.sling.testing.paxexam.SlingOptions.hamcrest;
+import static org.apache.sling.testing.paxexam.SlingOptions.junit;
+import static org.apache.sling.testing.paxexam.SlingOptions.slingInstaller;
+import static org.apache.sling.testing.paxexam.SlingOptions.slingQuickstartOakTar;
+import static org.ops4j.pax.exam.CoreOptions.composite;
+
+public abstract class InstallerHealthCheckTestSupport extends TestSupport {
+
+    @Inject
+    protected BundleContext bundleContext;
+
+    @Inject
+    protected ConfigurationAdmin configurationAdmin;
+
+    protected ModifiableCompositeOption baseConfiguration() {
+        return composite(
+            super.baseConfiguration(),
+            quickstart(),
+            // Sling Installer Health Checks
+            testBundle("bundle.filename"),
+            felixHealthcheck(),
+            slingInstaller(),
+            // testing
+            junit(),
+            hamcrest(),
+            awaitility()
+        );
+    }
+
+    protected Option quickstart() {
+        final int httpPort = findFreePort();
+        final String workingDirectory = workingDirectory();
+        return composite(
+            slingQuickstartOakTar(workingDirectory, httpPort)
+        );
+    }
+
+}
diff --git a/src/test/java/org/apache/sling/installer/hc/it/app/Foo.java b/src/test/java/org/apache/sling/installer/hc/it/app/Foo.java
new file mode 100644
index 0000000..fe8834f
--- /dev/null
+++ b/src/test/java/org/apache/sling/installer/hc/it/app/Foo.java
@@ -0,0 +1,27 @@
+/*
+ * 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 SF 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.hc.it.app;
+
+import java.io.Serializable;
+
+import org.osgi.service.component.annotations.Component;
+
+@Component
+public class Foo implements Serializable {
+
+}
diff --git a/src/test/java/org/apache/sling/installer/hc/it/tests/OsgiInstallerHealthCheckIT.java b/src/test/java/org/apache/sling/installer/hc/it/tests/OsgiInstallerHealthCheckIT.java
new file mode 100644
index 0000000..f7fd991
--- /dev/null
+++ b/src/test/java/org/apache/sling/installer/hc/it/tests/OsgiInstallerHealthCheckIT.java
@@ -0,0 +1,179 @@
+/*
+ * 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 SF 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.hc.it.tests;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Objects;
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import org.apache.felix.hc.api.HealthCheck;
+import org.apache.felix.hc.api.Result;
+import org.apache.sling.installer.hc.it.InstallerHealthCheckTestSupport;
+import org.apache.sling.installer.hc.it.app.Foo;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.ProbeBuilder;
+import org.ops4j.pax.exam.TestProbeBuilder;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+import org.ops4j.pax.exam.util.Filter;
+import org.ops4j.pax.tinybundles.core.TinyBundles;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.Version;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.apache.sling.testing.paxexam.SlingOptions.slingInstallerFactoryConfiguration;
+import static org.apache.sling.testing.paxexam.SlingOptions.slingInstallerProviderJcr;
+import static org.awaitility.Awaitility.with;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.cm.ConfigurationAdminOptions.newConfiguration;
+import static org.ops4j.pax.tinybundles.core.TinyBundles.withBnd;
+
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class OsgiInstallerHealthCheckIT extends InstallerHealthCheckTestSupport {
+
+    @Inject
+    @Filter(value = "(hc.name=OSGi Installer Health Check)")
+    private HealthCheck healthCheck;
+
+    private static final String PID = "org.apache.sling.installer.hc.OsgiInstallerHealthCheck";
+
+    private static final String BAR_PID = "org.apache.sling.installer.hc.it.app.Bar";
+
+    private static final String FOO_PID = "org.apache.sling.installer.hc.it.app.Foo";
+
+    private static final String BSN = "org.apache.sling.installer.hc.it.app";
+
+    @Configuration
+    public Option[] configuration() {
+        return options(
+            baseConfiguration(),
+            slingInstallerFactoryConfiguration(),
+            slingInstallerProviderJcr(),
+            newConfiguration(PID)
+                .put("allowIgnoredArtifactsInGroup", true)
+                .put("checkBundles", false)
+                .put("skipEntityIds", new String[]{"config:org.apache.sling.installer.hc.it.app.Bar 1.0.0"})
+                .asOption()
+        );
+    }
+
+    @ProbeBuilder
+    public TestProbeBuilder probeConfiguration(final TestProbeBuilder testProbeBuilder) {
+        testProbeBuilder.setHeader("Sling-Initial-Content", "initial-content;ignoreImportProviders:=jar");
+        return testProbeBuilder;
+    }
+
+    private boolean hasBundle(final String symbolicName, final String version) {
+        final Version v = new Version(version);
+        final Bundle[] bundles = bundleContext.getBundles();
+        for (final Bundle bundle : bundles) {
+            if (bundle.getSymbolicName().equals(symbolicName) && bundle.getVersion().equals(v)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean hasConfiguration(final String pid) throws InvalidSyntaxException, IOException {
+        final String filter = String.format("(service.pid=%s)", pid);
+        org.osgi.service.cm.Configuration[] configurations = configurationAdmin.listConfigurations(filter);
+        return !Objects.isNull(configurations) && configurations.length > 0;
+    }
+
+    private void installFooBundle() throws BundleException {
+        final InputStream inputStream = TinyBundles.
+            bundle().
+            add(Foo.class).
+            set("Bundle-Name", "Apache Sling Installer HealthChecks IT App").
+            set("Bundle-SymbolicName", BSN).
+            set("Bundle-Version", "1.0.0").
+            build(withBnd());
+        bundleContext.installBundle(UUID.randomUUID().toString(), inputStream);
+    }
+
+    @Test
+    public void testHealthCheckExecutionResults() throws Exception {
+
+        with().
+            pollInterval(100, MILLISECONDS).
+            then().
+            await("check for bundle installed via initial content").
+            atMost(10, SECONDS).
+            until(() -> hasBundle(BSN, "1.0.0"));
+
+        with().
+            pollInterval(100, MILLISECONDS).
+            then().
+            await("check for Bar configuration installed via initial content").
+            atMost(10, SECONDS).
+            until(() -> hasConfiguration(BAR_PID));
+
+        with().
+            pollInterval(100, MILLISECONDS).
+            then().
+            await("check for Foo configuration installed via initial content").
+            atMost(10, SECONDS).
+            until(() -> hasConfiguration(FOO_PID));
+
+        {
+            final Result result = healthCheck.execute();
+            assertThat(result.isOk(), equalTo(true));
+            assertThat(result.getStatus(), equalTo(Result.Status.OK));
+        }
+
+        {
+            final Dictionary<String, Object> properties = new Hashtable<>();
+            properties.put("source", "osgi-cm");
+            properties.put("updated", true);
+            final org.osgi.service.cm.Configuration configuration = configurationAdmin.getConfiguration(FOO_PID, null);
+            configuration.update(properties);
+        }
+
+        {
+            final Dictionary<String, Object> properties = new Hashtable<>();
+            properties.put("source", "osgi-cm");
+            properties.put("updated", true);
+            final org.osgi.service.cm.Configuration configuration = configurationAdmin.getConfiguration(BAR_PID, null);
+            configuration.update(properties);
+        }
+
+        with().
+            pollInterval(100, MILLISECONDS).
+            then().
+            await().
+            atMost(1, SECONDS).
+            until(() -> !healthCheck.execute().isOk());
+        assertThat(healthCheck.execute().getStatus(), equalTo(Result.Status.CRITICAL));
+    }
+
+}
diff --git a/src/test/resources/initial-content/apps/test/config/org.apache.sling.installer.hc.it.app.Bar.cfg b/src/test/resources/initial-content/apps/test/config/org.apache.sling.installer.hc.it.app.Bar.cfg
new file mode 100644
index 0000000..9c41085
--- /dev/null
+++ b/src/test/resources/initial-content/apps/test/config/org.apache.sling.installer.hc.it.app.Bar.cfg
@@ -0,0 +1,2 @@
+service.pid=org.apache.sling.installer.hc.it.app.Bar
+source=initial-content
diff --git a/src/test/resources/initial-content/apps/test/config/org.apache.sling.installer.hc.it.app.Foo.cfg b/src/test/resources/initial-content/apps/test/config/org.apache.sling.installer.hc.it.app.Foo.cfg
new file mode 100644
index 0000000..7176657
--- /dev/null
+++ b/src/test/resources/initial-content/apps/test/config/org.apache.sling.installer.hc.it.app.Foo.cfg
@@ -0,0 +1,2 @@
+service.pid=org.apache.sling.installer.hc.it.app.Foo
+source=initial-content
diff --git a/src/test/resources/initial-content/apps/test/install/org.apache.sling.installer.hc.it.app-1.0.0.jar b/src/test/resources/initial-content/apps/test/install/org.apache.sling.installer.hc.it.app-1.0.0.jar
new file mode 100644
index 0000000..016530d
Binary files /dev/null and b/src/test/resources/initial-content/apps/test/install/org.apache.sling.installer.hc.it.app-1.0.0.jar differ