Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiplatform tests #32

Merged
merged 7 commits into from
Mar 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 56 additions & 21 deletions .github/workflows/cpp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,47 +10,82 @@ env:
CARGO_TERM_COLOR: always

jobs:
build-scaffolding:
run-tests:
runs-on: ${{ matrix.os }}
strategy:
matrix:
# Ubuntu-20.04 is being used here on purpose instead of ubuntu-latest due to a bug with clang and libstdc++
# https://github.com/actions/runner-images/issues/8659
os: [ubuntu-20.04, windows-latest, macos-13]
build_type: [Release]
cpp_compiler: [g++, clang++, cl]
exclude:
- os: windows-latest
cpp_compiler: clang++
- os: windows-latest
cpp_compiler: g++
- os: ubuntu-20.04
cpp_compiler: cl
- os: macos-13
cpp_compiler: cl

steps:
- uses: actions/checkout@v3

- name: Set reusable strings
id: strings
shell: bash
run: |
echo "build-output-dir=${{ github.workspace }}/cpp-tests/build" >> "$GITHUB_OUTPUT"
echo "build-source-dir=${{ github.workspace }}/cpp-tests" >> "$GITHUB_OUTPUT"

- name: Install additional dependencies
shell: bash
run: |
if [ "$RUNNER_OS" == "Linux" ]; then
sudo apt update && sudo apt install -y valgrind
fi

- name: Configure CMake
run: >
cmake -B ${{ steps.strings.outputs.build-output-dir }}
-DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }}
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
-S ${{ steps.strings.outputs.build-source-dir }}

- name: Build
run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config ${{ matrix.build_type }}

- name: Run tests
working-directory: ${{ steps.strings.outputs.build-output-dir }}
run: ctest --build-config ${{ matrix.build_type }}

build-scaffolding-lib:
runs-on: ubuntu-latest
container:
image: ghcr.io/nordsecurity/uniffi-bindgen-cpp-test-runner:v0.3.0
steps:
- uses: actions/checkout@v3
- name: Build scaffolding

- name: Build scaffolding library
shell: bash
env:
# Github sets HOME to /github/home and breaks dependencies in Docker image..
# https://github.com/actions/runner/issues/863
HOME: /root
run: |
source ~/.bashrc
./build_bindgen.sh
./build_scaffolding.sh
./build_scaffolding_lib.sh
- uses: actions/upload-artifact@v3
with:
name: scaffolding_lib
path: cpp-tests/build/libuniffi_fixtures.so

run-tests:
runs-on: ubuntu-latest
container:
image: ghcr.io/nordsecurity/uniffi-bindgen-cpp-test-runner:v0.3.0
steps:
- uses: actions/checkout@v3
- name: Run tests
shell: bash
env:
HOME: /root
run: |
source ~/.bashrc
./build_bindgen.sh
./test_bindings.sh

test-scaffolding-go:
runs-on: ubuntu-latest
container:
image: ghcr.io/nordsecurity/uniffi-bindgen-cpp-test-runner:v0.3.0
needs: build-scaffolding
needs: build-scaffolding-lib
steps:
- uses: actions/checkout@v3
with:
Expand All @@ -71,7 +106,7 @@ jobs:
runs-on: ubuntu-latest
container:
image: ghcr.io/nordsecurity/uniffi-bindgen-cs-test-runner:v0.1.0
needs: build-scaffolding
needs: build-scaffolding-lib
steps:
- uses: actions/checkout@v3
with:
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
#### v0.5.0+v0.25.0

----

- Core: **POTENTIALLY BREAKING** changed `timestamp` type from `time_point<system_clock>`, to `time_point<system_clock, nanoseconds>`


#### v0.4.2+v0.25.0

----
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# uniffi-bindgen-cpp - UniFFI C++ bindings generator
# uniffi-bindgen-cpp - UniFFI C++ bindings/scaffolding generator

