luv

Workshop wiki

application-lifecycle-tests.lisp

hal/application-lifecycle-tests.lisp

system luv/test · 12 definitions · on GitHub

in-package#:luv.tests
deftestrelease-report-attempts-every-step-in-source-order
let
eventsnil
conditionnil
handler-case
luv:with-release-report
luv:releasing:first
setfevents
appendevents'
:first
error"first release failure"
luv:releasing:second
setfevents
appendevents'
:second
luv:releasing:third
setfevents
appendevents'
:third
error"third release failure"
luv:release-error
failure
setfconditionfailure
ok
equal'
:first:second:third
events
ok
typepcondition'luv:release-error
ok
equal'
:first:third
mapcar#'luv:release-failure-name
luv:release-error-failurescondition
ok
every
lambda
failure
typep
luv:release-failure-conditionfailure
'error
luv:release-error-failurescondition
deftestrelease-unwind-preserves-primary-and-reports-all-cleanup-failures
let
primary
make-condition'simple-error:format-control"primary body failure"
caughtnil
warningnil
eventsnil
handler-bind
luv:release-warning
lambda
condition
setfwarningcondition
muffle-warningcondition
handler-case
luv:unwind-protect-releasing
errorprimary
luv:releasing:one
setfevents
appendevents'
:one
error"cleanup one failed"
luv:releasing:two
setfevents
appendevents'
:two
luv:releasing:three
setfevents
appendevents'
:three
error"cleanup three failed"
error
condition
setfcaughtcondition
ok
eqprimarycaught
ok
equal'
:one:two:three
events
ok
typepwarning'luv:release-warning
ok
eqprimary
luv:release-warning-primary-conditionwarning
ok
equal'
:one:three
mapcar#'luv:release-failure-name
luv:release-warning-failureswarning
deftestnormal-release-unwind-signals-cleanup-failure
let
conditionnil
handler-case
luv:unwind-protect-releasing:body-value
luv:releasing:cleanup
error"normal cleanup failed"
luv:release-error
failure
setfconditionfailure
ok
typepcondition'luv:release-error
ok
equal'
:cleanup
mapcar#'luv:release-failure-name
luv:release-error-failurescondition
deftestcontained-release-failure-is-not-mislabeled-as-primary
let
warningnil
handler-bind
luv:release-warning
lambda
condition
setfwarningcondition
muffle-warningcondition
luv:with-release-warnings
luv:releasing:contained
error"contained release failure"
ok
typepwarning'luv:release-warning
ok
null
luv:release-warning-primary-conditionwarning
ok
equal'
:contained
mapcar#'luv:release-failure-name
luv:release-warning-failureswarning
deftestattachment-publication-finishes-before-a-racing-stop-can-begin
let*
controller
luv:make-stop-controller:name"attachment race"
publication-entered
sb-thread:make-semaphore:count0
continue-publication
sb-thread:make-semaphore:count0
stop-finished
sb-thread:make-semaphore:count0
eventsnil
publication-thread
sb-thread:make-thread
lambda
luv:call-with-running-stop-controllercontroller
lambda
push:publication-enteredevents
sb-thread:signal-semaphorepublication-entered
unless
sb-thread:wait-on-semaphorecontinue-publication:timeout1.0
error"The attachment publication was not released."
push:publication-finishedevents
:attached
unless
sb-thread:wait-on-semaphorepublication-entered:timeout1.0
error"The attachment publication did not begin."
let
stop-thread
sb-thread:make-thread
lambda
unwind-protect
luv:call-with-stop-controllercontroller
lambda
push:stopevents
sb-thread:signal-semaphorestop-finished
sb-thread:signal-semaphorecontinue-publication
ok
eq:attached
sb-thread:join-threadpublication-thread
unless
sb-thread:wait-on-semaphorestop-finished:timeout1.0
error"The racing stop did not finish."
sb-thread:join-threadstop-thread
ok
equal'
:publication-entered:publication-finished:stop
nreverseevents
ok
eq:stopped
defteststopping-controller-rejects-publication-without-running-it
let*
controller
luv:make-stop-controller:name"closed attachment"
stop-entered
sb-thread:make-semaphore:count0
continue-stop
sb-thread:make-semaphore:count0
attachment
list:attachment
called-pnil
conditionnil
stop-thread
sb-thread:make-thread
lambda
luv:call-with-stop-controllercontroller
lambda
sb-thread:signal-semaphorestop-entered
unless
sb-thread:wait-on-semaphorecontinue-stop:timeout1.0
error"The attachment rejection stop was not released."
unless
sb-thread:wait-on-semaphorestop-entered:timeout1.0
error"The attachment rejection stop did not begin."
unwind-protect
handler-case
luv:call-with-running-stop-controllercontroller
lambda
setfcalled-pt
:attachmentattachment
luv:application-attachment-closed
failure
setfconditionfailure
sb-thread:signal-semaphorecontinue-stop
sb-thread:join-threadstop-thread
ok
notcalled-p
ok
eqcontroller
luv:application-attachment-closed-controllercondition
ok
eqattachment
luv:application-attachment-closed-attachmentcondition
ok
eq:stopping
luv:application-attachment-closed-statecondition
deftestterminal-duplicate-attachment-is-an-idempotent-success
let*
controller
luv:make-stop-controller:name"duplicate attachment"
attachment
list:attachment
publication-calls0
membership-calls0
ok
eqattachment
luv:call-with-running-stop-controllercontroller
lambda
incfpublication-calls
:attachmentattachment:already-attached-p
lambda
incfmembership-calls
t
ok
zeroppublication-calls
ok
=1membership-calls
deftestattachment-rejection-is-signalled-outside-the-controller-lock
let*
controller
luv:make-stop-controller:name"reentrant rejection"
conditionnil
observed-statenil
handler-case
luv:call-with-running-stop-controllercontroller
lambda
:wrong
:attachment:late
luv:application-attachment-closed
failure
setfconditionfailure

