App-MtAws
view release on metacpan or search on metacpan
t/integration/config_engine_upload_file_real.t view on Meta::CPAN
#!/usr/bin/env perl
# mt-aws-glacier - Amazon Glacier sync client
# Copyright (C) 2012-2014 Victor Efimov
# http://mt-aws.com (also http://vs-dev.com) vs@vs-dev.com
# License: GPLv3
#
# This file is part of "mt-aws-glacier"
#
# mt-aws-glacier is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# mt-aws-glacier is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
use strict;
use warnings;
use utf8;
use Test::More tests => 194;
use Test::Deep;
use Carp;
use FindBin;
use lib map { "$FindBin::RealBin/$_" } qw{../lib ../../lib};
use TestUtils 'w_fatal';
use Test::MockModule;
use File::Path;
use File::stat;
use Encode;
use Data::Dumper;
use App::MtAws::Utils;
my $mtroot = get_temp_dir();
# upload_file command parsing test
my ($default_concurrency, $default_partsize) = (4, 16);
# upload-file
my %common = (
journal => 'j',
partsize => $default_partsize,
concurrency => $default_concurrency,
key=>'mykey',
secret => 'mysecret',
region => 'myregion',
protocol => 'http',
vault =>'myvault',
config=>'glacier.cfg',
timeout => 180,
'journal-encoding' => 'UTF-8',
'terminal-encoding' => 'UTF-8',
'config-encoding' => 'UTF-8'
);
#
# some integration testing
#
sub assert_passes_on_filesystem($$%)
{
my ($msg, $query, %result) = @_;
fake_config sub {
disable_validations qw/journal secret key/ => sub {
my $res = config_create_and_parse(@$query);
print Dumper $res->{error_texts} if $res->{errors};
ok !($res->{errors}||$res->{warnings}), $msg;
is $res->{command}, 'upload-file', $msg;
is_deeply($res->{options}, {
%common,
%result
}, $msg);
}
}
}
sub assert_fails_on_filesystem($$%)
{
my ($msg, $query, $novalidations, $error, %opts) = @_;
fake_config sub {
disable_validations qw/journal key secret/, @$novalidations => sub {
my $res = config_create_and_parse(@$query);
print Dumper $res->{options} unless $res->{errors};
ok $res->{errors}, $msg;
ok !defined $res->{warnings}, $msg;
ok !defined $res->{command}, $msg;
cmp_deeply [grep { $_->{format} eq $error } @{ $res->{errors} }], [{%opts, format => $error}], $msg;
}
}
}
sub test_file_and_dir
{
my ($msg, $dir, $filename, $expected, $encoding) = @_;
my $filename_enc = encode("UTF-8", $filename, Encode::DIE_ON_ERR|Encode::LEAVE_SRC);
my $dir_enc = encode("UTF-8", $dir, Encode::DIE_ON_ERR|Encode::LEAVE_SRC);
$encoding ||= "UTF-8";
local $App::MtAws::Utils::_filename_encoding = undef;
assert_passes_on_filesystem $msg,
[qw!upload-file --config glacier.cfg --vault myvault --journal j!, '--filename', $filename_enc, '--dir', $dir_enc,'--filenames-encoding', $encoding],
'name-type' => 'dir',
'data-type' => 'filename',
relfilename => $expected,
dir => $dir,
filename => $filename,
'filenames-encoding' => $encoding;
}
sub fails_file_and_dir
{
my ($msg, $dir, $filename, $error, %opts) = @_;
assert_fails_on_filesystem $msg,
[qw!upload-file --config glacier.cfg --vault myvault --journal j!, '--filename', $filename, '--dir', $dir],
[],
$error, %opts;
}
sub with_save_dir(&)
{
my $curdir = Cwd::getcwd;
shift->();
chdir $curdir or confess;
}
sub with_my_dir($%)
{
my ($d, $cb, @dirs) = (shift, pop, @_);
my $dir = "$mtroot/$d";
with_save_dir {
mkpath binaryfilename $dir;
mkpath binaryfilename "$mtroot/$_" for (@dirs);
chdir binaryfilename $dir or confess;
$cb->($dir);
}
}
sub touch
{
my ($filename, $content) = (@_, "1");
open my $f, ">", binaryfilename $filename or confess;
print $f $content;
close $f;
}
with_my_dir "d1/d2", sub {
touch "myfile";
test_file_and_dir "dir/filename should work with ..",
".", "myfile", "myfile";
test_file_and_dir "dir/filename should work with ..",
"..", "myfile", "d2/myfile";
test_file_and_dir "dir/filename should work with ../..",
"../..", "myfile", "d1/d2/myfile";
};
SKIP: {
skip "Test cannot be performed on character-oriented filesystem", 36 unless can_work_with_non_utf8_files;
for my $encoding (qw/UTF-8 CP1251 KOI8-R/) {
local $App::MtAws::Utils::_filename_encoding = $encoding;
with_my_dir "д1/д2", sub {
touch "мойÑайл";
test_file_and_dir "dir/filename should work with ..",
".", "мойÑайл", "мойÑайл", $encoding;
test_file_and_dir "dir/filename should work with ..",
"../д2", "мойÑайл", "мойÑайл", $encoding;
test_file_and_dir "dir/filename should work with ..",
"..", "мойÑайл", "д2/мойÑайл", $encoding;
test_file_and_dir "dir/filename should work with ../..",
"../..", "мойÑайл", "д1/д2/мойÑайл", $encoding;
};
}
t/integration/config_engine_upload_file_real.t view on Meta::CPAN
};
SKIP: {
skip "Cannot run under root", 24 if $^O eq 'cygwin' || is_posix_root; # too britle even under cygwin non-root
my $restricted_abs = "$mtroot/restricted";
my $normal_abs = "$restricted_abs/normal";
my $file_abs = "$normal_abs/file";
with_my_dir "restricted/normal", "restricted/normal/another", sub {
touch $file_abs;
mkpath "top";
my $file_rel = "file";
my $normal_rel = "../normal";
is stat($file_rel)->ino, stat($file_abs)->ino;
is stat($normal_rel)->ino, stat($normal_abs)->ino;
ok -f $file_rel;
ok -f $file_abs;
ok -d $normal_rel;
ok -d $normal_rel;
test_file_and_dir "dir/filename should work",
"another/..", $file_rel, $file_rel;
test_file_and_dir "dir/filename should work",
"$mtroot/restricted/normal", $file_rel, $file_rel;
chmod 000, $restricted_abs;
ok -f $file_rel;
ok !-f $file_abs;
ok !-d $normal_rel;
ok !-d $normal_abs;
fails_file_and_dir "filename inside dir - dir is unresolvable",
"another/..", $file_rel, 'cannot_resolve_dir', a => 'dir';
fails_file_and_dir "filename inside dir - file is unresolvable",
$mtroot, $file_rel, 'cannot_resolve_file', a => 'filename';
chmod 700, $restricted_abs;
}
};
# TODO: also test with non-ascii filenames
with_my_dir "d1", sub {
touch "myfile";
touch "unreadable";
touch "empty", "";
chmod 000, "unreadable";
assert_fails_on_filesystem "should check --filename for readability",
[qw!upload-file --config glacier.cfg --vault myvault --journal j --set-rel-filename somefile!, '--filename', "notafile"],
[],
'%option a% not a file', a => 'filename', value => 'notafile';
assert_fails_on_filesystem "should check --filename for readability",
[qw!upload-file --config glacier.cfg --vault myvault --journal j --set-rel-filename somefile!, '--filename', "empty"],
[],
'%option a% file size is zero', a => 'filename', value => 'empty';
SKIP: {
skip "Cannot run under root", 4 if is_posix_root;
assert_fails_on_filesystem "should check --filename for readability",
[qw!upload-file --config glacier.cfg --vault myvault --journal j --set-rel-filename somefile!, '--filename', "unreadable"],
[],
'%option a% file not readable', a => 'filename', value => 'unreadable';
}
assert_passes_on_filesystem "should check --filename for readability",
[qw!upload-file --config glacier.cfg --vault myvault --journal j --set-rel-filename somefile!, '--filename', "myfile"],
'name-type' => 'rel-filename',
'data-type' => 'filename',
'set-rel-filename' => 'somefile',
'relfilename' => 'somefile',
filename => 'myfile',
'filenames-encoding' => 'UTF-8';
};
1;
( run in 0.719 second using v1.01-cache-2.11-cpan-b16cb0d3907 )