diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml new file mode 100644 index 00000000000..01bff2cd9f1 --- /dev/null +++ b/.github/workflows/integration-test.yml @@ -0,0 +1,28 @@ +name: Integration test + +on: + pull_request: + types: + - labeled + - synchronize +env: + MAVEN_ARGS: "--no-transfer-progress -Dstyle.color=always" + +jobs: + run: + runs-on: ubuntu-latest + if: github.repository_owner == 'opentripplanner' && contains( github.event.pull_request.labels.*.name, 'Integration Test' ) + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: 21 + distribution: temurin + cache: maven + + + - name: Run integration tests + run: mvn test-compile failsafe:integration-test -PprettierSkip \ No newline at end of file diff --git a/pom.xml b/pom.xml index 5ce18e0196f..18427e601da 100644 --- a/pom.xml +++ b/pom.xml @@ -104,6 +104,7 @@ gtfs-realtime-protobuf application otp-shaded + test/integration diff --git a/renovate.json5 b/renovate.json5 index e0bf1c43889..71123c4a4c9 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -46,6 +46,7 @@ "org.mockito:mockito-core", "com.tngtech.archunit:archunit", "org.apache.maven.plugins:maven-surefire-plugin", + "org.apache.maven.plugins:maven-failsafe-plugin ", "me.fabriciorby:maven-surefire-junit5-tree-reporter", "com.google.truth:truth", "org.jacoco:jacoco-maven-plugin", // coverage plugin @@ -163,12 +164,20 @@ "description": "give some projects time to publish a changelog before opening the PR", "matchPackageNames": [ "com.google.dagger:{/,}**", - "org.apache.httpcomponents.client5:httpclient5" ], "matchUpdateTypes": ["major", "minor"], "minimumReleaseAge": "1 week", "schedule": "on the 13th through 14th day of the month" }, + { + "description": "Apache HTTP client", + "matchPackageNames": [ + "org.apache.httpcomponents.client5:httpclient5" + ], + "minimumReleaseAge": "1 week", + "changelogUrl": "https://github.com/apache/httpcomponents-client/blob/master/RELEASE_NOTES.txt", + "addLabels": ["Integration Test"] + }, { "groupName": "Jackson non-patch", "matchPackageNames": [ diff --git a/test/integration/pom.xml b/test/integration/pom.xml new file mode 100644 index 00000000000..2ec845fd6be --- /dev/null +++ b/test/integration/pom.xml @@ -0,0 +1,82 @@ + + + 4.0.0 + + org.opentripplanner + otp-root + 2.8.0-SNAPSHOT + ../../pom.xml + + + integration-test + + + + ${project.groupId} + application + ${project.version} + test + + + org.junit.jupiter + junit-jupiter-api + ${junit.version} + test + + + org.junit.jupiter + junit-jupiter-params + ${junit.version} + test + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + org.apache.maven.plugins + maven-failsafe-plugin + 3.5.3 + + + **/*Test.java + + + true + + plain + + true + true + true + true + false + true + true + false + UNICODE + + + + + me.fabriciorby + maven-surefire-junit5-tree-reporter + 1.4.0 + + + + + + + \ No newline at end of file diff --git a/test/integration/src/test/java/org/opentripplanner/OtpHttpClientTest.java b/test/integration/src/test/java/org/opentripplanner/OtpHttpClientTest.java new file mode 100644 index 00000000000..39bdaf758d6 --- /dev/null +++ b/test/integration/src/test/java/org/opentripplanner/OtpHttpClientTest.java @@ -0,0 +1,44 @@ +package org.opentripplanner; + +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import jakarta.ws.rs.core.UriBuilder; +import java.io.IOException; +import java.time.Duration; +import java.util.Map; +import org.apache.commons.io.IOUtils; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.opentripplanner.framework.io.OtpHttpClient; +import org.opentripplanner.framework.io.OtpHttpClientFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This integration test makes sure that Apache HTTP client still works with important hosts and + * HTTP servers. + */ +class OtpHttpClientTest { + + private static final Logger LOG = LoggerFactory.getLogger(OtpHttpClientTest.class); + private static final OtpHttpClient OTP_HTTP_CLIENT = new OtpHttpClientFactory().create(LOG); + + @ParameterizedTest + @ValueSource( + strings = { + // a few entur URLs + "https://api.entur.io/mobility/v2/gbfs/", + "https://storage.googleapis.com/marduk-production/outbound/gtfs/rb_sjn-aggregated-gtfs.zip", + // Apache HTTP Client broke handling of S3 SSL certificates previously + "https://s3.amazonaws.com/kcm-alerts-realtime-prod/tripupdates.pb", + } + ) + void httpGetRequest(String url) throws IOException { + var uri = UriBuilder.fromUri(url).build(); + + var stream = OTP_HTTP_CLIENT.getAsInputStream(uri, Duration.ofSeconds(30), Map.of()); + var bytes = IOUtils.toByteArray(stream); + + assertNotEquals(0, bytes.length, "Empty response body for %s".formatted(url)); + } +}