cml-check.scm 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Mike Sperber
  3. (define-test-suite rendezvous-channels-tests)
  4. (define-test-case channel-1 rendezvous-channels-tests
  5. (let ((channel (make-channel)))
  6. (spawn
  7. (lambda ()
  8. (sleep 500)
  9. (send channel 'message)))
  10. (check (receive channel) => 'message)))
  11. (define-test-case channel-2 rendezvous-channels-tests
  12. (let ((channel (make-channel)))
  13. (spawn
  14. (lambda ()
  15. (send channel 'message)))
  16. (sleep 500)
  17. (check (receive channel) => 'message)))
  18. (define-test-case channel-3 rendezvous-channels-tests
  19. (do ((i 0 (+ 1 i)))
  20. ((= i 100)) ; detect races more reliably
  21. (let ((channel (make-channel)))
  22. (spawn
  23. (lambda ()
  24. (let loop ((i 0))
  25. (if (not (= i 1000))
  26. (begin
  27. (send channel i)
  28. (loop (+ 1 i)))))))
  29. (spawn
  30. (lambda ()
  31. ;; (sleep 500)
  32. (let loop ((i 1000))
  33. (if (not (= i 2000))
  34. (begin
  35. (send channel i)
  36. (loop (+ 1 i)))))))
  37. (let loop ((count 0)
  38. (values '()))
  39. (if (= count 2000)
  40. (check-that values
  41. (is lset= (iota 2000)))
  42. (loop (+ 1 count)
  43. (cons (receive channel) values)))))))
  44. (define-test-case select-1 rendezvous-channels-tests
  45. (let ((channel-1 (make-channel))
  46. (channel-2 (make-channel)))
  47. (spawn
  48. (lambda ()
  49. (let loop ((i 0))
  50. (if (not (= i 1000))
  51. (begin
  52. (send channel-1 i)
  53. ;;(sleep 1000)
  54. (loop (+ 1 i)))))))
  55. (spawn
  56. (lambda ()
  57. ;; (sleep 500)
  58. (let loop ((i 1000))
  59. (if (not (= i 2000))
  60. (begin
  61. (send channel-2 i)
  62. (loop (+ 1 i)))))))
  63. (sleep 500)
  64. (let loop ((count 0)
  65. (values '()))
  66. (if (= count 2000)
  67. (check-that values (is lset= (iota 2000)))
  68. (loop (+ 1 count)
  69. (cons (select (receive-rv channel-1)
  70. (receive-rv channel-2))
  71. values))))))
  72. (define-test-case wrap-1 rendezvous-channels-tests
  73. (let ((channel-1 (make-channel))
  74. (channel-2 (make-channel)))
  75. (spawn
  76. (lambda ()
  77. (let loop ((i 0))
  78. (if (not (= i 1000))
  79. (begin
  80. (send channel-1 i)
  81. ;;(sleep 1000)
  82. (loop (+ 1 i)))))))
  83. (spawn
  84. (lambda ()
  85. ;; (sleep 500)
  86. (let loop ((i 1000))
  87. (if (not (= i 2000))
  88. (begin
  89. (send channel-2 i)
  90. (loop (+ 1 i)))))))
  91. (sleep 500)
  92. (let loop ((count 0)
  93. (values '()))
  94. (if (= count 2000)
  95. (check-that values (is lset= (iota 2000)))
  96. (let* ((val
  97. (select (wrap (receive-rv channel-1)
  98. (lambda (n)
  99. (cons 1 n)))
  100. (wrap (receive-rv channel-2)
  101. (lambda (n)
  102. (cons 2 n)))))
  103. (chan (car val))
  104. (n (cdr val)))
  105. (if (< n 1000)
  106. (check chan => 1)
  107. (check chan => 2))
  108. (loop (+ 1 count)
  109. (cons n values)))))))
  110. (define (make-rv-notifier rv ack-message nack-message callback)
  111. (with-nack
  112. (lambda (nack)
  113. (spawn
  114. (lambda ()
  115. (sync nack)
  116. (callback nack-message)))
  117. (wrap rv
  118. (lambda (ignore)
  119. (callback ack-message))))))
  120. (define-test-case with-nack-1 rendezvous-channels-tests
  121. (let ((channel-1 (make-channel))
  122. (channel-2 (make-channel))
  123. (message-1 #f)
  124. (message-2 #f))
  125. (spawn
  126. (lambda ()
  127. (sleep 500)
  128. (send channel-1 'ignore)))
  129. (let ((notifier-1
  130. (make-rv-notifier (receive-rv channel-1)
  131. "ch1" "not ch1"
  132. (lambda (message)
  133. (set! message-1 message))))
  134. (notifier-2
  135. (make-rv-notifier (receive-rv channel-2)
  136. "ch2" "not ch2"
  137. (lambda (message)
  138. (set! message-2 message)))))
  139. (select notifier-1 notifier-2)
  140. (sleep 500)
  141. (check message-1 => "ch1")
  142. (check message-2 => "not ch2")
  143. ;; kill off remaining thread
  144. (spawn
  145. (lambda ()
  146. (send channel-2 'ignore)))
  147. (select notifier-1 notifier-2))))
  148. (define-test-case with-nack-2 rendezvous-channels-tests
  149. (let ((channel-1 (make-channel))
  150. (channel-2 (make-channel))
  151. (message-1 #f)
  152. (message-2 #f))
  153. (spawn
  154. (lambda ()
  155. (send channel-1 'ignore)))
  156. (sleep 500)
  157. (let ((notifier-1
  158. (make-rv-notifier (receive-rv channel-1)
  159. "ch1" "not ch1"
  160. (lambda (message)
  161. (set! message-1 message))))
  162. (notifier-2
  163. (make-rv-notifier (receive-rv channel-2)
  164. "ch2" "not ch2"
  165. (lambda (message)
  166. (set! message-2 message)))))
  167. (select notifier-1 notifier-2)
  168. (sleep 500)
  169. (check message-1 => "ch1")
  170. (check message-2 => "not ch2")
  171. ;; kill off remaining thread
  172. (spawn
  173. (lambda ()
  174. (send channel-2 'ignore)))
  175. (select notifier-1 notifier-2))))
  176. (define-test-suite rendezvous-jars-tests)
  177. (define-test-case take rendezvous-jars-tests
  178. (let ((jar (make-jar)))
  179. (jar-put! jar 1)
  180. (check (jar-take jar) => 1)
  181. (jar-put! jar 2)
  182. (check (jar-take jar) => 2)
  183. (jar-put! jar 3)
  184. (check (jar-take jar) => 3)
  185. (jar-put! jar 4)
  186. (check (jar-take jar) => 4)))
  187. (define-test-case select rendezvous-jars-tests
  188. (let ((jar-1 (make-jar))
  189. (jar-2 (make-jar))
  190. (result-channel (make-channel)))
  191. (spawn
  192. (lambda ()
  193. (let ((contents (select (jar-take-rv jar-1)
  194. (jar-take-rv jar-2))))
  195. (send result-channel (cons 1 contents)))))
  196. (spawn
  197. (lambda ()
  198. (let ((contents (select (jar-take-rv jar-1)
  199. (jar-take-rv jar-2))))
  200. (send result-channel (cons 2 contents)))))
  201. (spawn
  202. (lambda ()
  203. (let ((contents (select (jar-take-rv jar-1)
  204. (jar-take-rv jar-2))))
  205. (send result-channel (cons 3 contents)))))
  206. (sleep 500)
  207. (jar-put! jar-1 17)
  208. (jar-put! jar-2 23)
  209. (let ((res-1 (receive result-channel))
  210. (res-2 (receive result-channel))
  211. (ensure
  212. (lambda (res)
  213. (check-that res
  214. (member-of '((1 . 17)
  215. (2 . 17)
  216. (3 . 17)
  217. (1 . 23)
  218. (2 . 23)
  219. (3 . 23)))))))
  220. ;; kill off remaining thread
  221. (jar-put! jar-1 #f)
  222. (receive result-channel)
  223. (ensure res-1)
  224. (ensure res-2))))
  225. (define-test-case multi rendezvous-jars-tests
  226. (let ((jar-1 (make-jar 1))
  227. (jar-2 (make-jar 2)))
  228. (spawn
  229. (lambda ()
  230. (let loop ((i 1))
  231. (if (< i 1000)
  232. (begin
  233. (check (jar-take jar-1) => (cons 1 (- i 1)))
  234. (jar-put! jar-2 (cons 2 i))
  235. (loop (+ i 1)))))))
  236. (jar-put! jar-2 (cons 2 0))
  237. (let loop ((i 0))
  238. (if (< i 1000)
  239. (begin
  240. (check (jar-take jar-2) => (cons 2 i))
  241. (jar-put! jar-1 (cons 1 i))
  242. (loop (+ i 1)))))))
  243. (define-test-suite rendezvous-placeholders-tests)
  244. (define-test-case placeholder-1 rendezvous-placeholders-tests
  245. (let ((placeholder-1 (make-placeholder))
  246. (placeholder-2 (make-placeholder))
  247. (results (make-channel)))
  248. (spawn
  249. (lambda ()
  250. (let ((contents (select (placeholder-value-rv placeholder-1)
  251. (placeholder-value-rv placeholder-1))))
  252. (send results contents))))
  253. (spawn
  254. (lambda ()
  255. (let ((contents (select (placeholder-value-rv placeholder-1)
  256. (placeholder-value-rv placeholder-2))))
  257. (send results contents))))
  258. (spawn
  259. (lambda ()
  260. (let ((contents (select (placeholder-value-rv placeholder-1)
  261. (placeholder-value-rv placeholder-2))))
  262. (send results contents))))
  263. (sleep 500)
  264. (placeholder-set! placeholder-1 17)
  265. (placeholder-set! placeholder-2 23)
  266. (let ((vals (list (receive results) (receive results) (receive results))))
  267. (check (lset<= vals '(17 23))))))
  268. (define-test-suite with-nack-tests)
  269. (define-test-case dummy with-nack-tests
  270. (let ((ch (make-channel)))
  271. (spawn
  272. (lambda ()
  273. (send ch 23)))
  274. (check
  275. (sync
  276. (with-nack (lambda (nack)
  277. (receive-rv ch))))
  278. => 23)))
  279. (define-test-case dummy-guard with-nack-tests
  280. (let ((ch (make-channel)))
  281. (spawn
  282. (lambda ()
  283. (send ch 23)))
  284. (check
  285. (sync
  286. (guard (lambda ()
  287. (with-nack (lambda (nack)
  288. (receive-rv ch))))))
  289. => 23)))
  290. (define-test-case no-nack-1 with-nack-tests
  291. (let ((ch (make-channel))
  292. (no #f))
  293. (spawn
  294. (lambda ()
  295. (sleep 500)
  296. (send ch 23)))
  297. (sync
  298. (wrap (with-nack (lambda (nack)
  299. (spawn (lambda ()
  300. (sync nack)
  301. (set! no #t)))
  302. (receive-rv ch)))
  303. (lambda (value)
  304. (check value => 23))))
  305. (sleep 500)
  306. (check-that no (is-false))))
  307. (define-test-case no-nack-2 with-nack-tests
  308. (let ((ch (make-channel))
  309. (no #f))
  310. (spawn
  311. (lambda ()
  312. (sync
  313. (wrap (with-nack (lambda (nack)
  314. (spawn (lambda ()
  315. (sync nack)
  316. (set! no 1)))
  317. (with-nack (lambda (nack)
  318. (spawn (lambda ()
  319. (sync nack)
  320. (set! no 2)))
  321. (with-nack (lambda (nack)
  322. (spawn (lambda ()
  323. (sync nack)
  324. (set! no 3)))
  325. (receive-rv ch)))))))
  326. (lambda (value)
  327. (check value => 10))))))
  328. (sleep 10)
  329. (send ch 10)
  330. (sleep 200)
  331. (check no => #f)))
  332. (define-test-case nack-1 with-nack-tests
  333. (let ((ch (make-channel))
  334. (results (make-channel)))
  335. (spawn
  336. (lambda ()
  337. (select
  338. (receive-rv ch)
  339. (wrap (with-nack (lambda (nack)
  340. (spawn (lambda ()
  341. (sync nack)
  342. (send results 1)))
  343. (with-nack (lambda (nack)
  344. (spawn (lambda ()
  345. (sync nack)
  346. (send results 2)))
  347. (with-nack (lambda (nack)
  348. (spawn (lambda ()
  349. (sync nack)
  350. (send results 3)))
  351. (send-rv ch 'jo)))))))
  352. (lambda (value)
  353. (check #f))))))
  354. (sleep 10)
  355. (send ch 10)
  356. (let ((vals (list (receive results) (receive results) (receive results))))
  357. (check-that vals (is lset= '(1 2 3))))))
  358. (define-test-case no-nack-3 with-nack-tests
  359. (let ((ch (make-channel))
  360. (results (make-channel)))
  361. (spawn
  362. (lambda ()
  363. (select
  364. (send-rv ch 'tralala)
  365. (with-nack (lambda (nack)
  366. (spawn (lambda ()
  367. (sync nack)
  368. (send results 1)))
  369. (guard (lambda ()
  370. (with-nack (lambda (nack)
  371. (spawn (lambda ()
  372. (sync nack)
  373. (send results 2)))
  374. (send-rv ch 'jo-man)))))))
  375. (send-rv ch 'dudel-di-dudel))))
  376. (sleep 10)
  377. (check-that (receive ch) (member-of '(tralala dudel-di-dudel)))
  378. (sleep 200)
  379. (check-that (list (receive results) (receive results))
  380. (is lset= '(1 2)))))
  381. (define-test-case nack-2 with-nack-tests
  382. (let* ((ch-1 (make-channel))
  383. (ch-2 (make-channel))
  384. (rv-1 (receive-rv ch-1))
  385. (rv-2 (receive-rv ch-2))
  386. (results (make-channel)))
  387. (spawn
  388. (lambda ()
  389. (select
  390. (wrap (with-nack (lambda (nack)
  391. (choose
  392. (with-nack (lambda (nack)
  393. (spawn (lambda ()
  394. (sync nack)
  395. (send results 'nack-1)))
  396. rv-1))
  397. (with-nack (lambda (nack)
  398. (spawn (lambda ()
  399. (send results 'nack-2)))
  400. rv-2))
  401. rv-1)))
  402. (lambda (value)
  403. (send results 'rv-1)))
  404. (wrap rv-2
  405. (lambda (value)
  406. (send results 'rv-2))))))
  407. (sleep 10)
  408. (send ch-1 'jo)
  409. (sleep 200)
  410. (check-that
  411. (list (receive results) (receive results) (receive results))
  412. (is lset= '(nack-1 nack-2 rv-1)))))
  413. (define (make-channels channels)
  414. (let loop ((res '()) (i channels))
  415. (if (= i 0)
  416. res
  417. (loop (cons (cons i (make-channel)) res) (- i 1)))))
  418. (define-test-case nack-3 with-nack-tests
  419. (let* ((channel-count 10)
  420. (channels (make-channels channel-count))
  421. (rvs (map (lambda (pair)
  422. (cons (car pair) (receive-rv (cdr pair))))
  423. channels))
  424. (results (make-channel)))
  425. (spawn
  426. (lambda ()
  427. (let ((select-rvs (map (lambda (rv)
  428. (wrap
  429. (with-nack
  430. (lambda (another-rv)
  431. (spawn (lambda ()
  432. (sync another-rv)))
  433. (cdr rv)))
  434. (lambda (val)
  435. (send results val))))
  436. rvs)))
  437. (let loop ()
  438. (apply select select-rvs)
  439. (loop)))))
  440. (sleep 50)
  441. (let loop ((channels channels))
  442. (if (not (null? channels))
  443. (let ((channel-no (car (car channels)))
  444. (channel (cdr (car channels))))
  445. (send channel channel-no)
  446. (sleep 100)
  447. (check (receive results) => channel-no)
  448. (loop (cdr channels)))))))
  449. (define-test-suite cml-tests
  450. (rendezvous-channels-tests
  451. rendezvous-jars-tests
  452. rendezvous-placeholders-tests
  453. with-nack-tests
  454. ))