;; This file is part of eris-cl. ;; Copyright (C) 2022 Piotr SzarmaƄski ;; eris-cl is free software: you can redistribute it and/or modify it under the ;; terms of the GNU Lesser General Public License as published by the Free ;; Software Foundation, either version 3 of the License, or (at your option) any ;; later version. ;; eris-cl is distributed in the hope that it will be useful, but WITHOUT ANY ;; WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR ;; A PARTICULAR PURPOSE. See the GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License along with ;; eris-cl. If not, see . (in-package :eris/test) (def-suite* decoding-tests :in eris-tests) (defvar *table* nil) (defvar *stream* nil) (defun hashtable-encode (block ref) (setf (gethash ref *table*) (copy-seq block)) block) (defun hashtable-decode (ref) (copy-seq (gethash ref *table*))) (defmacro assert-array-decode (array block-size) `(let* ((*table* (make-hash-table :test #'equalp)) (array ,array) (read-capability (eris-encode array ,block-size #'hashtable-encode)) (decoded-array (make-array (length array) :element-type '(unsigned-byte 8))) (stream (eris-decode read-capability #'hashtable-decode))) (stream-read-sequence stream decoded-array 0 (length decoded-array)) (is (equalp decoded-array array)) (setf (stream-file-position stream) 0) (is (equalp array (alexandria:read-stream-content-into-byte-vector stream))))) (defmacro assert-bytes-read (array block-size bytes-read-list) `(let* ((*table* (make-hash-table :test #'equalp)) (array ,array) (read-capability (eris-encode array ,block-size #'hashtable-encode)) (decoded-array (make-array (length array) :element-type '(unsigned-byte 8))) (stream (eris-decode read-capability #'hashtable-decode))) (is (equalp ',bytes-read-list (loop with buf = (make-array 1024 :element-type '(unsigned-byte 8)) with s = (length buf) for i = 0 then (incf i) for bytes = (read-sequence buf stream) collect bytes if (< bytes s) do (if (zerop bytes) (loop-finish) (progn (replace decoded-array buf :start1 (* i s) :end1 (length decoded-array)) (loop-finish))) else do (replace decoded-array buf :start1 (* i s))))))) (defmacro assert-bytes-read-4096 (array block-size bytes-read-list) `(let* ((*table* (make-hash-table :test #'equalp)) (array ,array) (read-capability (eris-encode array ,block-size #'hashtable-encode)) (decoded-array (make-array (length array) :element-type '(unsigned-byte 8))) (stream (eris-decode read-capability #'hashtable-decode))) (is (equalp ',bytes-read-list (loop with buf = (make-array 4096 :element-type '(unsigned-byte 8)) with s = (length buf) for i = 0 then (incf i) for bytes = (read-sequence buf stream) collect bytes if (< bytes s) do (if (zerop bytes) (loop-finish) (progn (replace decoded-array buf :start1 (* i s) :end1 (length decoded-array)) (loop-finish))) else do (replace decoded-array buf :start1 (* i s))))))) (test simple-decoding-1kib (assert-array-decode (make-octets 1 :element 1) 1024) (assert-array-decode (make-octets 1023 :element 2) 1024) (assert-array-decode (make-octets 1024 :element 3) 1024) (assert-array-decode (make-octets 1025 :element 4) 1024) (assert-array-decode (make-octets 2049 :element 5) 1024) (assert-array-decode (make-octets 4097 :element 5) 1024) (assert-array-decode (make-octets 16383 :element 6) 1024) (assert-array-decode (make-octets 16384 :element 7) 1024) (assert-array-decode (make-octets 16385 :element 8) 1024) (assert-array-decode (make-octets 32767 :element 9) 1024) (assert-array-decode (make-octets 32768 :element 10) 1024) (assert-array-decode (make-octets 131072 :element 11) 1024) (for-all ((buffer (gen-buffer :length (gen-integer :min 0 :max 40000)))) (assert-array-decode buffer 1024))) (test simple-decoding-32kib (assert-array-decode (make-octets 1 :element 2) 32kib) (assert-array-decode (make-octets 32767 :element 2) 32kib) (assert-array-decode (make-octets 32768 :element 2) 32kib) (assert-array-decode (make-octets 32769 :element 2) 32kib) (assert-array-decode (make-octets 32768 :element 2) 32kib) (assert-array-decode (make-octets 16777216 :element 2) 32kib) (for-all ((buffer (gen-buffer :length (gen-integer :min 0 :max 70000)))) (assert-array-decode buffer 32kib))) (test proper-return-values (assert-bytes-read (make-octets 1 :element 3) 1024 (1)) (assert-bytes-read (make-octets 1025 :element 3) 1024 (1024 1)) (assert-bytes-read (make-octets 16381 :element 3) 1024 (1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1021)) (assert-bytes-read (make-octets 16383 :element 3) 1024 (1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1023))) ;; random access tests (defmacro assert-random-access (array block-size buffer-pos pos array-at-pos) `(let* ((*table* (make-hash-table :test #'equalp)) (array ,array) (read-capability (eris-encode array ,block-size #'hashtable-encode)) (buf (make-array 24 :element-type '(unsigned-byte 8))) (stream (eris-decode read-capability #'hashtable-decode))) (setf (stream-file-position stream) ,pos) (stream-read-sequence stream buf 0 (length buf)) (is (and (eql (eris::pos (eris::buffer stream)) (+ 24 ,buffer-pos)) (eql (file-position stream) (+ 24 ,pos)) (equalp buf ,array-at-pos))))) (defmacro assert-random-access-condition (array block-size pos condition) `(let* ((*table* (make-hash-table :test #'equalp)) (array ,array) (read-capability (eris-encode array ,block-size #'hashtable-encode)) (stream (eris-decode read-capability #'hashtable-decode))) (signals ,condition (setf (stream-file-position stream) ,pos)))) (test random-access-eof-1kib (assert-random-access-condition (make-octets 512 :element 1) 1024 512 eof) (assert-random-access-condition (make-octets 512 :element 1) 1024 513 eof) (assert-random-access-condition (make-octets 512 :element 1) 1024 1025 eof) (assert-random-access-condition (make-octets 512 :element 1) 1024 2047 eof) (assert-random-access-condition (make-octets 512 :element 1) 1024 2048 eof) (assert-random-access-condition (make-octets 1024 :element 1) 1024 1024 eof) (assert-random-access-condition (make-octets 1024 :element 1) 1024 1512 eof) (assert-random-access-condition (make-octets 1024 :element 1) 1024 2048 eof) (assert-random-access-condition (make-octets 1024 :element 1) 1024 200000 eof)) (test random-access-eof-32kib (assert-random-access-condition (make-octets 10000 :element 1) 32kib 10000 eof) (assert-random-access-condition (make-octets 10000 :element 1) 32kib 10001 eof) (assert-random-access-condition (make-octets 10000 :element 1) 32kib (* 1024 128) eof) (assert-random-access-condition (make-octets 40000 :element 1) 32kib (* 1024 128) eof)) (test random-access-1kib (assert-random-access (make-octet-array-with-loop (loop for i from 0 to 1022 collect (mod i 256))) 1024 0 0 (make-octet-array-with-loop (loop for i from 0 to 23 collect i))) (assert-random-access (make-octet-array-with-loop (loop for i from 0 to 1022 collect (mod i 256))) 1024 513 513 (make-octet-array-with-loop (loop for i from 1 to 24 collect i))) (assert-random-access (make-octet-array-with-loop (loop for i from 0 to 2048 collect (mod i 256))) 1024 513 513 (make-octet-array-with-loop (loop for i from 1 to 24 collect i))) (assert-random-access (make-octet-array-with-loop (loop for i from 0 to 2048 collect (mod i 256))) 1024 24 1048 (make-octet-array-with-loop (loop for i from 24 to 47 collect i)))) (defmacro assert-length (array block-size) `(let* ((*table* (make-hash-table :test #'equalp)) (array ,array) (read-capability (eris-encode array ,block-size #'hashtable-encode)) (decoded-array (make-array (length array) :element-type '(unsigned-byte 8))) (stream (eris-decode read-capability #'hashtable-decode))) (stream-read-sequence stream decoded-array 0 (length decoded-array)) (is (equalp (length array) (eof stream))))) (test check-eof-length (assert-length (make-array 512 :element-type '(unsigned-byte 8) :initial-element 2) 1024) (assert-length (make-array 1023 :element-type '(unsigned-byte 8) :initial-element 2) 1024) (assert-length (make-array 1024 :element-type '(unsigned-byte 8) :initial-element 2) 1024) (assert-length (make-array 2048 :element-type '(unsigned-byte 8) :initial-element 2) 1024) (assert-length (make-array 16383 :element-type '(unsigned-byte 8) :initial-element 2) 1024) (assert-length (make-array 16384 :element-type '(unsigned-byte 8) :initial-element 2) 1024) (for-all ((buffer (gen-buffer :length (gen-integer :min 0 :max 40000)))) (assert-length buffer 1024))) (defmacro assert-read-byte (array block-size) `(let* ((*table* (make-hash-table :test #'equalp)) (array ,array) (read-capability (eris-encode array ,block-size #'hashtable-encode)) (decoded-array (make-array (length array) :element-type '(unsigned-byte 8) :fill-pointer 0)) (stream (eris-decode read-capability #'hashtable-decode))) (loop for i = (read-byte stream nil :eof) until (eq i :eof) do (vector-push i decoded-array)) (is (equalp decoded-array array)))) (test check-read-byte (assert-read-byte (make-octets 1 :element 2) 1024) (assert-read-byte (make-octets 512 :element 2) 1024) (assert-read-byte (make-octets 1023 :element 2) 1024) (assert-read-byte (make-octets 1024 :element 2) 1024) (assert-read-byte (make-octets 16383 :element 2) 1024) (assert-read-byte (make-octets 16384 :element 2) 1024) (assert-read-byte (make-octets 1024 :element 2) 32kib) (assert-read-byte (make-octets 32767 :element 2) 32kib) (assert-read-byte (make-octets 32768 :element 2) 32kib) (assert-read-byte (make-octets 64000 :element 2) 32kib)) (defmacro assert-read-byte-error (array block-size) `(let* ((*table* (make-hash-table :test #'equalp)) (array ,array) (read-capability (eris-encode array ,block-size #'hashtable-encode)) (stream (eris-decode read-capability #'hashtable-decode))) (signals end-of-file (loop for i = (read-byte stream t) for n = 0 then (incf n) until (eql n (length array)))))) (test read-byte-eof (assert-read-byte-error (make-octets 1 :element 2) 1024) (assert-read-byte-error (make-octets 1024 :element 2) 1024) (assert-read-byte-error (make-octets 16383 :element 2) 1024) (assert-read-byte-error (make-octets 1024 :element 2) 32kib) (assert-read-byte-error (make-octets 32767 :element 2) 32kib) (assert-read-byte-error (make-octets 32768 :element 2) 32kib))