user/dev discussion of public-inbox itself
 help / color / mirror / code / Atom feed
From: Eric Wong <e@80x24.org>
To: meta@public-inbox.org
Subject: [PATCH 4/7] t/kqnotify: improve test reliability on OpenBSD
Date: Wed, 30 Aug 2023 05:10:42 +0000	[thread overview]
Message-ID: <20230830051045.330641-5-e@80x24.org> (raw)
In-Reply-To: <20230830051045.330641-1-e@80x24.org>

Unlike FreeBSD, OpenBSD (tested 7.3) kevent doesn't document
EVFILT_VNODE behavior when directories are being watched.

Regardless, FreeBSD semantics appear to be mostly (if not
unreliably) supported.  Detecting rename(2) isn't reliable
at all and events seem to get lost and the test needs to
retry the rename(2) to succeed.  Fortunately, rename(2)
isn't recommended for Maildirs anyways since it can clobber
existing files.

link(2) detection appears to be merely delayed on OpenBSD,
so the test merely needs an occasional delay.
---
 t/kqnotify.t | 55 +++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 41 insertions(+), 14 deletions(-)

diff --git a/t/kqnotify.t b/t/kqnotify.t
index 902ce0f1..21381806 100644
--- a/t/kqnotify.t
+++ b/t/kqnotify.t
@@ -1,36 +1,63 @@
 #!perl -w
-# Copyright (C) 2020-2021 all contributors <meta@public-inbox.org>
+# Copyright (C) all contributors <meta@public-inbox.org>
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 #
 # Ensure KQNotify can pick up rename(2) and link(2) operations
 # used by Maildir writing tools
-use strict;
-use Test::More;
+use v5.12;
 use PublicInbox::TestCommon;
+use autodie;
 plan skip_all => 'KQNotify is only for *BSD systems' if $^O !~ /bsd/;
 require_mods('IO::KQueue');
 use_ok 'PublicInbox::KQNotify';
 my ($tmpdir, $for_destroy) = tmpdir();
-mkdir "$tmpdir/new" or BAIL_OUT "mkdir: $!";
-open my $fh, '>', "$tmpdir/tst" or BAIL_OUT "open: $!";
-close $fh or BAIL_OUT "close: $!";
+mkdir "$tmpdir/new";
 
 my $kqn = PublicInbox::KQNotify->new;
 my $mask = PublicInbox::KQNotify::MOVED_TO_OR_CREATE();
 my $w = $kqn->watch("$tmpdir/new", $mask);
 
-rename("$tmpdir/tst", "$tmpdir/new/tst") or BAIL_OUT "rename: $!";
+# Unlike FreeBSD, OpenBSD (tested 7.3) kevent NOTE_EXTEND doesn't detect
+# renames into directories reliably.  It's kevent(3) manpage doesn't
+# document this behavior (unlike FreeBSD), but it sometimes works...
+open my $fh, '>', "$tmpdir/tst";
+close $fh;
+rename("$tmpdir/tst", "$tmpdir/new/tst");
 my $hit = [ map { $_->fullname } $kqn->read ];
-is_deeply($hit, ["$tmpdir/new/tst"], 'rename(2) detected (via NOTE_EXTEND)');
+my $try = 0;
+while (!@$hit && $^O eq 'openbsd' && $try++ < 30) {
+	diag "retrying NOTE_EXTEND detection for $^O (#$try)";
+	# kevent can totally ignore the event, so delaying hasn't worked;
+	# keep doing the same thing until kevent notices one of them
+	open $fh, '>', "$tmpdir/tst";
+	close $fh;
+	rename("$tmpdir/tst", "$tmpdir/new/tst");
+	$hit = [ map { $_->fullname } $kqn->read ]
+}
+is_deeply($hit, ["$tmpdir/new/tst"],
+		'rename(2) detected (via NOTE_EXTEND)')
+		or diag explain($hit);
 
-open $fh, '>', "$tmpdir/tst" or BAIL_OUT "open: $!";
-close $fh or BAIL_OUT "close: $!";
-link("$tmpdir/tst", "$tmpdir/new/link") or BAIL_OUT "link: $!";
-$hit = [ grep m!/link$!, map { $_->fullname } $kqn->read ];
-is_deeply($hit, ["$tmpdir/new/link"], 'link(2) detected (via NOTE_WRITE)');
+# OpenBSD (tested 7.3) doesn't reliably trigger NOTE_WRITE on link(2)
+# into directories, but usually it does (and more reliably than rename(2)
+# above) and doesn't drop the event entirely.
+open $fh, '>', "$tmpdir/tst";
+close $fh;
+link("$tmpdir/tst", "$tmpdir/new/link");
+my @read = map { $_->fullname } $kqn->read;
+$try = 0;
+while (!@read && $^O eq 'openbsd' && $try++ < 30) {
+	diag "delaying and retrying NOTE_WRITE detection for $^O (#$try)";
+	tick;
+	# no need to link(2) again, at least, kevent can just be late, here
+	@read = map { $_->fullname } $kqn->read;
+}
+$hit = [ grep(m!/link$!, @read) ];
+is_deeply($hit, ["$tmpdir/new/link"], 'link(2) detected (via NOTE_WRITE)')
+	or diag explain(\@read);
 
 $w->cancel;
-link("$tmpdir/new/tst", "$tmpdir/new/link2") or BAIL_OUT "link: $!";
+link("$tmpdir/new/tst", "$tmpdir/new/link2");
 $hit = [ map { $_->fullname } $kqn->read ];
 is_deeply($hit, [], 'link(2) not detected after cancel');
 

  parent reply	other threads:[~2023-08-30  5:10 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-30  5:10 [PATCH 0/7] various build fixes + OpenBSD compat Eric Wong
2023-08-30  5:10 ` [PATCH 1/7] treewide: drop MSG_EOR with AF_UNIX+SOCK_SEQPACKET Eric Wong
2023-08-30  5:10 ` [PATCH 2/7] Makefile.PL: fix syntax for ASan and valgrind targets Eric Wong
2023-08-30  5:10 ` [PATCH 3/7] Makefile.PL: depend on autodie, at least for tests Eric Wong
2023-08-30  5:10 ` Eric Wong [this message]
2023-08-30  5:10 ` [PATCH 5/7] xap_helper.h: don't compress debug sections on OpenBSD Eric Wong
2023-08-30  5:10 ` [PATCH 6/7] xap_helper.h: limit stderr assignment to glibc+FreeBSD Eric Wong
2023-08-30  5:10 ` [PATCH 7/7] xap_helper.h: fix double-free on OpenBSD hdestroy Eric Wong
2023-08-30 12:34 ` [PATCH 0/7] various build fixes + OpenBSD compat, " Štěpán Němec
2023-08-30 21:18   ` Eric Wong
2023-08-31  9:11     ` Štěpán Němec
2023-08-31 17:26       ` Štěpán Němec
2023-09-01 11:09         ` Eric Wong
2023-09-02 10:54           ` Štěpán Němec
2023-09-02 11:07             ` [PATCH v2] Clarify Inline::C dependency (optional on Linux, required elsewhere) Štěpán Němec
2023-09-02 18:50               ` Eric Wong
2023-09-02 19:08                 ` Štěpán Němec
2023-09-02 19:44                   ` Eric Wong
2023-09-02 20:45                     ` Štěpán Němec
2023-09-02 20:56                       ` Eric Wong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://public-inbox.org/README

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230830051045.330641-5-e@80x24.org \
    --to=e@80x24.org \
    --cc=meta@public-inbox.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/public-inbox.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).