From 74dc39a46f105a3181a849d6962c0216c8a0f5c8 Mon Sep 17 00:00:00 2001 From: Jose Date: Wed, 28 Apr 2021 14:52:18 +0200 Subject: [PATCH] Configure Github CI to run tests on Windows Changes: - Windows fails to stop an application when running on DEV mode. Reported issue: https://github.com/quarkusio/quarkus/issues/14647 - Windows disallows to delete folders when they are being used by the file explorer or the processes are about to be exited. This is why: 1. I'm ignoring these errors when the directory can't be deleted (it's not Quarkus issue) 2. I splitted the "s p a c e s" runs into there different folders for jvm, native and dev mode. --- .github/workflows/ci.yaml | 96 ++++++++++++++++++- app-full-microprofile/threshold.properties | 6 +- app-jax-rs-minimal/threshold.properties | 6 +- .../ts/startstop/SpecialCharsTest.java | 33 ++++--- .../ts/startstop/utils/LogBuilder.java | 7 ++ .../io/quarkus/ts/startstop/utils/Logs.java | 13 +++ .../ts/startstop/utils/WhitelistLogLines.java | 42 +++++++- 7 files changed, 180 insertions(+), 23 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c63f75ed..0982bb8a 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -4,8 +4,8 @@ on: schedule: - cron: '0 23 * * *' jobs: - build-released-jvm: - name: JVM build - released Quarkus + linux-build-released-jvm: + name: Linux - JVM build - released Quarkus runs-on: ubuntu-latest strategy: matrix: @@ -35,8 +35,8 @@ jobs: with: name: ci-artifacts path: artifacts-jvm${{ matrix.java }}.zip - build-released-native: - name: Native build - released Quarkus + linux-build-released-native: + name: Linux - Native build - released Quarkus runs-on: ubuntu-latest strategy: matrix: @@ -96,4 +96,90 @@ jobs: if: failure() with: name: ci-artifacts - path: artifacts-code-start${{ matrix.java }}.zip \ No newline at end of file + path: artifacts-code-start${{ matrix.java }}.zip + windows-build-released-jvm: + name: Windows - JVM build - released Quarkus + runs-on: windows-latest + strategy: + matrix: + java: [ 11 ] + steps: + - uses: actions/checkout@v1 + - uses: actions/cache@v1 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + - name: Install JDK {{ matrix.java }} + uses: joschi/setup-jdk@e87a7cec853d2dd7066adf837fe12bf0f3d45e52 + with: + java-version: ${{ matrix.java }} + - name: Build with Maven + shell: bash + run: | + mvn -V -B -s .github/mvn-settings.xml clean verify -DexcludeTags='product,native,codequarkus' + - name: Zip Artifacts + if: failure() + shell: bash + run: | + # Disambiguate windows find from cygwin find + /usr/bin/find . -name '*-reports' -o -name 'archived-logs' -type d | tar -czf artifacts-windows-jvm${{ matrix.java }}.tar -T - + - name: Archive artifacts + uses: actions/upload-artifact@v1 + if: failure() + with: + name: ci-artifacts + path: artifacts-windows-jvm${{ matrix.java }}.tar + windows-build-released-native: + name: Windows - Native build - released Quarkus + runs-on: windows-latest + strategy: + matrix: + java: [ 11 ] + # Version 21.1 is not working due to https://github.com/quarkusio/quarkus/issues/14904 + graalvm-version: [ "21.0.0.2.java11" ] + steps: + - uses: actions/checkout@v1 + - uses: actions/cache@v1 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + - name: Install JDK {{ matrix.java }} + uses: joschi/setup-jdk@e87a7cec853d2dd7066adf837fe12bf0f3d45e52 + with: + java-version: ${{ matrix.java }} + - name: Install cl.exe + uses: ilammy/msvc-dev-cmd@v1 + - uses: microsoft/setup-msbuild@v1 + - name: Setup GraalVM + id: setup-graalvm + uses: DeLaGuardo/setup-graalvm@master + with: + graalvm-version: ${{ matrix.graalvm-version }} + java: java${{ matrix.graalvm-version }} + - name: Install native-image component + run: | + gu.cmd install native-image + - name: Configure Pagefile + # Increased the page-file size due to memory-consumption of native-image command + # For details see https://github.com/actions/virtual-environments/issues/785 + uses: al-cheb/configure-pagefile-action@v1.2 + - name: Build with Maven + run: | + mvn -V -B -s .github/mvn-settings.xml clean verify -DexcludeTags="product,codequarkus" -Dquarkus.native.native-image-xmx=6g + shell: cmd + - name: Zip Artifacts + if: failure() + shell: bash + run: | + # Disambiguate windows find from cygwin find + /usr/bin/find . -name '*-reports' -o -name 'archived-logs' -type d | tar -czf artifacts-windows-native${{ matrix.java }}.tar -T - + - name: Archive artifacts + uses: actions/upload-artifact@v1 + if: failure() + with: + name: ci-artifacts + path: artifacts-windows-native${{ matrix.java }}.tar diff --git a/app-full-microprofile/threshold.properties b/app-full-microprofile/threshold.properties index b182ddea..790e2c74 100644 --- a/app-full-microprofile/threshold.properties +++ b/app-full-microprofile/threshold.properties @@ -2,5 +2,7 @@ linux.jvm.time.to.first.ok.request.threshold.ms=2600 linux.jvm.RSS.threshold.kB=550000 linux.native.time.to.first.ok.request.threshold.ms=60 linux.native.RSS.threshold.kB=120000 -windows.jvm.time.to.first.ok.request.threshold.ms=2500 -windows.jvm.RSS.threshold.kB=4000 +windows.jvm.time.to.first.ok.request.threshold.ms=4500 +windows.jvm.RSS.threshold.kB=4600 +windows.native.time.to.first.ok.request.threshold.ms=1600 +windows.native.RSS.threshold.kB=120000 diff --git a/app-jax-rs-minimal/threshold.properties b/app-jax-rs-minimal/threshold.properties index 39433037..976f20b8 100644 --- a/app-jax-rs-minimal/threshold.properties +++ b/app-jax-rs-minimal/threshold.properties @@ -2,5 +2,7 @@ linux.jvm.time.to.first.ok.request.threshold.ms=2000 linux.jvm.RSS.threshold.kB=380000 linux.native.time.to.first.ok.request.threshold.ms=35 linux.native.RSS.threshold.kB=90000 -windows.jvm.time.to.first.ok.request.threshold.ms=2000 -windows.jvm.RSS.threshold.kB=4000 +windows.jvm.time.to.first.ok.request.threshold.ms=4500 +windows.jvm.RSS.threshold.kB=4500 +windows.native.time.to.first.ok.request.threshold.ms=800 +windows.native.RSS.threshold.kB=90000 diff --git a/testsuite/src/it/java/io/quarkus/ts/startstop/SpecialCharsTest.java b/testsuite/src/it/java/io/quarkus/ts/startstop/SpecialCharsTest.java index b17ab643..a2d1c931 100644 --- a/testsuite/src/it/java/io/quarkus/ts/startstop/SpecialCharsTest.java +++ b/testsuite/src/it/java/io/quarkus/ts/startstop/SpecialCharsTest.java @@ -68,10 +68,7 @@ public void testRuntime(TestInfo testInfo, Apps app, MvnCmds mvnCmds, String sub // Clean target directory cleanTarget(app); - // Delete dir with special chars - if (appDestDir.exists()) { - FileUtils.deleteDirectory(appDestDir); - } + removeDirWithSpecialCharacters(appDestDir); // Make dir with special chars if (!appDestDir.mkdir()) { @@ -155,28 +152,24 @@ public void testRuntime(TestInfo testInfo, Apps app, MvnCmds mvnCmds, String sub } writeReport(cn, mn, whatIDidReport.toString()); - // Remove dir with special chars - if (appDestDir.exists()) { - FileUtils.deleteDirectory(appDestDir); - } + removeDirWithSpecialCharacters(appDestDir); } } - @Test public void spacesJVM(TestInfo testInfo) throws IOException, InterruptedException { - testRuntime(testInfo, Apps.JAX_RS_MINIMAL, MvnCmds.JVM, "s p a c e s"); + testRuntime(testInfo, Apps.JAX_RS_MINIMAL, MvnCmds.JVM, "s p a c e s j v m"); } @Test public void spacesDEV(TestInfo testInfo) throws IOException, InterruptedException { - testRuntime(testInfo, Apps.JAX_RS_MINIMAL, MvnCmds.DEV, "s p a c e s"); + testRuntime(testInfo, Apps.JAX_RS_MINIMAL, MvnCmds.DEV, "s p a c e s d e v"); } @Test @Tag("native") public void spacesNative(TestInfo testInfo) throws IOException, InterruptedException { - testRuntime(testInfo, Apps.JAX_RS_MINIMAL, MvnCmds.NATIVE, "s p a c e s"); + testRuntime(testInfo, Apps.JAX_RS_MINIMAL, MvnCmds.NATIVE, "s p a c e s n a t i v e"); } @Test @@ -193,6 +186,7 @@ public void specialDEV(TestInfo testInfo) throws IOException, InterruptedExcepti @Test @Tag("native") + @DisabledOnOs({OS.WINDOWS}) // https://github.com/quarkusio/quarkus/issues/9707 public void specialNative(TestInfo testInfo) throws IOException, InterruptedException { testRuntime(testInfo, Apps.JAX_RS_MINIMAL, MvnCmds.NATIVE, ",;~!@#$%^&()"); } @@ -203,12 +197,14 @@ public void diacriticsJVM(TestInfo testInfo) throws IOException, InterruptedExce } @Test + @DisabledOnOs({OS.WINDOWS}) // https://github.com/quarkusio/quarkus/issues/9707 public void diacriticsDEV(TestInfo testInfo) throws IOException, InterruptedException { testRuntime(testInfo, Apps.JAX_RS_MINIMAL, MvnCmds.DEV, "ěščřžýáíéůú"); } @Test @Tag("native") + @DisabledOnOs({OS.WINDOWS}) // https://github.com/quarkusio/quarkus/issues/9707 public void diacriticsNative(TestInfo testInfo) throws IOException, InterruptedException { testRuntime(testInfo, Apps.JAX_RS_MINIMAL, MvnCmds.NATIVE, "ěščřžýáíéůú"); } @@ -226,6 +222,7 @@ public void japaneseDEV(TestInfo testInfo) throws IOException, InterruptedExcept @Test @Tag("native") + @DisabledOnOs({OS.WINDOWS}) // https://github.com/quarkusio/quarkus/issues/9707 public void japaneseNative(TestInfo testInfo) throws IOException, InterruptedException { testRuntime(testInfo, Apps.JAX_RS_MINIMAL, MvnCmds.NATIVE, "元気かい"); } @@ -243,8 +240,20 @@ public void otherDEV(TestInfo testInfo) throws IOException, InterruptedException @Test @Tag("native") + @DisabledOnOs({OS.WINDOWS}) // https://github.com/quarkusio/quarkus/issues/9707 public void otherNative(TestInfo testInfo) throws IOException, InterruptedException { testRuntime(testInfo, Apps.JAX_RS_MINIMAL, MvnCmds.NATIVE, "Îñţérñåţîöñåļîžåţîờñ"); } + private void removeDirWithSpecialCharacters(File appDestDir) { + // Remove dir with special chars + try { + if (appDestDir.exists()) { + FileUtils.deleteDirectory(appDestDir); + } + } catch (IOException ignored) { + // ignored when the folder could not be deleted. + } + } + } diff --git a/testsuite/src/it/java/io/quarkus/ts/startstop/utils/LogBuilder.java b/testsuite/src/it/java/io/quarkus/ts/startstop/utils/LogBuilder.java index a59ca88f..a89f7178 100644 --- a/testsuite/src/it/java/io/quarkus/ts/startstop/utils/LogBuilder.java +++ b/testsuite/src/it/java/io/quarkus/ts/startstop/utils/LogBuilder.java @@ -92,6 +92,13 @@ public LogBuilder startedInMs(long startedInMs) { } public LogBuilder stoppedInMs(long stoppedInMs) { + // Quarkus is not being gratefully shutdown in Windows when running in Dev mode. + // Reported by https://github.com/quarkusio/quarkus/issues/14647. + if (stoppedInMs <= 0 && Commands.isThisWindows) { + // do nothing in Windows + return this; + } + if (stoppedInMs <= 0) { throw new IllegalArgumentException("stoppedInMs must be a positive long, was: " + stoppedInMs); } diff --git a/testsuite/src/it/java/io/quarkus/ts/startstop/utils/Logs.java b/testsuite/src/it/java/io/quarkus/ts/startstop/utils/Logs.java index cb22175f..9acfcbc2 100644 --- a/testsuite/src/it/java/io/quarkus/ts/startstop/utils/Logs.java +++ b/testsuite/src/it/java/io/quarkus/ts/startstop/utils/Logs.java @@ -38,6 +38,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; +import java.util.stream.Stream; import static io.quarkus.ts.startstop.StartStopTest.BASE_DIR; import static io.quarkus.ts.startstop.utils.Commands.isThisWindows; @@ -72,6 +73,7 @@ public class Logs { private static final Pattern stoppedPatternControlSymbols = Pattern.compile(".* stopped in .*188m([0-9\\.]+).*", Pattern.DOTALL); private static final Pattern warnErrorDetectionPattern = Pattern.compile("(?i:.*(ERROR|WARN|SLF4J:).*)"); + private static final Pattern devModeError = Pattern.compile(".*Failed to run: Dev mode process did not complete successfully.*"); private static final Pattern listeningOnDetectionPattern = Pattern.compile("(?i:.*Listening on:.*)"); private static final Pattern devExpectedHostPattern = Pattern.compile("(?i:.*localhost:.*)"); private static final Pattern defaultExpectedHostPattern = Pattern.compile("(?i:.*0.0.0.0:.*)"); @@ -94,6 +96,13 @@ public static void checkLog(String testClass, String testMethod, Apps app, MvnCm } } } + + // Randomly fails when vertx-cache temporary directory exists. Related to https://github.com/quarkusio/quarkus/issues/7678 + // And https://github.com/quarkusio/quarkus/pull/15541/files#diff-a38e0d86cf6a637c19b6e0a0e23959f644886bdcc0f0e5615ce7cfa0e6bc9909R244 + if (Commands.isThisWindows && isDevModeError(offendingLines)) { + Stream.of(WhitelistLogLines.WINDOWS_DEV_MODE_ERRORS.errs).forEach(lineToIgnore -> offendingLines.removeIf(line -> lineToIgnore.matcher(line).matches())); + } + assertTrue(offendingLines.isEmpty(), cmd.name() + " log should not contain error or warning lines that are not whitelisted. " + "See testsuite" + File.separator + "target" + File.separator + "archived-logs" + @@ -125,6 +134,10 @@ public static void checkListeningHost(String testClass, String testMethod, MvnCm " and check the listening host."); } + private static boolean isDevModeError(Set offendingLines) { + return offendingLines.stream().anyMatch(line -> devModeError.matcher(line).matches()); + } + private static boolean isWhiteListed(Pattern[] patterns, String line) { for (Pattern p : patterns) { if (p.matcher(line).matches()) { diff --git a/testsuite/src/it/java/io/quarkus/ts/startstop/utils/WhitelistLogLines.java b/testsuite/src/it/java/io/quarkus/ts/startstop/utils/WhitelistLogLines.java index c3571783..624dfc4d 100755 --- a/testsuite/src/it/java/io/quarkus/ts/startstop/utils/WhitelistLogLines.java +++ b/testsuite/src/it/java/io/quarkus/ts/startstop/utils/WhitelistLogLines.java @@ -77,7 +77,27 @@ public enum WhitelistLogLines { // (no explicit configuration, none or multiple JDBC driver extensions) // Result of DevServices support https://github.com/quarkusio/quarkus/pull/14960 Pattern.compile(".*Unable to determine a database type for default datasource.*"), + }), + // Quarkus is not being gratefully shutdown in Windows when running in Dev mode. + // Reported by https://github.com/quarkusio/quarkus/issues/14647. + WINDOWS_DEV_MODE_ERRORS(new Pattern[]{ + Pattern.compile(".*Re-run Maven using the -X switch to enable full debug logging.*"), + Pattern.compile(".*For more information about the errors and possible solutions, please read the following articles.*"), + Pattern.compile(".*Failed to run: Dev mode process did not complete successfully.*"), + Pattern.compile(".*http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException.*"), + Pattern.compile(".*To see the full stack trace of the errors, re-run Maven with the -e switch.*"), + Pattern.compile("\\[ERROR\\] *"), }); + + // Randomly fails when vertx-cache temporary directory exists. Related to https://github.com/quarkusio/quarkus/issues/7678 + // And https://github.com/quarkusio/quarkus/pull/15541/files#diff-a38e0d86cf6a637c19b6e0a0e23959f644886bdcc0f0e5615ce7cfa0e6bc9909R244 + private static final Pattern COMMON_WARNING_VERTX_CACHE_DIRECTORY = Pattern.compile(".*Unable to make the Vert.x cache directory.*"); + // Depending to the OS and also on the Quarkus extensions, the Native build might print some warnings about duplicate entries + private static final Pattern COMMON_WARNING_DUPLICATE_ENTRY_NATIVE = Pattern.compile(".*Duplicate entry about.html entry.*"); + private static final Pattern COMMON_WARNING_DUPLICATE_ENTRIES_NATIVE = Pattern.compile(".*Dependencies with duplicate files detected.*"); + // When + private static final Pattern WARNING_MISSING_OBJCOPY_NATIVE = Pattern.compile(".*objcopy executable not found in PATH. Debug symbols will not be separated from executable.*"); + private static final Pattern WARNING_MISSING_OBJCOPY_RESULT_NATIVE = Pattern.compile(".*That will result in a larger native image with debug symbols embedded in it.*"); public final Pattern[] errs; @@ -89,8 +109,26 @@ public final Pattern[] platformErrs() { switch (OS.current()) { case MAC: return new Pattern[] { - Pattern.compile(".*objcopy executable not found in PATH. Debug symbols will not be separated from executable.*"), - Pattern.compile(".*That will result in a larger native image with debug symbols embedded in it.*"), + COMMON_WARNING_VERTX_CACHE_DIRECTORY, + COMMON_WARNING_DUPLICATE_ENTRY_NATIVE, + COMMON_WARNING_DUPLICATE_ENTRIES_NATIVE, + WARNING_MISSING_OBJCOPY_NATIVE, + WARNING_MISSING_OBJCOPY_RESULT_NATIVE, + }; + case WINDOWS: + return new Pattern[] { + COMMON_WARNING_VERTX_CACHE_DIRECTORY, + COMMON_WARNING_DUPLICATE_ENTRY_NATIVE, + COMMON_WARNING_DUPLICATE_ENTRIES_NATIVE, + WARNING_MISSING_OBJCOPY_NATIVE, + WARNING_MISSING_OBJCOPY_RESULT_NATIVE, + Pattern.compile(".*Uber JAR strategy is used for native image source JAR generation on Windows.*"), + }; + case LINUX: + return new Pattern[] { + COMMON_WARNING_VERTX_CACHE_DIRECTORY, + COMMON_WARNING_DUPLICATE_ENTRY_NATIVE, + COMMON_WARNING_DUPLICATE_ENTRIES_NATIVE, }; } return new Pattern[] {};