diff options
| author | Ludovic Courtès <ludo@gnu.org> | 2014-01-22 17:09:21 +0100 |
|---|---|---|
| committer | Ludovic Courtès <ludo@gnu.org> | 2014-01-24 00:01:50 +0100 |
| commit | cd4027fa478e20b59e798dd163a54e7ff9c42c98 (patch) | |
| tree | 5e8345f9800d039432fb98560ebd66a46d9eb024 /tests/nar.scm | |
| parent | ce4a482983abaf7090d098cdda973139cefb56b7 (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.scm | 103 |
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 | ||
