diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 3735e92..3d9483a 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,6 +1,17 @@
name: Build
-on: [push, pull_request]
+on:
+ # Trigger on push to develop or main branches
+ push:
+ branches:
+ - develop
+ - main
+
+ # Trigger on pull request (any branch that creates a PR)
+ pull_request:
+ branches:
+ - develop
+ - main
jobs:
build:
@@ -26,3 +37,14 @@ jobs:
- name: Build
run: mvn --batch-mode --update-snapshots install
+
+ - name: Integration tests
+ run: mvn --batch-mode clean verify -pl it.tests -Pit
+
+ # Save logs only if the job fails
+ - name: Upload logs on failure
+ if: failure()
+ uses: actions/upload-artifact@v3
+ with:
+ name: failure-logs
+ path: it.tests/target/launchers/model/logs/*
diff --git a/bundle/pom.xml b/bundle/pom.xml
index d249c95..ae9ab31 100644
--- a/bundle/pom.xml
+++ b/bundle/pom.xml
@@ -31,7 +31,7 @@
diff --git a/it.tests/pom.xml b/it.tests/pom.xml
new file mode 100644
index 0000000..405a245
--- /dev/null
+++ b/it.tests/pom.xml
@@ -0,0 +1,195 @@
+
+
+
+ 4.0.0
+
+
+ be.orbinson.aem
+ aem-groovy-console
+ 19.0.9-SNAPSHOT
+
+
+ aem-groovy-console-it-tests
+ AEM Groovy Console - IT Tests
+
+
+
+
+ apache-snapshot
+ https://repository.apache.org/content/groups/snapshots
+
+
+
+
+
+
+ biz.aQute.bnd
+ bnd-maven-plugin
+
+
+ bnd-process
+
+ bnd-process
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+
+
+
+
+ it
+
+
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+ 3.2.0
+
+
+ reserve-network-port
+
+ reserve-network-port
+
+ process-resources
+
+
+ http.port
+
+
+
+
+
+
+ org.apache.sling
+ slingfeature-maven-plugin
+ 1.8.4
+ true
+
+
+ aggregate-features
+
+ aggregate-features
+
+
+
+
+
+ org.apache.sling
+ org.apache.sling.starter
+ oak_tar
+ slingosgifeature
+ 13-SNAPSHOT
+
+ *.json
+
+
+ groovy.version
+
+
+
+
+ attach-features
+
+ attach-features
+
+
+
+
+ org.apache.sling
+ feature-launcher-maven-plugin
+ 0.1.6
+
+
+
+ model
+ ${skipTests}
+
+ ${project.groupId}
+ ${project.artifactId}
+ ${project.version}
+ slingosgifeature
+
+
+
+
+ ${http.port}
+
+
+
+
+
+
+ 180
+
+
+
+
+
+
+ start
+ stop
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+ 3.3.1
+
+
+ ${http.port}
+ ${project.build.directory}/../build.log
+
+
+
+
+
+ integration-test
+ verify
+
+
+
+
+
+
+
+
+
+
+
+
+ org.junit.jupiter
+ junit-jupiter
+ 5.10.2
+ test
+
+
+ org.awaitility
+ awaitility
+ 4.2.2
+ test
+
+
+ org.apache.httpcomponents
+ httpclient
+ 4.5.14
+ test
+
+
+ com.google.code.gson
+ gson
+ 2.11.0
+ test
+
+
+
diff --git a/it.tests/src/main/features/groovy.json b/it.tests/src/main/features/groovy.json
new file mode 100644
index 0000000..6ee2427
--- /dev/null
+++ b/it.tests/src/main/features/groovy.json
@@ -0,0 +1,8 @@
+{
+ "bundles": [
+ {
+ "id": "org.apache.groovy:groovy-dateutil:${groovy.version}",
+ "start-order": "20"
+ }
+ ]
+}
diff --git a/it.tests/src/main/features/groovyconsole-repoinit.txt b/it.tests/src/main/features/groovyconsole-repoinit.txt
new file mode 100644
index 0000000..c9ad0a2
--- /dev/null
+++ b/it.tests/src/main/features/groovyconsole-repoinit.txt
@@ -0,0 +1,8 @@
+create path /conf/groovyconsole/replication(sling:Folder)
+create path /var/groovyconsole/audit(sling:Folder)
+
+create service user aem-groovy-console-service with path system/aem-groovy-console
+set ACL for aem-groovy-console-service
+ allow jcr:all on /
+ allow jcr:all on /var/groovyconsole/audit
+end
\ No newline at end of file
diff --git a/it.tests/src/main/features/groovyconsole.json b/it.tests/src/main/features/groovyconsole.json
new file mode 100644
index 0000000..5a9043b
--- /dev/null
+++ b/it.tests/src/main/features/groovyconsole.json
@@ -0,0 +1,25 @@
+
+{
+ "bundles":[
+ {
+ "id": "be.orbinson.aem:groovy-osgi:${project.version}",
+ "start-order": "19"
+ },
+ {
+ "id":"be.orbinson.aem:aem-groovy-console-api:${project.version}",
+ "start-order":"20"
+ },
+ {
+ "id":"be.orbinson.aem:aem-groovy-console-bundle:${project.version}",
+ "start-order":"20"
+ }
+ ],
+ "configurations": {
+ "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~groovyconsole":{
+ "user.mapping":[
+ "aem-groovy-console-bundle=[aem-groovy-console-service]"
+ ]
+ }
+ },
+ "repoinit:TEXT|true":"@file"
+}
\ No newline at end of file
diff --git a/it.tests/src/test/java/be/orbinson/aem/groovy/console/it/GroovyConsoleServiceIT.java b/it.tests/src/test/java/be/orbinson/aem/groovy/console/it/GroovyConsoleServiceIT.java
new file mode 100644
index 0000000..aca5d2e
--- /dev/null
+++ b/it.tests/src/test/java/be/orbinson/aem/groovy/console/it/GroovyConsoleServiceIT.java
@@ -0,0 +1,92 @@
+package be.orbinson.aem.groovy.console.it;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.google.gson.JsonSyntaxException;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.time.Instant;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import static org.awaitility.Awaitility.await;
+import static org.junit.jupiter.api.Assertions.*;
+
+class GroovyConsoleServiceIT {
+
+ private static final int SLING_PORT = Integer.getInteger("HTTP_PORT", 8080);
+
+ @BeforeEach
+ void beforeEach() {
+ await().atMost(30, TimeUnit.SECONDS) // Set maximum wait time to 30 seconds
+ .pollInterval(5, TimeUnit.SECONDS)
+ .untilAsserted(() -> assertTrue(servicesAreAvailable()));
+ }
+
+ @Test
+ void testScriptReturnsResult() throws Exception {
+ String script = "print 'test'";
+ JsonObject response = executeScript(script);
+ System.out.println("Got response script at " + Instant.now());
+
+ assertNotNull(response, "Could not get response from API");
+ assertEquals("test", response.get("output").getAsString());
+ }
+
+ private static boolean servicesAreAvailable() throws IOException {
+ System.out.println("Checking if services are available");
+ try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
+ HttpGet printHealth = new HttpGet("http://localhost:" + SLING_PORT + "/system/health.json?tags=systemalive,bundles");
+ printHealth.addHeader("Authorization", "Basic " + Base64.encodeBase64String("admin:admin".getBytes(StandardCharsets.UTF_8)));
+ try (CloseableHttpResponse response = httpclient.execute(printHealth)) {
+ String body = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
+ JsonObject jsonResponse = JsonParser.parseString(body).getAsJsonObject();
+ try {
+ boolean systemAlive = "OK".equals(jsonResponse.get("overallResult").getAsString());
+ if (!systemAlive) {
+ System.out.println("Not alive yet:");
+ System.out.println(body);
+ }
+ return systemAlive;
+ } catch (JsonSyntaxException e) {
+ return false;
+ }
+ }
+ }
+ }
+
+
+ private static JsonObject executeScript(String script) throws IOException {
+ try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
+ HttpPost executeScript = new HttpPost("http://localhost:" + SLING_PORT + "/bin/groovyconsole/post");
+ List basicNameValuePairs = new java.util.ArrayList<>();
+ basicNameValuePairs.add(new BasicNameValuePair("script", script));
+ executeScript.setEntity(new UrlEncodedFormEntity(basicNameValuePairs, StandardCharsets.UTF_8));
+ executeScript.addHeader("Authorization", "Basic " + Base64.encodeBase64String("admin:admin".getBytes(StandardCharsets.UTF_8)));
+
+ try (CloseableHttpResponse response = httpclient.execute(executeScript)) {
+ System.out.println(response.getStatusLine());
+
+ String body = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
+ try {
+ return JsonParser.parseString(body).getAsJsonObject();
+ } catch (JsonSyntaxException e) {
+ System.out.println("Could not parse body from JSON: " + e.getMessage());
+ return null;
+ }
+ }
+ }
+ }
+}
diff --git a/pom.xml b/pom.xml
index 8667aff..099a43f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,6 +26,7 @@
ui.apps.aem
ui.config
ui.content
+ it.tests
https://github.com/orbinson/aem-groovy-console