Generate [UniFFI](https://github.com/mozilla/uniffi-rs) bindings for C++. `uniffi-bindgen-cpp` lives
as a separate project from `uniffi-rs`, as per
Expand Down Expand Up @@ -56,9 +56,9 @@ Note: configuration is not supported when using library mode
uniffi-bindgen-cpp path/to/definitions.udl --config path/to/uniffi.toml
```

# EXPERIMENTAL: C++ Scaffolding
# C++ Scaffolding

It is possible to generate experimental C++ uniffi scaffolding that allows bridging C++ code with any other uniffi supported language (except Rust).
It is possible to generate C++ uniffi scaffolding that allows bridging C++ code with any other uniffi supported language (except Rust).
More documentation and limitations can be found in the [scaffolding documentation](docs/SCAFFOLDING.md)

# Versioning
Expand Down
2 changes: 1 addition & 1 deletion bindgen/src/bindings/cpp/gen_cpp/miscellany.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ macro_rules! impl_code_type_for_miscellany {

impl_code_type_for_miscellany!(
TimestampCodeType,
"std::chrono::time_point<std::chrono::system_clock>",
"std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>",
"Timestamp"
);
impl_code_type_for_miscellany!(
Expand Down
2 changes: 1 addition & 1 deletion bindgen/src/bindings/cpp/templates/arith_conv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ void {{ ffi_converter_name }}::write(RustStream &stream, {{ type_name }} val) {
}

int32_t {{ ffi_converter_name }}::allocation_size({{ type_name }}) {
return sizeof({{ type_name }});
return static_cast<int32_t>(sizeof({{ type_name }}));
}
2 changes: 1 addition & 1 deletion bindgen/src/bindings/cpp/templates/bytes_conv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,5 @@ void {{ ffi_converter_name }}::write(RustStream &stream, const {{ type_name }} &
}

int32_t {{ ffi_converter_name }}::allocation_size(const {{ type_name }} &val) {
return sizeof(int32_t) + sizeof(uint8_t) * val.size();
return static_cast<int32_t>(sizeof(int32_t) + sizeof(uint8_t) * val.size());
}
2 changes: 1 addition & 1 deletion bindgen/src/bindings/cpp/templates/callback_iface_tmpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ void uniffi::{{ class_name }}::write(RustStream &stream, const {{ type_name }} &
}

int32_t uniffi::{{ class_name }}::allocation_size(const {{ type_name }} &impl) {
return sizeof(uint64_t);
return static_cast<int32_t>(sizeof(uint64_t));
}

int {{ class_name }}::callback_stub(uint64_t handle, uint32_t method, uint8_t *args_data, int32_t args_len, RustBuffer *buf_ptr) {
Expand Down
2 changes: 1 addition & 1 deletion bindgen/src/bindings/cpp/templates/duration_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@ void {{ ffi_converter_name }}::write(RustStream &stream, const {{ type_name }} &
}

int32_t {{ ffi_converter_name }}::allocation_size(const {{ type_name }} &) {
return sizeof(uint64_t) + sizeof(uint32_t);
return static_cast<int32_t>(sizeof(uint64_t) + sizeof(uint32_t));
}
4 changes: 2 additions & 2 deletions bindgen/src/bindings/cpp/templates/enum_tmpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void {{ ffi_converter_name }}::write(RustStream &stream, const {{ type_name }} &
}

int32_t {{ ffi_converter_name }}::allocation_size(const {{ type_name|class_name }} &) {
return sizeof(int32_t);
return static_cast<int32_t>(sizeof(int32_t));
}
{%- else %}
{{ type_name }} {{ ffi_converter_name }}::lift(RustBuffer buf) {
Expand Down Expand Up @@ -84,7 +84,7 @@ RustBuffer {{ ffi_converter_name }}::lower(const {{ type_name }} &val) {
}

void {{ ffi_converter_name }}::write(RustStream &stream, const {{ type_name }} &val) {
int32_t variant_id = val.variant.index() + 1;
int32_t variant_id = static_cast<int32_t>(val.variant.index() + 1);

stream << variant_id;

Expand Down
6 changes: 3 additions & 3 deletions bindgen/src/bindings/cpp/templates/err_tmpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,17 @@ void {{ ffi_converter_name }}::write(RustStream &stream, const {{ class_name }}

int32_t {{ ffi_converter_name }}::allocation_size(const {{ class_name }} &val) {
{%- if e.is_flat() %}
return sizeof(int32_t);
return static_cast<int32_t>(sizeof(int32_t));
{%- else %}
switch (val.get_variant_idx()) {
{%- for variant in e.variants() %}
case {{ loop.index }}:
{
auto& var = static_cast<const {{ class_name|to_lower_snake_case }}::{{ variant.name() }}&>(val);
return sizeof(int32_t)
return static_cast<int32_t>(sizeof(int32_t)
{%- for field in variant.fields() %}
+ {{ field|allocation_size_fn }}(var.{{ field.name()|var_name }})
{%- endfor %};
{%- endfor %});
}
{%- endfor %}
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ void {{ ffi_converter_name|class_name }}::write(RustStream &stream, const {{ typ
}

int32_t {{ ffi_converter_name|class_name }}::allocation_size(const {{ type_name }} &obj) {
return sizeof(uint64_t);
return static_cast<int32_t>(sizeof(uint64_t));
}

std::atomic<uint64_t> {{ ffi_converter_name|class_name }}::fn_handle = 0;
Expand Down
2 changes: 1 addition & 1 deletion bindgen/src/bindings/cpp/templates/scaffolding/err.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ void {{ ffi_converter_name }}{{ variant.name() }}::write(RustStream &stream, con
}

int32_t {{ ffi_converter_name }}{{ variant.name() }}::allocation_size(const {{ namespace }}::{{ variant.name() }} &val) {
auto size = sizeof(int32_t);
int32_t size = sizeof(int32_t);
{%- if e.is_flat() %}
size += {{ Type::String.borrow()|allocation_size_fn }}(val.what());
{%- else %}
Expand Down
2 changes: 1 addition & 1 deletion bindgen/src/bindings/cpp/templates/str_conv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,5 @@ void {{ ffi_converter_name }}::write(RustStream &stream, const std::string &val)
}

int32_t {{ ffi_converter_name }}::allocation_size(const std::string &val) {
return sizeof(int32_t) + val.length();
return static_cast<int32_t>(sizeof(int32_t) + val.length());
}
2 changes: 1 addition & 1 deletion bindgen/src/bindings/cpp/templates/timestamp_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,5 @@ void {{ ffi_converter_name }}::write(RustStream &stream, const {{ type_name }} &
}

int32_t {{ ffi_converter_name }}::allocation_size(const {{ type_name }} &) {
return sizeof(int64_t) + sizeof(uint32_t);
return static_cast<int32_t>(sizeof(int64_t) + sizeof(uint32_t));
}
4 changes: 0 additions & 4 deletions build_bindgen.sh

This file was deleted.

2 changes: 2 additions & 0 deletions build_scaffolding.sh → build_scaffolding_lib.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#!/bin/bash
set -euxo pipefail

cargo build --release --package uniffi-bindgen-cpp

mkdir -p cpp-tests/build
cd cpp-tests/build
cmake -DCMAKE_BUILD_TYPE=Debug ..
Expand Down
34 changes: 24 additions & 10 deletions cpp-tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,28 @@ find_package(Threads REQUIRED)
set(BINDINGS_BUILD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../target/debug)
set(BINDINGS_SRC_DIR ${BINDINGS_BUILD_DIR}/bindings)

if (WIN32)
set(UNIFFI_FIXTURES_LIB uniffi_bindgen_cpp_fixtures.dll)
set(ADDITIONAL_LIBS ws2_32 userenv advapi32 ntdll crypt32 Bcrypt)
elseif(UNIX AND NOT APPLE)
set(UNIFFI_FIXTURES_LIB libuniffi_bindgen_cpp_fixtures.so)
set(ADDITIONAL_LIBS)
else()
set(UNIFFI_FIXTURES_LIB libuniffi_bindgen_cpp_fixtures.dylib)
set(ADDITIONAL_LIBS)
endif()

find_program(VALGRIND "valgrind")
macro(memcheck_test TEST_NAME)
add_test(NAME ${TEST_NAME}-test-memcheck
COMMAND valgrind
--error-exitcode=1
--tool=memcheck
--leak-check=full
--errors-for-leak-kinds=definite
--show-leak-kinds=definite $<TARGET_FILE:${TEST_NAME}>)
if (VALGRIND)
add_test(NAME ${TEST_NAME}-test-memcheck
COMMAND valgrind
--error-exitcode=1
--tool=memcheck
--leak-check=full
--errors-for-leak-kinds=definite
--show-leak-kinds=definite $<TARGET_FILE:${TEST_NAME}>)
endif()
endmacro(memcheck_test)

# Add a bindings test case
Expand All @@ -28,7 +42,7 @@ add_executable(${TEST_NAME}-test tests/${TEST_NAME}/main.cpp ${BINDINGS_SRC_DIR}

target_include_directories(${TEST_NAME}-test PRIVATE ${BINDINGS_SRC_DIR} include)
target_link_directories(${TEST_NAME}-test PRIVATE ${BINDINGS_BUILD_DIR})
target_link_libraries(${TEST_NAME}-test uniffi_bindgen_cpp_fixtures Threads::Threads)
target_link_libraries(${TEST_NAME}-test uniffi_bindgen_cpp_fixtures Threads::Threads ${ADDITIONAL_LIBS})
target_compile_definitions(${TEST_NAME}-test PRIVATE UNIFFI_BINDING_DIR="${BINDINGS_SRC_DIR}")

add_test(NAME ${TEST_NAME}-test COMMAND ${TEST_NAME}-test)
Expand Down Expand Up @@ -101,15 +115,15 @@ add_custom_target(libs ALL

add_custom_target(bindings ALL
DEPENDS libs
COMMAND ./uniffi-bindgen-cpp --library libuniffi_bindgen_cpp_fixtures.so --out-dir bindings
COMMAND ./uniffi-bindgen-cpp --library ${UNIFFI_FIXTURES_LIB} --out-dir bindings
WORKING_DIRECTORY ${BINDINGS_BUILD_DIR}
COMMENT "Generating bindings"
)

add_custom_target(scaffolding ALL
BYPRODUCTS ${SCAFFOLDING_FILES}
DEPENDS libs
COMMAND ./uniffi-bindgen-cpp --scaffolding --library libuniffi_bindgen_cpp_fixtures.so --out-dir bindings
COMMAND ./uniffi-bindgen-cpp --scaffolding --library ${UNIFFI_FIXTURES_LIB} --out-dir bindings
WORKING_DIRECTORY ${BINDINGS_BUILD_DIR}
COMMENT "Generating scaffolding"
)
2 changes: 1 addition & 1 deletion cpp-tests/scaffolding_tests/callbacks/lib_callbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ std::string callbacks::Telephone::call(std::shared_ptr<CallAnswerer> answerer)
return answerer->answer();
} catch (telephone_error::Busy& e) {
throw e;
} catch (std::runtime_error& e) {
} catch (std::runtime_error&) {
throw telephone_error::InternalTelephoneError();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ chronological::duration chronological::return_duration(chronological::duration a
}

std::string chronological::to_string_timestamp(chronological::timestamp a) {
std::time_t time = std::chrono::system_clock::to_time_t(a);
using time_point = std::chrono::system_clock::time_point;
std::time_t time = std::chrono::system_clock::to_time_t(time_point {std::chrono::duration_cast<time_point::duration>(a.time_since_epoch())});
auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(a.time_since_epoch()).count() % 1000000000;
if (ns < 0) {
ns += 1000000000;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace {
namespace chronological {
typedef std::chrono::time_point<std::chrono::system_clock> timestamp;
typedef std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> timestamp;
typedef std::chrono::duration<int64_t, std::nano> duration;

namespace chronological_error {
Expand Down
11 changes: 5 additions & 6 deletions cpp-tests/scaffolding_tests/coverall/lib_coverall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,9 @@ std::unordered_map<uint32_t, uint64_t> coverall::Coveralls::get_dict3(uint32_t k
}

void coverall::Coveralls::add_patch(std::shared_ptr<Patch> patch) {
auto repair = Repair {
.when = std::chrono::high_resolution_clock::now(),
.patch = patch
};
auto repair = Repair();
repair.when = std::chrono::system_clock::now();
repair.patch = patch;

std::lock_guard<std::mutex> lock(this->repairs_mutex);
this->repairs.push_back(repair);
Expand Down Expand Up @@ -205,8 +204,8 @@ coverall::SimpleDict coverall::create_some_dict() {
.maybe_signed8 = 0,
.signed64 = std::numeric_limits<int64_t>::max(),
.maybe_signed64 = 0,
.float32 = 1.2345,
.maybe_float32 = 22.0 / 7.0,
.float32 = 1.2345f,
.maybe_float32 = 22.0f / 7.0f,
.float64 = 0.0,
.maybe_float64 = 1.0,
.coveralls = std::make_shared<Coveralls>("some_dict"),
Expand Down
2 changes: 1 addition & 1 deletion cpp-tests/scaffolding_tests/coverall/lib_coverall.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

namespace {
namespace coverall {
typedef std::chrono::time_point<std::chrono::system_clock> timestamp;
typedef std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> timestamp;

class IFirst {
public:
Expand Down
Loading
Loading