Skip to content

Commit

Permalink
feat: download protobuf sources to compile conformance runner
Browse files Browse the repository at this point in the history
  • Loading branch information
ahamez committed Dec 31, 2024
1 parent 0599cc7 commit 5c0f94c
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 231 deletions.
42 changes: 15 additions & 27 deletions .github/workflows/elixir.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
name: Elixir CI

env:
PROTOBUF_VERSION: "21.4"
PROTOBUF_LIB_VERSION_MAJOR: "32"
PROTOBUF_LIB_VERSION_MINOR: "0.4"
PROTOX_PROTOBUF_VERSION: "v29.2"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
MIX_ENV: test

Expand Down Expand Up @@ -64,27 +62,8 @@ jobs:
uses: actions/cache@v4
id: compile-conformance-test-runner
with:
path: conformance-bin
key: ${{ runner.os }}-protobuf-${{ env.PROTOBUF_VERSION }}

- name: Compile conformance-test-runner
if: steps.compile-conformance-test-runner.outputs.cache-hit != 'true'
run: |
mkdir -p ./conformance-bin/.libs
wget https://github.com/protocolbuffers/protobuf/archive/v${{ env.PROTOBUF_VERSION }}.tar.gz
tar xf v${{ env.PROTOBUF_VERSION }}.tar.gz
cd protobuf-${{ env.PROTOBUF_VERSION }}
./autogen.sh && ./configure --disable-maintainer-mode --disable-dependency-tracking --disable-static
make -C ./src protoc
make -C conformance
cp ./conformance/.libs/conformance-test-runner ../conformance-bin
cp ./src/.libs/libprotobuf.so.${{ env.PROTOBUF_LIB_VERSION_MAJOR }}.${{ env.PROTOBUF_LIB_VERSION_MINOR }} ../conformance-bin/.libs/libprotobuf.so.${{ env.PROTOBUF_LIB_VERSION_MAJOR }}
- name: Install protoc
run: |
wget https://github.com/protocolbuffers/protobuf/releases/download/v24.4/protoc-24.4-linux-x86_64.zip
unzip -d protoc protoc-24.4-linux-x86_64.zip
echo "${PWD}/protoc/bin" >> $GITHUB_PATH
path: conformance_test_runner
key: ${{ runner.os }}-protobuf-${{ env.PROTOX_PROTOBUF_VERSION }}

- name: Unlock all dependencies
run: mix deps.unlock --all
Expand All @@ -99,10 +78,19 @@ jobs:
- name: Compile prod with warnings as errors
run: MIX_ENV=prod mix compile --warnings-as-errors

- name: Compile conformance-test-runner
if: steps.compile-conformance-test-runner.outputs.cache-hit != 'true'
run: |
mix protox.conformance --compile-only
cp ./deps/protobuf/bin/conformance_test_runner ./conformance_test_runner
- name: Install protoc
run: |
wget https://github.com/protocolbuffers/protobuf/releases/download/v24.4/protoc-24.4-linux-x86_64.zip
unzip -d protoc protoc-24.4-linux-x86_64.zip
echo "${PWD}/protoc/bin" >> $GITHUB_PATH
- name: Run tests
env:
PROTOBUF_CONFORMANCE_RUNNER: conformance-bin/conformance-test-runner
LD_LIBRARY_PATH: conformance-bin/.libs
run: mix coveralls.github --include conformance

