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()
+
+}