Skip to content
Open
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
26 changes: 25 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,32 @@ jobs:

- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
# REQUIRED. Without `workspaces:` this action looks for ONE Cargo workspace at the
# checkout root, and nothing is checked out there: every checkout above uses `path:`.
# It logged "could not find Cargo.toml" and carried on WITHOUT failing, so this job
# rebuilt everything from scratch on every run while the log said the cache step
# succeeded. Each workspace this job actually builds must be named.
workspaces: |
store-valkey-repo/store-valkey
busbarAI
- name: cargo test -p busbar-store-valkey -- --ignored wipes_the_entire_namespace_destructively
working-directory: store-valkey-repo/store-valkey
env:
VALKEY_URL: redis://localhost:6379/0
run: cargo test -- --ignored --test-threads=1 wipes_the_entire_namespace_destructively
run: |
set -euo pipefail
# FLOOR ASSERTION on the number of tests that actually ran. `cargo test <filter>` is a
# SUBSTRING match with no minimum: rename the test (dropping "the_" is enough) and the
# filter matches ZERO tests, cargo prints "running 0 tests / test result: ok" and EXITS 0.
# This whole job — and the dedicated valkey/valkey:8 service container it stands up — then
# goes green having run nothing, and because the test is #[ignore]'d no other job covers
# it either. Requiring "1 passed" is what makes the rename fail loudly instead.
out="$(cargo test -- --ignored --test-threads=1 \
wipes_the_entire_namespace_destructively 2>&1 | tee /dev/stderr)"
grep -qE 'test result: ok\. 1 passed' <<<"$out" || {
echo "::error::the destructive-wipe test did not run (renamed, moved, or filtered out)." \
"The filter matched no tests and cargo exited 0. Re-point the filter at the test's" \
"current name — do NOT relax this assertion." >&2
exit 1
}
9 changes: 9 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,15 @@ jobs:
with:
targets: ${{ matrix.target }}
- uses: Swatinem/rust-cache@v2
with:
# REQUIRED. Without `workspaces:` this action looks for ONE Cargo workspace at the
# checkout root, and nothing is checked out there: every checkout above uses `path:`.
# It logged "could not find Cargo.toml" and carried on WITHOUT failing, so this job
# rebuilt everything from scratch on every run while the log said the cache step
# succeeded. Each workspace this job actually builds must be named.
workspaces: |
store-valkey
busbarAI

- name: Build the store-valkey plugin cdylib
working-directory: store-valkey
Expand Down
13 changes: 11 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 33 additions & 5 deletions store-valkey-plugin/tests/e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,39 @@ const TEST_SIGNING_KEY: &str = "0123456789abcdef0123456789abcdef0123456789abcdef
/// under `cargo test` (which builds the whole package including the cdylib target before running
/// tests) it is always present, so this only guards against unusual invocations.
fn plugin_path() -> Option<std::path::PathBuf> {
let exe = std::env::current_exe().ok()?; // .../target/<profile>/deps/e2e-<hash>
let profile_dir = exe.parent()?.parent()?; // .../target/<profile>
let name = plugin_library_filename("busbar_store_valkey_plugin");
let candidate = profile_dir.join(&name);
candidate.exists().then_some(candidate)
let candidate = (|| {
let exe = std::env::current_exe().ok()?; // .../target/<profile>/deps/e2e-<hash>
let profile_dir = exe.parent()?.parent()?; // .../target/<profile>
let name = plugin_library_filename("busbar_store_valkey_plugin");
// Check BOTH the "uplifted" <profile>/<name> copy and the raw <profile>/deps/<name>
// compiler output, newest wins: a bare `cargo test` does NOT uplift the cdylib to the
// top-level profile dir, only to deps/ (same fix already applied to store-postgres's,
// store-mysql's, auth-oidc's and webrequest-hook's equivalent helpers).
let uplifted = profile_dir.join(&name);
let raw = profile_dir.join("deps").join(&name);
[uplifted, raw]
.into_iter()
.filter_map(|p| {
std::fs::metadata(&p)
.and_then(|m| m.modified())
.ok()
.map(|mtime| (p, mtime))
})
.max_by_key(|(_, mtime)| *mtime)
.map(|(p, _)| p)
})();
// Under CI a missing cdylib is a HARD FAILURE, never a silent skip — the same discipline
// `valkey_url()` below already applies, and the one every sibling plugin repo applies here.
// Without it the three tests gated on this helper skip to green in 0.00s when their subject
// disappears, which is the only over-the-ABI coverage of the valkey store path.
if candidate.is_none() && std::env::var_os("CI").is_some() {
panic!(
"the store-valkey plugin cdylib is not built under CI: `cargo test` must build it \
(checked both the uplifted target dir and target/deps). Refusing to silently skip \
the only over-the-ABI coverage of the durable Valkey store path."
);
}
candidate
}

/// The live `VALKEY_URL`, mirroring `busbar-store-valkey`'s own `live_store()` gating discipline
Expand Down
Loading