|
| 1 | +# SPDX-License-Identifier: MPL-2.0 |
| 2 | + |
| 3 | +defmodule VeriSim.TransportTest do |
| 4 | + # async: false — these tests mutate the VERISIM_TRANSPORT OS env var. |
| 5 | + use ExUnit.Case, async: false |
| 6 | + |
| 7 | + alias VeriSim.{NifBridge, Transport} |
| 8 | + |
| 9 | + setup do |
| 10 | + prior = System.get_env("VERISIM_TRANSPORT") |
| 11 | + |
| 12 | + on_exit(fn -> |
| 13 | + if prior, |
| 14 | + do: System.put_env("VERISIM_TRANSPORT", prior), |
| 15 | + else: System.delete_env("VERISIM_TRANSPORT") |
| 16 | + end) |
| 17 | + |
| 18 | + :ok |
| 19 | + end |
| 20 | + |
| 21 | + describe "transport mode selection" do |
| 22 | + test "defaults to :http when unset" do |
| 23 | + System.delete_env("VERISIM_TRANSPORT") |
| 24 | + assert Transport.mode() == :http |
| 25 | + refute Transport.use_nif?() |
| 26 | + end |
| 27 | + |
| 28 | + test "explicit nif selects :nif" do |
| 29 | + System.put_env("VERISIM_TRANSPORT", "nif") |
| 30 | + assert Transport.mode() == :nif |
| 31 | + end |
| 32 | + |
| 33 | + test "auto does NOT select the NIF while it is non-operational" do |
| 34 | + System.put_env("VERISIM_TRANSPORT", "auto") |
| 35 | + assert Transport.mode() == :auto |
| 36 | + # No operation is implemented (every NIF/stub returns an error), so the |
| 37 | + # bridge is non-operational and auto must fall back to HTTP. This is the |
| 38 | + # guard against silently routing writes into a NIF that does nothing. |
| 39 | + refute Transport.use_nif?() |
| 40 | + end |
| 41 | + |
| 42 | + test "unknown value falls back to :http" do |
| 43 | + System.put_env("VERISIM_TRANSPORT", "banana") |
| 44 | + assert Transport.mode() == :http |
| 45 | + end |
| 46 | + end |
| 47 | + |
| 48 | + describe "the NIF bridge never fabricates success (regression for silent data loss)" do |
| 49 | + test "every operation returns an error tuple, never fake success" do |
| 50 | + # The previous Rust NIF returned canned success (e.g. delete -> "deleted") |
| 51 | + # having done nothing. After the fail-loudly fix, the compiled NIF and the |
| 52 | + # pure-Elixir stub are indistinguishable: both error, neither fabricates. |
| 53 | + assert {:error, _} = NifBridge.create_octad(~s({"document":{"title":"t","body":"b"}})) |
| 54 | + assert {:error, _} = NifBridge.get_octad("e-1") |
| 55 | + assert {:error, _} = NifBridge.delete_octad("e-1") |
| 56 | + assert {:error, _} = NifBridge.search_text("q", 10) |
| 57 | + assert {:error, _} = NifBridge.search_vector("[0.1,0.2,0.3]", 5) |
| 58 | + assert {:error, _} = NifBridge.list_octads(10, 0) |
| 59 | + assert {:error, _} = NifBridge.get_drift_score("e-1") |
| 60 | + assert {:error, _} = NifBridge.trigger_normalise("e-1") |
| 61 | + end |
| 62 | + |
| 63 | + test "loaded? is false when no operation is operational" do |
| 64 | + refute NifBridge.loaded?() |
| 65 | + end |
| 66 | + end |
| 67 | + |
| 68 | + describe "health does not fake success under an explicit nif transport" do |
| 69 | + test "nif health reports not operational, never {:ok, healthy}" do |
| 70 | + System.put_env("VERISIM_TRANSPORT", "nif") |
| 71 | + assert {:error, :nif_not_operational} = Transport.health() |
| 72 | + end |
| 73 | + end |
| 74 | +end |
0 commit comments