Skip to content

Commit 3f88e87

Browse files
committed
find some bugs with good testing
1 parent 0865b44 commit 3f88e87

File tree

4 files changed

+91
-11
lines changed

4 files changed

+91
-11
lines changed

test/basic.lisp

+28-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
(in-package #:thespis/test/basic)
44

55
(deftest test-counter ()
6+
"The most basic stateful usage."
67
(define-actor counter ((c 0)) (increment)
78
(incf c increment))
89

@@ -19,6 +20,7 @@
1920
(close-actor actor)))
2021

2122
(deftest test-lambda-rest ()
23+
"Make sure lambda lists work."
2224
(define-actor square-summer ((c 0)) (&rest args)
2325
(incf c (apply #'+ (mapcar (lambda (x) (* x x)) args))))
2426

@@ -28,6 +30,7 @@
2830
(close-actor actor)))
2931

3032
(deftest test-lambda-key ()
33+
"Make sure lambda lists work."
3134
(define-actor point-actor ((x 0) (y 0) (z 0))
3235
(&key (dx 0) (dy 0) (dz 0))
3336
(list
@@ -43,6 +46,7 @@
4346
(close-actor actor)))
4447

4548
(deftest test-multiple-values ()
49+
"Return multiple values on join."
4650
(define-actor multivaluer ((prev 0)) (next)
4751
(multiple-value-prog1 (values prev next)
4852
(setf prev next)))
@@ -55,6 +59,7 @@
5559
(is (equal '(2 1) (multiple-value-list (join-actor actor))))))
5660

5761
(deftest test-pong ()
62+
"More complicated test, could be cleaner using the registry."
5863
(let (pinger ponger (result 0))
5964
(define-actor pinger () (c)
6065
(incf result)
@@ -77,6 +82,7 @@
7782
(is (= 11 result))))
7883

7984
(deftest test-self ()
85+
"Make sure the actor can see itself."
8086
(let ((result 0))
8187
(define-actor selfish-counter () ()
8288
(incf result)
@@ -90,6 +96,7 @@
9096
(is (= result 11)))))
9197

9298
(deftest test-error-handling ()
99+
"Custom error handling."
93100
(define-actor failer () (x)
94101
(/ 1 x))
95102

@@ -101,44 +108,61 @@
101108
(close-actor actor)))
102109

103110
(deftest test-closed-actor ()
111+
"Sending messages to a closed actor signals an error."
104112
(define-actor closer () (x)
105113
x)
106114

107115
(let ((actor (closer)))
108116
(close-actor actor)
109-
(handler-case (send actor 'x)
110-
(error (c) (is (typep c 'simple-error))))))
117+
(signals simple-error
118+
(send actor 'x))))
111119

112120
(deftest test-redefine-actor ()
121+
"Actors can change behavior while they are running."
113122
(define-actor counter ((c 0)) (increment)
114123
(incf c increment))
115124

116125
(let ((actor (counter)))
117126
(ask actor 1)
127+
118128
(define-actor counter ((c 0)) (increment)
119129
(incf c (1- increment)))
130+
120131
(send actor 3)
121132
(is (= 3 (ask actor 1)))
133+
122134
(define-actor counter ((c 32)) (increment times)
123135
(incf c (* times increment)))
136+
124137
(is (= 10 (ask actor 1 7)))
125138
(close-actor actor)))
126139

127140
(deftest test-registry ()
141+
"Make sure the global registry works."
128142
(define-actor counter ((c 0)) (increment)
129143
(incf c increment))
130144

131145
(counter :name :my-counter)
132146
(send :my-counter 1)
133147
(is (= 3 (ask :my-counter 2)))
134-
(close-actor :my-counter))
148+
(join-actor (close-actor :my-counter)))
135149

136150
(deftest test-close-and-join ()
151+
"Make sure we can join globally registered actors after we close them."
137152
(define-actor counter ((c 0)) (increment)
138153
(incf c increment))
139154

140155
(counter :name :my-counter)
141156
(send :my-counter 1)
142157
(is (= 3 (ask :my-counter 2)))
143158
(close-and-join-actors :my-counter)
144-
(is (eql nil (gethash :my-counter *registry*))))
159+
(is (null (gethash :my-counter *registry*))))
160+
161+
(deftest test-destroy ()
162+
"Make sure destroy works on globally registered actors."
163+
(define-actor echoer () (x) x)
164+
165+
(echoer :name :echoer)
166+
(is (= 1 (ask :echoer 1)))
167+
(destroy-actor :echoer)
168+
(is (null (gethash :echoer *registry*))))

test/dispatcher.lisp

+58-3
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,10 @@
2525

2626
(let ((actor (sleeper :workers 2)))
2727
(dotimes (i 5)
28-
(send (first (thespis::dispatcher-workers actor)) 0.2))
29-
(dotimes (i 20) (sleep 0.01) (send actor 0))
30-
(is (equal '((5 20)) (close-and-join-actors actor)))))
28+
(send (first (thespis::dispatcher-workers actor)) 5))
29+
(dotimes (i 19) (sleep 0.001) (send actor 0))
30+
(is (= 20 (ask actor 0)))
31+
(destroy-actor actor)))
3132

3233
(deftest test-dispatcher-registry ()
3334
"Test registering a dispatcher with a global name."
@@ -53,3 +54,57 @@
5354
(send :my-counter 1)
5455
(send :my-counter 1)
5556
(is (= 6 (reduce #'+ (join-actor (close-actor :my-counter))))))
57+
58+
(deftest test-dispatcher-close-and-join ()
59+
(define-actor counter ((c 0)) (increment)
60+
(incf c increment)
61+
(counter :name :my-counter)
62+
(send :my-counter 1)
63+
(close-and-join-actors :my-counter)
64+
(is (eql nil (gethash :my-counter *registry*)))))
65+
66+
(deftest test-closed-actor ()
67+
"Sending messages to a closed dispatcher signals an error."
68+
(define-actor closer () (x)
69+
x)
70+
71+
(let ((actor (closer :workers 2)))
72+
(close-actor actor)
73+
(signals simple-error
74+
(send actor 'x))))
75+
76+
(deftest test-dispatcher-multiple-values ()
77+
"Return multiple values on join."
78+
(define-actor multivaluer ((prev 0)) (next)
79+
(multiple-value-prog1 (values prev next)
80+
(setf prev next))
81+
82+
(let ((actor (multivaluer :workers 2)))
83+
(send actor 1)
84+
(is (= 2 (length (multiple-value-list (ask actor 2)))))
85+
(is (= 2 (length (multiple-value-list (ask actor 2)))))
86+
(is (= 2 (length (multiple-value-list (ask actor 2)))))
87+
(close-actor actor))))
88+
89+
(deftest test-dispatcher-lambda-key ()
90+
"Make sure lambda lists work."
91+
(define-actor point-actor ((x 0) (y 0) (z 0))
92+
(&key (dx 0) (dy 0) (dz 0))
93+
(list
94+
:x (incf x dx)
95+
:y (incf y dy)
96+
:z (incf z dz)))
97+
98+
(let ((actor (point-actor :workers 2)))
99+
(is (equal '(:x -1 :y 0 :z 3) (ask actor :dx -1 :dz 3)))
100+
(ask actor)
101+
(close-and-join-actors actor)))
102+
103+
(deftest test-dispatcher-destroy ()
104+
"Make sure destroy works on globally registered dispatchers."
105+
(define-actor echoer () (x) x)
106+
107+
(echoer :name :echoer)
108+
(is (= 1 (ask :echoer 1)))
109+
(destroy-actor :echoer)
110+
(is (null (gethash :echoer *registry*))))

test/fuzz.lisp

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
:thespis/test/basic
99
:stream (make-broadcast-stream)))))
1010

11-
(deftest fuzz-dispatcher-tests (&optional (times 8))
11+
(deftest fuzz-dispatcher-tests (&optional (times 4))
1212
"Don't try as many reps here because it is too slow."
1313
(dotimes (i times)
1414
(is (fiasco:run-tests

thespis.lisp

+4-3
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,10 @@
9797
(defgeneric destroy-actor (actor)
9898
(:documentation "Immediately destroy an actor's thread.")
9999
(:method ((actor actor))
100-
(bt2:interrupt-thread (actor-thread actor)
101-
(lambda ()
102-
(signal (make-instance 'unregister)))))
100+
(bt2:interrupt-thread
101+
(actor-thread actor)
102+
(lambda () (signal (make-instance 'unregister))))
103+
(bt2:join-thread (actor-thread actor)))
103104
(:method ((actor dispatcher))
104105
(prog1 (mapcar #'destroy-actor (dispatcher-workers actor))
105106
(remhash (dispatcher-name actor) *registry*)))

0 commit comments

Comments
 (0)