164 lines
4.5 KiB
Plaintext
164 lines
4.5 KiB
Plaintext
;; Phase 8 FFI BIF tests — one round-trip per BIF.
|
|
;; Each BIF lives in lib/erlang/runtime.sx (registered with
|
|
;; er-bif-registry) and wraps an SX-host primitive.
|
|
|
|
(define er-ffi-test-count 0)
|
|
(define er-ffi-test-pass 0)
|
|
(define er-ffi-test-fails (list))
|
|
|
|
(define
|
|
er-ffi-test
|
|
(fn
|
|
(name actual expected)
|
|
(set! er-ffi-test-count (+ er-ffi-test-count 1))
|
|
(if
|
|
(= actual expected)
|
|
(set! er-ffi-test-pass (+ er-ffi-test-pass 1))
|
|
(append! er-ffi-test-fails {:name name :expected expected :actual actual}))))
|
|
|
|
(define ffi-ev erlang-eval-ast)
|
|
(define ffi-nm (fn (v) (get v :name)))
|
|
|
|
;; ── file:read_file/1 + file:write_file/2 ────────────────────────
|
|
(er-ffi-test
|
|
"file:write_file ok"
|
|
(ffi-nm (ffi-ev "file:write_file(\"/tmp/er-ffi-1.txt\", \"hello\")"))
|
|
"ok")
|
|
|
|
(er-ffi-test
|
|
"file:read_file ok tag"
|
|
(ffi-nm (ffi-ev "element(1, file:read_file(\"/tmp/er-ffi-1.txt\"))"))
|
|
"ok")
|
|
|
|
(er-ffi-test
|
|
"file:read_file payload is binary"
|
|
(ffi-nm
|
|
(ffi-ev
|
|
"case file:read_file(\"/tmp/er-ffi-1.txt\") of {ok, B} -> is_binary(B) end"))
|
|
"true")
|
|
|
|
(er-ffi-test
|
|
"file:read_file content byte_size"
|
|
(ffi-ev
|
|
"case file:read_file(\"/tmp/er-ffi-1.txt\") of {ok, B} -> byte_size(B) end")
|
|
5)
|
|
|
|
(er-ffi-test
|
|
"file:read_file missing enoent"
|
|
(ffi-nm (ffi-ev "element(2, file:read_file(\"/tmp/er-ffi-no-such-xyz\"))"))
|
|
"enoent")
|
|
|
|
(er-ffi-test
|
|
"file:write_file bad path enoent"
|
|
(ffi-nm
|
|
(ffi-ev "element(2, file:write_file(\"/tmp/er-ffi-no-dir-xyz/x\", \"y\"))"))
|
|
"enoent")
|
|
|
|
(er-ffi-test
|
|
"file:write_file binary payload"
|
|
(ffi-ev
|
|
"file:write_file(\"/tmp/er-ffi-2.bin\", <<1, 2, 3, 4, 5>>), case file:read_file(\"/tmp/er-ffi-2.bin\") of {ok, B} -> byte_size(B) end")
|
|
5)
|
|
|
|
;; ── file:delete/1 ────────────────────────────────────────────────
|
|
(er-ffi-test
|
|
"file:delete ok"
|
|
(ffi-nm
|
|
(ffi-ev
|
|
"file:write_file(\"/tmp/er-ffi-del.txt\", \"x\"), file:delete(\"/tmp/er-ffi-del.txt\")"))
|
|
"ok")
|
|
|
|
(er-ffi-test
|
|
"file:read_file after delete enoent"
|
|
(ffi-nm
|
|
(ffi-ev
|
|
"file:write_file(\"/tmp/er-ffi-del2.txt\", \"x\"), file:delete(\"/tmp/er-ffi-del2.txt\"), element(2, file:read_file(\"/tmp/er-ffi-del2.txt\"))"))
|
|
"enoent")
|
|
|
|
(er-ffi-test
|
|
"crypto:hash sha256 -> 32-byte binary"
|
|
(ffi-ev "byte_size(crypto:hash(sha256, <<97,98,99>>))")
|
|
32)
|
|
|
|
(er-ffi-test
|
|
"crypto:hash sha512 -> 64-byte binary"
|
|
(ffi-ev "byte_size(crypto:hash(sha512, <<97,98,99>>))")
|
|
64)
|
|
|
|
(er-ffi-test
|
|
"crypto:hash sha3_256 is_binary"
|
|
(ffi-nm (ffi-ev "is_binary(crypto:hash(sha3_256, <<120>>))"))
|
|
"true")
|
|
|
|
(er-ffi-test
|
|
"crypto:hash deterministic"
|
|
(ffi-nm (ffi-ev "crypto:hash(sha256, <<97>>) =:= crypto:hash(sha256, <<97>>)"))
|
|
"true")
|
|
|
|
(er-ffi-test
|
|
"crypto:hash distinct inputs distinct digests"
|
|
(ffi-nm (ffi-ev "crypto:hash(sha256, <<97>>) =/= crypto:hash(sha256, <<98>>)"))
|
|
"true")
|
|
|
|
(er-ffi-test
|
|
"crypto:hash bad type -> error:badarg"
|
|
(ffi-nm (ffi-ev "try crypto:hash(md5, <<120>>) catch error:badarg -> ok end"))
|
|
"ok")
|
|
|
|
(er-ffi-test
|
|
"cid:from_bytes is_binary"
|
|
(ffi-nm (ffi-ev "is_binary(cid:from_bytes(<<97,98,99>>))"))
|
|
"true")
|
|
|
|
(er-ffi-test
|
|
"cid:from_bytes deterministic"
|
|
(ffi-nm (ffi-ev "cid:from_bytes(<<97,98,99>>) =:= cid:from_bytes(<<97,98,99>>)"))
|
|
"true")
|
|
|
|
(er-ffi-test
|
|
"cid:from_bytes distinct inputs distinct CIDs"
|
|
(ffi-nm (ffi-ev "cid:from_bytes(<<97,98,99>>) =/= cid:from_bytes(<<97,98,100>>)"))
|
|
"true")
|
|
|
|
(er-ffi-test
|
|
"cid:from_bytes non-binary -> error:badarg"
|
|
(ffi-nm (ffi-ev "try cid:from_bytes(42) catch error:badarg -> ok end"))
|
|
"ok")
|
|
|
|
(er-ffi-test
|
|
"cid:to_string is_binary"
|
|
(ffi-nm (ffi-ev "is_binary(cid:to_string({ok, 42}))"))
|
|
"true")
|
|
|
|
(er-ffi-test
|
|
"cid:to_string deterministic"
|
|
(ffi-nm (ffi-ev "cid:to_string(foo) =:= cid:to_string(foo)"))
|
|
"true")
|
|
|
|
(er-ffi-test
|
|
"cid:to_string distinct terms distinct CIDs"
|
|
(ffi-nm (ffi-ev "cid:to_string(foo) =/= cid:to_string(bar)"))
|
|
"true")
|
|
|
|
(er-ffi-test
|
|
"file:list_dir unregistered"
|
|
(er-lookup-bif "file" "list_dir" 1)
|
|
nil)
|
|
|
|
;; ── Still deferred (no host primitive): httpc (HTTP client, v2),
|
|
;; sqlite-* (v2 indexes). Assert NOT registered so a future iteration
|
|
;; that wires them without updating this suite fails fast.
|
|
(er-ffi-test
|
|
"httpc:request unregistered"
|
|
(er-lookup-bif "httpc" "request" 4)
|
|
nil)
|
|
|
|
(er-ffi-test
|
|
"sqlite:exec unregistered"
|
|
(er-lookup-bif "sqlite" "exec" 2)
|
|
nil)
|
|
|
|
(define
|
|
er-ffi-test-summary
|
|
(str "ffi " er-ffi-test-pass "/" er-ffi-test-count))
|