From 96a7ffa36261a72018b055ce3b6fc08e6c5a99b5 Mon Sep 17 00:00:00 2001 From: ascopes <73482956+ascopes@users.noreply.github.com> Date: Sun, 4 Feb 2024 10:16:57 +0000 Subject: [PATCH] GH-26: Add tests for $PATH resolution of protoc --- .github/workflows/build.yml | 18 +++- .github/workflows/deploy.yml | 4 + .../invoker.properties | 1 + src/it/test-java-main-system-protoc/pom.xml | 91 +++++++++++++++++++ .../src/main/protobuf/helloworld.proto | 27 ++++++ .../org/example/helloworld/ProtobufTest.java | 60 ++++++++++++ .../test-java-main-system-protoc/test.groovy | 41 +++++++++ 7 files changed, 239 insertions(+), 3 deletions(-) create mode 100644 src/it/test-java-main-system-protoc/invoker.properties create mode 100644 src/it/test-java-main-system-protoc/pom.xml create mode 100644 src/it/test-java-main-system-protoc/src/main/protobuf/helloworld.proto create mode 100644 src/it/test-java-main-system-protoc/src/test/java/org/example/helloworld/ProtobufTest.java create mode 100644 src/it/test-java-main-system-protoc/test.groovy diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 451743f3..35c872d1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,9 +20,21 @@ jobs: java-version: [11, 21] steps: - - name: Checkout + - name: Checkout code uses: actions/checkout@v4 + # Install protoc onto the PATH so that we can test PATH resolution. + - name: Install protoc + shell: bash + run: |- + case "${{ matrix.os-name }}" in + macos-*) brew install protobuf ;; + ubuntu-*) sudo apt update -q && sudo apt install protobuf-compiler -qy ;; + windows-*) choco install protoc ;; + esac + + protoc --version + - name: Set up JDK ${{ matrix.java-version }} uses: actions/setup-java@v4 with: @@ -30,11 +42,11 @@ jobs: distribution: 'temurin' cache: maven - - name: Build with Maven + - name: Build and test shell: bash run: ./mvnw -B verify - - name: Publish to codecov + - name: Publish code coverage uses: codecov/codecov-action@v3 continue-on-error: true if: always() diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index a910562f..e4cf1c19 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -50,6 +50,10 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Install protoc + shell: bash + run: sudo apt update -q && sudo apt install protocol-buffers -qy + - name: Set up JDK uses: actions/setup-java@v4 with: diff --git a/src/it/test-java-main-system-protoc/invoker.properties b/src/it/test-java-main-system-protoc/invoker.properties new file mode 100644 index 00000000..3d041b81 --- /dev/null +++ b/src/it/test-java-main-system-protoc/invoker.properties @@ -0,0 +1 @@ +invoker.goals = clean package diff --git a/src/it/test-java-main-system-protoc/pom.xml b/src/it/test-java-main-system-protoc/pom.xml new file mode 100644 index 00000000..007f1994 --- /dev/null +++ b/src/it/test-java-main-system-protoc/pom.xml @@ -0,0 +1,91 @@ + + + + 4.0.0 + + org.example + example + 0.0.1-SNAPSHOT + + + 5.10.2 + 3.25.1 + + 3.11.0 + 3.2.2 + + UTF-8 + + + + + com.google.protobuf + protobuf-java + ${protobuf.version} + compile + + + + org.junit.jupiter + junit-jupiter + ${junit.version} + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + + 11 + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + + ${plugin-group-id} + ${plugin-artifact-id} + ${plugin-version} + + + PATH + + + + + + generate + + + + + + + diff --git a/src/it/test-java-main-system-protoc/src/main/protobuf/helloworld.proto b/src/it/test-java-main-system-protoc/src/main/protobuf/helloworld.proto new file mode 100644 index 00000000..8d91946c --- /dev/null +++ b/src/it/test-java-main-system-protoc/src/main/protobuf/helloworld.proto @@ -0,0 +1,27 @@ +// +// Copyright (C) 2023 - 2024, Ashley Scopes. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +syntax = "proto3"; + +option java_multiple_files = true; +option java_package = "org.example.helloworld"; + +package org.example.helloworld; + +message GreetingRequest { + string name = 1; +} + diff --git a/src/it/test-java-main-system-protoc/src/test/java/org/example/helloworld/ProtobufTest.java b/src/it/test-java-main-system-protoc/src/test/java/org/example/helloworld/ProtobufTest.java new file mode 100644 index 00000000..bc512d84 --- /dev/null +++ b/src/it/test-java-main-system-protoc/src/test/java/org/example/helloworld/ProtobufTest.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2023 - 2024, Ashley Scopes. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.example.helloworld; + +import java.io.ByteArrayOutputStream; +import java.util.ArrayList; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class ProtobufTest { + @Test + void generatedProtobufSourcesAreFullMessages() throws Throwable { + // When + var superClasses = new ArrayList(); + Class superClass = GreetingRequest.class; + + do { + superClasses.add(superClass.getName()); + superClass = superClass.getSuperclass(); + } while (superClass != null); + + // Then + assertTrue(superClasses.contains("com.google.protobuf.GeneratedMessageV3")); + } + + @Test + void generatedProtobufSourcesAreValid() throws Throwable { + // Given + var expectedGreetingRequest = GreetingRequest + .newBuilder() + .setName("Ashley") + .build(); + + // When + var baos = new ByteArrayOutputStream(); + expectedGreetingRequest.writeTo(baos); + var actualGreetingRequest = GreetingRequest.parseFrom(baos.toByteArray()); + + assertNotEquals(0, baos.toByteArray().length); + + // Then + assertEquals(expectedGreetingRequest.getName(), actualGreetingRequest.getName()); + } +} diff --git a/src/it/test-java-main-system-protoc/test.groovy b/src/it/test-java-main-system-protoc/test.groovy new file mode 100644 index 00000000..201af757 --- /dev/null +++ b/src/it/test-java-main-system-protoc/test.groovy @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2023 - 2024, Ashley Scopes. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import java.nio.file.Path + +import static org.assertj.core.api.Assertions.assertThat + +Path baseDirectory = basedir.toPath().toAbsolutePath() +def generatedSourcesDir = baseDirectory.resolve("target/generated-sources/protobuf") +def classesDir = baseDirectory.resolve("target/classes") +def expectedGeneratedFiles = [ + "org/example/helloworld/Helloworld", + "org/example/helloworld/GreetingRequest", + "org/example/helloworld/GreetingRequestOrBuilder", +] + +assertThat(generatedSourcesDir).isDirectory() + +assertThat(classesDir).isDirectory() + +expectedGeneratedFiles.forEach { + assertThat(generatedSourcesDir.resolve("${it}.java")) + .exists() + .isNotEmptyFile() + assertThat(classesDir.resolve("${it}.class")) + .exists() + .isNotEmptyFile() + +}