Emit detailed warning on unuseable default db dirs

This commit is contained in:
Jared Johnson 2015-03-09 16:59:51 -05:00
parent 1ae8ed206f
commit 88c55ed9a3
3 changed files with 79 additions and 16 deletions

View File

@ -186,14 +186,41 @@ sub dir {
return $self->{dir} = $dir; return $self->{dir} = $dir;
} }
return $self->{dir} if $self->{dir}; return $self->{dir} if $self->{dir};
my @err;
for my $d ( $self->candidate_dirs ) { for my $d ( $self->candidate_dirs ) {
# Ignore invalid directories for static default directories # Ignore invalid directories for static default directories
my $is_valid; my $is_valid;
eval { $is_valid = $self->validate_dir($d); }; eval { $is_valid = $self->validate_dir($d); };
next if $@; if ($@) {
next if !$is_valid; push @err, $@;
return $self->{dir} = $d; # first match wins next;
}
else {
$self->{dir} = $d; # first match wins
last;
}
} }
if ( !$self->{dir} ) {
my $err = join "\n",
"Unable to find a useable database directory!",
"",
@err;
die $err;
}
if (@err) {
my $err = join "\n",
"Encountered errors while selecting database directory:",
"",
@err,
"Selected database directory: $self->{dir}. Data is now stored in:",
"",
$self->path,
"",
"It is recommended to manually specify a useable database directory",
"and move any important data into this directory.\n";
warn $err;
}
return $self->{dir};
} }
sub candidate_dirs { sub candidate_dirs {

View File

@ -358,9 +358,10 @@ sub test_init_dbm {
my ($self) = @_; my ($self) = @_;
delete $self->{db}; delete $self->{db};
delete $self->{_args}{redis}; delete $self->{_args}{redis};
$self->{_args}{db_dir} = 't/tmp';
$self->init_db; $self->init_db;
is( $self->db->name, 'greylist', 'init_dbm() sets correct db name' ); is( $self->db->name, 'greylist', 'init_dbm() sets correct db name' );
is( $self->db->path, 't/config/greylist.dbm', 'init_dbm() sets correct path' ); is( $self->db->path, 't/tmp/greylist.dbm', 'init_dbm() sets correct path' );
is( ref $self->db, 'Qpsmtpd::DB::File::DBM', 'init_dbm() gives DBM object' ); is( ref $self->db, 'Qpsmtpd::DB::File::DBM', 'init_dbm() gives DBM object' );
} }

View File

@ -145,18 +145,53 @@ sub __validate_dir {
sub __dir { sub __dir {
my $db2 = Qpsmtpd::DB::File::DBM->new( name => 'dirtest' ); my $db2 = Qpsmtpd::DB::File::DBM->new( name => 'dirtest' );
is( $db2->dir(), 't/config', 'default directory' ); {
delete $db2->{dir}; local $SIG{__WARN__} = sub {
$db2->candidate_dirs('_invalid','t/Test'); warn @_ if $_[0] !~ /selecting database directory/;
is( $db2->dir, 't/Test', 'skip invalid candidate dirs' ); };
$db2->{dir} = '_cached'; is( $db2->dir(), 't/config', 'default directory' );
is( $db2->dir(), '_cached', 'cached directory' ); delete $db2->{dir};
is( $db2->dir('t/Test'), 't/Test', 'passing candidate dirs resets cache' ); $db2->candidate_dirs('_invalid','t/Test');
delete $db2->{dir}; is( $db2->dir, 't/Test', 'skip invalid candidate dirs' );
$db2->candidate_dirs('_invalid'); $db2->{dir} = '_cached';
is( $db2->dir, 't/config', 'invalid candidate dirs reverts to default' ); is( $db2->dir(), '_cached', 'cached directory' );
eval { $db2->dir('_invalid'); }; is( $db2->dir('t/Test'), 't/Test', 'passing candidate dirs resets cache' );
is( $@, "DB directory '_invalid' does not exist\n", 'die on invalid dir' ); delete $db2->{dir};
$db2->candidate_dirs('_invalid');
is( $db2->dir, 't/config', 'invalid candidate dirs reverts to default' );
eval { $db2->dir('_invalid'); };
is( $@, "DB directory '_invalid' does not exist\n", 'die on invalid dir' );
}
{
delete $db2->{dir};
my $warned;
local $SIG{__WARN__} = sub {
warn @_ if $_[0] !~ /selecting database directory/;
$warned .= join '', @_;
};
$db2->candidate_dirs('_invalid2','t/Test');
is( $db2->dir(), 't/Test', 'default directory' );
my $expected_warning =
"Encountered errors while selecting database directory:
DB directory '_invalid2' does not exist
Selected database directory: t/Test. Data is now stored in:
t/Test/dirtest.dbm
It is recommended to manually specify a useable database directory
and move any important data into this directory.\n";
is( $warned, $expected_warning, 'Emit warning on bad directories' );
delete $db2->{dir};
$db2->{candidate_dirs} = ['/___invalid___'];
my $expected_err =
"Unable to find a useable database directory!
DB directory '/___invalid___' does not exist\n";
eval { $db2->dir() };
is( $@, $expected_err, 'Die on no valid directories' );
}
} }
sub __untie_gotcha { sub __untie_gotcha {