From 1bd55f490d085f8951bd95aac1cbe9f5a8fe3228 Mon Sep 17 00:00:00 2001 From: Chapman Flack Date: Sat, 29 Aug 2020 16:53:07 -0400 Subject: [PATCH 01/13] Create two GitHub Actions workflows One to build with varying OS and JDK but the version of PostgreSQL preinstalled in the runner environment, and one that also builds PostgreSQL from source (or will, when completed). --- .github/workflows/ci-runnerpg.yml | 43 +++++++++++++++++++++++++++++++ .github/workflows/ci-sourcepg.yml | 41 +++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 .github/workflows/ci-runnerpg.yml create mode 100644 .github/workflows/ci-sourcepg.yml diff --git a/.github/workflows/ci-runnerpg.yml b/.github/workflows/ci-runnerpg.yml new file mode 100644 index 000000000..d7391d750 --- /dev/null +++ b/.github/workflows/ci-runnerpg.yml @@ -0,0 +1,43 @@ +# This workflow will build and test PL/Java against the version of PostgreSQL +# preinstalled in the GitHub Actions runner environment. + +name: PL/Java CI with PostgreSQL version supplied by the runner + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + if: true + + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest] + java: [9] # , 11, 12, 14, 15-ea] + + steps: + - name: Check out PL/Java + uses: actions/checkout@v2 + with: + path: pljava + - name: Set up JDK + uses: actions/setup-java@v1 + with: + java-version: ${{ matrix.java }} + - name: Report Java, Maven, and PostgreSQL versions + run: | + java -version + mvn --version + pg_config + ls $(pg_config --includedir-server) + - name: Build PL/Java + if: false + working-directory: pljava + run: | + mvn clean install --batch-mode \ + -Dnar.cores=1 -Pwnosign -Psaxon-examples -Ppgjdbc-ng \ + -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn diff --git a/.github/workflows/ci-sourcepg.yml b/.github/workflows/ci-sourcepg.yml new file mode 100644 index 000000000..0b35f3423 --- /dev/null +++ b/.github/workflows/ci-sourcepg.yml @@ -0,0 +1,41 @@ +# This workflow will build and test PL/Java against versions of PostgreSQL +# built from source. + +name: PL/Java CI with PostgreSQL versions built from source + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + if: false + + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + java: [9, 11, 12, 14, 15-ea] + pgsql: [REL_12_4, REL_11_9, REL_10_14, REL9_6_19, REL9_5_23] + + steps: + - name: Check out PL/Java + uses: actions/checkout@v2 + with: + path: pljava + - name: Check out PostgreSQL + uses: actions/checkout@v2 + with: + path: postgresql + repository: postgres/postgres + ref: ${{ matrix.pgsql }} + - name: Set up JDK + uses: actions/setup-java@v1 + with: + java-version: ${{ matrix.java }} + - name: Report Java and Maven versions + run: | + java -version + mvn --version From d90688aae994fb5c14154163406dfa2083f3ebee Mon Sep 17 00:00:00 2001 From: Chapman Flack Date: Sat, 29 Aug 2020 20:41:45 -0400 Subject: [PATCH 02/13] Get -dev on Linux runner. MacOS has it already. --- .github/workflows/ci-runnerpg.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-runnerpg.yml b/.github/workflows/ci-runnerpg.yml index d7391d750..0871dc3c0 100644 --- a/.github/workflows/ci-runnerpg.yml +++ b/.github/workflows/ci-runnerpg.yml @@ -33,7 +33,9 @@ jobs: java -version mvn --version pg_config - ls $(pg_config --includedir-server) + - name: Obtain PG development files (Ubuntu, PGDG) + if: ${{ 'Linux' == runner.os }} + run: sudo apt-get install postgresql-server-dev-12 libkrb5-dev - name: Build PL/Java if: false working-directory: pljava From 29cbff063770134ea9313c69345fb11f0f2cd565 Mon Sep 17 00:00:00 2001 From: Chapman Flack Date: Mon, 31 Aug 2020 19:35:52 -0400 Subject: [PATCH 03/13] Add the install-and-test step --- .github/workflows/ci-runnerpg.yml | 168 +++++++++++++++++++++++++++++- 1 file changed, 166 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-runnerpg.yml b/.github/workflows/ci-runnerpg.yml index 0871dc3c0..8811a2906 100644 --- a/.github/workflows/ci-runnerpg.yml +++ b/.github/workflows/ci-runnerpg.yml @@ -20,26 +20,190 @@ jobs: java: [9] # , 11, 12, 14, 15-ea] steps: + - name: Check out PL/Java uses: actions/checkout@v2 with: path: pljava + - name: Set up JDK uses: actions/setup-java@v1 with: java-version: ${{ matrix.java }} + - name: Report Java, Maven, and PostgreSQL versions run: | java -version mvn --version pg_config + - name: Obtain PG development files (Ubuntu, PGDG) if: ${{ 'Linux' == runner.os }} run: sudo apt-get install postgresql-server-dev-12 libkrb5-dev + - name: Build PL/Java - if: false working-directory: pljava run: | mvn clean install --batch-mode \ - -Dnar.cores=1 -Pwnosign -Psaxon-examples -Ppgjdbc-ng \ + -Psaxon-examples -Ppgjdbc-ng \ -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + + - name: Install and test PL/Java + working-directory: pljava + run: | + packageJar=$(find pljava-packaging -name pljava-pg*.jar -print) + + mavenRepo="$HOME/.m2/repository" + + saxonVer=$( + find "$mavenRepo/net/sf/saxon/Saxon-HE" \ + -name 'Saxon-HE-*.jar' -print | + sort | + tail -n 1 + ) + saxonVer=${saxonVer%/*} + saxonVer=${saxonVer##*/} + + jdbcJar=$( + find "$mavenRepo/com/impossibl/pgjdbc-ng/pgjdbc-ng-all" \ + -name 'pgjdbc-ng-all-*.jar' -print | + sort | + tail -n 1 + ) + + sudo java -Dpgconfig="$pgConfig" -jar "$packageJar" + + jshell \ + -execution local \ + "-J--class-path=$packageJar:$jdbcJar" \ + "--class-path=$packageJar" \ + "-J--add-modules=java.sql,java.sql.rowset" \ + "-J-Dpgconfig=$pgConfig" \ + "-J-Dcom.impossibl.shadow.io.netty.noUnsafe=true" \ + "-J-DmavenRepo=$mavenRepo" \ + "-J-DsaxonVer=$saxonVer" - <<\ENDJSHELL + + boolean succeeding = false; // begin pessimistic + + import static java.nio.file.Paths.get + import java.sql.Connection + import org.postgresql.pljava.packaging.Node + import static org.postgresql.pljava.packaging.Node.q + import static org.postgresql.pljava.packaging.Node.dfa + import static org.postgresql.pljava.packaging.Node.isVoidResultSet + + Path javaLibDir = get(System.getProperty("java.home"), "lib") + + Path libjvm = ( + "Mac OS X".equals(System.getProperty("os.name")) + ? Stream.of("libjli.dylib", "jli/libjli.dylib") + .map(s -> javaLibDir.resolve(s)) + .filter(Files::exists).findFirst().get() + : javaLibDir.resolve("server/libjvm.so") + ); + + String vmopts = "-enableassertions:org.postgresql.pljava... -Xcheck:jni" + + Node n1 = Node.get_new_node("TestNode1") + + /* + * Keep a tally of the three types of diagnostic notices that may be + * received, and, independently, how many represent no-good test results + * (error always, but also warning if seen from the tests in the + * examples.jar deployment descriptor). + */ + Map results = + Stream.of("info", "warning", "error", "ng").collect( + LinkedHashMap::new, + (m,k) -> m.put(k, 0), (r,s) -> {}) + + boolean isDiagnostic(Object o, Set whatIsNG) + { + if ( ! ( o instanceof Throwable ) ) + return false; + String[] parts = Node.classify((Throwable)o); + String type = parts[0]; + results.compute(type, (k,v) -> 1 + v); + if ( whatIsNG.contains(type) ) + results.compute("ng", (k,v) -> 1 + v); + return true; + } + + try ( + AutoCloseable t1 = n1.initialized_cluster(); + AutoCloseable t2 = n1.started_server(Map.of( + "client_min_messages", "info", + "pljava.vmoptions", vmopts, + "pljava.libjvm_location", libjvm.toString() + )); + ) + { + try ( Connection c = n1.connect() ) + { + succeeding = true; // become optimistic, will be using &= below + + succeeding &= dfa( + "create extension no result", + null, + + q(c, "create extension pljava") + .flatMap(Node::semiFlattenDiagnostics) + .peek(Node::peek), + + // state 1: consume any diagnostics, or to state 2 with same item + (o,p,q) -> isDiagnostic(o, Set.of("error")) ? 1 : -2, + + // state 2: must be end of input + (o,p,q) -> null == o + ); + } + + /* + * Get a new connection; 'create extension' always sets a near-silent + * logging level, and PL/Java only checks once at VM start time, so in + * the same session where 'create extension' was done, logging is + * somewhat suppressed. + */ + try ( Connection c = n1.connect() ) + { + succeeding &= dfa( + "saxon path examples path", + null, + + Node.installSaxonAndExamplesAndPath(c, + System.getProperty("mavenRepo"), + System.getProperty("saxonVer"), + true) + .flatMap(Node::semiFlattenDiagnostics) + .peek(Node::peek), + + // states 1,2: diagnostics* then a void result set (saxon install) + (o,p,q) -> isDiagnostic(o, Set.of("error")) ? 1 : -2, + (o,p,q) -> isVoidResultSet(o, 1, 1) ? 3 : false, + + // states 3,4: diagnostics* then a void result set (set classpath) + (o,p,q) -> isDiagnostic(o, Set.of("error")) ? 3 : -4, + (o,p,q) -> isVoidResultSet(o, 1, 1) ? 5 : false, + + // states 5,6: diagnostics* then void result set (example install) + (o,p,q) -> isDiagnostic(o, Set.of("error", "warning")) ? 5 : -6, + (o,p,q) -> isVoidResultSet(o, 1, 1) ? 7 : false, + + // states 7,8: diagnostics* then a void result set (set classpath) + (o,p,q) -> isDiagnostic(o, Set.of("error")) ? 7 : -8, + (o,p,q) -> isVoidResultSet(o, 1, 1) ? 9 : false, + + // state 9: must be end of input + (o,p,q) -> null == o + ); + } + } catch ( Throwable t ) + { + succeeding = false; + throw t; + } + + System.out.println(results); + succeeding &= (0 == results.get("ng")); + System.exit(succeeding ? 0 : 1) + ENDJSHELL From 8da1d2b236b6694fd46f00dcd225bb1d6b4b7cf3 Mon Sep 17 00:00:00 2001 From: Chapman Flack Date: Sat, 29 Aug 2020 20:20:20 -0400 Subject: [PATCH 04/13] Make sure $pgConfig is not empty For this workflow, using the runner-supplied PG, it can just be pg_config and rely on the PATH. Which would be the default if it were not supplied, but more of the script would have to be touched to remove uses of the variable than just to set it to pg_config. --- .github/workflows/ci-runnerpg.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci-runnerpg.yml b/.github/workflows/ci-runnerpg.yml index 8811a2906..01fb08a53 100644 --- a/.github/workflows/ci-runnerpg.yml +++ b/.github/workflows/ci-runnerpg.yml @@ -51,6 +51,8 @@ jobs: - name: Install and test PL/Java working-directory: pljava run: | + pgConfig=pg_config # runner-supplied, just get it from the PATH + packageJar=$(find pljava-packaging -name pljava-pg*.jar -print) mavenRepo="$HOME/.m2/repository" From 31a46c29b3cf02de0377990322a47629e4381a46 Mon Sep 17 00:00:00 2001 From: Chapman Flack Date: Sat, 29 Aug 2020 20:01:39 -0400 Subject: [PATCH 05/13] Why is the wrong java version used in a sudo? --- .github/workflows/ci-runnerpg.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-runnerpg.yml b/.github/workflows/ci-runnerpg.yml index 01fb08a53..c24ef2d93 100644 --- a/.github/workflows/ci-runnerpg.yml +++ b/.github/workflows/ci-runnerpg.yml @@ -73,7 +73,11 @@ jobs: tail -n 1 ) - sudo java -Dpgconfig="$pgConfig" -jar "$packageJar" + env | fgrep JAVA + java -version + sudo -E env | fgrep JAVA + sudo -E java -version + sudo -E java -Dpgconfig="$pgConfig" -jar "$packageJar" jshell \ -execution local \ From 7ee89a6eb386c20e1b217d20586ba4701ce303ad Mon Sep 17 00:00:00 2001 From: Chapman Flack Date: Mon, 31 Aug 2020 19:39:32 -0400 Subject: [PATCH 06/13] sudo "$JAVA_HOME"/bin/java ? The preceding commit clearly showed that sudo -E did what it says on the tin, preserved the environment, JAVA_HOME was pointing to 9 in the sudo environment, and sudo -E java still ran 8. Huh? Anyway, with this working, expand the matrix a little. --- .github/workflows/ci-runnerpg.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-runnerpg.yml b/.github/workflows/ci-runnerpg.yml index c24ef2d93..a186b5ff0 100644 --- a/.github/workflows/ci-runnerpg.yml +++ b/.github/workflows/ci-runnerpg.yml @@ -17,7 +17,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest] - java: [9] # , 11, 12, 14, 15-ea] + java: [9, 11] # , 12, 14, 15-ea] steps: @@ -73,11 +73,7 @@ jobs: tail -n 1 ) - env | fgrep JAVA - java -version - sudo -E env | fgrep JAVA - sudo -E java -version - sudo -E java -Dpgconfig="$pgConfig" -jar "$packageJar" + sudo "$JAVA_HOME"/bin/java -Dpgconfig="$pgConfig" -jar "$packageJar" jshell \ -execution local \ From e990e0dbe2eb9322f8d4371ed684a6570eff4d12 Mon Sep 17 00:00:00 2001 From: Chapman Flack Date: Tue, 1 Sep 2020 21:23:00 -0400 Subject: [PATCH 07/13] Add a Build PL/Java (Windows MinGW-w64) step In this particular workflow (relying on the PostgreSQL preinstalled on the runner), this step won't work, because the preinstalled PG was built with MSVC. But this gets the pieces in place. It would work, in a workflow where the PostgreSQL was built by MinGW; it would even work in this workflow, if we give pljava-so a set of rules for building with MinGW against an MSVC-built PostgreSQL. --- .github/workflows/ci-runnerpg.yml | 65 +++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-runnerpg.yml b/.github/workflows/ci-runnerpg.yml index a186b5ff0..103dc7763 100644 --- a/.github/workflows/ci-runnerpg.yml +++ b/.github/workflows/ci-runnerpg.yml @@ -13,10 +13,19 @@ jobs: build: if: true - runs-on: ${{ matrix.os }} + runs-on: ${{ matrix.oscc.os }} + continue-on-error: true strategy: matrix: - os: [ubuntu-latest, macos-latest] + oscc: +# - os: ubuntu-latest +# cc: gcc +# - os: macos-latest +# cc: clang +# - os: windows-latest +# cc: msvc + - os: windows-latest + cc: mingw java: [9, 11] # , 12, 14, 15-ea] steps: @@ -41,15 +50,65 @@ jobs: if: ${{ 'Linux' == runner.os }} run: sudo apt-get install postgresql-server-dev-12 libkrb5-dev - - name: Build PL/Java + - name: Build PL/Java (Linux, macOS) + if: ${{ 'Windows' != runner.os }} working-directory: pljava run: | mvn clean install --batch-mode \ -Psaxon-examples -Ppgjdbc-ng \ -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + - name: Build PL/Java (Windows MinGW-w64) + if: ${{ 'Windows' == runner.os && 'mingw' == matrix.oscc.cc }} + working-directory: pljava + # + # GitHub Actions will allow 'bash' as a shell choice, even on a Windows + # runner, in which case it's the bash from Git for Windows. That isn't the + # same as the msys64\usr\bin\bash that we want; what's more, while both + # rely on a cygwin DLL, they don't rely on the same one, and an attempt + # to exec one from the other leads to a "fatal error - cygheap base + # mismatch". So, the bash we want has to be started by something other + # than the bash we've got. In this case, set shell: to a command that + # will use cmd to start the right bash. + # + # Some of the MinGW magic is set up by the bash profile run at "login", so + # bash must be started with -l. That profile ends with a cd $HOME, so to + # avoid changing the current directory, set HOME=. first (credit for that: + # https://superuser.com/a/806371). As set above, . is really the pljava + # working-directory, so the bash script should start by resetting HOME to + # the path of its parent. + # + # The runner is provisioned with a very long PATH that includes separate + # bin directories for pre-provisioned packages. The MinGW profile replaces + # that with a much shorter path, so mvn and pg_config below must be given + # as absolute paths (using M2 and PGBIN supplied in the environment) or + # they won't be found. As long as mvn itself can be found, it is able + # to find java without difficulty, using the JAVA_HOME that is also in + # the environment. + # + # Those existing variables in the environment are all spelled in Windows + # style with drive letters, colons, and backslashes, rather than the MinGW + # unixy style, but the mingw bash doesn't seem to object. + # + # If you use the runner-supplied bash to examine the environment, you will + # see MSYSTEM=MINGW64 already in it, but that apparently is something the + # runner-supplied bash does. It must be set here before invoking the MinGW + # bash directly. + # + env: + HOME: . + MSYSTEM: MINGW64 + shell: 'cmd /C "c:\msys64\usr\bin\bash -l "{0}""' + run: | + HOME=$( (cd .. && pwd) ) + "$M2"/mvn clean install --batch-mode \ + -Dpgsql.pgconfig="$PGBIN"'\pg_config' \ + -Psaxon-examples -Ppgjdbc-ng \ + -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + - name: Install and test PL/Java working-directory: pljava + shell: bash run: | pgConfig=pg_config # runner-supplied, just get it from the PATH From dbd0a0bf9ac054c9fdfa54e467da17bdf3d12abc Mon Sep 17 00:00:00 2001 From: Chapman Flack Date: Tue, 1 Sep 2020 19:16:14 -0400 Subject: [PATCH 08/13] Windows tweaks to the install-and-test step --- .github/workflows/ci-runnerpg.yml | 33 ++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci-runnerpg.yml b/.github/workflows/ci-runnerpg.yml index 103dc7763..27910af16 100644 --- a/.github/workflows/ci-runnerpg.yml +++ b/.github/workflows/ci-runnerpg.yml @@ -1,5 +1,7 @@ # This workflow will build and test PL/Java against the version of PostgreSQL -# preinstalled in the GitHub Actions runner environment. +# preinstalled in the GitHub Actions runner environment. Naturally, this one +# does not have a PostgreSQL version in the build matrix. The version that's +# preinstalled is the version you get. name: PL/Java CI with PostgreSQL version supplied by the runner @@ -132,11 +134,27 @@ jobs: tail -n 1 ) - sudo "$JAVA_HOME"/bin/java -Dpgconfig="$pgConfig" -jar "$packageJar" + # + # The runner on a Unix-like OS is running as a non-privileged user, but + # has passwordless sudo available (needed to install the PL/Java files + # into the system directories where the supplied PostgreSQL lives). By + # contrast, on Windows the runner has admin privilege, and can install + # the files without any fuss (but later below, pg_ctl will have to be + # used when starting PostgreSQL; pg_ctl has a Windows-specific ability + # to drop admin privs so postgres will not refuse to start). + # + if [[ $RUNNER_OS == Windows ]] + then + pathSep=';' + java -Dpgconfig="$pgConfig" -jar "$packageJar" + else + pathSep=':' + sudo "$JAVA_HOME"/bin/java -Dpgconfig="$pgConfig" -jar "$packageJar" + fi jshell \ -execution local \ - "-J--class-path=$packageJar:$jdbcJar" \ + "-J--class-path=$packageJar$pathSep$jdbcJar" \ "--class-path=$packageJar" \ "-J--add-modules=java.sql,java.sql.rowset" \ "-J-Dpgconfig=$pgConfig" \ @@ -152,21 +170,26 @@ jobs: import static org.postgresql.pljava.packaging.Node.q import static org.postgresql.pljava.packaging.Node.dfa import static org.postgresql.pljava.packaging.Node.isVoidResultSet + import static org.postgresql.pljava.packaging.Node.s_isWindows - Path javaLibDir = get(System.getProperty("java.home"), "lib") + Path javaLibDir = + get(System.getProperty("java.home"), s_isWindows ? "bin" : "lib") Path libjvm = ( "Mac OS X".equals(System.getProperty("os.name")) ? Stream.of("libjli.dylib", "jli/libjli.dylib") .map(s -> javaLibDir.resolve(s)) .filter(Files::exists).findFirst().get() - : javaLibDir.resolve("server/libjvm.so") + : javaLibDir.resolve(s_isWindows ? "jvm.dll" : "server/libjvm.so") ); String vmopts = "-enableassertions:org.postgresql.pljava... -Xcheck:jni" Node n1 = Node.get_new_node("TestNode1") + if ( s_isWindows ) + n1.use_pg_ctl(true) + /* * Keep a tally of the three types of diagnostic notices that may be * received, and, independently, how many represent no-good test results From e0c627d6e19ce0da8624c3638601e83a19d25252 Mon Sep 17 00:00:00 2001 From: Chapman Flack Date: Tue, 1 Sep 2020 21:40:32 -0400 Subject: [PATCH 09/13] The Strawberry PG installation is an impostor The Windows runner seems to have an extra pg_config somewhere on the path, that reports it was built with MinGW and installed in paths containing Strawberry that don't really exist. It has cropped up for others too in other settings: https://github.com/timescale/timescaledb/issues/555 The pg_config found in $PGBIN refers to a PostgreSQL that was built with MSVC, and its reported directories really exist. Specify that one explicitly when running on Windows. In passing, avoid trying to run the jshell install-and-test with Java 9 in Windows (it will wait forever for someone to type on the console). --- .github/workflows/ci-runnerpg.yml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-runnerpg.yml b/.github/workflows/ci-runnerpg.yml index 27910af16..c371c727c 100644 --- a/.github/workflows/ci-runnerpg.yml +++ b/.github/workflows/ci-runnerpg.yml @@ -42,12 +42,20 @@ jobs: with: java-version: ${{ matrix.java }} - - name: Report Java, Maven, and PostgreSQL versions + - name: Report Java, Maven, and PostgreSQL versions (Linux, macOS) + if: ${{ 'Windows' != runner.os }} run: | java -version mvn --version pg_config + - name: Report Java, Maven, and PostgreSQL versions (Windows) + if: ${{ 'Windows' == runner.os }} + run: | + java -version + mvn --version + & "$Env:PGBIN\pg_config" + - name: Obtain PG development files (Ubuntu, PGDG) if: ${{ 'Linux' == runner.os }} run: sudo apt-get install postgresql-server-dev-12 libkrb5-dev @@ -109,6 +117,7 @@ jobs: -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - name: Install and test PL/Java + if: ${{ '9' != matrix.java || 'Windows' != runner.os }} working-directory: pljava shell: bash run: | @@ -143,9 +152,16 @@ jobs: # used when starting PostgreSQL; pg_ctl has a Windows-specific ability # to drop admin privs so postgres will not refuse to start). # + # The Windows runner seems to have an extra pg_config somewhere on the + # path, that reports it was built with MinGW and installed in paths + # containing Strawberry that don't really exist. $PGBIN\pg_config refers + # to a different build made with MSVC, and those directories really + # exist, so specify that one explicitly when running on Windows. + # if [[ $RUNNER_OS == Windows ]] then pathSep=';' + pgConfig="$PGBIN"'\pg_config' java -Dpgconfig="$pgConfig" -jar "$packageJar" else pathSep=':' From 25e326d6ee2f9c64d998c14059bdbf67d98b9381 Mon Sep 17 00:00:00 2001 From: Chapman Flack Date: Tue, 1 Sep 2020 20:09:41 -0400 Subject: [PATCH 10/13] Munge (or is it unmunge?) pathnames for Windows Using the bash environment in Windows offers the convenience of one scripting language to tee up the install-and-test, but at the cost of getting paths we need (jdbcJar and mavenRepo) munged into Unix style. They have to be unmunged, as the Windows native Java can't use them that way. --- .github/workflows/ci-runnerpg.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/ci-runnerpg.yml b/.github/workflows/ci-runnerpg.yml index c371c727c..e5846a7a9 100644 --- a/.github/workflows/ci-runnerpg.yml +++ b/.github/workflows/ci-runnerpg.yml @@ -158,11 +158,23 @@ jobs: # to a different build made with MSVC, and those directories really # exist, so specify that one explicitly when running on Windows. # + # The Git for Windows bash environment includes a find command, and the + # things found have unixy paths returned. Make them Windowsy here, with + # a hardcoded assumption they start with /c which should become c: (as + # appears to be the case in the Windows runner currently). + # if [[ $RUNNER_OS == Windows ]] then pathSep=';' pgConfig="$PGBIN"'\pg_config' java -Dpgconfig="$pgConfig" -jar "$packageJar" + function toWindowsPath() { + local p + p="c:${1#/c}" + printf "%s" "${p//\//\\}" + } + jdbcJar="$(toWindowsPath "$jdbcJar")" + mavenRepo="$(toWindowsPath "$mavenRepo")" else pathSep=':' sudo "$JAVA_HOME"/bin/java -Dpgconfig="$pgConfig" -jar "$packageJar" From f2e96a12907feb4b339a52493f4e3f27c46b7778 Mon Sep 17 00:00:00 2001 From: Chapman Flack Date: Tue, 1 Sep 2020 21:46:59 -0400 Subject: [PATCH 11/13] Exclude windows-mingw from the matrix for now It can't work in this workflow, where the supplied PostgreSQL was built with MSVC, at least for now. Re-enable the Linux and Mac builds to make sure the MinGW changes didn't break them. --- .github/workflows/ci-runnerpg.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-runnerpg.yml b/.github/workflows/ci-runnerpg.yml index e5846a7a9..5c65b0b78 100644 --- a/.github/workflows/ci-runnerpg.yml +++ b/.github/workflows/ci-runnerpg.yml @@ -20,14 +20,14 @@ jobs: strategy: matrix: oscc: -# - os: ubuntu-latest -# cc: gcc -# - os: macos-latest -# cc: clang + - os: ubuntu-latest + cc: gcc + - os: macos-latest + cc: clang # - os: windows-latest # cc: msvc - - os: windows-latest - cc: mingw +# - os: windows-latest +# cc: mingw java: [9, 11] # , 12, 14, 15-ea] steps: From a28228f4ba283e6defcdadc3e72567ec94c6ce25 Mon Sep 17 00:00:00 2001 From: Chapman Flack Date: Thu, 10 Sep 2020 21:59:07 -0400 Subject: [PATCH 12/13] Update ci-sourcepg.yml and add ci-packagedpg.yml Structure the matrix in each the same as in ci-runnerpg.yml (except that both of these will have a choice of PostgreSQL version, rather than being stuck with the version supplied on the runner). Both of these need to be completed, of course. There is much duplication among these three workflows (pretty much everything after installing or building PostgreSQL). They will probably be easier to get working that way. After most of the tricky bits have been worked out, it may be possible to combine them all into one giant uberworkflow with a lot of conditional steps. That feels like premature optimization for now. --- .github/workflows/ci-packagedpg.yml | 322 ++++++++++++++++++++++++++++ .github/workflows/ci-sourcepg.yml | 294 ++++++++++++++++++++++++- 2 files changed, 613 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/ci-packagedpg.yml diff --git a/.github/workflows/ci-packagedpg.yml b/.github/workflows/ci-packagedpg.yml new file mode 100644 index 000000000..4bcd523c2 --- /dev/null +++ b/.github/workflows/ci-packagedpg.yml @@ -0,0 +1,322 @@ +# This workflow will build and test PL/Java against versions of PostgreSQL +# installed from prebuilt packages. + +name: PL/Java CI with PostgreSQL prebuilt packaged versions + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + if: false + + runs-on: ${{ matrix.oscc.os }} + strategy: + matrix: + oscc: + - os: ubuntu-latest + cc: gcc + - os: macos-latest + cc: clang + - os: windows-latest + cc: msvc + - os: windows-latest + cc: mingw + java: [9, 11, 12, 14, 15-ea] + pgsql: [12, 11, 10, 9.6, 9.5] + + steps: + + - name: Check out PL/Java + uses: actions/checkout@v2 + with: + path: pljava + + - name: Install PostgreSQL + shell: bash + run: echo here a miracle occurs + + - name: Set up JDK + uses: actions/setup-java@v1 + with: + java-version: ${{ matrix.java }} + + - name: Report Java, Maven, and PostgreSQL versions (Linux, macOS) + if: ${{ 'Windows' != runner.os }} + run: | + java -version + mvn --version + pg_config # might need attention to the path + + - name: Report Java, Maven, and PostgreSQL versions (Windows) + if: ${{ 'Windows' == runner.os }} + run: | + java -version + mvn --version + & "$Env:PGBIN\pg_config" # might need attention to the path + + - name: Build PL/Java (Linux, macOS) + if: ${{ 'Windows' != runner.os }} + working-directory: pljava + run: | + pgConfig=pg_config # might need attention to the path + mvn clean install --batch-mode \ + -Dpgsql.pgconfig="$pgConfig" \ + -Psaxon-examples -Ppgjdbc-ng \ + -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + + - name: Build PL/Java (Windows MinGW-w64) + if: ${{ 'Windows' == runner.os && 'mingw' == matrix.oscc.cc }} + working-directory: pljava + # + # GitHub Actions will allow 'bash' as a shell choice, even on a Windows + # runner, in which case it's the bash from Git for Windows. That isn't the + # same as the msys64\usr\bin\bash that we want; what's more, while both + # rely on a cygwin DLL, they don't rely on the same one, and an attempt + # to exec one from the other leads to a "fatal error - cygheap base + # mismatch". So, the bash we want has to be started by something other + # than the bash we've got. In this case, set shell: to a command that + # will use cmd to start the right bash. + # + # Some of the MinGW magic is set up by the bash profile run at "login", so + # bash must be started with -l. That profile ends with a cd $HOME, so to + # avoid changing the current directory, set HOME=. first (credit for that: + # https://superuser.com/a/806371). As set above, . is really the pljava + # working-directory, so the bash script should start by resetting HOME to + # the path of its parent. + # + # The runner is provisioned with a very long PATH that includes separate + # bin directories for pre-provisioned packages. The MinGW profile replaces + # that with a much shorter path, so mvn and pg_config below must be given + # as absolute paths (using M2 and PGBIN supplied in the environment) or + # they won't be found. As long as mvn itself can be found, it is able + # to find java without difficulty, using the JAVA_HOME that is also in + # the environment. + # + # Those existing variables in the environment are all spelled in Windows + # style with drive letters, colons, and backslashes, rather than the MinGW + # unixy style, but the mingw bash doesn't seem to object. + # + # If you use the runner-supplied bash to examine the environment, you will + # see MSYSTEM=MINGW64 already in it, but that apparently is something the + # runner-supplied bash does. It must be set here before invoking the MinGW + # bash directly. + # + env: + HOME: . + MSYSTEM: MINGW64 + shell: 'cmd /C "c:\msys64\usr\bin\bash -l "{0}""' + run: | + HOME=$( (cd .. && pwd) ) + pgConfig="$PGBIN"'\pg_config' # might need attention to the path + "$M2"/mvn clean install --batch-mode \ + -Dpgsql.pgconfig="$pgConfig' \ + -Psaxon-examples -Ppgjdbc-ng \ + -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + + - name: Install and test PL/Java + if: ${{ '9' != matrix.java || 'Windows' != runner.os }} + working-directory: pljava + shell: bash + run: | + pgConfig=pg_config # might need attention to the path + + packageJar=$(find pljava-packaging -name pljava-pg*.jar -print) + + mavenRepo="$HOME/.m2/repository" + + saxonVer=$( + find "$mavenRepo/net/sf/saxon/Saxon-HE" \ + -name 'Saxon-HE-*.jar' -print | + sort | + tail -n 1 + ) + saxonVer=${saxonVer%/*} + saxonVer=${saxonVer##*/} + + jdbcJar=$( + find "$mavenRepo/com/impossibl/pgjdbc-ng/pgjdbc-ng-all" \ + -name 'pgjdbc-ng-all-*.jar' -print | + sort | + tail -n 1 + ) + + # + # The runner on a Unix-like OS is running as a non-privileged user, but + # has passwordless sudo available (needed to install the PL/Java files + # into the system directories where the supplied PostgreSQL lives). By + # contrast, on Windows the runner has admin privilege, and can install + # the files without any fuss (but later below, pg_ctl will have to be + # used when starting PostgreSQL; pg_ctl has a Windows-specific ability + # to drop admin privs so postgres will not refuse to start). + # + # The Windows runner seems to have an extra pg_config somewhere on the + # path, that reports it was built with MinGW and installed in paths + # containing Strawberry that don't really exist. $PGBIN\pg_config refers + # to a different build made with MSVC, and those directories really + # exist, so specify that one explicitly when running on Windows. + # + # The Git for Windows bash environment includes a find command, and the + # things found have unixy paths returned. Make them Windowsy here, with + # a hardcoded assumption they start with /c which should become c: (as + # appears to be the case in the Windows runner currently). + # + if [[ $RUNNER_OS == Windows ]] + then + pathSep=';' + pgConfig="$PGBIN"'\pg_config' + java -Dpgconfig="$pgConfig" -jar "$packageJar" + function toWindowsPath() { + local p + p="c:${1#/c}" + printf "%s" "${p//\//\\}" + } + jdbcJar="$(toWindowsPath "$jdbcJar")" + mavenRepo="$(toWindowsPath "$mavenRepo")" + else + pathSep=':' + sudo "$JAVA_HOME"/bin/java -Dpgconfig="$pgConfig" -jar "$packageJar" + fi + + jshell \ + -execution local \ + "-J--class-path=$packageJar$pathSep$jdbcJar" \ + "--class-path=$packageJar" \ + "-J--add-modules=java.sql,java.sql.rowset" \ + "-J-Dpgconfig=$pgConfig" \ + "-J-Dcom.impossibl.shadow.io.netty.noUnsafe=true" \ + "-J-DmavenRepo=$mavenRepo" \ + "-J-DsaxonVer=$saxonVer" - <<\ENDJSHELL + + boolean succeeding = false; // begin pessimistic + + import static java.nio.file.Paths.get + import java.sql.Connection + import org.postgresql.pljava.packaging.Node + import static org.postgresql.pljava.packaging.Node.q + import static org.postgresql.pljava.packaging.Node.dfa + import static org.postgresql.pljava.packaging.Node.isVoidResultSet + import static org.postgresql.pljava.packaging.Node.s_isWindows + + Path javaLibDir = + get(System.getProperty("java.home"), s_isWindows ? "bin" : "lib") + + Path libjvm = ( + "Mac OS X".equals(System.getProperty("os.name")) + ? Stream.of("libjli.dylib", "jli/libjli.dylib") + .map(s -> javaLibDir.resolve(s)) + .filter(Files::exists).findFirst().get() + : javaLibDir.resolve(s_isWindows ? "jvm.dll" : "server/libjvm.so") + ); + + String vmopts = "-enableassertions:org.postgresql.pljava... -Xcheck:jni" + + Node n1 = Node.get_new_node("TestNode1") + + if ( s_isWindows ) + n1.use_pg_ctl(true) + + /* + * Keep a tally of the three types of diagnostic notices that may be + * received, and, independently, how many represent no-good test results + * (error always, but also warning if seen from the tests in the + * examples.jar deployment descriptor). + */ + Map results = + Stream.of("info", "warning", "error", "ng").collect( + LinkedHashMap::new, + (m,k) -> m.put(k, 0), (r,s) -> {}) + + boolean isDiagnostic(Object o, Set whatIsNG) + { + if ( ! ( o instanceof Throwable ) ) + return false; + String[] parts = Node.classify((Throwable)o); + String type = parts[0]; + results.compute(type, (k,v) -> 1 + v); + if ( whatIsNG.contains(type) ) + results.compute("ng", (k,v) -> 1 + v); + return true; + } + + try ( + AutoCloseable t1 = n1.initialized_cluster(); + AutoCloseable t2 = n1.started_server(Map.of( + "client_min_messages", "info", + "pljava.vmoptions", vmopts, + "pljava.libjvm_location", libjvm.toString() + )); + ) + { + try ( Connection c = n1.connect() ) + { + succeeding = true; // become optimistic, will be using &= below + + succeeding &= dfa( + "create extension no result", + null, + + q(c, "create extension pljava") + .flatMap(Node::semiFlattenDiagnostics) + .peek(Node::peek), + + // state 1: consume any diagnostics, or to state 2 with same item + (o,p,q) -> isDiagnostic(o, Set.of("error")) ? 1 : -2, + + // state 2: must be end of input + (o,p,q) -> null == o + ); + } + + /* + * Get a new connection; 'create extension' always sets a near-silent + * logging level, and PL/Java only checks once at VM start time, so in + * the same session where 'create extension' was done, logging is + * somewhat suppressed. + */ + try ( Connection c = n1.connect() ) + { + succeeding &= dfa( + "saxon path examples path", + null, + + Node.installSaxonAndExamplesAndPath(c, + System.getProperty("mavenRepo"), + System.getProperty("saxonVer"), + true) + .flatMap(Node::semiFlattenDiagnostics) + .peek(Node::peek), + + // states 1,2: diagnostics* then a void result set (saxon install) + (o,p,q) -> isDiagnostic(o, Set.of("error")) ? 1 : -2, + (o,p,q) -> isVoidResultSet(o, 1, 1) ? 3 : false, + + // states 3,4: diagnostics* then a void result set (set classpath) + (o,p,q) -> isDiagnostic(o, Set.of("error")) ? 3 : -4, + (o,p,q) -> isVoidResultSet(o, 1, 1) ? 5 : false, + + // states 5,6: diagnostics* then void result set (example install) + (o,p,q) -> isDiagnostic(o, Set.of("error", "warning")) ? 5 : -6, + (o,p,q) -> isVoidResultSet(o, 1, 1) ? 7 : false, + + // states 7,8: diagnostics* then a void result set (set classpath) + (o,p,q) -> isDiagnostic(o, Set.of("error")) ? 7 : -8, + (o,p,q) -> isVoidResultSet(o, 1, 1) ? 9 : false, + + // state 9: must be end of input + (o,p,q) -> null == o + ); + } + } catch ( Throwable t ) + { + succeeding = false; + throw t; + } + + System.out.println(results); + succeeding &= (0 == results.get("ng")); + System.exit(succeeding ? 0 : 1) + ENDJSHELL diff --git a/.github/workflows/ci-sourcepg.yml b/.github/workflows/ci-sourcepg.yml index 0b35f3423..184d247a3 100644 --- a/.github/workflows/ci-sourcepg.yml +++ b/.github/workflows/ci-sourcepg.yml @@ -13,29 +13,317 @@ jobs: build: if: false - runs-on: ${{ matrix.os }} + runs-on: ${{ matrix.oscc.os }} strategy: matrix: - os: [ubuntu-latest] + oscc: + - os: ubuntu-latest + cc: gcc + - os: macos-latest + cc: clang + - os: windows-latest + cc: msvc + - os: windows-latest + cc: mingw java: [9, 11, 12, 14, 15-ea] pgsql: [REL_12_4, REL_11_9, REL_10_14, REL9_6_19, REL9_5_23] steps: + - name: Check out PL/Java uses: actions/checkout@v2 with: path: pljava + - name: Check out PostgreSQL uses: actions/checkout@v2 with: path: postgresql repository: postgres/postgres ref: ${{ matrix.pgsql }} + + - name: Configure and build PostgreSQL + shell: bash + run: echo here a miracle occurs + - name: Set up JDK uses: actions/setup-java@v1 with: java-version: ${{ matrix.java }} - - name: Report Java and Maven versions + + - name: Report Java, Maven, and PostgreSQL versions (Linux, macOS) + if: ${{ 'Windows' != runner.os }} run: | java -version mvn --version + pg_config # might need attention to the path + + - name: Report Java, Maven, and PostgreSQL versions (Windows) + if: ${{ 'Windows' == runner.os }} + run: | + java -version + mvn --version + & "$Env:PGBIN\pg_config" # might need attention to the path + + - name: Build PL/Java (Linux, macOS) + if: ${{ 'Windows' != runner.os }} + working-directory: pljava + run: | + pgConfig=pg_config # might need attention to the path + mvn clean install --batch-mode \ + -Dpgsql.pgconfig="$pgConfig" \ + -Psaxon-examples -Ppgjdbc-ng \ + -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + + - name: Build PL/Java (Windows MinGW-w64) + if: ${{ 'Windows' == runner.os && 'mingw' == matrix.oscc.cc }} + working-directory: pljava + # + # GitHub Actions will allow 'bash' as a shell choice, even on a Windows + # runner, in which case it's the bash from Git for Windows. That isn't the + # same as the msys64\usr\bin\bash that we want; what's more, while both + # rely on a cygwin DLL, they don't rely on the same one, and an attempt + # to exec one from the other leads to a "fatal error - cygheap base + # mismatch". So, the bash we want has to be started by something other + # than the bash we've got. In this case, set shell: to a command that + # will use cmd to start the right bash. + # + # Some of the MinGW magic is set up by the bash profile run at "login", so + # bash must be started with -l. That profile ends with a cd $HOME, so to + # avoid changing the current directory, set HOME=. first (credit for that: + # https://superuser.com/a/806371). As set above, . is really the pljava + # working-directory, so the bash script should start by resetting HOME to + # the path of its parent. + # + # The runner is provisioned with a very long PATH that includes separate + # bin directories for pre-provisioned packages. The MinGW profile replaces + # that with a much shorter path, so mvn and pg_config below must be given + # as absolute paths (using M2 and PGBIN supplied in the environment) or + # they won't be found. As long as mvn itself can be found, it is able + # to find java without difficulty, using the JAVA_HOME that is also in + # the environment. + # + # Those existing variables in the environment are all spelled in Windows + # style with drive letters, colons, and backslashes, rather than the MinGW + # unixy style, but the mingw bash doesn't seem to object. + # + # If you use the runner-supplied bash to examine the environment, you will + # see MSYSTEM=MINGW64 already in it, but that apparently is something the + # runner-supplied bash does. It must be set here before invoking the MinGW + # bash directly. + # + env: + HOME: . + MSYSTEM: MINGW64 + shell: 'cmd /C "c:\msys64\usr\bin\bash -l "{0}""' + run: | + HOME=$( (cd .. && pwd) ) + pgConfig="$PGBIN"'\pg_config' # might need attention to the path + "$M2"/mvn clean install --batch-mode \ + -Dpgsql.pgconfig="$pgConfig' \ + -Psaxon-examples -Ppgjdbc-ng \ + -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + + - name: Install and test PL/Java + if: ${{ '9' != matrix.java || 'Windows' != runner.os }} + working-directory: pljava + shell: bash + run: | + pgConfig=pg_config # might need attention to the path + + packageJar=$(find pljava-packaging -name pljava-pg*.jar -print) + + mavenRepo="$HOME/.m2/repository" + + saxonVer=$( + find "$mavenRepo/net/sf/saxon/Saxon-HE" \ + -name 'Saxon-HE-*.jar' -print | + sort | + tail -n 1 + ) + saxonVer=${saxonVer%/*} + saxonVer=${saxonVer##*/} + + jdbcJar=$( + find "$mavenRepo/com/impossibl/pgjdbc-ng/pgjdbc-ng-all" \ + -name 'pgjdbc-ng-all-*.jar' -print | + sort | + tail -n 1 + ) + + # + # The runner on a Unix-like OS is running as a non-privileged user, but + # has passwordless sudo available (needed to install the PL/Java files + # into the system directories where the supplied PostgreSQL lives). By + # contrast, on Windows the runner has admin privilege, and can install + # the files without any fuss (but later below, pg_ctl will have to be + # used when starting PostgreSQL; pg_ctl has a Windows-specific ability + # to drop admin privs so postgres will not refuse to start). + # + # The Windows runner seems to have an extra pg_config somewhere on the + # path, that reports it was built with MinGW and installed in paths + # containing Strawberry that don't really exist. $PGBIN\pg_config refers + # to a different build made with MSVC, and those directories really + # exist, so specify that one explicitly when running on Windows. + # + # The Git for Windows bash environment includes a find command, and the + # things found have unixy paths returned. Make them Windowsy here, with + # a hardcoded assumption they start with /c which should become c: (as + # appears to be the case in the Windows runner currently). + # + if [[ $RUNNER_OS == Windows ]] + then + pathSep=';' + pgConfig="$PGBIN"'\pg_config' + java -Dpgconfig="$pgConfig" -jar "$packageJar" + function toWindowsPath() { + local p + p="c:${1#/c}" + printf "%s" "${p//\//\\}" + } + jdbcJar="$(toWindowsPath "$jdbcJar")" + mavenRepo="$(toWindowsPath "$mavenRepo")" + else + pathSep=':' + sudo "$JAVA_HOME"/bin/java -Dpgconfig="$pgConfig" -jar "$packageJar" + fi + + jshell \ + -execution local \ + "-J--class-path=$packageJar$pathSep$jdbcJar" \ + "--class-path=$packageJar" \ + "-J--add-modules=java.sql,java.sql.rowset" \ + "-J-Dpgconfig=$pgConfig" \ + "-J-Dcom.impossibl.shadow.io.netty.noUnsafe=true" \ + "-J-DmavenRepo=$mavenRepo" \ + "-J-DsaxonVer=$saxonVer" - <<\ENDJSHELL + + boolean succeeding = false; // begin pessimistic + + import static java.nio.file.Paths.get + import java.sql.Connection + import org.postgresql.pljava.packaging.Node + import static org.postgresql.pljava.packaging.Node.q + import static org.postgresql.pljava.packaging.Node.dfa + import static org.postgresql.pljava.packaging.Node.isVoidResultSet + import static org.postgresql.pljava.packaging.Node.s_isWindows + + Path javaLibDir = + get(System.getProperty("java.home"), s_isWindows ? "bin" : "lib") + + Path libjvm = ( + "Mac OS X".equals(System.getProperty("os.name")) + ? Stream.of("libjli.dylib", "jli/libjli.dylib") + .map(s -> javaLibDir.resolve(s)) + .filter(Files::exists).findFirst().get() + : javaLibDir.resolve(s_isWindows ? "jvm.dll" : "server/libjvm.so") + ); + + String vmopts = "-enableassertions:org.postgresql.pljava... -Xcheck:jni" + + Node n1 = Node.get_new_node("TestNode1") + + if ( s_isWindows ) + n1.use_pg_ctl(true) + + /* + * Keep a tally of the three types of diagnostic notices that may be + * received, and, independently, how many represent no-good test results + * (error always, but also warning if seen from the tests in the + * examples.jar deployment descriptor). + */ + Map results = + Stream.of("info", "warning", "error", "ng").collect( + LinkedHashMap::new, + (m,k) -> m.put(k, 0), (r,s) -> {}) + + boolean isDiagnostic(Object o, Set whatIsNG) + { + if ( ! ( o instanceof Throwable ) ) + return false; + String[] parts = Node.classify((Throwable)o); + String type = parts[0]; + results.compute(type, (k,v) -> 1 + v); + if ( whatIsNG.contains(type) ) + results.compute("ng", (k,v) -> 1 + v); + return true; + } + + try ( + AutoCloseable t1 = n1.initialized_cluster(); + AutoCloseable t2 = n1.started_server(Map.of( + "client_min_messages", "info", + "pljava.vmoptions", vmopts, + "pljava.libjvm_location", libjvm.toString() + )); + ) + { + try ( Connection c = n1.connect() ) + { + succeeding = true; // become optimistic, will be using &= below + + succeeding &= dfa( + "create extension no result", + null, + + q(c, "create extension pljava") + .flatMap(Node::semiFlattenDiagnostics) + .peek(Node::peek), + + // state 1: consume any diagnostics, or to state 2 with same item + (o,p,q) -> isDiagnostic(o, Set.of("error")) ? 1 : -2, + + // state 2: must be end of input + (o,p,q) -> null == o + ); + } + + /* + * Get a new connection; 'create extension' always sets a near-silent + * logging level, and PL/Java only checks once at VM start time, so in + * the same session where 'create extension' was done, logging is + * somewhat suppressed. + */ + try ( Connection c = n1.connect() ) + { + succeeding &= dfa( + "saxon path examples path", + null, + + Node.installSaxonAndExamplesAndPath(c, + System.getProperty("mavenRepo"), + System.getProperty("saxonVer"), + true) + .flatMap(Node::semiFlattenDiagnostics) + .peek(Node::peek), + + // states 1,2: diagnostics* then a void result set (saxon install) + (o,p,q) -> isDiagnostic(o, Set.of("error")) ? 1 : -2, + (o,p,q) -> isVoidResultSet(o, 1, 1) ? 3 : false, + + // states 3,4: diagnostics* then a void result set (set classpath) + (o,p,q) -> isDiagnostic(o, Set.of("error")) ? 3 : -4, + (o,p,q) -> isVoidResultSet(o, 1, 1) ? 5 : false, + + // states 5,6: diagnostics* then void result set (example install) + (o,p,q) -> isDiagnostic(o, Set.of("error", "warning")) ? 5 : -6, + (o,p,q) -> isVoidResultSet(o, 1, 1) ? 7 : false, + + // states 7,8: diagnostics* then a void result set (set classpath) + (o,p,q) -> isDiagnostic(o, Set.of("error")) ? 7 : -8, + (o,p,q) -> isVoidResultSet(o, 1, 1) ? 9 : false, + + // state 9: must be end of input + (o,p,q) -> null == o + ); + } + } catch ( Throwable t ) + { + succeeding = false; + throw t; + } + + System.out.println(results); + succeeding &= (0 == results.get("ng")); + System.exit(succeeding ? 0 : 1) + ENDJSHELL From 909f7b450b481dcceb14b2a50c9348ce02559f2a Mon Sep 17 00:00:00 2001 From: Kartik Ohri Date: Mon, 21 Sep 2020 22:51:05 +0530 Subject: [PATCH 13/13] Add rule to build on MinGW with MSVC built PG --- pljava-so/pom.xml | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/pljava-so/pom.xml b/pljava-so/pom.xml index c8830e32b..71704ae2f 100644 --- a/pljava-so/pom.xml +++ b/pljava-so/pom.xml @@ -151,6 +151,51 @@ } }, + { + name : "Windows MinGW with MSVC PostgreSQL", + + object_extension : ".o", + + probe: function(os_name) { + return os_name.toLowerCase().contains("windows") + && java.lang.System.getenv().containsKey("MSYSTEM") + && java.lang.System.getenv().get("MSYSTEM").equalsIgnoreCase("MINGW64") + && getPgConfigProperty("--cc").equals("not recorded"); + }, + + compile : function(cc, files, output_dir, includes, defines, flags) { + includes.add(java_include.resolve("win32").toString()); + includes.add(Paths.get(includedir_server, "port", "win32").toString()); + includes.add(resolve(pljava_include, + Paths.get("fallback", "win32")).toString()); + defines.put("Windows", null); + + var compileProcess = utils.processBuilder(function(l) { + l.add(cc); + l.addAll(pgxs.formatDefines(defines)); + l.addAll(pgxs.formatIncludes(includes)); + l.add("-c"); + l.addAll(files); + }); + compileProcess.directory(output_dir.toFile()); + return runCommand(utils.forWindowsCRuntime(compileProcess)); + }, + + link : function(cc, flags, files, target_path) { + flags.addAll(of("-Wl,--export-all-symbols","-shared-libgcc")); + var linkingProcess = utils.processBuilder(function(l) { + l.add(cc); + l.addAll(of("-shared", "-o", library_name + ".dll")); + l.addAll(files); + + // From compiler-mingw64 profile + l.addAll(of("-L" + pkglibdir, "-Bdynamic", "-lpostgres")); + }); + linkingProcess.directory(target_path.toFile()); + return runCommand(utils.forWindowsCRuntime(linkingProcess)); + } + }, + { name : "Windows MinGW",