diff --git a/.github/actions/common/action.yml b/.github/actions/common/action.yml new file mode 100644 index 00000000000..f0ced9a9943 --- /dev/null +++ b/.github/actions/common/action.yml @@ -0,0 +1,176 @@ +# +# Copyright (c) 2023, 2024 Oracle and/or its affiliates. +# +# Licensed 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. +# + +name: 'Common Job Steps' +description: A composite action that abstracts the common steps needed to implement a job +inputs: + native-image: + description: Whether to setup GraalVM native-image + required: false + default: 'false' + maven-cache: + description: Whether to cache the Maven local repository (read-only or read-write) + required: false + default: 'read-only' + build-cache: + description: Whether to cache the Maven build (read-only or read-write) + required: false + default: '' + build-cache-id: + description: Build cache id + required: false + default: 'default' + GPG_PASSPHRASE: + description: Value of the GPG_PASSPHRASE environment variable + required: false + default: '' + GPG_PRIVATE_KEY: + description: Value of the GPG_PRIVATE_KEY environment variable + required: false + default: '' + MAVEN_SETTINGS: + description: Value of the MAVEN_SETTINGS environment variable + required: false + default: '' + run: + description: The bash command to run + required: true + artifact-name: + description: Name of the artifact to create + required: false + default: '' + artifact-path: + description: Path of the files to include in the artifact + required: false + default: '' + test-artifact-name: + description: Name of the test artifact to create (excluded on windows), if non empty tests are archived + required: false + default: '' + free-space: + description: Whether to aggressively free disk space on the runner + default: 'false' +runs: + using: "composite" + steps: + - if: ${{ inputs.free-space == 'true' }} + # See https://github.com/actions/runner-images/issues/2840 + name: Free disk space + shell: bash + run: | + sudo rm -rf /usr/share/dotnet + sudo rm -rf /usr/local/share/powershell + - if: ${{ runner.os == 'Windows' }} + name: Use GNU tar + shell: cmd + run: | + echo "Adding GNU tar to PATH" + echo C:\Program Files\Git\usr\bin>>"%GITHUB_PATH%" + git config --global core.autocrlf false + git config --global core.eol lf + - name: Set up GraalVM + if: ${{ inputs.native-image == 'true' }} + uses: graalvm/setup-graalvm@v1.2.1 + with: + java-version: ${{ env.JAVA_VERSION }} + version: ${{ env.GRAALVM_VERSION }} + components: ${{ env.GRAALVM_COMPONENTS }} + check-for-updates: 'false' + set-java-home: 'false' + - name: Set up JDK + uses: actions/setup-java@v4.1.0 + with: + distribution: ${{ env.JAVA_DISTRO }} + java-version: ${{ env.JAVA_VERSION }} + - name: Cache local Maven repository (read-write) + if: ${{ inputs.maven-cache == 'read-write' }} + uses: actions/cache@v4.0.2 + with: + # See https://github.com/actions/toolkit/issues/713 + # Include must not match top level directories + path: | + .m2/repository/**/*.* + !.m2/repository/io/helidon/** + enableCrossOsArchive: true + # only hash top-level poms to keep it fast + key: local-maven-${{ hashFiles('*/pom.xml', 'pom.xml') }} + restore-keys: | + local-maven- + - name: Cache local Maven repository (read-only) + if: ${{ inputs.maven-cache == 'read-only' }} + uses: actions/cache/restore@v4.0.2 + with: + path: | + .m2/repository/**/*.* + !.m2/repository/io/helidon/** + enableCrossOsArchive: true + key: local-maven-${{ hashFiles('*/pom.xml', 'pom.xml') }} + restore-keys: | + local-maven- + - name: Build cache (read-write) + if: ${{ inputs.build-cache == 'read-write' }} + uses: actions/cache@v4.0.2 + with: + path: | + ./**/target/** + .m2/repository/io/helidon/** + enableCrossOsArchive: true + key: build-cache-${{ github.run_id }}-${{ github.run_attempt }}-${{ inputs.build-cache-id }} + restore-keys: | + build-cache-${{ github.run_id }}-${{ github.run_attempt }}- + build-cache-${{ github.run_id }}- + - name: Build cache (read-only) + if: ${{ inputs.build-cache == 'read-only' }} + uses: actions/cache/restore@v4.0.2 + with: + path: | + ./**/target/** + .m2/repository/io/helidon/** + enableCrossOsArchive: true + fail-on-cache-miss: true + key: build-cache-${{ github.run_id }}-${{ github.run_attempt }}-${{ inputs.build-cache-id }} + restore-keys: | + build-cache-${{ github.run_id }}-${{ github.run_attempt }}- + build-cache-${{ github.run_id }}- + - name: Exec + env: + GPG_PASSPHRASE: ${{ inputs.GPG_PASSPHRASE }} + GPG_PRIVATE_KEY: ${{ inputs.GPG_PRIVATE_KEY }} + MAVEN_SETTINGS: ${{ inputs.MAVEN_SETTINGS }} + MAVEN_ARGS: | + ${{ env.MAVEN_ARGS }} + -Dmaven.repo.local=${{ github.workspace }}/.m2/repository + -Dcache.record=${{ inputs.build-cache == 'read-write' }} + run: ${{ inputs.run }} + shell: bash + - name: Archive test results + # https://github.com/actions/upload-artifact/issues/240 + if: ${{ inputs.test-artifact-name != '' && runner.os != 'Windows' && always() }} + uses: actions/upload-artifact@v4 + with: + if-no-files-found: 'ignore' + name: ${{ inputs.test-artifact-name }} + path: | + **/target/surefire-reports/*.txt + **/target/failsafe-reports/*.txt + **/target/it/**/*.log + - name: Archive artifacts + if: ${{ inputs.artifact-name != '' && inputs.artifact-path != '' && always() }} + uses: actions/upload-artifact@v4 + with: + if-no-files-found: 'ignore' + name: ${{ inputs.artifact-name }} + path: ${{ inputs.artifact-path }} diff --git a/.github/workflows/pr-merge.yaml b/.github/workflows/pr-merge.yaml index 5841badecd7..5d01670799d 100644 --- a/.github/workflows/pr-merge.yaml +++ b/.github/workflows/pr-merge.yaml @@ -1,13 +1,23 @@ # -# Workflow that runs on any push to main. +# Copyright (c) 2024 Oracle and/or its affiliates. +# +# Licensed 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. name: "Post PR Merge" on: push: - branches: - - 'main' - - 'helidon-*.x' + branches: [ 'main', 'helidon-*.x' ] concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -18,5 +28,5 @@ jobs: uses: ./.github/workflows/validate.yml snapshot: needs: validate - uses: ./.github/workflows/snapshotrelease.yaml + uses: ./.github/workflows/snapshot.yaml secrets: inherit diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index e7e72b18ad3..45c92e84f1b 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,66 +1,74 @@ -# Notes -# - cannot run on Windows, as we use shell scripts +# +# Copyright (c) 2023, 2024 Oracle and/or its affiliates. +# +# Licensed 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. name: "Release" on: push: - branches: - - 'release-*' + branches: [ 'release-*' ] + env: JAVA_VERSION: '21' JAVA_DISTRO: 'oracle' - MAVEN_HTTP_ARGS: '-Dmaven.wagon.httpconnectionManager.ttlSeconds=60 -Dmaven.wagon.http.retryHandler.count=3' + MAVEN_ARGS: | + -B -e + -Dmaven.wagon.httpconnectionManager.ttlSeconds=60 + -Dmaven.wagon.http.retryHandler.count=3 + -Djdk.toolchain.version=${JAVA_VERSION} concurrency: group: release-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: - copyright: - timeout-minutes: 10 + create-tag: runs-on: ubuntu-20.04 + environment: release + outputs: + tag: ${{ steps.create-tag.outputs.tag }} steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 - - name: Set up JDK ${{ env.JAVA_VERSION }} + token: ${{ secrets.SERVICE_ACCOUNT_TOKEN }} + - name: Set up JDK uses: actions/setup-java@v4.1.0 with: distribution: ${{ env.JAVA_DISTRO }} java-version: ${{ env.JAVA_VERSION }} - cache: maven - - name: Copyright - run: etc/scripts/copyright.sh + - id: create-tag + run: ./etc/scripts/release.sh create_tag >> "${GITHUB_OUTPUT}" + validate: + needs: create-tag + uses: ./.github/workflows/validate.yml + with: + ref: ${{ needs.create-tag.outputs.tag }} release: - timeout-minutes: 60 + needs: [ create-tag, validate ] runs-on: ubuntu-20.04 + timeout-minutes: 30 environment: release steps: - uses: actions/checkout@v4 with: - token: ${{ secrets.SERVICE_ACCOUNT_TOKEN }} - fetch-depth: '0' - - name: Set up JDK ${{ env.JAVA_VERSION }} - uses: actions/setup-java@v4.1.0 + ref: ${{ needs.create-tag.outputs.tag }} + - uses: ./.github/actions/common with: - distribution: ${{ env.JAVA_DISTRO }} - java-version: ${{ env.JAVA_VERSION }} - cache: maven - - name: Release - env: - GPG_PASSPHRASE: ${{ secrets.HELIDON_GPG_PASSPHRASE }} - GPG_PRIVATE_KEY: ${{ secrets.HELIDON_GPG_PRIVATE_KEY }} - GPG_PUBLIC_KEY: ${{ secrets.HELIDON_GPG_PUBLIC_KEY }} + GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} + GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} MAVEN_SETTINGS: ${{ secrets.MAVEN_SETTINGS }} - RELEASE_WORKFLOW: "true" - run: | - git config user.email "helidon-robot_ww@oracle.com" - git config user.name "Helidon Robot" - etc/scripts/release.sh release_build - - name: Upload Staged Artifacts - uses: actions/upload-artifact@v4 - with: - name: io-helidon-artifacts-${{ github.ref_name }} - path: parent/target/nexus-staging/ - retention-days: 90 + build-cache: read-only + artifact-name: io-helidon-artifacts-${{ github.ref_name }} + artifact-path: target/nexus-staging/ + run: etc/scripts/release.sh release_build diff --git a/.github/workflows/snapshot.yaml b/.github/workflows/snapshot.yaml new file mode 100644 index 00000000000..c3c2cb83afc --- /dev/null +++ b/.github/workflows/snapshot.yaml @@ -0,0 +1,48 @@ +# +# Copyright (c) 2024 Oracle and/or its affiliates. +# +# Licensed 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. + +name: "Snapshot Release" + +on: + workflow_dispatch: + workflow_call: + +env: + JAVA_VERSION: '21' + JAVA_DISTRO: 'oracle' + MAVEN_ARGS: | + -B -e + -Dmaven.wagon.httpconnectionManager.ttlSeconds=60 + -Dmaven.wagon.http.retryHandler.count=3 + -Djdk.toolchain.version=${JAVA_VERSION} + +concurrency: + group: release-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + +jobs: + deploy: + timeout-minutes: 60 + runs-on: ubuntu-20.04 + environment: release + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: '0' + - uses: ./.github/actions/common + with: + MAVEN_SETTINGS: ${{ secrets.MAVEN_SETTINGS }} + build-cache: read-only + run: etc/scripts/release.sh deploy_snapshot diff --git a/.github/workflows/snapshotrelease.yaml b/.github/workflows/snapshotrelease.yaml deleted file mode 100644 index d32f67eee92..00000000000 --- a/.github/workflows/snapshotrelease.yaml +++ /dev/null @@ -1,40 +0,0 @@ -# Perform a snapshot build and deploy to snapshot repository -# Notes -# - cannot run on Windows, as we use shell scripts - -name: "Snapshot Release" - -on: - workflow_dispatch: - workflow_call: - -env: - JAVA_VERSION: '21' - JAVA_DISTRO: 'oracle' - MAVEN_HTTP_ARGS: '-Dmaven.wagon.httpconnectionManager.ttlSeconds=60 -Dmaven.wagon.http.retryHandler.count=3' - -concurrency: - group: release-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: false - -jobs: - deploy: - timeout-minutes: 60 - runs-on: ubuntu-20.04 - environment: release - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: '0' - - name: Set up JDK ${{ env.JAVA_VERSION }} - uses: actions/setup-java@v4.1.0 - with: - distribution: ${{ env.JAVA_DISTRO }} - java-version: ${{ env.JAVA_VERSION }} - cache: maven - - name: Build and deploy - env: - MAVEN_SETTINGS: ${{ secrets.MAVEN_SETTINGS }} - RELEASE_WORKFLOW: "true" - run: | - etc/scripts/release.sh deploy_snapshot diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index d8c4c31993c..b09432d36a5 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -1,6 +1,17 @@ -# Notes -# - cannot run on Windows, as we use shell scripts -# - removed macos from most jobs to speed up the process +# +# Copyright (c) 2023, 2024 Oracle and/or its affiliates. +# +# Licensed 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. name: "Validate" @@ -10,195 +21,282 @@ on: branches-ignore: [ 'main', 'helidon-*.x', 'release-*' ] tags-ignore: [ '**' ] workflow_call: + inputs: + ref: + description: The branch, tag or SHA to checkout + required: false + type: string + default: '' env: - JAVA_VERSION: '21' - JAVA_DISTRO: 'oracle' + JAVA_VERSION: 21 + JAVA_DISTRO: oracle MAVEN_ARGS: | -B -fae -e -Dmaven.wagon.httpconnectionManager.ttlSeconds=60 -Dmaven.wagon.http.retryHandler.count=3 + -Djdk.toolchain.version=${JAVA_VERSION} + -Dcache.enabled=true concurrency: - group: Validate-${{ github.ref }} + group: validate-${{ github.ref }} cancel-in-progress: true jobs: copyright: - timeout-minutes: 10 + timeout-minutes: 5 runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Set up JDK ${{ env.JAVA_VERSION }} - uses: actions/setup-java@v4.1.0 - with: - distribution: ${{ env.JAVA_DISTRO }} - java-version: ${{ env.JAVA_VERSION }} - cache: maven - - name: Copyright - run: etc/scripts/copyright.sh + - uses: actions/checkout@v4 + with: + ref: ${{ inputs.ref }} + fetch-depth: 0 + - uses: ./.github/actions/common + with: + run: etc/scripts/copyright.sh checkstyle: - timeout-minutes: 10 + timeout-minutes: 5 runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v4 - - name: Set up JDK ${{ env.JAVA_VERSION }} - uses: actions/setup-java@v4.1.0 with: - distribution: ${{ env.JAVA_DISTRO }} - java-version: ${{ env.JAVA_VERSION }} - cache: maven - - name: Checkstyle - run: etc/scripts/checkstyle.sh + ref: ${{ inputs.ref }} + - uses: ./.github/actions/common + with: + run: etc/scripts/checkstyle.sh shellcheck: timeout-minutes: 5 runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v4 - - name: ShellCheck - run: etc/scripts/shellcheck.sh - spotbugs: - timeout-minutes: 45 + with: + ref: ${{ inputs.ref }} + - uses: ./.github/actions/common + with: + maven-cache: none + run: etc/scripts/shellcheck.sh + build: + timeout-minutes: 15 runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v4 - - name: Set up JDK ${{ env.JAVA_VERSION }} - uses: actions/setup-java@v4.1.0 with: - distribution: ${{ env.JAVA_DISTRO }} - java-version: ${{ env.JAVA_VERSION }} - cache: maven - - name: Spotbugs - run: | - mvn ${MAVEN_ARGS} -e \ - -DskipTests \ - -Dmaven.test.skip=true \ - -Pspotbugs \ - install - docs: + ref: ${{ inputs.ref }} + - uses: ./.github/actions/common + with: + build-cache: read-write + maven-cache: read-write + run: | + mvn ${MAVEN_ARGS} build-cache:go-offline + mvn ${MAVEN_ARGS} -T8 \ + -Dorg.slf4j.simpleLogger.showThreadName=true \ + -DskipTests \ + -Ptests \ + install + _tests: + needs: build + timeout-minutes: 30 + strategy: + matrix: + os: [ ubuntu-20.04 ] + moduleSet: [ core, it, jpa, jpa-oracle, dbclient, dbclient-oracle, others ] + include: + - { os: ubuntu-20.04, platform: linux } + runs-on: ${{ matrix.os }} + name: tests/${{ matrix.moduleSet }} + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ inputs.ref }} + - uses: ./.github/actions/common + with: + build-cache: read-only + test-artifact-name: tests-${{ matrix.moduleSet }} + run: | + mvn ${MAVEN_ARGS} \ + -DreactorRule=tests \ + -DmoduleSet=${{ matrix.moduleSet }} \ + -Dsurefire.reportNameSuffix=${{ matrix.platform }} \ + verify + _tck: + needs: build timeout-minutes: 30 + strategy: + matrix: + moduleSet: [ cdi, rest, others ] runs-on: ubuntu-20.04 + name: tests/tck-${{ matrix.moduleSet }} steps: - uses: actions/checkout@v4 - - name: Set up JDK ${{ env.JAVA_VERSION }} - uses: actions/setup-java@v4.1.0 with: - distribution: ${{ env.JAVA_DISTRO }} - java-version: ${{ env.JAVA_VERSION }} - cache: maven - - name: Docs - run: | - mvn ${MAVEN_ARGS} \ - -DskipTests \ - install - mvn ${MAVEN_ARGS} \ - -f docs/pom.xml \ - -Pjavadoc \ - install - build: - timeout-minutes: 60 + ref: ${{ inputs.ref }} + - uses: ./.github/actions/common + with: + build-cache: read-only + test-artifact-name: tests-tck-${{ matrix.moduleSet }} + run: | + mvn ${MAVEN_ARGS} \ + -DreactorRule=tck \ + -DmoduleSet=${{ matrix.moduleSet }} \ + verify + _spotbugs: + needs: build + timeout-minutes: 30 strategy: matrix: - os: [ ubuntu-20.04 ] - runs-on: ${{ matrix.os }} + moduleSet: [ core, integrations, others ] + runs-on: ubuntu-20.04 + name: spotbugs/${{ matrix.moduleSet }} steps: - uses: actions/checkout@v4 - - name: Set up JDK ${{ env.JAVA_VERSION }} - uses: actions/setup-java@v4.1.0 with: - distribution: ${{ env.JAVA_DISTRO }} - java-version: ${{ env.JAVA_VERSION }} - cache: maven - - name: Maven build - run: | - mvn ${MAVEN_ARGS} \ - -Dmaven.test.failure.ignore=false \ - -Pjavadoc,sources,tests \ - install - examples: - timeout-minutes: 40 + ref: ${{ inputs.ref }} + - uses: ./.github/actions/common + with: + build-cache: read-only + run: | + mvn ${MAVEN_ARGS} -T8 \ + -Dorg.slf4j.simpleLogger.showThreadName=true \ + -DreactorRule=default \ + -DmoduleSet=${{ matrix.moduleSet }} \ + -DskipTests \ + -Pspotbugs \ + verify + javadoc: + needs: build + timeout-minutes: 30 + strategy: + matrix: + moduleSet: [ core, integrations, others ] + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ inputs.ref }} + - uses: ./.github/actions/common + with: + build-cache: read-only + run: | + mvn ${MAVEN_ARGS} -T8 \ + -Dorg.slf4j.simpleLogger.showThreadName=true \ + -DreactorRule=default \ + -DmoduleSet=${{ matrix.moduleSet }} \ + -DskipTests \ + -Pjavadoc \ + package + docs: + needs: build + timeout-minutes: 15 + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ inputs.ref }} + - uses: ./.github/actions/common + with: + build-cache: read-only + run: | + mvn ${MAVEN_ARGS} \ + -f docs/pom.xml \ + -Pjavadoc \ + install + quickstarts: + needs: build + timeout-minutes: 30 strategy: matrix: os: [ ubuntu-20.04, macos-14 ] + include: + - { os: ubuntu-20.04, platform: linux } + - { os: macos-14, platform: macos } runs-on: ${{ matrix.os }} + name: quickstarts/${{ matrix.platform }} steps: - uses: actions/checkout@v4 - - name: Set up JDK ${{ env.JAVA_VERSION }} - uses: actions/setup-java@v4.1.0 with: - distribution: ${{ env.JAVA_DISTRO }} - java-version: ${{ env.JAVA_VERSION }} - cache: maven - - uses: graalvm/setup-graalvm@v1 + ref: ${{ inputs.ref }} + - uses: ./.github/actions/common with: - java-version: ${{ env.JAVA_VERSION }} - distribution: graalvm-community - github-token: ${{ secrets.GITHUB_TOKEN }} - native-image-job-reports: true - cache: maven - - name: Maven build - run: | - # prime build - mvn ${MAVEN_ARGS} -T8 \ - -DskipTests \ - install - - name: Examples build - run: etc/scripts/build-examples.sh - - name: Test quickstarts native image - run: etc/scripts/test-quickstarts.sh - mp-tck: - timeout-minutes: 60 + free-space: true + build-cache: read-only + native-image: true + test-artifact-name: tests-quickstarts-${{ matrix.platform }} + run: | + etc/scripts/test-quickstarts.sh + examples: + needs: build + timeout-minutes: 30 strategy: matrix: - os: [ ubuntu-20.04 ] + os: [ ubuntu-20.04, macos-14 ] include: - { os: ubuntu-20.04, platform: linux } + - { os: macos-14, platform: macos } runs-on: ${{ matrix.os }} - name: tests/tck-${{ matrix.platform }} + name: examples/${{ matrix.platform }} steps: - uses: actions/checkout@v4 - - name: Set up JDK ${{ env.JAVA_VERSION }} - uses: actions/setup-java@v4.1.0 with: - distribution: ${{ env.JAVA_DISTRO }} - java-version: ${{ env.JAVA_VERSION }} - cache: maven - - name: Maven build - run: | - # prime build - mvn ${MAVEN_ARGS} -T8 \ - -DskipTests \ - install - mvn ${MAVEN_ARGS} \ - -f microprofile/tests/tck/pom.xml \ - -Ptck-ft \ - verify + ref: ${{ inputs.ref }} + - uses: ./.github/actions/common + with: + free-space: true + build-cache: read-only + test-artifact-name: tests-examples-${{ matrix.platform }} + run: etc/scripts/build-examples.sh archetypes: - timeout-minutes: 45 + needs: build + timeout-minutes: 30 strategy: matrix: - os: [ ubuntu-20.04 ] - runs-on: ${{ matrix.os }} + group: [ r1, r2, r3, r4, r5 ] + packaging: [ jar ] + include: + - { group: r1, start: 1, end: 25 } + - { group: r2, start: 26, end: 50 } + - { group: r3, start: 51, end: 75 } + - { group: r4, start: 75, end: 100 } + - { group: r5, start: 101, end: -1 } + - { packaging: jar } + runs-on: ubuntu-20.04 + name: archetypes/${{ matrix.group }}-${{ matrix.packaging }} steps: - uses: actions/checkout@v4 - - name: Set up JDK ${{ env.JAVA_VERSION }} - uses: actions/setup-java@v4.1.0 with: - distribution: ${{ env.JAVA_DISTRO }} - java-version: ${{ env.JAVA_VERSION }} - cache: maven - - name: Test archetypes - run: | - # prime build - mvn ${MAVEN_ARGS} -T8 \ - -DskipTests \ - install - mvn ${MAVEN_ARGS} -e \ - -f archetypes/pom.xml \ - install + ref: ${{ inputs.ref }} + - uses: ./.github/actions/common + with: + build-cache: read-only + native-image: ${{ matrix.packaging == 'native' }} + test-artifact-name: tests-archetypes-${{ matrix.group }}-${{ matrix.packaging }} + run: | + mvn ${MAVEN_ARGS} \ + -f archetypes/archetypes/pom.xml \ + -Darchetype.test.permutationStartIndex=${{ matrix.start }} \ + -Darchetype.test.permutationEndIndex=${{ matrix.end }} \ + -Darchetype.test.testGoal=verify \ + -Darchetype.test.testProfiles=${{ matrix.profile }} \ + verify + legacy-archetypes: + needs: build + timeout-minutes: 30 + runs-on: ubuntu-20.04 + name: archetypes/legacy + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ inputs.ref }} + - uses: ./.github/actions/common + with: + build-cache: read-only + test-artifact-name: tests-legacy-archetypes + run: | + mvn ${MAVEN_ARGS} \ + -f archetypes/pom.xml \ + -Darchetype.test.generatePermutations=false \ + install packaging: + needs: build timeout-minutes: 30 strategy: matrix: @@ -213,32 +311,18 @@ jobs: - uses: actions/checkout@v4 with: ref: ${{ inputs.ref }} - - name: Set up JDK ${{ env.JAVA_VERSION }} - uses: actions/setup-java@v4.1.0 + - uses: ./.github/actions/common with: - distribution: ${{ env.JAVA_DISTRO }} - java-version: ${{ env.JAVA_VERSION }} - cache: maven - - name: Free Space - shell: bash - run: | - # See https://github.com/actions/runner-images/issues/2840 - sudo rm -rf /usr/share/dotnet - sudo rm -rf /usr/local/share/powershell - - name: Build Helidon - run: | - # prime build - mvn ${MAVEN_ARGS} -T4 \ - -DskipTests \ - -Ptests \ - install - - name: Run Test - run: | + free-space: true + build-cache: read-only + test-artifact-name: tests-packaging-${{ matrix.packaging }}-${{ matrix.platform }} + run: | mvn ${MAVEN_ARGS} \ -f tests/integration/packaging/pom.xml \ -P${{ matrix.packaging }}-image \ verify - native-image: + _native-image: + needs: build timeout-minutes: 30 strategy: matrix: @@ -253,76 +337,31 @@ jobs: - uses: actions/checkout@v4 with: ref: ${{ inputs.ref }} - - uses: graalvm/setup-graalvm@v1 + - uses: ./.github/actions/common with: - java-version: ${{ env.JAVA_VERSION }} - distribution: graalvm-community - github-token: ${{ secrets.GITHUB_TOKEN }} - native-image-job-reports: true - cache: maven - - name: Free Space - shell: bash - run: | - # See https://github.com/actions/runner-images/issues/2840 - sudo rm -rf /usr/share/dotnet - sudo rm -rf /usr/local/share/powershell - - name: Build Helidon - run: | - # prime build - mvn ${MAVEN_ARGS} -T4 \ - -DskipTests \ - -Ptests \ - install - - name: Run Test - run: | - mvn ${MAVEN_ARGS} -e \ - -f tests/integration/packaging/pom.xml \ - -pl ${{ matrix.module }} \ - -Pnative-image \ - -am \ - verify - dbclient: - timeout-minutes: 60 - strategy: - matrix: - os: [ ubuntu-20.04 ] - group: [ oracle, others ] - include: - - { group: others, modules: '!oracle' } - - { os: ubuntu-20.04, platform: linux } - runs-on: ${{ matrix.os }} - name: tests/dbclient-${{ matrix.group }}-${{ matrix.platform }} + free-space: true + build-cache: read-only + native-image: true + test-artifact-name: tests-native-image-${{ matrix.module }}-${{ matrix.platform }} + run: | + mvn ${MAVEN_ARGS} \ + -f tests/integration/packaging/pom.xml \ + -pl ${{ matrix.module }} \ + -Pnative-image \ + -am \ + verify + test-results: + runs-on: ubuntu-20.04 + needs: [ _tests, archetypes, legacy-archetypes, _tck, packaging, _native-image ] + name: tests/results steps: - - uses: actions/checkout@v4 - - name: Set up JDK ${{ env.JAVA_VERSION }} - uses: actions/setup-java@v4.1.0 + - uses: actions/upload-artifact/merge@v4 with: - distribution: ${{ env.JAVA_DISTRO }} - java-version: ${{ env.JAVA_VERSION }} - cache: maven - - name: Free Space - shell: bash - run: | - # See https://github.com/actions/runner-images/issues/2840 - sudo rm -rf /usr/share/dotnet - sudo rm -rf /usr/local/share/powershell - - name: Build Helidon - run: | - # prime build - mvn ${MAVEN_ARGS} -T4 \ - -DskipTests \ - -Ptests \ - install - - name: Run Tests - run: | - mvn ${MAVEN_ARGS} \ - -f tests/integration/dbclient/pom.xml \ - -pl ${{ matrix.modules || matrix.group }} \ - -am \ - verify + name: test-results + pattern: "tests-*" gate: runs-on: ubuntu-20.04 - needs: [ copyright, checkstyle, shellcheck, build, docs, spotbugs, packaging, native-image, dbclient, archetypes, mp-tck ] + needs: [ copyright, checkstyle, shellcheck, docs, javadoc, _spotbugs, test-results ] steps: - shell: bash run: | diff --git a/.mvn/cache-config.xml b/.mvn/cache-config.xml new file mode 100644 index 00000000000..3ec832585ba --- /dev/null +++ b/.mvn/cache-config.xml @@ -0,0 +1,133 @@ + + + + false + + + + .*/** + etc/** + + + + + *@copy-libs + + + + + + tests + + + + + webserver/** + webclient/** + common/** + config/** + security/** + + + + + tests/integration/jpa/oracle/** + + + + + tests/integration/jpa/** + + + + + tests/integration/dbclient/oracle/** + + + + + tests/integration/dbclient/** + + + + + tests/integration/** + + + tests/integration/packaging/** + + + + + **/* + + + tests/benchmark/** + tests/integration/packaging/** + + + + + + + tck + + + + + microprofile/tests/tck/tck-cdi*/** + + + + + microprofile/tests/tck/tck-rest*/** + + + + + microprofile/tests/tck/** + + + + + + + + + webserver/** + webclient/** + common/** + config/** + security/** + + + + + integrations/** + + + + + **/* + + + + + + diff --git a/tests/integration/jpa/model/src/main/resources/META-INF/beans.xml b/.mvn/extensions.xml similarity index 54% rename from tests/integration/jpa/model/src/main/resources/META-INF/beans.xml rename to .mvn/extensions.xml index e1f8b242429..31a57c82dbb 100644 --- a/tests/integration/jpa/model/src/main/resources/META-INF/beans.xml +++ b/.mvn/extensions.xml @@ -1,7 +1,7 @@ - - + + + io.helidon.build-tools + helidon-build-cache-maven-extension + 4.0.9 + + + diff --git a/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/MPTest.java b/microprofile/testing/junit5/src/main/java/io/helidon/microprofile/testing/junit5/AddConfigMap.java similarity index 65% rename from tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/MPTest.java rename to microprofile/testing/junit5/src/main/java/io/helidon/microprofile/testing/junit5/AddConfigMap.java index 16cb4c98184..3dcea214517 100644 --- a/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/MPTest.java +++ b/microprofile/testing/junit5/src/main/java/io/helidon/microprofile/testing/junit5/AddConfigMap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023 Oracle and/or its affiliates. + * Copyright (c) 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,18 +13,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.helidon.tests.integration.jpa.appl; + +package io.helidon.microprofile.testing.junit5; import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * Test method annotation. - * This is security enhancement which restricts methods invoked by Dispatcher only to those with this annotation. + * Identifies static methods of which the values should be added to MicroProfile configuration. + * The return type of the annotated methods must be of type {@code Map}. */ @Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface MPTest { +@Target({ElementType.METHOD}) +@Inherited +public @interface AddConfigMap { } + diff --git a/microprofile/testing/junit5/src/main/java/io/helidon/microprofile/testing/junit5/HelidonJunitExtension.java b/microprofile/testing/junit5/src/main/java/io/helidon/microprofile/testing/junit5/HelidonJunitExtension.java index 5599a1bc9fe..c877d02ef31 100644 --- a/microprofile/testing/junit5/src/main/java/io/helidon/microprofile/testing/junit5/HelidonJunitExtension.java +++ b/microprofile/testing/junit5/src/main/java/io/helidon/microprofile/testing/junit5/HelidonJunitExtension.java @@ -25,11 +25,14 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Executable; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.net.URL; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; +import java.util.Deque; import java.util.Enumeration; import java.util.HashMap; import java.util.List; @@ -110,7 +113,6 @@ class HelidonJunitExtension implements BeforeAllCallback, private SeContainer container; - @SuppressWarnings("unchecked") @Override public void beforeAll(ExtensionContext context) { testClass = context.getRequiredTestClass(); @@ -154,6 +156,7 @@ public void beforeAll(ExtensionContext context) { classLevelBeans.add(WeldRequestScopeLiteral.INSTANCE); } + addConfigMaps(); configure(classLevelConfigMeta); if (!classLevelConfigMeta.useExisting) { @@ -188,7 +191,7 @@ private T[] getAnnotations(Class testClass, Class a } @Override - public void beforeEach(ExtensionContext context) throws Exception { + public void beforeEach(ExtensionContext context) { if (resetPerTest) { Method method = context.getRequiredTestMethod(); AddConfig[] configs = method.getAnnotationsByType(AddConfig.class); @@ -219,13 +222,14 @@ public void beforeEach(ExtensionContext context) throws Exception { } @Override - public void afterEach(ExtensionContext context) throws Exception { + public void afterEach(ExtensionContext context) { if (resetPerTest) { releaseConfig(); stopContainer(); } } + @SuppressWarnings("ExtractMethodRecommender") private void validatePerClass() { Method[] methods = testClass.getMethods(); for (Method method : methods) { @@ -270,6 +274,7 @@ private boolean hasHelidonTestAnnotation(AnnotatedElement element) { return false; } + @SuppressWarnings("ExtractMethodRecommender") private void validatePerTest() { Constructor[] constructors = testClass.getConstructors(); if (constructors.length > 1) { @@ -337,6 +342,35 @@ private void configure(ConfigMeta configMeta) { configProviderResolver.registerConfig(config, Thread.currentThread().getContextClassLoader()); } } + + private void addConfigMaps() { + Deque> stack = new ArrayDeque<>(); + stack.push(testClass); + while (!stack.isEmpty()) { + Class clazz = stack.pop(); + try { + for (Method method : clazz.getDeclaredMethods()) { + if (Modifier.isStatic(method.getModifiers()) && method.isAnnotationPresent(AddConfigMap.class)) { + method.setAccessible(true); + Object value = method.invoke(null); + if (value instanceof Map map) { + classLevelConfigMeta.addConfigMap(map); + } + } + } + } catch (InvocationTargetException | IllegalAccessException e) { + throw new RuntimeException(e); + } + Class superclass = clazz.getSuperclass(); + if (superclass != null) { + stack.push(superclass); + } + for (Class interfaceClass : clazz.getInterfaces()) { + stack.push(interfaceClass); + } + } + } + private void releaseConfig() { if (configProviderResolver != null && config != null) { configProviderResolver.releaseConfig(config); @@ -400,11 +434,12 @@ public T interceptTestClassConstructor(Invocation invocation, if (container == null) { // at this early stage the class should be checked whether it is annotated with // @TestInstance(TestInstance.Lifecycle.PER_CLASS) to start correctly the container + Class testClass = extensionContext.getRequiredTestClass(); TestInstance testClassAnnotation = testClass.getAnnotation(TestInstance.class); if (testClassAnnotation != null && testClassAnnotation.value().equals(TestInstance.Lifecycle.PER_CLASS)){ throw new RuntimeException("When a class is annotated with @HelidonTest, " + "it is not compatible with @TestInstance(TestInstance.Lifecycle.PER_CLASS)" - + "annotation, as it is a Singleton CDI Bean."); + + " annotation, as it is a Singleton CDI Bean."); } startContainer(classLevelBeans, classLevelExtensions, classLevelDisableDiscovery); } @@ -444,11 +479,8 @@ public boolean supportsParameter(ParameterContext parameterContext, ExtensionCon if (paramType.equals(SeContainer.class)) { return true; } - if (paramType.equals(WebTarget.class)) { - return true; - } + return paramType.equals(WebTarget.class); } - return false; } @@ -518,7 +550,7 @@ private AddBeansExtension(Class testClass, List addBeans) { } - void processSocketInjectionPoints(@Observes ProcessInjectionPoint event) throws Exception{ + void processSocketInjectionPoints(@Observes ProcessInjectionPoint event) { InjectionPoint injectionPoint = event.getInjectionPoint(); Set qualifiers = injectionPoint.getQualifiers(); for (Annotation qualifier : qualifiers) { @@ -533,17 +565,16 @@ void processSocketInjectionPoints(@Observes ProcessInjectionPoint void registerOtherBeans(@Observes AfterBeanDiscovery event) { + @SuppressWarnings("resource") Client client = ClientBuilder.newClient(); //register for all named Ports - socketAnnotations.forEach((namedPort, qualifier) -> { - - event.addBean() - .addType(WebTarget.class) - .scope(ApplicationScoped.class) - .qualifiers(qualifier) - .createWith(context -> getWebTarget(client, namedPort)); - }); + socketAnnotations.forEach((namedPort, qualifier) -> event + .addBean() + .addType(WebTarget.class) + .scope(ApplicationScoped.class) + .qualifiers(qualifier) + .createWith(context -> getWebTarget(client, namedPort))); event.addBean() .addType(jakarta.ws.rs.client.WebTarget.class) @@ -592,7 +623,7 @@ void registerAddedBeans(@Observes BeforeBeanDiscovery event) { } private boolean hasBda(Class value) { - // does it have bean defining annotation? + // does it have a "bean defining annotation"? for (Class aClass : BEAN_DEFINING.keySet()) { if (value.getAnnotation(aClass) != null) { return true; @@ -649,6 +680,15 @@ private void addConfigBlock(AddConfigBlock config) { this.block = config.value(); } + private void addConfigMap(Map map) { + map.forEach((k, v) -> { + String key = k.toString(); + if (v != null) { + additionalKeys.put(key, v.toString()); + } + }); + } + ConfigMeta nextMethod() { ConfigMeta methodMeta = new ConfigMeta(); @@ -747,5 +787,4 @@ public Class value() { return CdiComponentProvider.class; } } - } diff --git a/microprofile/tests/tck/pom.xml b/microprofile/tests/tck/pom.xml index 4932cc40478..c8f100ccb74 100644 --- a/microprofile/tests/tck/pom.xml +++ b/microprofile/tests/tck/pom.xml @@ -53,6 +53,7 @@ tck-jsonp tck-inject tck-annotations + tck-fault-tolerance @@ -61,13 +62,4 @@ --> true - - - - tck-ft - - tck-fault-tolerance - - - diff --git a/parent/pom.xml b/parent/pom.xml index 92c4f131e8e..54ff43b2702 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -192,6 +192,11 @@ versions-maven-plugin ${version.plugin.versions} + + io.helidon.build-tools + helidon-build-cache-maven-plugin + 4.0.9 + diff --git a/pom.xml b/pom.xml index 8e211c55dd1..8a102100c9f 100644 --- a/pom.xml +++ b/pom.xml @@ -119,6 +119,7 @@ 2.3 4.0.9 ${version.lib.hibernate} + 3.1.2 0.8.5 3.1.2 3.3.0 @@ -560,6 +561,11 @@ + + org.apache.maven.plugins + maven-install-plugin + ${version.plugin.install} + org.apache.maven.plugins maven-scm-publish-plugin @@ -843,6 +849,7 @@ + org.apache.maven.plugins maven-antrun-plugin ${version.plugin.ant} @@ -1384,8 +1391,10 @@ - check + spotbugs + verify + verify diff --git a/tests/functional/request-scope/src/test/java/io/helidon/tests/functional/requestscope/TenantTest.java b/tests/functional/request-scope/src/test/java/io/helidon/tests/functional/requestscope/TenantTest.java index 97a02ceef94..c170358f8fa 100644 --- a/tests/functional/request-scope/src/test/java/io/helidon/tests/functional/requestscope/TenantTest.java +++ b/tests/functional/request-scope/src/test/java/io/helidon/tests/functional/requestscope/TenantTest.java @@ -17,6 +17,7 @@ package io.helidon.tests.functional.requestscope; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import io.helidon.faulttolerance.Async; @@ -27,6 +28,7 @@ import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; @@ -40,18 +42,21 @@ class TenantTest { private WebTarget baseTarget; @Test + @Timeout(value = 1, unit = TimeUnit.MINUTES) public void test() throws Exception { asyncCalls(() -> baseTarget.path("test").request() .header("x-tenant-id", "123").get(), null); } @Test + @Timeout(value = 1, unit = TimeUnit.MINUTES) public void test2() throws Exception { asyncCalls(() -> baseTarget.path("test2").request() .header("x-tenant-id", "123").get(), null); } @Test + @Timeout(value = 1, unit = TimeUnit.MINUTES) public void test3() throws Exception { asyncCalls(() -> baseTarget.path("test3").queryParam("param1", "1").request() .header("x-tenant-id", "123").get(), "1"); diff --git a/tests/integration/jpa/appl/pom.xml b/tests/integration/jpa/appl/pom.xml deleted file mode 100644 index 7c6c69c2805..00000000000 --- a/tests/integration/jpa/appl/pom.xml +++ /dev/null @@ -1,506 +0,0 @@ - - - - - 4.0.0 - - - io.helidon.applications - helidon-mp - 4.1.0-SNAPSHOT - ../../../../applications/mp/pom.xml - - - io.helidon.tests.integration.jpa - helidon-tests-integration-jpa-appl - Helidon Tests Integration JPA MP Application - - - io.helidon.microprofile.cdi.Main - org.h2.tools.Server - 0.34.1 - - - - - io.helidon.tests.integration.jpa - helidon-tests-integration-jpa-model - ${project.version} - - - io.helidon.microprofile.server - helidon-microprofile-server - - - io.helidon.config - helidon-config-yaml - - - io.helidon.microprofile.config - helidon-microprofile-config - - - io.helidon.integrations.cdi - helidon-integrations-cdi-hibernate - compile - - - io.helidon.integrations.cdi - helidon-integrations-cdi-jta-weld - compile - - - io.helidon.integrations.cdi - helidon-integrations-cdi-jta - compile - - - io.helidon.integrations.cdi - helidon-integrations-cdi-delegates - runtime - - - io.helidon.integrations.cdi - helidon-integrations-cdi-datasource-hikaricp - runtime - - - io.helidon.integrations.cdi - helidon-integrations-cdi-jpa - runtime - - - jakarta.persistence - jakarta.persistence-api - compile - - - jakarta.transaction - jakarta.transaction-api - compile - - - jakarta.json - jakarta.json-api - compile - - - io.smallrye - jandex - runtime - - - org.slf4j - slf4j-jdk14 - runtime - - - org.junit.jupiter - junit-jupiter-api - test - - - org.hamcrest - hamcrest-all - test - - - io.helidon.logging - helidon-logging-jul - test - - - - - - - ${basedir}/src/main/resources/META-INF - META-INF - - microprofile-config.properties - persistence.xml - - true - - - ${basedir}/src/main/resources - - META-INF/microprofile-config.properties - META-INF/persistence.xml - - - - - - - io.fabric8 - docker-maven-plugin - ${version.plugin.docker-maven-plugin} - - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - io.smallrye - jandex-maven-plugin - - - org.hibernate.orm.tooling - hibernate-enhance-maven-plugin - - - - true - true - true - - - enhance - - - - - - org.apache.maven.plugins - maven-jar-plugin - ${version.plugin.jar} - - - - true - libs - ${mainClass} - false - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - true - - - - org.apache.maven.plugins - maven-failsafe-plugin - - methods - 10 - - true - ${db.user} - ${db.password} - ${db.url} - - - - - test - integration-test - - integration-test - verify - - - - io.helidon.tests.integration.jpa.appl.test.*IT - - - - - - - - - - - - - !native-image - - - java-image - - - - org.codehaus.mojo - exec-maven-plugin - - - app - pre-integration-test - - exec - - - java - - -classpath - - ${mainClass} - - true - - - - - - - - - - - native-image - - - native-image - - - - org.codehaus.mojo - exec-maven-plugin - - - app - pre-integration-test - - exec - - - ${project.build.directory}/${project.artifactId} - true - - - - - - - - - docker - - - - io.fabric8 - docker-maven-plugin - - - - start - package - - start - - - - stop - post-integration-test - - stop - - - - - - - - - - - h2 - - - !db - - - - 9092 - localhost - test - sa - - jdbc:h2:mem:test;INIT=SET TRACE_LEVEL_FILE=4 - org.hibernate.dialect.H2Dialect - org.h2.jdbcx.JdbcDataSource - - - - io.helidon.integrations.db - h2 - - - com.h2database - h2 - runtime - - - - - mysql - - - db - mysql - - - - 3306 - 127.0.0.1 - pokemon - useSSL=false&allowPublicKeyRetrieval=true - user - password - root - jdbc:mysql://${db.host}:${db.port}/${db.database}?${db.args} - org.hibernate.dialect.MySQL8Dialect - com.mysql.cj.jdbc.MysqlDataSource - com.mysql.cj.jdbc.Driver - - - - io.helidon.integrations.db - helidon-integrations-db-mysql - ${project.version} - - - com.mysql - mysql-connector-j - runtime - - - - - - io.fabric8 - docker-maven-plugin - - - - mysql:8 - mysql - - - ${db.user} - ${db.password} - ${db.roootpw} - ${db.database} - - ${db.host} - - ${db.host}:${db.port}:3306 - - - - - MySQL init process done. Ready for start up. - - - - - true - false - - - - - - - pgsql - - - db - pgsql - - - - 5432 - 127.0.0.1 - pokemon - user - password - jdbc:postgresql://${db.host}:${db.port}/${db.database} - org.hibernate.dialect.PostgreSQLDialect - org.postgresql.ds.PGSimpleDataSource - org.postgresql.Driver - - - - io.helidon.integrations.db - helidon-integrations-db-pgsql - ${project.version} - - - org.postgresql - postgresql - runtime - - - - - - io.fabric8 - docker-maven-plugin - - - - postgres - postgres - - - ${db.user} - ${db.password} - ${db.database} - - ${db.host} - - ${db.host}:${db.port}:5432 - - - - 127.0.0.1 - - ${db.port} - - - - - - - - true - false - - - - - - - - diff --git a/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/DbUtils.java b/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/DbUtils.java deleted file mode 100644 index 440d44dfb80..00000000000 --- a/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/DbUtils.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.appl; - -import java.util.List; - -import jakarta.persistence.EntityManager; - -import io.helidon.tests.integration.jpa.model.Pokemon; - -/** - * Database utilities. - */ -public class DbUtils { - - private DbUtils() { - throw new UnsupportedOperationException("Instances of DbUtils class are not allowed"); - } - - /** - * Flush Entity manager and clear caches. - * - * @param em Entity manager instance - */ - public static void cleanEm(final EntityManager em) { - em.flush(); - em.clear(); - em.getEntityManagerFactory().getCache().evictAll(); - } - - /** - * Find pokemon by name from pokemon List. - * - * @param pokemons List to search - * @param name name of pokemon - * @return found pokemon or null when no such pokemon exists - */ - public static Pokemon findPokemonByName(List pokemons, String name) { - if (pokemons != null && !pokemons.isEmpty()) { - for (Pokemon pokemon : pokemons) { - if (pokemon.getName().equals(name)) { - return pokemon; - } - } - } - return null; - } - -} diff --git a/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/DeleteIT.java b/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/DeleteIT.java deleted file mode 100644 index bfcd0e58c03..00000000000 --- a/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/DeleteIT.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.appl; - -import java.util.List; - -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.persistence.EntityManager; -import jakarta.persistence.PersistenceContext; -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.CriteriaDelete; -import jakarta.persistence.criteria.CriteriaQuery; -import jakarta.persistence.criteria.Root; - -import io.helidon.tests.integration.jpa.dao.Create; -import io.helidon.tests.integration.jpa.dao.Delete; -import io.helidon.tests.integration.jpa.model.City; -import io.helidon.tests.integration.jpa.model.Pokemon; -import io.helidon.tests.integration.jpa.model.Stadium; -import io.helidon.tests.integration.jpa.model.Trainer; - -/** - * Verify delete operations of ORM (server side). - */ -@ApplicationScoped -public class DeleteIT { - - @PersistenceContext(unitName = "test") - private EntityManager em; - - /** - * Initialize test suite. - * - * @param result test execution result - * @return test execution result - */ - @MPTest - public TestResult setup(TestResult result) { - Create.dbInsertMisty(em); - Create.dbInsertViridian(em); - return result; - } - - /** - * Clean up test suite. - * - * @param result test execution result - * @return test execution result - */ - @MPTest - public TestResult destroy(TestResult result) { - Delete.dbDeleteMisty(em); - Delete.dbDeleteViridian(em); - return result; - } - - /** - * Delete pokemon: release Misty's Staryu. - * Modification is done using entity instance. - * - * @param result test execution result - * @return test execution result - */ - @MPTest - public TestResult testDeleteEntity(TestResult result) { - Pokemon staryu = em.createQuery( - "SELECT p FROM Pokemon p WHERE p.name = :name", Pokemon.class) - .setParameter("name", "Staryu") - .getSingleResult(); - int id = staryu.getId(); - em.remove(staryu); - DbUtils.cleanEm(em); - Pokemon dbStaryu = em.find(Pokemon.class, id); - result.assertNull(dbStaryu); - return result; - } - - /** - * Delete pokemon: release Misty's Psyduck. - * Modification is done using JPQL. - * - * @param result test execution result - * @return test execution result - */ - @MPTest - public TestResult testDeleteJPQL(TestResult result) { - int deleted = em.createQuery( - "DELETE FROM Pokemon p WHERE p.name = :name") - .setParameter("name", "Psyduck") - .executeUpdate(); - result.assertEquals(1, deleted); - DbUtils.cleanEm(em); - List pokemons = em.createQuery( - "SELECT p FROM Pokemon p WHERE p.name=:name", Pokemon.class) - .setParameter("name", "Psyduck") - .getResultList(); - result.assertTrue(pokemons.isEmpty()); - return result; - } - - /** - * Delete pokemon: release Misty's Corsola. - * Modification is done using CriteriaDelete. - * - * @param result test execution result - * @return test execution result - */ - @MPTest - public TestResult testDeleteCriteria(TestResult result) { - CriteriaBuilder cb = em.getCriteriaBuilder(); - CriteriaDelete cu = cb.createCriteriaDelete(Pokemon.class); - Root pokemonRoot = cu.from(Pokemon.class); - cu.where(cb.equal(pokemonRoot.get("name"), "Corsola")); - int deleted = em.createQuery(cu).executeUpdate(); - result.assertEquals(1, deleted); - DbUtils.cleanEm(em); - cb = em.getCriteriaBuilder(); - CriteriaQuery cq = cb.createQuery(Pokemon.class); - pokemonRoot = cq.from(Pokemon.class); - cq.select(pokemonRoot) - .where(cb.equal(pokemonRoot.get("name"), "Corsola")); - List pokemons = em.createQuery(cq).getResultList(); - result.assertTrue(pokemons.isEmpty()); - return result; - } - - /** - * Delete Viridian City. - * - * @param result test execution result - * @return test execution result - */ - @MPTest - public TestResult testDeleteViridianCity(TestResult result) { - City city = em.createQuery( - "SELECT c FROM City c WHERE c.name = :name", City.class) - .setParameter("name", "Viridian City") - .getSingleResult(); - Stadium stadium = city.getStadium(); - Trainer trainer = stadium.getTrainer(); - List pokemons = trainer.getPokemons(); - em.remove(city); - em.remove(trainer); - pokemons.forEach(poklemon -> em.remove(poklemon)); - DbUtils.cleanEm(em); - List cities = em.createQuery( - "SELECT c FROM City c WHERE c.name = :name", City.class) - .setParameter("name", "Viridian City") - .getResultList(); - result.assertTrue(cities.isEmpty()); - return result; - } - -} diff --git a/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/Dispatcher.java b/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/Dispatcher.java deleted file mode 100644 index 579c1ef829e..00000000000 --- a/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/Dispatcher.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (c) 2020, 2023 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.appl; - -import java.lang.System.Logger.Level; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.inject.Inject; - -/** - * Test name and class dispatcher. - */ -@ApplicationScoped -public class Dispatcher { - - private static final System.Logger LOGGER = System.getLogger(Dispatcher.class.getName()); - - /** - * Test invocation handler. - */ - static final class Handle { - - private final Object instance; - private final Method method; - private final TestResult result; - - /** - * Creates an instance of test invocation handler. - * - * @param instance test class instance - * @param method method handler to invoke - * @param result test execution result - */ - Handle(final Object instance, final Method method, final TestResult result) { - if (result == null) { - this.result = new TestResult(); - } else { - this.result = result; - } - this.instance = instance; - this.method = method; - } - - /** - * Invoke test. - * - * @return test execution result - */ - TestResult invoke() { - try { - if (method.getAnnotation(MPTest.class) != null) { - try { - return (TestResult) method.invoke(instance, result); - } catch (InvocationTargetException ie) { - Throwable cause = ie.getCause(); - return result.throwed(cause != null ? cause : ie); - } - } else { - return result.fail("Method is missing MPTest annotation"); - } - } catch (IllegalAccessException | IllegalArgumentException ex) { - result.throwed(ex); - } - return result; - } - - /** - * Get result of test execution. - * - * @return result of test execution - */ - TestResult result() { - return result; - } - - } - - @Inject - private InsertIT insertIt; - - @Inject - private UpdateIT updateIt; - - @Inject - private DeleteIT deleteIt; - - @Inject - private QueryIT queryIt; - - private static Handle createHandle(final Class testClass, final Object instance, final String methodName, final TestResult result) { - try { - return new Handle( - instance, - testClass.getDeclaredMethod(methodName, TestResult.class), - result); - } catch (NoSuchMethodException ex) { - result.throwed(ex); - } - return null; - } - - private Handle getHandle(final String name) { - final int nameLen = name.length(); - final int serpPos = name.indexOf('.'); - final TestResult result = new TestResult(); - result.name(name); - if (serpPos < 0 || (serpPos + 1) >= nameLen) { - result.fail("Invalid test identifier: " + name); - return null; - } - final String className = name.substring(0, serpPos); - final String methodName = name.substring(serpPos + 1, nameLen); - if (null == className) { - result.fail("Unknown test class: " + className); - } else switch (className) { - case "InsertIT": - return createHandle(InsertIT.class, insertIt, methodName, result); - case "UpdateIT": - return createHandle(UpdateIT.class, updateIt, methodName, result); - case "DeleteIT": - return createHandle(DeleteIT.class, deleteIt, methodName, result); - case "QueryIT": - return createHandle(QueryIT.class, queryIt, methodName, result); - default: - result.fail("Unknown test class: " + className); - } - return null; - } - - /** - * Run test identified by it's name ({@code.}). - * - * @param name name of the test - * @return test execution result - */ - public TestResult runTest(final String name) { - Handle handle = getHandle(name); - if (handle == null) { - try { - return handle.result().fail("Missing method handle."); - } catch (Exception ex) { - LOGGER.log(Level.WARNING, () -> String.format("Test %s execution throwed an exception: %s", - name, ex.getMessage())); - throw ex; - } - } - return handle.invoke(); - } - -} diff --git a/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/ExitThread.java b/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/ExitThread.java deleted file mode 100644 index 2f662f42bfc..00000000000 --- a/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/ExitThread.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2020, 2023 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.appl; - -import java.lang.System.Logger.Level; - -/** - * Exits JPA MP application after short delay. - */ -public class ExitThread implements Runnable { - - private static final System.Logger LOGGER = System.getLogger(ExitThread.class.getName()); - - /** - * Starts application exit thread. - */ - public static final void start() { - new Thread(new ExitThread()).start(); - } - - /** - * Wait few seconds and terminate Java VM. - */ - @Override - public void run() { - try { - Thread.sleep(3000); - } catch (InterruptedException ie) { - LOGGER.log(Level.WARNING, () -> String.format("Thread was interrupted: %s", ie.getMessage()), ie); - } finally { - System.exit(0); - } - } - -} diff --git a/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/InsertIT.java b/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/InsertIT.java deleted file mode 100644 index c3c737bb968..00000000000 --- a/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/InsertIT.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.appl; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.persistence.EntityManager; -import jakarta.persistence.PersistenceContext; - -import io.helidon.tests.integration.jpa.model.City; -import io.helidon.tests.integration.jpa.model.Pokemon; -import io.helidon.tests.integration.jpa.model.Stadium; -import io.helidon.tests.integration.jpa.model.Trainer; -import io.helidon.tests.integration.jpa.model.Type; - -/** - * Verify create/insert operations of ORM. - */ -@ApplicationScoped -public class InsertIT { - - private static final Set DELETE_POKEMONS = new HashSet<>(); - private static final Set DELETE_TRAINERS = new HashSet<>(); - private static final Set DELETE_STADIUMS = new HashSet<>(); - private static final Set DELETE_TOWNS = new HashSet<>(); - - @PersistenceContext(unitName = "test") - private EntityManager em; - - /** - * Clean up test suite. - * - * @param result test execution result - * @return test execution result - */ - @MPTest - public TestResult destroy(TestResult result) { - // testInsertType cleanup - em.createQuery("DELETE FROM Type t WHERE t.id = :id") - .setParameter("id", 20) - .executeUpdate(); - // Towns cleanup - DELETE_TOWNS.forEach((id) -> { - em.createQuery("DELETE FROM City c WHERE c.id = :id") - .setParameter("id", id) - .executeUpdate(); - }); - // Stadiums cleanup - DELETE_STADIUMS.forEach((id) -> { - em.createQuery("DELETE FROM Stadium s WHERE s.id = :id") - .setParameter("id", id) - .executeUpdate(); - }); - // Pokemons cleanup - DELETE_POKEMONS.forEach((id) -> { - em.createQuery("DELETE FROM Pokemon p WHERE p.id = :id") - .setParameter("id", id) - .executeUpdate(); - }); - // Trainers cleanup - DELETE_TRAINERS.forEach((id) -> { - em.createQuery("DELETE FROM Trainer t WHERE t.id = :id") - .setParameter("id", id) - .executeUpdate(); - }); - return result; - } - - /** - * Verify simple create operation (persist) on a single database row. - * - * @param result test execution result - * @return test execution result - */ - @MPTest - public TestResult testInsertType(TestResult result) { - Type type = new Type(20, "TestType"); - em.persist(type); - em.flush(); - Type dbType = em.find(Type.class, 20); - result.assertEquals(type, dbType); - return result; - } - - /** - * Verify complex create operation (persist) on a full ORM model (Gary Oak and his 6 pokemons). - * Relations are not marked for cascade persist operation so every entity instance has to be persisted separately. - * - * @param result test execution result - * @return test execution result - */ - @MPTest - public TestResult testInsertTrainerWithPokemons(TestResult result) { - final Pokemon[] pokemons = new Pokemon[6]; - Type normal = em.find(Type.class, 1); - Type flying = em.find(Type.class, 3); - Type poison = em.find(Type.class, 4); - Type fire = em.find(Type.class, 10); - Type water = em.find(Type.class, 11); - Type electric = em.find(Type.class, 13); - final Trainer trainer = new Trainer("Gary Oak", 10); - pokemons[0] = new Pokemon(trainer, "Krabby", 236, Arrays.asList(water)); - pokemons[1] = new Pokemon(trainer, "Nidoran", 251, Arrays.asList(poison)); - pokemons[2] = new Pokemon(trainer, "Eevee", 115, Arrays.asList(normal)); - pokemons[3] = new Pokemon(trainer, "Electivire", 648, Arrays.asList(electric)); - pokemons[4] = new Pokemon(trainer, "Dodrio", 346, Arrays.asList(normal, flying)); - pokemons[5] = new Pokemon(trainer, "Magmar", 648, Arrays.asList(fire)); - em.persist(trainer); - for (Pokemon pokemon : pokemons) { - em.persist(pokemon); - } - DbUtils.cleanEm(em); - Pokemon dbKrabby = em.find(Pokemon.class, pokemons[0].getId()); - Pokemon dbNidoran = em.find(Pokemon.class, pokemons[1].getId()); - Pokemon dbEvee = em.find(Pokemon.class, pokemons[2].getId()); - Pokemon dbElectivire = em.find(Pokemon.class, pokemons[3].getId()); - Pokemon dbDodrio = em.find(Pokemon.class, pokemons[4].getId()); - Pokemon dbMagmar = em.find(Pokemon.class, pokemons[5].getId()); - Trainer dbTrainer = dbKrabby.getTrainer(); - result.assertEquals(pokemons[0], dbKrabby); - result.assertEquals(pokemons[1], dbNidoran); - result.assertEquals(pokemons[2], dbEvee); - result.assertEquals(pokemons[3], dbElectivire); - result.assertEquals(pokemons[4], dbDodrio); - result.assertEquals(pokemons[5], dbMagmar); - result.assertEquals(trainer, dbTrainer); - for (Pokemon pokemon : pokemons) { - DELETE_POKEMONS.add(pokemon.getId()); - } - DELETE_TRAINERS.add(dbTrainer.getId()); - return result; - } - - /** - * Verify complex create operation (persist) on a full ORM model (Lt. Surge in Vermilion City). - * - * @param result test execution result - * @return test execution result - */ - @MPTest - public TestResult testInsertTownWithStadium(TestResult result) { - final Trainer[] trainers = new Trainer[1]; - final Pokemon[] pokemons = new Pokemon[6]; - final Stadium[] stadiums = new Stadium[1]; - final City[] cities = new City[1]; - Type steel = em.find(Type.class, 9); - Type electric = em.find(Type.class, 13); - trainers[0] = new Trainer("Lt. Surge", 28); - pokemons[0] = new Pokemon(trainers[0], "Raichu", 1521, Arrays.asList(electric)); - pokemons[1] = new Pokemon(trainers[0], "Manectric", 1589, Arrays.asList(electric)); - pokemons[2] = new Pokemon(trainers[0], "Magnezone", 1853, Arrays.asList(electric)); - pokemons[3] = new Pokemon(trainers[0], "Electrode", 1237, Arrays.asList(electric)); - pokemons[4] = new Pokemon(trainers[0], "Pachirisu", 942, Arrays.asList(electric)); - pokemons[5] = new Pokemon(trainers[0], "Electivire", 1931, Arrays.asList(electric)); - stadiums[0] = new Stadium("Vermilion Gym", trainers[0]); - cities[0] = new City("Vermilion City", "Mina", stadiums[0]); - em.persist(trainers[0]); - em.persist(pokemons[0]); - em.persist(pokemons[1]); - em.persist(pokemons[2]); - em.persist(pokemons[3]); - em.persist(pokemons[4]); - em.persist(pokemons[5]); - //em.persist(stadiums[0]); - em.persist(cities[0]); - em.flush(); - DbUtils.cleanEm(em); - City dbCity = em.find(City.class, cities[0].getId()); - Stadium dbStadium = dbCity.getStadium(); - Trainer dbTrainer = dbStadium.getTrainer(); - List dbPokemons = dbTrainer.getPokemons(); - Set pokemonSet = new HashSet<>(pokemons.length); - pokemonSet.addAll(Arrays.asList(pokemons)); - dbPokemons.forEach((dbPokemon) -> { - result.assertTrue(pokemonSet.remove(dbPokemon)); - }); - result.assertTrue(pokemonSet.isEmpty()); - result.assertEquals(trainers[0], dbTrainer); - result.assertEquals(stadiums[0], dbStadium); - result.assertEquals(cities[0], dbCity); - for (Pokemon pokemon : pokemons) { - DELETE_POKEMONS.add(pokemon.getId()); - } - DELETE_TRAINERS.add(dbTrainer.getId()); - DELETE_STADIUMS.add(dbStadium.getId()); - DELETE_TOWNS.add(dbCity.getId()); - return result; - } - -} diff --git a/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/JdbcApiIT.java b/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/JdbcApiIT.java deleted file mode 100644 index 09f54b863fc..00000000000 --- a/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/JdbcApiIT.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2020, 2023 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.appl; - -import java.io.IOException; -import java.io.InputStream; -import java.lang.System.Logger.Level; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Properties; - -import jakarta.enterprise.context.ApplicationScoped; - -/** - * Test JDBC API without JPA. - */ -@ApplicationScoped -public class JdbcApiIT { - - private static final System.Logger LOGGER = System.getLogger(JdbcApiIT.class.getName()); - - /* Database connection. */ - private static Connection conn = null; - - /** - * Initialize database connection. - * - * @param result test execution result - * @return test execution result - */ - @MPTest - public TestResult setup(TestResult result) { - Properties config = new Properties(); - try (InputStream is = JdbcApiIT.class.getResourceAsStream("/META-INF/microprofile-config.properties")) { - config.load(is); - } catch (IOException ex) { - LOGGER.log(Level.ERROR, () -> String.format("Could not load configuration properties: %s", ex.getMessage())); - } - final String dbUser = config.getProperty("javax.sql.DataSource.test.dataSource.user"); - final String dbPassword = config.getProperty("javax.sql.DataSource.test.dataSource.password"); - final String dbUrl = config.getProperty("javax.sql.DataSource.test.dataSource.url"); - if (dbUser == null) { - throw new IllegalStateException("Database user name was not set, check javax.sql.DataSource.test.dataSource.user property! "); - } - if (dbPassword == null) { - throw new IllegalStateException("Database user password was not set, check javax.sql.DataSource.test.dataSource.password property!"); - } - if (dbUrl == null) { - throw new IllegalStateException("Database URL was not set, check javax.sql.DataSource.test.dataSource.url property!"); - } - try { - conn = DriverManager.getConnection(dbUrl, dbUser, dbPassword); - } catch (SQLException ex) { - LOGGER.log(Level.INFO, () -> String.format("Could not open database connection: %s", ex.getMessage())); - conn = null; - } - return result; - } - - /** - * Close database connection. - * - * @param result test execution result - * @return test execution result - */ - @MPTest - public TestResult destroy(TestResult result) { - if (conn != null) { - Utils.closeConnection(conn); - } - return result; - } - - - /** - * Test simple ping query. - * - * @param result test execution result - * @return test execution result - */ - @MPTest - public TestResult ping(TestResult result) throws SQLException { - if (conn == null) { - return result.fail("No database connection is available!"); - } - try (Statement stmt = conn.createStatement()) { - try (ResultSet rs = stmt.executeQuery("SELECT 1")) { - result.assertTrue(rs.next(), "Is 1st result available?"); - Integer value = rs.getInt(1); - result.assertNotNull(value); - result.assertEquals(1, value); - } - } catch (SQLException e) { - LOGGER.log(Level.WARNING, () -> String.format("Simple ping query failed: ", e.getMessage())); - result.throwed(e); - } - return result; - } - -} diff --git a/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/JdbcTestResource.java b/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/JdbcTestResource.java deleted file mode 100644 index a1ef4925878..00000000000 --- a/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/JdbcTestResource.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.appl; - -import jakarta.enterprise.context.RequestScoped; -import jakarta.inject.Inject; -import jakarta.json.JsonObject; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.PathParam; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.core.MediaType; - -/** - * REST Resource for JDBC test application. - */ -@Path("/testJdbc") -@RequestScoped -public class JdbcTestResource { - - @Inject - private JdbcApiIT jdbcApiIt; - - private Dispatcher.Handle getHandle(final String name) { - final int nameLen = name.length(); - final int serpPos = name.indexOf('.'); - final TestResult result = new TestResult(); - result.name(name); - if (serpPos < 0 || (serpPos + 1) >= nameLen) { - result.fail("Invalid test identifier: " + name); - return null; - } - final String className = name.substring(0, serpPos); - final String methodName = name.substring(serpPos + 1, nameLen); - if ("JdbcApiIT".equals(className)) { - try { - return new Dispatcher.Handle( - jdbcApiIt, - JdbcApiIT.class.getDeclaredMethod(methodName, TestResult.class), - result); - } catch (NoSuchMethodException ex) { - result.throwed(ex); - } - } else { - result.fail("Unknown test class: " + className); - } - return null; - } - - /** - * Run test identified by it's name ({@code.}). - * - * @param name name of the test - * @return test execution result - */ - private TestResult runTest(final String name) { - Dispatcher.Handle handle = getHandle(name); - if (handle == null) { - return handle.result().fail("Missing method handle."); - } - return handle.invoke(); - } - - /** - * Test setup invocation. - * - * @return test result - */ - @GET - @Path("/setup") - @Produces(MediaType.APPLICATION_JSON) - public JsonObject setup() { - return runTest("JdbcApiIT.setup").build(); - } - - /** - * Test cleanup invocation. - * - * @return test result - */ - @GET - @Path("/destroy") - @Produces(MediaType.APPLICATION_JSON) - public JsonObject destroy() { - return runTest("JdbcApiIT.destroy").build(); - } - - - /** - * Test invocation. - * - * @param name test name - * @return test result - */ - @GET - @Path("/test/{name}") - @Produces(MediaType.APPLICATION_JSON) - public JsonObject test(@PathParam("name") String name) { - return runTest(name).build(); - } - -} diff --git a/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/JpaTestResource.java b/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/JpaTestResource.java deleted file mode 100644 index 35588dea83e..00000000000 --- a/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/JpaTestResource.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2020, 2023 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.appl; - -import java.lang.System.Logger.Level; - -import jakarta.enterprise.context.RequestScoped; -import jakarta.inject.Inject; -import jakarta.json.JsonObject; -import jakarta.persistence.EntityManager; -import jakarta.persistence.PersistenceContext; -import jakarta.transaction.Transactional; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.PathParam; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.core.MediaType; - -import io.helidon.tests.integration.jpa.dao.Create; - -/** - * REST Resource for JPA test application. - */ -@Path("/test") -@RequestScoped -public class JpaTestResource { - - private static final System.Logger LOGGER = System.getLogger(JpaTestResource.class.getName()); - - @PersistenceContext(unitName = "test") - private EntityManager em; - - @Inject - Dispatcher dispatcher; - - /** - * Resource status check - * - * @return status message - */ - @GET - @Path("/status") - public String status() { - return "JPA test application is alive."; - } - - /** - * Test initialization. - * - * @return initialization result - */ - @GET - @Path("/init") - @Produces(MediaType.APPLICATION_JSON) - @Transactional - public JsonObject init() { - final TestResult result = new TestResult(); - result.name("Initialization"); - try { - Create.dbInsertTypes(em); - result.message("Database was initialized"); - } catch (Throwable t) { - LOGGER.log(Level.ERROR, () -> String.format("Pokemon types initialization failed: %s", t.getMessage()), t); - result.throwed(t); - } - return result.build(); - } - - /** - * Test whether MP application can access JPA Entity Beans. - * - * @return test result - */ - @GET - @Path("/beans") - @Produces(MediaType.APPLICATION_JSON) - public JsonObject beans() { - final TestResult result = new TestResult(); - result.name("Beans check"); - try { - Class typeClass = Class.forName("io.helidon.tests.integration.jpa.model.Type"); - Class pokemonClass = Class.forName("io.helidon.tests.integration.jpa.model.Pokemon"); - Class trainerClass = Class.forName("io.helidon.tests.integration.jpa.model.Trainer"); - result.assertNotNull(typeClass); - result.assertNotNull(pokemonClass); - result.assertNotNull(trainerClass); - } catch (Throwable t) { - LOGGER.log(Level.ERROR, () -> String.format("JPA Entity beans check failed: %s", t.getMessage()), t); - result.throwed(t); - } - return result.build(); - } - - /** - * Test invocation. - * - * @param name test name - * @return test result - */ - @GET - @Path("/test/{name}") - @Produces(MediaType.APPLICATION_JSON) - @Transactional - public JsonObject test(@PathParam("name") String name) { - TestResult result = dispatcher.runTest(name); - return result.build(); - } - - /** - * Terminate JPA MP application. - * - * @return shutdown message - */ - @GET - @Path("/exit") - public String exit() { - ExitThread.start(); - return "JPA MP application shutting down."; - } - -} diff --git a/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/QueryIT.java b/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/QueryIT.java deleted file mode 100644 index f2ff1cd061c..00000000000 --- a/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/QueryIT.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.appl; - -import java.util.List; - -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.persistence.EntityManager; -import jakarta.persistence.PersistenceContext; -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.CriteriaQuery; -import jakarta.persistence.criteria.Root; - -import io.helidon.tests.integration.jpa.dao.Create; -import io.helidon.tests.integration.jpa.dao.Delete; -import io.helidon.tests.integration.jpa.model.City; -import io.helidon.tests.integration.jpa.model.Pokemon; -import io.helidon.tests.integration.jpa.model.Trainer; - -/** - * Verify query operations of ORM (server side). - */ -@ApplicationScoped -public class QueryIT { - - private static int ASH_ID; - - @PersistenceContext(unitName = "test") - private EntityManager em; - - /** - * Initialize test suite. - * - * @param result test execution result - * @return test execution result - */ - @MPTest - public TestResult setup(TestResult result) { - ASH_ID = Create.dbInsertAsh(em); - Create.dbInsertCeladon(em); - return result; - } - - /** - * Clean up test suite. - * - * @param result test execution result - * @return test execution result - */ - @MPTest - public TestResult destroy(TestResult result) { - Delete.dbDeleteAsh(em); - Delete.dbDeleteCeladon(em); - return result; - } - - /** - * Find trainer Ash and his pokemons. - * - * @param result test execution result - * @return test execution result - */ - @MPTest - public TestResult testFind(TestResult result) { - Trainer ash = em.find(Trainer.class, ASH_ID); - List pokemons = ash.getPokemons(); - result.assertNotNull(ash); - result.assertFalse(pokemons.isEmpty()); - return result; - } - - /** - * Query trainer Ash and his pokemons using JPQL. - * - * @param result test execution result - * @return test execution result - */ - @MPTest - public TestResult testQueryJPQL(TestResult result) { - Trainer ash = em.createQuery( - "SELECT t FROM Trainer t JOIN FETCH t.pokemons p WHERE t.id = :id", Trainer.class) - .setParameter("id", ASH_ID) - .getSingleResult(); - List pokemons = ash.getPokemons(); - result.assertNotNull(ash); - result.assertFalse(pokemons.isEmpty()); - return result; - } - - /** - * Query trainer Ash and his pokemons using CriteriaQuery. - * - * @param result test execution result - * @return test execution result - */ - @MPTest - public TestResult testQueryCriteria(TestResult result) { - CriteriaBuilder cb = em.getCriteriaBuilder(); - CriteriaQuery cq = cb.createQuery(Trainer.class); - Root trainerRoot = cq.from(Trainer.class); - cq.select(trainerRoot) - .where(cb.equal(trainerRoot.get("id"), ASH_ID)); - Trainer ash = em.createQuery(cq).getSingleResult(); - List pokemons = ash.getPokemons(); - result.assertNotNull(ash); - result.assertFalse(pokemons.isEmpty()); - return result; - } - - /** - * Query Celadon city using JPQL. - * - * @param result test execution result - * @return test execution result - */ - @MPTest - public TestResult testQueryCeladonJPQL(TestResult result) { - City city = em.createQuery( - "SELECT c FROM City c " - + "JOIN FETCH c.stadium s " - + "JOIN FETCH s.trainer t " - + "WHERE c.name = :name", City.class) - .setParameter("name", "Celadon City") - .getSingleResult(); - result.assertEquals(city.getName(), "Celadon City"); - result.assertEquals(city.getStadium().getName(), "Celadon Gym"); - result.assertEquals(city.getStadium().getTrainer().getName(), "Erika"); - return result; - } - - /** - * Query Celadon city using CriteriaQuery. - * - * @param result test execution result - * @return test execution result - */ - @MPTest - public TestResult testQueryCeladonCriteria(TestResult result) { - CriteriaBuilder cb = em.getCriteriaBuilder(); - CriteriaQuery cq = cb.createQuery(City.class); - Root cityRoot = cq.from(City.class); - cityRoot - .fetch("stadium") - .fetch("trainer"); - cq.select(cityRoot) - .where(cb.equal(cityRoot.get("name"), "Celadon City")); - City city = em.createQuery(cq).getSingleResult(); - result.assertEquals(city.getName(), "Celadon City"); - result.assertEquals(city.getStadium().getName(), "Celadon Gym"); - result.assertEquals(city.getStadium().getTrainer().getName(), "Erika"); - return result; - } - -} diff --git a/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/TestResult.java b/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/TestResult.java deleted file mode 100644 index 058db7f7554..00000000000 --- a/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/TestResult.java +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.appl; - -import jakarta.json.Json; -import jakarta.json.JsonArrayBuilder; -import jakarta.json.JsonObject; -import jakarta.json.JsonObjectBuilder; - -/** - * Test execution result. - */ -public class TestResult { - - private boolean failed; - - private final JsonObjectBuilder ob; - - private final JsonArrayBuilder msg; - - private JsonObjectBuilder ex; - - /** - * Creates an instance of test execution result. - */ - public TestResult() { - failed = false; - ob = Json.createObjectBuilder(); - msg = Json.createArrayBuilder(); - ex = null; - } - - /** - * Add test name. - * - * @param name name of the test - */ - public void name(final String name) { - ob.add("name", name); - } - - /** - * Get execution status (failed or not failed). - * - * @return execution status - */ - public boolean failed() { - return failed; - } - - /** - * Build test execution result JSON object. - * - * @return test execution result JSON object - */ - public JsonObject build() { - ob.add("status", failed ? "FAILURE" : "SUCCESS"); - ob.add("messages", msg.build()); - if (ex != null) { - ob.add("exception", ex.build()); - } - return ob.build(); - } - /** - * Add test execution activity message. - * - * @param message test execution activity message - * @return this instance - */ - public TestResult message(final String message) { - msg.add(message); - return this; - } - - /** - * Mark executed test as failed and store message related to failure. - * - * @param message message related to failure - * @return this instance - */ - public TestResult fail(final String message) { - // Log 1st failure as an error. - if (!failed) { - ob.add("error", message); - } - failed = true; - msg.add(message); - return this; - } - - /** - * Store an exception thrown during test execution. - * - * @param t exception thrown during test execution - * @return this instance - */ - public TestResult throwed(final Throwable t) { - // Log 1st failure as an error. - if (!failed) { - ob.add("error", t.getMessage()); - } - failed = true; - if (ex == null) { - JsonArrayBuilder trace = Json.createArrayBuilder(); - ex = Json.createObjectBuilder(); - ex.add("message", t.getMessage()); - StackTraceElement[] st = t.getStackTrace(); - for (StackTraceElement ste : st) { - trace.add(ste.toString()); - } - ex.add("trace", trace.build()); - } - return this; - } - - /** - * Test result check: equals - * - * @param expected expected value - * @param actual actual value to be checked - */ - public void assertEquals(Object expected, Object actual) { - boolean addError = false; - StringBuilder sb = new StringBuilder(); - sb.append("Expected: "); - sb.append(expected != null ? expected.toString() : ""); - sb.append(" Actual: "); - sb.append(actual != null ? actual.toString() : ""); - sb.append(" :: "); - if (expected == actual || (expected != null && expected.equals(actual))) { - sb.append("EQUAL"); - } else { - if (!failed) { - addError = true; - } - failed = true; - sb.append("NOT EQUAL"); - } - String message = sb.toString(); - msg.add(message); - if (addError) { - ob.add("error", message); - } - } - - /** - * Test result check: boolean true - * - * @param value actual value to be checked - */ - public void assertTrue(Boolean value) { - StringBuilder sb = new StringBuilder(); - sb.append("Expected: true"); - sb.append(" Actual: "); - sb.append(Boolean.toString(value)); - sb.append(" :: "); - sb.append(value ? "EQUAL" : "NOT EQUAL"); - String message = sb.toString(); - msg.add(message); - if (!value) { - ob.add("error", message); - failed = true; - } - } - - /** - * Test result check: boolean true - * - * @param value actual value to be checked - */ - public void assertTrue(Boolean value, String header) { - StringBuilder sb = new StringBuilder(); - sb.append(header); - sb.append(" Expected: true"); - sb.append(" Actual: "); - sb.append(Boolean.toString(value)); - sb.append(" :: "); - sb.append(value ? "EQUAL" : "NOT EQUAL"); - String message = sb.toString(); - msg.add(message); - if (!value) { - ob.add("error", message); - failed = true; - } - } - - /** - * Test result check: boolean false - * - * @param value actual value to be checked - */ - public void assertFalse(Boolean value) { - StringBuilder sb = new StringBuilder(); - sb.append("Expected: false"); - sb.append(" Actual: "); - sb.append(Boolean.toString(value)); - sb.append(" :: "); - sb.append(value ? "NOT EQUAL" : "EQUAL"); - String message = sb.toString(); - msg.add(message); - if (value) { - ob.add("error", message); - failed = true; - } - } - - /** - * Test result check: null value - * - * @param value actual value to be checked - */ - public void assertNull(Object value) { - StringBuilder sb = new StringBuilder(); - sb.append("Expected: null"); - sb.append(" Actual: "); - sb.append(value == null ? "null" : "not null"); - sb.append(" :: "); - sb.append(value == null ? "EQUAL" : "NOT EQUAL"); - String message = sb.toString(); - msg.add(message); - if (value != null ) { - ob.add("error", message); - failed = true; - } - } - - /** - * Test result check: non null value - * - * @param value actual value to be checked - */ - public void assertNotNull(Object value) { - StringBuilder sb = new StringBuilder(); - sb.append("Expected: not null"); - sb.append(" Actual: "); - sb.append(value == null ? "null" : "not null"); - sb.append(" :: "); - sb.append(value == null ? "NOT EQUAL" : "EQUAL"); - String message = sb.toString(); - msg.add(message); - if (value == null ) { - ob.add("error", message); - failed = true; - } - } - -} diff --git a/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/UpdateIT.java b/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/UpdateIT.java deleted file mode 100644 index 96cec511ad8..00000000000 --- a/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/UpdateIT.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 2020, 2022 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.appl; - -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.persistence.EntityManager; -import jakarta.persistence.PersistenceContext; -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.CriteriaQuery; -import jakarta.persistence.criteria.CriteriaUpdate; -import jakarta.persistence.criteria.Root; - -import io.helidon.tests.integration.jpa.dao.Create; -import io.helidon.tests.integration.jpa.dao.Delete; -import io.helidon.tests.integration.jpa.model.City; -import io.helidon.tests.integration.jpa.model.Pokemon; -import io.helidon.tests.integration.jpa.model.Stadium; -import io.helidon.tests.integration.jpa.model.Trainer; - -/** - * Verify update operations of ORM (server side). - */ -@ApplicationScoped -public class UpdateIT { - - @PersistenceContext(unitName = "test") - private EntityManager em; - - - /** - * Initialize test suite. - * - * @param result test execution result - * @return test execution result - */ - @MPTest - public TestResult setup(TestResult result) { - Create.dbInsertBrock(em); - Create.dbInsertSaffron(em); - return result; - } - - /** - * Clean up test suite. - * - * @param result test execution result - * @return test execution result - */ - @MPTest - public TestResult destroy(TestResult result) { - Delete.dbDeleteBrock(em); - Delete.dbDeleteSaffron(em); - return result; - } - - /** - * Update pokemon: evolve Broke's Geodude into Graveler. - * Modification is done using entity instance. - * - * @param result test execution result - * @return test execution result - */ - @MPTest - public TestResult testUpdateEntity(TestResult result) { - Pokemon[] pokemons = new Pokemon[1]; - pokemons[0] = em.createQuery( - "SELECT p FROM Pokemon p WHERE p.name = :name", Pokemon.class) - .setParameter("name", "Geodude") - .getSingleResult(); - pokemons[0].getTypes().size(); - pokemons[0].setName("Graveler"); - pokemons[0].setCp(527); - em.persist(pokemons[0]); - DbUtils.cleanEm(em); - Pokemon dbGraveler = em.find(Pokemon.class, pokemons[0].getId()); - result.assertEquals(pokemons[0], dbGraveler); - return result; - } - - /** - * Update pokemon: evolve Broke's Slowpoke into Slowbro. - * Modification is done using JPQL. - * - * @param result test execution result - * @return test execution result - */ - @MPTest - public TestResult testUpdateJPQL(TestResult result) { - int updated = em.createQuery( - "UPDATE Pokemon p SET p.name = :newName, p.cp = :newCp WHERE p.name = :name") - .setParameter("newName", "Slowbro") - .setParameter("newCp", 647) - .setParameter("name", "Slowpoke") - .executeUpdate(); - result.assertEquals(1, updated); - DbUtils.cleanEm(em); - Pokemon dbWartortle = em.createQuery( - "SELECT p FROM Pokemon p WHERE p.name=:name", Pokemon.class) - .setParameter("name", "Slowbro") - .getSingleResult(); - result.assertEquals(647, dbWartortle.getCp()); - return result; - } - - /** - * Update pokemon: evolve Broke's Teddiursa into Ursaring. - * Modification is done using CriteriaUpdate. - * - * @param result test execution result - * @return test execution result - */ - @MPTest - public TestResult testUpdateCriteria(TestResult result) { - CriteriaBuilder cb = em.getCriteriaBuilder(); - CriteriaUpdate cu = cb.createCriteriaUpdate(Pokemon.class); - Root pokemonRoot = cu.from(Pokemon.class); - cu.where(cb.equal(pokemonRoot.get("name"), "Teddiursa")) - .set("name", "Ursaring") - .set("cp", 1568); - int updated = em.createQuery(cu).executeUpdate(); - result.assertEquals(1, updated); - DbUtils.cleanEm(em); - cb = em.getCriteriaBuilder(); - CriteriaQuery cq = cb.createQuery(Pokemon.class); - pokemonRoot = cq.from(Pokemon.class); - cq.select(pokemonRoot) - .where(cb.equal(pokemonRoot.get("name"), "Ursaring")); - Pokemon dbUrsaring = em.createQuery(cq).getSingleResult(); - result.assertEquals(1568, dbUrsaring.getCp()); - return result; - } - - /** - * Update Saffron City data structure. - * Replace stadium trainer with new guy who will get all pokemons from previous trainer. - * Also Alakazam evolves to Mega Alakazam at the same time. - * - * @param result test execution result - * @return test execution result - */ - @MPTest - public TestResult testUpdateSaffron(TestResult result) { - City[] cities = new City[1]; - Set pokemonNames = new HashSet<>(6); - cities[0] = em.createQuery( - "SELECT c FROM City c WHERE c.name = :name", City.class) - .setParameter("name", "Saffron City") - .getSingleResult(); - Stadium stadium = cities[0].getStadium(); - Trainer sabrina = stadium.getTrainer(); - Trainer janine = new Trainer("Janine", 24); - stadium.setTrainer(janine); - List pokemons = sabrina.getPokemons(); - janine.setPokemons(pokemons); - sabrina.setPokemons(Collections.EMPTY_LIST); - em.remove(sabrina); - em.persist(janine); - for (Pokemon pokemon : pokemons) { - pokemon.setTrainer(janine); - pokemonNames.add(pokemon.getName()); - em.persist(pokemon); - } - em.persist(stadium); - Pokemon alkazam = DbUtils.findPokemonByName(pokemons, "Alakazam"); - // Update pokemon by query - em.createQuery( - "UPDATE Pokemon p SET p.name = :newName, p.cp = :newCp WHERE p.id = :id") - .setParameter("newName", "Mega Alakazam") - .setParameter("newCp", 4348) - .setParameter("id", alkazam.getId()) - .executeUpdate(); - pokemonNames.remove("Alakazam"); - pokemonNames.add("Mega Alakazam"); - DbUtils.cleanEm(em); - City city = em.find(City.class, cities[0].getId()); - stadium = city.getStadium(); - Trainer trainer = stadium.getTrainer(); - pokemons = trainer.getPokemons(); - result.assertEquals(trainer.getName(), "Janine"); - for (Pokemon pokemon : pokemons) { - result.assertTrue(pokemonNames.remove(pokemon.getName()), "Pokemon " + pokemon.getName() + " is missing"); - } - return result; - } - -} diff --git a/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/Utils.java b/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/Utils.java deleted file mode 100644 index 68f2b93366c..00000000000 --- a/tests/integration/jpa/appl/src/main/java/io/helidon/tests/integration/jpa/appl/Utils.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2019, 2023 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.appl; - -import java.lang.System.Logger.Level; -import java.sql.Connection; -import java.sql.SQLException; - -/** - * Test utilities. - */ -public class Utils { - - private static final System.Logger LOGGER = System.getLogger(Utils.class.getName()); - - private Utils() { - throw new IllegalStateException("No instances of this class are allowed!"); - } - - /** - * Close database connection. - * - * @param connection database connection - */ - public static void closeConnection(final Connection connection) { - try { - connection.close(); - } catch (SQLException ex) { - LOGGER.log(Level.WARNING, () -> String.format("Could not close database connection: %s", ex.getMessage())); - } - } - -} diff --git a/tests/integration/jpa/appl/src/main/resources/logging.properties b/tests/integration/jpa/appl/src/main/resources/logging.properties deleted file mode 100644 index 2d270fc6875..00000000000 --- a/tests/integration/jpa/appl/src/main/resources/logging.properties +++ /dev/null @@ -1,28 +0,0 @@ -# -# Copyright (c) 2020, 2023 Oracle and/or its affiliates. -# -# Licensed 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. -# - -# Example Logging Configuration File -# For more information see $JAVA_HOME/jre/lib/logging.properties -# Send messages to the console - -handlers=io.helidon.logging.jul.HelidonConsoleHandler -# HelidonConsoleHandler uses a SimpleFormatter subclass that replaces "!thread!" with the current thread -java.util.logging.SimpleFormatter.format=%1$tY.%1$tm.%1$td %1$tH:%1$tM:%1$tS %4$s %3$s !thread!: %5$s%6$s%n -# Global logging level. Can be overridden by specific loggers -.level=WARNING -io.helidon.level=INFO -io.helidon.config.level=INFO -io.helidon.webserver.level=WARNING diff --git a/tests/integration/jpa/appl/src/test/java/io/helidon/tests/integration/jpa/appl/test/ClientUtils.java b/tests/integration/jpa/appl/src/test/java/io/helidon/tests/integration/jpa/appl/test/ClientUtils.java deleted file mode 100644 index d1b34f728c7..00000000000 --- a/tests/integration/jpa/appl/src/test/java/io/helidon/tests/integration/jpa/appl/test/ClientUtils.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2020, 2023 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.appl.test; - -import java.lang.System.Logger.Level; - -import jakarta.json.stream.JsonParsingException; -import jakarta.ws.rs.client.Client; -import jakarta.ws.rs.client.ClientBuilder; -import jakarta.ws.rs.client.WebTarget; -import jakarta.ws.rs.core.Response; - -/** - * REST client utilities for remote test calls. - */ -public class ClientUtils { - - private static final System.Logger LOGGER = System.getLogger(ClientUtils.class.getName()); - - private ClientUtils() { - throw new UnsupportedOperationException("Instances of ClientUtils class are not allowed"); - } - - private static final Client CLIENT = ClientBuilder.newClient(); - // FIXME: Use random port. - private static final WebTarget TARGET = CLIENT.target("http://localhost:7001/test"); - private static final WebTarget TARGET_JDBC = CLIENT.target("http://localhost:7001/testJdbc"); - - /** - * Call remote test on MP server using REST interface. - * - * @param path test path (URL suffix {@code .}) - */ - public static void callTest(final String path) { - WebTarget status = TARGET.path(path); - Response response = status.request().get(); - String responseStr = response.readEntity(String.class); - try { - Validate.check(responseStr); - } catch (JsonParsingException t) { - LOGGER.log(Level.ERROR, () -> String.format("Response is not JSON: %s, message: %s", t.getMessage(), responseStr), t); - } - } - - /** - * Call remote test on MP server using REST interface. - * - * @param path test path (URL suffix {@code .}) - */ - public static void callJdbcTest(final String path) { - WebTarget status = TARGET_JDBC.path(path); - Response response = status.request().get(); - String responseStr = response.readEntity(String.class); - try { - Validate.check(responseStr); - } catch (JsonParsingException t) { - LOGGER.log(Level.ERROR, () -> String.format("Response is not JSON: %s, message: %s", t.getMessage(), responseStr), t); - } - } - -} diff --git a/tests/integration/jpa/appl/src/test/java/io/helidon/tests/integration/jpa/appl/test/DeleteIT.java b/tests/integration/jpa/appl/src/test/java/io/helidon/tests/integration/jpa/appl/test/DeleteIT.java deleted file mode 100644 index 435610423f9..00000000000 --- a/tests/integration/jpa/appl/src/test/java/io/helidon/tests/integration/jpa/appl/test/DeleteIT.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.appl.test; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -/** - * Verify delete operations of ORM (client side). - */ -public class DeleteIT { - - @BeforeAll - public static void setup() { - ClientUtils.callTest("/test/DeleteIT.setup"); - } - - @AfterAll - public static void destroy() { - ClientUtils.callTest("/test/DeleteIT.destroy"); - } - - /** - * Delete pokemon: release Misty's Staryu. - * Modification is done using entity instance. - */ - @Test - public void testDeleteEntity() { - ClientUtils.callTest("/test/DeleteIT.testDeleteEntity"); - } - - /** - * Delete pokemon: release Misty's Psyduck. - * Modification is done using JPQL. - */ - @Test - public void testDeleteJPQL() { - ClientUtils.callTest("/test/DeleteIT.testDeleteJPQL"); - - } - - /** - * Delete pokemon: release Misty's Corsola. - * Modification is done using CriteriaUpdate. - */ - @Test - public void testDeleteCriteria() { - ClientUtils.callTest("/test/DeleteIT.testDeleteCriteria"); - } - - /** - * Delete Viridian City. - */ - @Test - public void testDeleteViridianCity() { - ClientUtils.callTest("/test/DeleteIT.testDeleteViridianCity"); - } - -} diff --git a/tests/integration/jpa/appl/src/test/java/io/helidon/tests/integration/jpa/appl/test/InsertIT.java b/tests/integration/jpa/appl/src/test/java/io/helidon/tests/integration/jpa/appl/test/InsertIT.java deleted file mode 100644 index 723cc796e8f..00000000000 --- a/tests/integration/jpa/appl/src/test/java/io/helidon/tests/integration/jpa/appl/test/InsertIT.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.appl.test; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Test; - -/** - * Verify update operations of ORM (clienbt side). - */ -public class InsertIT { - - @AfterAll - public static void destroy() { - ClientUtils.callTest("/test/InsertIT.destroy"); - } - - /** - * Verify simple create operation (persist) on a single database row. - */ - @Test - public void testInsertType() { - ClientUtils.callTest("/test/InsertIT.testInsertType"); - } - - /** - * Verify complex create operation (persist) on a full ORM model (Gary Oak and his 6 pokemons). - * Relations are not marked for cascade persist operation so every entity instance has to be persisted separately. - */ - @Test - public void testInsertTrainerWithPokemons() { - ClientUtils.callTest("/test/InsertIT.testInsertTrainerWithPokemons"); - } - - /** - * Verify complex create operation (persist) on a full ORM model (Lt. Surge in Vermilion City). - */ - @Test - public void testInsertTownWithStadium() { - ClientUtils.callTest("/test/InsertIT.testInsertTownWithStadium"); - } - -} diff --git a/tests/integration/jpa/appl/src/test/java/io/helidon/tests/integration/jpa/appl/test/LifeCycleExtension.java b/tests/integration/jpa/appl/src/test/java/io/helidon/tests/integration/jpa/appl/test/LifeCycleExtension.java deleted file mode 100644 index ad37279eab2..00000000000 --- a/tests/integration/jpa/appl/src/test/java/io/helidon/tests/integration/jpa/appl/test/LifeCycleExtension.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2020, 2023 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.appl.test; - -import java.lang.System.Logger.Level; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; - -import io.helidon.logging.common.LogConfig; -import io.helidon.tests.integration.jpa.appl.Utils; - -import jakarta.json.stream.JsonParsingException; -import jakarta.ws.rs.client.Client; -import jakarta.ws.rs.client.ClientBuilder; -import jakarta.ws.rs.client.WebTarget; -import jakarta.ws.rs.core.Response; -import org.junit.jupiter.api.extension.BeforeAllCallback; -import org.junit.jupiter.api.extension.ExtensionContext; - -import static org.junit.jupiter.api.extension.ExtensionContext.Namespace.GLOBAL; - -/** - * Test Life Cycle. - * Contains setup and cleanup methods for the tests. - */ -public class LifeCycleExtension implements BeforeAllCallback, ExtensionContext.Store.CloseableResource { - - private static final System.Logger LOGGER = System.getLogger(LifeCycleExtension.class.getName()); - - private static final String STORE_KEY = LifeCycleExtension.class.getName(); - - /* Startup timeout in seconds for both database and web server. */ - private static final int TIMEOUT = 60; - - /* Thread sleep time in miliseconds while waiting for database or appserver to come up. */ - private static final int SLEEP_MILIS = 250; - - private static final Client CLIENT = ClientBuilder.newClient(); - - private static final WebTarget TARGET = CLIENT.target("http://localhost:7001/test"); - - /** - * Test setup. - * - * @param ec current extension context - * @throws Exception when test setup fails - */ - @Override - public void beforeAll(ExtensionContext ec) throws Exception { - final Object resource = ec.getRoot().getStore(GLOBAL).get(STORE_KEY); - if (resource == null) { - LogConfig.configureRuntime(); - LOGGER.log(Level.TRACE, "Running beforeAll lifecycle method for the first time, invoking setup()"); - ec.getRoot().getStore(GLOBAL).put(STORE_KEY, this); - setup(); - } else { - LOGGER.log(Level.TRACE, "Running beforeAll lifecycle method next time, skipping setup()"); - } - } - - /** - * Setup JPA application tests. - */ - private void setup() { - LOGGER.log(Level.DEBUG, "Running JPA application test setup()"); - waitForDatabase(); - waitForServer(); - ClientUtils.callJdbcTest("/setup"); - ClientUtils.callJdbcTest("/test/JdbcApiIT.ping"); - init(); - testBeans(); - } - - /** - * Cleanup JPA application tests. - */ - @Override - public void close() throws Throwable { - LOGGER.log(Level.DEBUG, "Running JPA application test close()"); - shutdown(); - } - - @SuppressWarnings("SleepWhileInLoop") - public static void waitForDatabase() { - final String dbUser = System.getProperty("db.user"); - final String dbPassword = System.getProperty("db.password"); - final String dbUrl = System.getProperty("db.url"); - boolean connected = false; - if (dbUser == null) { - throw new IllegalStateException("Database user name was not set, check db.user property!"); - } - if (dbPassword == null) { - throw new IllegalStateException("Database user password was not set, check db.password property!"); - } - if (dbUrl == null) { - throw new IllegalStateException("Database URL was not set, check db.url property"); - } - long endTm = 1000 * TIMEOUT + System.currentTimeMillis(); - while (true) { - try { - Connection conn = DriverManager.getConnection(dbUrl, dbUser, dbPassword); - connected = true; - Utils.closeConnection(conn); - return; - } catch (SQLException ex) { - LOGGER.log(Level.DEBUG, () -> String.format("Connection check: %s", ex.getMessage())); - if (System.currentTimeMillis() > endTm) { - throw new IllegalStateException(String.format("Database is not ready within %d seconds", TIMEOUT)); - } - try { - Thread.sleep(SLEEP_MILIS); - } catch (InterruptedException ie) { - LOGGER.log(Level.WARNING, () -> String.format("Thread was interrupted: %s", ie.getMessage()), ie); - } - } - } - } - - @SuppressWarnings("SleepWhileInLoop") - public static void waitForServer() { - WebTarget status = TARGET.path("/status"); - - long tmEnd = System.currentTimeMillis() + (TIMEOUT * 1000); - boolean retry = true; - while (retry) { - try { - Response response = status.request().get(); - retry = false; - } catch (Exception ex) { - LOGGER.log(Level.DEBUG, () -> String.format("Connection check: %s", ex.getMessage())); - if (System.currentTimeMillis() > tmEnd) { - throw new IllegalStateException(String.format("Appserver is not ready within %d seconds", TIMEOUT)); - } - try { - Thread.sleep(SLEEP_MILIS); - } catch (InterruptedException ie) { - LOGGER.log(Level.WARNING, () -> String.format("Thread was interrupted: %s", ie.getMessage()), ie); - } - } - } - } - - public void init() { - WebTarget status = TARGET.path("/init"); - Response response = status.request().get(); - String responseStr = response.readEntity(String.class); - try { - Validate.check(responseStr); - } catch (JsonParsingException t) { - LOGGER.log(Level.ERROR, () -> String.format("Response is not JSON: %s, message: %s", t.getMessage(), responseStr), t); - } - } - - public void testBeans() { - WebTarget status = TARGET.path("/beans"); - Response response = status.request().get(); - String responseStr = response.readEntity(String.class); - try { - Validate.check(responseStr); - } catch (JsonParsingException t) { - LOGGER.log(Level.ERROR, () -> String.format("Response is not JSON: %s, message: %s", t.getMessage(), responseStr), t); - } - } - - public void shutdown() { - WebTarget exit = TARGET.path("/exit"); - Response response = exit.request().get(); - LOGGER.log(Level.INFO, () -> String.format("Status: %s", response.readEntity(String.class))); - } - -} diff --git a/tests/integration/jpa/appl/src/test/java/io/helidon/tests/integration/jpa/appl/test/QueryIT.java b/tests/integration/jpa/appl/src/test/java/io/helidon/tests/integration/jpa/appl/test/QueryIT.java deleted file mode 100644 index 8fd849b466a..00000000000 --- a/tests/integration/jpa/appl/src/test/java/io/helidon/tests/integration/jpa/appl/test/QueryIT.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.appl.test; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -/** - * Verify query operations of ORM (client side). - */ -public class QueryIT { - - @BeforeAll - public static void setup() { - ClientUtils.callTest("/test/QueryIT.setup"); - } - - @AfterAll - public static void destroy() { - ClientUtils.callTest("/test/QueryIT.destroy"); - } - - /** - * Find trainer Ash and his pokemons. - */ - @Test - public void testDeleteEntity() { - ClientUtils.callTest("/test/QueryIT.testFind"); - } - - /** - * Query trainer Ash and his pokemons using JPQL. - */ - @Test - public void testDeleteJPQL() { - ClientUtils.callTest("/test/QueryIT.testQueryJPQL"); - - } - - /** - * Query trainer Ash and his pokemons using CriteriaQuery. - */ - @Test - public void testDeleteCriteria() { - ClientUtils.callTest("/test/QueryIT.testQueryCriteria"); - } - - /** - * Query Celadon city using JPQL. - */ - @Test - public void testQueryCeladonJPQL() { - ClientUtils.callTest("/test/QueryIT.testQueryCeladonJPQL"); - } - - /** - * Query Celadon city using CriteriaQuery. - */ - @Test - public void testQueryCeladonCriteria() { - ClientUtils.callTest("/test/QueryIT.testQueryCeladonCriteria"); - } - -} diff --git a/tests/integration/jpa/appl/src/test/java/io/helidon/tests/integration/jpa/appl/test/UpdateIT.java b/tests/integration/jpa/appl/src/test/java/io/helidon/tests/integration/jpa/appl/test/UpdateIT.java deleted file mode 100644 index 6389cc63214..00000000000 --- a/tests/integration/jpa/appl/src/test/java/io/helidon/tests/integration/jpa/appl/test/UpdateIT.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.appl.test; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -/** - * Verify update operations of ORM (client side). - */ -public class UpdateIT { - - @BeforeAll - public static void setup() { - ClientUtils.callTest("/test/UpdateIT.setup"); - } - - @AfterAll - public static void destroy() { - ClientUtils.callTest("/test/UpdateIT.destroy"); - } - - /** - * Update pokemon: evolve Broke's Geodude into Graveler. - * Modification is done using entity instance. - */ - @Test - public void testUpdateEntity() { - ClientUtils.callTest("/test/UpdateIT.testUpdateEntity"); - } - - /** - * Update pokemon: evolve Broke's Slowpoke into Slowbro. - * Modification is done using JPQL. - */ - @Test - public void testUpdateJPQL() { - ClientUtils.callTest("/test/UpdateIT.testUpdateJPQL"); - } - - /** - * Update pokemon: evolve Broke's Teddiursa into Ursaring. - * Modification is done using CriteriaUpdate. - */ - @Test - public void testUpdateCriteria() { - ClientUtils.callTest("/test/UpdateIT.testUpdateCriteria"); - } - - /** - * Update Saffron City data structure. - * Replace stadium trainer with new guy who will get all pokemons from previous trainer. - * Also Alakazam evolves to Mega Alakazam at the same time. - */ - @Test - public void testUpdateSaffron() { - ClientUtils.callTest("/test/UpdateIT.testUpdateSaffron"); - } - -} diff --git a/tests/integration/jpa/appl/src/test/java/io/helidon/tests/integration/jpa/appl/test/Validate.java b/tests/integration/jpa/appl/src/test/java/io/helidon/tests/integration/jpa/appl/test/Validate.java deleted file mode 100644 index 0e7e102a206..00000000000 --- a/tests/integration/jpa/appl/src/test/java/io/helidon/tests/integration/jpa/appl/test/Validate.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2020, 2023 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.appl.test; - -import java.io.StringReader; -import java.lang.System.Logger.Level; - -import jakarta.json.Json; -import jakarta.json.JsonArray; -import jakarta.json.JsonObject; - -import static org.junit.jupiter.api.Assertions.fail; - -/** - * Validate test response. - * Utility class. - */ -public class Validate { - - private static final System.Logger LOGGER = System.getLogger(Validate.class.getName()); - - private Validate() { - throw new UnsupportedOperationException("Instances of Validate class are not allowed"); - } - - /** - * Check test result String. - * - * @param resultString test result string with JSON data - */ - public static void check(String resultString) { - JsonObject testResult = Json.createReader(new StringReader(resultString)).readObject(); - String name = testResult.getString("name"); - String status = testResult.getString("status"); - printTestHeader(name, status); - if (testResult.containsKey("messages")) { - printMessages(testResult.getJsonArray("messages")); - } - if (testResult.containsKey("exception")) { - printException(testResult.getJsonObject("exception")); - } - if (!"SUCCESS".equals(status.toUpperCase())) { - StringBuilder sb = new StringBuilder(); - sb.append("Test "); - sb.append(name != null ? name : "UNKNOWN TEST"); - sb.append(" failed"); - if (testResult.containsKey("error")) { - sb.append(": "); - sb.append(testResult.getString("error")); - } - fail(sb.toString()); - } - } - - private static String dots(int count) { - StringBuilder sb = new StringBuilder(count); - for (int i = 0; i < count; i++) { - sb.append('.'); - } - return sb.toString(); - } - - private static void printTestHeader(final String name, final String status) { - final String printName = name != null ? name : "UNKNOWN TEST"; - final String printStatus = status != null ? status : "N?A"; - final int dotsCount = 60 - printName.length(); - LOGGER.log(Level.DEBUG, () -> String.format("*** %s %s", printName, dots(dotsCount))); - LOGGER.log(Level.DEBUG, printStatus); - } - - private static void printMessages(final JsonArray messages) { - if (messages != null && messages.size() > 0) { - LOGGER.log(Level.DEBUG, "Messages:"); - for (int i = 0; i < messages.size(); i++) { - final int idx = i; - LOGGER.log(Level.DEBUG, () -> String.format(" - %s", messages.getString(idx))); - } - } - } - - private static void printException(final JsonObject exception) { - final String message = exception.getString("message"); - LOGGER.log(Level.DEBUG, () -> String.format("Exception: %s", message != null ? message : "")); - if (exception.containsKey("trace")) { - final JsonArray trace = exception.getJsonArray("trace"); - for (int i = 0; i < trace.size(); i++) { - final int idx = i; - LOGGER.log(Level.DEBUG, () -> String.format(" - %s", trace.getString(idx))); - } - } - } - -} diff --git a/tests/integration/jpa/appl/src/test/resources/logging.properties b/tests/integration/jpa/appl/src/test/resources/logging.properties deleted file mode 100644 index 4e59ca90ef4..00000000000 --- a/tests/integration/jpa/appl/src/test/resources/logging.properties +++ /dev/null @@ -1,32 +0,0 @@ -# -# Copyright (c) 2018, 2023 Oracle and/or its affiliates. -# -# Licensed 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. -# - -# Example Logging Configuration File -# For more information see $JAVA_HOME/jre/lib/logging.properties - -# Send messages to the console -handlers=io.helidon.logging.jul.HelidonConsoleHandler - -# HelidonConsoleHandler uses a SimpleFormatter subclass that replaces "!thread!" with the current thread -java.util.logging.SimpleFormatter.format=%1$tY.%1$tm.%1$td %1$tH:%1$tM:%1$tS %4$s %3$s !thread!: %5$s%6$s%n - -# Global logging level. Can be overridden by specific loggers -.level=WARNING - -io.helidon.level=INFO -io.helidon.config.level=INFO -io.helidon.webserver.level=WARNING -io.helidon.tests.integration.jpa.appl.test.level=INFO diff --git a/tests/integration/jpa/model/pom.xml b/tests/integration/jpa/common/pom.xml similarity index 62% rename from tests/integration/jpa/model/pom.xml rename to tests/integration/jpa/common/pom.xml index aa4fac410be..b405854a546 100644 --- a/tests/integration/jpa/model/pom.xml +++ b/tests/integration/jpa/common/pom.xml @@ -26,16 +26,49 @@ 4.1.0-SNAPSHOT ../pom.xml - - io.helidon.tests.integration.jpa - helidon-tests-integration-jpa-model - Helidon Tests Integration JPA Model + helidon-tests-integration-jpa-common + Helidon Tests Integration JPA Common + + io.helidon.microprofile.bundles + helidon-microprofile-core + jakarta.persistence jakarta.persistence-api - provided + + + jakarta.transaction + jakarta.transaction-api + + + jakarta.enterprise + jakarta.enterprise.cdi-api + + + jakarta.ws.rs + jakarta.ws.rs-api + + + io.helidon.integrations.cdi + helidon-integrations-cdi-jta-weld + + + io.helidon.integrations.cdi + helidon-integrations-cdi-datasource-hikaricp + + + io.helidon.integrations.cdi + helidon-integrations-cdi-jpa + + + io.helidon.integrations.cdi + helidon-integrations-cdi-hibernate + + + org.hamcrest + hamcrest-all @@ -72,5 +105,4 @@ - diff --git a/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/AbstractTestImpl.java b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/AbstractTestImpl.java new file mode 100644 index 00000000000..0fa935e0350 --- /dev/null +++ b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/AbstractTestImpl.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.common; + +import io.helidon.tests.integration.jpa.common.model.PokemonDataSet; + +import jakarta.inject.Inject; +import jakarta.persistence.EntityManager; +import jakarta.persistence.NoResultException; +import jakarta.persistence.PersistenceContext; +import jakarta.persistence.TypedQuery; + +/** + * Base test implementation. + */ +public abstract class AbstractTestImpl { + + @Inject + @SuppressWarnings("unused") + protected PokemonDataSet dataSet; + + @PersistenceContext(unitName = "test") + protected EntityManager em; + + protected T result(TypedQuery typedQuery) { + try { + return typedQuery.getSingleResult(); + } catch (NoResultException ex) { + return null; + } + } + + protected void clear() { + em.flush(); + em.clear(); + em.getEntityManagerFactory().getCache().evictAll(); + } +} diff --git a/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/DeleteTest.java b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/DeleteTest.java new file mode 100644 index 00000000000..ea577397471 --- /dev/null +++ b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/DeleteTest.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.common; + +/** + * Verify delete operations of ORM. + */ +public interface DeleteTest { + + /** + * Test deletion using entity instance. + */ + void testDeleteEntity(); + + /** + * Test deletion using JPQL. + */ + void testDeleteJPQL(); + + /** + * Test deletion using {@link jakarta.persistence.criteria.CriteriaDelete}. + */ + void testDeleteCriteria(); + + /** + * Test deleting a complex entity. + */ + void testDeleteCity(); +} diff --git a/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/DeleteTestImpl.java b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/DeleteTestImpl.java new file mode 100644 index 00000000000..84c512c78bb --- /dev/null +++ b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/DeleteTestImpl.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.common; + +import java.util.List; + +import io.helidon.tests.integration.jpa.common.model.City; +import io.helidon.tests.integration.jpa.common.model.Pokemon; +import io.helidon.tests.integration.jpa.common.model.Stadium; +import io.helidon.tests.integration.jpa.common.model.Trainer; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaDelete; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.Root; +import jakarta.transaction.Transactional; + +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; + +/** + * Actual implementation of {@link DeleteTest}. + */ +@Transactional +@ApplicationScoped +@SuppressWarnings({"SpellCheckingInspection"}) +public class DeleteTestImpl extends AbstractTestImpl implements DeleteTest { + + @Override + public void testDeleteEntity() { + Pokemon orig = result(em + .createQuery("SELECT p FROM Pokemon p WHERE p.name = :name", Pokemon.class) + .setParameter("name", "Staryu")); + assertThat(orig, is(not(nullValue()))); + em.remove(orig); + + clear(); + Pokemon actual = em.find(Pokemon.class, orig.getId()); + assertThat(actual, nullValue()); + } + + @Override + public void testDeleteJPQL() { + int deleted = em.createQuery("DELETE FROM Pokemon p WHERE p.name = :name") + .setParameter("name", "Psyduck") + .executeUpdate(); + assertThat(deleted, is(1)); + + clear(); + List results = em.createQuery("SELECT p FROM Pokemon p WHERE p.name=:name", Pokemon.class) + .setParameter("name", "Psyduck") + .getResultList(); + assertThat(results, is(empty())); + } + + @Override + @SuppressWarnings("DuplicatedCode") + public void testDeleteCriteria() { + CriteriaBuilder cb1 = em.getCriteriaBuilder(); + CriteriaDelete cd = cb1.createCriteriaDelete(Pokemon.class); + Root r1 = cd.from(Pokemon.class); + cd.where(cb1.equal(r1.get("name"), "Corsola")); + int deleted = em.createQuery(cd).executeUpdate(); + assertThat(deleted, is(1)); + + clear(); + CriteriaBuilder cb2 = em.getCriteriaBuilder(); + CriteriaQuery cq = cb2.createQuery(Pokemon.class); + Root r2 = cq.from(Pokemon.class); + cq.select(r2).where(cb2.equal(r2.get("name"), "Corsola")); + List results = em.createQuery(cq).getResultList(); + assertThat(results, is(empty())); + } + + @Override + public void testDeleteCity() { + City orig = result(em + .createQuery("SELECT c FROM City c WHERE c.name = :name", City.class) + .setParameter("name", "Viridian City")); + assertThat(orig, is(not(nullValue()))); + Stadium stadium = orig.getStadium(); + Trainer trainer = stadium.getTrainer(); + List pokemons = trainer.getPokemons(); + em.remove(orig); + em.remove(trainer); + pokemons.forEach(poklemon -> em.remove(poklemon)); + + clear(); + City actual = result(em + .createQuery("SELECT c FROM City c WHERE c.name = :name", City.class) + .setParameter("name", "Viridian City")); + assertThat(actual, is(nullValue())); + } +} diff --git a/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/InsertTest.java b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/InsertTest.java new file mode 100644 index 00000000000..c4990240680 --- /dev/null +++ b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/InsertTest.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.common; + +/** + * Verify create/insert operations of ORM. + */ +public interface InsertTest { + + /** + * Test simple create operation (persist) on a single database row. + */ + void testInsertType(); + + /** + * Test complex create operation (persist) on a full ORM model. + */ + void testInsertTrainerWithPokemons(); + + /** + * Test complex create operation (persist) on a full ORM model. + */ + void testTownWithStadium(); +} diff --git a/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/InsertTestImpl.java b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/InsertTestImpl.java new file mode 100644 index 00000000000..d48542cd377 --- /dev/null +++ b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/InsertTestImpl.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.common; + +import java.util.List; + +import io.helidon.tests.integration.jpa.common.model.City; +import io.helidon.tests.integration.jpa.common.model.Pokemon; +import io.helidon.tests.integration.jpa.common.model.Stadium; +import io.helidon.tests.integration.jpa.common.model.Trainer; +import io.helidon.tests.integration.jpa.common.model.Type; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.transaction.Transactional; + +import static org.hamcrest.Matchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; + +/** + * Actual implementation of {@link InsertTest}. + */ +@Transactional +@ApplicationScoped +@SuppressWarnings({"SpellCheckingInspection", "ResultOfMethodCallIgnored"}) +public class InsertTestImpl extends AbstractTestImpl implements InsertTest { + + @Override + public void testInsertType() { + Type type = new Type(20, "TestType"); + em.persist(type); + em.flush(); + Type dbType = em.find(Type.class, 20); + assertThat(dbType, is(type)); + } + + @Override + public void testInsertTrainerWithPokemons() { + Trainer origTrainer = new Trainer("Gary Oak", 10); + List origPokemons = List.of( + new Pokemon(origTrainer, "Krabby", 236, List.of(dataSet.water())), + new Pokemon(origTrainer, "Nidoran", 251, List.of(dataSet.poison())), + new Pokemon(origTrainer, "Eevee", 115, List.of(dataSet.normal())), + new Pokemon(origTrainer, "Electivire", 648, List.of(dataSet.electric())), + new Pokemon(origTrainer, "Dodrio", 346, List.of(dataSet.normal(), dataSet.flying())), + new Pokemon(origTrainer, "Magmar", 648, List.of(dataSet.fire()))); + + em.persist(origTrainer); + origPokemons.forEach(em::persist); + em.flush(); + + clear(); + Trainer actualTrainer = em.find(Trainer.class, origTrainer.getId()); + List actualPokemons = List.copyOf(actualTrainer.getPokemons()); + actualPokemons.forEach(Pokemon::getTypes); // lazy fetch + assertThat(actualTrainer, is(origTrainer)); + assertThat(actualPokemons, is(origPokemons)); + } + + @Override + public void testTownWithStadium() { + Trainer origTrainer = new Trainer("Lt. Surge", 28); + List origPokemons = List.of( + new Pokemon(origTrainer, "Raichu", 1521, List.of(dataSet.electric())), + new Pokemon(origTrainer, "Manectric", 1589, List.of(dataSet.electric())), + new Pokemon(origTrainer, "Magnezone", 1853, List.of(dataSet.electric())), + new Pokemon(origTrainer, "Electrode", 1237, List.of(dataSet.electric())), + new Pokemon(origTrainer, "Pachirisu", 942, List.of(dataSet.electric())), + new Pokemon(origTrainer, "Electivire", 1931, List.of(dataSet.electric()))); + Stadium origStadium = new Stadium("Vermilion Gym", origTrainer); + City origCity = new City("Vermilion City", "Mina", origStadium); + + em.persist(origTrainer); + origPokemons.forEach(em::persist); + em.persist(origStadium); + em.persist(origCity); + + clear(); + City actualCity = em.find(City.class, origCity.getId()); + assertThat(actualCity, is(not(nullValue()))); + List actualPokemons = List.copyOf(actualCity.getStadium().getTrainer().getPokemons()); + actualPokemons.forEach(Pokemon::getTypes); // lazy fetch + assertThat(actualCity, is(origCity)); + assertThat(actualPokemons, is(origPokemons)); + } +} diff --git a/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/QueryTest.java b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/QueryTest.java new file mode 100644 index 00000000000..5c13c264bd2 --- /dev/null +++ b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/QueryTest.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.common; + +/** + * Verify query operations of ORM. + */ +public interface QueryTest { + + /** + * Test query using entity manager. + */ + void testFind(); + + /** + * Test query using JPQL. + */ + void testQueryJPQL(); + + /** + * Test query using {@link jakarta.persistence.criteria.CriteriaQuery}. + */ + void testQueryCriteria(); + + /** + * Test complex query using JPQL. + */ + void testQueryCeladonJPQL(); + + /** + * Query Celadon city using CriteriaQuery. + */ + void testQueryCeladonCriteria(); +} diff --git a/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/QueryTestImpl.java b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/QueryTestImpl.java new file mode 100644 index 00000000000..5b2dbc99bf0 --- /dev/null +++ b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/QueryTestImpl.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.common; + +import java.util.List; + +import io.helidon.tests.integration.jpa.common.model.City; +import io.helidon.tests.integration.jpa.common.model.Pokemon; +import io.helidon.tests.integration.jpa.common.model.Trainer; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.Root; +import jakarta.transaction.Transactional; + +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; + +/** + * Actual implementation of {@link QueryTest}. + */ +@Transactional +@ApplicationScoped +@SuppressWarnings("SpellCheckingInspection") +public class QueryTestImpl extends AbstractTestImpl implements QueryTest { + + @Override + public void testFind() { + clear(); + int id = dataSet.ash().getId(); + Trainer ash = em.find(Trainer.class, id); + List pokemons = ash.getPokemons(); + assertThat(ash, is(not(nullValue()))); + assertThat(pokemons, not(empty())); + } + + @Override + public void testQueryJPQL() { + clear(); + int id = dataSet.ash().getId(); + Trainer trainer = result(em + .createQuery("SELECT t FROM Trainer t JOIN FETCH t.pokemons p WHERE t.id = :id", Trainer.class) + .setParameter("id", id)); + assertThat(trainer, is(not(nullValue()))); + List pokemons = trainer.getPokemons(); // lazy fetch + assertThat(pokemons, is(not(empty()))); + } + + @Override + public void testQueryCriteria() { + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery query = cb.createQuery(Trainer.class); + Root root = query.from(Trainer.class); + query.select(root).where(cb.equal(root.get("name"), "Ash Ketchum")); + Trainer trainer = result(em.createQuery(query)); + assertThat(trainer, is(not(nullValue()))); + assertThat(trainer.getPokemons(), is(not(empty()))); + } + + @Override + public void testQueryCeladonJPQL() { + City city = result(em + .createQuery("SELECT c FROM City c " + + "JOIN FETCH c.stadium s " + + "JOIN FETCH s.trainer t " + + "WHERE c.name = :name", City.class) + .setParameter("name", "Celadon City")); + assertCeladon(city); + } + + @Override + public void testQueryCeladonCriteria() { + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery query = cb.createQuery(City.class); + Root root = query.from(City.class); + root.fetch("stadium").fetch("trainer"); + query.select(root).where(cb.equal(root.get("name"), "Celadon City")); + + City city = result(em.createQuery(query)); + assertCeladon(city); + } + + private void assertCeladon(City city) { + assertThat(city, is(not(nullValue()))); + assertThat(city.getStadium(), is(not(nullValue()))); + assertThat(city.getStadium().getName(), is("Celadon Gym")); + assertThat(city.getStadium().getTrainer(), is(not(nullValue()))); + assertThat(city.getStadium().getTrainer().getName(), is("Erika")); + } +} diff --git a/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/RemoteTest.java b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/RemoteTest.java new file mode 100644 index 00000000000..ebc14fb2fc8 --- /dev/null +++ b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/RemoteTest.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.common; + +import java.util.NoSuchElementException; + +import jakarta.ws.rs.client.ClientBuilder; +import jakarta.ws.rs.client.WebTarget; +import jakarta.ws.rs.core.Response; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +/** + * Base class for remote tests. + */ +public abstract class RemoteTest { + private final WebTarget target; + + /** + * Create a new instance. + * + * @param path base path + * @param port port + */ + @SuppressWarnings("resource") + protected RemoteTest(String path, int port) { + target = ClientBuilder.newClient() + .target("http://localhost:" + port) + .path(path); + } + + /** + * Invoke a GET request against {@code /{path}/{testName}} and assert a {@code 200} response status. + */ + protected void remoteTest() { + String testName = findTestName(); + Response response = target.path(testName).request().get(); + assertThat(response.getStatus(), is(200)); + } + + private String findTestName() { + return StackWalker.getInstance().walk(s -> + s.dropWhile(f -> f.getClassName().equals(RemoteTest.class.getName())) + .findFirst() + .map(StackWalker.StackFrame::getMethodName) + .orElseThrow(() -> new NoSuchElementException("Unable to find caller method name"))); + } +} diff --git a/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/TestResource.java b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/TestResource.java new file mode 100644 index 00000000000..d00b6a8349e --- /dev/null +++ b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/TestResource.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.common; + +import java.lang.reflect.InvocationTargetException; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.InternalServerErrorException; +import jakarta.ws.rs.NotFoundException; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; + +import static java.util.Objects.requireNonNullElse; + +/** + * Resource to expose all tests. + */ +@Path("/test") +@ApplicationScoped +public class TestResource { + + @Inject + private InsertTestImpl insert; + + @Inject + private DeleteTestImpl delete; + + @Inject + private UpdateTestImpl update; + + @Inject + private QueryTestImpl query; + + @GET + @Path("/insert/{testName}") + public String insert(@PathParam("testName") String testName) { + return invokeTest(insert, testName); + } + + @GET + @Path("/delete/{testName}") + public String delete(@PathParam("testName") String testName) { + return invokeTest(delete, testName); + } + + @GET + @Path("/update/{testName}") + public String update(@PathParam("testName") String testName) { + return invokeTest(update, testName); + } + + @GET + @Path("/query/{testName}") + public String query(@PathParam("testName") String testName) { + return invokeTest(query, testName); + } + + private static String invokeTest(Object o, String testName) { + try { + o.getClass().getMethod(testName).invoke(o); + return "OK"; + } catch (IllegalAccessException ex) { + throw new InternalServerErrorException(ex); + } catch (InvocationTargetException ex) { + requireNonNullElse(ex.getCause(), ex).printStackTrace(System.err); + throw new InternalServerErrorException(); + } catch (NoSuchMethodException ignored) { + throw new NotFoundException(); + } + } +} diff --git a/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/UpdateTest.java b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/UpdateTest.java new file mode 100644 index 00000000000..5d20ae8d58b --- /dev/null +++ b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/UpdateTest.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.common; + +/** + * Verify update operations on ORM. + */ +public interface UpdateTest { + + /** + * Test update using entity instance. + */ + void testUpdateEntity(); + + /** + * Test update using JPQL. + */ + void testUpdateJPQL(); + + /** + * Test update {@link jakarta.persistence.criteria.CriteriaUpdate}. + */ + void testUpdateCriteria(); + + /** + * Test update of a complex entity. + */ + void testUpdateCity(); +} diff --git a/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/UpdateTestImpl.java b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/UpdateTestImpl.java new file mode 100644 index 00000000000..c142cdb1cde --- /dev/null +++ b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/UpdateTestImpl.java @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.common; + +import java.util.ArrayList; +import java.util.List; + +import io.helidon.tests.integration.jpa.common.model.City; +import io.helidon.tests.integration.jpa.common.model.Pokemon; +import io.helidon.tests.integration.jpa.common.model.Stadium; +import io.helidon.tests.integration.jpa.common.model.Trainer; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.CriteriaUpdate; +import jakarta.persistence.criteria.Root; +import jakarta.transaction.Transactional; + +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.nullValue; + +/** + * Actual implementation of {@link UpdateTest}. + */ +@Transactional +@ApplicationScoped +@SuppressWarnings({"SpellCheckingInspection", "ResultOfMethodCallIgnored"}) +public class UpdateTestImpl extends AbstractTestImpl implements UpdateTest { + + @Override + public void testUpdateEntity() { + Pokemon orig = result(em + .createQuery("SELECT p FROM Pokemon p WHERE p.name = :name", Pokemon.class) + .setParameter("name", "Geodude")); + orig.getTypes().size(); // lazy fetch + orig.setName("Graveler"); + orig.setCp(527); + em.persist(orig); + + clear(); + Pokemon actual = em.find(Pokemon.class, orig.getId()); + assertThat(actual, is(orig)); + } + + @Override + public void testUpdateJPQL() { + int updated = em.createQuery("UPDATE Pokemon p SET p.name = :newName, p.cp = :newCp WHERE p.name = :name") + .setParameter("newName", "Slowbro") + .setParameter("newCp", 647) + .setParameter("name", "Slowpoke") + .executeUpdate(); + assertThat(updated, is(1)); + + clear(); + Pokemon pokemon = result(em + .createQuery("SELECT p FROM Pokemon p WHERE p.name=:name", Pokemon.class) + .setParameter("name", "Slowbro")); + assertThat(pokemon, is(not(nullValue()))); + assertThat(pokemon.getCp(), is(647)); + } + + @Override + @SuppressWarnings("DuplicatedCode") + public void testUpdateCriteria() { + CriteriaBuilder cb1 = em.getCriteriaBuilder(); + CriteriaUpdate cu = cb1.createCriteriaUpdate(Pokemon.class); + Root r1 = cu.from(Pokemon.class); + cu.where(cb1.equal(r1.get("name"), "Teddiursa")) + .set("name", "Ursaring") + .set("cp", 1568); + int updated = em.createQuery(cu).executeUpdate(); + assertThat(updated, is(1)); + + clear(); + CriteriaBuilder cb2 = em.getCriteriaBuilder(); + CriteriaQuery cq = cb2.createQuery(Pokemon.class); + Root r2 = cq.from(Pokemon.class); + cq.select(r2).where(cb2.equal(r2.get("name"), "Ursaring")); + Pokemon pokemon = result(em.createQuery(cq)); + assertThat(pokemon, is(not(nullValue()))); + assertThat(pokemon.getCp(), is(1568)); + } + + @Override + public void testUpdateCity() { + List origPokemonNames = new ArrayList<>(); + + City origCity = result(em + .createQuery("SELECT c FROM City c WHERE c.name = :name", City.class) + .setParameter("name", "Saffron City")); + assertThat(origCity, is(not(nullValue()))); + + Stadium stadium = origCity.getStadium(); + Trainer trainer = stadium.getTrainer(); + List pokemons = trainer.getPokemons(); + + pokemons.stream() + .map(Pokemon::getName) + .forEach(origPokemonNames::add); + + Trainer newTrainer = new Trainer("Janine", 24); + stadium.setTrainer(newTrainer); + trainer.setPokemons(List.of()); + + em.remove(trainer); + em.persist(newTrainer); + + for (Pokemon pokemon : pokemons) { + pokemon.setTrainer(newTrainer); + em.persist(pokemon); + } + em.persist(stadium); + + Pokemon pokemon = pokemons.stream() + .filter(p -> p.getName().equals("Alakazam")) + .findFirst() + .orElse(null); + assertThat(pokemon, is(not(nullValue()))); + + origPokemonNames.replaceAll(s -> s.equals("Alakazam") ? "Mega Alakazam" : s); + + int updated = em.createQuery("UPDATE Pokemon p SET p.name = :newName, p.cp = :newCp WHERE p.id = :id") + .setParameter("newName", "Mega Alakazam") + .setParameter("newCp", 4348) + .setParameter("id", pokemon.getId()) + .executeUpdate(); + assertThat(updated, is(1)); + + clear(); + City actualCity = em.find(City.class, origCity.getId()); + assertThat(actualCity, is(origCity)); + + List actualPokemonNames = actualCity.getStadium() + .getTrainer() + .getPokemons() + .stream() + .map(Pokemon::getName) + .toList(); + + assertThat(actualPokemonNames, containsInAnyOrder(origPokemonNames.toArray())); + } +} diff --git a/tests/integration/jpa/model/src/main/java/io/helidon/tests/integration/jpa/model/City.java b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/model/City.java similarity index 52% rename from tests/integration/jpa/model/src/main/java/io/helidon/tests/integration/jpa/model/City.java rename to tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/model/City.java index 747ca2e0b52..bfdc73de6be 100644 --- a/tests/integration/jpa/model/src/main/java/io/helidon/tests/integration/jpa/model/City.java +++ b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/model/City.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021 Oracle and/or its affiliates. + * Copyright (c) 2020, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.helidon.tests.integration.jpa.model; +package io.helidon.tests.integration.jpa.common.model; import java.util.Objects; @@ -23,7 +23,7 @@ import jakarta.persistence.OneToOne; /** - * City in pokemon world + * City in {@code Pokemon} world */ @Entity public class City extends Settlement { @@ -60,57 +60,29 @@ public void setStadium(Stadium stadium) { } @Override - public boolean equals(Object oth) { - if (this == oth) { + public boolean equals(Object o) { + if (this == o) { return true; } - if (oth == null) { + if (!(o instanceof City city)) { return false; } - if (super.equals(oth) && (oth instanceof City)) { - return Objects.equals(mayor, ((City) oth).mayor) - && Objects.equals(stadium, ((City) oth).stadium); + if (!super.equals(o)) { + return false; } - return false; + return Objects.equals(mayor, city.mayor) && Objects.equals(stadium, city.stadium); } @Override public int hashCode() { - int hashCode = super.hashCode(); - if (mayor != null) { - hashCode = hashCode * 31 + mayor.hashCode(); - } - if (stadium != null) { - hashCode = hashCode * 31 + stadium.hashCode(); - } - return hashCode; + return Objects.hash(super.hashCode(), mayor, stadium); } @Override public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("Town: {id="); - sb.append(getId()); - sb.append(", name="); - if (getName() != null) { - sb.append('"').append(getName()).append('"'); - } else { - sb.append(""); - } - sb.append(", mayor="); - if (mayor != null) { - sb.append('"').append(mayor).append('"'); - } else { - sb.append(""); - } - sb.append(", stadium="); - if (stadium != null) { - sb.append('"').append(stadium.toString()).append('"'); - } else { - sb.append(""); - } - sb.append('}'); - return sb.toString(); + return "City{" + + "mayor='" + mayor + '\'' + + ", stadium=" + stadium + + '}'; } - } diff --git a/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/model/Lists.java b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/model/Lists.java new file mode 100644 index 00000000000..a53ffbbf99c --- /dev/null +++ b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/model/Lists.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2020, 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.common.model; + +import java.util.Iterator; +import java.util.List; +import java.util.Objects; + +/** + * {@link List} utility. + */ +public abstract class Lists { + + private Lists() { + // cannot be instantiated + } + + /** + * Compare two lists. + * + * @param actual actual + * @param other other + * @param element type + * @return {@code true} if both lists are equal + */ + public static boolean equals(List actual, List other) { + if (actual == other) { + return true; + } + if (actual == null || other == null || actual.size() != other.size()) { + return false; + } + Iterator actualIt = actual.iterator(); + Iterator otherIt = other.iterator(); + while (actualIt.hasNext() && otherIt.hasNext()) { + T actualElt = actualIt.next(); + T otherElt = otherIt.next(); + if (!Objects.equals(actualElt, otherElt)) { + return false; + } + } + return !actualIt.hasNext() && !otherIt.hasNext(); + } +} diff --git a/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/model/Pokemon.java b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/model/Pokemon.java new file mode 100644 index 00000000000..f00f9994813 --- /dev/null +++ b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/model/Pokemon.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2020, 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.common.model; + +import java.io.Serializable; +import java.util.List; +import java.util.Objects; + +import jakarta.persistence.*; + +/** + * {@code Pokemon} entity. + */ +@Entity +@SuppressWarnings("JpaDataSourceORMInspection") +public class Pokemon implements Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.TABLE) + private int id; + + @ManyToOne + @JoinColumn(name = "trainer_id") + private Trainer trainer; + + @ManyToMany + @JoinTable( + name = "pokemon_type", + joinColumns = @JoinColumn(name = "type_id", referencedColumnName = "id"), + inverseJoinColumns = @JoinColumn(name = "pokemon_id", referencedColumnName = "id"), + uniqueConstraints = @UniqueConstraint(columnNames = {"type_id", "pokemon_id"}) + ) + private List types; + + private String name; + + private int cp; + + public Pokemon() { + } + + public Pokemon(Trainer trainer, String name, int cp, List types) { + this.trainer = trainer; + this.name = name; + this.cp = cp; + this.types = types; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Trainer getTrainer() { + return trainer; + } + + public void setTrainer(Trainer trainer) { + this.trainer = trainer; + } + + public List getTypes() { + return types; + } + + public void setTypes(List types) { + this.types = types; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getCp() { + return cp; + } + + public void setCp(int cp) { + this.cp = cp; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Pokemon pokemon)) { + return false; + } + return id == pokemon.id + && cp == pokemon.cp + && Objects.equals(trainer, pokemon.trainer) + && Objects.equals(name, pokemon.name) + && Lists.equals(types, pokemon.types); + } + + @Override + public int hashCode() { + return Objects.hash(id, trainer, types, name, cp); + } + + @Override + public String toString() { + return "Pokemon{" + + "id=" + id + + ", trainer=" + trainer + + ", types=" + types + + ", name='" + name + '\'' + + ", cp=" + cp + + '}'; + } +} diff --git a/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/model/PokemonDataSet.java b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/model/PokemonDataSet.java new file mode 100644 index 00000000000..aef8a37fc9e --- /dev/null +++ b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/model/PokemonDataSet.java @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2020, 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.common.model; + +import java.util.List; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.context.Initialized; +import jakarta.enterprise.event.Observes; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import jakarta.transaction.Transactional; + +/** + * {@code Pokemon} data set. + */ +@ApplicationScoped +@SuppressWarnings("SpellCheckingInspection") +public class PokemonDataSet { + + private final Type normal = new Type(1, "Normal"); + private final Type fighting = new Type(2, "Fighting"); + private final Type flying = new Type(3, "Flying"); + private final Type poison = new Type(4, "Poison"); + private final Type ground = new Type(5, "Ground"); + private final Type rock = new Type(6, "Rock"); + private final Type bug = new Type(7, "Bug"); + private final Type ghost = new Type(8, "Ghost"); + private final Type steel = new Type(9, "Steel"); + private final Type fire = new Type(10, "Fire"); + private final Type water = new Type(11, "Water"); + private final Type grass = new Type(12, "Grass"); + private final Type electric = new Type(13, "Electric"); + private final Type psychic = new Type(14, "Psychic"); + private final Type ice = new Type(15, "Ice"); + private final Type dragon = new Type(16, "Dragon"); + private final Type dark = new Type(17, "Dark"); + private final Type fairy = new Type(18, "Fairy"); + + private final Trainer ash = new Trainer("Ash Ketchum", 10); + private final Trainer misty = new Trainer("Misty", 10); + private final Trainer brock = new Trainer("Brock", 12); + private final Trainer giovanni = new Trainer("Giovanni", 37); + private final Trainer erika = new Trainer("Erika", 16); + private final Trainer sabrina = new Trainer("Sabrina", 23); + + private final Pokemon pikachu = new Pokemon(ash, "Pikachu", 252, List.of(electric)); + private final Pokemon caterpie = new Pokemon(ash, "Caterpie", 123, List.of(bug)); + private final Pokemon charmander = new Pokemon(ash, "Charmander", 207, List.of(fire)); + private final Pokemon squirtle = new Pokemon(ash, "Squirtle", 187, List.of(water)); + private final Pokemon bulbasaur = new Pokemon(ash, "Bulbasaur", 204, List.of(grass, poison)); + private final Pokemon pidgey = new Pokemon(ash, "Pidgey", 107, List.of(normal, flying)); + + private final Pokemon staryu = new Pokemon(misty, "Staryu", 184, List.of(water)); + private final Pokemon psyduck = new Pokemon(misty, "Psyduck", 92, List.of(water)); + private final Pokemon corsola = new Pokemon(misty, "Corsola", 147, List.of(rock)); + private final Pokemon horsea = new Pokemon(misty, "Horsea", 64, List.of(water)); + private final Pokemon azurill = new Pokemon(misty, "Azurill", 217, List.of(normal, fairy)); + private final Pokemon togepi = new Pokemon(misty, "Togepi", 51, List.of(fairy)); + + private final Pokemon geodude = new Pokemon(brock, "Geodude", 236, List.of(rock, ground)); + private final Pokemon onix = new Pokemon(brock, "Onix", 251, List.of(rock, ground)); + private final Pokemon rhyhorn = new Pokemon(brock, "Rhyhorn", 251, List.of(rock, ground)); + private final Pokemon slowpoke = new Pokemon(brock, "Slowpoke", 251, List.of(water, psychic)); + private final Pokemon teddiursa = new Pokemon(brock, "Teddiursa", 275, List.of(normal)); + private final Pokemon omanyte = new Pokemon(brock, "Omanyte", 275, List.of(rock, water)); + + private final Pokemon rhyperior = new Pokemon(giovanni, "Rhyperior", 3841, List.of(ground, rock)); + private final Pokemon golem = new Pokemon(giovanni, "Golem", 3651, List.of(ground, rock)); + private final Pokemon nidoking = new Pokemon(giovanni, "Nidoking", 2451, List.of(ground, poison)); + private final Pokemon marowak = new Pokemon(giovanni, "Marowak", 2249, List.of(ground)); + private final Pokemon sandslash = new Pokemon(giovanni, "Sandslash", 1953, List.of(ground)); + private final Pokemon nidoqueen = new Pokemon(giovanni, "Nidoqueen", 3147, List.of(ground)); + + private final Pokemon alakazam = new Pokemon(sabrina, "Alakazam", 2178, List.of(psychic)); + private final Pokemon espeon = new Pokemon(sabrina, "Espeon", 2745, List.of(psychic)); + private final Pokemon pokemon = new Pokemon(sabrina, "Mr. Mime", 1478, List.of(psychic)); + private final Pokemon jynx = new Pokemon(sabrina, "Jynx", 2471, List.of(psychic, ice)); + private final Pokemon wobbuffet = new Pokemon(sabrina, "Wobbuffet", 1478, List.of(psychic)); + private final Pokemon gallade = new Pokemon(sabrina, "Gallade", 2147, List.of(psychic, fighting)); + + private final Pokemon gloom = new Pokemon(erika, "Gloom", 651, List.of(grass, poison)); + private final Pokemon victreebel = new Pokemon(erika, "Victreebel", 751, List.of(grass, poison)); + private final Pokemon tangela = new Pokemon(erika, "Tangela", 234, List.of(grass)); + private final Pokemon vileplume = new Pokemon(erika, "Vileplume", 1571, List.of(grass, poison)); + private final Pokemon weepinbell = new Pokemon(erika, "Weepinbell", 1923, List.of(grass, poison)); + private final Pokemon exeggcute = new Pokemon(erika, "Exeggcute", 317, List.of(grass, psychic)); + + private final Stadium viridianGym = new Stadium("Viridian Gym", giovanni); + private final Stadium celadonGym = new Stadium("Celadon Gym", erika); + private final Stadium saffronGym = new Stadium("Saffron Gym", sabrina); + + private final City viridian = new City("Viridian City", "Koichi", viridianGym); + private final City celadon = new City("Celadon City", "Madam Celadon", celadonGym); + private final City saffron = new City("Saffron City", "Koichi", saffronGym); + + private final List allTypes = List.of( + normal, fighting, flying, poison, ground, rock, bug, ghost, steel, fire, + water, grass, electric, psychic, ice, dragon, dark, fairy); + + private final List allPokemons = List.of( + pikachu, caterpie, charmander, squirtle, bulbasaur, pidgey, + staryu, psyduck, corsola, horsea, azurill, togepi, geodude, onix, rhyhorn, slowpoke, teddiursa, omanyte, rhyperior, + golem, nidoking, marowak, sandslash, nidoqueen, alakazam, espeon, pokemon, jynx, wobbuffet, gallade, gloom, + victreebel, tangela, vileplume, weepinbell, exeggcute); + + private final List allTrainers = List.of(ash, misty, brock, giovanni, erika, sabrina); + private final List allStadiums = List.of(viridianGym, celadonGym, saffronGym); + private final List allCities = List.of(viridian, celadon, saffron); + + @PersistenceContext(unitName = "test") + private EntityManager em; + + @Transactional + private void setup(@Observes @Initialized(ApplicationScoped.class) Object event) { + allTypes.forEach(em::persist); + allTrainers.forEach(em::persist); + allPokemons.forEach(em::persist); + allStadiums.forEach(em::persist); + allCities.forEach(em::persist); + em.flush(); + em.clear(); + em.getEntityManagerFactory().getCache().evictAll(); + } + + /** + * Get Ash. + * + * @return Trainer + */ + public Trainer ash() { + return ash; + } + + /** + * Get the water type. + * + * @return Type + */ + public Type water() { + return water; + } + + /** + * Get the poison type. + * + * @return Type + */ + public Type poison() { + return poison; + } + + /** + * Get the normal type. + * + * @return Type + */ + public Type normal() { + return normal; + } + + /** + * Get the electric type. + * + * @return Type + */ + public Type electric() { + return electric; + } + + /** + * Get the flying type. + * + * @return Type + */ + public Type flying() { + return flying; + } + + /** + * Get the fire type. + * + * @return Type + */ + public Type fire() { + return fire; + } +} diff --git a/tests/integration/jpa/model/src/main/java/io/helidon/tests/integration/jpa/model/Settlement.java b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/model/Settlement.java similarity index 61% rename from tests/integration/jpa/model/src/main/java/io/helidon/tests/integration/jpa/model/Settlement.java rename to tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/model/Settlement.java index eb4c0749482..d3f628f99db 100644 --- a/tests/integration/jpa/model/src/main/java/io/helidon/tests/integration/jpa/model/Settlement.java +++ b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/model/Settlement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022 Oracle and/or its affiliates. + * Copyright (c) 2020, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.helidon.tests.integration.jpa.model; +package io.helidon.tests.integration.jpa.common.model; import java.util.Objects; @@ -23,7 +23,7 @@ import jakarta.persistence.MappedSuperclass; /** - * Settlement in pokemon world. + * Settlement in {@code Pokemon} world. */ @MappedSuperclass public class Settlement { @@ -58,42 +58,26 @@ public void setName(String name) { } @Override - public boolean equals(Object oth) { - if (this == oth) { + public boolean equals(Object o) { + if (this == o) { return true; } - if (oth == null) { + if (!(o instanceof Settlement that)) { return false; } - if (oth instanceof Settlement) { - return id == ((Settlement)oth).id - && Objects.equals(name, ((Settlement)oth).name); - } - return false; + return id == that.id && Objects.equals(name, that.name); } @Override public int hashCode() { - int hashCode = id; - if (name != null) { - hashCode = hashCode * 31 + name.hashCode(); - } - return hashCode; + return Objects.hash(id, name); } @Override public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("Settlement: {id="); - sb.append(id); - sb.append(", name="); - if (name != null) { - sb.append('"').append(name).append('"'); - } else { - sb.append(""); - } - sb.append('}'); - return sb.toString(); + return "Settlement{" + + "id=" + id + + ", name='" + name + '\'' + + '}'; } - } diff --git a/tests/integration/jpa/model/src/main/java/io/helidon/tests/integration/jpa/model/Stadium.java b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/model/Stadium.java similarity index 93% rename from tests/integration/jpa/model/src/main/java/io/helidon/tests/integration/jpa/model/Stadium.java rename to tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/model/Stadium.java index f3932403e2d..c9ab62ba1bc 100644 --- a/tests/integration/jpa/model/src/main/java/io/helidon/tests/integration/jpa/model/Stadium.java +++ b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/model/Stadium.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022 Oracle and/or its affiliates. + * Copyright (c) 2020, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,16 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.helidon.tests.integration.jpa.model; +package io.helidon.tests.integration.jpa.common.model; import java.util.Objects; import jakarta.persistence.*; /** - * Pokemon stadium. + * {@code Pokemon} stadium. */ @Entity +@SuppressWarnings("JpaDataSourceORMInspection") public class Stadium { @Id diff --git a/tests/integration/jpa/model/src/main/java/io/helidon/tests/integration/jpa/model/Trainer.java b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/model/Trainer.java similarity index 63% rename from tests/integration/jpa/model/src/main/java/io/helidon/tests/integration/jpa/model/Trainer.java rename to tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/model/Trainer.java index 2e79bbf7e8a..d2e05db3ada 100644 --- a/tests/integration/jpa/model/src/main/java/io/helidon/tests/integration/jpa/model/Trainer.java +++ b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/model/Trainer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022 Oracle and/or its affiliates. + * Copyright (c) 2020, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.helidon.tests.integration.jpa.model; +package io.helidon.tests.integration.jpa.common.model; import java.io.Serializable; import java.util.List; @@ -69,7 +69,7 @@ public int getAge() { public void setAge(int age) { this.age = age; } - + public List getPokemons() { return pokemons; } @@ -79,48 +79,29 @@ public void setPokemons(List pokemons) { } @Override - public boolean equals(Object oth) { - if (this == oth) { + public boolean equals(Object o) { + if (this == o) { return true; } - if (oth == null) { + if (!(o instanceof Trainer trainer)) { return false; } - if (oth instanceof Trainer) { - return id == ((Trainer)oth).id - && age == ((Trainer)oth).age - && Objects.equals(name, ((Trainer)oth).name); - } - return false; + return id == trainer.id + && age == trainer.age + && Objects.equals(name, trainer.name); } @Override public int hashCode() { - int hashCode = id; - if (name != null) { - hashCode = hashCode * 31 + name.hashCode(); - } - if (age != 0) { - hashCode = hashCode * 31 + age; - } - return hashCode; + return Objects.hash(id, name, age, pokemons); } @Override public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("Trainer: {id="); - sb.append(id); - sb.append(", name="); - if (name != null) { - sb.append('"').append(name).append('"'); - } else { - sb.append(""); - } - sb.append(", age="); - sb.append(age); - sb.append('}'); - return sb.toString(); + return "Trainer{" + + "id=" + id + + ", name='" + name + '\'' + + ", age=" + age + + '}'; } - } diff --git a/tests/integration/jpa/model/src/main/java/io/helidon/tests/integration/jpa/model/Type.java b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/model/Type.java similarity index 66% rename from tests/integration/jpa/model/src/main/java/io/helidon/tests/integration/jpa/model/Type.java rename to tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/model/Type.java index 4358a623180..401f67ab643 100644 --- a/tests/integration/jpa/model/src/main/java/io/helidon/tests/integration/jpa/model/Type.java +++ b/tests/integration/jpa/common/src/main/java/io/helidon/tests/integration/jpa/common/model/Type.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021 Oracle and/or its affiliates. + * Copyright (c) 2020, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.helidon.tests.integration.jpa.model; +package io.helidon.tests.integration.jpa.common.model; import java.io.Serializable; import java.util.Objects; @@ -29,7 +29,7 @@ public class Type implements Serializable { @Id private int id; - + private String name; public Type() { @@ -57,37 +57,26 @@ public void setName(String name) { } @Override - public boolean equals(Object oth) { - if (this == oth) { + public boolean equals(Object o) { + if (this == o) { return true; } - if (oth == null) { + if (!(o instanceof Type type)) { return false; } - if (oth instanceof Type) { - return id == ((Type)oth).id && Objects.equals(name, ((Type)oth).name); - } - return false; + return id == type.id && Objects.equals(name, type.name); } @Override public int hashCode() { - return 31 * id + (name != null ? name.hashCode() : 0); + return Objects.hash(id, name); } @Override public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("Type: {id="); - sb.append(id); - sb.append(", name="); - if (name != null) { - sb.append('"').append(name).append('"'); - } else { - sb.append(""); - } - sb.append('}'); - return sb.toString(); + return "Type{" + + "id=" + id + + ", name='" + name + '\'' + + '}'; } - } diff --git a/tests/integration/jpa/appl/src/main/resources/META-INF/beans.xml b/tests/integration/jpa/common/src/main/resources/META-INF/beans.xml similarity index 94% rename from tests/integration/jpa/appl/src/main/resources/META-INF/beans.xml rename to tests/integration/jpa/common/src/main/resources/META-INF/beans.xml index e1f8b242429..d0922683055 100644 --- a/tests/integration/jpa/appl/src/main/resources/META-INF/beans.xml +++ b/tests/integration/jpa/common/src/main/resources/META-INF/beans.xml @@ -1,7 +1,7 @@ + --> - io.helidon.tests.integration.jpa.model.City - io.helidon.tests.integration.jpa.model.Stadium - io.helidon.tests.integration.jpa.model.Type - io.helidon.tests.integration.jpa.model.Trainer - io.helidon.tests.integration.jpa.model.Pokemon + io.helidon.tests.integration.jpa.common.model.Type + io.helidon.tests.integration.jpa.common.model.Trainer + io.helidon.tests.integration.jpa.common.model.Pokemon + io.helidon.tests.integration.jpa.common.model.Stadium + io.helidon.tests.integration.jpa.common.model.City - + - - diff --git a/tests/integration/jpa/h2/README.md b/tests/integration/jpa/h2/README.md new file mode 100644 index 00000000000..188543c6568 --- /dev/null +++ b/tests/integration/jpa/h2/README.md @@ -0,0 +1,6 @@ +# JPA Integration Test H2 + +To run this test: +```shell +mvn clean verify +``` diff --git a/tests/integration/jpa/h2/pom.xml b/tests/integration/jpa/h2/pom.xml new file mode 100644 index 00000000000..436d5a57f60 --- /dev/null +++ b/tests/integration/jpa/h2/pom.xml @@ -0,0 +1,67 @@ + + + + + 4.0.0 + + io.helidon.tests.integration.jpa + helidon-tests-integration-jpa-parent + 4.1.0-SNAPSHOT + ../parent/pom.xml + + helidon-tests-integration-jpa-h2 + Helidon Tests Integration JPA H2 + + + + io.helidon.integrations.db + h2 + + + com.h2database + h2 + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-libs + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + + integration-test + verify + + + + + + + diff --git a/tests/integration/jpa/simple/src/test/resources/META-INF/microprofile-config.properties b/tests/integration/jpa/h2/src/main/resources/META-INF/microprofile-config.properties similarity index 80% rename from tests/integration/jpa/simple/src/test/resources/META-INF/microprofile-config.properties rename to tests/integration/jpa/h2/src/main/resources/META-INF/microprofile-config.properties index d7e8bc6db9e..07bb64db95a 100644 --- a/tests/integration/jpa/simple/src/test/resources/META-INF/microprofile-config.properties +++ b/tests/integration/jpa/h2/src/main/resources/META-INF/microprofile-config.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2021 Oracle and/or its affiliates. +# Copyright (c) 2024 Oracle and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,10 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - -mp.initializer.allow=true -mp.initializer.no-warn=true +server.port=0 +features.print-details=true javax.sql.DataSource.test.dataSource.url=jdbc:h2:mem:test;INIT=SET TRACE_LEVEL_FILE=4 javax.sql.DataSource.test.dataSource.user=sa -javax.sql.DataSource.test.dataSource.password=${EMPTY} -javax.sql.DataSource.test.dataSourceClassName=org.h2.jdbcx.JdbcDataSource \ No newline at end of file +javax.sql.DataSource.test.dataSource.password= +javax.sql.DataSource.test.dataSourceClassName=org.h2.jdbcx.JdbcDataSource diff --git a/tests/integration/jpa/appl/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension b/tests/integration/jpa/h2/src/main/resources/logging.properties similarity index 82% rename from tests/integration/jpa/appl/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension rename to tests/integration/jpa/h2/src/main/resources/logging.properties index e9c3dcb5083..d590b197673 100644 --- a/tests/integration/jpa/appl/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension +++ b/tests/integration/jpa/h2/src/main/resources/logging.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2019 Oracle and/or its affiliates. +# Copyright (c) 2024 Oracle and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,4 +14,5 @@ # limitations under the License. # -io.helidon.tests.integration.jpa.appl.test.LifeCycleExtension +handlers=org.slf4j.bridge.SLF4JBridgeHandler +.level=INFO diff --git a/tests/integration/jpa/h2/src/main/resources/simplelogger.properties b/tests/integration/jpa/h2/src/main/resources/simplelogger.properties new file mode 100644 index 00000000000..7e96c6fca94 --- /dev/null +++ b/tests/integration/jpa/h2/src/main/resources/simplelogger.properties @@ -0,0 +1,27 @@ +# +# Copyright (c) 2024 Oracle and/or its affiliates. +# +# Licensed 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. +# +<<<<<<<< HEAD:tests/integration/packaging/mp-3/src/main/resources/META-INF/native-image/io.helidon.tests.integration.packaging/helidon-tests-integration-packaging-mp-3/native-image.properties + +Args=--initialize-at-build-time=io.helidon.tests.integration.packaging.mp3 +======== +org.slf4j.simpleLogger.defaultLogLevel=warn +org.slf4j.simpleLogger.showThreadName=false +org.slf4j.simpleLogger.log.org.testcontainers=info +org.slf4j.simpleLogger.log.org.testcontainers.utility=error +org.slf4j.simpleLogger.log.io.helidon=info +org.slf4j.simpleLogger.log.org.hibernate=info +org.slf4j.simpleLogger.log.com.zaxxer=info +>>>>>>>> f00b85e2dc (pipeline updates !!!!!):tests/integration/jpa/h2/src/main/resources/simplelogger.properties diff --git a/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2DeleteLocalTestIT.java b/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2DeleteLocalTestIT.java new file mode 100644 index 00000000000..038f0f47604 --- /dev/null +++ b/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2DeleteLocalTestIT.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.h2; + +import io.helidon.microprofile.testing.junit5.HelidonTest; +import io.helidon.tests.integration.jpa.common.DeleteTest; +import io.helidon.tests.integration.jpa.common.DeleteTestImpl; + +import jakarta.inject.Inject; +import org.junit.jupiter.api.Test; + +/** + * Local delete test. + */ +@HelidonTest +class H2DeleteLocalTestIT extends H2LocalTest implements DeleteTest { + + @Inject + private DeleteTestImpl delegate; + + @Test + @Override + public void testDeleteEntity() { + delegate.testDeleteEntity(); + } + + @Test + @Override + public void testDeleteJPQL() { + delegate.testDeleteJPQL(); + } + + @Test + @Override + public void testDeleteCriteria() { + delegate.testDeleteCriteria(); + } + + @Test + @Override + public void testDeleteCity() { + delegate.testDeleteCity(); + } +} diff --git a/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2DeleteRemoteTestIT.java b/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2DeleteRemoteTestIT.java new file mode 100644 index 00000000000..ae474b13c7c --- /dev/null +++ b/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2DeleteRemoteTestIT.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.h2; + +import io.helidon.tests.integration.jpa.common.DeleteTest; + +import org.junit.jupiter.api.Test; + +/** + * Remote delete test. + */ +class H2DeleteRemoteTestIT extends H2RemoteTest implements DeleteTest { + + H2DeleteRemoteTestIT() { + super("/test/delete"); + } + + @Test + @Override + public void testDeleteEntity() { + remoteTest(); + } + + @Test + @Override + public void testDeleteJPQL() { + remoteTest(); + } + + @Test + @Override + public void testDeleteCriteria() { + remoteTest(); + } + + @Test + @Override + public void testDeleteCity() { + remoteTest(); + } +} diff --git a/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2InsertLocalTestIT.java b/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2InsertLocalTestIT.java new file mode 100644 index 00000000000..8981c7954fe --- /dev/null +++ b/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2InsertLocalTestIT.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.h2; + +import io.helidon.microprofile.testing.junit5.HelidonTest; +import io.helidon.tests.integration.jpa.common.InsertTest; +import io.helidon.tests.integration.jpa.common.InsertTestImpl; + +import jakarta.inject.Inject; +import org.junit.jupiter.api.Test; + +/** + * Local insert test. + */ +@HelidonTest +class H2InsertLocalTestIT extends H2LocalTest implements InsertTest { + + @Inject + private InsertTestImpl delegate; + + @Test + @Override + public void testInsertType() { + delegate.testInsertType(); + } + + @Test + @Override + public void testInsertTrainerWithPokemons() { + delegate.testInsertTrainerWithPokemons(); + } + + @Test + @Override + public void testTownWithStadium() { + delegate.testTownWithStadium(); + } +} diff --git a/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2InsertRemoteTestIT.java b/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2InsertRemoteTestIT.java new file mode 100644 index 00000000000..685a2c25dd6 --- /dev/null +++ b/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2InsertRemoteTestIT.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.h2; + +import io.helidon.tests.integration.jpa.common.InsertTest; + +import org.junit.jupiter.api.Test; + +/** + * Local insert test. + */ +class H2InsertRemoteTestIT extends H2RemoteTest implements InsertTest { + + H2InsertRemoteTestIT() { + super("/test/insert"); + } + + @Test + @Override + public void testInsertType() { + remoteTest(); + } + + @Test + @Override + public void testInsertTrainerWithPokemons() { + remoteTest(); + } + + @Test + @Override + public void testTownWithStadium() { + remoteTest(); + } +} diff --git a/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2LocalTest.java b/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2LocalTest.java new file mode 100644 index 00000000000..872b7ccf27b --- /dev/null +++ b/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2LocalTest.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.h2; + +/** + * Base class for the local tests. + */ +abstract class H2LocalTest { +} diff --git a/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2QueryLocalTestIT.java b/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2QueryLocalTestIT.java new file mode 100644 index 00000000000..dc664d8c32b --- /dev/null +++ b/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2QueryLocalTestIT.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.h2; + +import io.helidon.microprofile.testing.junit5.HelidonTest; +import io.helidon.tests.integration.jpa.common.QueryTest; +import io.helidon.tests.integration.jpa.common.QueryTestImpl; + +import jakarta.inject.Inject; +import org.junit.jupiter.api.Test; + +/** + * Local query test. + */ +@HelidonTest +class H2QueryLocalTestIT extends H2LocalTest implements QueryTest { + + @Inject + private QueryTestImpl delegate; + + @Test + @Override + public void testFind() { + delegate.testFind(); + } + + @Test + @Override + public void testQueryJPQL() { + delegate.testQueryJPQL(); + } + + @Test + @Override + public void testQueryCriteria() { + delegate.testQueryCriteria(); + } + + @Test + @Override + public void testQueryCeladonJPQL() { + delegate.testQueryCeladonJPQL(); + } + + @Test + @Override + public void testQueryCeladonCriteria() { + delegate.testQueryCeladonCriteria(); + } +} diff --git a/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2QueryRemoteTestIT.java b/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2QueryRemoteTestIT.java new file mode 100644 index 00000000000..6e5efa662f3 --- /dev/null +++ b/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2QueryRemoteTestIT.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.h2; + +import io.helidon.tests.integration.jpa.common.QueryTest; + +import org.junit.jupiter.api.Test; + +/** + * Invoke {@code /test/query} endpoints. + */ +class H2QueryRemoteTestIT extends H2RemoteTest implements QueryTest { + + H2QueryRemoteTestIT() { + super("/test/query"); + } + + @Test + @Override + public void testFind() { + remoteTest(); + } + + @Test + @Override + public void testQueryJPQL() { + remoteTest(); + } + + @Test + @Override + public void testQueryCriteria() { + remoteTest(); + } + + @Test + @Override + public void testQueryCeladonJPQL() { + remoteTest(); + } + + @Test + @Override + public void testQueryCeladonCriteria() { + remoteTest(); + } +} diff --git a/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2RemoteTest.java b/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2RemoteTest.java new file mode 100644 index 00000000000..9e74622fd7d --- /dev/null +++ b/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2RemoteTest.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.h2; + +import java.nio.file.Path; +import java.util.Map; + +import io.helidon.tests.integration.harness.ProcessRunner; +import io.helidon.tests.integration.harness.ProcessRunner.ExecMode; +import io.helidon.tests.integration.harness.WaitStrategy; +import io.helidon.tests.integration.harness.TestProcess; +import io.helidon.tests.integration.harness.TestProcesses; +import io.helidon.tests.integration.jpa.common.RemoteTest; + +/** + * Base class for the remote tests. + */ +@TestProcesses +abstract class H2RemoteTest extends RemoteTest { + @TestProcess + static final ProcessRunner PROCESS_RUNNER = ProcessRunner.of(ExecMode.CLASS_PATH) + .finalName("helidon-tests-integration-jpa-h2") + .properties(Map.of("java.util.logging.config.file", Path.of("target/classes/logging.properties").toAbsolutePath())) + .waitingFor(WaitStrategy.waitForPort()); + + /** + * Create a new instance. + * + * @param path base path + */ + @SuppressWarnings("resource") + H2RemoteTest(String path) { + super(path, PROCESS_RUNNER.process().port()); + } +} diff --git a/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2UpdateLocalTestIT.java b/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2UpdateLocalTestIT.java new file mode 100644 index 00000000000..bf9e4e6ec50 --- /dev/null +++ b/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2UpdateLocalTestIT.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.h2; + +import io.helidon.microprofile.testing.junit5.HelidonTest; +import io.helidon.tests.integration.jpa.common.UpdateTest; +import io.helidon.tests.integration.jpa.common.UpdateTestImpl; + +import jakarta.inject.Inject; +import org.junit.jupiter.api.Test; + +/** + * Local update test. + */ +@HelidonTest +class H2UpdateLocalTestIT extends H2LocalTest implements UpdateTest { + + @Inject + private UpdateTestImpl delegate; + + @Test + @Override + public void testUpdateEntity() { + delegate.testUpdateEntity(); + } + + @Test + @Override + public void testUpdateJPQL() { + delegate.testUpdateJPQL(); + } + + @Test + @Override + public void testUpdateCriteria() { + delegate.testUpdateCriteria(); + } + + @Test + @Override + public void testUpdateCity() { + delegate.testUpdateCity(); + } +} diff --git a/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2UpdateRemoteTestIT.java b/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2UpdateRemoteTestIT.java new file mode 100644 index 00000000000..17f44afd39c --- /dev/null +++ b/tests/integration/jpa/h2/src/test/java/io/helidon/tests/integration/jpa/h2/H2UpdateRemoteTestIT.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.h2; + +import io.helidon.tests.integration.jpa.common.UpdateTest; + +import org.junit.jupiter.api.Test; + +/** + * Invoke {@code /test/update} endpoints. + */ +class H2UpdateRemoteTestIT extends H2RemoteTest implements UpdateTest { + + H2UpdateRemoteTestIT() { + super("/test/update"); + } + + @Test + @Override + public void testUpdateEntity() { + remoteTest(); + } + + @Test + @Override + public void testUpdateJPQL() { + remoteTest(); + } + + @Test + @Override + public void testUpdateCriteria() { + remoteTest(); + } + + @Test + @Override + public void testUpdateCity() { + remoteTest(); + } +} diff --git a/tests/integration/jpa/model/src/main/java/io/helidon/tests/integration/jpa/dao/Create.java b/tests/integration/jpa/model/src/main/java/io/helidon/tests/integration/jpa/dao/Create.java deleted file mode 100644 index 899dbae50cc..00000000000 --- a/tests/integration/jpa/model/src/main/java/io/helidon/tests/integration/jpa/dao/Create.java +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.dao; - -import java.util.Arrays; -import java.util.List; - -import jakarta.persistence.EntityManager; - -import io.helidon.tests.integration.jpa.model.City; -import io.helidon.tests.integration.jpa.model.Pokemon; -import io.helidon.tests.integration.jpa.model.Stadium; -import io.helidon.tests.integration.jpa.model.Trainer; -import io.helidon.tests.integration.jpa.model.Type; - -/** - * Create data for the tests. - */ -public class Create { - - private Create() { - throw new UnsupportedOperationException("Instances of Create class are not allowed"); - } - - /** - * Insert pokemon types. - * - * @param em Entity manager instance - */ - public static void dbInsertTypes(final EntityManager em) { - em.persist(new Type(1, "Normal")); - em.persist(new Type(2, "Fighting")); - em.persist(new Type(3, "Flying")); - em.persist(new Type(4, "Poison")); - em.persist(new Type(5, "Ground")); - em.persist(new Type(6, "Rock")); - em.persist(new Type(7, "Bug")); - em.persist(new Type(8, "Ghost")); - em.persist(new Type(9, "Steel")); - em.persist(new Type(10, "Fire")); - em.persist(new Type(11, "Water")); - em.persist(new Type(12, "Grass")); - em.persist(new Type(13, "Electric")); - em.persist(new Type(14, "Psychic")); - em.persist(new Type(15, "Ice")); - em.persist(new Type(16, "Dragon")); - em.persist(new Type(17, "Dark")); - em.persist(new Type(18, "Fairy")); - em.flush(); - } - - /** - * Insert trainer Ash and his pokemons. - * Ash and his pokemons are used for query tests only. - * - * @param em Entity manager instance - * @return ID of the trainer (Ash) - */ - public static int dbInsertAsh(final EntityManager em) { - Trainer trainer = new Trainer("Ash Ketchum", 10); - Type normal = em.find(Type.class, 1); - Type flying = em.find(Type.class, 3); - Type poison = em.find(Type.class, 4); - Type bug = em.find(Type.class, 7); - Type fire = em.find(Type.class, 10); - Type water = em.find(Type.class, 11); - Type grass = em.find(Type.class, 12); - Type electric = em.find(Type.class, 13); - em.persist(trainer); - em.persist(new Pokemon(trainer, "Pikachu", 252, Arrays.asList(electric))); - em.persist(new Pokemon(trainer, "Caterpie", 123, Arrays.asList(bug))); - em.persist(new Pokemon(trainer, "Charmander", 207, Arrays.asList(fire))); - em.persist(new Pokemon(trainer, "Squirtle", 187, Arrays.asList(water))); - em.persist(new Pokemon(trainer, "Bulbasaur", 204, Arrays.asList(grass, poison))); - em.persist(new Pokemon(trainer, "Pidgey", 107, Arrays.asList(normal, flying))); - em.flush(); - return trainer.getId(); - } - - /** - * Create Brock and his pokemons. - * Brock and his pokemons are used for update tests only. - * - * @param em Entity manager instance - */ - public static void dbInsertBrock(final EntityManager em) { - Trainer trainer = new Trainer("Brock", 12); - Type normal = em.find(Type.class, 1); - Type ground = em.find(Type.class, 5); - Type rock = em.find(Type.class, 6); - Type water = em.find(Type.class, 11); - Type psychic = em.find(Type.class, 14); - List types = Arrays.asList(rock, ground); - em.persist(trainer); - em.persist(new Pokemon(trainer, "Geodude", 236, types)); - em.persist(new Pokemon(trainer, "Onix", 251, types)); - em.persist(new Pokemon(trainer, "Rhyhorn", 251, types)); - em.persist(new Pokemon(trainer, "Slowpoke", 251, Arrays.asList(water, psychic))); - em.persist(new Pokemon(trainer, "Teddiursa", 275, Arrays.asList(normal))); - em.persist(new Pokemon(trainer, "Omanyte", 275, Arrays.asList(rock, water))); - em.flush(); - em.clear(); - em.getEntityManagerFactory().getCache().evictAll(); - } - - /** - * Create Misty and her pokemons. - * Misty and her pokemons are used for delete tests only. - * - * @param em Entity manager instance - */ - public static void dbInsertMisty(final EntityManager em) { - Trainer trainer = new Trainer("Misty", 10); - Type normal = em.find(Type.class, 1); - Type rock = em.find(Type.class, 6); - Type water = em.find(Type.class, 11); - Type fairy = em.find(Type.class, 18); - em.persist(trainer); - em.persist(new Pokemon(trainer, "Staryu", 184, Arrays.asList(water))); - em.persist(new Pokemon(trainer, "Psyduck", 92, Arrays.asList(water))); - em.persist(new Pokemon(trainer, "Corsola", 147, Arrays.asList(rock))); - em.persist(new Pokemon(trainer, "Horsea", 64, Arrays.asList(water))); - em.persist(new Pokemon(trainer, "Azurill", 217, Arrays.asList(normal, fairy))); - em.persist(new Pokemon(trainer, "Togepi", 51, Arrays.asList(fairy))); - em.flush(); - em.clear(); - em.getEntityManagerFactory().getCache().evictAll(); - } - - /** - * Create Celadon City with stadium and trainer. - * Used for query tests only. - */ - public static void dbInsertCeladon(final EntityManager em) { - Type poison = em.find(Type.class, 4); - Type grass = em.find(Type.class, 12); - Type psychic = em.find(Type.class, 14); - Trainer trainer = new Trainer("Erika", 16); - Stadium stadium = new Stadium("Celadon Gym", trainer); - City city = new City("Celadon City", "Madam Celadon", stadium); - em.persist(trainer); - em.persist(new Pokemon(trainer, "Gloom", 651, Arrays.asList(grass, poison))); - em.persist(new Pokemon(trainer, "Victreebel", 751, Arrays.asList(grass, poison))); - em.persist(new Pokemon(trainer, "Tangela", 234, Arrays.asList(grass))); - em.persist(new Pokemon(trainer, "Vileplume", 1571, Arrays.asList(grass, poison))); - em.persist(new Pokemon(trainer, "Weepinbell", 1923, Arrays.asList(grass, poison))); - em.persist(new Pokemon(trainer, "Exeggcute", 317, Arrays.asList(grass, psychic))); - //em.persist(stadium); - em.persist(city); - } - - /** - * Create Saffron City with stadium and trainer. - * Used for update tests only. - */ - public static void dbInsertSaffron(final EntityManager em) { - Type fighting = em.find(Type.class, 2); - Type psychic = em.find(Type.class, 14); - Type ice = em.find(Type.class, 15); - Trainer trainer = new Trainer("Sabrina", 23); - Stadium stadium = new Stadium("Saffron Gym", trainer); - City city = new City("Saffron City", "Koichi", stadium); - em.persist(trainer); - em.persist(new Pokemon(trainer, "Alakazam", 2178, Arrays.asList(psychic))); - em.persist(new Pokemon(trainer, "Espeon", 2745, Arrays.asList(psychic))); - em.persist(new Pokemon(trainer, "Mr. Mime", 1478, Arrays.asList(psychic))); - em.persist(new Pokemon(trainer, "Jynx", 2471, Arrays.asList(psychic, ice))); - em.persist(new Pokemon(trainer, "Wobbuffet", 1478, Arrays.asList(psychic))); - em.persist(new Pokemon(trainer, "Gallade", 2147, Arrays.asList(psychic, fighting))); - //em.persist(stadium); - em.persist(city); - } - - /** - * Create Viridian City with stadium and trainer. - * Used for delete tests only. - */ - public static void dbInsertViridian(final EntityManager em) { - Type poison = em.find(Type.class, 4); - Type ground = em.find(Type.class, 5); - Type rock = em.find(Type.class, 6); - Trainer trainer = new Trainer("Giovanni", 37); - Stadium stadium = new Stadium("Viridian Gym", trainer); - City city = new City("Viridian City", "Koichi", stadium); - em.persist(trainer); - em.persist(new Pokemon(trainer, "Rhyperior", 3841, Arrays.asList(ground, rock))); - em.persist(new Pokemon(trainer, "Golem", 3651, Arrays.asList(ground, rock))); - em.persist(new Pokemon(trainer, "Nidoking", 2451, Arrays.asList(ground, poison))); - em.persist(new Pokemon(trainer, "Marowak", 2249, Arrays.asList(ground))); - em.persist(new Pokemon(trainer, "Sandslash", 1953, Arrays.asList(ground))); - em.persist(new Pokemon(trainer, "Nidoqueen", 3147, Arrays.asList(ground))); - //em.persist(stadium); - em.persist(city); - } - -} diff --git a/tests/integration/jpa/model/src/main/java/io/helidon/tests/integration/jpa/dao/Delete.java b/tests/integration/jpa/model/src/main/java/io/helidon/tests/integration/jpa/dao/Delete.java deleted file mode 100644 index 51b51412943..00000000000 --- a/tests/integration/jpa/model/src/main/java/io/helidon/tests/integration/jpa/dao/Delete.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.dao; - -import java.util.List; - -import jakarta.persistence.EntityManager; - -import io.helidon.tests.integration.jpa.model.City; -import io.helidon.tests.integration.jpa.model.Pokemon; -import io.helidon.tests.integration.jpa.model.Stadium; -import io.helidon.tests.integration.jpa.model.Trainer; - -/** - * Delete data for the tests. - */ -public class Delete { - - private Delete() { - throw new UnsupportedOperationException("Instances of Delete class are not allowed"); - } - - /** - * Delete Brock and his pokemons. - * Brock and his pokemons are used for update tests only. - * - * @param em Entity manager instance - */ - public static void dbDeleteBrock(final EntityManager em) { - dbDeleteTrainerAndHisPokemons(em, "Brock"); - } - - /** - * Delete Misty and her pokemons. - * Misty and her pokemons are used for delete tests only. - * - * @param em Entity manager instance - */ - public static void dbDeleteMisty(final EntityManager em) { - dbDeleteTrainerAndHisPokemons(em, "Misty"); - } - - /** - * Delete Ash and his pokemons. - * Ash and his pokemons are used for delete tests only. - * - * @param em Entity manager instance - */ - public static void dbDeleteAsh(final EntityManager em) { - dbDeleteTrainerAndHisPokemons(em, "Ash Ketchum"); - } - - /** - * Delete Celadon City. - * Celadon City is used for query tests only. - * - * @param em Entity manager instance - */ - public static void dbDeleteCeladon(final EntityManager em) { - dbDeleteCity(em, "Celadon City"); - } - - /** - * Delete Saffron City. - * Saffron City is used for update tests only. - * - * @param em Entity manager instance - */ - public static void dbDeleteSaffron(final EntityManager em) { - dbDeleteCity(em, "Saffron City"); - } - - /** - * Delete Viridian City. - * Viridian City is used for update tests only. - * - * @param em Entity manager instance - */ - public static void dbDeleteViridian(final EntityManager em) { - dbDeleteCity(em, "Viridian City"); - } - - /** - * Delete city. - * - * @param em Entity manager instance - * @param name name of city to delete - */ - public static void dbDeleteCity(final EntityManager em, final String name) { - List cities = em.createQuery( - "SELECT c FROM City c WHERE c.name = :name", City.class) - .setParameter("name", name) - .getResultList(); - if (!cities.isEmpty()) { - cities.forEach((city) -> { - Stadium stadium = city.getStadium(); - Trainer trainer = stadium.getTrainer(); - List pokemons = trainer.getPokemons(); - em.remove(city); - //em.remove(stadium); - pokemons.forEach((pokemon) -> em.remove(pokemon)); - em.remove(trainer); - }); - } - } - - /** - * Delete trainer and his pokemons. - * Trainer is identified by his name. - * - * @param em Entity manager instance - * @param name name of trainer to delete - */ - public static void dbDeleteTrainerAndHisPokemons(final EntityManager em, final String name) { - List trainers = em.createQuery( - "SELECT t FROM Trainer t WHERE t.name = :name", Trainer.class) - .setParameter("name", name) - .getResultList(); - if (!trainers.isEmpty()) { - trainers.forEach((trainer) -> { - List pokemons = em.createQuery( - "SELECT p FROM Pokemon p INNER JOIN p.trainer t WHERE t.name = :name", Pokemon.class) - .setParameter("name", name) - .getResultList(); - pokemons.forEach((pokemon) -> em.remove(pokemon)); - em.remove(trainer); - }); - } - } - - /** - * Delete all pokemons. - * - * @param em Entity manager instance - */ - public static void deletePokemons(final EntityManager em) { - em.createQuery("DELETE FROM Pokemon").executeUpdate(); - } - - /** - * Delete all trainers. - * - * @param em Entity manager instance - */ - public static void deleteTrainers(final EntityManager em) { - em.createQuery("DELETE FROM Trainer").executeUpdate(); - } - - /** - * Delete all types. - * - * @param em Entity manager instance - */ - public static void deleteTypes(final EntityManager em) { - em.createQuery("DELETE FROM Type").executeUpdate(); - } - - /** - * Delete all cities. - * - * @param em Entity manager instance - */ - public static void deleteCities(final EntityManager em) { - em.createQuery("DELETE FROM City").executeUpdate(); - } - - /** - * Delete all stadiums. - * - * @param em Entity manager instance - */ - public static void deleteStadiums(final EntityManager em) { - em.createQuery("DELETE FROM Stadium").executeUpdate(); - } - - /** - * Delete all database records. - * - * @param em Entity manager instance - */ - public static void dbCleanup(final EntityManager em) { - deleteCities(em); - deleteStadiums(em); - deletePokemons(em); - deleteTrainers(em); - deleteTypes(em); - } - -} diff --git a/tests/integration/jpa/model/src/main/java/io/helidon/tests/integration/jpa/model/Pokemon.java b/tests/integration/jpa/model/src/main/java/io/helidon/tests/integration/jpa/model/Pokemon.java deleted file mode 100644 index 44cbed6fb77..00000000000 --- a/tests/integration/jpa/model/src/main/java/io/helidon/tests/integration/jpa/model/Pokemon.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2020, 2023 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.model; - -import java.io.Serializable; -import java.lang.System.Logger.Level; -import java.util.Iterator; -import java.util.List; -import java.util.Objects; - -import jakarta.persistence.*; - -/** - * Pokemon entity. - */ -@Entity -public class Pokemon implements Serializable { - - private static final System.Logger LOGGER = System.getLogger(Pokemon.class.getName()); - - @Id - @GeneratedValue(strategy = GenerationType.TABLE) - private int id; - - @ManyToOne - @JoinColumn(name = "trainer_id") - private Trainer trainer; - - @ManyToMany - @JoinTable( - name="pokemon_type", - joinColumns=@JoinColumn(name="type_id", referencedColumnName="id"), - inverseJoinColumns=@JoinColumn(name="pokemon_id", referencedColumnName="id"), - uniqueConstraints=@UniqueConstraint(columnNames={"type_id", "pokemon_id"}) - ) - private List types; - - private String name; - - private int cp; - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("Pokemon: {id="); - sb.append(id); - sb.append(", name="); - if (name != null) { - sb.append('"').append(name).append('"'); - } else { - sb.append(""); - } - sb.append(", cp="); - sb.append(cp); - sb.append(", trainer="); - sb.append(trainer != null ? trainer.toString() : ""); - sb.append(", types="); - sb.append(types != null ? types.toString() : ""); - return sb.toString(); - } - - public Pokemon() { - } - - public Pokemon(Trainer trainer, String name, int cp, List types) { - this.trainer = trainer; - this.name = name; - this.cp = cp; - this.types = types; - } - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public Trainer getTrainer() { - return trainer; - } - - public void setTrainer(Trainer trainer) { - this.trainer = trainer; - } - - public List getTypes() { - return types; - } - - public void setTypes(List types) { - this.types = types; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public int getCp() { - return cp; - } - - public void setCp(int cp) { - this.cp = cp; - } - - @Override - public boolean equals(Object oth) { - if (this == oth) { - return true; - } - if (oth == null) { - return false; - } - if (oth instanceof Pokemon) { - return id == ((Pokemon)oth).id - && cp == ((Pokemon)oth).cp - && Objects.equals(name, ((Pokemon)oth).name) - && Objects.equals(trainer, ((Pokemon)oth).trainer) - && listEquals(((Pokemon)oth).types); - } - LOGGER.log(Level.WARNING, () -> String.format("Pokemon instanceof failed: %s", oth.getClass().getName())); - return false; - } - - private boolean listEquals(List other) { - if (this.types == other) { - return true; - } - if (this.types == null && other != null - || this.types != null && other == null - || this.types.size() != other.size()) { - return false; - } - Iterator otherIterator = other.iterator(); - for (Type thisType : this.types) { - Type otherType = otherIterator.next(); - if ( (thisType != otherType) && ( thisType == null || !thisType.equals(otherType)) ) { - return false; - } - } - return true; - } - - @Override - public int hashCode() { - int hashCode = id; - if (name != null) { - hashCode = hashCode * 31 + name.hashCode(); - } - if (trainer != null) { - hashCode = hashCode * 31 + trainer.hashCode(); - } - if (cp != 0) { - hashCode = hashCode * 31 + cp; - } - if (types != null) { - for (Type type : types) { - hashCode = hashCode * 31 + type.hashCode(); - } - } - return hashCode; - } - -} diff --git a/tests/integration/jpa/mysql/README.md b/tests/integration/jpa/mysql/README.md new file mode 100644 index 00000000000..13d6b1e1b16 --- /dev/null +++ b/tests/integration/jpa/mysql/README.md @@ -0,0 +1,17 @@ +# JPA Integration Test MySQL + +To run this test: +```shell +mvn clean verify +``` + +Start the database: +```shell +docker run -d \ + --name mysql \ + -e MYSQL_DATABASE=test \ + -e MYSQL_USER=test \ + -e MYSQL_PASSWORD=mysql123 \ + -p 3306:3306 \ + container-registry.oracle.com/mysql/community-server:latest +``` diff --git a/tests/integration/jpa/mysql/pom.xml b/tests/integration/jpa/mysql/pom.xml new file mode 100644 index 00000000000..a1e333a8f09 --- /dev/null +++ b/tests/integration/jpa/mysql/pom.xml @@ -0,0 +1,72 @@ + + + + + 4.0.0 + + io.helidon.tests.integration.jpa + helidon-tests-integration-jpa-parent + 4.1.0-SNAPSHOT + ../parent/pom.xml + + helidon-tests-integration-jpa-mysql + Helidon Tests Integration JPA MySQL + + + + io.helidon.integrations.db + helidon-integrations-db-mysql + + + com.mysql + mysql-connector-j + + + org.testcontainers + mysql + test + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-libs + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + + integration-test + verify + + + + + + + diff --git a/tests/integration/jpa/mysql/src/main/resources/META-INF/microprofile-config.properties b/tests/integration/jpa/mysql/src/main/resources/META-INF/microprofile-config.properties new file mode 100644 index 00000000000..3ef12d51593 --- /dev/null +++ b/tests/integration/jpa/mysql/src/main/resources/META-INF/microprofile-config.properties @@ -0,0 +1,21 @@ +# +# Copyright (c) 2024 Oracle and/or its affiliates. +# +# Licensed 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. +# +server.port=0 +features.print-details=true +javax.sql.DataSource.test.dataSource.url=jdbc:mysql://localhost:3306/test?useSSL=false&allowPublicKeyRetrieval=true +javax.sql.DataSource.test.dataSource.user=test +javax.sql.DataSource.test.dataSource.password=mysql123 +javax.sql.DataSource.test.dataSourceClassName=com.mysql.cj.jdbc.MysqlDataSource diff --git a/tests/integration/jpa/simple/src/test/resources/hibernate.properties b/tests/integration/jpa/mysql/src/main/resources/logging.properties similarity index 71% rename from tests/integration/jpa/simple/src/test/resources/hibernate.properties rename to tests/integration/jpa/mysql/src/main/resources/logging.properties index e27b413cc73..d590b197673 100644 --- a/tests/integration/jpa/simple/src/test/resources/hibernate.properties +++ b/tests/integration/jpa/mysql/src/main/resources/logging.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2023 Oracle and/or its affiliates. +# Copyright (c) 2024 Oracle and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,7 +14,5 @@ # limitations under the License. # -# Byte code for JPA must be generated at compile time. -# This is a limitation of native image -# No longer supported with Hibernate 6.3.x -# hibernate.bytecode.provider=none +handlers=org.slf4j.bridge.SLF4JBridgeHandler +.level=INFO diff --git a/tests/integration/jpa/mysql/src/main/resources/simplelogger.properties b/tests/integration/jpa/mysql/src/main/resources/simplelogger.properties new file mode 100644 index 00000000000..fcc605df165 --- /dev/null +++ b/tests/integration/jpa/mysql/src/main/resources/simplelogger.properties @@ -0,0 +1,22 @@ +# +# Copyright (c) 2024 Oracle and/or its affiliates. +# +# Licensed 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. +# +org.slf4j.simpleLogger.defaultLogLevel=warn +org.slf4j.simpleLogger.showThreadName=false +org.slf4j.simpleLogger.log.org.testcontainers=info +org.slf4j.simpleLogger.log.org.testcontainers.utility=error +org.slf4j.simpleLogger.log.io.helidon=info +org.slf4j.simpleLogger.log.org.hibernate=info +org.slf4j.simpleLogger.log.com.zaxxer=info diff --git a/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLDeleteLocalTestIT.java b/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLDeleteLocalTestIT.java new file mode 100644 index 00000000000..36a7aa259c5 --- /dev/null +++ b/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLDeleteLocalTestIT.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.mysql; + +import io.helidon.microprofile.testing.junit5.HelidonTest; +import io.helidon.tests.integration.jpa.common.DeleteTest; +import io.helidon.tests.integration.jpa.common.DeleteTestImpl; + +import jakarta.inject.Inject; +import org.junit.jupiter.api.Test; + +/** + * Local delete test. + */ +@HelidonTest +class MySQLDeleteLocalTestIT extends MySQLLocalTest implements DeleteTest { + + @Inject + private DeleteTestImpl delegate; + + @Test + @Override + public void testDeleteEntity() { + delegate.testDeleteEntity(); + } + + @Test + @Override + public void testDeleteJPQL() { + delegate.testDeleteJPQL(); + } + + @Test + @Override + public void testDeleteCriteria() { + delegate.testDeleteCriteria(); + } + + @Test + @Override + public void testDeleteCity() { + delegate.testDeleteCity(); + } +} diff --git a/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLDeleteRemoteTestIT.java b/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLDeleteRemoteTestIT.java new file mode 100644 index 00000000000..5209aa9d0a4 --- /dev/null +++ b/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLDeleteRemoteTestIT.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.mysql; + +import io.helidon.tests.integration.jpa.common.DeleteTest; + +import org.junit.jupiter.api.Test; + +/** + * Remote delete test. + */ +class MySQLDeleteRemoteTestIT extends MySQLRemoteTest implements DeleteTest { + + MySQLDeleteRemoteTestIT() { + super("/test/delete"); + } + + @Test + @Override + public void testDeleteEntity() { + remoteTest(); + } + + @Test + @Override + public void testDeleteJPQL() { + remoteTest(); + } + + @Test + @Override + public void testDeleteCriteria() { + remoteTest(); + } + + @Test + @Override + public void testDeleteCity() { + remoteTest(); + } +} diff --git a/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLInsertLocalTestIT.java b/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLInsertLocalTestIT.java new file mode 100644 index 00000000000..143e9c0622a --- /dev/null +++ b/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLInsertLocalTestIT.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.mysql; + +import io.helidon.microprofile.testing.junit5.HelidonTest; +import io.helidon.tests.integration.jpa.common.InsertTest; +import io.helidon.tests.integration.jpa.common.InsertTestImpl; + +import jakarta.inject.Inject; +import org.junit.jupiter.api.Test; + +/** + * Local insert test. + */ +@HelidonTest +class MySQLInsertLocalTestIT extends MySQLLocalTest implements InsertTest { + + @Inject + private InsertTestImpl delegate; + + @Test + @Override + public void testInsertType() { + delegate.testInsertType(); + } + + @Test + @Override + public void testInsertTrainerWithPokemons() { + delegate.testInsertTrainerWithPokemons(); + } + + @Test + @Override + public void testTownWithStadium() { + delegate.testTownWithStadium(); + } +} diff --git a/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLInsertRemoteTestIT.java b/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLInsertRemoteTestIT.java new file mode 100644 index 00000000000..5a0fc1f22ca --- /dev/null +++ b/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLInsertRemoteTestIT.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.mysql; + +import io.helidon.tests.integration.jpa.common.InsertTest; + +import org.junit.jupiter.api.Test; + +/** + * Local insert test. + */ +class MySQLInsertRemoteTestIT extends MySQLRemoteTest implements InsertTest { + + MySQLInsertRemoteTestIT() { + super("/test/insert"); + } + + @Test + @Override + public void testInsertType() { + remoteTest(); + } + + @Test + @Override + public void testInsertTrainerWithPokemons() { + remoteTest(); + } + + @Test + @Override + public void testTownWithStadium() { + remoteTest(); + } +} diff --git a/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLLocalTest.java b/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLLocalTest.java new file mode 100644 index 00000000000..a679f073b63 --- /dev/null +++ b/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLLocalTest.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.mysql; + +import java.util.Map; + +import io.helidon.microprofile.testing.junit5.AddConfigMap; + +import org.testcontainers.containers.MySQLContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +/** + * Base class for the local tests. + */ +@Testcontainers(disabledWithoutDocker = true) +abstract class MySQLLocalTest { + + @Container + static final MySQLContainer CONTAINER = MySQLTestContainer.CONTAINER; + + @AddConfigMap + static Map config() { + return MySQLTestContainer.config(); + } +} diff --git a/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLQueryLocalTestIT.java b/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLQueryLocalTestIT.java new file mode 100644 index 00000000000..9a9a7f61ae6 --- /dev/null +++ b/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLQueryLocalTestIT.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.mysql; + +import io.helidon.microprofile.testing.junit5.HelidonTest; +import io.helidon.tests.integration.jpa.common.QueryTest; +import io.helidon.tests.integration.jpa.common.QueryTestImpl; + +import jakarta.inject.Inject; +import org.junit.jupiter.api.Test; + +/** + * Local query test. + */ +@HelidonTest +class MySQLQueryLocalTestIT extends MySQLLocalTest implements QueryTest { + + @Inject + private QueryTestImpl delegate; + + @Test + @Override + public void testFind() { + delegate.testFind(); + } + + @Test + @Override + public void testQueryJPQL() { + delegate.testQueryJPQL(); + } + + @Test + @Override + public void testQueryCriteria() { + delegate.testQueryCriteria(); + } + + @Test + @Override + public void testQueryCeladonJPQL() { + delegate.testQueryCeladonJPQL(); + } + + @Test + @Override + public void testQueryCeladonCriteria() { + delegate.testQueryCeladonCriteria(); + } +} diff --git a/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLQueryRemoteTestIT.java b/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLQueryRemoteTestIT.java new file mode 100644 index 00000000000..35ccec68805 --- /dev/null +++ b/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLQueryRemoteTestIT.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.mysql; + +import io.helidon.tests.integration.jpa.common.QueryTest; + +import org.junit.jupiter.api.Test; + +/** + * Invoke {@code /test/query} endpoints. + */ +class MySQLQueryRemoteTestIT extends MySQLRemoteTest implements QueryTest { + + MySQLQueryRemoteTestIT() { + super("/test/query"); + } + + @Test + @Override + public void testFind() { + remoteTest(); + } + + @Test + @Override + public void testQueryJPQL() { + remoteTest(); + } + + @Test + @Override + public void testQueryCriteria() { + remoteTest(); + } + + @Test + @Override + public void testQueryCeladonJPQL() { + remoteTest(); + } + + @Test + @Override + public void testQueryCeladonCriteria() { + remoteTest(); + } +} diff --git a/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLRemoteTest.java b/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLRemoteTest.java new file mode 100644 index 00000000000..00ba026cc83 --- /dev/null +++ b/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLRemoteTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.mysql; + +import java.nio.file.Path; +import java.util.Map; + +import io.helidon.tests.integration.harness.ProcessRunner; +import io.helidon.tests.integration.harness.ProcessRunner.ExecMode; +import io.helidon.tests.integration.harness.WaitStrategy; +import io.helidon.tests.integration.harness.TestProcess; +import io.helidon.tests.integration.harness.TestProcesses; +import io.helidon.tests.integration.jpa.common.RemoteTest; + +import org.testcontainers.containers.MySQLContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +/** + * Base class for the remote tests. + */ +@Testcontainers(disabledWithoutDocker = true) +@TestProcesses +abstract class MySQLRemoteTest extends RemoteTest { + + @Container + static final MySQLContainer CONTAINER = MySQLTestContainer.CONTAINER; + + @TestProcess + static final ProcessRunner PROCESS_RUNNER = ProcessRunner.of(ExecMode.CLASS_PATH) + .finalName("helidon-tests-integration-jpa-mysql") + .properties(Map.of("java.util.logging.config.file", Path.of("target/classes/logging.properties").toAbsolutePath())) + .properties(MySQLTestContainer::config) + .waitingFor(WaitStrategy.waitForPort()); + + /** + * Create a new instance. + * + * @param path base path + */ + @SuppressWarnings("resource") + MySQLRemoteTest(String path) { + super(path, PROCESS_RUNNER.process().port()); + } +} diff --git a/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLTestContainer.java b/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLTestContainer.java new file mode 100644 index 00000000000..921bf4f641d --- /dev/null +++ b/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLTestContainer.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.mysql; + +import java.util.Map; + +import org.testcontainers.containers.MySQLContainer; +import org.testcontainers.utility.DockerImageName; + +/** + * Database container utility. + */ +abstract class MySQLTestContainer { + + private static final DockerImageName IMAGE = DockerImageName.parse("container-registry.oracle.com/mysql/community-server") + .asCompatibleSubstituteFor("mysql"); + + static final MySQLContainer CONTAINER = new MySQLContainer<>(IMAGE) + .withPassword("mysql123"); + + static Map config() { + return Map.of("javax.sql.DataSource.test.dataSource.url", CONTAINER.getJdbcUrl()); + } + + private MySQLTestContainer() { + } +} diff --git a/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLUpdateLocalTestIT.java b/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLUpdateLocalTestIT.java new file mode 100644 index 00000000000..26a9c1b65a1 --- /dev/null +++ b/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLUpdateLocalTestIT.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.mysql; + +import io.helidon.microprofile.testing.junit5.HelidonTest; +import io.helidon.tests.integration.jpa.common.UpdateTest; +import io.helidon.tests.integration.jpa.common.UpdateTestImpl; + +import jakarta.inject.Inject; +import org.junit.jupiter.api.Test; + +/** + * Local update test. + */ +@HelidonTest +class MySQLUpdateLocalTestIT extends MySQLLocalTest implements UpdateTest { + + @Inject + private UpdateTestImpl delegate; + + @Test + @Override + public void testUpdateEntity() { + delegate.testUpdateEntity(); + } + + @Test + @Override + public void testUpdateJPQL() { + delegate.testUpdateJPQL(); + } + + @Test + @Override + public void testUpdateCriteria() { + delegate.testUpdateCriteria(); + } + + @Test + @Override + public void testUpdateCity() { + delegate.testUpdateCity(); + } +} diff --git a/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLUpdateRemoteTestIT.java b/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLUpdateRemoteTestIT.java new file mode 100644 index 00000000000..7c9b43b4fdc --- /dev/null +++ b/tests/integration/jpa/mysql/src/test/java/io/helidon/tests/integration/jpa/mysql/MySQLUpdateRemoteTestIT.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.mysql; + +import io.helidon.tests.integration.jpa.common.UpdateTest; + +import org.junit.jupiter.api.Test; + +/** + * Invoke {@code /test/update} endpoints. + */ +class MySQLUpdateRemoteTestIT extends MySQLRemoteTest implements UpdateTest { + + MySQLUpdateRemoteTestIT() { + super("/test/update"); + } + + @Test + @Override + public void testUpdateEntity() { + remoteTest(); + } + + @Test + @Override + public void testUpdateJPQL() { + remoteTest(); + } + + @Test + @Override + public void testUpdateCriteria() { + remoteTest(); + } + + @Test + @Override + public void testUpdateCity() { + remoteTest(); + } +} diff --git a/tests/integration/jpa/oracle/README.md b/tests/integration/jpa/oracle/README.md new file mode 100644 index 00000000000..55996fb990b --- /dev/null +++ b/tests/integration/jpa/oracle/README.md @@ -0,0 +1,15 @@ +# JPA Integration Test Oracle + +To run this test: +```shell +mvn clean verify +``` + +Start the database: +```shell +docker run -d \ + -name oracledb \ + -e ORACLE_PWD=oracle123 \ + -p 1521:1521 \ + container-registry.oracle.com/database/express:latest +``` diff --git a/tests/integration/jpa/oracle/pom.xml b/tests/integration/jpa/oracle/pom.xml new file mode 100644 index 00000000000..31c632480d2 --- /dev/null +++ b/tests/integration/jpa/oracle/pom.xml @@ -0,0 +1,63 @@ + + + + + 4.0.0 + + io.helidon.tests.integration.jpa + helidon-tests-integration-jpa-parent + 4.1.0-SNAPSHOT + ../parent/pom.xml + + helidon-tests-integration-jpa-oracle + Helidon Tests Integration JPA Oracle + + + + io.helidon.integrations.db + ojdbc + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-libs + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + + integration-test + verify + + + + + + + diff --git a/tests/integration/jpa/oracle/src/main/resources/META-INF/microprofile-config.properties b/tests/integration/jpa/oracle/src/main/resources/META-INF/microprofile-config.properties new file mode 100644 index 00000000000..f3a405a66ec --- /dev/null +++ b/tests/integration/jpa/oracle/src/main/resources/META-INF/microprofile-config.properties @@ -0,0 +1,21 @@ +# +# Copyright (c) 2024 Oracle and/or its affiliates. +# +# Licensed 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. +# +server.port=0 +features.print-details=true +javax.sql.DataSource.test.dataSource.url=jdbc:oracle:thin:@localhost:1521/XE +javax.sql.DataSource.test.dataSource.user=system +javax.sql.DataSource.test.dataSource.password=oracle123 +javax.sql.DataSource.test.dataSourceClassName=oracle.jdbc.pool.OracleDataSource diff --git a/tests/integration/jpa/appl/src/main/resources/hibernate.properties b/tests/integration/jpa/oracle/src/main/resources/logging.properties similarity index 70% rename from tests/integration/jpa/appl/src/main/resources/hibernate.properties rename to tests/integration/jpa/oracle/src/main/resources/logging.properties index 19ea0ba7e87..d590b197673 100644 --- a/tests/integration/jpa/appl/src/main/resources/hibernate.properties +++ b/tests/integration/jpa/oracle/src/main/resources/logging.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2023 Oracle and/or its affiliates. +# Copyright (c) 2024 Oracle and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,7 +14,5 @@ # limitations under the License. # -# Byte code for JPA must be generated at compile time. -# This is a limitation of native image -# No longer supported with Hibernate 6.3.x -# hibernate.bytecode.provider=none +handlers=org.slf4j.bridge.SLF4JBridgeHandler +.level=INFO diff --git a/tests/integration/jpa/oracle/src/main/resources/simplelogger.properties b/tests/integration/jpa/oracle/src/main/resources/simplelogger.properties new file mode 100644 index 00000000000..fcc605df165 --- /dev/null +++ b/tests/integration/jpa/oracle/src/main/resources/simplelogger.properties @@ -0,0 +1,22 @@ +# +# Copyright (c) 2024 Oracle and/or its affiliates. +# +# Licensed 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. +# +org.slf4j.simpleLogger.defaultLogLevel=warn +org.slf4j.simpleLogger.showThreadName=false +org.slf4j.simpleLogger.log.org.testcontainers=info +org.slf4j.simpleLogger.log.org.testcontainers.utility=error +org.slf4j.simpleLogger.log.io.helidon=info +org.slf4j.simpleLogger.log.org.hibernate=info +org.slf4j.simpleLogger.log.com.zaxxer=info diff --git a/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleDeleteLocalTestIT.java b/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleDeleteLocalTestIT.java new file mode 100644 index 00000000000..4ec2fc729aa --- /dev/null +++ b/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleDeleteLocalTestIT.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.oracle; + +import io.helidon.microprofile.testing.junit5.HelidonTest; +import io.helidon.tests.integration.jpa.common.DeleteTest; +import io.helidon.tests.integration.jpa.common.DeleteTestImpl; + +import jakarta.inject.Inject; +import org.junit.jupiter.api.Test; + +/** + * Local delete test. + */ +@HelidonTest +class OracleDeleteLocalTestIT extends OracleLocalTest implements DeleteTest { + + @Inject + private DeleteTestImpl delegate; + + @Test + @Override + public void testDeleteEntity() { + delegate.testDeleteEntity(); + } + + @Test + @Override + public void testDeleteJPQL() { + delegate.testDeleteJPQL(); + } + + @Test + @Override + public void testDeleteCriteria() { + delegate.testDeleteCriteria(); + } + + @Test + @Override + public void testDeleteCity() { + delegate.testDeleteCity(); + } +} diff --git a/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleDeleteRemoteTestIT.java b/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleDeleteRemoteTestIT.java new file mode 100644 index 00000000000..418d52cc209 --- /dev/null +++ b/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleDeleteRemoteTestIT.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.oracle; + +import io.helidon.tests.integration.jpa.common.DeleteTest; + +import org.junit.jupiter.api.Test; + +/** + * Remote delete test. + */ +class OracleDeleteRemoteTestIT extends OracleRemoteTest implements DeleteTest { + + OracleDeleteRemoteTestIT() { + super("/test/delete"); + } + + @Test + @Override + public void testDeleteEntity() { + remoteTest(); + } + + @Test + @Override + public void testDeleteJPQL() { + remoteTest(); + } + + @Test + @Override + public void testDeleteCriteria() { + remoteTest(); + } + + @Test + @Override + public void testDeleteCity() { + remoteTest(); + } +} diff --git a/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleInsertLocalTestIT.java b/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleInsertLocalTestIT.java new file mode 100644 index 00000000000..cb7ff555443 --- /dev/null +++ b/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleInsertLocalTestIT.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.oracle; + +import io.helidon.microprofile.testing.junit5.HelidonTest; +import io.helidon.tests.integration.jpa.common.InsertTest; +import io.helidon.tests.integration.jpa.common.InsertTestImpl; + +import jakarta.inject.Inject; +import org.junit.jupiter.api.Test; + +/** + * Local insert test. + */ +@HelidonTest +class OracleInsertLocalTestIT extends OracleLocalTest implements InsertTest { + + @Inject + private InsertTestImpl delegate; + + @Test + @Override + public void testInsertType() { + delegate.testInsertType(); + } + + @Test + @Override + public void testInsertTrainerWithPokemons() { + delegate.testInsertTrainerWithPokemons(); + } + + @Test + @Override + public void testTownWithStadium() { + delegate.testTownWithStadium(); + } +} diff --git a/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleInsertRemoteTestIT.java b/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleInsertRemoteTestIT.java new file mode 100644 index 00000000000..ba4ec126bb5 --- /dev/null +++ b/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleInsertRemoteTestIT.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.oracle; + +import io.helidon.tests.integration.jpa.common.InsertTest; + +import org.junit.jupiter.api.Test; + +/** + * Local insert test. + */ +class OracleInsertRemoteTestIT extends OracleRemoteTest implements InsertTest { + + OracleInsertRemoteTestIT() { + super("/test/insert"); + } + + @Test + @Override + public void testInsertType() { + remoteTest(); + } + + @Test + @Override + public void testInsertTrainerWithPokemons() { + remoteTest(); + } + + @Test + @Override + public void testTownWithStadium() { + remoteTest(); + } +} diff --git a/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleLocalTest.java b/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleLocalTest.java new file mode 100644 index 00000000000..1e08543b269 --- /dev/null +++ b/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleLocalTest.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.oracle; + +import java.util.Map; + +import io.helidon.microprofile.testing.junit5.AddConfigMap; + +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +/** + * Base class for the local tests. + */ +@Testcontainers(disabledWithoutDocker = true) +abstract class OracleLocalTest { + + @Container + static final GenericContainer CONTAINER = OracleTestContainer.CONTAINER; + + @AddConfigMap + static Map config() { + return OracleTestContainer.config(); + } +} diff --git a/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleQueryLocalTestIT.java b/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleQueryLocalTestIT.java new file mode 100644 index 00000000000..63e0c943eeb --- /dev/null +++ b/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleQueryLocalTestIT.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.oracle; + +import io.helidon.microprofile.testing.junit5.HelidonTest; +import io.helidon.tests.integration.jpa.common.QueryTest; +import io.helidon.tests.integration.jpa.common.QueryTestImpl; + +import jakarta.inject.Inject; +import org.junit.jupiter.api.Test; + +/** + * Local query test. + */ +@HelidonTest +class OracleQueryLocalTestIT extends OracleLocalTest implements QueryTest { + + @Inject + private QueryTestImpl delegate; + + @Test + @Override + public void testFind() { + delegate.testFind(); + } + + @Test + @Override + public void testQueryJPQL() { + delegate.testQueryJPQL(); + } + + @Test + @Override + public void testQueryCriteria() { + delegate.testQueryCriteria(); + } + + @Test + @Override + public void testQueryCeladonJPQL() { + delegate.testQueryCeladonJPQL(); + } + + @Test + @Override + public void testQueryCeladonCriteria() { + delegate.testQueryCeladonCriteria(); + } +} diff --git a/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleQueryRemoteTestIT.java b/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleQueryRemoteTestIT.java new file mode 100644 index 00000000000..efb10393ff3 --- /dev/null +++ b/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleQueryRemoteTestIT.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.oracle; + +import io.helidon.tests.integration.jpa.common.QueryTest; + +import org.junit.jupiter.api.Test; + +/** + * Invoke {@code /test/query} endpoints. + */ +class OracleQueryRemoteTestIT extends OracleRemoteTest implements QueryTest { + + OracleQueryRemoteTestIT() { + super("/test/query"); + } + + @Test + @Override + public void testFind() { + remoteTest(); + } + + @Test + @Override + public void testQueryJPQL() { + remoteTest(); + } + + @Test + @Override + public void testQueryCriteria() { + remoteTest(); + } + + @Test + @Override + public void testQueryCeladonJPQL() { + remoteTest(); + } + + @Test + @Override + public void testQueryCeladonCriteria() { + remoteTest(); + } +} diff --git a/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleRemoteTest.java b/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleRemoteTest.java new file mode 100644 index 00000000000..aa9eeb6fd2d --- /dev/null +++ b/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleRemoteTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.oracle; + +import java.nio.file.Path; +import java.util.Map; + +import io.helidon.tests.integration.harness.ProcessRunner; +import io.helidon.tests.integration.harness.ProcessRunner.ExecMode; +import io.helidon.tests.integration.harness.WaitStrategy; +import io.helidon.tests.integration.harness.TestProcess; +import io.helidon.tests.integration.harness.TestProcesses; +import io.helidon.tests.integration.jpa.common.RemoteTest; + +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +/** + * Base class for the remote tests. + */ +@Testcontainers(disabledWithoutDocker = true) +@TestProcesses +abstract class OracleRemoteTest extends RemoteTest { + + @Container + static final GenericContainer CONTAINER = OracleTestContainer.CONTAINER; + + @TestProcess + static final ProcessRunner PROCESS_RUNNER = ProcessRunner.of(ExecMode.CLASS_PATH) + .finalName("helidon-tests-integration-jpa-oracle") + .properties(Map.of("java.util.logging.config.file", Path.of("target/classes/logging.properties").toAbsolutePath())) + .properties(OracleTestContainer::config) + .waitingFor(WaitStrategy.waitForPort()); + + /** + * Create a new instance. + * + * @param path base path + */ + @SuppressWarnings("resource") + OracleRemoteTest(String path) { + super(path, PROCESS_RUNNER.process().port()); + } +} diff --git a/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleTestContainer.java b/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleTestContainer.java new file mode 100644 index 00000000000..c752e2f40a2 --- /dev/null +++ b/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleTestContainer.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.oracle; + +import java.time.Duration; +import java.util.Map; + +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.utility.DockerImageName; + +/** + * Database container utility. + */ +abstract class OracleTestContainer { + + private static final DockerImageName IMAGE = DockerImageName.parse("container-registry.oracle.com/database/express"); + + static final GenericContainer CONTAINER = new GenericContainer<>(IMAGE) + .withEnv("ORACLE_PWD", "oracle123") + .withExposedPorts(1521) + .waitingFor(Wait.forHealthcheck() + .withStartupTimeout(Duration.ofMinutes(5))); + + static Map config() { + String jdbcUrl = String.format("jdbc:oracle:thin:@localhost:%s/XE", CONTAINER.getMappedPort(1521)); + return Map.of("javax.sql.DataSource.test.dataSource.url", jdbcUrl); + } + + private OracleTestContainer() { + } +} diff --git a/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleUpdateLocalTestIT.java b/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleUpdateLocalTestIT.java new file mode 100644 index 00000000000..192f4f40834 --- /dev/null +++ b/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleUpdateLocalTestIT.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.oracle; + +import io.helidon.microprofile.testing.junit5.HelidonTest; +import io.helidon.tests.integration.jpa.common.UpdateTest; +import io.helidon.tests.integration.jpa.common.UpdateTestImpl; + +import jakarta.inject.Inject; +import org.junit.jupiter.api.Test; + +/** + * Local update test. + */ +@HelidonTest +class OracleUpdateLocalTestIT extends OracleLocalTest implements UpdateTest { + + @Inject + private UpdateTestImpl delegate; + + @Test + @Override + public void testUpdateEntity() { + delegate.testUpdateEntity(); + } + + @Test + @Override + public void testUpdateJPQL() { + delegate.testUpdateJPQL(); + } + + @Test + @Override + public void testUpdateCriteria() { + delegate.testUpdateCriteria(); + } + + @Test + @Override + public void testUpdateCity() { + delegate.testUpdateCity(); + } +} diff --git a/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleUpdateRemoteTestIT.java b/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleUpdateRemoteTestIT.java new file mode 100644 index 00000000000..844afab2b0a --- /dev/null +++ b/tests/integration/jpa/oracle/src/test/java/io/helidon/tests/integration/jpa/oracle/OracleUpdateRemoteTestIT.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.oracle; + +import io.helidon.tests.integration.jpa.common.UpdateTest; + +import org.junit.jupiter.api.Test; + +/** + * Invoke {@code /test/update} endpoints. + */ +class OracleUpdateRemoteTestIT extends OracleRemoteTest implements UpdateTest { + + OracleUpdateRemoteTestIT() { + super("/test/update"); + } + + @Test + @Override + public void testUpdateEntity() { + remoteTest(); + } + + @Test + @Override + public void testUpdateJPQL() { + remoteTest(); + } + + @Test + @Override + public void testUpdateCriteria() { + remoteTest(); + } + + @Test + @Override + public void testUpdateCity() { + remoteTest(); + } +} diff --git a/tests/integration/jpa/parent/pom.xml b/tests/integration/jpa/parent/pom.xml new file mode 100644 index 00000000000..a603c423c1b --- /dev/null +++ b/tests/integration/jpa/parent/pom.xml @@ -0,0 +1,146 @@ + + + + + 4.0.0 + + io.helidon.applications + helidon-mp + 4.1.0-SNAPSHOT + ../../../../applications/mp/pom.xml + + io.helidon.tests.integration.jpa + helidon-tests-integration-jpa-parent + Helidon Tests Integration JPA Parent + pom + + + true + + + + + io.helidon.tests.integration.jpa + helidon-tests-integration-jpa-common + ${project.version} + + + io.helidon.logging + helidon-logging-slf4j + + + org.slf4j + jul-to-slf4j + + + org.slf4j + slf4j-simple + + + org.junit.jupiter + junit-jupiter-api + test + + + io.helidon.microprofile.testing + helidon-microprofile-testing-junit5 + test + + + + org.testcontainers + junit-jupiter + test + + + io.helidon.tests.integration + helidon-tests-integration-harness + ${project.version} + test + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/*IT + + + + ${project.build.outputDirectory}/logging.properties + + + ${redirectTestOutputToFile} + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + + ${project.build.testOutputDirectory}/logging.properties + + + ${redirectTestOutputToFile} + ${project.build.outputDirectory} + + + + + + + + remote + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + **/*RemoteTestIT + + + + + + + + local + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + **/*LocalTestIT + + + + + + + + diff --git a/tests/integration/jpa/pgsql/README.md b/tests/integration/jpa/pgsql/README.md new file mode 100644 index 00000000000..bcf023b65b3 --- /dev/null +++ b/tests/integration/jpa/pgsql/README.md @@ -0,0 +1,22 @@ +# JPA Integration Test PostgreSQL + +To run this test: +```shell +mvn clean verify +``` + +Build the database Docker image: +```shell +docker build etc/docker -t pgsql +``` + +Start the database: +```shell +docker run -d \ + --name pgsql \ + -e POSTGRES_USER=test \ + -e POSTGRES_PASSWORD=pgsql123 \ + -e POSTGRES_DB=test \ + -p 5432:5432 \ + pgsql +``` diff --git a/tests/integration/jpa/pgsql/etc/docker/Dockerfile b/tests/integration/jpa/pgsql/etc/docker/Dockerfile new file mode 100644 index 00000000000..cfc1a6240dd --- /dev/null +++ b/tests/integration/jpa/pgsql/etc/docker/Dockerfile @@ -0,0 +1,28 @@ +# +# Copyright (c) 2024 Oracle and/or its affiliates. +# +# Licensed 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. +# + +FROM oraclelinux:9-slim + +RUN microdnf install postgresql-server && microdnf clean all +ADD entrypoint.sh /usr/local/bin/ + +ENV PGDATA /var/lib/pgsql/data +USER postgres +ENTRYPOINT ["entrypoint.sh"] +STOPSIGNAL SIGINT +EXPOSE 5432 +CMD ["postgres"] + diff --git a/tests/integration/jpa/pgsql/etc/docker/entrypoint.sh b/tests/integration/jpa/pgsql/etc/docker/entrypoint.sh new file mode 100755 index 00000000000..701e1e3a4e1 --- /dev/null +++ b/tests/integration/jpa/pgsql/etc/docker/entrypoint.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2024 Oracle and/or its affiliates. +# +# Licensed 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. +# +set -Eeo pipefail + +PGDATA="${PGDATA:-/var/lib/pgsql/data}" + +# initialize the data directory +initdb \ + --username="${POSTGRES_USER:-test}" \ + --pwfile=<(printf "%s" "${POSTGRES_PASSWORD:-test}") \ + -D "${PGDATA}" + +# update config file +# - listen on all network interfaces +# - turn off logging collector to log to the console +sed -e "s/^#listen_addresses = 'localhost'/listen_addresses = '*'/g" \ + -e "s/logging_collector = on/logging_collector = off/g" \ + -e "s/^#session_replication_role = 'origin'/session_replication_role = '${POSTGRES_SRR:-origin}'/g" \ + -i "${PGDATA}/postgresql.conf" + +# enabling trust for all connections +printf 'host all all all %s\n' "$(postgres -C password_encryption)" >> "${PGDATA}/pg_hba.conf" + +# temporary start to create the database +pg_ctl -D "${PGDATA}" -w start +psql \ + --username "${POSTGRES_USER:-test}" \ + --no-password \ + --dbname postgres \ + --set db="${POSTGRES_DB:-test}" <<-'EOSQL' + create database :"db"; + set session_replication_role = replica; +EOSQL +pg_ctl -D "${PGDATA}" -m fast -w stop + +exec "${@}" diff --git a/tests/integration/jpa/pgsql/pom.xml b/tests/integration/jpa/pgsql/pom.xml new file mode 100644 index 00000000000..28475c5020a --- /dev/null +++ b/tests/integration/jpa/pgsql/pom.xml @@ -0,0 +1,72 @@ + + + + + 4.0.0 + + io.helidon.tests.integration.jpa + helidon-tests-integration-jpa-parent + 4.1.0-SNAPSHOT + ../parent/pom.xml + + helidon-tests-integration-jpa-pgsql + Helidon Tests Integration JPA PostgreSQL + + + + io.helidon.integrations.db + helidon-integrations-db-pgsql + + + org.postgresql + postgresql + + + org.testcontainers + jdbc + test + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-libs + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + + integration-test + verify + + + + + + + diff --git a/tests/integration/jpa/appl/src/main/resources/META-INF/microprofile-config.properties b/tests/integration/jpa/pgsql/src/main/resources/META-INF/microprofile-config.properties similarity index 63% rename from tests/integration/jpa/appl/src/main/resources/META-INF/microprofile-config.properties rename to tests/integration/jpa/pgsql/src/main/resources/META-INF/microprofile-config.properties index 9ecc2c009ac..c4893fa8f25 100644 --- a/tests/integration/jpa/appl/src/main/resources/META-INF/microprofile-config.properties +++ b/tests/integration/jpa/pgsql/src/main/resources/META-INF/microprofile-config.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2021 Oracle and/or its affiliates. +# Copyright (c) 2024 Oracle and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,11 +13,10 @@ # See the License for the specific language governing permissions and # limitations under the License. # - -mp.initializer.allow=true -mp.initializer.no-warn=true +server.port=0 features.print-details=true -javax.sql.DataSource.test.dataSource.url=${db.url} -javax.sql.DataSource.test.dataSource.user=${db.user} -javax.sql.DataSource.test.dataSource.password=${db.password} -javax.sql.DataSource.test.dataSourceClassName=${db.datasource} +javax.sql.DataSource.test.dataSource.url=jdbc:postgresql://localhost:5432/test +javax.sql.DataSource.test.dataSource.user=test +javax.sql.DataSource.test.dataSource.password=pgsql123 +javax.sql.DataSource.test.dataSourceClassName=org.postgresql.ds.PGSimpleDataSource + diff --git a/tests/integration/jpa/pgsql/src/main/resources/logging.properties b/tests/integration/jpa/pgsql/src/main/resources/logging.properties new file mode 100644 index 00000000000..d590b197673 --- /dev/null +++ b/tests/integration/jpa/pgsql/src/main/resources/logging.properties @@ -0,0 +1,18 @@ +# +# Copyright (c) 2024 Oracle and/or its affiliates. +# +# Licensed 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. +# + +handlers=org.slf4j.bridge.SLF4JBridgeHandler +.level=INFO diff --git a/tests/integration/jpa/pgsql/src/main/resources/simplelogger.properties b/tests/integration/jpa/pgsql/src/main/resources/simplelogger.properties new file mode 100644 index 00000000000..fcc605df165 --- /dev/null +++ b/tests/integration/jpa/pgsql/src/main/resources/simplelogger.properties @@ -0,0 +1,22 @@ +# +# Copyright (c) 2024 Oracle and/or its affiliates. +# +# Licensed 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. +# +org.slf4j.simpleLogger.defaultLogLevel=warn +org.slf4j.simpleLogger.showThreadName=false +org.slf4j.simpleLogger.log.org.testcontainers=info +org.slf4j.simpleLogger.log.org.testcontainers.utility=error +org.slf4j.simpleLogger.log.io.helidon=info +org.slf4j.simpleLogger.log.org.hibernate=info +org.slf4j.simpleLogger.log.com.zaxxer=info diff --git a/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLDeleteLocalTestIT.java b/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLDeleteLocalTestIT.java new file mode 100644 index 00000000000..3d387c85204 --- /dev/null +++ b/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLDeleteLocalTestIT.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.pgsql; + +import io.helidon.microprofile.testing.junit5.HelidonTest; +import io.helidon.tests.integration.jpa.common.DeleteTest; +import io.helidon.tests.integration.jpa.common.DeleteTestImpl; + +import jakarta.inject.Inject; +import org.junit.jupiter.api.Test; + +/** + * Local delete test. + */ +@HelidonTest +class PostgreSQLDeleteLocalTestIT extends PostgreSQLLocalTest implements DeleteTest { + + @Inject + private DeleteTestImpl delegate; + + @Test + @Override + public void testDeleteEntity() { + delegate.testDeleteEntity(); + } + + @Test + @Override + public void testDeleteJPQL() { + delegate.testDeleteJPQL(); + } + + @Test + @Override + public void testDeleteCriteria() { + delegate.testDeleteCriteria(); + } + + @Test + @Override + public void testDeleteCity() { + delegate.testDeleteCity(); + } +} diff --git a/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLDeleteRemoteTestIT.java b/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLDeleteRemoteTestIT.java new file mode 100644 index 00000000000..62f057aebbd --- /dev/null +++ b/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLDeleteRemoteTestIT.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.pgsql; + +import io.helidon.tests.integration.jpa.common.DeleteTest; + +import org.junit.jupiter.api.Test; + +/** + * Remote delete test. + */ +class PostgreSQLDeleteRemoteTestIT extends PostgreSQLRemoteTest implements DeleteTest { + + PostgreSQLDeleteRemoteTestIT() { + super("/test/delete"); + } + + @Test + @Override + public void testDeleteEntity() { + remoteTest(); + } + + @Test + @Override + public void testDeleteJPQL() { + remoteTest(); + } + + @Test + @Override + public void testDeleteCriteria() { + remoteTest(); + } + + @Test + @Override + public void testDeleteCity() { + remoteTest(); + } +} diff --git a/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLInsertLocalTestIT.java b/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLInsertLocalTestIT.java new file mode 100644 index 00000000000..c8f1b4488fb --- /dev/null +++ b/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLInsertLocalTestIT.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.pgsql; + +import io.helidon.microprofile.testing.junit5.HelidonTest; +import io.helidon.tests.integration.jpa.common.InsertTest; +import io.helidon.tests.integration.jpa.common.InsertTestImpl; + +import jakarta.inject.Inject; +import org.junit.jupiter.api.Test; + +/** + * Local insert test. + */ +@HelidonTest +class PostgreSQLInsertLocalTestIT extends PostgreSQLLocalTest implements InsertTest { + + @Inject + private InsertTestImpl delegate; + + @Test + @Override + public void testInsertType() { + delegate.testInsertType(); + } + + @Test + @Override + public void testInsertTrainerWithPokemons() { + delegate.testInsertTrainerWithPokemons(); + } + + @Test + @Override + public void testTownWithStadium() { + delegate.testTownWithStadium(); + } +} diff --git a/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLInsertRemoteTestIT.java b/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLInsertRemoteTestIT.java new file mode 100644 index 00000000000..565a7f5ddb1 --- /dev/null +++ b/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLInsertRemoteTestIT.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.pgsql; + +import io.helidon.tests.integration.jpa.common.InsertTest; + +import org.junit.jupiter.api.Test; + +/** + * Local insert test. + */ +class PostgreSQLInsertRemoteTestIT extends PostgreSQLRemoteTest implements InsertTest { + + PostgreSQLInsertRemoteTestIT() { + super("/test/insert"); + } + + @Test + @Override + public void testInsertType() { + remoteTest(); + } + + @Test + @Override + public void testInsertTrainerWithPokemons() { + remoteTest(); + } + + @Test + @Override + public void testTownWithStadium() { + remoteTest(); + } +} diff --git a/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLLocalTest.java b/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLLocalTest.java new file mode 100644 index 00000000000..41c8c1bf3c6 --- /dev/null +++ b/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLLocalTest.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.pgsql; + +import java.util.Map; + +import io.helidon.microprofile.testing.junit5.AddConfigMap; + +import org.testcontainers.containers.JdbcDatabaseContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +/** + * Base class for the local tests. + */ +@Testcontainers(disabledWithoutDocker = true) +abstract class PostgreSQLLocalTest { + + @Container + static final JdbcDatabaseContainer CONTAINER = PostgreSQLTestContainer.CONTAINER; + + @AddConfigMap + static Map config() { + return PostgreSQLTestContainer.config(); + } +} diff --git a/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLQueryLocalTestIT.java b/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLQueryLocalTestIT.java new file mode 100644 index 00000000000..f66ef2140dd --- /dev/null +++ b/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLQueryLocalTestIT.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.pgsql; + +import io.helidon.microprofile.testing.junit5.HelidonTest; +import io.helidon.tests.integration.jpa.common.QueryTest; +import io.helidon.tests.integration.jpa.common.QueryTestImpl; + +import jakarta.inject.Inject; +import org.junit.jupiter.api.Test; + +/** + * Local query test. + */ +@HelidonTest +class PostgreSQLQueryLocalTestIT extends PostgreSQLLocalTest implements QueryTest { + + @Inject + private QueryTestImpl delegate; + + @Test + @Override + public void testFind() { + delegate.testFind(); + } + + @Test + @Override + public void testQueryJPQL() { + delegate.testQueryJPQL(); + } + + @Test + @Override + public void testQueryCriteria() { + delegate.testQueryCriteria(); + } + + @Test + @Override + public void testQueryCeladonJPQL() { + delegate.testQueryCeladonJPQL(); + } + + @Test + @Override + public void testQueryCeladonCriteria() { + delegate.testQueryCeladonCriteria(); + } +} diff --git a/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLQueryRemoteTestIT.java b/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLQueryRemoteTestIT.java new file mode 100644 index 00000000000..976f037b36d --- /dev/null +++ b/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLQueryRemoteTestIT.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.pgsql; + +import io.helidon.tests.integration.jpa.common.QueryTest; + +import org.junit.jupiter.api.Test; + +/** + * Invoke {@code /test/query} endpoints. + */ +class PostgreSQLQueryRemoteTestIT extends PostgreSQLRemoteTest implements QueryTest { + + PostgreSQLQueryRemoteTestIT() { + super("/test/query"); + } + + @Test + @Override + public void testFind() { + remoteTest(); + } + + @Test + @Override + public void testQueryJPQL() { + remoteTest(); + } + + @Test + @Override + public void testQueryCriteria() { + remoteTest(); + } + + @Test + @Override + public void testQueryCeladonJPQL() { + remoteTest(); + } + + @Test + @Override + public void testQueryCeladonCriteria() { + remoteTest(); + } +} diff --git a/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLRemoteTest.java b/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLRemoteTest.java new file mode 100644 index 00000000000..b131646725b --- /dev/null +++ b/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLRemoteTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.pgsql; + +import java.nio.file.Path; +import java.util.Map; + +import io.helidon.tests.integration.harness.ProcessRunner; +import io.helidon.tests.integration.harness.ProcessRunner.ExecMode; +import io.helidon.tests.integration.harness.WaitStrategy; +import io.helidon.tests.integration.harness.TestProcess; +import io.helidon.tests.integration.harness.TestProcesses; +import io.helidon.tests.integration.jpa.common.RemoteTest; + +import org.testcontainers.containers.JdbcDatabaseContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +/** + * Base class for the remote tests. + */ +@Testcontainers(disabledWithoutDocker = true) +@TestProcesses +abstract class PostgreSQLRemoteTest extends RemoteTest { + + @Container + static final JdbcDatabaseContainer CONTAINER = PostgreSQLTestContainer.CONTAINER; + + @TestProcess + static final ProcessRunner PROCESS_RUNNER = ProcessRunner.of(ExecMode.CLASS_PATH) + .finalName("helidon-tests-integration-jpa-pgsql") + .properties(Map.of("java.util.logging.config.file", Path.of("target/classes/logging.properties").toAbsolutePath())) + .properties(PostgreSQLTestContainer::config) + .waitingFor(WaitStrategy.waitForPort()); + + /** + * Create a new instance. + * + * @param path base path + */ + @SuppressWarnings("resource") + PostgreSQLRemoteTest(String path) { + super(path, PROCESS_RUNNER.process().port()); + } +} diff --git a/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLTestContainer.java b/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLTestContainer.java new file mode 100644 index 00000000000..88f09c3cd04 --- /dev/null +++ b/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLTestContainer.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.pgsql; + +import java.nio.file.Path; +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.util.Map; +import java.util.concurrent.Future; + +import org.testcontainers.containers.JdbcDatabaseContainer; +import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy; +import org.testcontainers.images.builder.ImageFromDockerfile; + +/** + * Database container utility. + */ +abstract class PostgreSQLTestContainer { + + private static final ImageFromDockerfile IMAGE = new ImageFromDockerfile("pgsql", false) + .withFileFromPath(".", Path.of("etc/docker")); + + static final JdbcDatabaseContainer CONTAINER = new PostgreSQLContainer(IMAGE) + .withPassword("pgsql123"); + + static Map config() { + return Map.of("javax.sql.DataSource.test.dataSource.url", CONTAINER.getJdbcUrl()); + } + + private PostgreSQLTestContainer() { + } + + private static final class PostgreSQLContainer extends JdbcDatabaseContainer { + + private String dbName = "test"; + private String username = "test"; + private String password = "test"; + + PostgreSQLContainer(Future image) { + super(image); + waitStrategy = new LogMessageWaitStrategy() + .withRegEx(".*database system is ready to accept connections.*\\s") + .withTimes(2) + .withStartupTimeout(Duration.of(60, ChronoUnit.SECONDS)); + addExposedPort(5432); + } + + @Override + protected void configure() { + // Disable Postgres driver use of java.util.logging to reduce noise at startup time + withUrlParam("loggerLevel", "OFF"); + addEnv("POSTGRES_DB", dbName); + addEnv("POSTGRES_USER", username); + addEnv("POSTGRES_PASSWORD", password); + } + + @Override + public PostgreSQLContainer withUsername(String username) { + this.username = username; + return this; + } + + @Override + public PostgreSQLContainer withPassword(String password) { + this.password = password; + return this; + } + + @Override + public PostgreSQLContainer withDatabaseName(String dbName) { + this.dbName = dbName; + return this; + } + + @Override + public String getDriverClassName() { + return "org.postgresql.Driver"; + } + + @Override + public String getJdbcUrl() { + return "jdbc:postgresql://localhost:%d/%s".formatted(getMappedPort(5432), dbName); + } + + @Override + public String getUsername() { + return username; + } + + @Override + public String getPassword() { + return password; + } + + @Override + protected String getTestQueryString() { + return "SELECT 1"; + } + } +} diff --git a/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLUpdateLocalTestIT.java b/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLUpdateLocalTestIT.java new file mode 100644 index 00000000000..338e4ac8764 --- /dev/null +++ b/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLUpdateLocalTestIT.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.pgsql; + +import io.helidon.microprofile.testing.junit5.HelidonTest; +import io.helidon.tests.integration.jpa.common.UpdateTest; +import io.helidon.tests.integration.jpa.common.UpdateTestImpl; + +import jakarta.inject.Inject; +import org.junit.jupiter.api.Test; + +/** + * Local update test. + */ +@HelidonTest +class PostgreSQLUpdateLocalTestIT extends PostgreSQLLocalTest implements UpdateTest { + + @Inject + private UpdateTestImpl delegate; + + @Test + @Override + public void testUpdateEntity() { + delegate.testUpdateEntity(); + } + + @Test + @Override + public void testUpdateJPQL() { + delegate.testUpdateJPQL(); + } + + @Test + @Override + public void testUpdateCriteria() { + delegate.testUpdateCriteria(); + } + + @Test + @Override + public void testUpdateCity() { + delegate.testUpdateCity(); + } +} diff --git a/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLUpdateRemoteTestIT.java b/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLUpdateRemoteTestIT.java new file mode 100644 index 00000000000..88a3ee33de3 --- /dev/null +++ b/tests/integration/jpa/pgsql/src/test/java/io/helidon/tests/integration/jpa/pgsql/PostgreSQLUpdateRemoteTestIT.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed 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 io.helidon.tests.integration.jpa.pgsql; + +import io.helidon.tests.integration.jpa.common.UpdateTest; + +import org.junit.jupiter.api.Test; + +/** + * Invoke {@code /test/update} endpoints. + */ +class PostgreSQLUpdateRemoteTestIT extends PostgreSQLRemoteTest implements UpdateTest { + + PostgreSQLUpdateRemoteTestIT() { + super("/test/update"); + } + + @Test + @Override + public void testUpdateEntity() { + remoteTest(); + } + + @Test + @Override + public void testUpdateJPQL() { + remoteTest(); + } + + @Test + @Override + public void testUpdateCriteria() { + remoteTest(); + } + + @Test + @Override + public void testUpdateCity() { + remoteTest(); + } +} diff --git a/tests/integration/jpa/pom.xml b/tests/integration/jpa/pom.xml index c7562079b27..27065664583 100644 --- a/tests/integration/jpa/pom.xml +++ b/tests/integration/jpa/pom.xml @@ -26,21 +26,21 @@ 4.1.0-SNAPSHOT ../pom.xml - pom - io.helidon.tests.integration.jpa helidon-tests-integration-jpa-project - Helidon Tests Integration JPA + Helidon Tests Integration JPA Project A set of tests that validate JPA API implementation - model - simple - appl + common + parent + oracle + mysql + pgsql + h2 - diff --git a/tests/integration/jpa/simple/pom.xml b/tests/integration/jpa/simple/pom.xml deleted file mode 100644 index 0f8331e3ede..00000000000 --- a/tests/integration/jpa/simple/pom.xml +++ /dev/null @@ -1,187 +0,0 @@ - - - - - 4.0.0 - - - io.helidon.tests.integration.jpa - helidon-tests-integration-jpa-project - 4.1.0-SNAPSHOT - ../pom.xml - - - helidon-tests-integration-jpa-simple - Helidon Tests Integration JPA Simple Tests - - - - io.helidon.tests.integration.jpa - helidon-tests-integration-jpa-model - ${project.version} - - - io.helidon.microprofile.metrics - helidon-microprofile-metrics - - - io.helidon.integrations.cdi - helidon-integrations-cdi-jta-weld - test - - - io.helidon.integrations.cdi - helidon-integrations-cdi-datasource-hikaricp - test - - - io.helidon.integrations.cdi - helidon-integrations-cdi-jpa - test - - - io.helidon.integrations.cdi - helidon-integrations-cdi-hibernate - test - - - io.helidon.microprofile.cdi - helidon-microprofile-cdi - test - - - io.helidon.integrations.cdi - helidon-integrations-cdi-delegates - test - - - io.helidon.integrations.cdi - helidon-integrations-cdi-reference-counted-context - test - - - - jakarta.persistence - jakarta.persistence-api - test - - - jakarta.transaction - jakarta.transaction-api - test - - - jakarta.enterprise - jakarta.enterprise.cdi-api - test - - - jakarta.validation - jakarta.validation-api - - - - com.h2database - h2 - test - - - org.junit.jupiter - junit-jupiter-api - test - - - org.hamcrest - hamcrest-all - test - - - io.smallrye - jandex - runtime - - - org.slf4j - slf4j-jdk14 - runtime - - - io.helidon.logging - helidon-logging-jul - test - - - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - copy-libs - - - - - io.smallrye - jandex-maven-plugin - - - make-index - - jandex - - process-classes - - - - - org.apache.maven.plugins - maven-surefire-plugin - - true - - - - org.apache.maven.plugins - maven-failsafe-plugin - - methods - 10 - - - - test-run - integration-test - - integration-test - - - - io.helidon.tests.integration.jpa.simple.test.*IT - - - - - - - - - diff --git a/tests/integration/jpa/simple/src/test/java/io/helidon/tests/integration/jpa/simple/DbUtils.java b/tests/integration/jpa/simple/src/test/java/io/helidon/tests/integration/jpa/simple/DbUtils.java deleted file mode 100644 index 24b5bc4d932..00000000000 --- a/tests/integration/jpa/simple/src/test/java/io/helidon/tests/integration/jpa/simple/DbUtils.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.simple; - -import java.util.List; - -import jakarta.persistence.EntityManager; -import jakarta.persistence.TypedQuery; - -import io.helidon.tests.integration.jpa.dao.Create; -import io.helidon.tests.integration.jpa.dao.Delete; -import io.helidon.tests.integration.jpa.model.Pokemon; -import io.helidon.tests.integration.jpa.model.Trainer; - -/** - * Database utilities. - */ -public class DbUtils { - - public static int ASH_ID = -1; - - private DbUtils() { - throw new UnsupportedOperationException("Instances of DbUtils class are not allowed"); - } - - /** - * Initialize database records. - * - * @param pu persistence unit context - */ - public static void dbInit(PU pu) { - Create.dbInsertTypes(pu.getEm()); - ASH_ID = Create.dbInsertAsh(pu.getEm()); - Create.dbInsertCeladon(pu.getEm()); - pu.getEm().flush(); - pu.getEm().clear(); - pu.getEm().getEntityManagerFactory().getCache().evictAll(); - - } - - /** - * Delete all database records. - * - * @param pu persistence unit context - */ - public static void dbCleanup(PU pu) { - Delete.dbCleanup(pu.getEm()); - } - - /** - * Find trainer by ID. - * - * @param pu persistence unit context - * @param id trainer ID - * @return trainer with specified ID or {@code null} if no such trainer exists - */ - public static Trainer findTrainer(PU pu, int id) { - final EntityManager em = pu.getEm(); - TypedQuery q = em.createQuery("SELECT t FROM Trainer t JOIN FETCH t.pokemons WHERE t.id = :id", Trainer.class); - q.setParameter("id", ASH_ID); - List result = q.getResultList(); - return result != null && result.size() > 0 ? result.get(0) : null; - } - - /** - * Find trainer's pokemons. - * - * @param pu persistence unit context - * @param trainer trainer entity - * @return {@code List} of trainer's pokemons - */ - public static List trainersPokemons(PU pu, Trainer trainer) { - final EntityManager em = pu.getEm(); - TypedQuery q = em.createQuery("SELECT p FROM Pokemon p WHERE p.trainer.id = :id", Pokemon.class); - q.setParameter("id", trainer.getId()); - return q.getResultList(); - } - - /** - * Find pokemon by name from pokemon List. - * - * @param pokemons List to search - * @param name name of pokemon - * @return found pokemon or null when no such pokemon exists - */ - public static Pokemon findPokemonByName(List pokemons, String name) { - if (pokemons != null && !pokemons.isEmpty()) { - for (Pokemon pokemon : pokemons) { - if (pokemon.getName().equals(name)) { - return pokemon; - } - } - } - return null; - } - -} diff --git a/tests/integration/jpa/simple/src/test/java/io/helidon/tests/integration/jpa/simple/PU.java b/tests/integration/jpa/simple/src/test/java/io/helidon/tests/integration/jpa/simple/PU.java deleted file mode 100644 index a07e4f09fca..00000000000 --- a/tests/integration/jpa/simple/src/test/java/io/helidon/tests/integration/jpa/simple/PU.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.simple; - -import java.util.function.Consumer; - -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.enterprise.inject.se.SeContainer; -import jakarta.enterprise.inject.se.SeContainerInitializer; -import jakarta.persistence.EntityManager; -import jakarta.persistence.PersistenceContext; -import jakarta.transaction.Transactional; - -import static org.junit.jupiter.api.Assertions.assertNotNull; - -/** - * Persistence unit context. - */ -@ApplicationScoped -public class PU { - - private static final SeContainer CONTAINER = initContainer(); - - private static SeContainer initContainer() { - final SeContainerInitializer initializer = SeContainerInitializer - .newInstance() - .addBeanClasses(PU.class); - assertNotNull(initializer); - return initializer.initialize(); - } - - /** - * Provides an instance of persistence unit context. - * - * @return an instance of persistence unit context - */ - public static PU getInstance() { - return CONTAINER.select(PU.class).get(); - } - - @PersistenceContext(unitName = "test") - private EntityManager em; - - /** - * Get EntityManager instance. - * - * @return EntityManager instance - */ - public EntityManager getEm() { - return em; - } - - /** - * Get EntityManager instance with all caches evicted. - * - * @return EntityManager instance with all caches evicted - */ - public EntityManager getCleanEm() { - em.flush(); - em.clear(); - em.getEntityManagerFactory().getCache().evictAll(); - return em; - } - - /*** - * Run provided function in transaction. - * - * @param tx function to be run in transaction - */ - @Transactional - public void tx(Consumer tx) { - tx.accept(this); - } - -} diff --git a/tests/integration/jpa/simple/src/test/java/io/helidon/tests/integration/jpa/simple/test/DeleteIT.java b/tests/integration/jpa/simple/src/test/java/io/helidon/tests/integration/jpa/simple/test/DeleteIT.java deleted file mode 100644 index d9b30c93393..00000000000 --- a/tests/integration/jpa/simple/src/test/java/io/helidon/tests/integration/jpa/simple/test/DeleteIT.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2020, 2023 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.simple.test; - -import java.util.List; - -import io.helidon.tests.integration.jpa.simple.DbUtils; -import jakarta.persistence.EntityManager; -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.CriteriaDelete; -import jakarta.persistence.criteria.CriteriaQuery; -import jakarta.persistence.criteria.Root; - -import io.helidon.tests.integration.jpa.dao.Create; -import io.helidon.tests.integration.jpa.dao.Delete; -import io.helidon.tests.integration.jpa.model.City; -import io.helidon.tests.integration.jpa.model.Pokemon; -import io.helidon.tests.integration.jpa.model.Stadium; -import io.helidon.tests.integration.jpa.model.Trainer; -import io.helidon.tests.integration.jpa.simple.PU; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.nullValue; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.empty; - -/** - * Verify delete operations of ORM. - */ -public class DeleteIT { - - private static PU pu; - - // Misty and her pokemons are used for delete tests only - private static void dbInsertMisty() { - pu.tx(pu -> { - final EntityManager em = pu.getEm(); - Create.dbInsertMisty(em); - Create.dbInsertViridian(em); - }); - } - - // Delete Misty and her pokemons after delete tests - private static void dbDeleteMisty() { - pu.tx(pu -> { - final EntityManager em = pu.getEm(); - Delete.dbDeleteMisty(em); - Delete.dbDeleteViridian(em); - }); - } - - @BeforeAll - public static void setup() { - pu = PU.getInstance(); - pu.tx(pu -> DbUtils.dbInit(pu)); - dbInsertMisty(); - } - - @AfterAll - public static void destroy() { - pu.tx(pu -> DbUtils.dbCleanup(pu)); - pu = null; - } - - /** - * Delete pokemon: release Misty's Staryu. - * Modification is done using entity instance. - */ - @Test - public void testDeleteEntity() { - int ids[] = new int[1]; - pu.tx(pu -> { - final EntityManager em = pu.getEm(); - Pokemon staryu = em.createQuery( - "SELECT p FROM Pokemon p WHERE p.name = :name", Pokemon.class) - .setParameter("name", "Staryu") - .getSingleResult(); - ids[0] = staryu.getId(); - em.remove(staryu); - }); - pu.tx(pu -> { - final EntityManager em = pu.getCleanEm(); - Pokemon dbStaryu = em.find(Pokemon.class, ids[0]); - assertThat(dbStaryu, nullValue()); - }); - } - - /** - * Delete pokemon: release Misty's Psyduck. - * Modification is done using JPQL. - */ - @Test - public void testDeleteJPQL() { - pu.tx(pu -> { - final EntityManager em = pu.getEm(); - int deleted = em.createQuery( - "DELETE FROM Pokemon p WHERE p.name = :name") - .setParameter("name", "Psyduck") - .executeUpdate(); - assertThat(deleted, is(1)); - }); - pu.tx(pu -> { - final EntityManager em = pu.getCleanEm(); - List pokemons = em.createQuery( - "SELECT p FROM Pokemon p WHERE p.name=:name", Pokemon.class) - .setParameter("name", "Psyduck") - .getResultList(); - assertThat(pokemons, empty()); - }); - } - - /** - * Delete pokemon: release Misty's Corsola. - * Modification is done using CriteriaDelete. - */ - @Test - public void testDeleteCriteria() { - pu.tx(pu -> { - final EntityManager em = pu.getEm(); - CriteriaBuilder cb = em.getCriteriaBuilder(); - CriteriaDelete cu = cb.createCriteriaDelete(Pokemon.class); - Root pokemonRoot = cu.from(Pokemon.class); - cu.where(cb.equal(pokemonRoot.get("name"), "Corsola")); - int deleted = em.createQuery(cu).executeUpdate(); - assertThat(deleted, is(1)); - }); - pu.tx(pu -> { - final EntityManager em = pu.getCleanEm(); - CriteriaBuilder cb = em.getCriteriaBuilder(); - CriteriaQuery cq = cb.createQuery(Pokemon.class); - Root pokemonRoot = cq.from(Pokemon.class); - cq.select(pokemonRoot) - .where(cb.equal(pokemonRoot.get("name"), "Corsola")); - List pokemons = em.createQuery(cq).getResultList(); - assertThat(pokemons, empty()); - }); - } - - /** - * Delete Viridian City. - */ - @Test - public void testDeleteViridianCity() { - pu.tx(pu -> { - final EntityManager em = pu.getEm(); - City city = em.createQuery( - "SELECT c FROM City c WHERE c.name = :name", City.class) - .setParameter("name", "Viridian City") - .getSingleResult(); - Stadium stadium = city.getStadium(); - Trainer trainer = stadium.getTrainer(); - List pokemons = trainer.getPokemons(); - em.remove(city); - em.remove(trainer); - pokemons.forEach(poklemon -> em.remove(poklemon)); - }); - pu.tx(pu -> { - final EntityManager em = pu.getCleanEm(); - List cities = em.createQuery( - "SELECT c FROM City c WHERE c.name = :name", City.class) - .setParameter("name", "Viridian City") - .getResultList(); - assertThat(cities, empty()); - }); - } - -} diff --git a/tests/integration/jpa/simple/src/test/java/io/helidon/tests/integration/jpa/simple/test/InsertIT.java b/tests/integration/jpa/simple/src/test/java/io/helidon/tests/integration/jpa/simple/test/InsertIT.java deleted file mode 100644 index b3733339c01..00000000000 --- a/tests/integration/jpa/simple/src/test/java/io/helidon/tests/integration/jpa/simple/test/InsertIT.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (c) 2020, 2023 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.simple.test; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import io.helidon.tests.integration.jpa.simple.DbUtils; -import jakarta.persistence.EntityManager; - -import io.helidon.tests.integration.jpa.model.Pokemon; -import io.helidon.tests.integration.jpa.model.Stadium; -import io.helidon.tests.integration.jpa.model.City; -import io.helidon.tests.integration.jpa.model.Trainer; -import io.helidon.tests.integration.jpa.model.Type; -import io.helidon.tests.integration.jpa.simple.PU; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.empty; - -/** - * Verify create/insert operations of ORM. - */ -public class InsertIT { - - private static PU pu; - - private static final Set DELETE_POKEMONS = new HashSet<>(); - private static final Set DELETE_TRAINERS = new HashSet<>(); - private static final Set DELETE_STADIUMS = new HashSet<>(); - private static final Set DELETE_TOWNS = new HashSet<>(); - - @BeforeAll - public static void setup() { - pu = PU.getInstance(); - pu.tx(pu -> DbUtils.dbInit(pu)); - } - - @AfterAll - public static void destroy() { - pu.tx(pu -> DbUtils.dbCleanup(pu)); - pu = null; - } - - /** - * Verify simple create operation (persist) on a single database row. - */ - @Test - public void testInsertType() { - pu.tx(pu -> { - final EntityManager em = pu.getEm(); - Type type = new Type(20, "TestType"); - em.persist(type); - em.flush(); - Type dbType = em.find(Type.class, 20); - assertThat(dbType, is(type)); - }); - } - - /** - * Verify complex create operation (persist) on a full ORM model (Gary Oak and his 6 pokemons). - * Relations are not marked for cascade persist operation so every entity instance has to be persisted separately. - */ - @Test - void testInsertTrainerWithPokemons() { - // Pass data between lambdas - final Pokemon[] pokemons = new Pokemon[6]; - final Trainer[] trainers = new Trainer[1]; - pu.tx(pu -> { - final EntityManager em = pu.getEm(); - Type normal = em.find(Type.class, 1); - Type flying = em.find(Type.class, 3); - Type poison = em.find(Type.class, 4); - Type fire = em.find(Type.class, 10); - Type water = em.find(Type.class, 11); - Type electric = em.find(Type.class, 13); - trainers[0] = new Trainer("Gary Oak", 10); - pokemons[0] = new Pokemon(trainers[0], "Krabby", 236, Arrays.asList(water)); - pokemons[1] = new Pokemon(trainers[0], "Nidoran", 251, Arrays.asList(poison)); - pokemons[2] = new Pokemon(trainers[0], "Eevee", 115, Arrays.asList(normal)); - pokemons[3] = new Pokemon(trainers[0], "Electivire", 648, Arrays.asList(electric)); - pokemons[4] = new Pokemon(trainers[0], "Dodrio", 346, Arrays.asList(normal, flying)); - pokemons[5] = new Pokemon(trainers[0], "Magmar", 648, Arrays.asList(fire)); - em.persist(trainers[0]); - em.persist(pokemons[0]); - em.persist(pokemons[1]); - em.persist(pokemons[2]); - em.persist(pokemons[3]); - em.persist(pokemons[4]); - em.persist(pokemons[5]); - em.flush(); - }); - pu.tx(pu -> { - final EntityManager em = pu.getCleanEm(); - Pokemon dbKrabby = em.find(Pokemon.class, pokemons[0].getId()); - Pokemon dbNidoran = em.find(Pokemon.class, pokemons[1].getId()); - Pokemon dbEvee = em.find(Pokemon.class, pokemons[2].getId()); - Pokemon dbElectivire = em.find(Pokemon.class, pokemons[3].getId()); - Pokemon dbDodrio = em.find(Pokemon.class, pokemons[4].getId()); - Pokemon dbMagmar = em.find(Pokemon.class, pokemons[5].getId()); - Trainer dbTrainer = dbKrabby.getTrainer(); - assertThat(dbKrabby, is(pokemons[0])); - assertThat(dbNidoran, is(pokemons[1])); - assertThat(dbEvee, is(pokemons[2])); - assertThat(dbElectivire, is(pokemons[3])); - assertThat(dbDodrio, is(pokemons[4])); - assertThat(dbMagmar, is(pokemons[5])); - assertThat(dbTrainer, is(trainers[0])); - for (Pokemon pokemon : pokemons) { - DELETE_POKEMONS.add(pokemon.getId()); - } - DELETE_TRAINERS.add(dbTrainer.getId()); - }); - } - - /** - * Verify complex create operation (persist) on a full ORM model (Lt. Surge in Vermilion City). - */ - @Test - void testTownWithStadium() { - final Trainer[] trainers = new Trainer[1]; - final Pokemon[] pokemons = new Pokemon[6]; - final Stadium[] stadiums = new Stadium[1]; - final City[] cities = new City[1]; - pu.tx(pu -> { - final EntityManager em = pu.getEm(); - Type steel = em.find(Type.class, 9); - Type electric = em.find(Type.class, 13); - trainers[0] = new Trainer("Lt. Surge", 28); - pokemons[0] = new Pokemon(trainers[0], "Raichu", 1521, Arrays.asList(electric)); - pokemons[1] = new Pokemon(trainers[0], "Manectric", 1589, Arrays.asList(electric)); - pokemons[2] = new Pokemon(trainers[0], "Magnezone", 1853, Arrays.asList(electric)); - pokemons[3] = new Pokemon(trainers[0], "Electrode", 1237, Arrays.asList(electric)); - pokemons[4] = new Pokemon(trainers[0], "Pachirisu", 942, Arrays.asList(electric)); - pokemons[5] = new Pokemon(trainers[0], "Electivire", 1931, Arrays.asList(electric)); - stadiums[0] = new Stadium("Vermilion Gym", trainers[0]); - cities[0] = new City("Vermilion City", "Mina", stadiums[0]); - em.persist(trainers[0]); - em.persist(pokemons[0]); - em.persist(pokemons[1]); - em.persist(pokemons[2]); - em.persist(pokemons[3]); - em.persist(pokemons[4]); - em.persist(pokemons[5]); - //em.persist(stadiums[0]); - em.persist(cities[0]); - em.flush(); - }); - pu.tx(pu -> { - final EntityManager em = pu.getCleanEm(); - City dbCity = em.find(City.class, cities[0].getId()); - Stadium dbStadium = dbCity.getStadium(); - Trainer dbTrainer = dbStadium.getTrainer(); - List dbPokemons = dbTrainer.getPokemons(); - Set pokemonSet = new HashSet<>(pokemons.length); - for (Pokemon pokemon : pokemons) { - pokemonSet.add(pokemon); - } - for (Pokemon dbPokemon : dbPokemons) { - assertThat(pokemonSet.remove(dbPokemon), is(true)); - } - assertThat(pokemonSet, empty()); - assertThat(dbTrainer, is(trainers[0])); - assertThat(dbStadium, is(stadiums[0])); - assertThat(dbCity, is(cities[0])); - for (Pokemon pokemon : pokemons) { - DELETE_POKEMONS.add(pokemon.getId()); - } - DELETE_TRAINERS.add(dbTrainer.getId()); - DELETE_STADIUMS.add(dbStadium.getId()); - DELETE_TOWNS.add(dbCity.getId()); - }); - } - -} diff --git a/tests/integration/jpa/simple/src/test/java/io/helidon/tests/integration/jpa/simple/test/QueryIT.java b/tests/integration/jpa/simple/src/test/java/io/helidon/tests/integration/jpa/simple/test/QueryIT.java deleted file mode 100644 index cd91f34887d..00000000000 --- a/tests/integration/jpa/simple/src/test/java/io/helidon/tests/integration/jpa/simple/test/QueryIT.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2020, 2023 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.simple.test; - -import java.util.List; - -import jakarta.persistence.EntityManager; -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.CriteriaQuery; -import jakarta.persistence.criteria.Root; - -import io.helidon.tests.integration.jpa.model.City; -import io.helidon.tests.integration.jpa.model.Pokemon; -import io.helidon.tests.integration.jpa.model.Trainer; -import io.helidon.tests.integration.jpa.simple.DbUtils; -import io.helidon.tests.integration.jpa.simple.PU; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.empty; - -/** - * Verify query operations of ORM. - */ -public class QueryIT { - - private static PU pu; - - @BeforeAll - public static void setup() { - pu = PU.getInstance(); - pu.tx(pu -> DbUtils.dbInit(pu)); - } - - @AfterAll - public static void destroy() { - pu.tx(pu -> DbUtils.dbCleanup(pu)); - pu = null; - } - - /** - * Find trainer Ash and his pokemons. - */ - @Test - public void testFind() { - pu.tx(pu -> { - final EntityManager em = pu.getCleanEm(); - Trainer ash = em.find(Trainer.class, DbUtils.ASH_ID); - List pokemons = ash.getPokemons(); - assertThat(ash, notNullValue()); - assertThat(pokemons, not(empty())); - }); - } - - /** - * Query trainer Ash and his pokemons using JPQL. - */ - @Test - public void testQueryJPQL() { - pu.tx(pu -> { - final EntityManager em = pu.getCleanEm(); - Trainer ash = em.createQuery( - "SELECT t FROM Trainer t JOIN FETCH t.pokemons p WHERE t.id = :id", Trainer.class) - .setParameter("id", DbUtils.ASH_ID) - .getSingleResult(); - List pokemons = ash.getPokemons(); - assertThat(ash, notNullValue()); - assertThat(pokemons, not(empty())); - }); - } - - /** - * Query trainer Ash and his pokemons using CriteriaQuery. - */ - @Test - public void testQueryCriteria() { - pu.tx(pu -> { - final EntityManager em = pu.getCleanEm(); - CriteriaBuilder cb = em.getCriteriaBuilder(); - CriteriaQuery cq = cb.createQuery(Trainer.class); - Root trainerRoot = cq.from(Trainer.class); - cq.select(trainerRoot) - .where(cb.equal(trainerRoot.get("id"), DbUtils.ASH_ID)); - Trainer ash = em.createQuery(cq).getSingleResult(); - List pokemons = ash.getPokemons(); - assertThat(ash, notNullValue()); - assertThat(pokemons, not(empty())); - }); - } - - /** - * Query Celadon city using JPQL. - */ - @Test - public void testQueryCeladonJPQL() { - pu.tx(pu -> { - final EntityManager em = pu.getCleanEm(); - City city = em.createQuery( - "SELECT c FROM City c " - + "JOIN FETCH c.stadium s " - + "JOIN FETCH s.trainer t " - + "WHERE c.name = :name", City.class) - .setParameter("name", "Celadon City") - .getSingleResult(); - assertThat(city.getName(), is("Celadon City")); - assertThat(city.getStadium().getName(), is("Celadon Gym")); - assertThat(city.getStadium().getTrainer().getName(), is("Erika")); - }); - } - - /** - * Query Celadon city using CriteriaQuery. - */ - @Test - public void testQueryCeladonCriteria() { - pu.tx(pu -> { - final EntityManager em = pu.getCleanEm(); - CriteriaBuilder cb = em.getCriteriaBuilder(); - CriteriaQuery cq = cb.createQuery(City.class); - Root cityRoot = cq.from(City.class); - cityRoot - .fetch("stadium") - .fetch("trainer"); - cq.select(cityRoot) - .where(cb.equal(cityRoot.get("name"), "Celadon City")); - City city = em.createQuery(cq).getSingleResult(); - assertThat(city.getName(), is("Celadon City")); - assertThat(city.getStadium().getName(), is("Celadon Gym")); - assertThat(city.getStadium().getTrainer().getName(), is("Erika")); - }); - } - -} diff --git a/tests/integration/jpa/simple/src/test/java/io/helidon/tests/integration/jpa/simple/test/UpdateIT.java b/tests/integration/jpa/simple/src/test/java/io/helidon/tests/integration/jpa/simple/test/UpdateIT.java deleted file mode 100644 index aa9a11b955f..00000000000 --- a/tests/integration/jpa/simple/src/test/java/io/helidon/tests/integration/jpa/simple/test/UpdateIT.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (c) 2020, 2023 Oracle and/or its affiliates. - * - * Licensed 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 io.helidon.tests.integration.jpa.simple.test; - -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import jakarta.persistence.EntityManager; -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.CriteriaQuery; -import jakarta.persistence.criteria.CriteriaUpdate; -import jakarta.persistence.criteria.Root; - -import io.helidon.tests.integration.jpa.dao.Create; -import io.helidon.tests.integration.jpa.model.City; -import io.helidon.tests.integration.jpa.model.Pokemon; -import io.helidon.tests.integration.jpa.model.Stadium; -import io.helidon.tests.integration.jpa.model.Trainer; -import io.helidon.tests.integration.jpa.simple.DbUtils; -import io.helidon.tests.integration.jpa.simple.PU; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; - -/** - * Verify update operations on ORM. - */ -public class UpdateIT { - - private static PU pu; - - @BeforeAll - public static void setup() { - pu = PU.getInstance(); - pu.tx(pu -> { - final EntityManager em = pu.getEm(); - DbUtils.dbInit(pu); - Create.dbInsertBrock(em); - Create.dbInsertSaffron(em); - }); - } - - @AfterAll - public static void destroy() { - pu.tx(pu -> DbUtils.dbCleanup(pu)); - pu = null; - } - - /** - * Update pokemon: evolve Broke's Geodude into Graveler. - * Modification is done using entity instance. - */ - @Test - public void testUpdateEntity() { - Pokemon[] pokemons = new Pokemon[1]; - pu.tx(pu -> { - final EntityManager em = pu.getEm(); - pokemons[0] = em.createQuery( - "SELECT p FROM Pokemon p WHERE p.name = :name", Pokemon.class) - .setParameter("name", "Geodude") - .getSingleResult(); - pokemons[0].getTypes().size(); - pokemons[0].setName("Graveler"); - pokemons[0].setCp(527); - em.persist(pokemons[0]); - }); - pu.tx(pu -> { - final EntityManager em = pu.getCleanEm(); - Pokemon dbGraveler = em.find(Pokemon.class, pokemons[0].getId()); - assertThat(dbGraveler, is(pokemons[0])); - }); - } - - /** - * Update pokemon: evolve Broke's Slowpoke into Slowbro. - * Modification is done using JPQL. - */ - @Test - public void testUpdateJPQL() { - pu.tx(pu -> { - final EntityManager em = pu.getEm(); - int updated = em.createQuery( - "UPDATE Pokemon p SET p.name = :newName, p.cp = :newCp WHERE p.name = :name") - .setParameter("newName", "Slowbro") - .setParameter("newCp", 647) - .setParameter("name", "Slowpoke") - .executeUpdate(); - assertThat(updated, is(1)); - }); - pu.tx(pu -> { - final EntityManager em = pu.getCleanEm(); - Pokemon dbWartortle = em.createQuery( - "SELECT p FROM Pokemon p WHERE p.name=:name", Pokemon.class) - .setParameter("name", "Slowbro") - .getSingleResult(); - assertThat(dbWartortle.getCp(), is(647)); - }); - } - - /** - * Update pokemon: evolve Broke's Teddiursa into Ursaring. - * Modification is done using CriteriaUpdate. - */ - @Test - public void testUpdateCriteria() { - pu.tx(pu -> { - final EntityManager em = pu.getEm(); - CriteriaBuilder cb = em.getCriteriaBuilder(); - CriteriaUpdate cu = cb.createCriteriaUpdate(Pokemon.class); - Root pokemonRoot = cu.from(Pokemon.class); - cu.where(cb.equal(pokemonRoot.get("name"), "Teddiursa")) - .set("name", "Ursaring") - .set("cp", 1568); - int updated = em.createQuery(cu).executeUpdate(); - assertThat(updated, is(1)); - }); - pu.tx(pu -> { - final EntityManager em = pu.getCleanEm(); - CriteriaBuilder cb = em.getCriteriaBuilder(); - CriteriaQuery cq = cb.createQuery(Pokemon.class); - Root pokemonRoot = cq.from(Pokemon.class); - cq.select(pokemonRoot) - .where(cb.equal(pokemonRoot.get("name"), "Ursaring")); - Pokemon dbUrsaring = em.createQuery(cq).getSingleResult(); - assertThat(dbUrsaring.getCp(), is(1568)); - }); - } - - /** - * Update Saffron City data structure. - * Replace stadium trainer with new guy who will get all pokemons from previous trainer. - * Also Alakazam evolves to Mega Alakazam at the same time. - */ - @Test - public void testUpdateSaffron() { - City[] cities = new City[1]; - Set pokemonNames = new HashSet<>(6); - pu.tx(pu -> { - final EntityManager em = pu.getEm(); - cities[0] = em.createQuery( - "SELECT c FROM City c WHERE c.name = :name", City.class) - .setParameter("name", "Saffron City") - .getSingleResult(); - Stadium stadium = cities[0].getStadium(); - Trainer sabrina = stadium.getTrainer(); - Trainer janine = new Trainer("Janine", 24); - stadium.setTrainer(janine); - List pokemons = sabrina.getPokemons(); - janine.setPokemons(pokemons); - sabrina.setPokemons(Collections.EMPTY_LIST); - em.remove(sabrina); - em.persist(janine); - for (Pokemon pokemon : pokemons) { - pokemon.setTrainer(janine); - pokemonNames.add(pokemon.getName()); - em.persist(pokemon); - } - em.persist(stadium); - Pokemon alkazam = DbUtils.findPokemonByName(pokemons, "Alakazam"); - // Update pokemon by query - em.createQuery( - "UPDATE Pokemon p SET p.name = :newName, p.cp = :newCp WHERE p.id = :id") - .setParameter("newName", "Mega Alakazam") - .setParameter("newCp", 4348) - .setParameter("id", alkazam.getId()) - .executeUpdate(); - pokemonNames.remove("Alakazam"); - pokemonNames.add("Mega Alakazam"); - }); - pu.tx(pu -> { - final EntityManager em = pu.getCleanEm(); - City city = em.find(City.class, cities[0].getId()); - Stadium stadium = city.getStadium(); - Trainer trainer = stadium.getTrainer(); - List pokemons = trainer.getPokemons(); - assertThat(trainer.getName(), is("Janine")); - for (Pokemon pokemon : pokemons) { - assertThat("Pokemon " + pokemon.getName() + " is missing", pokemonNames.remove(pokemon.getName()), is(true)); - } - }); - } - -} diff --git a/tests/integration/jpa/simple/src/test/resources/META-INF/persistence.xml b/tests/integration/jpa/simple/src/test/resources/META-INF/persistence.xml deleted file mode 100644 index 163e1d7a11e..00000000000 --- a/tests/integration/jpa/simple/src/test/resources/META-INF/persistence.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - io.helidon.tests.integration.jpa.model.Type - io.helidon.tests.integration.jpa.model.Trainer - io.helidon.tests.integration.jpa.model.Pokemon - io.helidon.tests.integration.jpa.model.Stadium - io.helidon.tests.integration.jpa.model.City - - - - - - - - - - diff --git a/tests/integration/jpa/simple/src/test/resources/logging.properties b/tests/integration/jpa/simple/src/test/resources/logging.properties deleted file mode 100644 index e5f909036bd..00000000000 --- a/tests/integration/jpa/simple/src/test/resources/logging.properties +++ /dev/null @@ -1,28 +0,0 @@ -# -# Copyright (c) 2020, 2023 Oracle and/or its affiliates. -# -# Licensed 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. -# - -# Example Logging Configuration File -# For more information see $JAVA_HOME/jre/lib/logging.properties -# Send messages to the console - -handlers=io.helidon.logging.jul.HelidonConsoleHandler -java.util.logging.SimpleFormatter.format=%4$s %3$s: %5$s%6$s%n - -.level=WARNING - -io.helidon.level=INFO -org.hibernate.level=INFO -com.zaxxer.level=INFO diff --git a/tests/integration/packaging/mp-3/src/main/java/module-info.java b/tests/integration/packaging/mp-3/src/main/java/module-info.java index 8ed300e2f52..5582b4bdf40 100644 --- a/tests/integration/packaging/mp-3/src/main/java/module-info.java +++ b/tests/integration/packaging/mp-3/src/main/java/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024 Oracle and/or its affiliates. + * Copyright (c) 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/tests/integration/packaging/mp-3/src/main/resources/META-INF/native-image/io.helidon.tests.integration.packaging/helidon-tests-integration-packaging-mp-3/native-image.properties b/tests/integration/packaging/mp-3/src/main/resources/META-INF/native-image/io.helidon.tests.integration.packaging/helidon-tests-integration-packaging-mp-3/native-image.properties index af277f9d118..7e96c6fca94 100644 --- a/tests/integration/packaging/mp-3/src/main/resources/META-INF/native-image/io.helidon.tests.integration.packaging/helidon-tests-integration-packaging-mp-3/native-image.properties +++ b/tests/integration/packaging/mp-3/src/main/resources/META-INF/native-image/io.helidon.tests.integration.packaging/helidon-tests-integration-packaging-mp-3/native-image.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2023, 2024 Oracle and/or its affiliates. +# Copyright (c) 2024 Oracle and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,5 +13,15 @@ # See the License for the specific language governing permissions and # limitations under the License. # +<<<<<<<< HEAD:tests/integration/packaging/mp-3/src/main/resources/META-INF/native-image/io.helidon.tests.integration.packaging/helidon-tests-integration-packaging-mp-3/native-image.properties Args=--initialize-at-build-time=io.helidon.tests.integration.packaging.mp3 +======== +org.slf4j.simpleLogger.defaultLogLevel=warn +org.slf4j.simpleLogger.showThreadName=false +org.slf4j.simpleLogger.log.org.testcontainers=info +org.slf4j.simpleLogger.log.org.testcontainers.utility=error +org.slf4j.simpleLogger.log.io.helidon=info +org.slf4j.simpleLogger.log.org.hibernate=info +org.slf4j.simpleLogger.log.com.zaxxer=info +>>>>>>>> f00b85e2dc (pipeline updates !!!!!):tests/integration/jpa/h2/src/main/resources/simplelogger.properties diff --git a/tests/integration/pom.xml b/tests/integration/pom.xml index 502e1856d35..f517ca55af1 100644 --- a/tests/integration/pom.xml +++ b/tests/integration/pom.xml @@ -38,6 +38,7 @@ config + dbclient harness health jep290 @@ -59,6 +60,7 @@ mp-graphql mp-security-client mp-ws-services + packaging oidc restclient restclient-connector @@ -85,19 +87,4 @@ - - - - dbclient - - dbclient - - - - packaging - - packaging - - - diff --git a/tests/integration/restclient-connector/pom.xml b/tests/integration/restclient-connector/pom.xml index f083269752d..ce7ef05eb28 100644 --- a/tests/integration/restclient-connector/pom.xml +++ b/tests/integration/restclient-connector/pom.xml @@ -26,7 +26,7 @@ helidon-tests-integration-restclient-connector - Helidon Integration Test RestClient Webclient Connector + Helidon Tests Integration RestClient Connector diff --git a/webserver/observe/pom.xml b/webserver/observe/pom.xml index f1e083b925f..0a49b8d4528 100644 --- a/webserver/observe/pom.xml +++ b/webserver/observe/pom.xml @@ -26,7 +26,7 @@ io.helidon.webserver.observe helidon-webserver-observe-project - Helidon Observe Project + Helidon WebServer Observe Project pom diff --git a/webserver/static-content/pom.xml b/webserver/static-content/pom.xml index e6b7c3d647a..9a6cd5c0fe6 100644 --- a/webserver/static-content/pom.xml +++ b/webserver/static-content/pom.xml @@ -25,7 +25,7 @@ helidon-webserver-static-content - Helidon Server Static Content + Helidon WebServer Static Content etc/spotbugs/exclude.xml