This takes the same mutex. It can complete only when the semantic rejection was signalled after leaving the gate.

observed-state
ok
eq:stoppedobserved-state
defteststop-controller-runs-one-owner-and-publishes-values
let*
controller
luv:make-stop-controller:name"concurrency probe"
started
sb-thread:make-semaphore:count0
continue
sb-thread:make-semaphore:count0
calls0
owner
sb-thread:make-thread
lambda
multiple-value-list
luv:call-with-stop-controllercontroller
lambda
incfcalls
sb-thread:signal-semaphorestarted
unless
sb-thread:wait-on-semaphorecontinue:timeout1.0
error"stop-controller test owner was not released"
values:stopped42
unless
sb-thread:wait-on-semaphorestarted:timeout1.0
error"stop-controller test owner did not start"
let
waiter
sb-thread:make-thread
lambda
multiple-value-list
luv:call-with-stop-controllercontroller
lambda
error"a concurrent stop body ran twice"
sb-thread:signal-semaphorecontinue
ok
equal'
:stopped42
sb-thread:join-threadowner
ok
equal'
:stopped42
sb-thread:join-threadwaiter
ok
equal'
:stopped42
multiple-value-list
luv:call-with-stop-controllercontroller
lambda
error"a completed stop body ran twice"
ok
=1calls
ok
eq:stopped
ok
equal'
:stopped42
defteststop-controller-publishes-one-failure-to-every-caller
let*
controller
luv:make-stop-controller:name"failure probe"
primary
make-condition'simple-error:format-control"teardown failed"
calls0
first
handler-case
luv:call-with-stop-controllercontroller
lambda
incfcalls
errorprimary
error
condition
condition
second
handler-case
luv:call-with-stop-controllercontroller
lambda
incfcalls
:wrong-result
error
condition
condition
ok
eqprimaryfirst
ok
eqprimarysecond
ok
ok
=1calls
deftestrequested-stop-publishes-its-exact-failure
let*
controller
luv:make-stop-controller:name"async failure probe"
primary
make-condition'simple-error:format-control"async teardown failed"
calls0
multiple-value-bind
began-pworker
luv:request-controlled-stopcontroller
lambda
incfcalls
errorprimary
:thread-name"stop-controller failing test worker"
okbegan-p
ok
typepworker'sb-thread:thread
sb-thread:join-threadworker
let
published
handler-case
error
condition
condition
ok
eqprimarypublished
ok
ok
=1calls
multiple-value-bind
began-pworker
luv:request-controlled-stopcontroller
lambda
:wrong
ok
notbegan-p
ok
nullworker
deftestcanvas-thread-guard-rejects-blocking-but-allows-request
let*
forbidden-threadsb-thread:*current-thread*
controller
luv:make-stop-controller:name"canvas-thread probe":blocking-thread-p
lambda
eqsb-thread:*current-thread*forbidden-thread
calls0
ok
eq:running
multiple-value-bind
began-pworker
luv:request-controlled-stopcontroller
lambda
incfcalls
values:done7
:thread-name"stop-controller test worker"
okbegan-p
ok
typepworker'sb-thread:thread
sb-thread:join-threadworker

Reading an already-published result never waits and is safe here.

ok
equal'
:done7
multiple-value-list
ok
=1calls
multiple-value-bind
began-pworker
luv:request-controlled-stopcontroller
lambda
:wrong
ok
notbegan-p
ok
nullworker