summaryrefslogtreecommitdiff
path: root/tests/nar.scm
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2014-01-22 17:09:21 +0100
committerLudovic Courtès <ludo@gnu.org>2014-01-24 00:01:50 +0100
commitcd4027fa478e20b59e798dd163a54e7ff9c42c98 (patch)
tree5e8345f9800d039432fb98560ebd66a46d9eb024 /tests/nar.scm
parentce4a482983abaf7090d098cdda973139cefb56b7 (diff)
nar: Add 'restore-file-set', for use by build hooks.
* guix/nar.scm (&nar-invalid-hash-error, &nar-signature-error): New condition types. (&nar-error): Add 'file' and 'port' fields. (&nar-read-error): Remove 'port' and 'file' fields. (lock-store-file, unlock-store-file, finalize-store-file, temporary-store-directory, restore-file-set): New procedures. * tests/nar.scm (%seed): New variable. (random-text): New procedure. ("restore-file-set (signed, valid)", "restore-file-set (missing signature)", "restore-file-set (corrupt)"): New tests. * po/Makevars (XGETTEXT_OPTIONS): Add '--keyword=message'.nar fixes * po/POTFILES.in: Add guix/nar.scm.
Diffstat (limited to 'tests/nar.scm')
-rw-r--r--tests/nar.scm103
1 files changed, 102 insertions, 1 deletions
diff --git a/tests/nar.scm b/tests/nar.scm
index 6493d76876f..9f21f990c82 100644
--- a/tests/nar.scm
+++ b/tests/nar.scm
@@ -1,5 +1,5 @@
1;;; GNU Guix --- Functional package management for GNU 1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2012, 2013 Ludovic Courtès <ludo@gnu.org> 2;;; Copyright © 2012, 2013, 2014 Ludovic Courtès <ludo@gnu.org>
3;;; 3;;;
4;;; This file is part of GNU Guix. 4;;; This file is part of GNU Guix.
5;;; 5;;;
@@ -18,11 +18,17 @@
18 18
19(define-module (test-nar) 19(define-module (test-nar)
20 #:use-module (guix nar) 20 #:use-module (guix nar)
21 #:use-module (guix store)
22 #:use-module ((guix hash) #:select (open-sha256-input-port))
21 #:use-module (rnrs bytevectors) 23 #:use-module (rnrs bytevectors)
22 #:use-module (rnrs io ports) 24 #:use-module (rnrs io ports)
25 #:use-module (srfi srfi-1)
23 #:use-module (srfi srfi-26) 26 #:use-module (srfi srfi-26)
27 #:use-module (srfi srfi-34)
28 #:use-module (srfi srfi-35)
24 #:use-module (srfi srfi-64) 29 #:use-module (srfi srfi-64)
25 #:use-module (ice-9 ftw) 30 #:use-module (ice-9 ftw)
31 #:use-module (ice-9 regex)
26 #:use-module (ice-9 match)) 32 #:use-module (ice-9 match))
27 33
28;; Test the (guix nar) module. 34;; Test the (guix nar) module.
@@ -156,6 +162,24 @@
156 (string-append (dirname (search-path %load-path "pre-inst-env")) 162 (string-append (dirname (search-path %load-path "pre-inst-env"))
157 "/test-nar-" (number->string (getpid)))) 163 "/test-nar-" (number->string (getpid))))
158 164
165;; XXX: Factorize.
166(define %seed
167 (seed->random-state (logxor (getpid) (car (gettimeofday)))))
168
169(define (random-text)
170 (number->string (random (expt 2 256) %seed) 16))
171
172(define-syntax-rule (let/ec k exp...)
173 ;; This one appeared in Guile 2.0.9, so provide a copy here.
174 (let ((tag (make-prompt-tag)))
175 (call-with-prompt tag
176 (lambda ()
177 (let ((k (lambda args
178 (apply abort-to-prompt tag args))))
179 exp...))
180 (lambda (_ . args)
181 (apply values args)))))
182
159 183
160(test-begin "nar") 184(test-begin "nar")
161 185
@@ -201,6 +225,83 @@
201 (lambda () 225 (lambda ()
202 (rmdir input))))) 226 (rmdir input)))))
203 227
228;; 'restore-file-set' depends on 'open-sha256-input-port', which in turn
229;; relies on a Guile 2.0.10+ feature.
230(test-skip (if (false-if-exception
231 (open-sha256-input-port (%make-void-port "r")))
232 0
233 3))
234
235(test-assert "restore-file-set (signed, valid)"
236 (with-store store
237 (let* ((texts (unfold (cut >= <> 10)
238 (lambda _ (random-text))
239 1+
240 0))
241 (files (map (cut add-text-to-store store "text" <>) texts))
242 (dump (call-with-bytevector-output-port
243 (cut export-paths store files <>))))
244 (delete-paths store files)
245 (and (every (negate file-exists?) files)
246 (let* ((source (open-bytevector-input-port dump))
247 (imported (restore-file-set source)))
248 (and (equal? imported files)
249 (every (lambda (file)
250 (and (file-exists? file)
251 (valid-path? store file)))
252 files)
253 (equal? texts
254 (map (lambda (file)
255 (call-with-input-file file
256 get-string-all))
257 files))))))))
258
259(test-assert "restore-file-set (missing signature)"
260 (let/ec return
261 (with-store store
262 (let* ((file (add-text-to-store store "foo" "Hello, world!"))
263 (dump (call-with-bytevector-output-port
264 (cute export-paths store (list file) <>
265 #:sign? #f))))
266 (delete-paths store (list file))
267 (and (not (file-exists? file))
268 (let ((source (open-bytevector-input-port dump)))
269 (guard (c ((nar-signature-error? c)
270 (let ((message (condition-message c))
271 (port (nar-error-port c)))
272 (return
273 (and (string-match "lacks.*signature" message)
274 (string=? file (nar-error-file c))
275 (eq? source port))))))
276 (restore-file-set source))
277 #f))))))
278
279(test-assert "restore-file-set (corrupt)"
280 (let/ec return
281 (with-store store
282 (let* ((file (add-text-to-store store "foo"
283 (random-text)))
284 (dump (call-with-bytevector-output-port
285 (cute export-paths store (list file) <>))))
286 (delete-paths store (list file))
287
288 ;; Flip a byte in the file contents.
289 (let* ((index 120)
290 (byte (bytevector-u8-ref dump index)))
291 (bytevector-u8-set! dump index (logxor #xff byte)))
292
293 (and (not (file-exists? file))
294 (let ((source (open-bytevector-input-port dump)))
295 (guard (c ((nar-invalid-hash-error? c)
296 (let ((message (condition-message c))
297 (port (nar-error-port c)))
298 (return
299 (and (string-contains message "hash")
300 (string=? file (nar-error-file c))
301 (eq? source port))))))
302 (restore-file-set source))
303 #f))))))
304
204(test-end "nar") 305(test-end "nar")
205 306
206 307