view release on metacpan or search on metacpan
lib/App/MtAws/ConfigEngine.pm view on Meta::CPAN
our @EXPORT = qw/option options positional command validation message
mandatory optional seen deprecated validate scope
present valid value lists raw_option custom error warning impose explicit/;
our $context; # it's a not a global. always localized in code
# TODOS
#refactor messages %option a% vs %option option%
#options_encoding_error specify source of problem
sub message($;$%)
{
my ($message, $format, %opts) = @_;
$format = $message unless defined $format;
confess "message $message already defined" if defined $context->{messages}->{$message} and !$context->{messages}->{$message}->{allow_redefine};
$context->{messages}->{$message} = { %opts, format => $format };
$message;
}
sub new
lib/App/MtAws/ConfigEngine.pm view on Meta::CPAN
if (ref($_) eq ref({})) {
my $name = $_->{format} || confess "format not defined";
confess qq{message $name not defined} unless $self->{messages}->{$name} and my $format = $self->{messages}->{$name}->{format};
error_to_message($format, %$_);
} else {
$_;
}
} @{$err};
}
sub arrayref_or_undef($)
{
my ($ref) = @_;
defined($ref) && @$ref > 0 ? $ref : undef;
}
sub define($&)
{
my ($self, $block) = @_;
local $context = $self; # TODO: create wrapper like 'localize sub ..'
$block->();
}
sub decode_option_value
{
my ($self, $val) = @_;
my $enc = $self->{cmd_encoding}||confess;
lib/App/MtAws/ConfigEngine.pm view on Meta::CPAN
}
$dest->{$k} = $v->{value};
}
}
$self->{data} = $options;
}
sub assert_option { $context->{options}->{$_} or confess "undeclared option $_"; }
sub option($;%) {
my ($name, %opts) = @_;
confess "option already declared" if $context->{options}->{$name};
if (%opts) {
if (defined $opts{alias}) {
$opts{alias} = [$opts{alias}] if ref $opts{alias} eq ref ''; # TODO: common code for two subs, move out
}
if (defined $opts{deprecated}) {
$opts{deprecated} = [$opts{deprecated}] if ref $opts{deprecated} eq ref '';
lib/App/MtAws/ConfigEngine.pm view on Meta::CPAN
confess "alias $_ already declared" if defined $context->{optaliasmap}->{$_};
$context->{optaliasmap}->{$_} = $name;
}
$context->{deprecated_options}->{$_} = 1 for (@{$opts{deprecated}||[]});
}
$context->{options}->{$name} = { %opts, name => $name } unless $context->{options}->{$name};
return $name;
};
sub positional($;%)
{
option shift, @_, positional => 1;
}
sub options(@) {
map {
confess "option already declared $_" if $context->{options}->{$_};
$context->{options}->{$_} = { name => $_ };
$_
} @_;
};
sub validation(@)
{
my ($name, $message, $cb, %opts) = (shift, shift, pop @_, @_);
confess "undeclared option" unless defined $context->{options}->{$name};
push @{ $context->{options}->{$name}->{validations} }, { %opts, 'message' => $message, cb => $cb }
unless $context->{override_validations} && exists($context->{override_validations}->{$name});
$name;
}
sub command($@)
{
my ($name, $cb, %opts) = (shift, pop, @_); # firs arg is name, last is cb, optional middle is opt
confess "command $name already declared" if defined $context->{commands}->{$name};
confess "alias $name already declared" if defined $context->{aliasmap}->{$name};
if (%opts) {
$opts{alias} = [$opts{alias}] if (defined $opts{alias}) && (ref $opts{alias} eq ref '');
$opts{deprecated} = [$opts{deprecated}] if (defined $opts{deprecated}) && ref $opts{deprecated} eq ref '';
lib/App/MtAws/ConfigEngine.pm view on Meta::CPAN
confess "alias $_ already declared" if defined $context->{aliasmap}->{$_};
$context->{aliasmap}->{$_} = $name;
}
$context->{deprecated_commands}->{$_} = 1 for (@{$opts{deprecated}||[]});
}
$context->{commands}->{$name} = { cb => $cb, %opts };
return;
};
sub _real_option_name($)
{
my ($opt) = @_;
defined($opt->{original_option}) ? $opt->{original_option} : $opt->{name};
}
sub seen
{
my $o = @_ ? shift : $_;
my $option = $context->{options}->{$o} or confess "undeclared option $o";
unless ($option->{seen}) {
lib/App/MtAws/ConfigEngine.pm view on Meta::CPAN
@{$option}{qw/value source/} = (decode($context->{cmd_encoding}||'UTF-8', $v, Encode::DIE_ON_ERR|Encode::LEAVE_SRC), 'positional');
}) {
error("options_encoding_error", encoding => $context->{cmd_encoding}||'UTF-8'); # TODO: actually remove UTF and fix tests
}
}
}
}
$o;
}
sub mandatory(@) {
return map {
my $opt = assert_option;
unless ($opt->{seen}) {
seen;
confess "mandatory positional argument goes after optional one"
if ($opt->{positional} and ($context->{positional_level} ||= 'mandatory') ne 'mandatory');
unless (defined($opt->{value})) {
$opt->{positional} ?
error("positional_mandatory", a => $_, n => scalar @{$context->{positional_backlog}||[]}+1) :
error("mandatory", a => _real_option_name($opt)); # actually does not have much sense
}
}
$_;
} @_;
};
sub optional(@)
{
return map {
seen;
$context->{positional_level} = 'optional' if ($context->{options}->{$_}->{positional});
$_;
} @_;
};
sub deprecated(@)
{
return map {
assert_option;
my $opt = $context->{options}->{ seen() };
confess "positional options can't be deprecated" if $opt->{positional};
if (defined $opt->{value}) {
warning('option_deprecated_for_command', a => _real_option_name $opt) if $opt->{source} eq 'option';
undef $opt->{value};
}
$_;
} @_;
};
sub validate(@)
{
return map {
my $opt = $context->{options}->{seen()};
if (defined($opt->{value}) && !$opt->{validated}) {
$opt->{validated} = $opt->{valid} = 1;
VALIDATION: for my $v (@{ $opt->{validations} }) {
for ($opt->{value}) {
error ({ format => $v->{message}, a => _real_option_name $opt, value => $_}),
$opt->{valid} = 0,
$v->{stop} && last VALIDATION
unless $v->{cb}->();
}
}
};
$_;
} @_;
};
sub scope($@)
{
my $scopename = shift;
return map {
assert_option;
unshift @{$context->{options}->{$_}->{scope}}, $scopename;
$_;
} @_;
};
sub present(@) # TODO: test that it works with arrays
{
my $name = @_ ? shift : $_;
assert_option for $name;
return defined($context->{options}->{$name}->{value})
};
# TODO: test
sub explicit(@) # TODO: test that it works with arrays
{
my $name = @_ ? shift : $_;
return present($name) && $context->{options}->{$name}->{source} eq 'option'
};
sub valid($)
{
my ($name) = @_;
assert_option for $name;
confess "validation not performed yet" unless $context->{options}->{$name}->{validated};
return $context->{options}->{$name}->{valid};
};
sub value($)
{
my ($name) = @_;
assert_option for $name;
confess "option not present" unless defined($context->{options}->{$name}->{value});
return $context->{options}->{$name}->{value};
};
sub impose(@)
{
my ($name, $value) = @_;
assert_option for $name;
my $opt = $context->{options}->{$name};
$opt->{source} = 'impose';
$opt->{value} = $value;
return $name;
};
sub lists(@)
{
my @a = @_;
grep { my $o = $_; first { $_ eq $o->{name} } @a; } @{$context->{option_list}};
}
sub raw_option($)
{
my ($name) = @_;
assert_option for $name;
confess "option not present" unless defined($context->{options}->{$name}->{value});
return $context->{options}->{$name};
};
sub custom($$)
{
my ($name, $value) = @_;
confess if ($context->{options}->{$name});
$context->{options}->{$name} = {source => 'set', value => $value, name => $name, seen => 1 };
return $name;
};
sub error($;%)
{
my ($name, %data) = @_;
push @{$context->{errors}},
defined($context->{messages}->{$name}) ?
{ format => $name, %data } :
(%data ? confess("message '$name' is undefined") : $name);
return;
};
sub warning($;%)
{
my ($name, %data) = @_;
push @{$context->{warnings}},
defined($context->{messages}->{$name}) ?
{ format => $name, %data } :
(%data ? confess("message '$name' is undefined") : $name);
return;
};
sub read_config
lib/App/MtAws/ForkEngine.pm view on Meta::CPAN
use POSIX;
use Exporter 'import';
our @EXPORT_OK = qw/with_forks fork_engine/;
# some DSL
our $FE = undef;
sub fork_engine()
{
$FE||confess;
}
sub with_forks($$&)
{
my ($flag, $options, $cb) = @_;
local $FE = undef;
if ($flag) {
$FE = App::MtAws::ForkEngine->new(options => $options);
$FE->start_children();
if (defined eval {$cb->(); 1;}) {
$FE->terminate_children();
} else {
dump_error(q{parent});
lib/App/MtAws/GlacierRequest.pm view on Meta::CPAN
my $auth = "AWS4-HMAC-SHA256 Credential=$self->{key}/$credentials, SignedHeaders=$signed_headers, Signature=$signature";
push @{$self->{req_headers}}, { name => 'Authorization', value => $auth};
}
sub _max_retries { 100 }
sub _sleep($) { sleep shift }
sub throttle
{
my ($i) = @_;
if ($i <= 5) {
_sleep 1;
} elsif ($i <= 10) {
_sleep 5;
} elsif ($i <= 20) {
_sleep 15;
lib/App/MtAws/HttpSegmentWriter.pm view on Meta::CPAN
use warnings;
use utf8;
use App::MtAws::Utils;
use Fcntl qw/SEEK_SET LOCK_EX/;
use Carp;
use base qw/App::MtAws::HttpWriter/;
# when file not found/etc error happen, it can mean Temp file deleted by another process, so we
# don't need to throw error, most likelly signal will arrive in a few milliseconds
sub delayed_confess(@)
{
sleep 2;
confess @_;
}
sub new
{
my ($class, %args) = @_;
my $self = \%args;
lib/App/MtAws/QueueJobResult.pm view on Meta::CPAN
sub full_new
{
my ($class, %args) = @_;
my $self = $class->new(%args);
$self->{_type} = 'full';
return $self;
}
### Class methods and DSL
sub is_code($)
{
$valid_codes_h{shift()};
}
# state STATE
# returns: list with 2 elements
sub state($)
{
my $class = __PACKAGE__;
confess unless wantarray;
return
$class->partial_new(state => shift),
$class->partial_new(default_code => JOB_RETRY);
}
# job JOB
# returns: list with 2 elements
sub job(@)
{
my ($job, $cb) = @_;
confess unless wantarray;
return
JOB_RETRY,
__PACKAGE__->partial_new(job => { job => $job, $cb ? (cb => $cb) : () } );
}
# task ACTION, sub { ... }
# task ACTION, { k1 => v1, k2 => v2 ... }, sub { ... }
# task ACTION, { k1 => v1, k2 => v2 ... }, \$ATTACHMENT, sub { ... }
# returns: list with 2 elements
sub task(@)
{
confess unless wantarray;
my $class = __PACKAGE__;
confess "at least two args expected" unless @_ >= 2;
my ($task_action, $cb, $task_args, $attachment) = (shift, pop, @_);
if (ref $task_action eq ref {}) {
my $h = $task_action;
($task_action, $task_args, $attachment) = ($h->{action}, $h->{args}, $h->{attachment} ? $h->{attachment} : ());
}
lib/App/MtAws/Utils.pm view on Meta::CPAN
return undef if $abspath eq ''; # workaround RT#47755
# workaround RT#47755 - in case perms problem it tries to return File::Spec->rel2abs
return undef unless -e $abspath && file_inodev($abspath, use_filename_encoding => 0) eq $orig_id;
return $abspath;
}
our $_filename_encoding = 'UTF-8'; # global var
sub set_filename_encoding($) { $_filename_encoding = shift };
sub get_filename_encoding() { $_filename_encoding || confess };
sub binaryfilename(;$)
{
encode(get_filename_encoding, @_ ? shift : $_, Encode::DIE_ON_ERR|Encode::LEAVE_SRC);
}
sub characterfilename(;$)
{
decode(get_filename_encoding, @_ ? shift : $_, Encode::DIE_ON_ERR|Encode::LEAVE_SRC);
}
# TODO: test
sub abs2rel
{
my ($path, $base) = (shift, shift);
confess "too few arguments" unless defined($path) && defined($base);
my (%args) = (use_filename_encoding => 1, @_);
lib/App/MtAws/Utils.pm view on Meta::CPAN
2) File is not a plain file
3) File is not a plain file, but after open (race conditions)
4) File is empty and not_empty specified
5) File is empty and not_empty specified, but after open (race conditions)
NOTE: If you want exceptions for (2) and (4) - check it before open_file. And additional checks inside open_file will
prevent race conditions
=cut
sub open_file($$%)
{
(undef, my $filename, my %args) = @_;
%args = (use_filename_encoding => 1, %args);
my $original_filename = $filename;
my %checkargs = %args;
defined $checkargs{$_} && delete $checkargs{$_} for qw/use_filename_encoding mode file_encoding not_empty binary/;
confess "Unknown argument(s) to open_file: ".join(';', keys %checkargs) if %checkargs;
confess 'Argument "mode" is required' unless defined($args{mode});
lib/App/MtAws/Utils.pm view on Meta::CPAN
my $f = $_[0];
confess unless -f $f; # check for race condition - it was a file when we last checked, but now it's a directory
confess if $args{not_empty} && (! -s $f);
binmode $f if $args{binary};
return $f;
}
sub file_size($%)
{
my $filename = shift;
my (%args) = (use_filename_encoding => 1, @_);
if ($args{use_filename_encoding}) {
$filename = binaryfilename $filename;
}
confess "file not exists" unless -f $filename;
return -s $filename;
}
sub file_exists($%)
{
my $filename = shift;
my (%args) = (use_filename_encoding => 1, @_);
if ($args{use_filename_encoding}) {
$filename = binaryfilename $filename;
}
return -f $filename;
}
sub file_mtime($%)
{
my $filename = shift;
my (%args) = (use_filename_encoding => 1, @_);
if ($args{use_filename_encoding}) {
$filename = binaryfilename $filename;
}
confess "file not exists" unless -f $filename;
return stat($filename)->mtime;
}
# TODO: test
sub file_inodev($%)
{
my $filename = shift;
my (%args) = (use_filename_encoding => 1, @_);
if ($args{use_filename_encoding}) {
$filename = binaryfilename $filename;
}
confess "file not exists" unless -e $filename;
my $s = stat($filename);
$s->dev."-".$s->ino;
}
lib/App/MtAws/Utils.pm view on Meta::CPAN
defined($_[0]) && utf8::is_utf8($_[0]) && (bytes::length($_[0]) != length($_[0]))
}
# if we have ASCII-only data, let's drop UTF-8 flag in order to optimize some regexp stuff
# TODO: write also version which does not check is_utf8 - it's faster when utf8 always set
sub try_drop_utf8_flag
{
Encode::_utf8_off($_[0]) if utf8::is_utf8($_[0]) && (bytes::length($_[0]) == length($_[0]));
}
sub sysreadfull_chk($$$)
{
my $len = $_[2];
sysreadfull(@_) == $len;
}
sub sysreadfull($$$)
{
my ($file, $len) = ($_[0], $_[2]);
my $n = 0;
while ($len - $n) {
my $i = sysread($file, $_[1], $len - $n, $n);
if (defined($i)) {
if ($i == 0) {
return $n;
} else {
$n += $i;
}
} elsif ($!{EINTR}) {
redo;
} else {
return $n ? $n : undef;
}
}
return $n;
}
sub syswritefull_chk($$)
{
my $length = length $_[1];
syswritefull(@_) == $length
}
sub syswritefull($$)
{
my ($file, $len) = ($_[0], length($_[1]));
confess if is_wide_string($_[1]);
my $n = 0;
while ($len - $n) {
my $i = syswrite($file, $_[1], $len - $n, $n);
if (defined($i)) {
$n += $i;
} elsif ($!{EINTR}) {
redo;
lib/App/MtAws/Utils.pm view on Meta::CPAN
$out .= $resp->headers->as_string;
if ($resp->content_type eq 'application/json' && $resp->content && length($resp->content)) {
$out .= "\n".$resp->content;
}
$out .= "\n\n";
$out;
}
sub get_config_var($) # separate function so we can override it in tests
{
$Config{shift()}
}
sub is_64bit_os
{
get_config_var('longsize') >= 8
}
sub is_64bit_time
t/integration/config_engine_filters.t view on Meta::CPAN
use lib map { "$FindBin::RealBin/$_" } qw{../lib ../../lib};
use TestUtils 'w_fatal';
use Test::MockModule;
use Data::Dumper;
sub assert_filters($$@)
{
my ($msg, $queryref, @parsed) = @_;
fake_config sub {
disable_validations qw/journal secret key filename dir/ => sub {
my $res = config_create_and_parse(@$queryref);
#print Dumper $res->{errors};
ok !($res->{errors}||$res->{warnings}), $msg;
is scalar (my @got = @{$res->{options}{filters}{parsed}{filters}}), scalar @parsed;
while (@parsed) {
my $got = shift @got;
my $expected = shift @parsed;
cmp_deeply $got, superhashof $expected;
}
}
}
}
sub assert_fails($$%)
{
my ($msg, $queryref, $novalidations, $error, %opts) = @_;
fake_config sub {
disable_validations qw/journal key secret dir/, @$novalidations => sub {
my $res = config_create_and_parse(@$queryref);
ok $res->{errors}, $msg;
ok !defined $res->{warnings}, $msg;
ok !defined $res->{command}, $msg;
is_deeply $res->{errors}, [{%opts, format => $error}], $msg;
}
t/integration/config_engine_partsize.t view on Meta::CPAN
use strict;
use warnings;
use utf8;
use Test::More tests => 86;
use Test::Deep;
use FindBin;
use lib map { "$FindBin::RealBin/$_" } qw{../lib ../../lib};
use TestUtils 'w_fatal';
use App::MtAws::Utils;
sub assert_partsize($$@) # should have same number of assertions as assert_partsize_error
{
my $msg = shift;;
my $expected = shift;;
my $res = config_create_and_parse(@_);
ok !($res->{errors}||$res->{warnings}), $msg;
is $res->{options}{partsize}, $expected, $msg;
}
sub assert_partsize_error($$@) # should have same number of assertions as assert_partsize
{
my $msg = shift;;
my $error = shift;;
my $res = config_create_and_parse(@_);
ok $res->{errors}, $msg;
cmp_deeply $res->{errors}, $error, $msg;
}
for my $line (
[qw!sync --config glacier.cfg --vault myvault --journal j --dir a --concurrency=1!],
t/integration/config_engine_segment_size.t view on Meta::CPAN
use warnings;
use utf8;
use Test::More tests => 39;
use Test::Deep;
use FindBin;
use lib map { "$FindBin::RealBin/$_" } qw{../lib ../../lib};
use TestUtils 'w_fatal';
sub assert_segment_size($$@)
{
my $msg = shift;;
my $expected = shift;;
my $res = config_create_and_parse(@_);
ok !($res->{errors}||$res->{warnings}), $msg;
is $res->{options}{file_downloads}{'segment-size'}, $expected, $msg;
}
sub assert_segment_error($$@)
{
my $msg = shift;;
my $error = shift;;
my $res = config_create_and_parse(@_);
cmp_deeply $res->{errors}, $error, $msg;
}
for my $line (
[qw!restore-completed --config glacier.cfg --vault myvault --journal j --dir a!],
) {
t/integration/config_engine_sync_new.t view on Meta::CPAN
use warnings;
use utf8;
use Test::More tests => 173;
use Test::Deep;
use FindBin;
use lib map { "$FindBin::RealBin/$_" } qw{../lib ../../lib};
use TestUtils 'w_fatal';
# TODO: reenable when get rid of GetOpt warning
sub assert_options($$@)
{
my $msg = shift;;
my $expected = shift;;
my $res = config_create_and_parse(@_);
ok !($res->{errors}||$res->{warnings}), $msg;
cmp_deeply $res->{options}, superhashof($expected), $msg;
}
sub assert_error($$@)
{
my $msg = shift;;
my $error = shift;;
my $res = config_create_and_parse(@_);
cmp_deeply $res->{errors}, $error, $msg;
}
for my $line (
[qw!sync --config glacier.cfg --vault myvault --journal j --dir a!],
) {
t/integration/config_engine_upload_file.t view on Meta::CPAN
config=>'glacier.cfg',
timeout => 180,
'journal-encoding' => 'UTF-8',
'filenames-encoding' => 'UTF-8',
'terminal-encoding' => 'UTF-8',
'config-encoding' => 'UTF-8'
);
#### PASS
sub assert_passes($$%)
{
my ($msg, $query, %result) = @_;
fake_config sub {
disable_validations qw/journal secret key filename dir/ => sub {
my $res = config_create_and_parse(split(' ', $query));
print Dumper $res->{errors} if $res->{errors};
ok !($res->{errors}||$res->{warnings}), $msg;
is $res->{command}, 'upload-file', $msg;
is_deeply($res->{options}, {
%common,
t/integration/config_engine_upload_file.t view on Meta::CPAN
'data-type' => 'stdin',
stdin => 1,
'check-max-file-size' => 100,
relfilename => 'x/y/z',
'set-rel-filename' => 'x/y/z';
#### FAIL
sub assert_fails($$%)
{
my ($msg, $query, $novalidations, $error, %opts) = @_;
fake_config sub {
disable_validations qw/journal key secret/, @$novalidations => sub {
my $res = config_create_and_parse(split(' ', $query));
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;
}
t/integration/config_engine_upload_file_real.t view on Meta::CPAN
'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;
t/integration/config_engine_upload_file_real.t view on Meta::CPAN
{
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);
}
}
t/integration/fork_engine.t view on Meta::CPAN
my $rootdir = get_temp_dir();
my @TRUE_CMD = ($Config{'perlpath'}, '-e', '0');
print "# STARTED $$ ".time()."\n";
$SIG{ALRM} = sub { print STDERR "ALARM $$ ".time()."\n"; exit(1) };
sub fork_engine_test($%)
{
my ($cnt, %cb) = @_;
no warnings 'redefine';
local ($SIG{INT}, $SIG{USR1}, $SIG{USR2}, $SIG{TERM}, $SIG{HUP}, $SIG{CHLD});
local *App::MtAws::ForkEngine::run_children = sub {
alarm 40;
my ($self, $out, $in) = @_;
confess unless $self->{parent_pid};
$cb{child}->($in, $out, $self->{parent_pid}) if $cb{child};
t/integration/journal_parselines.t view on Meta::CPAN
archive_id => "HdGDbije6lWPT8Q8S3uOWJF6Ou9MWRlrfMGDr6TCrhXuDqJ1pzwKR6XV4l1IZ-VrDd2rlLxDFACqnuJouYTzsT5zd6s2ZEAHfRQFriVbjpFfJ1uWruHRRXIrFIma4PVuz-fp9_pBkA",
job_id => "HdGDbije6lWPT8Q8S3uOWJF6777MWRlrfMGDr688888888888zwKR6XV4l1IZ-VrDd2rlLxDFACqnuJouYTzsT5zd6s2ZEAHfRQFriVbjpFfJ1uWruHRRXIrFIma4PVuz-fp9_pBkA",
size => 7684356,
'time' => 1355666755,
mtime => 1355566755,
relfilename => 'def/abc',
treehash => '1368761bd826f76cae8b8a74b3aae210b476333484c2d612d061d52e36af631a',
};
sub create_journal(@)
{
open F, ">:encoding(UTF-8)", $journal;
print F for (@_);
close F;
}
sub assert_last_line_exception
{
t/lib/TestUtils.pm view on Meta::CPAN
}
};
}
sub get_temp_dir
{
$SIG{INT} = sub { exit(1); }; # Global signal, for cleaning temporary files
tempdir("__AppMtAws_t_${$}_XXXXXXXX", TMPDIR => 1, CLEANUP => 1); # pid needed cause child processes re-use random number generators
}
sub fake_config(@)
{
my ($cb, %data) = (pop @_, @_);
no warnings 'redefine';
local *App::MtAws::ConfigEngine::read_config = sub { %data ? { %data } : { (key=>'mykey', secret => 'mysecret', region => 'myregion') } };
disable_validations($cb);
}
sub no_disable_validations
{
local %disable_validations = ();
t/lib/TestUtils.pm view on Meta::CPAN
'override_validations' => {
journal => undef,
secret => undef,
key => undef,
dir => undef,
},
);
$cb->();
}
sub config_create_and_parse(@)
{
# use Data::Dumper;
# die Dumper {%disable_validations};
my $c = App::MtAws::ConfigDefinition::get_config(%disable_validations);
my $res = $c->parse_options(@_);
$res->{_config} = $c;
wantarray ? ($res->{error_texts}, $res->{warning_texts}, $res->{command}, $res->{options}) : $res;
}
sub capture_stdout($&)
{
local(*STDOUT);
my $enc = 'UTF-8';
$_[0]='';# perl 5.8.x issue warning if undefined $out is used in open() below
open STDOUT, '>', \$_[0] or die "Can't open STDOUT: $!";
binmode STDOUT, ":encoding($enc)";
my $res = $_[1]->();
close STDOUT;
$_[0] = decode($enc, $_[0], Encode::DIE_ON_ERR|Encode::LEAVE_SRC);
$res;
}
sub capture_stderr($&)
{
local(*STDERR);
my $enc = 'UTF-8';
$_[0]='';# perl 5.8.x issue warning if undefined $out is used in open() below
open STDERR, '>', \$_[0] or die "Can't open STDERR: $!";
binmode STDOUT, ":encoding($enc)";
my $res = $_[1]->();
close STDERR;
$_[0] = decode($enc, $_[0], Encode::DIE_ON_ERR|Encode::LEAVE_SRC);
$res;
}
# TODO: call only as assert_raises_exception sub {}, $e - don't omit sub!
sub assert_raises_exception(&@)
{
my ($cb, $exception) = @_;
ok !defined eval { $cb->(); 1 };
my $err = $@;
cmp_deeply $err, superhashof($exception);
return ;
}
our $mock_order_declare;
our $mock_order_realtime;
t/lib/TestUtils.pm view on Meta::CPAN
die $@;
}
};
if ($test_fast_ok_cnt) {
ok 0, "$message - expected $plan tests, but ran ".($plan - $test_fast_ok_cnt);
} else {
ok (1, $message);
}
}
sub with_fork(&&)
{
my ($parent_cb, $child_cb) = @_;
my $ppid = $$;
my $fromchild = new IO::Pipe;
my $tochild = new IO::Pipe;
if (my $pid = fork()) {
my $child_exited = 0;
$fromchild->reader();
$fromchild->autoflush(1);
t/lib/TestUtils.pm view on Meta::CPAN
B::class(B::svref_2object(\$_[0]));
}
sub is_iv_without_pv
{
&get_pv_iv eq 'IV';
}
our $_cached_posix_root = undef;
sub is_posix_root()
{
$_cached_posix_root = do {
if ($^O eq 'cygwin') {
local ($!, $^E, $@);
eval {
require Win32;
Win32::IsAdminUser();
}
} else {
$> == 0;
}
} unless defined $_cached_posix_root;
$_cached_posix_root;
}
sub plan_tests($$)
{
my ($n, $cb) = @_;
if ($ENV{MT_STRESSTEST}){
plan tests => $ENV{MT_STRESSTEST};
for (1..$ENV{MT_STRESSTEST}) {
subtest("d$_", sub {
plan tests => $n;
$cb->();
});
my (undef, $mem) = `ps -p $$ -o rss`;
t/unit/config_engine_new.t view on Meta::CPAN
use Test::Spec;
use Encode;
use FindBin;
use lib map { "$FindBin::RealBin/$_" } qw{../lib ../../lib};
use TestUtils 'w_fatal';
use App::MtAws::ConfigEngine;
use Data::Dumper;
sub Context()
{
$App::MtAws::ConfigEngine::context
}
sub localize(&)
{
local $App::MtAws::ConfigEngine::context;
shift->();
}
describe "command" => sub {
it "should work" => sub {
localize sub {
my $code = sub { $_*2 };
t/unit/config_engine_parse.t view on Meta::CPAN
#
# This time we test both current config and current code together
#
my $max_concurrency = 30;
my $too_big_concurrency = $max_concurrency+1;
sub assert_config_throw_error($$$)
{
my ($config, $errorre, $text) = @_;
fake_config %$config => sub {
disable_validations 'journal' => sub {
my ($errors, $warnings, $command, $result) = config_create_and_parse(split(' ', $_ ));
ok( $errors && $errors->[0] =~ $errorre, $text);
}
}
}
t/unit/exceptions.t view on Meta::CPAN
is 'My message :NULL:', exception_message(exception 'code' => 'My message %04d a_42%', b_42 => 42);
is 'My message :NULL:', exception_message(exception 'code' => 'My message %a_42%', b_42 => 42);
is 'My message :NULL:', exception_message(exception 'code' => 'My message %string a_42%', b_42 => 42);
ok exception_message(exception 'code' => 'My message %string a_42%', a_42 => 42, c_42=>33);
# dump_error
sub test_error(&$$)
{
my ($cb, $where, $e) = @_;
capture_stderr my $out, sub {
eval { die $e };
dump_error($where);
};
$cb->($out, $@);
}
t/unit/exceptions.t view on Meta::CPAN
} '', 'somestring';
test_error {
my ($out, $err) = @_;
ok $out =~ /^UNEXPECTED ERROR \(here\): somestring/;
} 'here', 'somestring';
# TODO: check also that 'next' is called!
sub check_localized(&)
{
local $@ = 'checkme';
local $! = ENOMEM;
shift->();
is $@, 'checkme', "should not clobber eval error";
is $!+0, ENOMEM, "should not clobber errno";
}
# test get_errno with argument
{
t/unit/filter.t view on Meta::CPAN
'ss' => 'Ã',
'Ã' => 'ss',
);
is length('Ã'), 1; # make sure we're running unicode
#
# _filters_to_pattern
#
sub assert_parse_filter_error($$)
{
my ($data, $err) = @_;
my $F = App::MtAws::Filter->new();
ok ! defined $F->_filters_to_pattern($data);
is $F->{error}, $err;
}
sub assert_parse_filter_ok(@)
{
my ($expected, @data) = (pop, @_);
my $F = App::MtAws::Filter->new();
ok !$F->{error};
cmp_deeply [$F->_filters_to_pattern(@data)], $expected;
}
my @spaces = ('', ' ', ' ');
my @onespace = ('', ' ');
t/unit/open_file.t view on Meta::CPAN
my $mtroot = get_temp_dir();
my $tmp_file = "$mtroot/open_file_test";
unlink $tmp_file;
rmtree $tmp_file;
sub new_stack(&)
{
local $OpenStack = [];
local $BinmodeStack = [];
shift->();
}
sub last_call()
{
$OpenStack->[0]
}
#
# mode
#
ok ! defined eval { open_file(my $f, $tmp_file); 1};