cml-check.scm 12 KB

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