├── .editorconfig ├── .github ├── dependabot.yml ├── release-drafter.yml └── workflows │ ├── changelog-draft.yml │ ├── ci.yml │ ├── container-image-scan.yml │ ├── main.yml │ ├── nightly.yml │ ├── patch.yml │ ├── release-2.x.yml │ ├── release.yml │ └── update-docs.yml ├── .gitignore ├── .snyk ├── Dockerfile ├── Dockerfile-nightly ├── LICENSE.txt ├── README.md ├── alpine ├── .snyk ├── Dockerfile ├── Dockerfile-nightly └── docker-entrypoint.sh ├── docker-entrypoint.sh ├── samples ├── hello │ ├── Dockerfile │ ├── Dockerfile-nightly │ └── stubs │ │ ├── __files │ │ └── hello.json │ │ └── mappings │ │ └── hello.json └── random │ ├── Dockerfile │ ├── Dockerfile-nightly │ ├── README.md │ └── stubs │ ├── __files │ ├── user.json │ └── users.csv.template │ └── mappings │ ├── user.json │ └── users.json └── test └── integration-tests ├── README.md ├── pom.xml └── src ├── main └── java │ └── org │ └── wiremock │ └── docker │ └── it │ └── Stub.java └── test ├── java └── org │ └── wiremock │ └── docker │ └── it │ ├── HealthTest.java │ ├── SmokeTest.java │ ├── TestConfig.java │ ├── WireMockOptionsTest.java │ ├── extensions │ └── WireMockContainerExtensionsWebhookTest.java │ ├── samples │ ├── AbtsractSampleTest.java │ ├── HelloSampleHttpsTest.java │ ├── HelloSampleTest.java │ └── RandomSampleTest.java │ └── util │ ├── HttpResponse.java │ ├── TestHttpClient.java │ └── TestHttpServer.java └── resources ├── logback-test.xml └── org └── wiremock └── docker └── it ├── SmokeTest ├── hello-world-resource-response.xml ├── hello-world-resource.json └── hello-world.json └── extensions └── WireMockContainerExtensionsWebhookTest └── webhook-callback-template.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | 9 | # Change these settings to your own preference 10 | indent_style = space 11 | indent_size = 2 12 | 13 | # We recommend you to keep these unchanged 14 | end_of_line = lf 15 | charset = utf-8 16 | trim_trailing_whitespace = true 17 | insert_final_newline = true 18 | 19 | [*.md] 20 | trim_trailing_whitespace = false 21 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | 4 | - package-ecosystem: "docker" 5 | directory: "/" 6 | schedule: 7 | interval: "weekly" 8 | 9 | - package-ecosystem: "github-actions" 10 | directory: "/" 11 | schedule: 12 | interval: "weekly" 13 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | # Use https://github.com/wiremock/.github/blob/main/.github/release_drafter.yml 2 | _extends: .github 3 | -------------------------------------------------------------------------------- /.github/workflows/changelog-draft.yml: -------------------------------------------------------------------------------- 1 | name: Release Drafter 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | workflow_dispatch: 8 | 9 | jobs: 10 | update_release_draft: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: release-drafter/release-drafter@v5 14 | with: 15 | name: next 16 | tag: next 17 | version: next 18 | env: 19 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 20 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | pull_request: 7 | branches: [ "main" ] 8 | workflow_dispatch: 9 | 10 | jobs: 11 | docker-build: 12 | runs-on: ubuntu-latest 13 | strategy: 14 | matrix: 15 | versions: 16 | - CONTEXT: . 17 | TAGS: 18 | - wiremock/wiremock:test 19 | PLATFORMS: 20 | - linux/amd64 21 | - linux/arm64 22 | - linux/arm/v7 23 | - CONTEXT: alpine 24 | TAGS: 25 | - wiremock/wiremock:test-alpine 26 | PLATFORMS: 27 | - linux/amd64 28 | 29 | steps: 30 | 31 | - name: Set up QEMU 32 | uses: docker/setup-qemu-action@v2 33 | with: 34 | image: tonistiigi/binfmt:latest 35 | platforms: all 36 | 37 | - name: Set up Docker Buildx 38 | uses: docker/setup-buildx-action@v2 39 | 40 | - name: Checkout sources 41 | uses: actions/checkout@main 42 | 43 | # TODO: Re-enable if rate limit becomes an issues 44 | # - name: Login to Docker Hub 45 | # uses: docker/login-action@v2 46 | # with: 47 | # username: wiremock 48 | # password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} 49 | 50 | - name: Build WireMock Docker image 51 | uses: docker/build-push-action@v4 52 | with: 53 | context: ${{ matrix.versions.CONTEXT }} 54 | platforms: ${{ join(matrix.versions.PLATFORMS, ',') }} 55 | push: false 56 | file: ${{ matrix.versions.CONTEXT }}/Dockerfile 57 | tags: ${{ matrix.versions.TAGS[0] }} 58 | 59 | - name: Build Wiremock Docker image 60 | run: docker buildx build --tag ${{ matrix.versions.TAGS[0] }} --load ${{ matrix.versions.CONTEXT }} --file ${{ matrix.versions.CONTEXT }}/Dockerfile 61 | 62 | - name: Set up JDK 63 | uses: actions/setup-java@v3 64 | with: 65 | java-version: 11 66 | distribution: 'temurin' 67 | cache: maven 68 | 69 | - name: Run integration test 70 | working-directory: test/integration-tests 71 | run: mvn -B -ntp package verify --file pom.xml -DargLine="-Dit.wiremock-image=${{ matrix.versions.TAGS[0] }}" 72 | 73 | container-image-scan: 74 | uses: ./.github/workflows/container-image-scan.yml 75 | needs: docker-build 76 | with: 77 | image_version: latest 78 | secrets: inherit -------------------------------------------------------------------------------- /.github/workflows/container-image-scan.yml: -------------------------------------------------------------------------------- 1 | name: Container image scan (reusable) 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | image_version: 7 | description: The Docker container image version 8 | type: string 9 | required: true 10 | default: latest 11 | 12 | jobs: 13 | container-image-scan: 14 | name: Snyk container image scan 15 | runs-on: ubuntu-latest 16 | 17 | strategy: 18 | matrix: 19 | versions: 20 | - CONTEXT: . 21 | image: ghcr.io/wiremock/wiremock:${{ inputs.image_version }} 22 | - CONTEXT: alpine 23 | image: ghcr.io/wiremock/wiremock:${{ inputs.image_version }}-alpine 24 | 25 | steps: 26 | - uses: actions/checkout@v4 27 | 28 | - name: Login to GitHub Container Registry 29 | uses: docker/login-action@v2 30 | with: 31 | registry: ghcr.io 32 | username: wiremock 33 | password: ${{ secrets.GITHUB_TOKEN }} 34 | 35 | - name: Pull image to check we've got it 36 | run: docker pull ${{ matrix.versions.image }} 37 | 38 | - name: Run Snyk to check Docker image for vulnerabilities 39 | uses: snyk/actions/docker@master 40 | env: 41 | SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} 42 | with: 43 | image: ${{ matrix.versions.image }} 44 | command: test 45 | args: --file=${{ matrix.versions.CONTEXT }}/Dockerfile --severity-threshold=high --fail-on=upgradable --org=f310ee2f-5552-444d-84ee-ec8c44c33adb --policy-path=${{ matrix.versions.CONTEXT }}/.snyk 46 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Main 2 | 3 | on: 4 | push: 5 | branches: [ main, "3.x" ] 6 | 7 | workflow_dispatch: 8 | 9 | jobs: 10 | 11 | docker-build-push: 12 | runs-on: ubuntu-latest 13 | strategy: 14 | matrix: 15 | versions: 16 | - CONTEXT: . 17 | TAGS: 18 | - wiremock/wiremock:3x 19 | - ghcr.io/wiremock/wiremock:3x 20 | PLATFORMS: 21 | - linux/amd64 22 | - linux/arm64 23 | - linux/arm/v7 24 | - CONTEXT: alpine 25 | TAGS: 26 | - wiremock/wiremock:3x-alpine 27 | - ghcr.io/wiremock/wiremock:3x-alpine 28 | PLATFORMS: 29 | - linux/amd64 30 | steps: 31 | 32 | - name: Set up QEMU 33 | uses: docker/setup-qemu-action@v2 34 | if: ${{ matrix.versions.CONTEXT != 'alpine' }} 35 | with: 36 | image: tonistiigi/binfmt:latest 37 | platforms: all 38 | 39 | - name: Set up Docker Buildx 40 | uses: docker/setup-buildx-action@v2 41 | 42 | - name: Checkout sources 43 | uses: actions/checkout@main 44 | 45 | - name: Login to Docker Hub 46 | uses: docker/login-action@v2 47 | with: 48 | username: wiremockio 49 | password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} 50 | 51 | - name: Login to GitHub Container Registry 52 | uses: docker/login-action@v2 53 | with: 54 | registry: ghcr.io 55 | username: wiremock 56 | password: ${{ secrets.GITHUB_TOKEN }} 57 | 58 | - name: Build WireMock Docker image 59 | uses: docker/build-push-action@v4 60 | with: 61 | context: ${{ matrix.versions.CONTEXT }} 62 | load: true 63 | tags: ${{ matrix.versions.TAGS[0] }} 64 | 65 | - name: Set up JDK 66 | uses: actions/setup-java@v3 67 | with: 68 | java-version: 11 69 | distribution: 'temurin' 70 | cache: maven 71 | 72 | - name: Run integration test 73 | working-directory: test/integration-tests 74 | run: mvn -B -ntp package verify --file pom.xml -DargLine="-Dit.wiremock-image=${{ matrix.versions.TAGS[0] }}" 75 | 76 | - name: Test WireMock Docker image with SSL 77 | run: | 78 | docker container run -d --name test -p 8443:8443 ${{ matrix.versions.TAGS[0] }} --https-port 8443 79 | timeout 10 bash -c 'while ! curl --fail --insecure https://localhost:8443/__admin/; do sleep 1; done' 80 | docker container rm -f test 81 | 82 | - name: Push Wiremock Docker image 83 | uses: docker/build-push-action@v4 84 | with: 85 | context: ${{ matrix.versions.CONTEXT }} 86 | platforms: ${{ join(matrix.versions.PLATFORMS, ',') }} 87 | push: true 88 | tags: ${{ join(matrix.versions.TAGS, ',') }} 89 | -------------------------------------------------------------------------------- /.github/workflows/nightly.yml: -------------------------------------------------------------------------------- 1 | name: Nightly 2 | 3 | on: 4 | schedule: 5 | - cron: '0 0 * * *' 6 | 7 | workflow_dispatch: 8 | 9 | jobs: 10 | 11 | docker-build-push: 12 | runs-on: ubuntu-latest 13 | strategy: 14 | matrix: 15 | versions: 16 | - CONTEXT: . 17 | TAGS: 18 | - wiremock/wiremock:nightly 19 | - ghcr.io/wiremock/wiremock:nightly 20 | PLATFORMS: 21 | - linux/amd64 22 | - linux/arm64 23 | - linux/arm/v7 24 | - CONTEXT: alpine 25 | TAGS: 26 | - wiremock/wiremock:nightly-alpine 27 | - ghcr.io/wiremock/wiremock:nightly-alpine 28 | PLATFORMS: 29 | - linux/amd64 30 | steps: 31 | 32 | - name: Set up QEMU 33 | uses: docker/setup-qemu-action@v2 34 | if: ${{ matrix.versions.CONTEXT != 'alpine' }} 35 | with: 36 | image: tonistiigi/binfmt:latest 37 | platforms: all 38 | 39 | - name: Set up Docker Buildx 40 | uses: docker/setup-buildx-action@v2 41 | 42 | - name: Checkout sources 43 | uses: actions/checkout@main 44 | 45 | - name: Login to Docker Hub 46 | uses: docker/login-action@v2 47 | with: 48 | username: wiremockio 49 | password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} 50 | 51 | - name: Login to GitHub Container Registry 52 | uses: docker/login-action@v2 53 | with: 54 | registry: ghcr.io 55 | username: wiremock 56 | password: ${{ secrets.GITHUB_TOKEN }} 57 | 58 | - name: Build Wiremock Docker image 59 | uses: docker/build-push-action@v4 60 | with: 61 | context: ${{ matrix.versions.CONTEXT }} 62 | load: true 63 | file: ${{ matrix.versions.CONTEXT }}/Dockerfile-nightly 64 | tags: ${{ matrix.versions.TAGS[0] }} 65 | 66 | - name: Build Wiremock Docker image 67 | run: docker buildx build --tag ${{ matrix.versions.TAGS[0] }} --load ${{ matrix.versions.CONTEXT }} --file ${{ matrix.versions.CONTEXT }}/Dockerfile-nightly 68 | 69 | - name: Set up JDK 70 | uses: actions/setup-java@v3 71 | with: 72 | java-version: 11 73 | distribution: 'temurin' 74 | cache: maven 75 | 76 | - name: Run integration test 77 | working-directory: test/integration-tests 78 | run: mvn -B -ntp package verify --file pom.xml -DargLine="-Dit.wiremock-image=${{ matrix.versions.TAGS[0] }}" 79 | 80 | - name: Test Wiremock Docker image with SSL 81 | run: | 82 | docker container run -d --name test -p 8443:8443 ${{ matrix.versions.TAGS[0] }} --https-port 8443 83 | timeout 10 bash -c 'while ! curl --fail --insecure https://localhost:8443/__admin/; do sleep 1; done' 84 | docker container rm -f test 85 | 86 | - name: Push Wiremock Docker image 87 | uses: docker/build-push-action@v4 88 | with: 89 | context: ${{ matrix.versions.CONTEXT }} 90 | platforms: ${{ join(matrix.versions.PLATFORMS, ',') }} 91 | push: true 92 | file: ${{ matrix.versions.CONTEXT }}/Dockerfile-nightly 93 | tags: ${{ join(matrix.versions.TAGS, ',') }} 94 | -------------------------------------------------------------------------------- /.github/workflows/patch.yml: -------------------------------------------------------------------------------- 1 | name: Patch 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | tag: 7 | description: 'Wiremock Docker image tag' 8 | required: true 9 | 10 | jobs: 11 | 12 | docker-build-push: 13 | runs-on: ubuntu-latest 14 | strategy: 15 | matrix: 16 | versions: 17 | - CONTEXT: . 18 | IMAGES: 19 | - wiremock/wiremock:latest 20 | - wiremock/wiremock:${{ github.event.inputs.tag }} 21 | - ghcr.io/wiremock/wiremock:latest 22 | - ghcr.io/wiremock/wiremock:${{ github.event.inputs.tag }} 23 | PLATFORMS: 24 | - linux/amd64 25 | - linux/arm64 26 | - linux/arm/v7 27 | - CONTEXT: alpine 28 | IMAGES: 29 | - wiremock/wiremock:latest-alpine 30 | - wiremock/wiremock:${{ github.event.inputs.tag }}-alpine 31 | - ghcr.io/wiremock/wiremock:latest-alpine 32 | - ghcr.io/wiremock/wiremock:${{ github.event.inputs.tag }}-alpine 33 | PLATFORMS: 34 | - linux/amd64 35 | steps: 36 | 37 | - name: Set up QEMU 38 | uses: docker/setup-qemu-action@v2 39 | if: ${{ matrix.versions.CONTEXT != 'alpine' }} 40 | with: 41 | image: tonistiigi/binfmt:latest 42 | platforms: all 43 | 44 | - name: Set up Docker Buildx 45 | uses: docker/setup-buildx-action@v2 46 | 47 | - name: Checkout sources 48 | uses: actions/checkout@main 49 | 50 | - name: Login to Docker Hub 51 | uses: docker/login-action@v2 52 | with: 53 | username: wiremockio 54 | password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} 55 | 56 | - name: Login to GitHub Container Registry 57 | uses: docker/login-action@v2 58 | with: 59 | registry: ghcr.io 60 | username: wiremock 61 | password: ${{ secrets.GITHUB_TOKEN }} 62 | 63 | - name: Push Wiremock Docker image 64 | uses: docker/build-push-action@v4 65 | with: 66 | context: ${{ matrix.versions.CONTEXT }} 67 | platforms: ${{ join(matrix.versions.PLATFORMS, ',') }} 68 | push: true 69 | tags: ${{ join(matrix.versions.IMAGES, ',') }} 70 | 71 | release: 72 | runs-on: ubuntu-latest 73 | needs: docker-build-push 74 | steps: 75 | 76 | - name: Checkout sources 77 | uses: actions/checkout@main 78 | with: 79 | fetch-depth: 0 80 | 81 | - name: Update version 82 | run: | 83 | LAST_VERSION=$(git describe --tag --abbrev=0) 84 | LAST_MINOR_VERSION=${LAST_VERSION%.*} 85 | NEW_VERSION=${{ github.event.inputs.tag }} 86 | NEW_MINOR_VERSION=${NEW_VERSION%.*} 87 | sed -i s/${LAST_VERSION}/${NEW_VERSION}/g readme.md 88 | sed -i s/${LAST_MINOR_VERSION}/${NEW_MINOR_VERSION}/g readme.md 89 | git config --local user.name "rodolpheche" 90 | git config --local user.email "rodolphe.chaigneau@gmail.com" 91 | git add . 92 | git commit -m "upgrade to version $NEW_VERSION" 93 | git remote set-url origin https://${{ secrets.GITHUB_TOKEN }}@github.com/wiremock/wiremock-docker.git 94 | git push origin main 95 | 96 | - name: Release 97 | uses: softprops/action-gh-release@v1 98 | env: 99 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 100 | with: 101 | tag_name: ${{ github.event.inputs.tag }} 102 | -------------------------------------------------------------------------------- /.github/workflows/release-2.x.yml: -------------------------------------------------------------------------------- 1 | name: Release 2.x 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | version: 7 | description: 'Image version (single-digit suffix like 2.35.0-1)' 8 | required: true 9 | default: 1 10 | bundled-version: 11 | description: 'Bundled WireMock version' 12 | required: true 13 | default: 2.35.1 14 | 15 | jobs: 16 | 17 | check-new-version: 18 | runs-on: ubuntu-latest 19 | outputs: 20 | new_version: ${{ steps.new_version.outputs.NEW_VERSION }} 21 | steps: 22 | 23 | - name: Release if newer version 24 | id: new_version 25 | run: | 26 | CURRENT_VERSION=$(git -c 'versionsort.suffix=-' ls-remote --tags --sort='v:refname' https://github.com/wiremock/wiremock-docker.git '2.*.*' | tail -1 | cut -d '/' -f3) 27 | CURRENT_VERSION=${CURRENT_VERSION%-*} 28 | LATEST_VERSION=$(git -c 'versionsort.suffix=-' ls-remote --tags --sort='v:refname' https://github.com/wiremock/wiremock.git '2.*.*' | tail -1 | cut -d '/' -f3) 29 | echo "NEW_VERSION=${{ github.event.inputs.bundled-version }}-${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT 30 | 31 | docker-build-push: 32 | runs-on: ubuntu-latest 33 | needs: [check-new-version] 34 | if: needs.check-new-version.outputs.new_version 35 | strategy: 36 | matrix: 37 | versions: 38 | - CONTEXT: . 39 | IMAGES: 40 | - wiremock/wiremock:${{ needs.check-new-version.outputs.new_version }} 41 | - wiremock/wiremock:${{ github.event.inputs.bundled-version }} 42 | - ghcr.io/wiremock/wiremock:${{ needs.check-new-version.outputs.new_version }} 43 | PLATFORMS: 44 | - linux/amd64 45 | - linux/arm64 46 | - linux/arm/v7 47 | - CONTEXT: alpine 48 | IMAGES: 49 | - wiremock/wiremock:${{ needs.check-new-version.outputs.new_version }}-alpine 50 | - wiremock/wiremock:${{ github.event.inputs.bundled-version }}-alpine 51 | - ghcr.io/wiremock/wiremock:${{ needs.check-new-version.outputs.new_version }}-alpine 52 | PLATFORMS: 53 | - linux/amd64 54 | steps: 55 | 56 | - name: Set up QEMU 57 | uses: docker/setup-qemu-action@v2 58 | if: ${{ matrix.versions.CONTEXT != 'alpine' }} 59 | with: 60 | image: tonistiigi/binfmt:latest 61 | platforms: all 62 | 63 | - name: Set up Docker Buildx 64 | uses: docker/setup-buildx-action@v2 65 | 66 | - name: Checkout sources 67 | uses: actions/checkout@main 68 | with: 69 | fetch-depth: 0 70 | ref: 2.x 71 | 72 | - name: Login to Docker Hub 73 | uses: docker/login-action@v2 74 | with: 75 | username: wiremockio 76 | password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} 77 | 78 | - name: Login to GitHub Container Registry 79 | uses: docker/login-action@v2 80 | with: 81 | registry: ghcr.io 82 | username: wiremock 83 | password: ${{ secrets.GITHUB_TOKEN }} 84 | 85 | - name: Push WireMock Docker image 86 | uses: docker/build-push-action@v4 87 | with: 88 | context: ${{ matrix.versions.CONTEXT }} 89 | platforms: ${{ join(matrix.versions.PLATFORMS, ',') }} 90 | push: true 91 | tags: ${{ join(matrix.versions.IMAGES, ',') }} 92 | build-args: | 93 | "WIREMOCK_VERSION=${{ github.event.inputs.bundled-version }}" 94 | 95 | release: 96 | runs-on: ubuntu-latest 97 | needs: [docker-build-push, check-new-version] 98 | steps: 99 | 100 | - name: Checkout sources 101 | uses: actions/checkout@main 102 | with: 103 | fetch-depth: 0 104 | ref: "2.x" 105 | 106 | - name: Update version 107 | run: | 108 | # Replace version in readme.md 109 | LAST_VERSION=$(git describe --tag --abbrev=0) 110 | LAST_MINOR_VERSION=${LAST_VERSION%.*} 111 | NEW_VERSION=${{ needs.check-new-version.outputs.new_version }} 112 | NEW_MINOR_VERSION=${NEW_VERSION%.*} 113 | sed -i s/${LAST_VERSION}/${NEW_VERSION}/g readme.md 114 | sed -i s/${LAST_MINOR_VERSION}/${NEW_MINOR_VERSION}/g readme.md 115 | 116 | # Replace version in Dockerfiles 117 | LAST_VERSION=${LAST_VERSION%-*} 118 | sed -i 's/ARG WIREMOCK_VERSION=.*/ARG WIREMOCK_VERSION=${{ github.event.inputs.bundled-version }}/g' Dockerfile alpine/Dockerfile 119 | 120 | # Push update 121 | git config --local user.name "wiremockio" 122 | git config --local user.email "release-bot@wiremock.org" 123 | git add . 124 | git commit -m "upgrade to version ${NEW_VERSION}" 125 | git remote set-url origin https://${{ secrets.GITHUB_TOKEN }}@github.com/wiremock/wiremock-docker.git 126 | git push origin 2.x 127 | 128 | - name: Release 129 | uses: softprops/action-gh-release@v1 130 | env: 131 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 132 | with: 133 | tag_name: ${{ needs.check-new-version.outputs.new_version }} 134 | target_commitish: "2.x" 135 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | version: 7 | description: 'Image version (single-digit suffix like 2.35.0-1)' 8 | required: true 9 | default: 1 10 | bundled-version: 11 | description: 'Bundled WireMock version' 12 | required: true 13 | default: 3.6.0 14 | 15 | jobs: 16 | 17 | check-new-version: 18 | runs-on: ubuntu-latest 19 | outputs: 20 | new_version: ${{ steps.new_version.outputs.NEW_VERSION }} 21 | steps: 22 | 23 | - name: Release if newer version 24 | id: new_version 25 | run: | 26 | CURRENT_VERSION=$(git -c 'versionsort.suffix=-' ls-remote --tags --sort='v:refname' https://github.com/wiremock/wiremock-docker.git '*.*.*' | tail -1 | cut -d '/' -f3) 27 | CURRENT_VERSION=${CURRENT_VERSION%-*} 28 | LATEST_VERSION=$(git -c 'versionsort.suffix=-' ls-remote --tags --sort='v:refname' https://github.com/wiremock/wiremock.git '*.*.*' | tail -1 | cut -d '/' -f3) 29 | echo "NEW_VERSION=${{ github.event.inputs.bundled-version }}-${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT 30 | 31 | docker-build-push: 32 | runs-on: ubuntu-latest 33 | needs: [check-new-version] 34 | if: needs.check-new-version.outputs.new_version 35 | strategy: 36 | matrix: 37 | versions: 38 | - CONTEXT: . 39 | IMAGES: 40 | - wiremock/wiremock:latest 41 | - wiremock/wiremock:3x 42 | - wiremock/wiremock:${{ needs.check-new-version.outputs.new_version }} 43 | - wiremock/wiremock:${{ github.event.inputs.bundled-version }} 44 | - ghcr.io/wiremock/wiremock:latest 45 | - ghcr.io/wiremock/wiremock:${{ needs.check-new-version.outputs.new_version }} 46 | PLATFORMS: 47 | - linux/amd64 48 | - linux/arm64 49 | - linux/arm/v7 50 | - CONTEXT: alpine 51 | IMAGES: 52 | - wiremock/wiremock:latest-alpine 53 | - wiremock/wiremock:3x-alpine 54 | - wiremock/wiremock:${{ needs.check-new-version.outputs.new_version }}-alpine 55 | - wiremock/wiremock:${{ github.event.inputs.bundled-version }}-alpine 56 | - ghcr.io/wiremock/wiremock:latest-alpine 57 | - ghcr.io/wiremock/wiremock:${{ needs.check-new-version.outputs.new_version }}-alpine 58 | PLATFORMS: 59 | - linux/amd64 60 | 61 | steps: 62 | 63 | - name: Set up QEMU 64 | uses: docker/setup-qemu-action@v2 65 | with: 66 | image: tonistiigi/binfmt:latest 67 | platforms: all 68 | 69 | - name: Set up Docker Buildx 70 | uses: docker/setup-buildx-action@v2 71 | 72 | - name: Checkout sources 73 | uses: actions/checkout@main 74 | with: 75 | fetch-depth: 0 76 | 77 | - name: Login to Docker Hub 78 | uses: docker/login-action@v2 79 | with: 80 | username: wiremockio 81 | password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} 82 | 83 | - name: Login to GitHub Container Registry 84 | uses: docker/login-action@v2 85 | with: 86 | registry: ghcr.io 87 | username: wiremock 88 | password: ${{ secrets.GITHUB_TOKEN }} 89 | 90 | - name: Push WireMock Docker image 91 | uses: docker/build-push-action@v4 92 | with: 93 | context: ${{ matrix.versions.CONTEXT }} 94 | platforms: ${{ join(matrix.versions.PLATFORMS, ',') }} 95 | push: true 96 | tags: ${{ join(matrix.versions.IMAGES, ',') }} 97 | build-args: | 98 | "WIREMOCK_VERSION=${{ github.event.inputs.bundled-version }}" 99 | 100 | container-image-scan: 101 | uses: ./.github/workflows/container-image-scan.yml 102 | needs: [check-new-version, docker-build-push] 103 | if: needs.check-new-version.outputs.new_version 104 | with: 105 | image_version: ${{ needs.check-new-version.outputs.new_version }} 106 | secrets: inherit 107 | 108 | release: 109 | runs-on: ubuntu-latest 110 | needs: [docker-build-push, check-new-version] 111 | steps: 112 | 113 | - name: Checkout sources 114 | uses: actions/checkout@main 115 | with: 116 | fetch-depth: 0 117 | 118 | - name: Update version 119 | run: | 120 | # Replace version in README.md 121 | LAST_VERSION=$(git describe --tag --abbrev=0) 122 | LAST_MINOR_VERSION=${LAST_VERSION%.*} 123 | NEW_VERSION=${{ needs.check-new-version.outputs.new_version }} 124 | NEW_MINOR_VERSION=${NEW_VERSION%.*} 125 | sed -i s/${LAST_VERSION}/${NEW_VERSION}/g README.md 126 | sed -i s/${LAST_MINOR_VERSION}/${NEW_MINOR_VERSION}/g README.md 127 | 128 | # Replace version in Dockerfiles 129 | LAST_VERSION=${LAST_VERSION%-*} 130 | sed -i 's/ARG WIREMOCK_VERSION=.*/ARG WIREMOCK_VERSION=${{ github.event.inputs.bundled-version }}/g' Dockerfile alpine/Dockerfile 131 | 132 | # Push update 133 | git config --local user.name "wiremockio" 134 | git config --local user.email "release-bot@wiremock.org" 135 | git add . 136 | git commit -m "upgrade to version ${NEW_VERSION}" 137 | git remote set-url origin https://${{ secrets.GITHUB_TOKEN }}@github.com/wiremock/wiremock-docker.git 138 | git push origin main 139 | 140 | - name: Release 141 | uses: softprops/action-gh-release@v1 142 | env: 143 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 144 | with: 145 | tag_name: ${{ needs.check-new-version.outputs.new_version }} 146 | 147 | container-image-monitor: 148 | name: Snyk container image monitoring 149 | runs-on: ubuntu-latest 150 | needs: [check-new-version, release] 151 | 152 | if: needs.check-new-version.outputs.new_version 153 | strategy: 154 | matrix: 155 | versions: 156 | - CONTEXT: . 157 | image: wiremock/wiremock:${{ needs.check-new-version.outputs.new_version }} 158 | - CONTEXT: alpine 159 | image: wiremock/wiremock:${{ needs.check-new-version.outputs.new_version }}-alpine 160 | 161 | steps: 162 | - uses: actions/checkout@v4 163 | 164 | - name: Pull image to check we've got it 165 | run: docker pull ${{ matrix.versions.image }} 166 | 167 | - name: Run Snyk to monitor Docker image for vulnerabilities 168 | uses: snyk/actions/docker@master 169 | env: 170 | SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} 171 | with: 172 | image: ${{ matrix.versions.image }} 173 | command: monitor 174 | args: --file=${{ matrix.versions.CONTEXT }}/Dockerfile --org=f310ee2f-5552-444d-84ee-ec8c44c33adb --project-name=wiremock-docker --policy-path=${{ matrix.versions.CONTEXT }}/.snyk 175 | -------------------------------------------------------------------------------- /.github/workflows/update-docs.yml: -------------------------------------------------------------------------------- 1 | name: Update Documentation 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | workflow_dispatch: 8 | 9 | jobs: 10 | update_release_draft: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout sources 14 | uses: actions/checkout@main 15 | - name: Push DockerHub Description 16 | uses: peter-evans/dockerhub-description@v3.4.2 17 | with: 18 | username: wiremockio 19 | password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} 20 | repository: wiremock/wiremock 21 | short-description: Official images for the WireMock standalone server 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .project 2 | .settings 3 | .idea 4 | .history 5 | 6 | test/integration-tests/target 7 | test/integration-tests/integration-tests.iml 8 | -------------------------------------------------------------------------------- /.snyk: -------------------------------------------------------------------------------- 1 | # Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities. 2 | version: v1.25.0 3 | # ignores vulnerabilities until expiry date; change duration by modifying expiry date 4 | ignore: 5 | SNYK-UBUNTU2404-LIBPNG16-6702001: 6 | - '*': 7 | reason: Brought in by base layer eclipse-temurin:11.0.24_8-jre, no fixed image available yet 8 | expires: 2024-10-13T13:00:41.094Z 9 | created: 2024-09-13T13:00:41.095Z 10 | SNYK-UBUNTU2404-KRB5-6693034: 11 | - '*': 12 | reason: Brought in by base layer eclipse-temurin:11.0.24_8-jre, no fixed image available yet 13 | expires: 2024-10-13T13:00:54.423Z 14 | created: 2024-09-13T13:00:54.427Z 15 | SNYK-UBUNTU2404-KRB5-6693038: 16 | - '*': 17 | reason: Brought in by base layer eclipse-temurin:11.0.24_8-jre, no fixed image available yet 18 | expires: 2024-10-13T13:01:09.219Z 19 | created: 2024-09-13T13:01:09.223Z 20 | SNYK-UBUNTU2404-GNUPG2-6702792: 21 | - '*': 22 | reason: Brought in by base layer eclipse-temurin:11.0.24_8-jre, no fixed image available yet 23 | expires: 2024-10-13T13:01:22.110Z 24 | created: 2024-09-13T13:01:22.113Z 25 | SNYK-UBUNTU2404-GLIBC-6727419: 26 | - '*': 27 | reason: Brought in by base layer eclipse-temurin:11.0.24_8-jre, no fixed image available yet 28 | expires: 2024-10-13T13:01:32.787Z 29 | created: 2024-09-13T13:01:32.791Z 30 | SNYK-UBUNTU2404-COREUTILS-6727355: 31 | - '*': 32 | reason: Brought in by base layer eclipse-temurin:11.0.24_8-jre, no fixed image available yet 33 | expires: 2024-10-13T13:01:45.887Z 34 | created: 2024-09-13T13:01:45.892Z 35 | SNYK-UBUNTU2404-WGET-6709170: 36 | - '*': 37 | reason: Brought in by base layer eclipse-temurin:11.0.24_8-jre, no fixed image available yet 38 | expires: 2024-10-13T13:02:00.232Z 39 | created: 2024-09-13T13:02:00.238Z 40 | SNYK-UBUNTU2404-OPENSSL-7838291: 41 | - '*': 42 | reason: Brought in by base layer eclipse-temurin:11.0.24_8-jre, no fixed image available yet 43 | expires: 2024-10-13T13:02:12.079Z 44 | created: 2024-09-13T13:02:12.083Z 45 | SNYK-UBUNTU2404-OPENSSL-7886358: 46 | - '*': 47 | reason: Brought in by base layer eclipse-temurin:11.0.24_8-jre, no fixed image available yet 48 | expires: 2024-10-13T13:02:35.392Z 49 | created: 2024-09-13T13:02:35.397Z 50 | SNYK-UBUNTU2404-LIBGCRYPT20-6693674: 51 | - '*': 52 | reason: Brought in by base layer eclipse-temurin:11.0.24_8-jre, no fixed image available yet 53 | expires: 2024-10-13T13:02:52.497Z 54 | created: 2024-09-13T13:02:52.501Z 55 | SNYK-UBUNTU2404-KRB5-6693037: 56 | - '*': 57 | reason: Brought in by base layer eclipse-temurin:11.0.24_8-jre, no fixed image available yet 58 | expires: 2024-10-13T13:03:09.281Z 59 | created: 2024-09-13T13:03:09.286Z 60 | SNYK-UBUNTU2404-EXPAT-7885392: 61 | - '*': 62 | reason: Brought in by base layer eclipse-temurin:11.0.24_8-jre, no fixed image available yet 63 | expires: 2024-10-13T13:03:21.125Z 64 | created: 2024-09-13T13:03:21.130Z 65 | SNYK-UBUNTU2404-EXPAT-7885502: 66 | - '*': 67 | reason: Brought in by base layer eclipse-temurin:11.0.24_8-jre, no fixed image available yet 68 | expires: 2024-10-13T13:03:31.155Z 69 | created: 2024-09-13T13:03:31.159Z 70 | SNYK-UBUNTU2404-EXPAT-7885595: 71 | - '*': 72 | reason: Brought in by base layer eclipse-temurin:11.0.24_8-jre, no fixed image available yet 73 | expires: 2024-10-13T13:03:50.947Z 74 | created: 2024-09-13T13:03:50.952Z 75 | SNYK-UBUNTU2404-CURL-7931919: 76 | - '*': 77 | reason: Brought in by base layer eclipse-temurin:11.0.24_8-jre, no fixed image available yet 78 | expires: 2024-10-13T13:03:59.372Z 79 | created: 2024-09-13T13:03:59.377Z 80 | patch: {} 81 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM eclipse-temurin:11.0.24_8-jre 2 | 3 | LABEL maintainer="Rodolphe CHAIGNEAU " 4 | 5 | ARG WIREMOCK_VERSION=3.13.0 6 | ENV WIREMOCK_VERSION=$WIREMOCK_VERSION 7 | ENV GOSU_VERSION=1.17 8 | 9 | WORKDIR /home/wiremock 10 | 11 | # grab gosu for easy step-down from root 12 | RUN set -eux; \ 13 | # save list of currently installed packages for later so we can clean up 14 | savedAptMark="$(apt-mark showmanual)"; \ 15 | apt-get update; \ 16 | apt-get install -y --no-install-recommends ca-certificates wget; \ 17 | if ! command -v gpg; then \ 18 | apt-get install -y --no-install-recommends gnupg2 dirmngr; \ 19 | elif gpg --version | grep -q '^gpg (GnuPG) 1\.'; then \ 20 | # "This package provides support for HKPS keyservers." (GnuPG 1.x only) 21 | apt-get install -y --no-install-recommends gnupg-curl; \ 22 | fi; \ 23 | rm -rf /var/lib/apt/lists/*; \ 24 | \ 25 | dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \ 26 | wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \ 27 | wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \ 28 | \ 29 | # verify the signature 30 | export GNUPGHOME="$(mktemp -d)"; \ 31 | gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \ 32 | gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \ 33 | command -v gpgconf && gpgconf --kill all || :; \ 34 | rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \ 35 | \ 36 | # clean up fetch dependencies 37 | apt-mark auto '.*' > /dev/null; \ 38 | [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \ 39 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ 40 | \ 41 | chmod +x /usr/local/bin/gosu; \ 42 | # verify that the binary works 43 | gosu --version; \ 44 | gosu nobody true 45 | 46 | # grab wiremock standalone jar 47 | RUN mkdir -p /var/wiremock/lib/ \ 48 | && curl https://repo1.maven.org/maven2/org/wiremock/wiremock-standalone/$WIREMOCK_VERSION/wiremock-standalone-$WIREMOCK_VERSION.jar \ 49 | -o /var/wiremock/lib/wiremock-standalone.jar 50 | 51 | # Init WireMock files structure 52 | RUN mkdir -p /home/wiremock/mappings && \ 53 | mkdir -p /home/wiremock/__files && \ 54 | mkdir -p /var/wiremock/extensions 55 | 56 | COPY docker-entrypoint.sh / 57 | 58 | EXPOSE 8080 8443 59 | 60 | HEALTHCHECK --start-period=5s --start-interval=100ms CMD curl -f http://localhost:8080/__admin/health || exit 1 61 | 62 | ENTRYPOINT ["/docker-entrypoint.sh"] 63 | -------------------------------------------------------------------------------- /Dockerfile-nightly: -------------------------------------------------------------------------------- 1 | # BUILD 2 | 3 | FROM gradle:7-jdk11 AS builder 4 | 5 | WORKDIR /workdir 6 | 7 | RUN git clone https://github.com/wiremock/wiremock . 8 | 9 | RUN sed -i /Xmx3g/d gradle.properties 10 | 11 | RUN ./gradlew shadowJar 12 | 13 | # RUN 14 | 15 | FROM eclipse-temurin:11.0.24_8-jre 16 | 17 | LABEL maintainer="Rodolphe CHAIGNEAU " 18 | 19 | WORKDIR /home/wiremock 20 | 21 | COPY --from=builder /workdir/build/libs/*.jar /var/wiremock/lib/wiremock-standalone.jar 22 | 23 | COPY docker-entrypoint.sh / 24 | 25 | # Init WireMock files structure 26 | RUN mkdir -p /home/wiremock/mappings && \ 27 | mkdir -p /home/wiremock/__files && \ 28 | mkdir -p /var/wiremock/extensions 29 | 30 | EXPOSE 8080 8443 31 | 32 | HEALTHCHECK --start-period=5s --start-interval=100ms CMD curl -f http://localhost:8080/__admin/health || exit 1 33 | 34 | ENTRYPOINT ["/docker-entrypoint.sh"] 35 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016-2023 Rodolphe CHAIGNEAU, Oleg NENASHEV, and all contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WireMock Docker images 2 | 3 | [![Main](https://github.com/wiremock/wiremock-docker/actions/workflows/main.yml/badge.svg)](https://github.com/wiremock/wiremock-docker/actions/workflows/main.yml) [![Nightly](https://github.com/wiremock/wiremock-docker/actions/workflows/nightly.yml/badge.svg)](https://github.com/wiremock/wiremock-docker/actions/workflows/nightly.yml) [![Docker Pulls](https://img.shields.io/docker/pulls/wiremock/wiremock.svg)](https://hub.docker.com/r/wiremock/wiremock/) 4 | [![a](https://img.shields.io/badge/slack-Join%20us-brightgreen?style=flat&logo=slack)](https://slack.wiremock.org/) 5 | 6 | The official Docker image for WireMock Standalone deployments. 7 | It includes WireMock for Java under the hood, and fully compatible with its features. 8 | You can learn more about WireMock standalone on the 9 | [WireMock docs site]((http://wiremock.org/docs/standalone)). 10 | 11 | ## Quick Start 12 | 13 | In a temporary directory, checkout the demo repository, 14 | pull the Docker image, 15 | and start the WireMock instance. 16 | 17 | ```shell 18 | docker pull wiremock/wiremock:latest 19 | git clone https://github.com/wiremock/wiremock-docker.git 20 | docker run -it --rm \ 21 | -p 8080:8080 \ 22 | -v $PWD/wiremock-docker/samples/hello/stubs:/home/wiremock \ 23 | wiremock/wiremock:latest 24 | ``` 25 | 26 | You will get a CLI output like this one: 27 | 28 | ```shell 29 | ██ ██ ██ ██████ ███████ ███ ███ ██████ ██████ ██ ██ 30 | ██ ██ ██ ██ ██ ██ ████ ████ ██ ██ ██ ██ ██ 31 | ██ █ ██ ██ ██████ █████ ██ ████ ██ ██ ██ ██ █████ 32 | ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ 33 | ███ ███ ██ ██ ██ ███████ ██ ██ ██████ ██████ ██ ██ 34 | 35 | ---------------------------------------------------------------- 36 | | Cloud: https://wiremock.io/cloud | 37 | | Slack: https://slack.wiremock.org | 38 | ---------------------------------------------------------------- 39 | 40 | port: 8080 41 | enable-browser-proxying: false 42 | no-request-journal: false 43 | verbose: false 44 | extensions: response-template,webhook 45 | ``` 46 | 47 | ## Supported architectures 48 | 49 | - x64 50 | - armv7 51 | - armv8 52 | 53 | ## Supported tags 54 | 55 | There are multiple image tags provided for end users. 56 | These tags are available on DockerHub and GitHub Packages, 57 | see the full list [here](https://hub.docker.com/r/wiremock/wiremock/tags/). 58 | The most important tags are listed below. 59 | 60 | ### Latest images 61 | 62 | - `3.13.0-1` [(3.13.0-1/Dockerfile)](https://github.com/wiremock/wiremock-docker/blob/3.13.0-1/Dockerfile) 63 | - `3.13.0-1-alpine` [(3.13-alpine/Dockerfile)](https://github.com/wiremock/wiremock-docker/blob/3.13.0-1/alpine/Dockerfile) 64 | - `latest` [(latest/Dockerfile)](https://github.com/wiremock/wiremock-docker/blob/latest/Dockerfile) 65 | - `latest-alpine` [(latest-alpine/Dockerfile)](https://github.com/wiremock/wiremock-docker/blob/latest-alpine/Dockerfile) 66 | - `main` [(main/Dockerfile)](https://github.com/wiremock/wiremock-docker/blob/main/Dockerfile) 67 | - `main-alpine` [(main-alpine/Dockerfile)](https://github.com/wiremock/wiremock-docker/blob/main/alpine/Dockerfile) 68 | 69 | ### Latest WireMock 2.x images 70 | 71 | - `2.35.1-1` [(2.35.1-1/Dockerfile)](https://github.com/wiremock/wiremock-docker/blob/2.35.1-1/Dockerfile) 72 | - `2.35.1-1-alpine` [(2.35.1-1-alpine/Dockerfile)](https://github.com/wiremock/wiremock-docker/blob/2.35.1-1/alpine/Dockerfile) 73 | 74 | ### Deprecated and experimental tags 75 | 76 | - `nightly` [(main/Dockerfile-nightly)](https://github.com/wiremock/wiremock-docker/blob/main/Dockerfile-nightly) 77 | - `nightly-alpine` [(main-alpine/Dockerfile-nightly)](https://github.com/wiremock/wiremock-docker/blob/main/alpine/Dockerfile-nightly) 78 | - `3x`- Latest WireMock 3.x image, with bundled Java 11 - now `latest` 79 | - `3x-alpine` - Latest WireMock alpine 3.x image, with bundled Java 11 - now `latest` 80 | 81 | ## Using WireMock in Docker 82 | 83 | To start WireMock with the default settings: 84 | 85 | ```sh 86 | docker run -it --rm -p 8080:8080 wiremock/wiremock 87 | ``` 88 | 89 | By default, the image exposes the 8080 port for HTTP. 90 | To verify the WireMock state, 91 | access [http://localhost:8080/__admin/health](http://localhost:8080/__admin/health) to display the health status and the information. 92 | The `/__admin/health` endpoint is available for WireMock 3.1.0 or above. 93 | 94 | A [HEALTHCHECK](https://docs.docker.com/reference/dockerfile/#healthcheck) is also built into the docker image to 95 | allow direct querying of the docker container's health status. 96 | Under the hood, this uses the same method as above to verify the status of the container. 97 | 98 | ## Configuring WireMock 99 | 100 | You can configure WireMock using the following ways: 101 | 102 | - Passing the CLI arguments 103 | - Passing Environment variables 104 | - Passing configuration files via volumes 105 | - Building a custom image using `wiremock/wiremock` as a base image 106 | 107 | ### Passing the CLI arguments 108 | 109 | To start with these WireMock arguments, 110 | you can add them to the end of the command line. 111 | For example, to enable HTTPs: `--https-port 8443 --verbose` 112 | 113 | ```sh 114 | docker run -it --rm -p 8443.13443 wiremock/wiremock --https-port 8443 --verbose 115 | ``` 116 | 117 | ### Using environment variables 118 | 119 | The following environment variables are supported by the image: 120 | 121 | - `uid` : the container executor uid, useful to avoid file creation owned by root 122 | - `JAVA_OPTS` : for passing any custom options to Java e.g. `-Xmx128m` 123 | - `WIREMOCK_OPTIONS`: CLI options to be passed to WireMock (starting from `3.2.0-2`). 124 | 125 | Example for passing the CLI options: 126 | 127 | ```sh 128 | docker run -it --rm \ 129 | -e WIREMOCK_OPTIONS='--https-port 8443 --verbose' \ 130 | -p 8443.13443 \ 131 | --name wiremock \ 132 | wiremock/wiremock:latest 133 | ``` 134 | 135 | ### Passing configuration files as volumes 136 | 137 | Inside the container, the WireMock uses `/home/wiremock` as the root from which it reads the `mappings` and `__files` directories. 138 | This means you can mount a directory containing these from your host machine into Docker and WireMock will load the stub mappings. 139 | 140 | To mount the current directory use `-v $PWD:/home/wiremock` e.g.: 141 | 142 | ```sh 143 | docker run -it --rm \ 144 | -p 8080:8080 \ 145 | --name wiremock \ 146 | -v $PWD:/home/wiremock \ 147 | wiremock/wiremock:{{ site.wiremock_version }} 148 | ``` 149 | 150 | ## Building your own image 151 | 152 | Inside the container, the WireMock uses `/home/wiremock` as the root from which it reads the `mappings` and `__files` directories. 153 | This means you can copy your configuration from your host machine into Docker and WireMock will load the stub mappings. 154 | 155 | WireMock utilizes a custom entrypoint script that passes all provided arguments as WireMock startup parameters. To modify the WireMock launch parameters it is recommended to override the entrypoint in your custom Docker image. 156 | 157 | ```Dockerfile 158 | # Sample Dockerfile 159 | FROM wiremock/wiremock:latest 160 | COPY wiremock /home/wiremock 161 | ENTRYPOINT ["/docker-entrypoint.sh", "--global-response-templating", "--disable-gzip", "--verbose"] 162 | ``` 163 | 164 | ## Using WireMock extensions 165 | 166 | You can use any [WireMock extension](https://wiremock.org/docs/extensions) 167 | with the Docker image. 168 | They can be added via CLI and volumes, 169 | but for most of the use-cases it is recommended to build a custom image by extending the 170 | official one. 171 | 172 | ### Using extensions in CLI 173 | 174 | For old style extensions (that don't have Java service loader metadata) you need to add the extension JAR file into the extensions directory and 175 | specify the name of the extension's main class via the `--extensions` parameter: 176 | 177 | ```sh 178 | # prepare extension folder 179 | mkdir wiremock-docker/samples/random/extensions 180 | # download extension 181 | wget https://repo1.maven.org/maven2/com/opentable/wiremock-body-transformer/1.1.3/wiremock-body-transformer-1.1.3.jar \ 182 | -O wiremock-docker/samples/random/extensions/wiremock-body-transformer-1.1.3.jar 183 | # run a container using extension 184 | docker run -it --rm \ 185 | -p 8080:8080 \ 186 | -v $PWD/wiremock-docker/samples/random/stubs:/home/wiremock \ 187 | -v $PWD/wiremock-docker/samples/random/extensions:/var/wiremock/extensions \ 188 | wiremock/wiremock \ 189 | --extensions com.opentable.extension.BodyTransformer 190 | ``` 191 | 192 | For new style extensions the `--extensions` part should not be included as the extension will be discovered and loaded automatically: 193 | 194 | ```sh 195 | # prepare extension folder 196 | mkdir wiremock-docker/samples/random/extensions 197 | # download extension 198 | wget https://repo1.maven.org/maven2/org/wiremock/wiremock-grpc-extension-standalone/0.5.0/wiremock-grpc-extension-standalone-0.5.0.jar \ 199 | -O wiremock-docker/samples/random/extensions/wiremock-grpc-extension-standalone-0.5.0.jar 200 | # run a container using extension 201 | docker run -it --rm \ 202 | -p 8080:8080 \ 203 | -v $PWD/wiremock-docker/samples/random/stubs:/home/wiremock \ 204 | -v $PWD/wiremock-docker/samples/random/extensions:/var/wiremock/extensions \ 205 | wiremock/wiremock 206 | ``` 207 | 208 | ### Using extensions in the Dockerfile 209 | 210 | ```sh 211 | git clone https://github.com/wiremock/wiremock-docker.git 212 | docker build -t wiremock-random wiremock-docker/samples/random 213 | docker run -it --rm -p 8080:8080 wiremock-random 214 | ``` 215 | 216 | > Access [http://localhost:8080/random](http://localhost:8080/random) to show random number 217 | 218 | ## Advanced use-cases 219 | 220 | ### Using HTTPs 221 | 222 | For HTTPs, the `8443` port is exposed by default. 223 | To run with HTTPs, run the following command: 224 | 225 | ```sh 226 | docker run -it --rm -p 8443.13443 wiremock/wiremock --https-port 8443 --verbose 227 | ``` 228 | 229 | To check the HTTPs on the default exposed port, 230 | use [https://localhost:8443/__admin](https://localhost:8443/__admin) to check HTTPs working. 231 | 232 | ### Using the Record Mode 233 | 234 | In Record mode, when binding host folders (e.g. $PWD/test) with the container volume (/home/wiremock), the created files will be owned by root, which is, in most cases, undesired. 235 | To avoid this, you can use the `uid` docker environment variable to also bind host uid with the container executor uid. 236 | 237 | ```sh 238 | docker run -d --name wiremock-container \ 239 | -p 8080:8080 \ 240 | -v $PWD/test:/home/wiremock \ 241 | -e uid=$(id -u) \ 242 | wiremock/wiremock \ 243 | --proxy-all="http://registry.hub.docker.com" \ 244 | --record-mappings --verbose 245 | curl http://localhost:8080 246 | docker rm -f wiremock-container 247 | ``` 248 | 249 | > Check the created file owner with `ls -alR test` 250 | 251 | However, the example above is a facility. 252 | The good practice is to create yourself the binded folder with correct permissions and to use the *-u* docker argument. 253 | 254 | ```sh 255 | mkdir test 256 | docker run -d --name wiremock-container \ 257 | -p 8080:8080 \ 258 | -v $PWD/test:/home/wiremock \ 259 | -u $(id -u):$(id -g) \ 260 | wiremock/wiremock \ 261 | --proxy-all="http://registry.hub.docker.com" \ 262 | --record-mappings --verbose 263 | curl http://localhost:8080 264 | docker rm -f wiremock-container 265 | ``` 266 | 267 | > Check the created file owner with `ls -alR test` 268 | 269 | ### Docker Compose 270 | 271 | Configuration in compose file is similar to Dockerfile definition 272 | 273 | ```yaml 274 | # Sample compose file 275 | version: "3" 276 | services: 277 | wiremock: 278 | image: "wiremock/wiremock:latest" 279 | container_name: my_wiremock 280 | entrypoint: ["/docker-entrypoint.sh", "--global-response-templating", "--disable-gzip", "--verbose"] 281 | ``` 282 | 283 | You can also mount your local `__files` and `mappings` files into the container e.g: 284 | 285 | ```yaml 286 | # Sample compose file 287 | version: "3" 288 | services: 289 | wiremock: 290 | image: "wiremock/wiremock:latest" 291 | container_name: my_wiremock 292 | volumes: 293 | - ./__files:/home/wiremock/__files 294 | - ./mappings:/home/wiremock/mappings 295 | entrypoint: ["/docker-entrypoint.sh", "--global-response-templating", "--disable-gzip", "--verbose"] 296 | ``` 297 | 298 | ## References 299 | 300 | - [WireMock modules for Testcontainers](https://wiremock.org/docs/solutions/testcontainers/), based on this official image 301 | - [Helm Chart for WireMock](https://wiremock.org/docs/solutions/kubernetes/) 302 | -------------------------------------------------------------------------------- /alpine/.snyk: -------------------------------------------------------------------------------- 1 | # Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities. 2 | version: v1.25.0 3 | # ignores vulnerabilities until expiry date; change duration by modifying expiry date 4 | ignore: 5 | SNYK-ALPINE320-EXPAT-7908298: 6 | - '*': 7 | reason: Brought in by base layer eclipse-temurin:11-jre-alpine, no fixed image available yet 8 | expires: 2024-10-13T13:27:25.403Z 9 | created: 2024-09-13T13:27:25.405Z 10 | SNYK-ALPINE320-EXPAT-7908299: 11 | - '*': 12 | reason: Brought in by base layer eclipse-temurin:11-jre-alpine, no fixed image available yet 13 | expires: 2024-10-13T13:27:35.505Z 14 | created: 2024-09-13T13:27:35.509Z 15 | SNYK-ALPINE320-EXPAT-7908300: 16 | - '*': 17 | reason: Brought in by base layer eclipse-temurin:11-jre-alpine, no fixed image available yet 18 | expires: 2024-10-13T13:27:45.509Z 19 | created: 2024-09-13T13:27:45.513Z 20 | patch: {} 21 | -------------------------------------------------------------------------------- /alpine/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM eclipse-temurin:11-jre-alpine 2 | 3 | LABEL maintainer="Rodolphe CHAIGNEAU " 4 | 5 | ARG WIREMOCK_VERSION=3.13.0 6 | ENV WIREMOCK_VERSION=$WIREMOCK_VERSION 7 | 8 | WORKDIR /home/wiremock 9 | 10 | RUN apk add --update openssl 11 | 12 | # grab su-exec for easy step-down from root 13 | # and bash 14 | RUN apk add --no-cache 'su-exec>=0.2' bash 15 | 16 | # grab wiremock standalone jar 17 | RUN mkdir -p /var/wiremock/lib/ \ 18 | && wget https://repo1.maven.org/maven2/org/wiremock/wiremock-standalone/$WIREMOCK_VERSION/wiremock-standalone-$WIREMOCK_VERSION.jar \ 19 | -O /var/wiremock/lib/wiremock-standalone.jar 20 | 21 | # Init WireMock files structure 22 | RUN mkdir -p /home/wiremock/mappings && \ 23 | mkdir -p /home/wiremock/__files && \ 24 | mkdir -p /var/wiremock/extensions 25 | 26 | COPY docker-entrypoint.sh / 27 | 28 | EXPOSE 8080 8443 29 | 30 | HEALTHCHECK --start-period=5s --start-interval=100ms CMD wget --no-verbose --tries=1 --spider http://localhost:8080/__admin/health || exit 1 31 | 32 | ENTRYPOINT ["/docker-entrypoint.sh"] 33 | -------------------------------------------------------------------------------- /alpine/Dockerfile-nightly: -------------------------------------------------------------------------------- 1 | # BUILD 2 | 3 | FROM gradle:7-jdk11 AS builder 4 | 5 | WORKDIR /workdir 6 | 7 | RUN git clone https://github.com/wiremock/wiremock . 8 | 9 | RUN ./gradlew shadowJar 10 | 11 | # RUN 12 | 13 | FROM eclipse-temurin:11.0.20_8-jre-alpine 14 | 15 | LABEL maintainer="Rodolphe CHAIGNEAU " 16 | 17 | WORKDIR /home/wiremock 18 | 19 | RUN apk add --update openssl 20 | 21 | # grab su-exec for easy step-down from root 22 | # and bash 23 | RUN apk add --no-cache 'su-exec>=0.2' bash 24 | 25 | COPY --from=builder /workdir/build/libs/*.jar /var/wiremock/lib/wiremock-standalone.jar 26 | 27 | # Init WireMock files structure 28 | RUN mkdir -p /home/wiremock/mappings && \ 29 | mkdir -p /home/wiremock/__files && \ 30 | mkdir -p /var/wiremock/extensions 31 | 32 | COPY docker-entrypoint.sh / 33 | 34 | EXPOSE 8080 8443 35 | 36 | HEALTHCHECK --start-period=5s --start-interval=100ms CMD wget --no-verbose --tries=1 --spider http://localhost:8080/__admin/health || exit 1 37 | 38 | ENTRYPOINT ["/docker-entrypoint.sh"] 39 | -------------------------------------------------------------------------------- /alpine/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | # Set `java` command if needed 6 | if [ "$1" = "" -o "${1#-}" != "$1" ]; then 7 | set -- java $JAVA_OPTS -cp /var/wiremock/lib/*:/var/wiremock/extensions/* wiremock.Run "$@" 8 | fi 9 | 10 | # allow the container to be started with `-e uid=` 11 | if [ "$uid" != "" ]; then 12 | # Change the ownership of /home/wiremock to $uid 13 | chown -R $uid:$uid /home/wiremock 14 | 15 | set -- su-exec $uid:$uid "$@" 16 | fi 17 | 18 | exec "$@" $WIREMOCK_OPTIONS 19 | -------------------------------------------------------------------------------- /docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | # Set `java` command if needed 6 | if [ "$1" = "" -o "${1:0:1}" = "-" ]; then 7 | set -- java $JAVA_OPTS -cp /var/wiremock/lib/*:/var/wiremock/extensions/* wiremock.Run "$@" 8 | fi 9 | 10 | # allow the container to be started with `-e uid=` 11 | if [ "$uid" != "" ]; then 12 | # Change the ownership of /home/wiremock to $uid 13 | chown -R $uid:$uid /home/wiremock 14 | set -- gosu $uid:$uid "$@" 15 | fi 16 | 17 | exec "$@" $WIREMOCK_OPTIONS 18 | -------------------------------------------------------------------------------- /samples/hello/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM wiremock/wiremock 2 | 3 | COPY stubs /home/wiremock 4 | -------------------------------------------------------------------------------- /samples/hello/Dockerfile-nightly: -------------------------------------------------------------------------------- 1 | FROM wiremock/wiremock:nightly 2 | 3 | COPY stubs /home/wiremock 4 | -------------------------------------------------------------------------------- /samples/hello/stubs/__files/hello.json: -------------------------------------------------------------------------------- 1 | { 2 | "message": "Hello World !" 3 | } 4 | -------------------------------------------------------------------------------- /samples/hello/stubs/mappings/hello.json: -------------------------------------------------------------------------------- 1 | { 2 | "request": { 3 | "method": "GET", 4 | "url": "/hello" 5 | }, 6 | "response": { 7 | "status": 200, 8 | "bodyFileName": "hello.json" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /samples/random/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM wiremock/wiremock:3.3.1-1 2 | 3 | COPY stubs /home/wiremock 4 | 5 | ADD https://repo1.maven.org/maven2/org/wiremock/extensions/wiremock-faker-extension-standalone/0.1.1/wiremock-faker-extension-standalone-0.1.1.jar /var/wiremock/extensions/ 6 | # TODO: Checksum Validation 7 | 8 | CMD ["--global-response-templating", "--extensions", "org.wiremock.RandomExtension"] 9 | -------------------------------------------------------------------------------- /samples/random/Dockerfile-nightly: -------------------------------------------------------------------------------- 1 | FROM wiremock/wiremock:nightly 2 | 3 | COPY stubs /home/wiremock 4 | 5 | ADD https://repo1.maven.org/maven2/com/opentable/wiremock-body-transformer/1.1.3/wiremock-body-transformer-1.1.3.jar /var/wiremock/extensions/ 6 | 7 | CMD ["--extensions", "com.opentable.extension.BodyTransformer"] 8 | -------------------------------------------------------------------------------- /samples/random/README.md: -------------------------------------------------------------------------------- 1 | # Sample - Random Response Field 2 | 3 | We use WireMock Faker extension in this demo: 4 | 5 | To run: 6 | 7 | ```shell 8 | docker build -t wiremock/random-data-demo . 9 | docker run --rm - p 8080:8080 wiremock/random-data-demo 10 | ``` 11 | 12 | Then you can use the following endpoints: 13 | 14 | - '/user' - random user ID 15 | - '/user?pretty=true' - random user id with fancy layout 16 | - '/users.csv' - generate a CSV file with a random number of users 17 | -------------------------------------------------------------------------------- /samples/random/stubs/__files/user.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{ random 'Name.first_name' }}", 3 | "surname": "{{ random 'Name.last_name' }}", 4 | "country": "{{ random 'Address.country' }}", 5 | "city": "{{ random 'Address.city' }}", 6 | "favorite_tool": "WireMock" 7 | } 8 | -------------------------------------------------------------------------------- /samples/random/stubs/__files/users.csv.template: -------------------------------------------------------------------------------- 1 | ID, First Name, Last Name, Country, City, Favorite Tool, 2 | {{#each (range 0 (randomInt lower=1 upper=20)) as |index|}}{{index}}, {{ random 'Name.first_name' }}, {{ random 'Name.last_name' }}, {{ random 'Address.country' }}, {{ random 'Address.city' }}, WireMock,{{/each}} 3 | -------------------------------------------------------------------------------- /samples/random/stubs/mappings/user.json: -------------------------------------------------------------------------------- 1 | { 2 | "mappings": [ 3 | { 4 | "request": { 5 | "method": "GET", 6 | "urlPath": "/user", 7 | "queryParameters" : { 8 | "pretty" : { 9 | "absent" : true 10 | } 11 | } 12 | }, 13 | "response": { 14 | "status": 200, 15 | "headers": { 16 | "Content-Type": "application/json" 17 | }, 18 | "jsonBody": { 19 | "name": "{{ random 'Name.first_name' }}", 20 | "surname": "{{ random 'Name.last_name' }}", 21 | "country": "{{ random 'Address.country' }}", 22 | "city": "{{ random 'Address.city' }}", 23 | "favorite_tool": "WireMock" 24 | } 25 | } 26 | }, 27 | { 28 | "request": { 29 | "method": "GET", 30 | "urlPath": "/user", 31 | "queryParameters" : { 32 | "pretty" : { 33 | "equalTo" : "true" 34 | } 35 | } 36 | }, 37 | "response": { 38 | "status": 200, 39 | "headers": { 40 | "Content-Type": "application/json" 41 | }, 42 | "bodyFileName": "user.json" 43 | } 44 | } 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /samples/random/stubs/mappings/users.json: -------------------------------------------------------------------------------- 1 | { 2 | "request": { 3 | "method": "GET", 4 | "url": "/users" 5 | }, 6 | "response": { 7 | "status": 200, 8 | "headers": { 9 | "Content-Type": "text/csv" 10 | }, 11 | "bodyFileName": "users.csv.template" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/integration-tests/README.md: -------------------------------------------------------------------------------- 1 | # WireMock Docker - Integration tests 2 | 3 | Runs tests for the WireMock Docker image and validates its behavior for key cases. 4 | It also tests the demos in this repository. 5 | The integration tests are executed as a part of the CI run on GitHub Actions. 6 | 7 | Powered by the [WireMock Module](https://github.com/wiremock/wiremock-testcontainers-java) for Testcontainers Java. 8 | 9 | ## Configuration 10 | 11 | The test can be configured via system properties: 12 | 13 | - `it.wiremock-image` - Image to be used instead of the default one 14 | - `it.samples-path` - Relative or absolute path to the sample/example files 15 | -------------------------------------------------------------------------------- /test/integration-tests/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | org.wiremock.docker 6 | integration-tests 7 | Integration Tests for WireMock Docker 8 | 1.0-SNAPSHOT 9 | 10 | 11 | 12 | Apache License Version 2.0 13 | https://www.apache.org/licenses/LICENSE-2.0 14 | repo 15 | 16 | 17 | 18 | 19 | 11 20 | ${java.version} 21 | ${java.version} 22 | 1.0-alpha-13 23 | 1.18.3 24 | 5.9.3 25 | 2.0.7 26 | 3.24.2 27 | 4.2.0 28 | github 29 | 30 | 31 | 32 | 33 | 34 | org.testcontainers 35 | testcontainers-bom 36 | ${testcontainers.version} 37 | pom 38 | import 39 | 40 | 41 | org.junit 42 | junit-bom 43 | ${junit.version} 44 | pom 45 | import 46 | 47 | 48 | org.assertj 49 | assertj-bom 50 | ${assertj.version} 51 | pom 52 | import 53 | 54 | 55 | 56 | org.slf4j 57 | slf4j-api 58 | ${slf4j.version} 59 | 60 | 61 | 62 | 63 | 64 | 65 | org.testcontainers 66 | testcontainers 67 | test 68 | 69 | 70 | org.wiremock.integrations.testcontainers 71 | wiremock-testcontainers-module 72 | ${wiremock-testcontainers.version} 73 | test 74 | 75 | 76 | org.testcontainers 77 | junit-jupiter 78 | test 79 | 80 | 81 | org.junit.jupiter 82 | junit-jupiter-engine 83 | test 84 | 85 | 86 | org.junit.jupiter 87 | junit-jupiter-params 88 | test 89 | 90 | 91 | org.junit.vintage 92 | junit-vintage-engine 93 | test 94 | 95 | 96 | org.assertj 97 | assertj-core 98 | test 99 | 100 | 101 | org.awaitility 102 | awaitility 103 | ${awaitility.version} 104 | test 105 | 106 | 107 | ch.qos.logback 108 | logback-classic 109 | 1.4.12 110 | test 111 | 112 | 113 | 114 | 115 | 116 | 117 | org.apache.maven.plugins 118 | maven-compiler-plugin 119 | 3.11.0 120 | 121 | 122 | org.apache.maven.plugins 123 | maven-surefire-plugin 124 | 3.1.2 125 | 126 | 127 | 128 | 129 | org.apache.maven.plugins 130 | maven-dependency-plugin 131 | 3.6.0 132 | 133 | 134 | copy 135 | compile 136 | 137 | copy 138 | 139 | 140 | 141 | 142 | org.wiremock 143 | wiremock-webhooks-extension 144 | 2.35.1 145 | 146 | 147 | ${project.build.directory}/test-wiremock-extension 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | scm:git:git://github.com/wiremock/wiremock-docker.git 157 | scm:git:https://github.com/wiremock/wiremock-docker.git 158 | https://github.com/wiremock/wiremock-docker 159 | ${scmTag} 160 | 161 | 162 | -------------------------------------------------------------------------------- /test/integration-tests/src/main/java/org/wiremock/docker/it/Stub.java: -------------------------------------------------------------------------------- 1 | package org.wiremock.docker.it; 2 | 3 | public class Stub { 4 | 5 | // No-op 6 | } 7 | -------------------------------------------------------------------------------- /test/integration-tests/src/test/java/org/wiremock/docker/it/HealthTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2024 WireMock Inc, Rafe Arnold and all project contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.wiremock.docker.it; 17 | 18 | import org.junit.jupiter.api.Test; 19 | import org.testcontainers.containers.wait.strategy.Wait; 20 | import org.wiremock.integrations.testcontainers.WireMockContainer; 21 | 22 | import java.net.URI; 23 | import java.net.http.HttpClient; 24 | import java.net.http.HttpRequest; 25 | import java.net.http.HttpResponse; 26 | import java.time.Duration; 27 | 28 | import static org.assertj.core.api.Assertions.assertThat; 29 | 30 | class HealthTest { 31 | 32 | @Test 33 | public void containerCanWaitForDockerHealthcheck() throws Exception { 34 | try (WireMockContainer wiremockServer = 35 | new WireMockContainer(TestConfig.WIREMOCK_IMAGE).waitingFor(Wait.forHealthcheck())) { 36 | wiremockServer.start(); 37 | final HttpClient client = HttpClient.newHttpClient(); 38 | final HttpRequest request = HttpRequest.newBuilder() 39 | .uri(new URI(wiremockServer.getUrl("/__admin/health"))) 40 | .timeout(Duration.ofSeconds(1)) 41 | .GET() 42 | .build(); 43 | 44 | HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); 45 | 46 | assertThat(response.statusCode()).isEqualTo(200); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /test/integration-tests/src/test/java/org/wiremock/docker/it/SmokeTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 WireMock Inc, Oleg Nenashev and all project contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.wiremock.docker.it; 17 | 18 | import org.junit.jupiter.api.Test; 19 | import org.testcontainers.junit.jupiter.Container; 20 | import org.testcontainers.junit.jupiter.Testcontainers; 21 | 22 | import java.net.URI; 23 | import java.net.http.HttpClient; 24 | import java.net.http.HttpRequest; 25 | import java.net.http.HttpResponse; 26 | import java.time.Duration; 27 | 28 | import org.wiremock.integrations.testcontainers.WireMockContainer; 29 | 30 | import static org.assertj.core.api.Assertions.assertThat; 31 | 32 | @Testcontainers(parallel = true) 33 | class SmokeTest { 34 | 35 | @Container 36 | public WireMockContainer wiremockServer = new WireMockContainer(TestConfig.WIREMOCK_IMAGE) 37 | .withMapping("hello", SmokeTest.class, "hello-world.json") 38 | .withMapping("hello-resource", SmokeTest.class, "hello-world-resource.json") 39 | .withFileFromResource("hello-world-resource-response.xml", SmokeTest.class, 40 | "hello-world-resource-response.xml"); 41 | 42 | @Test 43 | public void helloWorld() throws Exception { 44 | final HttpClient client = HttpClient.newBuilder().build(); 45 | final HttpRequest request = HttpRequest.newBuilder() 46 | .uri(new URI(wiremockServer.getUrl("hello"))) 47 | .timeout(Duration.ofSeconds(10)) 48 | .header("Content-Type", "application/json") 49 | .GET().build(); 50 | 51 | HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); 52 | 53 | assertThat(response.body()) 54 | .as("Wrong response body") 55 | .contains("Hello, world!"); 56 | } 57 | 58 | @Test 59 | public void helloWorldFromFile() throws Exception { 60 | final HttpClient client = HttpClient.newBuilder() 61 | .version(HttpClient.Version.HTTP_1_1) 62 | .build(); 63 | 64 | HttpRequest request = HttpRequest.newBuilder() 65 | .uri(new URI(wiremockServer.getUrl("hello-from-file"))) 66 | .timeout(Duration.ofSeconds(10)) 67 | .header("Content-Type", "application/json") 68 | .GET() 69 | .build(); 70 | 71 | HttpResponse response = 72 | client.send(request, HttpResponse.BodyHandlers.ofString()); 73 | 74 | assertThat(response.body()) 75 | .as("Wrong response body") 76 | .contains("Hello, world!"); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /test/integration-tests/src/test/java/org/wiremock/docker/it/TestConfig.java: -------------------------------------------------------------------------------- 1 | package org.wiremock.docker.it; 2 | 3 | import java.io.File; 4 | import java.nio.file.Path; 5 | 6 | /** 7 | * WireMock Test configuration. 8 | * To be set by the test runner to configure proper execution. 9 | */ 10 | public class TestConfig { 11 | 12 | /** 13 | * Docker image tag to be used for testing. 14 | */ 15 | public static String WIREMOCK_IMAGE = 16 | System.getProperty("it.wiremock-image", "wiremock/wiremock:test"); 17 | 18 | public static String SAMPLES_DIR = 19 | System.getProperty("it.samples-path", "../../samples"); 20 | 21 | public static boolean isWebkooksExtensionEmbedded() { 22 | // TODO Fixme 23 | return true; 24 | } 25 | 26 | public static Path getSamplesPath() { 27 | return new File(SAMPLES_DIR).toPath(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test/integration-tests/src/test/java/org/wiremock/docker/it/WireMockOptionsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 WireMock Inc, Oleg Nenashev and all project contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.wiremock.docker.it; 17 | 18 | import org.junit.jupiter.api.Test; 19 | import org.testcontainers.junit.jupiter.Container; 20 | import org.testcontainers.junit.jupiter.Testcontainers; 21 | 22 | import org.wiremock.integrations.testcontainers.WireMockContainer; 23 | import static org.junit.jupiter.api.Assertions.assertTrue; 24 | 25 | @Testcontainers 26 | class WireMockOptionsTest { 27 | 28 | @Container 29 | public WireMockContainer wiremockServer = new WireMockContainer(TestConfig.WIREMOCK_IMAGE) 30 | .withEnv("WIREMOCK_OPTIONS", "--verbose"); 31 | 32 | @Test 33 | public void checkVerboseEnablingLogLine() { 34 | assertTrue(wiremockServer.getLogs().contains("Verbose logging enabled")); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /test/integration-tests/src/test/java/org/wiremock/docker/it/extensions/WireMockContainerExtensionsWebhookTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 WireMock Inc, Oleg Nenashev and all project contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.wiremock.docker.it.extensions; 17 | 18 | import org.junit.Before; 19 | import org.junit.jupiter.api.Test; 20 | import org.slf4j.Logger; 21 | import org.slf4j.LoggerFactory; 22 | import org.testcontainers.containers.GenericContainer; 23 | import org.testcontainers.containers.output.Slf4jLogConsumer; 24 | import org.testcontainers.junit.jupiter.Container; 25 | import org.testcontainers.junit.jupiter.Testcontainers; 26 | import org.wiremock.docker.it.TestConfig; 27 | import org.wiremock.docker.it.util.HttpResponse; 28 | import org.wiremock.docker.it.util.TestHttpClient; 29 | import org.wiremock.docker.it.util.TestHttpServer; 30 | import org.wiremock.integrations.testcontainers.WireMockContainer; 31 | 32 | import static org.assertj.core.api.Assertions.assertThat; 33 | import static org.testcontainers.Testcontainers.exposeHostPorts; 34 | import static org.testcontainers.shaded.org.awaitility.Awaitility.await; 35 | 36 | import java.io.IOException; 37 | import java.nio.file.Paths; 38 | import java.time.Duration; 39 | import java.util.Collections; 40 | 41 | import static org.testcontainers.shaded.org.awaitility.Awaitility.await; 42 | 43 | /** 44 | * Tests the WireMock Webhook extension and TestContainers Networking 45 | * For this type of tests we should use following steps: 46 | *

