Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
153 lines
3.5 KiB
Plaintext
153 lines
3.5 KiB
Plaintext
;; Fib server — long-lived process that computes fibonacci numbers on
|
|
;; request. Tests recursive function evaluation inside a server loop.
|
|
|
|
(define er-fib-test-count 0)
|
|
(define er-fib-test-pass 0)
|
|
(define er-fib-test-fails (list))
|
|
|
|
(define
|
|
er-fib-test
|
|
(fn
|
|
(name actual expected)
|
|
(set! er-fib-test-count (+ er-fib-test-count 1))
|
|
(if
|
|
(= actual expected)
|
|
(set! er-fib-test-pass (+ er-fib-test-pass 1))
|
|
(append! er-fib-test-fails {:actual actual :expected expected :name name}))))
|
|
|
|
(define fib-ev erlang-eval-ast)
|
|
|
|
;; Fib + server-loop source. Standalone so each test can chain queries.
|
|
(define
|
|
er-fib-server-src
|
|
"Fib = fun (0) -> 0; (1) -> 1; (N) -> Fib(N-1) + Fib(N-2) end,
|
|
FibSrv = fun () ->
|
|
Loop = fun () ->
|
|
receive
|
|
{fib, N, From} -> From ! Fib(N), Loop();
|
|
stop -> ok
|
|
end
|
|
end,
|
|
Loop()
|
|
end")
|
|
|
|
;; Base cases.
|
|
(er-fib-test
|
|
"fib(0)"
|
|
(fib-ev
|
|
(str
|
|
er-fib-server-src
|
|
", Me = self(),
|
|
Srv = spawn(FibSrv),
|
|
Srv ! {fib, 0, Me},
|
|
receive R -> Srv ! stop, R end"))
|
|
0)
|
|
|
|
(er-fib-test
|
|
"fib(1)"
|
|
(fib-ev
|
|
(str
|
|
er-fib-server-src
|
|
", Me = self(),
|
|
Srv = spawn(FibSrv),
|
|
Srv ! {fib, 1, Me},
|
|
receive R -> Srv ! stop, R end"))
|
|
1)
|
|
|
|
;; Larger values.
|
|
(er-fib-test
|
|
"fib(10) = 55"
|
|
(fib-ev
|
|
(str
|
|
er-fib-server-src
|
|
", Me = self(),
|
|
Srv = spawn(FibSrv),
|
|
Srv ! {fib, 10, Me},
|
|
receive R -> Srv ! stop, R end"))
|
|
55)
|
|
|
|
(er-fib-test
|
|
"fib(15) = 610"
|
|
(fib-ev
|
|
(str
|
|
er-fib-server-src
|
|
", Me = self(),
|
|
Srv = spawn(FibSrv),
|
|
Srv ! {fib, 15, Me},
|
|
receive R -> Srv ! stop, R end"))
|
|
610)
|
|
|
|
;; Multiple sequential queries to one server. Sum to avoid dict-equality.
|
|
(er-fib-test
|
|
"sequential fib(5..8) sum"
|
|
(fib-ev
|
|
(str
|
|
er-fib-server-src
|
|
", Me = self(),
|
|
Srv = spawn(FibSrv),
|
|
Srv ! {fib, 5, Me}, A = receive Ra -> Ra end,
|
|
Srv ! {fib, 6, Me}, B = receive Rb -> Rb end,
|
|
Srv ! {fib, 7, Me}, C = receive Rc -> Rc end,
|
|
Srv ! {fib, 8, Me}, D = receive Rd -> Rd end,
|
|
Srv ! stop,
|
|
A + B + C + D"))
|
|
47)
|
|
|
|
;; Verify Fib obeys the recurrence — fib(n) = fib(n-1) + fib(n-2).
|
|
(er-fib-test
|
|
"fib recurrence at n=12"
|
|
(fib-ev
|
|
(str
|
|
er-fib-server-src
|
|
", Me = self(),
|
|
Srv = spawn(FibSrv),
|
|
Srv ! {fib, 10, Me}, A = receive Ra -> Ra end,
|
|
Srv ! {fib, 11, Me}, B = receive Rb -> Rb end,
|
|
Srv ! {fib, 12, Me}, C = receive Rc -> Rc end,
|
|
Srv ! stop,
|
|
C - (A + B)"))
|
|
0)
|
|
|
|
;; Two clients each get their own answer; main sums the results.
|
|
(er-fib-test
|
|
"two clients sum"
|
|
(fib-ev
|
|
(str
|
|
er-fib-server-src
|
|
", Me = self(),
|
|
Srv = spawn(FibSrv),
|
|
Client = fun (N) ->
|
|
spawn(fun () ->
|
|
Srv ! {fib, N, self()},
|
|
receive R -> Me ! {result, R} end
|
|
end)
|
|
end,
|
|
Client(7),
|
|
Client(9),
|
|
{result, A} = receive M1 -> M1 end,
|
|
{result, B} = receive M2 -> M2 end,
|
|
Srv ! stop,
|
|
A + B"))
|
|
47)
|
|
|
|
;; Trace queries via io-buffer.
|
|
(er-fib-test
|
|
"trace fib 0..6"
|
|
(do
|
|
(er-io-flush!)
|
|
(fib-ev
|
|
(str
|
|
er-fib-server-src
|
|
", Me = self(),
|
|
Srv = spawn(FibSrv),
|
|
Ask = fun (N) -> Srv ! {fib, N, Me}, receive R -> io:format(\"~p \", [R]) end end,
|
|
Ask(0), Ask(1), Ask(2), Ask(3), Ask(4), Ask(5), Ask(6),
|
|
Srv ! stop,
|
|
done"))
|
|
(er-io-buffer-content))
|
|
"0 1 1 2 3 5 8 ")
|
|
|
|
(define
|
|
er-fib-test-summary
|
|
(str "fib " er-fib-test-pass "/" er-fib-test-count))
|