Blob


1 ;; test suite for kami
2 ;; Copyright (C) 2021 cage
4 ;; This program is free software: you can redistribute it and/or modify
5 ;; it under the terms of the GNU General Public License as published by
6 ;; the Free Software Foundation, either version 3 of the License, or
7 ;; (at your option) any later version.
9 ;; This program is distributed in the hope that it will be useful,
10 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 ;; GNU General Public License for more details.
14 ;; You should have received a copy of the GNU General Public License
15 ;; along with this program.
16 ;; If not, see [[http://www.gnu.org/licenses/][http://www.gnu.org/licenses/]].
18 (in-package :kami-tests)
20 (defparameter *remote-test-file* "test-file") ; note: missing "/" is intentional
22 (defparameter *remote-test-path* "/test-file")
24 (defparameter *remote-test-path-write* "/dir/subdir/test-file-write")
26 (defparameter *remote-test-path-huge* "/test-file-huge")
28 (defparameter *remote-test-path-contents* (format nil "qwertyuiopasdfghjklòàù è~%"))
30 (alexandria:define-constant +remote-test-path-ovewrwrite-data+ "12" :test #'string=)
32 (defsuite kami-suite (all-suite))
34 (defun start-non-tls-socket (host port)
35 (usocket:socket-connect host
36 port
37 :protocol :stream
38 :element-type +byte-type+))
40 (defun example-mount (&optional (root "/"))
41 (with-open-ssl-stream (stream
42 socket
43 *host*
44 *port*
45 *client-certificate*
46 *certificate-key*)
47 (let ((*messages-sent* '())
48 (root-fid (mount stream root)))
49 (9p-clunk stream root-fid)
50 (read-all-pending-message stream)
51 (9p-attach stream root)
52 (read-all-pending-message stream)
53 t)))
55 (deftest test-mount (kami-suite)
56 (assert-true (ignore-errors (example-mount))))
58 (defun example-walk (path &optional (root "/"))
59 (with-open-ssl-stream (stream
60 socket
61 *host*
62 *port*
63 *client-certificate*
64 *certificate-key*)
66 (let ((*messages-sent* '())
67 (root-fid (mount stream root)))
68 (with-new-fid (path-fid)
69 (9p-walk stream root-fid path-fid path)
70 (read-all-pending-message stream)
71 t))))
73 (deftest test-walk (kami-suite)
74 (assert-true (ignore-errors (example-walk *remote-test-file*))))
76 (defun example-open-path (path &optional (root "/"))
77 (with-open-ssl-stream (stream
78 socket
79 *host*
80 *port*
81 *client-certificate*
82 *certificate-key*)
83 (let ((*messages-sent* '())
84 (root-fid (mount stream root)))
85 (with-new-fid (saved-root-fid)
86 (9p-walk stream root-fid saved-root-fid +nwname-clone+)
87 (open-path stream root-fid path)
88 (read-all-pending-message stream)
89 t))))
91 (deftest test-open-path (kami-suite)
92 (assert-true (ignore-errors (example-open-path *remote-test-path*))))
94 (defun example-read (path &optional (root "/"))
95 (with-open-ssl-stream (stream
96 socket
97 *host*
98 *port*
99 *client-certificate*
100 *certificate-key*)
101 (let ((*messages-sent* ())
102 (*buffer-size* 256)
103 (root-fid (mount stream root)))
104 (with-new-fid (path-fid)
105 (9p-walk stream root-fid path-fid path)
106 (9p-open stream path-fid)
107 (9p-read stream path-fid 0 10)
108 (read-all-pending-message stream)
109 t))))
111 (deftest test-read ((kami-suite) (test-walk))
112 (assert-true (ignore-errors (example-open-path *remote-test-file*))))
114 (defun example-slurp (path &optional (root "/"))
115 (with-open-ssl-stream (stream
116 socket
117 *host*
118 *port*
119 *client-certificate*
120 *certificate-key*)
121 (let ((*messages-sent* ())
122 (*buffer-size* 256)
123 (root-fid (mount stream root)))
124 (babel:octets-to-string (slurp-file stream
125 root-fid path
126 :buffer-size 3)
127 :errorp nil))))
129 (deftest test-slurp-file ((kami-suite) (test-read))
130 (assert-equality #'string=
131 *remote-test-path-contents*
132 (example-slurp *remote-test-path*)))
134 (defun example-write (path &optional (root "/"))
135 (with-open-ssl-stream (stream
136 socket
137 *host*
138 *port*
139 *client-certificate*
140 *certificate-key*)
141 (let* ((*messages-sent* ())
142 (*buffer-size* 256)
143 (root-fid (mount stream root))
144 (fid (open-path stream root-fid path :mode +create-for-read-write+)))
145 (9p-write stream fid 0 *remote-test-path-contents*)
146 (read-all-pending-message stream)
147 t)))
149 (deftest test-write ((kami-suite) (test-open-path test-read))
150 (assert-true (ignore-errors (example-write *remote-test-path-write*))))
152 (defun example-write-2-3 (path &optional (root "/"))
153 (with-open-ssl-stream (stream
154 socket
155 *host*
156 *port*
157 *client-certificate*
158 *certificate-key*)
159 (let* ((*messages-sent* ())
160 (*buffer-size* 256)
161 (root-fid (mount stream root)))
162 (with-new-fid (saved-root-fid)
163 (9p-walk stream root-fid saved-root-fid +nwname-clone+)
164 (let ((fid (open-path stream root-fid path :mode +create-for-read-write+)))
165 (9p-write stream fid 2 +remote-test-path-ovewrwrite-data+)
166 (read-all-pending-message stream)
167 (babel:octets-to-string (slurp-file stream saved-root-fid path)))))))
169 (defun read-entire-file-as-string (path &optional (root "/"))
170 (with-open-ssl-stream (stream
171 socket
172 *host*
173 *port*
174 *client-certificate*
175 *certificate-key*)
176 (let* ((*messages-sent* ())
177 (*buffer-size* 256)
178 (root-fid (mount stream root)))
179 (babel:octets-to-string (slurp-file stream root-fid path)))))
181 (deftest test-example-write-2-3 ((kami-suite) (test-write))
182 (example-write-2-3 *remote-test-path-write*)
183 (let* ((expected-sequence (copy-seq *remote-test-path-contents*))
184 (file-sequence (read-entire-file-as-string *remote-test-path-write*)))
185 (setf (subseq expected-sequence 2 4) +remote-test-path-ovewrwrite-data+)
186 (assert-equality #'string= file-sequence expected-sequence)))
188 (defun example-write-fails (path &optional (root "/"))
189 (with-open-ssl-stream (stream
190 socket
191 *host*
192 *port*
193 *client-certificate*
194 *certificate-key*)
195 (let* ((*messages-sent* ())
196 (*buffer-size* 256)
197 (root-fid (mount stream root))
198 (fid (open-path stream root-fid path :mode +create-for-read-write+)))
199 (9p-write stream fid 0 *remote-test-path-contents*)
200 (read-all-pending-message stream))))
202 (deftest test-write-on-directory-fails ((kami-suite) (test-write))
203 (assert-condition 9p-error (example-write-fails "/")))
205 (defun example-stat (path &optional (root "/"))
206 (with-open-ssl-stream (stream
207 socket
208 *host*
209 *port*
210 *client-certificate*
211 *certificate-key*)
212 (let* ((*messages-sent* ())
213 (*buffer-size* 256)
214 (root-fid (mount stream root))
215 (fid (open-path stream root-fid path :mode +create-for-read+))
216 (results nil))
217 (9p-stat stream fid
218 :callback (lambda (x data)
219 (declare (ignore x))
220 (setf results (decode-rstat data))))
221 (read-all-pending-message stream)
222 results)))
224 (deftest test-stat (kami-suite)
225 (assert-true (ignore-errors (example-stat "/")))
226 (assert-true (ignore-errors (example-stat *remote-test-path*)))
227 (assert-eq :directory
228 (stat-entry-type (example-stat "/")))
229 (assert-eq :file
230 (stat-entry-type (example-stat *remote-test-path*))))
232 (defun example-path-exists (path &optional (root "/"))
233 (with-open-ssl-stream (stream
234 socket
235 *host*
236 *port*
237 *client-certificate*
238 *certificate-key*)
239 (let* ((*messages-sent* ())
240 (root-fid (mount stream root)))
241 (path-exists-p stream root-fid path)
242 (path-exists-p stream root-fid path))))
244 (deftest test-path-exists ((kami-suite) (test-stat))
245 (assert-true (example-path-exists *remote-test-path*))
246 (assert-false (example-path-exists (concatenate 'string *remote-test-path* ".$$$"))))
248 (defun example-create-file (path &optional (root "/"))
249 (with-open-ssl-stream (stream
250 socket
251 *host*
252 *port*
253 *client-certificate*
254 *certificate-key*)
255 (let* ((*messages-sent* ())
256 (root-fid (mount stream root)))
257 (with-new-fid (saved-root-fid)
258 (9p-walk stream root-fid saved-root-fid +nwname-clone+)
259 (9p-create stream root-fid path)
260 (read-all-pending-message stream)
261 (9p-clunk stream root-fid)
262 (open-path stream saved-root-fid path)
263 (read-all-pending-message stream)
264 t))))
266 (alexandria:define-constant +create-file+ "test-file-create" :test #'string=)
268 (defun example-create-directory (path &optional (root "/"))
269 (with-open-ssl-stream (stream
270 socket
271 *host*
272 *port*
273 *client-certificate*
274 *certificate-key*)
275 (let* ((*messages-sent* ())
276 (root-fid (mount stream root)))
277 (create-directory stream root-fid path)
278 t)))
280 (alexandria:define-constant +create-directory+ "test-dir-create" :test #'string=)
282 (defun example-create-path-read-write (path &optional (root "/"))
283 (with-open-ssl-stream (stream
284 socket
285 *host*
286 *port*
287 *client-certificate*
288 *certificate-key*)
289 (let* ((*messages-sent* ())
290 (root-fid (mount stream root))
291 (saved-root-fid (clone-fid stream root-fid))
292 (new-path-fid (create-path stream root-fid path)))
293 (9p-write stream new-path-fid 0 *remote-test-path-contents*)
294 (read-all-pending-message stream)
295 (9p-clunk stream new-path-fid)
296 (read-all-pending-message stream)
297 (babel:octets-to-string (slurp-file stream saved-root-fid path)))))
299 (defun example-create-path (path &optional (root "/"))
300 (with-open-ssl-stream (stream
301 socket
302 *host*
303 *port*
304 *client-certificate*
305 *certificate-key*)
306 (let* ((*messages-sent* ())
307 (root-fid (mount stream root)))
308 (create-path stream root-fid path))))
310 (alexandria:define-constant +create-path-read-write+ "/a/totaly/new/path/new-file" :test #'string=)
312 (alexandria:define-constant +create-path-dir+ "/this/" :test #'string=)
314 (alexandria:define-constant +create-path-file+ "/this-file" :test #'string=)
316 (deftest test-create ((kami-suite) (test-open-path))
317 (assert-true (ignore-errors (example-create-file +create-file+)))
318 (assert-true (ignore-errors (example-create-directory +create-directory+)))
319 (assert-true (ignore-errors (example-create-path +create-path-dir+)))
320 (assert-true (ignore-errors (example-create-path +create-path-file+)))
321 (assert-equality #'string=
322 *remote-test-path-contents*
323 (ignore-errors (example-create-path-read-write +create-path-read-write+))))
325 (deftest test-create-existing-path ((kami-suite) (test-create))
326 (assert-true (ignore-errors (example-create-path +create-path-read-write+))))
328 (defun close-parent-fid (&optional (root "/"))
329 (with-open-ssl-stream (stream
330 socket
331 *host*
332 *port*
333 *client-certificate*
334 *certificate-key*)
335 (let* ((*messages-sent* ())
336 (root-fid (mount stream root)))
337 (with-new-fid (dir-fid)
338 (9p-walk stream root-fid dir-fid "dir")
339 (read-all-pending-message stream)
340 (9p-clunk stream root-fid)
341 (read-all-pending-message stream)
342 (with-new-fid (subdir-fid)
343 (9p-walk stream dir-fid subdir-fid "subdir")
344 (read-all-pending-message stream)
345 (9p-clunk stream dir-fid)
346 (read-all-pending-message stream)
347 (with-new-fid (file-fid)
348 (9p-walk stream subdir-fid file-fid "test-file-write")
349 (read-all-pending-message stream)
350 (9p-clunk stream subdir-fid)
351 (read-all-pending-message stream)
352 (9p-open stream file-fid)
353 (read-all-pending-message stream)
354 t))))))
356 (deftest test-close-parent-fid ((kami-suite) (test-walk))
357 (assert-true (ignore-errors (close-parent-fid))))
359 (defun %remove-path (path &optional (root "/"))
360 (with-open-ssl-stream (stream
361 socket
362 *host*
363 *port*
364 *client-certificate*
365 *certificate-key*)
367 (let* ((*messages-sent* ())
368 (root-fid (mount stream root)))
369 (remove-path stream root-fid path)
370 t)))
372 (deftest test-remove-file ((kami-suite) (test-create-existing-path))
373 (assert-true (ignore-errors (%remove-path +create-path-read-write+))))
375 (defun parent-dir-path (path)
376 (let ((position-backslash (position #\/ path :from-end t :test #'char=)))
377 (subseq path 0 position-backslash)))
379 (deftest test-remove-directory ((kami-suite) (test-remove-file))
380 (assert-true
381 (ignore-errors (%remove-path (parent-dir-path +create-path-read-write+)))))
383 (defun read-dir-same-offset (dir-path &optional (root "/"))
384 (with-open-ssl-stream (stream
385 socket
386 *host*
387 *port*
388 *client-certificate*
389 *certificate-key*)
390 (let* ((*messages-sent* ())
391 (root-fid (mount stream root))
392 (root-fid-cloned (clone-fid stream root-fid))
393 (dir-fid (open-path stream root-fid-cloned dir-path))
394 (res-read-1 nil)
395 (res-read-2 nil))
396 (9p-read stream
397 dir-fid
398 0 10
399 :callback (lambda (x data)
400 (declare (ignore x))
401 (setf res-read-1 data)))
402 (9p-read stream
403 dir-fid
404 0 10
405 :callback (lambda (x data)
406 (declare (ignore x))
407 (setf res-read-2 data)))
408 (read-all-pending-message stream)
409 (not (mismatch res-read-1 res-read-2)))))
411 (defun example-directory-children (path &optional (root "/"))
412 (with-open-ssl-stream (stream
413 socket
414 *host*
415 *port*
416 *client-certificate*
417 *certificate-key*)
418 (let* ((*messages-sent* ())
419 (root-fid (mount stream root)))
420 (collect-directory-children stream root-fid path))))
422 (deftest test-collect-dir-root-children ((kami-suite) (test-read))
423 (assert-true (example-directory-children "/")))
425 (defun make-huge-data ()
426 (let* ((*random-state* (make-random-state nil)))
427 (make-array 1000000
428 :element-type '(unsigned-byte 8)
429 :initial-contents (loop repeat 1000000
430 collect
431 (random 256)))))
433 (defun write-huge-file (path &optional (root "/"))
434 (with-open-ssl-stream (stream
435 socket
436 *host*
437 *port*
438 *client-certificate*
439 *certificate-key*)
440 (let* ((*messages-sent* ())
441 (*buffer-size* 256)
442 (root-fid (mount stream root))
443 (saved-root-fid (clone-fid stream root-fid))
444 (fid (create-path stream root-fid path))
445 (data (make-huge-data)))
446 (9p-write stream fid 0 data)
447 (9p-clunk stream fid)
448 (read-all-pending-message stream)
449 (path-info stream saved-root-fid path))))
451 (deftest test-write-huge-file ((kami-suite) (test-collect-dir-root-children))
452 (let* ((size-file (stat-size (write-huge-file *remote-test-path-huge*))))
453 (assert-equality #'= (length (make-huge-data)) size-file)))
455 (defun read-huge-file (path &optional (root "/"))
456 (with-open-ssl-stream (stream
457 socket
458 *host*
459 *port*
460 *client-certificate*
461 *certificate-key*)
462 (let ((*messages-sent* ())
463 (*buffer-size* 4096)
464 (root-fid (mount stream root)))
465 (slurp-file stream
466 root-fid path
467 :buffer-size 3000))))
469 (deftest test-read-huge-data ((kami-suite) (test-write-huge-file))
470 (assert-equality #'=
471 (length (make-huge-data))
472 (length (read-huge-file *remote-test-path-huge*))))
474 (defun read-a-tiny-amount-of-data (path amount &optional (root "/"))
475 (with-open-ssl-stream (stream
476 socket
477 *host*
478 *port*
479 *client-certificate*
480 *certificate-key*)
481 (let* ((*messages-sent* ())
482 (*buffer-size* 4096)
483 (root-fid (mount stream root))
484 (path-fid (open-path stream root-fid path))
485 (results nil))
486 (9p-read stream
487 path-fid
489 amount
490 :callback (lambda (x reply)
491 (declare (ignore x))
492 (let ((data (decode-read-reply reply nil)))
493 (setf results data))))
494 (read-all-pending-message stream)
495 results)))
497 (deftest test-read-a-tiny-amount-of-data ((kami-suite) (test-write-huge-file))
498 (let ((amount 3))
499 (assert-equality #'=
500 amount
501 (length (read-a-tiny-amount-of-data *remote-test-path-huge* amount)))))
503 (defun read-data-exceeding-msize (path buffer-size &optional (root "/"))
504 (with-open-ssl-stream (stream
505 socket
506 *host*
507 *port*
508 *client-certificate*
509 *certificate-key*)
510 (let* ((*messages-sent* ())
511 (*buffer-size* buffer-size)
512 (root-fid (mount stream root))
513 (path-fid (open-path stream root-fid path))
514 (results nil))
515 (9p-read stream
516 path-fid
518 (* 2 buffer-size)
519 :callback (lambda (x reply)
520 (declare (ignore x))
521 (let ((data (decode-read-reply reply nil)))
522 (setf results data))))
523 (read-all-pending-message stream)
524 results)))
526 (deftest test-read-a-tiny-amount-of-data ((kami-suite) (test-write-huge-file))
527 (let ((buffer-size 256))
528 (assert-condition 9p-error
529 (read-data-exceeding-msize *remote-test-path-huge* buffer-size))))
531 (deftest test-read-a-tiny-amount-of-data ((kami-suite) (test-write-huge-file))
532 (let ((buffer-size 256))
533 (assert-condition 9p-error
534 (read-data-exceeding-msize *remote-test-path-huge* buffer-size))))
536 (defun example-copy-file (from to &optional (root "/"))
537 (with-open-ssl-stream (stream
538 socket
539 *host*
540 *port*
541 *client-certificate*
542 *certificate-key*)
543 (let* ((*messages-sent* ())
544 (root-fid (mount stream root)))
545 (copy-file stream root-fid from to)
546 (slurp-file stream root-fid to))))
548 (deftest test-copy-file ((kami-suite) (test-write-huge-file))
549 (assert-equality #'equalp
550 (make-huge-data)
551 (example-copy-file *remote-test-path-huge*
552 (concatenate 'string
553 *remote-test-path-huge*
554 "-copy"))))
556 (defun example-move-file (from to &optional (root "/"))
557 (with-open-ssl-stream (stream
558 socket
559 *host*
560 *port*
561 *client-certificate*
562 *certificate-key*)
563 (let* ((*messages-sent* ())
564 (root-fid (mount stream root)))
565 (move-file stream root-fid from to)
566 (path-exists-p stream root-fid from))))
568 (deftest test-move-file ((kami-suite) (test-copy-file))
569 (assert-false (example-move-file *remote-test-path-huge*
570 (concatenate 'string
571 *remote-test-path-huge*
572 "-renamed"))))