Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/MirrorCache/Task/FolderPkgSync.pm
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ sub _sync {
$job->note($realpath => 1);

$schema->resultset('Folder')->add_redirect($path, $realpath);
$minion->enqueue('folder_pkg_sync' => [$realpath] => { queue => $job->info->{queue} });
return $job->finish("redirected to $realpath");
}

return $job->finish('not dir') unless ($root->is_dir($realpath));
Expand Down
12 changes: 12 additions & 0 deletions lib/MirrorCache/Task/FolderSync.pm
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,18 @@ sub _sync {
$job->note($realpath => 1);

$schema->resultset('Folder')->add_redirect($path, $realpath);
$app->backstage->enqueue('folder_sync', $realpath);

my $otherFolder = $schema->resultset('Folder')->find({path => $path});
if ($otherFolder) {
$otherFolder->update({
sync_last => \'CURRENT_TIMESTAMP(3)',
sync_requested => \'coalesce(sync_requested, CURRENT_TIMESTAMP(3))',
sync_scheduled => \'coalesce(sync_scheduled, CURRENT_TIMESTAMP(3))',
scan_requested => \'CURRENT_TIMESTAMP(3)'
});
}
return $job->finish("redirected to $realpath");
}
my $proj = $schema->resultset('Rollout')->project_for_folder($path);
my ($proj_type, $proj_prefix);
Expand Down
3 changes: 1 addition & 2 deletions lib/MirrorCache/WebAPI/Plugin/Dir.pm
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,7 @@ sub _render_dir_from_db {
my $basename = $child->{name};
my $size = $child->{size};
my $mtime = $child->{mtime};
$max_mtime = $mtime unless $max_mtime && $mtime && ($max_mtime > $mtime);
my $desc = $folderDesc{$c->mcbranding}{$dir}{$basename};
if ($json) {
push @files, {
Expand All @@ -663,8 +664,6 @@ sub _render_dir_from_db {
my $encoded = Encode::decode_utf8( './' . $basename );
my $mime_type = $dm->mime || 'text/plain';

$max_mtime = $mtime unless $max_mtime && $mtime && ($max_mtime > $mtime);

push @files, {
url => $encoded,
name => $basename,
Expand Down
111 changes: 111 additions & 0 deletions t/Directory/02-dir-plugin.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
use Mojo::Base -strict;

use Test::More;
use POSIX;
use MirrorCache::WebAPI::Plugin::Dir;

# Define methods for Mock classes
sub MockController::schema { shift->{schema} }
sub MockController::mc { shift->{mc} }
sub MockController::res { shift->{res} }
sub MockController::render {
my $self = shift;
if (scalar(@_) % 2 == 1) {
my $template = shift;
$self->{rendered_template} = $template;
}
$self->{rendered} = { @_ };
}
sub MockController::mcbranding { 'suse' }

sub MockSchema::resultset {
my ($self, $type) = @_;
return bless {}, 'MockRS';
}

sub MockRS::find_with_regex {
return {
1 => {
name => 'file1.txt',
size => 1024,
mtime => 1661211960, # 22-Aug-2022 23:46:00
},
2 => {
name => 'file2.txt',
size => 2048,
mtime => 1661212020, # 22-Aug-2022 23:47:00
}
};
}

sub MockResponse::headers { shift->{headers} }

sub MockHeaders::etag {
my ($self, $etag) = @_;
$self->{etag} = $etag if defined $etag;
return $self->{etag};
}
sub MockHeaders::add {
my ($self, $key, $val) = @_;
$self->{$key} = $val;
}

# Mock the Controller
my $c = bless {
mc => bless({
root => bless({
rooturl => 'http://example.com'
}, 'MockRoot')
}, 'MockMC'),
schema => bless({}, 'MockSchema'),
res => bless({
headers => bless({}, 'MockHeaders')
}, 'MockResponse'),
rendered => undef,
}, 'MockController';

# Also need MockRoot methods
sub MockRoot::rooturl { shift->{rooturl} }

# Mock the Datamodule
my $dm = bless {
c => $c,
json => 0,
browse => 0,
glob_regex => undef,
regex => undef,
folder_sync_last => undef,
folder_sync_requested => undef,
route => 'download',
mime => 'text/plain',
jsontable => 0,
}, 'MockDM';

sub MockDM::c { shift->{c} }
sub MockDM::json { shift->{json} }
sub MockDM::browse { shift->{browse} }
sub MockDM::glob_regex { shift->{glob_regex} }
sub MockDM::regex { shift->{regex} }
sub MockDM::folder_sync_last { shift->{folder_sync_last} }
sub MockDM::folder_sync_requested { shift->{folder_sync_requested} }
sub MockDM::route { shift->{route} }
sub MockDM::mime { shift->{mime} }
sub MockDM::jsontable { shift->{jsontable} }

subtest 'render_dir_from_db max_mtime and warning-free comparison' => sub {
my @warnings;
{
local $SIG{__WARN__} = sub { push @warnings, shift };
MirrorCache::WebAPI::Plugin::Dir::_render_dir_from_db($dm, 1, '/some/dir');
}

is_deeply \@warnings, [], "No warnings generated during rendering";

# Let's verify that the calculated ETag is based on the maximum numeric mtime (1661212020 = 0x630416F4)
# The ETag format is: sprintf('%X', scalar(@files)) . '-' . sprintf('%X', $max_mtime)
# 2 files, so: 2-630416F4
my $expected_etag = sprintf('%X', 2) . '-' . sprintf('%X', 1661212020);
is $c->res->headers->etag, $expected_etag, "ETag matches expected value based on numeric mtime";
};

done_testing();
27 changes: 27 additions & 0 deletions t/environ/15-local-symlink-4.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!lib/test-in-container-environ.sh
set -ex

mc=$(environ mc $(pwd))

$mc/start
$mc/status

# Create folder1 and a symlink pointing to '.' inside it
mkdir -p $mc/dt/folder1
echo "hello" > $mc/dt/folder1/file1.txt
(
cd $mc/dt/folder1
ln -s . Changes
)

# Sync folder1
$mc/backstage/job -e folder_sync -a '["/folder1", 1]'
$mc/backstage/shoot

# Check if a redirect was inserted for /folder1/Changes -> /folder1
$mc/sql_test 1 == "select count(*) from redirect where pathfrom = '/folder1/Changes' and pathto = '/folder1'"

# Check that NO nested redirects like /folder1/Changes/Changes exist
$mc/sql_test 0 == "select count(*) from redirect where pathfrom like '%Changes/Changes%'"

echo success
Loading