X-Git-Url: https://git.hcoop.net/jackhill/guix/guix.git/blobdiff_plain/a13c1bf4ca0b15fa53235c2bd6aa53e4a75c7d0f..76ab528d017442203f6bce4b0b1d8395a786ce0f:/tests/store-deduplication.scm diff --git a/tests/store-deduplication.scm b/tests/store-deduplication.scm index 04817a193a..e2870a363d 100644 --- a/tests/store-deduplication.scm +++ b/tests/store-deduplication.scm @@ -19,7 +19,7 @@ (define-module (test-store-deduplication) #:use-module (guix tests) #:use-module (guix store deduplication) - #:use-module (guix hash) + #:use-module (gcrypt hash) #:use-module ((guix utils) #:select (call-with-temporary-directory)) #:use-module (guix build utils) #:use-module (rnrs bytevectors) @@ -37,22 +37,25 @@ (lambda (store) (let ((data (string->utf8 "Hello, world!")) (identical (map (lambda (n) - (string-append store "/" (number->string n))) + (string-append store "/" (number->string n) + "/a/b/c")) (iota 5))) (unique (string-append store "/unique"))) (for-each (lambda (file) + (mkdir-p (dirname file)) (call-with-output-file file (lambda (port) (put-bytevector port data)))) identical) + ;; Make the parent of IDENTICAL read-only. This should not prevent + ;; deduplication from inserting its hard link. + (chmod (dirname (second identical)) #o544) + (call-with-output-file unique (lambda (port) (put-bytevector port (string->utf8 "This is unique.")))) - (for-each (lambda (file) - (deduplicate file (sha256 data) #:store store)) - identical) - (deduplicate unique (nar-sha256 unique) #:store store) + (deduplicate store (nar-sha256 store) #:store store) ;; (system (string-append "ls -lRia " store)) (cons* (apply = (map (compose stat:ino stat) identical)) @@ -61,4 +64,46 @@ (stat:nlink (stat unique)) (map (compose stat:nlink stat) identical)))))) +(test-equal "deduplicate, ENOSPC" + (cons* #f ;inode comparison + (append (make-list 3 4) + (make-list 7 1))) ;'nlink' values + + ;; In this scenario the first 3 files are properly deduplicated and then we + ;; simulate a full '.links' directory where link(2) gets ENOSPC, thereby + ;; preventing deduplication of the subsequent files. + (call-with-temporary-directory + (lambda (store) + (let ((true-link link) + (links 0) + (data1 (string->utf8 "Hello, world!")) + (data2 (string->utf8 "Hi, world!")) + (identical (map (lambda (n) + (string-append store "/" (number->string n) + "/a/b/c")) + (iota 10))) + (populate (lambda (data) + (lambda (file) + (mkdir-p (dirname file)) + (call-with-output-file file + (lambda (port) + (put-bytevector port data))))))) + (for-each (populate data1) (take identical 5)) + (for-each (populate data2) (drop identical 5)) + (dynamic-wind + (lambda () + (set! link (lambda (old new) + (set! links (+ links 1)) + (if (<= links 3) + (true-link old new) + (throw 'system-error "link" "~A" '("Whaaat?!") + (list ENOSPC)))))) + (lambda () + (deduplicate store (nar-sha256 store) #:store store)) + (lambda () + (set! link true-link))) + + (cons (apply = (map (compose stat:ino stat) identical)) + (map (compose stat:nlink stat) identical)))))) + (test-end "store-deduplication")