From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.2 required=3.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 0828D1F518 for ; Wed, 30 Aug 2023 05:10:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=80x24.org; s=selector1; t=1693372246; bh=znsY0X0o7s1vY2KIC1qoruaNPNnNeeCcQse6jppg5NA=; h=From:To:Subject:Date:In-Reply-To:References:From; b=ELZ2FQ2+98Ykq5IwZnK4asNh4DeEkhM32hLg+2ObDTQPVxX0QTpp3NkbJ7s1FXbLC rkJl2+1e/x4FhnYp5Tz2SkvbApN95/sBurDwxSAA0oP0k589JlDAp+lcxiRTIQS6Vg kYUpsUM0f/EPgEX6qnEq90yw3e0ORQ6L5P6cRr+g= From: Eric Wong 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 Message-Id: <20230830051045.330641-5-e@80x24.org> In-Reply-To: <20230830051045.330641-1-e@80x24.org> References: <20230830051045.330641-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: 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 +# Copyright (C) all contributors # License: AGPL-3.0+ # # 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');