Skip to content

Commit

Permalink
Fix bindings and add CI tests
Browse files Browse the repository at this point in the history
Also update version numbers of binding Rust projects to match Regorus

Signed-off-by: Anand Krishnamoorthi <[email protected]>
  • Loading branch information
anakrish committed May 21, 2024
1 parent 495e91c commit 40de868
Show file tree
Hide file tree
Showing 19 changed files with 232 additions and 81 deletions.
43 changes: 43 additions & 0 deletions .github/workflows/test-c-cpp.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: test-c-cpp

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:
setup:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup gcc, g++, cmake, ninja
run: sudo apt update && sudo apt install -y gcc g++ cmake ninja-build

- name: Test c binding
run: |
mkdir bindings/c/build
cd bindings/c/build
cmake -G Ninja ..
ninja
./regorus_test
- name: Test c-nostd binding
run: |
mkdir bindings/c-nostd/build
cd bindings/c-nostd/build
cmake -G Ninja ..
ninja
./regorus_test
- name: Test cpp binding
run: |
mkdir bindings/cpp/build
cd bindings/cpp/build
cmake -G Ninja ..
ninja
./regorus_test
36 changes: 36 additions & 0 deletions .github/workflows/test-python.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: test-python

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

env:
PYTHON_VERSION: "3.10"

jobs:
setup:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: actions/setup-python@v4
with:
python-version: ${{ env.PYTHON_VERSION }}

- name: Build wheels
uses: PyO3/maturin-action@v1
with:
args: --release --out dist --find-interpreter --manifest-path bindings/python/Cargo.toml
sccache: 'true'
manylinux: auto

- name: Test wheel
run: |
pip3 install dist/regorus-*.whl
cd bindings/python
python3 test.py
30 changes: 30 additions & 0 deletions .github/workflows/test-wasm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: test-wasm

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:
setup:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 18

- name: Install wasmlpack
run: cargo install wasm-pack

- name: Test wasm binding
run: |
cd bindings/wasm
wasm-pack build --target nodejs --release
node test.js
6 changes: 3 additions & 3 deletions bindings/c-nostd/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ corrosion_import_crate(
CRATE_TYPES staticlib FLAGS --crate-type=staticlib
)

