tar-extension.scm 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. ;;; Disarchive
  2. ;;; Copyright © 2020, 2021 Timothy Sample <samplet@ngyro.com>
  3. ;;;
  4. ;;; This file is part of Disarchive.
  5. ;;;
  6. ;;; Disarchive is free software: you can redistribute it and/or modify
  7. ;;; it under the terms of the GNU General Public License as published by
  8. ;;; the Free Software Foundation, either version 3 of the License, or
  9. ;;; (at your option) any later version.
  10. ;;;
  11. ;;; Disarchive is distributed in the hope that it will be useful,
  12. ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. ;;; GNU General Public License for more details.
  15. ;;;
  16. ;;; You should have received a copy of the GNU General Public License
  17. ;;; along with Disarchive. If not, see <http://www.gnu.org/licenses/>.
  18. (use-modules (disarchive kinds tar-extension)
  19. (disarchive kinds zero-string)
  20. (disarchive serialization)
  21. (quickcheck)
  22. (quickcheck arbitrary)
  23. (quickcheck property)
  24. (rnrs bytevectors)
  25. (srfi srfi-64)
  26. (tests kinds))
  27. (define (bytevector-take bv k)
  28. (let ((bv* (make-bytevector k)))
  29. (bytevector-copy! bv 0 bv* 0 k)
  30. bv*))
  31. (configure-quickcheck
  32. ;; Perform 1000 tests per property...
  33. (stop? (lambda (success-count _)
  34. (>= success-count 1000)))
  35. ;; ...over input sizes from 0 to 100.
  36. (size (lambda (test-number)
  37. (if (zero? test-number) 0 (1+ (quotient test-number 10))))))
  38. (test-begin "kinds--tar-extension")
  39. (test-equal "Reads a single pax record"
  40. `(("foo" . "bar"))
  41. (decode-pax-records (string->utf8 "11 foo=bar\n")))
  42. (test-equal "Reads multiple pax records"
  43. `(("foo" . "bar") ("baz" . "quux"))
  44. (decode-pax-records (string->utf8 "11 foo=bar\n12 baz=quux\n")))
  45. (test-equal "Gives up on malformed pax record"
  46. (list (string->utf8 "123abc"))
  47. (decode-pax-records (string->utf8 "123abc")))
  48. (test-equal "Reads until malformed pax record"
  49. `(("foo" . "bar") ,(string->utf8 "123abc"))
  50. (decode-pax-records (string->utf8 "11 foo=bar\n123abc")))
  51. (test-equal "Reads a GNU record"
  52. `(("path" . ,(make-zero-string "foo" "")))
  53. (decode-gnu-path (string->utf8 "foo\x00")))
  54. (test-assert "[prop] Reading pax is reversible"
  55. (quickcheck
  56. (property ((bv $bytevector))
  57. (let* ((records (decode-pax-records bv))
  58. (bv* (encode-pax-records records)))
  59. (equal? bv bv*)))))
  60. (test-assert "[prop] Reading pax is reversible (limited)"
  61. (quickcheck
  62. (property ((bv $bytevector)
  63. (n $byte))
  64. (let* ((limit (max 0 (- (bytevector-length bv)
  65. (quotient n 8))))
  66. (records (decode-pax-records bv 0 limit))
  67. (bv* (encode-pax-records records))
  68. (len (min limit (bytevector-length bv))))
  69. (equal? (bytevector-take bv len) bv*)))))
  70. (test-assert "[prop] Reading pax records produces a valid result"
  71. (quickcheck
  72. (property ((bv $bytevector))
  73. (valid-pax-records? (decode-pax-records bv)))))
  74. (test-assert "[prop] Reading a GNU path is reversible"
  75. (quickcheck
  76. (property ((bv $bytevector))
  77. (let* ((records (decode-gnu-path bv))
  78. (bv* (make-bytevector (bytevector-length bv))))
  79. (encode-gnu-path records bv*)
  80. (equal? bv bv*)))))
  81. (test-assert "[prop] Reading a GNU path produces a valid result"
  82. (quickcheck
  83. (property ((bv $bytevector))
  84. (valid-gnu-path? (decode-gnu-path bv)))))
  85. (test-assert "[prop] Writing a GNU path is reversible"
  86. (quickcheck
  87. (property ((records $gnu-path))
  88. (test-when (valid-gnu-path? records)
  89. (equal? records
  90. (decode-gnu-path (encode-gnu-path records)))))))
  91. (test-assert "[prop] Reading a GNU linkpath is reversible"
  92. (quickcheck
  93. (property ((bv $bytevector))
  94. (let* ((records (decode-gnu-linkpath bv))
  95. (bv* (make-bytevector (bytevector-length bv))))
  96. (encode-gnu-linkpath records bv*)
  97. (equal? bv bv*)))))
  98. (test-assert "[prop] Reading a GNU linkpath produces a valid result"
  99. (quickcheck
  100. (property ((bv $bytevector))
  101. (valid-gnu-linkpath? (decode-gnu-linkpath bv)))))
  102. (test-assert "[prop] Writing a GNU linkpath is reversible"
  103. (quickcheck
  104. (property ((records $gnu-linkpath))
  105. (test-when (valid-gnu-linkpath? records)
  106. (equal? records
  107. (decode-gnu-linkpath (encode-gnu-linkpath records)))))))
  108. ;; Make the test sizes smaller for these two slow tests.
  109. (configure-quickcheck
  110. (size (lambda (test-number)
  111. (if (zero? test-number)
  112. 0
  113. (1+ (quotient test-number 100))))))
  114. (test-assert "[prop] Writing (simple) pax records is reversible"
  115. ;; The way that pax records use raw bytevectors as an escape hatch
  116. ;; makes testing the reversibility of writing very difficult. We get
  117. ;; away with it for binary strings because it's easy to check if a
  118. ;; bytevector is valid UTF-8. Here, we would have to try and rewrite
  119. ;; 'get-pax-record', which is just too much work. Hence, we cheat by
  120. ;; only checking non-bytevector pax records.
  121. (quickcheck
  122. (property ((records $non-bytevector-pax-records))
  123. (test-when (valid-pax-records? records)
  124. (equal? records
  125. (decode-pax-records (encode-pax-records records)))))))
  126. (test-assert "[prop] Serializing pax records is reversible"
  127. (quickcheck
  128. (property ((records $pax-records))
  129. (test-when (valid-pax-records? records)
  130. (equal? records (serdeser -pax-records- records))))))
  131. (test-end "kinds--tar-extension")