Skip to content

Commit

Permalink
Run tests and lint for Rust code in CI. (#1289)
Browse files Browse the repository at this point in the history
Run tools like `clippy`, `cargo fmt`, `cargo doc`, and tests over our
Rust code in CI.
  • Loading branch information
obi1kenobi authored Dec 5, 2024
1 parent 6106403 commit 47be091
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 21 deletions.
114 changes: 114 additions & 0 deletions .github/workflows/rust_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
name: Run Rust CI

# Our Rust code depends on the vendored `orjson` and `pyo3` workspaces,
# so ensure that CI re-runs if they are modified.
on:
push:
branches:
- main
paths:
- "rust/**"
- "vendor/orjson/**"
- "vendor/pyo3/**"
- ".github/workflows/rust_test.yml"
pull_request:
paths:
- "rust/**"
- "vendor/orjson/**"
- "vendor/pyo3/**"
- ".github/workflows/rust_test.yml"
workflow_dispatch:

permissions:
contents: read

env:
RUST_VERSION: '1.82' # Be careful, "stable" gets you "whatever GitHub ships", which is quite old.
RUST_WORKSPACE_PATH: 'rust' # The location of the Rust workspace relative to the repo root.

jobs:
lint:
name: Check lint and rustfmt
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false

- name: Install rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: "${{env.RUST_VERSION}}"
components: rustfmt, clippy
cache-workspaces: "${{env.RUST_WORKSPACE_PATH}} -> target"
rustflags: ""

- name: cargo clippy
working-directory: ${{env.RUST_WORKSPACE_PATH}}
run: cargo clippy --workspace --all-targets --all-features --no-deps -- -D warnings --allow deprecated

- name: cargo fmt
working-directory: ${{env.RUST_WORKSPACE_PATH}}
run: cargo fmt -- --check

- name: cargo doc
working-directory: ${{env.RUST_WORKSPACE_PATH}}
env:
RUSTDOCFLAGS: -D warnings
run: cargo doc --workspace --no-deps --document-private-items
cargo-test:
name: Run `cargo test`
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false

- name: Install rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: "${{env.RUST_VERSION}}"
cache-workspaces: "${{env.RUST_WORKSPACE_PATH}} -> target"
rustflags: ""

- name: cargo test
working-directory: ${{env.RUST_WORKSPACE_PATH}}
run: |
set -euxo pipefail
# We exclude `langsmith-pyo3` since its tests:
# - Have to be run under `nextest`, since they require one-process-per-test.
# - Require a non-default configuration in order to run.
cargo test --workspace --exclude langsmith-pyo3 --all-features
langsmith-pyo3-tests:
name: Run langsmith-pyo3 tests
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false

- name: Install rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: "${{env.RUST_VERSION}}"
cache-workspaces: "${{env.RUST_WORKSPACE_PATH}} -> target"
rustflags: ""

- name: Install cargo-nextest
uses: taiki-e/install-action@v2
with:
tool: cargo-nextest

- name: cargo test
working-directory: "${{env.RUST_WORKSPACE_PATH}}/crates/langsmith-pyo3"
run: |
set -euxo pipefail
# See the langsmith-pyo3 README.md file for an explanation
# of why tests have to run under nextest & without default features.
cargo nextest run --no-default-features
42 changes: 22 additions & 20 deletions rust/crates/langsmith-pyo3/src/py_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,13 @@ impl FromPyObject<'_> for RunCreate {

let run_type =
value.get_item(pyo3::intern!(value.py(), "run_type"))?.extract::<String>()?;
let reference_example_id = extract_string_like_or_none(get_optional_value_from_mapping(
value,
pyo3::intern!(value.py(), "reference_example_id"),
).as_ref())?;
let reference_example_id = extract_string_like_or_none(
get_optional_value_from_mapping(
value,
pyo3::intern!(value.py(), "reference_example_id"),
)
.as_ref(),
)?;

Ok(Self(langsmith_tracing_client::client::RunCreate {
common,
Expand Down Expand Up @@ -151,32 +154,31 @@ impl FromPyObject<'_> for RunCommon {
extract_string_like(&value.get_item(pyo3::intern!(value.py(), "trace_id"))?)?;

let dotted_order = value.get_item(pyo3::intern!(value.py(), "dotted_order"))?.extract()?;
let parent_run_id = extract_string_like_or_none(get_optional_value_from_mapping(
value,
pyo3::intern!(value.py(), "parent_run_id"),
).as_ref())?;
let parent_run_id = extract_string_like_or_none(
get_optional_value_from_mapping(value, pyo3::intern!(value.py(), "parent_run_id"))
.as_ref(),
)?;

let extra = extract_optional_value_from_mapping(value, pyo3::intern!(value.py(), "extra"))?;

let error = extract_string_like_or_none(get_optional_value_from_mapping(
value,
pyo3::intern!(value.py(), "error"),
).as_ref())?;
let error = extract_string_like_or_none(
get_optional_value_from_mapping(value, pyo3::intern!(value.py(), "error")).as_ref(),
)?;

let serialized =
extract_optional_value_from_mapping(value, pyo3::intern!(value.py(), "serialized"))?;
let events =
extract_optional_value_from_mapping(value, pyo3::intern!(value.py(), "events"))?;
let tags = extract_optional_value_from_mapping(value, pyo3::intern!(value.py(), "tags"))?;

let session_id = extract_string_like_or_none(get_optional_value_from_mapping(
value,
pyo3::intern!(value.py(), "session_id"),
).as_ref())?;
let session_name = extract_string_like_or_none(get_optional_value_from_mapping(
value,
pyo3::intern!(value.py(), "session_name"),
).as_ref())?;
let session_id = extract_string_like_or_none(
get_optional_value_from_mapping(value, pyo3::intern!(value.py(), "session_id"))
.as_ref(),
)?;
let session_name = extract_string_like_or_none(
get_optional_value_from_mapping(value, pyo3::intern!(value.py(), "session_name"))
.as_ref(),
)?;

Ok(Self(langsmith_tracing_client::client::RunCommon {
id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ fn benchmark_gzip_only_parallel(data: &Vec<Vec<u8>>) -> Vec<Vec<u8>> {

// into par iter
fn benchmark_json_only_parallel(data: &[Value]) -> Vec<Vec<u8>> {
data.par_iter().map(|json| serde_json::to_vec(json).expect("Failed to serialize JSON")).collect()
data.par_iter()
.map(|json| serde_json::to_vec(json).expect("Failed to serialize JSON"))
.collect()
}

fn json_benchmark_large_array(c: &mut Criterion) {
Expand Down

0 comments on commit 47be091

Please sign in to comment.