add_executable(regorus_test_nostd main.c)
add_executable(regorus_test main.c)
# Add path to <regorus-source-folder>/bindings/ffi
target_include_directories(regorus_test_nostd PRIVATE "../ffi")
target_link_libraries(regorus_test_nostd regorus-ffi)
target_include_directories(regorus_test PRIVATE "../ffi")
target_link_libraries(regorus_test regorus-ffi)
18 changes: 10 additions & 8 deletions bindings/c-nostd/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ char* file_to_string(const char* file) {
char * buffer = 0;
long length;
FILE * f = fopen (file, "rb");

if (f)
{
fseek (f, 0, SEEK_END);
length = ftell (f);
fseek (f, 0, SEEK_SET);
buffer = malloc (length);
buffer = malloc (length + 1);
buffer[length] = '\0';
if (buffer)
{
fread (buffer, 1, length, f);
Expand All @@ -26,8 +27,6 @@ char* file_to_string(const char* file) {

// If regorus is built with custom-allocator, then provide implementation.
uint8_t* regorus_aligned_alloc(size_t alignment, size_t size) {
printf("%ld %ld\n", size, alignment);
fflush(stdout);
return aligned_alloc(alignment, size);
}

Expand All @@ -47,18 +46,21 @@ int main() {
free(buffer);
if (r.status != RegorusStatusOk)
goto error;
printf("Loaded policy %s\n", r.output);
regorus_result_drop(r);

r = regorus_engine_add_policy(engine, "api.rego", (buffer = file_to_string("../../../tests/aci/api.rego")));
free(buffer);
if (r.status != RegorusStatusOk)
goto error;
printf("Loaded policy %s\n", r.output);
regorus_result_drop(r);

r = regorus_engine_add_policy(engine, "policy.rego", (buffer = file_to_string("../../../tests/aci/policy.rego")));
free(buffer);
if (r.status != RegorusStatusOk)
goto error;
printf("Loaded policy %s\n", r.output);
regorus_result_drop(r);

// Add data
Expand All @@ -83,14 +85,14 @@ int main() {
// Print output
printf("%s", r.output);
regorus_result_drop(r);


// Free the engine.
regorus_engine_drop(engine);

return 0;
error:
printf("%s", r.error_message);

return 1;
}
3 changes: 3 additions & 0 deletions bindings/c/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,19 @@ int main() {
r = regorus_engine_add_policy_from_file(engine, "../../../tests/aci/framework.rego");
if (r.status != RegorusStatusOk)
goto error;
printf("Loaded policy %s\n", r.output);
regorus_result_drop(r);

r = regorus_engine_add_policy_from_file(engine, "../../../tests/aci/api.rego");
if (r.status != RegorusStatusOk)
goto error;
printf("Loaded policy %s\n", r.output);
regorus_result_drop(r);

r = regorus_engine_add_policy_from_file(engine, "../../../tests/aci/policy.rego");
if (r.status != RegorusStatusOk)
goto error;
printf("Loaded policy %s\n", r.output);
regorus_result_drop(r);

// Add data
Expand Down
10 changes: 8 additions & 2 deletions bindings/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,14 @@ corrosion_import_crate(
MANIFEST_PATH "../ffi/Cargo.toml"
# Always build regorus in Release mode.
PROFILE "release"
# Only build the "regorusc" crate.
CRATES "regorus-ffi")
# Only build the "regorus-ffi" crate.
CRATES "regorus-ffi"

# Select specific features in regorus.
FEATURES "regorus/semver"

# Link statically
CRATE_TYPES "staticlib")

add_executable(regorus_test main.cpp)
# Add path to <regorus-source-folder>/bindings/ffi
Expand Down
1 change: 1 addition & 0 deletions bindings/cpp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ int main() {
std::cerr<<result.error()<<std::endl;
return -1;
}
std::cout<<"Loaded policy "<<result.output()<< std::endl;
}
{
auto result = engine.add_data_from_json_file("../../../tests/aci/data.json");
Expand Down
2 changes: 1 addition & 1 deletion bindings/ffi/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "regorus-ffi"
version = "0.1.0"
version = "0.1.5"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
44 changes: 31 additions & 13 deletions bindings/ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ fn to_c_str(s: String) -> *mut c_char {
}
}

fn from_c_str(s: *const c_char) -> Result<String> {
fn from_c_str(name: &str, s: *const c_char) -> Result<String> {
if s.is_null() {
bail!("null pointer");
}
unsafe {
CStr::from_ptr(s)
.to_str()
.map_err(|_| anyhow!("`path`: invalid utf8"))
.map_err(|e| anyhow!("`{name}`: invalid utf8.\n{e}"))
.map(|s| s.to_string())
}
}
Expand All @@ -70,6 +70,21 @@ fn to_regorus_result(r: Result<()>) -> RegorusResult {
}
}

fn to_regorus_string_result(r: Result<String>) -> RegorusResult {
match r {
Ok(s) => RegorusResult {
status: RegorusStatus::RegorusStatusOk,
output: to_c_str(s),
error_message: std::ptr::null_mut(),
},
Err(e) => RegorusResult {
status: RegorusStatus::RegorusStatusError,
output: std::ptr::null_mut(),
error_message: to_c_str(format!("{e}")),
},
}
}

/// Wrapper for `regorus::Engine`.
#[derive(Clone)]
pub struct RegorusEngine {
Expand All @@ -81,10 +96,13 @@ pub struct RegorusEngine {
/// `output` and `error_message` strings are not valid after drop.
#[no_mangle]
pub extern "C" fn regorus_result_drop(r: RegorusResult) {
if !r.error_message.is_null() {
unsafe {
unsafe {
if !r.error_message.is_null() {
let _ = CString::from_raw(r.error_message);
}
if !r.output.is_null() {
let _ = CString::from_raw(r.output);
}
}
}

Expand Down Expand Up @@ -133,10 +151,10 @@ pub extern "C" fn regorus_engine_add_policy(
path: *const c_char,
rego: *const c_char,
) -> RegorusResult {
to_regorus_result(|| -> Result<()> {
to_regorus_string_result(|| -> Result<String> {
to_ref(&engine)?
.engine
.add_policy(from_c_str(path)?, from_c_str(rego)?)
.add_policy(from_c_str("path", path)?, from_c_str("rego", rego)?)
}())
}

Expand All @@ -146,10 +164,10 @@ pub extern "C" fn regorus_engine_add_policy_from_file(
engine: *mut RegorusEngine,
path: *const c_char,
) -> RegorusResult {
to_regorus_result(|| -> Result<()> {
to_regorus_string_result(|| -> Result<String> {
to_ref(&engine)?
.engine
.add_policy_from_file(from_c_str(path)?)
.add_policy_from_file(from_c_str("path", path)?)
}())
}

Expand All @@ -165,7 +183,7 @@ pub extern "C" fn regorus_engine_add_data_json(
to_regorus_result(|| -> Result<()> {
to_ref(&engine)?
.engine
.add_data(regorus::Value::from_json_str(&from_c_str(data)?)?)
.add_data(regorus::Value::from_json_str(&from_c_str("data", data)?)?)
}())
}

Expand All @@ -178,7 +196,7 @@ pub extern "C" fn regorus_engine_add_data_from_json_file(
to_regorus_result(|| -> Result<()> {
to_ref(&engine)?
.engine
.add_data(regorus::Value::from_json_file(&from_c_str(path)?)?)
.add_data(regorus::Value::from_json_file(&from_c_str("path", path)?)?)
}())
}

Expand All @@ -205,7 +223,7 @@ pub extern "C" fn regorus_engine_set_input_json(
to_regorus_result(|| -> Result<()> {
to_ref(&engine)?
.engine
.set_input(regorus::Value::from_json_str(&from_c_str(input)?)?);
.set_input(regorus::Value::from_json_str(&from_c_str("input", input)?)?);
Ok(())
}())
}
Expand All @@ -219,7 +237,7 @@ pub extern "C" fn regorus_engine_set_input_from_json_file(
to_regorus_result(|| -> Result<()> {
to_ref(&engine)?
.engine
.set_input(regorus::Value::from_json_file(&from_c_str(path)?)?);
.set_input(regorus::Value::from_json_file(&from_c_str("path", path)?)?);
Ok(())
}())
}
Expand All @@ -236,7 +254,7 @@ pub extern "C" fn regorus_engine_eval_query(
let output = || -> Result<String> {
let results = to_ref(&engine)?
.engine
.eval_query(from_c_str(query)?, false)?;
.eval_query(from_c_str("query", query)?, false)?;
Ok(serde_json::to_string_pretty(&results)?)
}();
match output {
Expand Down
2 changes: 1 addition & 1 deletion bindings/java/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "regorus-java"
version = "0.1.0"
version = "0.1.5"
edition = "2021"
repository = "https://github.com/microsoft/regorus/bindings/java"
description = "Java bindings for Regorus - a fast, lightweight Rego interpreter written in Rust"
Expand Down
2 changes: 1 addition & 1 deletion bindings/python/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "regoruspy"
version = "0.1.0"
version = "0.1.5"
edition = "2021"
repository = "https://github.com/microsoft/regorus/bindings/python"
description = "Python bindings for Regorus - a fast, lightweight Rego interpreter written in Rust"
Expand Down
Loading

0 comments on commit 40de868

Please sign in to comment.