From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.1 required=3.0 tests=ALL_TRUSTED,AWL,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id EFDC01F852 for ; Thu, 22 Dec 2022 10:43:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=80x24.org; s=selector1; t=1671705823; bh=SIKqdMaJDIOvh81exBDfmZTaZmJe2FuNwqL1VXz8TZ8=; h=From:To:Subject:Date:From; b=o1wUZ57cJciSZPNdgMKuYPbPKjZI1VDxZOgiMhLZW40WVxsmoEFW4VVVI0JS63jrh mTNkjkiwRqT7OerP/d4VAb2jgcpzbQOrrZiNob/8DcqT+0HNv4P4hUP4NJmIdhBw/7 qyC2BIpbhK2LOfReIcnPfi3468kz9mHTD5QBmG9E= From: Eric Wong To: meta@public-inbox.org Subject: [PATCH] tests: add tests for cloning coderepos w/ manifest Date: Thu, 22 Dec 2022 10:43:42 +0000 Message-Id: <20221222104342.259214-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: It's not much, yet, but it's something for the corner cases which I'm maybe not hitting under normal use. --- MANIFEST | 2 + t/clone-coderepo.psgi | 21 +++++++ t/clone-coderepo.t | 130 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 153 insertions(+) create mode 100644 t/clone-coderepo.psgi create mode 100644 t/clone-coderepo.t diff --git a/MANIFEST b/MANIFEST index 8d60d9dc..2966a121 100644 --- a/MANIFEST +++ b/MANIFEST @@ -396,6 +396,8 @@ t/altid.t t/altid_v2.t t/cgi.t t/check-www-inbox.perl +t/clone-coderepo.psgi +t/clone-coderepo.t t/cmd_ipc.t t/config.t t/config_limiter.t diff --git a/t/clone-coderepo.psgi b/t/clone-coderepo.psgi new file mode 100644 index 00000000..77072174 --- /dev/null +++ b/t/clone-coderepo.psgi @@ -0,0 +1,21 @@ +#!perl -w +# Copyright (C) all contributors +# License: AGPL-3.0+ +# for clone-coderepo.t +use v5.12; +use Plack::Builder; +use PublicInbox::WwwStatic; +use PublicInbox::WWW; +my $www = PublicInbox::WWW->new; +my $static = PublicInbox::WwwStatic->new(docroot => $ENV{TEST_DOCROOT}); +builder { + enable 'Head'; + sub { + my ($env) = @_; + if ($env->{PATH_INFO} eq '/manifest.js.gz') { + my $res = $static->call($env); + return $res if $res->[0] != 404; + } + $www->call($env); + }; +} diff --git a/t/clone-coderepo.t b/t/clone-coderepo.t new file mode 100644 index 00000000..eb8f8b37 --- /dev/null +++ b/t/clone-coderepo.t @@ -0,0 +1,130 @@ +#!perl -w +# Copyright (C) all contributors +# License: AGPL-3.0+ +use v5.12; +use PublicInbox::TestCommon; +use PublicInbox::Import; +use File::Temp; +use Digest::SHA qw(sha1_hex); +require_mods(qw(json Plack::Builder HTTP::Date HTTP::Status)); +require_git '1.8.5'; +require_ok 'PublicInbox::LeiMirror'; +my ($tmpdir, $for_destroy) = tmpdir(); +my $pa = "$tmpdir/src/a.git"; +my $pb = "$tmpdir/src/b.git"; +PublicInbox::Import::init_bare($pa); +my ($stdout, $stderr) = ("$tmpdir/out.log", "$tmpdir/err.log"); +my $pi_config = "$tmpdir/pi_config"; +my $td; +my $tcp = tcp_server(); +my $url = 'http://'.tcp_host_port($tcp).'/'; +my $set_manifest = sub { + my ($m, $f) = @_; + $f //= "$tmpdir/src/manifest.js.gz"; + my $ft = File::Temp->new(TMPDIR => $tmpdir, UNLINK => 0); + PublicInbox::LeiMirror::dump_manifest($m, $ft); + PublicInbox::LeiMirror::ft_rename($ft, $f, 0666); +}; +my $read_manifest = sub { + my ($f) = @_; + open my $fh, '<', $f or xbail "open($f): $!"; + PublicInbox::LeiMirror::decode_manifest($fh, $f, $f); +}; + +my $t0 = time - 1; +my $m; # manifest hashref + +{ + my $rdr = {}; + my $fi_data = './t/git.fast-import-data'; + open $rdr->{0}, '<', $fi_data or xbail "open($fi_data): $!"; + my @git = ('git', "--git-dir=$pa"); + xsys_e([@git, qw(fast-import --quiet)], undef, $rdr); + xsys_e([qw(/bin/cp -Rp a.git b.git)], undef, { -C => "$tmpdir/src" }); + open my $fh, '>', $pi_config or xbail "open($pi_config): $!"; + print $fh <', $f or xbail "open($f): $!"; + print $fh <rel2abs('t/clone-coderepo.psgi') ]; + my $env = { TEST_DOCROOT => "$tmpdir/src", PI_CONFIG => $pi_config }; + $td = start_script($cmd, $env, { 3 => $tcp }); + my $fp = sha1_hex(my $refs = xqx([@git, 'show-ref'])); + $m = { + '/a.git' => { + fingerprint => $fp, + modified => 1, + owner => 'Alice', + }, + '/b.git' => { + fingerprint => $fp, + modified => 1, + owner => 'Bob', + }, + }; + $set_manifest->($m); + $f = "$tmpdir/src/projects.list"; + open $fh, '>', $f, or xbail "open($f): $!"; + print $fh < "$tmpdir/dst/a.git" }), + "Alice\n", 'a.git gitweb.owner set'); +is(xqx([qw(git config gitweb.owner)], { GIT_DIR => "$tmpdir/dst/b.git" }), + "Bob\n", 'b.git gitweb.owner set'); + +my $dst_pl = "$tmpdir/dst/projects.list"; +my $dst_mf = "$tmpdir/dst/manifest.js.gz"; +ok(!-d "$tmpdir/dst/objstore", 'no objstore created w/o forkgroups'); +my $r = $read_manifest->($dst_mf); +is_deeply($r, $m, 'manifest matches'); + +is(PublicInbox::Git::try_cat($dst_pl), "a.git\nb.git\n", + 'wrote projects.list'); + +{ # check symlinks + $m->{'/a.git'}->{symlinks} = [ '/old/a.git' ]; + $set_manifest->($m); + utime($t0, $t0, $dst_mf) or xbail "utime: $!"; + ok(run_script($cmd), 'clone again +symlinks'); + ok(-l "$tmpdir/dst/old/a.git", 'symlink created'); + is(PublicInbox::Git::try_cat($dst_pl), "a.git\nb.git\n", + 'projects.list does not include symlink by default'); + + $r = $read_manifest->($dst_mf); + is_deeply($r, $m, 'updated manifest matches'); +} +{ # cleanup old projects from projects.list + open my $fh, '>>', $dst_pl or xbail $!; + print $fh "gone.git\n" or xbail $!; + close $fh or xbail $!; + + utime($t0, $t0, $dst_mf) or xbail "utime: $!"; + my $rdr = { 2 => \(my $err = '') }; + ok(run_script($cmd, undef, $rdr), 'clone again for expired gone.git'); + is(PublicInbox::Git::try_cat($dst_pl), "a.git\nb.git\n", + 'project list cleaned'); + like($err, qr/no longer exist.*\bgone\.git\b/s, 'gone.git noted'); +} + + +done_testing;