use strict; use warnings; use Test::More; use Test::File qw/file_exists_ok/; use File::Temp qw/tempdir/; use File::Touch qw/touch/; use File::Find::Rule qw//; use File::Basename qw/dirname/; use File::Path qw/mkpath/; use File::Spec qw/catpath/; use_ok('File::CleanupTask'); my $Cleanup = File::CleanupTask->new(); ok($Cleanup, 'created File::CleanupTask instance'); my $temp_dir = File::Temp->tempdir("file_cleanup_test_XXXXX", CLEANUP => 1); my $rah_tests = [ { name => 'backup, no gzip', filenames_given => [ qw( abc.txt def.xml.gz )], filenames_expected => [ qw( backup/abc.txt backup/def.xml.gz )], task_config => { path => 'TEMPDIR', backup_path => 'TEMPDIR/backup', # note: doesn't exist yet }, }, { name => 'backup and gzip', filenames_given => [ qw( abc.txt def.xml.gz )], filenames_expected => [ qw( backup/abc.txt.gz backup/def.xml.gz )], task_config => { path => 'TEMPDIR', backup_gzip => 1, backup_path => 'TEMPDIR/backup', # note: doesn't exist yet }, }, { name => 'backup and gzip, file already exists', filenames_given => [ qw( abc.txt def.xml.gz backup/abc.txt.gz backup/def.xml.gz )], filenames_expected => [ qw( backup/abc.txt.gz backup/def.xml.gz )], task_config => { path => 'TEMPDIR', backup_gzip => 1, backup_path => 'TEMPDIR/backup', # note: doesn't exist yet }, }, { name => 'backup with symlinks', filenames_given => [ qw( abc.txt def.xml.gz )], symlinks_given => [ { symlink => 'sym.link', target => 'abc.txt', } ], filenames_expected => [ qw( backup/abc.txt.gz backup/def.xml.gz )], task_config => { path => 'TEMPDIR', backup_gzip => 1, backup_path => 'TEMPDIR/backup', # note: doesn't exist yet }, } ]; foreach my $rh_test ( @$rah_tests ){ my @a_filenames_given = sort @{$rh_test->{filenames_given}}; my $temp_dir = create_test_files(\@a_filenames_given); SKIP: { ## create symlinks if any if ($rh_test->{symlinks_given}) { _make_symlinks( $rh_test->{symlinks_given}, $temp_dir ) or skip("Unable to create symlinks", 1); } my @a_filenames_expected = sort @{$rh_test->{filenames_expected}}; my %task_config = map { s!TEMPDIR!$temp_dir!; $_ } %{$rh_test->{task_config}}; $Cleanup->run_one_task(\%task_config, $rh_test->{name}); my @a_filenames_after = sort File::Find::Rule->file()->relative()->in( $temp_dir ); is_deeply( \@a_filenames_after, \@a_filenames_expected, "$rh_test->{name} -- directory contains the expected files", ); } } ######################################################################## # # 1. created a temporary directory # 2. creates all files given in $ra_filenames # 3. changes $ra_filenames: prefixes the directory # sub create_test_files { my $ra_filenames = shift; my $temp_dir = tempdir( TEMPLATE => 'ops_cleanup_backup_t', DIR => $temp_dir, CLEANUP => 1 ); ok( -d $temp_dir, "created test dir '$temp_dir'"); my @a_created = (); foreach my $filename ( map { "$temp_dir/$_" } @$ra_filenames ) { ## Create the parent up to the path _ensure_path($filename); touch($filename); file_exists_ok($filename); push(@a_created, $filename); } @$ra_filenames = @a_created; return $temp_dir; } done_testing(); =head2 _make_symlinks Make Symlinks according to the specified configuration $rah_params => [ { symlink => "some/path", target => "some/other/path", }, ... ] =cut sub _make_symlinks { my $rah_params = shift; my $make_in_dir = shift; my $can_symlink = eval { symlink("",""); 1 }; return 0 unless $can_symlink; foreach my $rh_param (@$rah_params) { my $sym_name = File::Spec->catpath('', $make_in_dir, $rh_param->{"symlink"}); my $target_name = File::Spec->catpath('', $make_in_dir, $rh_param->{"target"}); if (!exists $rh_param->{broken}) { symlink($target_name, $sym_name); } else { # Make a broken symlink _touch_am_time( [$target_name]); symlink($target_name, $sym_name); unlink($target_name); } } return 1; } =head2 _ensure_path Given a path to a file, makes sure that the path to its parent directory exists. If not, this directory is created. =cut sub _ensure_path { my $filename = shift; my $dir; if ( $filename =~ m!/$! ) { $dir = $filename; } else { $dir = dirname($filename); } File::Path::mkpath($dir) if $dir; }