summaryrefslogtreecommitdiff
path: root/tests/decode-tests.lisp
blob: 73fc9d2571ba70281d2462ffe66f453e57cb64f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
;; 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 Lesser General Public LIcense for more details.

;; You should have received a copy of the GNU Lesser General Public LIcense along with
;; eris-cl. If not, see <https://www.gnu.org/licenses/>.


(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 1 :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 1 :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 1 :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))