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

sseifert pushed a commit to branch master
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-models-validation-impl.git


The following commit(s) were added to refs/heads/master by this push:
     new e71d181  SLING-13080 Migrate ITs to Feature Model and Sling 14 (#2)
e71d181 is described below

commit e71d1818605f8267cdcbd6e43a9e8925732f99a0
Author: Stefan Seifert <[email protected]>
AuthorDate: Thu Jan 29 20:57:46 2026 +0100

    SLING-13080 Migrate ITs to Feature Model and Sling 14 (#2)
---
 .sling-module.json                                 |   5 +
 pom.xml                                            | 442 ++++++++++++++-------
 .../it-launcher-repoinit.txt}                      |  24 +-
 src/test/it-features/it-launcher.json              |  26 ++
 .../customizers/SM_TeleporterCustomizer.java       |  59 +++
 .../validation/impl/it/GenerateTestBundle.java     | 109 +++++
 .../models}/ModelValidationDisabled.java           |   2 +-
 .../models}/ModelValidationOptional.java           |   2 +-
 .../models}/ModelValidationRequired.java           |   2 +-
 .../impl/it/{ => testing}/ModelValidationIT.java   |  13 +-
 10 files changed, 521 insertions(+), 163 deletions(-)

diff --git a/.sling-module.json b/.sling-module.json
new file mode 100644
index 0000000..cfad4d2
--- /dev/null
+++ b/.sling-module.json
@@ -0,0 +1,5 @@
+{
+  "jenkins": {
+    "jdks": [17, 21]
+  }
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 9512dfd..b87cbc2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -18,13 +18,12 @@
     under the License.
 -->
 <project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
-
     <modelVersion>4.0.0</modelVersion>
 
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling-bundle-parent</artifactId>
-        <version>49</version>
+        <version>52</version>
         <relativePath />
     </parent>
 
@@ -35,126 +34,22 @@
     <description>Validation Implementation which leverages Sling 
Validation</description>
 
     <properties>
-        <sling.java.version>8</sling.java.version>
-        <http.host>localhost</http.host>
-        <!-- start with -DkeepITServerRunning=true to allow to rerun ITs or 
inspect the server after the ITs have been executed there -->
-        <keepITServerRunning>false</keepITServerRunning>
         
<project.build.outputTimestamp>2021-12-07T08:24:38Z</project.build.outputTimestamp>
+        <sling.java.version>11</sling.java.version>
+        <!-- integration tests -->
+        <sling.starter.version>14-SNAPSHOT</sling.starter.version>
+        <starter.min.bundles.count>200</starter.min.bundles.count>
+        <it.startTimeoutSeconds>60</it.startTimeoutSeconds>
+        <it.models.log.level>debug</it.models.log.level>
     </properties>
 
     <scm>
         
<connection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-models-validation-impl.git</connection>
         
<developerConnection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-models-validation-impl.git</developerConnection>
         
<url>https://github.com/apache/sling-org-apache-sling-models-validation-impl.git</url>
-      <tag>HEAD</tag>
-  </scm>
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>biz.aQute.bnd</groupId>
-                <artifactId>bnd-baseline-maven-plugin</artifactId>
-                <configuration>
-                    <failOnMissing>false</failOnMissing>
-                </configuration>
-            </plugin>
-            <plugin>
-                <!-- Find free ports to run our server -->
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>build-helper-maven-plugin</artifactId>
-                <executions>
-                    <execution>
-                        <id>reserve-server-port</id>
-                        <goals>
-                            <goal>reserve-network-port</goal>
-                        </goals>
-                        <phase>pre-integration-test</phase>
-                        <configuration>
-                            <portNames>
-                                <!-- used port name must be stored in property 
because it must be used for the base url -->
-                                <portName>http.port</portName>
-                            </portNames>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
-            <plugin>
-                <!-- the Sling instance is provisioned from the model in 
src/main/provisioning/model.txt -->
-                <groupId>org.apache.sling</groupId>
-                <artifactId>slingstart-maven-plugin</artifactId>
-                <extensions>true</extensions>
-                <executions>
-                    <execution>
-                        <id>prepare-launchpad-package</id>
-                        <goals>
-                            <goal>prepare-package</goal>
-                        </goals>
-                        <phase>pre-integration-test</phase>
-                    </execution>
-                    <execution>
-                        <id>build-launchpad-package</id>
-                        <goals>
-                            <goal>package</goal>
-                        </goals>
-                        <phase>pre-integration-test</phase>
-                    </execution>
-                    <execution>
-                        <id>start-container-before-IT</id>
-                        <goals>
-                            <goal>start</goal>
-                        </goals>
-                        <configuration>
-                        </configuration>
-                    </execution>
-                    <execution>
-                        <id>stop-container-after-IT</id>
-                        <goals>
-                            <goal>stop</goal>
-                        </goals>
-                        <configuration>
-                            
<shouldBlockUntilKeyIsPressed>${keepITServerRunning}</shouldBlockUntilKeyIsPressed>
-                        </configuration>
-                    </execution>
-                </executions>
-                <configuration>
-                    <servers>
-                        <!-- this configuration applies to both 'start' and 
'stop' -->
-                        <server>
-                            <id>singleinstance</id>
-                            <port>${http.port}</port>
-                            <vmOpts>${sling.vm.options}</vmOpts>
-                            <stdOutFile>sling/logs/stdout.log</stdOutFile>
-                        </server>
-                    </servers>
-                    <!-- this configuration only applies to 'prepare-package' 
and 'package' -->
-                    
<disableExtendingMavenClasspath>true</disableExtendingMavenClasspath>
-                    <attachArtifact>false</attachArtifact>
-                </configuration>
-            </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>
-                    <systemPropertyVariables>
-                        
<ClientSideTeleporter.baseUrl>http://${http.host}:${http.port}/</ClientSideTeleporter.baseUrl>
-                        
<ClientSideTeleporter.testReadyTimeoutSeconds>20</ClientSideTeleporter.testReadyTimeoutSeconds>
-                        
<ClientSideTeleporter.testBundleDirectory>${project.build.directory}/test-bundles</ClientSideTeleporter.testBundleDirectory>
-                        
<ClientSideTeleporter.enableLogging>true</ClientSideTeleporter.enableLogging>
-                        <!-- deploy test content and some Sling models with 
the test bundle -->
-                        
<ClientSideTeleporter.additionalBundleHeaders>Sling-Initial-Content:SLING-CONTENT/apps/sling/validation;overwrite:=true;path:=/apps/sling/validation,Sling-Model-Packages:org.apache.sling.models.validation.impl.it</ClientSideTeleporter.additionalBundleHeaders>
-                        
<ClientSideTeleporter.includeDependencyPrefixes>org.apache.sling.models.validation.impl.it</ClientSideTeleporter.includeDependencyPrefixes>
-                    </systemPropertyVariables>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
+        <tag>HEAD</tag>
+    </scm>
+
     <dependencies>
         <dependency>
             <groupId>org.osgi</groupId>
@@ -162,31 +57,30 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.models.api</artifactId>
-            <version>1.2.0</version>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.service.component.annotations</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>javax.servlet</groupId>
-            <artifactId>javax.servlet-api</artifactId>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.service.metatype.annotations</artifactId>
             <scope>provided</scope>
         </dependency>
-        <!-- OSGi annotations -->
         <dependency>
-            <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.service.component.annotations</artifactId>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.models.api</artifactId>
+            <version>1.5.4</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.service.metatype.annotations</artifactId>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.api</artifactId>
-            <version>2.5.0</version>
+            <version>2.25.4</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
@@ -205,32 +99,312 @@
             <artifactId>annotations</artifactId>
             <scope>provided</scope>
         </dependency>
+        <!-- Test dependencies -->
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>org.mockito</groupId>
-            <artifactId>mockito-all</artifactId>
-            <version>1.9.5</version>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
             <scope>test</scope>
         </dependency>
+        <!-- Integration test dependencies -->
         <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-simple</artifactId>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.junit.core</artifactId>
+            <version>1.2.0</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.testing.rules</artifactId>
+            <version>2.0.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.testing.clients</artifactId>
+            <version>3.1.0</version>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>javax.servlet</groupId>
+                    <artifactId>servlet-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.junit.teleporter</artifactId>
-            <version>1.0.22</version>
+            <version>1.1.0</version>
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.framework</artifactId>
+            <groupId>jakarta.json</groupId>
+            <artifactId>jakarta.json-api</artifactId>
+            <version>2.1.1</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.johnzon</groupId>
+            <artifactId>johnzon-core</artifactId>
+            <version>2.0.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.engine</artifactId>
+            <version>3.0.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>io.github.classgraph</groupId>
+            <artifactId>classgraph</artifactId>
+            <version>4.8.184</version>
             <scope>test</scope>
         </dependency>
     </dependencies>
+
+    <build>
+        <plugins>
+
+            <!-- Generate IT Test Bundle on the fly via TinyBundles -->
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>exec-maven-plugin</artifactId>
+                <version>3.6.3</version>
+                <executions>
+                    <execution>
+                        <id>generate-it-testbundle</id>
+                        <goals>
+                            <goal>java</goal>
+                        </goals>
+                        <phase>prepare-package</phase>
+                        <configuration>
+                            <classpathScope>test</classpathScope>
+                            
<mainClass>org.apache.sling.models.validation.impl.it.GenerateTestBundle</mainClass>
+                            <arguments>
+                                
<argument>${project.build.directory}/it-testbundle.jar</argument>
+                            </arguments>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>reserve-network-port</id>
+                        <goals>
+                            <goal>reserve-network-port</goal>
+                        </goals>
+                        <phase>initialize</phase>
+                        <configuration>
+                            <portNames>
+                                <portName>http.port</portName>
+                                <portName>jacoco.port</portName>
+                            </portNames>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>attach-it-testbundle</id>
+                        <goals>
+                            <goal>attach-artifact</goal>
+                        </goals>
+                        <configuration>
+                            <artifacts>
+                                <artifact>
+                                    
<file>${project.build.directory}/it-testbundle.jar</file>
+                                    <type>jar</type>
+                                    <classifier>it-testbundle</classifier>
+                                </artifact>
+                            </artifacts>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.jacoco</groupId>
+                <artifactId>jacoco-maven-plugin</artifactId>
+                <executions>
+                    <!--
+                    Record integration test code coverage via jacoco, using 
TCP server
+                    We cannot rely on the default file-based approach as the 
sling JVM is stopped forcefully, preventing proper file write on shutdown.
+                    -->
+                    <execution>
+                        <id>prepare-agent-integration-launcher</id>
+                        <goals>
+                            <goal>prepare-agent-integration</goal>
+                        </goals>
+                        <configuration>
+                            
<propertyName>jacoco.launcher.command</propertyName>
+                            <output>tcpserver</output>
+                            <address>localhost</address>
+                            <port>${jacoco.port}</port>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>dump-coverage-launcher</id>
+                        <goals>
+                            <goal>dump</goal>
+                        </goals>
+                        <phase>post-integration-test</phase>
+                        <configuration>
+                            <address>localhost</address>
+                            <port>${jacoco.port}</port>
+                            
<destFile>${project.build.directory}/jacoco-it.exec</destFile>
+                            <append>true</append>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.sling</groupId>
+                <artifactId>slingfeature-maven-plugin</artifactId>
+                <version>1.9.2</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <features>src/test/it-features</features>
+                    
<replacePropertyVariables>it.models.log.level</replacePropertyVariables>
+                    
<skipAddFeatureDependencies>true</skipAddFeatureDependencies>
+                    <aggregates>
+                        <aggregate>
+                            <classifier>it-app</classifier>
+                            <filesInclude>*.json</filesInclude>
+                            <variablesOverrides>
+                                <http.port>${http.port}</http.port>
+                            </variablesOverrides>
+                            <artifactsOverrides>
+                                
<artifactsOverride>org.apache.sling:org.apache.sling.models.validation-impl:HIGHEST</artifactsOverride>
+                            </artifactsOverrides>
+                            <includeArtifact>
+                                <groupId>org.apache.sling</groupId>
+                                
<artifactId>org.apache.sling.starter</artifactId>
+                                <classifier>nosample_base</classifier>
+                                <version>${sling.starter.version}</version>
+                                <type>slingosgifeature</type>
+                            </includeArtifact>
+                            <includeArtifact>
+                                <groupId>org.apache.sling</groupId>
+                                
<artifactId>org.apache.sling.starter</artifactId>
+                                <classifier>oak_persistence_sns</classifier>
+                                <version>${sling.starter.version}</version>
+                                <type>slingosgifeature</type>
+                            </includeArtifact>
+                            <includeArtifact>
+                                <groupId>org.apache.sling</groupId>
+                                
<artifactId>org.apache.sling.starter</artifactId>
+                                <classifier>junit</classifier>
+                                <version>${sling.starter.version}</version>
+                                <type>slingosgifeature</type>
+                            </includeArtifact>
+                        </aggregate>
+                    </aggregates>
+                    <scans>
+                        <scan>
+                            <includeClassifier>it-app</includeClassifier>
+                        </scan>
+                    </scans>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>prepare-features</id>
+                        <goals>
+                            <goal>aggregate-features</goal>
+                            <goal>analyse-features</goal>
+                            <goal>attach-features</goal>
+                        </goals>
+                        <phase>pre-integration-test</phase>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.sling</groupId>
+                <artifactId>feature-launcher-maven-plugin</artifactId>
+                <version>1.0.3-SNAPSHOT</version>
+                <configuration>
+                    <launches>
+                        <launch>
+                            <id>sling-starter-oak-tar</id>
+                            <feature>
+                                <groupId>org.apache.sling</groupId>
+                                
<artifactId>org.apache.sling.models.validation-impl</artifactId>
+                                <version>${project.version}</version>
+                                <classifier>it-app</classifier>
+                                <type>slingosgifeature</type>
+                            </feature>
+                            <launcherArguments>
+                                <vmOptions>
+                                    <value>--add-opens 
java.base/java.lang=ALL-UNNAMED</value>
+                                    <value>${jacoco.launcher.command}</value>
+                                </vmOptions>
+                                <frameworkProperties>
+                                    
<org.osgi.service.http.port>${http.port}</org.osgi.service.http.port>
+                                    
<org.apache.felix.http.jetty.responseBufferSize>5000000</org.apache.felix.http.jetty.responseBufferSize>
+                                </frameworkProperties>
+                            </launcherArguments>
+                            
<startTimeoutSeconds>${it.startTimeoutSeconds}</startTimeoutSeconds>
+                        </launch>
+                    </launches>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>launcher-start</id>
+                        <goals>
+                            <goal>start</goal>
+                            <goal>stop</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <artifactId>maven-failsafe-plugin</artifactId>
+                <configuration>
+                    <systemPropertyVariables>
+                        
<launchpad.http.server.url>http://localhost:${http.port}</launchpad.http.server.url>
+                        
<starter.http.test.ports>false:${http.port}</starter.http.test.ports>
+                        
<starter.min.bundles.count>${starter.min.bundles.count}</starter.min.bundles.count>
+                        <!-- Comma-separated list of paths to check for 200 
status -->
+                        
<starter.check.paths>/system/console/bundles,</starter.check.paths>
+                    </systemPropertyVariables>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>integration-test</id>
+                        <goals>
+                            <goal>integration-test</goal>
+                            <goal>verify</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+        </plugins>
+    </build>
+
+    <profiles>
+        <!--
+          Debugging profile:
+          - Run on port 8080 (not random port)
+          - Waits for user input after tests are completed to allow inspection 
before shutting down the Sling instance
+          - Sets log level for Sling Models to DEBUG
+         -->
+        <profile>
+            <id>it-debug</id>
+            <properties>
+                <http.port>8080</http.port>
+                
<feature-launcher.waitForInput>true</feature-launcher.waitForInput>
+                <it.models.log.level>debug</it.models.log.level>
+            </properties>
+        </profile>
+    </profiles>
+
 </project>
diff --git a/src/test/provisioning/model.txt 
b/src/test/it-features/it-launcher-repoinit.txt
similarity index 50%
rename from src/test/provisioning/model.txt
rename to src/test/it-features/it-launcher-repoinit.txt
index 7a690a1..7d36118 100644
--- a/src/test/provisioning/model.txt
+++ b/src/test/it-features/it-launcher-repoinit.txt
@@ -17,23 +17,7 @@
 #  under the License.
 #
 
-# features are ordered alphabetically, so make this feature the last one in 
order to overwrite configurations with same PIDs from other features
-[feature name=zzz.models.validation-impl.it]
-# Dependencies
-[artifacts]
-  org.apache.sling/org.apache.sling.starter/11/slingstart
-  # this is necessary to execute the tests
-  org.apache.sling/org.apache.sling.junit.core/1.0.28
-  # deploy the to-be-tested bundle as well
-  org.apache.sling/org.apache.sling.models.validation-impl
-
-[configurations]
-
-  # configure service user mapping for junit core (being used in the IT itself)
-  org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended-junit
-    user.mapping=[
-    "org.apache.sling.junit.core\=sling-readall"
-    ]
-
-[settings]
-  org.apache.sling.commons.log.julenabled=true
+create service user models-it
+set ACL for models-it
+    allow   jcr:all    on /
+end
\ No newline at end of file
diff --git a/src/test/it-features/it-launcher.json 
b/src/test/it-features/it-launcher.json
new file mode 100644
index 0000000..458d55b
--- /dev/null
+++ b/src/test/it-features/it-launcher.json
@@ -0,0 +1,26 @@
+{
+    "bundles": [
+        {
+            "id": 
"org.apache.sling/org.apache.sling.models.validation-impl/${project.version}",
+            "start-order": 20
+        },
+        {
+            "id": 
"org.apache.sling/org.apache.sling.models.validation-impl/${project.version}//it-testbundle",
+            "start-order": 20
+        }
+    ],
+    "configurations": {
+        
"org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~integration-tests":
 {
+            "user.mapping": [
+                "org.apache.sling.junit.core=models-it"
+            ]
+        },
+        
"org.apache.sling.commons.log.LogManager.factory.config~integration-tests": {
+            "org.apache.sling.commons.log.names": [
+                "org.apache.sling.models"
+            ],
+            "org.apache.sling.commons.log.level": "${it.models.log.level}"
+        }
+    },
+    "repoinit:TEXT|true": "@file"
+}
\ No newline at end of file
diff --git 
a/src/test/java/org/apache/sling/junit/teleporter/customizers/SM_TeleporterCustomizer.java
 
b/src/test/java/org/apache/sling/junit/teleporter/customizers/SM_TeleporterCustomizer.java
new file mode 100644
index 0000000..d33d117
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/junit/teleporter/customizers/SM_TeleporterCustomizer.java
@@ -0,0 +1,59 @@
+/*
+ * 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.junit.teleporter.customizers;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.sling.junit.rules.TeleporterRule;
+import org.apache.sling.models.validation.impl.ModelValidationImpl;
+import org.apache.sling.testing.clients.ClientException;
+import org.apache.sling.testing.clients.osgi.OsgiConsoleClient;
+import org.apache.sling.testing.serversetup.instance.SlingTestBase;
+import org.apache.sling.testing.teleporter.client.ClientSideTeleporter;
+import org.apache.sling.testing.timeouts.TimeoutsProvider;
+
+/** This is required by the TeleporterRule, to setup the client-side
+ *  teleporter with (at least) the test server URL.
+ */
+public class SM_TeleporterCustomizer implements TeleporterRule.Customizer {
+
+    private static final SlingTestBase S = new SlingTestBase();
+
+    private static final Class[] EXPECTED_COMPONENTS = new Class[] 
{ModelValidationImpl.class};
+
+    @Override
+    public void customize(TeleporterRule t, String options) {
+        final ClientSideTeleporter cst = (ClientSideTeleporter) t;
+        cst.setBaseUrl(S.getServerBaseUrl());
+        cst.setServerCredentials(S.getServerUsername(), S.getServerPassword());
+        
cst.setTestReadyTimeoutSeconds(TimeoutsProvider.getInstance().getTimeout(5));
+
+        // additionally check for the registration of mandatory sling models 
components
+        try (OsgiConsoleClient osgiClient =
+                new OsgiConsoleClient(URI.create(S.getServerBaseUrl()), 
S.getServerUsername(), S.getServerPassword())) {
+            for (Class clazz : EXPECTED_COMPONENTS) {
+                osgiClient.waitComponentRegistered(clazz.getName(), 20000, 
200);
+            }
+        } catch (ClientException | TimeoutException | InterruptedException | 
IOException ex) {
+            throw new RuntimeException("Error waiting for expected 
components.", ex);
+        }
+    }
+}
diff --git 
a/src/test/java/org/apache/sling/models/validation/impl/it/GenerateTestBundle.java
 
b/src/test/java/org/apache/sling/models/validation/impl/it/GenerateTestBundle.java
new file mode 100644
index 0000000..b2994da
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/models/validation/impl/it/GenerateTestBundle.java
@@ -0,0 +1,109 @@
+/*
+ * 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.models.validation.impl.it;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+
+import org.apache.sling.models.annotations.Model;
+import org.ops4j.pax.tinybundles.TinyBundle;
+import org.ops4j.pax.tinybundles.TinyBundles;
+import org.osgi.framework.Constants;
+
+import io.github.classgraph.ClassGraph;
+import io.github.classgraph.ClassInfo;
+import io.github.classgraph.ScanResult;
+
+/**
+ * This uses tinybundles to create a test bundle that is deployed to sling
+ * starter. The test bundle contains all classes from the packages
+ * org.apache.sling.models.it.testbundle.*
+ */
+public class GenerateTestBundle {
+
+    private static final String DUMMY_TEXT = "Dummy file for Integration Test 
bundle.";
+
+    public static void main(String[] args) throws Exception {
+        Path outputFile = Paths.get(args[0]);
+        try (InputStream bundleStream = 
createBundle().build(TinyBundles.bndBuilder())) {
+            Files.copy(bundleStream, outputFile);
+        }
+        System.out.println("Test bundle created at " + 
outputFile.toAbsolutePath());
+    }
+
+    static TinyBundle createBundle() {
+        TinyBundle bundle = TinyBundles.bundle()
+                .setHeader(Constants.BUNDLE_NAME, "Apache Sling Models 
Validation Implementation - IT Test Bundle")
+                .setHeader(Constants.BUNDLE_VERSION, "1.0.0-SNAPSHOT")
+                .setHeader(Constants.EXPORT_PACKAGE, 
"org.apache.sling.models.validation.impl.it.testbundle.*")
+                // add dummy files to please verify-legal-files check
+                .addResource("META-INF/LICENSE", new 
ByteArrayInputStream(DUMMY_TEXT.getBytes(StandardCharsets.UTF_8)))
+                .addResource("META-INF/NOTICE", new 
ByteArrayInputStream(DUMMY_TEXT.getBytes(StandardCharsets.UTF_8)));
+
+        // add all testbundle classes
+        Set<String> modelClassNames = new TreeSet<>();
+        getAllClasses().forEach(clazz -> {
+            bundle.addClass(clazz);
+            if (clazz.isAnnotationPresent(Model.class)) {
+                modelClassNames.add(clazz.getName());
+            }
+        });
+
+        // register sling models
+        bundle.setHeader("Sling-Model-Classes", 
modelClassNames.stream().collect(Collectors.joining(",")));
+
+        // add all test resources from SLING-CONTENT
+        bundle.setHeader("Sling-Initial-Content", 
"SLING-CONTENT/apps/sling/validation;overwrite:=true;path:=/apps/sling/validation");
+        addTestResources(bundle);
+
+        return bundle;
+    }
+
+    /**
+     * Dynamically find all classes in classpath under package(s) 
org.apache.sling.models.it.testbundle.*
+     */
+    static List<Class<?>> getAllClasses() {
+        try (ScanResult scanResult = new ClassGraph()
+                .enableClassInfo()
+                
.acceptPackages("org.apache.sling.models.validation.impl.it.testbundle")
+                .scan()) {
+            return 
scanResult.getAllClasses().stream().map(ClassInfo::loadClass).collect(Collectors.toList());
+        }
+    }
+
+    /**
+     * Add all test resources from SLING-CONTENT directory to the bundle.
+     */
+    static void addTestResources(TinyBundle bundle) {
+        try (ScanResult scanResult = new ClassGraph()
+                .acceptPaths("SLING-CONTENT")
+                .scan()) {
+            scanResult.getAllResources().forEach(resource -> 
bundle.addResource(resource.getPath(), resource.getURL()));
+        }
+    }
+
+}
diff --git 
a/src/test/java/org/apache/sling/models/validation/impl/it/ModelValidationDisabled.java
 
b/src/test/java/org/apache/sling/models/validation/impl/it/testbundle/models/ModelValidationDisabled.java
similarity index 93%
rename from 
src/test/java/org/apache/sling/models/validation/impl/it/ModelValidationDisabled.java
rename to 
src/test/java/org/apache/sling/models/validation/impl/it/testbundle/models/ModelValidationDisabled.java
index e9a8068..4543300 100644
--- 
a/src/test/java/org/apache/sling/models/validation/impl/it/ModelValidationDisabled.java
+++ 
b/src/test/java/org/apache/sling/models/validation/impl/it/testbundle/models/ModelValidationDisabled.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sling.models.validation.impl.it;
+package org.apache.sling.models.validation.impl.it.testbundle.models;
 
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.models.annotations.Model;
diff --git 
a/src/test/java/org/apache/sling/models/validation/impl/it/ModelValidationOptional.java
 
b/src/test/java/org/apache/sling/models/validation/impl/it/testbundle/models/ModelValidationOptional.java
similarity index 93%
rename from 
src/test/java/org/apache/sling/models/validation/impl/it/ModelValidationOptional.java
rename to 
src/test/java/org/apache/sling/models/validation/impl/it/testbundle/models/ModelValidationOptional.java
index 5ff27db..63d2c7d 100644
--- 
a/src/test/java/org/apache/sling/models/validation/impl/it/ModelValidationOptional.java
+++ 
b/src/test/java/org/apache/sling/models/validation/impl/it/testbundle/models/ModelValidationOptional.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sling.models.validation.impl.it;
+package org.apache.sling.models.validation.impl.it.testbundle.models;
 
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.models.annotations.Model;
diff --git 
a/src/test/java/org/apache/sling/models/validation/impl/it/ModelValidationRequired.java
 
b/src/test/java/org/apache/sling/models/validation/impl/it/testbundle/models/ModelValidationRequired.java
similarity index 93%
rename from 
src/test/java/org/apache/sling/models/validation/impl/it/ModelValidationRequired.java
rename to 
src/test/java/org/apache/sling/models/validation/impl/it/testbundle/models/ModelValidationRequired.java
index 84d2a59..8c9871a 100644
--- 
a/src/test/java/org/apache/sling/models/validation/impl/it/ModelValidationRequired.java
+++ 
b/src/test/java/org/apache/sling/models/validation/impl/it/testbundle/models/ModelValidationRequired.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sling.models.validation.impl.it;
+package org.apache.sling.models.validation.impl.it.testbundle.models;
 
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.models.annotations.Model;
diff --git 
a/src/test/java/org/apache/sling/models/validation/impl/it/ModelValidationIT.java
 
b/src/test/java/org/apache/sling/models/validation/impl/it/testing/ModelValidationIT.java
similarity index 93%
rename from 
src/test/java/org/apache/sling/models/validation/impl/it/ModelValidationIT.java
rename to 
src/test/java/org/apache/sling/models/validation/impl/it/testing/ModelValidationIT.java
index 55f3edc..0644d53 100644
--- 
a/src/test/java/org/apache/sling/models/validation/impl/it/ModelValidationIT.java
+++ 
b/src/test/java/org/apache/sling/models/validation/impl/it/testing/ModelValidationIT.java
@@ -14,9 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sling.models.validation.impl.it;
-
-import java.io.IOException;
+package org.apache.sling.models.validation.impl.it.testing;
 
 import org.apache.sling.api.resource.LoginException;
 import org.apache.sling.api.resource.Resource;
@@ -26,6 +24,9 @@ import org.apache.sling.junit.rules.TeleporterRule;
 import org.apache.sling.models.factory.ModelFactory;
 import org.apache.sling.models.factory.ValidationException;
 import org.apache.sling.models.validation.InvalidResourceException;
+import 
org.apache.sling.models.validation.impl.it.testbundle.models.ModelValidationDisabled;
+import 
org.apache.sling.models.validation.impl.it.testbundle.models.ModelValidationOptional;
+import 
org.apache.sling.models.validation.impl.it.testbundle.models.ModelValidationRequired;
 import org.apache.sling.validation.ValidationService;
 import org.apache.sling.validation.model.ValidationModel;
 import org.junit.After;
@@ -38,7 +39,7 @@ import org.junit.rules.ExpectedException;
 public class ModelValidationIT {
 
     @Rule
-    public final TeleporterRule teleporter = 
TeleporterRule.forClass(getClass()).withResources("/SLING-CONTENT/");
+    public final TeleporterRule teleporter = 
TeleporterRule.forClass(getClass(), "SM_Teleporter");
 
     @Rule
     public ExpectedException expectedEx = ExpectedException.none();
@@ -83,7 +84,7 @@ public class ModelValidationIT {
     }
 
     @Test
-    public void testValidModel() throws IOException {
+    public void testValidModel() {
         // create a valid resource
         Resource contentResource = 
resourceResolver.getResource("/apps/sling/validation/content/contentValid");
         Assert.assertNotNull("Content resource must exist", contentResource);
@@ -93,7 +94,7 @@ public class ModelValidationIT {
     }
 
     @Test
-    public void testInvalidModel() throws IOException {
+    public void testInvalidModel() {
         // create a valid resource
         Resource contentResource = 
resourceResolver.getResource("/apps/sling/validation/content/contentInvalid");
         Assert.assertNotNull("Content resource must exist", contentResource);


Reply via email to