update.scm 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. ;; This file is part of scheme-GNUnet.
  2. ;; Copyright (C) 2021 GNUnet e.V.
  3. ;;
  4. ;; scheme-GNUnet is free software: you can redistribute it and/or modify it
  5. ;; under the terms of the GNU Affero General Public License as published
  6. ;; by the Free Software Foundation, either version 3 of the License,
  7. ;; or (at your option) any later version.
  8. ;;
  9. ;; scheme-GNUnet is distributed in the hope that it will be useful, but
  10. ;; WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. ;; Affero General Public License for more details.
  13. ;;
  14. ;; You should have received a copy of the GNU Affero General Public License
  15. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. ;;
  17. ;; SPDX-License-Identifier: AGPL-3.0-or-later
  18. (use-modules (gnu gnunet concurrency update)
  19. (srfi srfi-8)
  20. (srfi srfi-11)
  21. (srfi srfi-26)
  22. (fibers operations)
  23. (fibers timers)
  24. (fibers))
  25. (test-begin "update")
  26. ;; Tests without concurrency
  27. (test-equal "make-update result types"
  28. '(#t . #t)
  29. (receive (update update!)
  30. (make-update 0)
  31. (cons (update? update)
  32. (procedure? update!))))
  33. (test-equal "update! and next-update-peek"
  34. '(new #t #t)
  35. (let*-values (((update update!) (make-update 'old))
  36. ((next-update next-update!) (update! 'new)))
  37. (receive (next-update-peeked) (next-update-peek update)
  38. (list (update-value next-update-peeked)
  39. (procedure? next-update!)
  40. (eq? next-update-peeked next-update)))))
  41. (test-eq "no update! and next-update-peek"
  42. #f
  43. (next-update-peek (make-update 0)))
  44. (test-error "update! twice -> &double-update"
  45. &double-update
  46. (receive (next-update next-update!)
  47. (make-update 0)
  48. (next-update! next-update)
  49. (next-update! next-update)))
  50. ;; Tests with operations
  51. ;; Unfortunately, fibers does not not have
  52. ;; a ‘run this operation -- unless it would
  53. ;; block’ procedure, and using a combination
  54. ;; of wrap-operation and sleep-operation/
  55. ;; timer-operation turns out to be racy.
  56. ;;
  57. ;; Our approach:
  58. ;; * if an operation is expected to block,
  59. ;; include a short timer-operation
  60. ;; for testing detecting blocking.
  61. ;; (Short to ensure tests still pass
  62. ;; quickly.)
  63. ;;
  64. ;; A false ‘PASS’ could occassionally
  65. ;; result, but no false ‘FAIL’ will
  66. ;; be created.
  67. ;; * if a test is expected *not* to block,
  68. ;; just perform the operation.
  69. ;;
  70. ;; If the test terminates, it's a PASS,
  71. ;; if it loops forever, that would be a FAIL.
  72. (define expected-blocking-operation
  73. (wrap-operation (sleep-operation 1e-4)
  74. (lambda () 'blocking)))
  75. (test-eq "no update -> blocking next-update"
  76. 'blocking
  77. (perform-operation
  78. (choice-operation
  79. (wrap-operation (wait-for-update-operation (make-update #f))
  80. (lambda (_) 'nonblocking))
  81. expected-blocking-operation)))
  82. (test-eq "updated -> non-blocking next-update"
  83. 'nonblocking
  84. (perform-operation
  85. (receive (update update!)
  86. (make-update 'old)
  87. (update! 'new)
  88. (wrap-operation (wait-for-update-operation update)
  89. (lambda (update) 'nonblocking)))))
  90. (receive (update update!)
  91. (make-update 'old)
  92. (let ((new (update! 'new)))
  93. (test-eq "updated -> correct non-blocking next-update"
  94. new
  95. ;; For unknown reasons, using choice-operation
  96. ;; and blocking-operation leads to a FAIL.
  97. (perform-operation (wait-for-update-operation update)))))
  98. (test-end "update")