47 | * Use {@link GenericContainer#withAccessToHost(boolean)} to force the host access mechanism 48 | *

49 | * Use {@link org.testcontainers.Testcontainers#exposeHostPorts(int...)} to expose host machine ports to containers 50 | *

51 | * Use {@link GenericContainer#INTERNAL_HOST_HOSTNAME} to calculate hostname for callback 52 | * 53 | * @see Testcontainers Networking 54 | */ 55 | @Testcontainers 56 | class WireMockContainerExtensionsWebhookTest { 57 | 58 | private static final Logger LOGGER = LoggerFactory.getLogger(WireMockContainerExtensionsWebhookTest.class); 59 | private static final String WIREMOCK_PATH = "/wiremock/callback-trigger"; 60 | private static final String APPLICATION_PATH = "/application/callback-receiver"; 61 | 62 | TestHttpServer applicationServer = TestHttpServer.newInstance(); 63 | Slf4jLogConsumer logConsumer = new Slf4jLogConsumer(LOGGER); 64 | 65 | @Container 66 | WireMockContainer wiremockServer = new WireMockContainer(TestConfig.WIREMOCK_IMAGE) 67 | .withLogConsumer(new Slf4jLogConsumer(LOGGER)) 68 | .withCliArg("--global-response-templating") 69 | .withMapping("webhook-callback-template", WireMockContainerExtensionsWebhookTest.class, 70 | "webhook-callback-template.json") 71 | // No longer needed and leads to crash on 3.3.1 72 | // .withExtension("org.wiremock.webhooks.Webhooks") 73 | .withAccessToHost(true); // Force the host access mechanism 74 | 75 | @Before 76 | public void setupLogging() { 77 | wiremockServer.followOutput(logConsumer); 78 | } 79 | 80 | @Test 81 | void callbackUsingJsonStub() throws Exception { 82 | // given 83 | exposeHostPorts(applicationServer.getPort()); // Exposing host ports to the container 84 | 85 | String wiremockUrl = wiremockServer.getUrl(WIREMOCK_PATH); 86 | String applicationCallbackUrl = String.format("http://%s:%d%s", GenericContainer.INTERNAL_HOST_HOSTNAME, applicationServer.getPort(), APPLICATION_PATH); 87 | 88 | // when 89 | HttpResponse response = new TestHttpClient().post( 90 | wiremockUrl, 91 | "{\"callbackMethod\": \"PUT\", \"callbackUrl\": \"" + applicationCallbackUrl + "\"}" 92 | ); 93 | 94 | // then 95 | assertThat(response).as("Wiremock Response").isNotNull().satisfies(it -> { 96 | assertThat(it.getStatusCode()).as("Wiremock Response Status").isEqualTo(200); 97 | assertThat(it.getBody()).as("Wiremock Response Body") 98 | .contains("Please wait callback") 99 | .contains("PUT") 100 | .contains(applicationCallbackUrl); 101 | }); 102 | 103 | await().atMost(Duration.ofMillis(5000)).untilAsserted(() -> { 104 | assertThat(applicationServer.getRecordedRequests()).as("Received Callback") 105 | .hasSize(1) 106 | .first().usingRecursiveComparison() 107 | .isEqualTo(new TestHttpServer.RecordedRequest("PUT", APPLICATION_PATH, "Async processing Finished")); 108 | }); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /test/integration-tests/src/test/java/org/wiremock/docker/it/samples/AbtsractSampleTest.java: -------------------------------------------------------------------------------- 1 | package org.wiremock.docker.it.samples; 2 | 3 | import org.testcontainers.junit.jupiter.Container; 4 | import org.testcontainers.utility.MountableFile; 5 | import org.wiremock.docker.it.TestConfig; 6 | import org.wiremock.integrations.testcontainers.WireMockContainer; 7 | 8 | import java.io.File; 9 | import java.io.FileNotFoundException; 10 | import java.io.IOException; 11 | import java.nio.file.FileVisitOption; 12 | import java.nio.file.Files; 13 | import java.nio.file.Path; 14 | 15 | public abstract class AbtsractSampleTest { 16 | 17 | @Container 18 | public WireMockContainer wiremockServer = createWireMockContainer(); 19 | 20 | private static final String MAPPINGS_DIR = "/home/wiremock/mappings/"; 21 | private static final String FILES_DIR = "/home/wiremock/__files/"; 22 | 23 | public WireMockContainer createWireMockContainer() { 24 | return createWireMockContainer(false); 25 | } 26 | 27 | //TODO: Simplify API once WireMock container is amended 28 | public WireMockContainer createWireMockContainer(boolean useHttps) { 29 | final WireMockContainer wiremockServer = useHttps 30 | ? new WireMockHttpsContainer(TestConfig.WIREMOCK_IMAGE) 31 | : new WireMockContainer(TestConfig.WIREMOCK_IMAGE); 32 | 33 | // TODO: Move to the WireMock Module 34 | try { 35 | forMappingsDir(wiremockServer, getMappingsDir()); 36 | forFilesDir(wiremockServer, getFilesDir()); 37 | } catch (IOException ex) { 38 | throw new AssertionError("Failed to read the home directory", ex); 39 | } 40 | return wiremockServer; 41 | } 42 | 43 | public void forMappingsDir(WireMockContainer container, Path mappingsDir) throws IOException { 44 | final Path targetMappingDir = new File(MAPPINGS_DIR).toPath(); 45 | 46 | if (Files.exists(mappingsDir) && Files.isDirectory(mappingsDir)) { 47 | Files.walk(mappingsDir, FileVisitOption.FOLLOW_LINKS).forEach(path -> { 48 | if (!Files.isRegularFile(path)) { 49 | return; 50 | } 51 | container.withCopyToContainer(MountableFile.forHostPath(path), 52 | targetMappingDir.resolve(mappingsDir.relativize(path)).toString()); 53 | }); 54 | } else { 55 | throw new FileNotFoundException("Mappings directory does not exist: " + mappingsDir); 56 | } 57 | } 58 | 59 | public void forFilesDir(WireMockContainer container, Path filesDir) throws IOException { 60 | final Path targetFilesDir = new File(FILES_DIR).toPath(); 61 | if (Files.exists(filesDir) && Files.isDirectory(filesDir)) { 62 | Files.walk(filesDir, FileVisitOption.FOLLOW_LINKS).forEach(path -> { 63 | if (Files.isRegularFile(path)) { 64 | container.withCopyToContainer(MountableFile.forHostPath(path), 65 | targetFilesDir.resolve(filesDir.relativize(path)).toString()); 66 | } 67 | }); 68 | } else { 69 | throw new FileNotFoundException("Files directory does not exist: " + filesDir); 70 | } 71 | } 72 | 73 | public abstract Path getHomeDir(); 74 | 75 | public Path getMappingsDir() { 76 | return getHomeDir().resolve("stubs/mappings"); 77 | } 78 | 79 | public Path getFilesDir() { 80 | return getHomeDir().resolve("stubs/__files"); 81 | } 82 | 83 | public static class WireMockHttpsContainer extends WireMockContainer { 84 | 85 | public WireMockHttpsContainer(String tag) { 86 | super(tag); 87 | } 88 | 89 | @Override 90 | protected void configure() { 91 | super.configure(); 92 | withExposedPorts(8080, 8443); 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /test/integration-tests/src/test/java/org/wiremock/docker/it/samples/HelloSampleHttpsTest.java: -------------------------------------------------------------------------------- 1 | package org.wiremock.docker.it.samples; 2 | 3 | import org.junit.jupiter.api.Disabled; 4 | import org.junit.jupiter.api.Test; 5 | import org.testcontainers.junit.jupiter.Testcontainers; 6 | import org.wiremock.docker.it.TestConfig; 7 | import org.wiremock.integrations.testcontainers.WireMockContainer; 8 | 9 | import java.net.URI; 10 | import java.net.http.HttpClient; 11 | import java.net.http.HttpRequest; 12 | import java.net.http.HttpResponse; 13 | import java.nio.file.Path; 14 | import java.time.Duration; 15 | 16 | import static org.assertj.core.api.Assertions.assertThat; 17 | 18 | /** 19 | * Verifies samples in the repository root and mimics the old smoke tests. 20 | * In the future it can be extended for bigger acceptance tests 21 | */ 22 | @Testcontainers 23 | public class HelloSampleHttpsTest extends AbtsractSampleTest { 24 | 25 | @Override 26 | public Path getHomeDir() { 27 | return TestConfig.getSamplesPath().resolve("hello"); 28 | } 29 | 30 | @Override 31 | public WireMockContainer createWireMockContainer() { 32 | return createWireMockContainer(true) 33 | .withCliArg("--https-port") 34 | .withCliArg("8443"); 35 | } 36 | 37 | @Test 38 | @Disabled("Needs a valid certificate. Otherwise, can run only with -Djdk.internal.httpclient.disableHostnameVerification=true") 39 | public void helloWorldHttps() throws Exception { 40 | final HttpClient client = HttpClient.newBuilder().build(); 41 | final String url = String.format("https://%s:%d/hello", 42 | wiremockServer.getHost(), 43 | wiremockServer.getMappedPort(8443)); 44 | 45 | final HttpRequest request = HttpRequest.newBuilder() 46 | .uri(new URI(url)) 47 | .timeout(Duration.ofSeconds(10)) 48 | .header("Content-Type", "application/json") 49 | .GET().build(); 50 | 51 | HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); 52 | 53 | assertThat(response.body()) 54 | .as("Wrong response body") 55 | .contains("Hello World !"); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /test/integration-tests/src/test/java/org/wiremock/docker/it/samples/HelloSampleTest.java: -------------------------------------------------------------------------------- 1 | package org.wiremock.docker.it.samples; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.testcontainers.junit.jupiter.Testcontainers; 5 | import org.wiremock.docker.it.TestConfig; 6 | 7 | import java.net.URI; 8 | import java.net.http.HttpClient; 9 | import java.net.http.HttpRequest; 10 | import java.net.http.HttpResponse; 11 | import java.nio.file.Path; 12 | import java.time.Duration; 13 | 14 | import static org.assertj.core.api.Assertions.assertThat; 15 | 16 | /** 17 | * Verifies samples in the repository root and mimics the old smoke tests. 18 | * In the future it can be extended for bigger acceptance tests 19 | */ 20 | @Testcontainers 21 | public class HelloSampleTest extends AbtsractSampleTest { 22 | 23 | @Override 24 | public Path getHomeDir() { 25 | return TestConfig.getSamplesPath().resolve("hello"); 26 | } 27 | 28 | @Test 29 | public void helloWorld() throws Exception { 30 | final HttpClient client = HttpClient.newBuilder().build(); 31 | final HttpRequest request = HttpRequest.newBuilder() 32 | .uri(new URI(wiremockServer.getUrl("hello"))) 33 | .timeout(Duration.ofSeconds(10)) 34 | .header("Content-Type", "application/json") 35 | .GET().build(); 36 | 37 | HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); 38 | 39 | assertThat(response.body()) 40 | .as("Wrong response body") 41 | .contains("Hello World !"); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /test/integration-tests/src/test/java/org/wiremock/docker/it/samples/RandomSampleTest.java: -------------------------------------------------------------------------------- 1 | package org.wiremock.docker.it.samples; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.testcontainers.junit.jupiter.Testcontainers; 5 | import org.wiremock.docker.it.TestConfig; 6 | import org.wiremock.integrations.testcontainers.WireMockContainer; 7 | 8 | import java.io.File; 9 | import java.net.URI; 10 | import java.net.http.HttpClient; 11 | import java.net.http.HttpRequest; 12 | import java.net.http.HttpResponse; 13 | import java.nio.file.Path; 14 | import java.time.Duration; 15 | import java.util.Collections; 16 | 17 | import static org.assertj.core.api.Assertions.assertThat; 18 | 19 | @Testcontainers 20 | public class RandomSampleTest extends AbtsractSampleTest { 21 | 22 | @Override 23 | public Path getHomeDir() { 24 | return TestConfig.getSamplesPath().resolve("random"); 25 | } 26 | 27 | @Test 28 | public void testRandom() throws Exception { 29 | final HttpClient client = HttpClient.newBuilder().build(); 30 | final HttpRequest request = HttpRequest.newBuilder() 31 | .uri(new URI(wiremockServer.getUrl("user"))) 32 | .timeout(Duration.ofSeconds(10)) 33 | .header("Content-Type", "application/json") 34 | .GET().build(); 35 | 36 | HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); 37 | 38 | assertThat(response.body()) 39 | .as("Wrong response body") 40 | .contains("surname"); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /test/integration-tests/src/test/java/org/wiremock/docker/it/util/HttpResponse.java: -------------------------------------------------------------------------------- 1 | package org.wiremock.docker.it.util; 2 | 3 | public class HttpResponse { 4 | 5 | String body; 6 | int statusCode; 7 | public HttpResponse(String body, int statusCode) { 8 | this.body = body; 9 | this.statusCode = statusCode; 10 | } 11 | 12 | public String getBody() { 13 | return body; 14 | } 15 | 16 | public int getStatusCode() { 17 | return statusCode; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/integration-tests/src/test/java/org/wiremock/docker/it/util/TestHttpClient.java: -------------------------------------------------------------------------------- 1 | package org.wiremock.docker.it.util; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.io.InputStreamReader; 7 | import java.io.OutputStream; 8 | import java.net.HttpURLConnection; 9 | import java.net.URL; 10 | import java.nio.charset.StandardCharsets; 11 | 12 | public final class TestHttpClient { 13 | 14 | public HttpResponse send(HttpURLConnection connection) throws IOException { 15 | InputStream inputStream = connection.getInputStream(); 16 | 17 | BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); 18 | StringBuilder response = new StringBuilder(); 19 | 20 | String line; 21 | while ((line = reader.readLine()) != null) { 22 | response.append(line); 23 | } 24 | reader.close(); 25 | 26 | 27 | 28 | return new HttpResponse(response.toString(), connection.getResponseCode()); 29 | } 30 | 31 | public HttpResponse get(String uri) throws IOException { 32 | URL url = new URL(uri); 33 | HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 34 | connection.setRequestMethod("GET"); 35 | 36 | return send(connection); 37 | } 38 | 39 | 40 | public HttpResponse post(String uri, String body) throws IOException { 41 | URL url = new URL(uri); 42 | HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 43 | connection.setRequestMethod("POST"); 44 | connection.setRequestProperty("Content-Type", "application/json"); 45 | connection.setRequestProperty("Accept", "application/json"); 46 | connection.setDoOutput(true); 47 | connection.setConnectTimeout(10000); 48 | 49 | try (OutputStream outputStream = connection.getOutputStream()) { 50 | byte[] input = body.getBytes(StandardCharsets.UTF_8); 51 | outputStream.write(input, 0, input.length); 52 | } 53 | 54 | return send(connection); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /test/integration-tests/src/test/java/org/wiremock/docker/it/util/TestHttpServer.java: -------------------------------------------------------------------------------- 1 | package org.wiremock.docker.it.util; 2 | 3 | import com.sun.net.httpserver.HttpExchange; 4 | import com.sun.net.httpserver.HttpHandler; 5 | import com.sun.net.httpserver.HttpServer; 6 | 7 | import java.io.IOException; 8 | import java.io.InputStream; 9 | import java.net.InetSocketAddress; 10 | import java.nio.charset.StandardCharsets; 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | public class TestHttpServer { 15 | private final HttpServer server; 16 | private final AllRequestsRecorder handler; 17 | 18 | public static TestHttpServer newInstance() { 19 | try { 20 | return new TestHttpServer(0); 21 | } catch (IOException e) { 22 | throw new RuntimeException("Failed to start Test Http Server", e); 23 | } 24 | } 25 | 26 | private TestHttpServer(int port) throws IOException { 27 | // handlers 28 | handler = new AllRequestsRecorder(); 29 | // server 30 | server = HttpServer.create(new InetSocketAddress(port), 0); 31 | server.createContext("/", handler); 32 | server.start(); 33 | } 34 | 35 | public int getPort() { 36 | return server.getAddress().getPort(); 37 | } 38 | 39 | public List getRecordedRequests() { 40 | return handler.getRecordedRequests(); 41 | } 42 | 43 | 44 | private static final class AllRequestsRecorder implements HttpHandler { 45 | 46 | private final List recordedRequests = new ArrayList<>(); 47 | 48 | @Override 49 | public void handle(HttpExchange exchange) throws IOException { 50 | String method = exchange.getRequestMethod(); 51 | String path = exchange.getRequestURI().getPath(); 52 | String body = null; 53 | 54 | InputStream requestBody = exchange.getRequestBody(); 55 | if (requestBody.available() > 0) { 56 | byte[] requestBodyBytes = new byte[requestBody.available()]; 57 | requestBody.read(requestBodyBytes); 58 | body = new String(requestBodyBytes, StandardCharsets.UTF_8); 59 | } 60 | 61 | recordedRequests.add(new RecordedRequest(method, path, body)); 62 | 63 | exchange.sendResponseHeaders(200, 0); 64 | exchange.getResponseBody().close(); 65 | } 66 | 67 | public List getRecordedRequests() { 68 | return recordedRequests; 69 | } 70 | } 71 | 72 | public static final class RecordedRequest { 73 | private final String method; 74 | private final String path; 75 | private final String body; 76 | 77 | public RecordedRequest(String method, String path, String body) { 78 | this.method = method; 79 | this.path = path; 80 | this.body = body; 81 | } 82 | 83 | public String getMethod() { 84 | return method; 85 | } 86 | 87 | public String getPath() { 88 | return path; 89 | } 90 | 91 | public String getBody() { 92 | return body; 93 | } 94 | 95 | @Override 96 | public String toString() { 97 | return "RecordedRequest{" + 98 | "method='" + method + '\'' + 99 | ", path='" + path + '\'' + 100 | ", body='" + body + '\'' + 101 | '}'; 102 | } 103 | 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /test/integration-tests/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | INFO 5 | 6 | 7 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /test/integration-tests/src/test/resources/org/wiremock/docker/it/SmokeTest/hello-world-resource-response.xml: -------------------------------------------------------------------------------- 1 | 2 | you 3 | WireMock 4 | Response 5 | Hello, world! 6 | 7 | -------------------------------------------------------------------------------- /test/integration-tests/src/test/resources/org/wiremock/docker/it/SmokeTest/hello-world-resource.json: -------------------------------------------------------------------------------- 1 | { 2 | "request": { 3 | "method": "GET", 4 | "url": "/hello-from-file" 5 | }, 6 | "response": { 7 | "status": 200, 8 | "bodyFileName": "hello-world-resource-response.xml" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/integration-tests/src/test/resources/org/wiremock/docker/it/SmokeTest/hello-world.json: -------------------------------------------------------------------------------- 1 | { 2 | "request": { 3 | "method": "GET", 4 | "url": "/hello" 5 | }, 6 | 7 | "response": { 8 | "status": 200, 9 | "body": "Hello, world!" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/integration-tests/src/test/resources/org/wiremock/docker/it/extensions/WireMockContainerExtensionsWebhookTest/webhook-callback-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "request": { 3 | "method": "POST", 4 | "urlPath": "/wiremock/callback-trigger" 5 | }, 6 | "response": { 7 | "status": 200, 8 | "headers": { 9 | "Content-Type": "application/json" 10 | }, 11 | "jsonBody": { 12 | "message": "Please wait callback", 13 | "method": "{{jsonPath request.body '$.callbackMethod'}}", 14 | "url": "{{jsonPath request.body '$.callbackUrl'}}" 15 | } 16 | }, 17 | "postServeActions": [ 18 | { 19 | "name": "webhook", 20 | "parameters": { 21 | "method": "{{jsonPath originalRequest.body '$.callbackMethod'}}", 22 | "url": "{{jsonPath originalRequest.body '$.callbackUrl'}}", 23 | "body": "Async processing Finished", 24 | "delay": { 25 | "type": "fixed", 26 | "milliseconds": 1000 27 | } 28 | } 29 | } 30 | ] 31 | } --------------------------------------------------------------------------------