Subject: Re: bug#75590: ports.test: "SEEK_DATA while in hole" fails on some hosts

From: Rob Browning <[email-masked]>
Date: Sun, 19 Jan 2025 14:14:32 -0600

Mikael Djurfeldt <[email-masked]> writes:

> We could, in addition to "stat", provide "statfs" (on systems that provide
> it).
>
> The test could then first test for the presence of "statfs" and then check
> if the filesystem is ext4.

Here's what I've done in Debian for now after double-checking the
test on a few filesystems:

>From ea1750ad7f27593ee42ca48c74cc5b3e3cdd2d1d Mon Sep 17 00:00:00 2001
From: Rob Browning <[email-masked]>
Date: Wed, 15 Jan 2025 12:54:02 -0600
Subject: [PATCH 1/1] Skip ports.test seek tests unless filesystem looks
 suitable

For now, only test on filesystems that we know have the expected
semantics, i.e. btrfs, ext4, and xfs.
---
 test-suite/tests/ports.test | 32 +++++++++++++++++++++-----------
 1 file changed, 21 insertions(+), 11 deletions(-)

diff --git a/test-suite/tests/ports.test b/test-suite/tests/ports.test
index bec5e356c5..baa9edb700 100644
--- a/test-suite/tests/ports.test
+++ b/test-suite/tests/ports.test
@@ -39,9 +39,23 @@
 (define (test-file)
   (data-file-name "ports-test.tmp"))
 
-(define (skip-on-darwin)
-  (when (string-ci=? "darwin" (utsname:sysname (uname)))
-    (throw 'untested)))
+(define (skip-unless-fs-handles-holes-as-expected)
+  ;; For now only allow filesystems that should have the seek hole/data
+  ;; semantics the tests expect.  Filesystems vary both in how they
+  ;; handle sparseness in general (e.g. granularity), how they handle
+  ;; SEEK_DATA and SEEK_HOLE (see lseek(2) for some related info), and
+  ;; even how quickly they reflect changes.  du's output, for example,
+  ;; may not immediately reflect sparseness changes (previously observed
+  ;; on btrfs and zfs).
+  (let* ((p (open-input-pipe "debian/bin/path-fs ."))
+         (fs (read-all p)))
+    (close p)
+    (when (string=? "\n" fs)
+      (error "unexpected output from debian/bin/path-fs" fs))
+    (or (string=? "btrfs\n" fs)
+        (string=? "ext4\n" fs)
+        (string=? "xfs\n" fs)
+        (throw 'untested))))
 
 
 ;;;; Some general utilities for testing ports.
@@ -189,7 +203,6 @@
     (close-port iport))
   (delete-file filename))
 
-;;; Note: Holes are weird on Darwin.
 (let* ((file (test-file))
        (port (open-output-file file)))
   (seek port 4096 SEEK_SET)
@@ -198,15 +211,12 @@
 
   (pass-if-equal "size of sparse file"
       4100
-    ;; XXX: On macOS, APFS does support sparse files, they do not behave
-    ;; like on Linux.  Skip these tests on macOS.
-    (skip-on-darwin)
-
+    (skip-unless-fs-handles-holes-as-expected)
     (stat:size (stat file)))
 
   (pass-if-equal "SEEK_DATA while on data"
       4096
-    (skip-on-darwin)
+    (skip-unless-fs-handles-holes-as-expected)
     (if (defined? 'SEEK_DATA)
         (call-with-input-file file
           (lambda (port)
@@ -219,7 +229,7 @@
 
   (pass-if-equal "SEEK_DATA while in hole"
       4096
-    (skip-on-darwin)
+    (skip-unless-fs-handles-holes-as-expected)
     (if (defined? 'SEEK_DATA)
         (call-with-input-file file
           (lambda (port)
@@ -232,7 +242,7 @@
 
   (pass-if-equal "SEEK_HOLE while in hole"
       10
-    (skip-on-darwin)
+    (skip-unless-fs-handles-holes-as-expected)
     (if (defined? 'SEEK_HOLE)
         (call-with-input-file file
           (lambda (port)
-- 
2.45.2

But happy to help with whatever solution we prefer in guile itself.

-- 
Rob Browning
rlb @defaultvalue.org and @debian.org
GPG as of 2011-07-10 E6A9 DA3C C9FD 1FF8 C676 D2C4 C0F0 39E9 ED1B 597A
GPG as of 2002-11-03 14DD 432F AE39 534D B592 F9A0 25C8 D377 8C7E 73A4