- name: Check formatting
Expand Down
12 changes: 3 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -516,16 +516,10 @@ The protox library has been thoroughly tested using the conformance checker [pro

Here's how to launch the conformance tests:
* Get conformance-test-runner [sources](https://github.com/protocolbuffers/protobuf/archive/refs/tags/v3.18.0.tar.gz).
* Compile conformance-test-runner ([macOS and Linux only](https://github.com/protocolbuffers/protobuf/tree/master/conformance#portability)):
```
tar xf protobuf-3.18.0.tar.gz && cd protobuf-3.18.0 && ./autogen.sh && ./configure && make -j && cd conformance && make -j
```
```
mix protox.conformance
```
* Launch the conformance tests:
```
mix protox.conformance --runner=/path/to/protobuf-3.18.0/conformance/conformance-test-runner
```
* A report will be generated in the directory `conformance_report` and the following text should be displayed:
```
Expand Down
117 changes: 100 additions & 17 deletions conformance/mix/tasks/protox/task.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,116 @@ defmodule Mix.Tasks.Protox.Conformance do
@impl Mix.Task
@spec run(any) :: any
def run(args) do
with {options, _, []} <- OptionParser.parse(args, strict: [runner: :string, quiet: :boolean]),
{:ok, runner} <- Keyword.fetch(options, :runner),
quiet <- Keyword.get(options, :quiet, false),
with {options, _, []} <-
OptionParser.parse(args,
strict: [
runner: :string,
quiet: :boolean,
force_runner_build: :boolean,
compile_only: :boolean
]
),
{:ok, runner} <- get_runner(options),
:ok <- Mix.Tasks.Escript.Build.run([]),
:ok <- launch(runner, quiet) do
:ok <- launch_runner(options, runner) do
{:ok, :conformance_successful}
else
# We return :ok here because it means that the conformance test was launched, not necessarily successful.
{:error, :runner_failure} -> {:ok, :conformance_failure}
e -> e
end
end

defp launch(runner, quiet) do
shell =
case quiet do
true -> Mix.Shell.Quiet
false -> Mix.Shell.IO
defp launch_runner(options, runner) do
compile_only = Keyword.get(options, :compile_only, false)

if compile_only do
:ok
else
shell = shell(options)

cmd =
shell.cmd(
"#{runner} --enforce_recommended --failure_list ./conformance/failure_list.txt --output_dir . ./protox_conformance"
)

case cmd do
0 -> :ok
1 -> {:error, :runner_failure}
126 -> {:error, :cannot_execute_runner}
127 -> {:error, :no_such_file_or_directory}
code -> {:error, code}
end
end
end

defp get_runner(options) do
case Keyword.get(options, :runner) do
nil ->
runner_path =
Path.expand("#{Mix.Project.deps_paths().protobuf}/bin/conformance_test_runner")

force_runner_build = Keyword.get(options, :force_runner_build, false)

if File.exists?(runner_path) and not force_runner_build do
{:ok, runner_path}
else
with :ok <- configure_runner(options),
:ok <- build_runner(options) do
{:ok, runner_path}
end
end

runner_path ->
{:ok, runner_path}
end
end

defp configure_runner(options) do
shell = shell(options)

configuration =
[
{"CMAKE_CXX_STANDARD", "14"},
{"protobuf_INSTALL", "OFF"},
{"protobuf_BUILD_TESTS", "OFF"},
{"protobuf_BUILD_CONFORMANCE", "ON"},
{"protobuf_BUILD_EXAMPLES", "OFF"},
{"protobuf_BUILD_PROTOBUF_BINARIES", "ON"},
{"protobuf_BUILD_PROTOC_BINARIES", "OFF"},
{"protobuf_BUILD_LIBPROTOC", "OFF"},
{"protobuf_BUILD_LIBUPB", "OFF"}
]
|> Enum.map(fn {key, value} -> "-D#{key}=#{value}" end)
|> Enum.join(" ")

File.cd!(Mix.Project.deps_paths().protobuf, fn ->
cmd = shell.cmd("cmake . #{configuration}")

case cmd do
0 -> :ok
code -> {:error, code}
end
end)
end

defp build_runner(options) do
shell = shell(options)

File.cd!(Mix.Project.deps_paths().protobuf, fn ->
cmd = shell.cmd("cmake --build . --parallel")

case cmd do
0 -> :ok
code -> {:error, code}
end
end)
end

case shell.cmd(
"#{runner} --enforce_recommended --failure_list ./conformance/failure_list.txt ./protox_conformance"
) do
0 -> :ok
1 -> {:error, :runner_failure}
126 -> {:error, :cannot_execute_runner}
127 -> {:error, :no_such_file_or_directory}
code -> {:error, code}
defp shell(options) do
case Keyword.get(options, :quiet, false) do
true -> Mix.Shell.Quiet
false -> Mix.Shell.IO
end
end
end
175 changes: 0 additions & 175 deletions conformance/protox/conformance/conformance.proto

This file was deleted.

Loading

0 comments on commit 5c0f94c

Please sign in to comment.