summaryrefslogtreecommitdiff
path: root/tests/backup-tests.lisp
blob: 932ab249968b940d0ee92a38e886846d22a79341 (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
;; This file is part of ybackup.
;; Copyright (C) 2023 Piotr Szarmański

;; ybackup is free software: you can redistribute it and/or modify it under the
;; terms of the GNU General Public License as published by the Free
;; Software Foundation, either version 3 of the License, or (at your option) any
;; later version.

;; ybackup 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
;; ybackup. If not, see <https://www.gnu.org/licenses/>.


(in-package :ybackup/test)

(def-suite* backup-tests :in ybackup-tests )

(defun make-temporary-dir ()
  (let* ((tmpdir (uiop:temporary-directory))
         (tmp-tmpdir (make-pathname :directory (serapeum:append1
                                     (pathname-directory tmpdir)
                                     (ironclad:byte-array-to-hex-string (ironclad:random-data 10)))
                         :defaults tmpdir)))
    (ensure-directories-exist tmp-tmpdir)
    tmp-tmpdir))

(defun sha256sum (f)
  (crypto:digest-file :sha256 f))

(defun dir256sum (directory)
  "Recursively compute sha256 of a directory."
  (macrolet ((catsum (s)
               `(crypto:digest-sequence
                 :sha256
                 (apply #'concatenate '(simple-array (unsigned-byte 8) (*)) ,s))))
    (catsum
     (list
      (catsum (map 'list #'dir256sum (uiop:subdirectories directory)))
      (catsum (map 'list #'sha256sum (uiop:directory-files directory)))))))

(defun random-dir (dir)
  (let ((d (make-pathname
              :directory
              (serapeum:append1
               (pathname-directory dir)
               (funcall (gen-string :length (gen-integer :min 1 :max 20)
                                    :elements (gen-character :alphanumericp t)))))))
    (ensure-directories-exist d)
    d))

(defun make-random-file (directory)
  (with-open-file (file (make-pathname
                         :name (funcall (gen-string :length (gen-integer :min 1 :max 20)
                                                    :elements (gen-character :alphanumericp t)))
                         :defaults directory)
                        :direction :output :if-does-not-exist :create
                        :element-type 'serapeum:octet)
    (write-sequence (funcall (gen-buffer :length (gen-integer :min 0 :max 80000))) file)))

(defun random-files (tmpdir)
  "Make some random files."
  (lambda ()
    (flet ((random-files (dir)
             (loop repeat (random 20) do (make-random-file dir))))
      (let ((tdir (random-dir tmpdir)))
       (random-files (random-dir tdir))
       (random-files (random-dir (random-dir (random-dir tdir))))
        tdir))))

(test simple-rw-test
  (let ((tmpdir (make-temporary-dir)))
    (unwind-protect
         (for-all ((dir (random-files tmpdir)))
           (let ((c1 (dir256sum dir))
                 (backend (make-instance 'eris:hash-backend)))
             (let* ((urn (make-backup dir backend))
                    (d1 (random-dir dir)))
               (read-backup urn backend d1)
               (is (equalp
                    c1
                    (dir256sum
                     (make-pathname
                      :directory
                      (append (pathname-directory d1) (last (pathname-directory dir))))))))))
      (uiop:delete-directory-tree tmpdir :validate t))))