about summary refs log tree commit homepage
path: root/t
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2015-12-17 05:37:31 +0000
committerEric Wong <e@80x24.org>2015-12-22 00:58:12 +0000
commitb140961420c0f240c9c3f55e83c52cfc3efa709d (patch)
treea1e92354800ec7f514738f60cce38e8f159afe3b /t
parente00a6f63ef80f3540a159ef4fdc4bba359dc5596 (diff)
downloadpublic-inbox-b140961420c0f240c9c3f55e83c52cfc3efa709d.tar.gz
The "cat_file" sub now allows a block to be passed for partial
processing.  Additionally, a new "check" method is added to
retrieve only object metadata: (SHA-1 identifier, type, size)
Diffstat (limited to 't')
-rw-r--r--t/git.fast-import-data101
-rw-r--r--t/git.t134
2 files changed, 235 insertions, 0 deletions
diff --git a/t/git.fast-import-data b/t/git.fast-import-data
new file mode 100644
index 00000000..4a105ee7
--- /dev/null
+++ b/t/git.fast-import-data
@@ -0,0 +1,101 @@
+blob
+mark :1
+data 6
+hello
+
+reset refs/heads/header
+commit refs/heads/header
+mark :2
+author AU Thor <e@example.com> 0 +0000
+committer AU Thor <e@example.com> 0 +0000
+data 8
+initial
+M 100644 :1 foo.txt
+
+blob
+mark :3
+data 12
+hello
+world
+
+commit refs/heads/master
+mark :4
+author AU Thor <e@example.com> 0 +0000
+committer AU Thor <e@example.com> 0 +0000
+data 7
+second
+from :2
+M 100644 :3 foo.txt
+
+blob
+mark :5
+data 12
+-----
+hello
+
+commit refs/heads/header
+mark :6
+author AU Thor <e@example.com> 0 +0000
+committer AU Thor <e@example.com> 0 +0000
+data 11
+add header
+from :2
+M 100644 :5 foo.txt
+
+blob
+mark :7
+data 18
+-----
+hello
+world
+
+commit refs/heads/master
+mark :8
+author AU Thor <e@example.com> 0 +0000
+committer AU Thor <e@example.com> 0 +0000
+data 46
+Merge branch 'header'
+
+* header:
+  add header
+from :4
+merge :6
+M 100644 :7 foo.txt
+
+blob
+mark :9
+data 0
+
+blob
+mark :10
+data 16
+dir/dur/der/derp
+commit refs/heads/master
+mark :11
+author AU Thor <e@example.com> 0 +0000
+committer AU Thor <e@example.com> 0 +0000
+data 26
+add symlink and deep file
+from :8
+M 100644 :9 dir/dur/der/derp
+M 120000 :10 link
+
+blob
+mark :12
+data 78
+[submodule "git"]
+        path = git
+        url = git://git.kernel.org/pub/scm/git/git.git
+
+commit refs/heads/master
+mark :13
+author AU Thor <e@example.com> 0 +0000
+committer AU Thor <e@example.com> 0 +0000
+data 18
+add git submodule
+from :11
+M 100644 :12 .gitmodules
+M 160000 f3adf457e046f92f039353762a78dcb3afb2cb13 git
+
+reset refs/heads/master
+from :13
diff --git a/t/git.t b/t/git.t
new file mode 100644
index 00000000..4532921d
--- /dev/null
+++ b/t/git.t
@@ -0,0 +1,134 @@
+# Copyright (C) 2015 all contributors <meta@public-inbox.org>
+# License: AGPL-3.0+ (https://www.gnu.org/licenses/agpl-3.0.txt)
+use strict;
+use warnings;
+use Test::More;
+use File::Temp qw/tempdir/;
+my $dir = tempdir(CLEANUP => 1);
+use Cwd qw/getcwd/;
+
+use_ok 'PublicInbox::GitCatFile';
+{
+        is(system(qw(git init -q --bare), $dir), 0, 'created git directory');
+        my @cmd = ('git', "--git-dir=$dir", 'fast-import', '--quiet');
+
+        my $fi_data = getcwd().'/t/git.fast-import-data';
+        ok(-r $fi_data, "fast-import data readable (or run test at top level)");
+        my $pid = fork;
+        defined $pid or die "fork failed: $!\n";
+        if ($pid == 0) {
+                open STDIN, '<', $fi_data or die "open $fi_data: $!\n";
+                exec @cmd;
+                die "failed exec: ",join(' ', @cmd),": $!\n";
+        }
+        waitpid $pid, 0;
+        is($?, 0, 'fast-import succeeded');
+}
+
+{
+        my $gcf = PublicInbox::GitCatFile->new($dir);
+        my $f = 'HEAD:foo.txt';
+        my @x = $gcf->check($f);
+        is(scalar @x, 3, 'returned 3 element array for existing file');
+        like($x[0], qr/\A[a-f0-9]{40}\z/, 'returns obj ID in 1st element');
+        is('blob', $x[1], 'returns obj type in 2nd element');
+        like($x[2], qr/\A\d+\z/, 'returns obj size in 3rd element');
+
+        my $raw = $gcf->cat_file($f);
+        is($x[2], length($$raw), 'length matches');
+
+        {
+                my $size;
+                my $rv = $gcf->cat_file($f, sub {
+                        my ($in, $left) = @_;
+                        $size = $$left;
+                        'nothing'
+                });
+                is($rv, 'nothing', 'returned from callback without reading');
+                is($size, $x[2], 'set size for callback correctly');
+        }
+
+        eval { $gcf->cat_file($f, sub { die 'OMG' }) };
+        like($@, qr/\bOMG\b/, 'died in callback propagated');
+        is(${$gcf->cat_file($f)}, $$raw, 'not broken after failures');
+
+        {
+                my ($buf, $r);
+                my $rv = $gcf->cat_file($f, sub {
+                        my ($in, $left) = @_;
+                        $r = read($in, $buf, 2);
+                        $$left -= $r;
+                        'blah'
+                });
+                is($r, 2, 'only read 2 bytes');
+                is($buf, '--', 'partial read succeeded');
+                is($rv, 'blah', 'return value propagated');
+        }
+        is(${$gcf->cat_file($f)}, $$raw, 'not broken after partial read');
+}
+
+if (1) {
+        use POSIX qw(dup2);
+        my @cmd = ('git', "--git-dir=$dir", qw(hash-object -w --stdin));
+
+        # need a big file, use the AGPL-3.0 :p
+        my $big_data = getcwd().'/COPYING';
+        ok(-r $big_data, 'COPYING readable');
+        my $size = -s $big_data;
+        ok($size > 8192, 'file is big enough');
+
+        my ($r, $w);
+        ok(pipe($r, $w), 'created pipe');
+
+        my $pid = fork;
+        defined $pid or die "fork failed: $!\n";
+        if ($pid == 0) {
+                close $r;
+                open STDIN, '<', $big_data or die "open $big_data: $!\n";
+                dup2(fileno($w), 1);
+                exec @cmd;
+                die "failed exec: ",join(' ', @cmd),": $!\n";
+        }
+        close $w;
+        my $n = read $r, my $buf, 41;
+        waitpid $pid, 0;
+        is(0, $?, 'hashed object successfully');
+        chomp $buf;
+
+        my $gcf = PublicInbox::GitCatFile->new($dir);
+        my $rsize;
+        is($gcf->cat_file($buf, sub {
+                $rsize = ${$_[1]};
+                'x';
+        }), 'x', 'checked input');
+        is($rsize, $size, 'got correct size on big file');
+
+        my $x = $gcf->cat_file($buf, \$rsize);
+        is($rsize, $size, 'got correct size ref on big file');
+        is(length($$x), $size, 'read correct number of bytes');
+
+        my $rline;
+        $gcf->cat_file($buf, sub {
+                my ($in, $left) = @_;
+                $rline = <$in>;
+                $$left -= length($rline);
+        });
+        {
+                open my $fh, '<', $big_data or die "open failed: $!\n";
+                is($rline, <$fh>, 'first line matches');
+        };
+
+        my $all;
+        $gcf->cat_file($buf, sub {
+                my ($in, $left) = @_;
+                my $x = read($in, $all, $$left);
+                $$left -= $x;
+        });
+        {
+                open my $fh, '<', $big_data or die "open failed: $!\n";
+                local $/;
+                is($all, <$fh>, 'entire read matches');
+        };
+}
+
+done_testing();