2 # Copyright (C) 2020 all contributors <meta@public-inbox.org>
3 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
5 use PublicInbox::TestCommon;
10 require_mods('PublicInbox::Gcf2');
11 use_ok 'PublicInbox::Gcf2';
12 my $gcf2 = PublicInbox::Gcf2::new();
13 is(ref($gcf2), 'PublicInbox::Gcf2', '::new works');
14 chomp(my $objdir = xqx([qw(git rev-parse --git-path objects)]));
15 if ($objdir =~ /\A--git-path\n/) { # git <2.5
16 chomp($objdir = xqx([qw(git rev-parse --git-dir)]));
17 $objdir .= '/objects';
18 $objdir = undef unless -d $objdir;
21 my $COPYING = 'dba13ed2ddf783ee8118c6a581dbf75305f816a3';
22 open my $agpl, '<', 'COPYING' or BAIL_OUT "AGPL-3 missing: $!";
23 $agpl = do { local $/; <$agpl> };
26 skip 'not in git worktree', 15 unless defined($objdir);
27 $gcf2->add_alternate($objdir);
28 open my $fh, '+>', undef or BAIL_OUT "open: $!";
32 $gcf2->cat_oid($fd, 'invalid');
33 seek($fh, 0, SEEK_SET) or BAIL_OUT "seek: $!";
34 is(do { local $/; <$fh> }, "invalid missing\n", 'got missing message');
36 seek($fh, 0, SEEK_SET) or BAIL_OUT "seek: $!";
37 $gcf2->cat_oid($fd, '0'x40);
38 seek($fh, 0, SEEK_SET) or BAIL_OUT "seek: $!";
39 is(do { local $/; <$fh> }, ('0'x40)." missing\n",
40 'got missing message for 0x40');
42 seek($fh, 0, SEEK_SET) or BAIL_OUT "seek: $!";
43 $gcf2->cat_oid($fd, $COPYING);
45 my $ck_copying = sub {
47 seek($fh, 0, SEEK_SET) or BAIL_OUT "seek: $!";
48 is(<$fh>, "$COPYING blob 34520\n", 'got expected header');
49 $buf = do { local $/; <$fh> };
50 is(chop($buf), "\n", 'got trailing \\n');
51 is($buf, $agpl, "AGPL matches ($desc)");
53 $ck_copying->('regular file');
55 $^O eq 'linux' or skip('pipe tests are Linux-only', 12);
59 pipe($r, $w) or BAIL_OUT $!;
60 fcntl($w, 1031, 4096) or
61 skip('Linux too old for F_SETPIPE_SZ', 12);
63 seek($fh, 0, SEEK_SET) or BAIL_OUT "seek: $!";
64 truncate($fh, 0) or BAIL_OUT "truncate: $!";
65 defined(my $pid = fork) or BAIL_OUT "fork: $!";
68 tick; # wait for parent to block on writev
69 $buf = do { local $/; <$r> };
70 print $fh $buf or _exit(1);
73 $gcf2->cat_oid(fileno($w), $COPYING);
74 close $w or BAIL_OUT "close: $!";
75 is(waitpid($pid, 0), $pid, 'child exited');
76 is($?, 0, 'no error in child');
77 $ck_copying->("pipe blocking($blk)");
79 pipe($r, $w) or BAIL_OUT $!;
80 fcntl($w, 1031, 4096) or BAIL_OUT $!;
83 local $SIG{PIPE} = 'IGNORE';
84 eval { $gcf2->cat_oid(fileno($w), $COPYING) };
85 like($@, qr/writev error:/, 'got writev error');
89 if (my $nr = $ENV{TEST_LEAK_NR}) {
90 open my $null, '>', '/dev/null' or BAIL_OUT "open /dev/null: $!";
91 my $fd = fileno($null);
92 my $cat = $ENV{TEST_LEAK_CAT} // 10;
93 diag "checking for leaks... (TEST_LEAK_NR=$nr TEST_LEAK_CAT=$cat)";
94 local $SIG{PIPE} = 'IGNORE';
98 my $broken = fileno($w);
100 my $obj = PublicInbox::Gcf2::new();
101 if (defined($objdir)) {
102 $obj->add_alternate($objdir);
104 $obj->cat_oid($fd, $COPYING);
105 eval { $obj->cat_oid($broken, $COPYING) };
106 $obj->cat_oid($fd, '0'x40);
107 $obj->cat_oid($fd, 'invalid');