1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
use warnings;
use strict;
use Time::HiRes qw(time);
use Data::Dumper;
use AnyEvent;
local $Data::Dumper::Indent = 0;
local $Data::Dumper::Terse = 1;
local $Data::Dumper::Useqq = 1;
local $Data::Dumper::Deepcopy = 1;
use Test::More tests => 54;
BEGIN {
use_ok 'AnyEvent';
use_ok('AnyEvent::Serialize', ':all', 'block_size' => 10);
};
sub rand_array($);
sub compare_object($$);
sub rand_hash($);
my @a;
for (0 .. 9) {
push @a, (50 < rand 100) ? rand_hash 6 : rand_array 6;
# push @a, (50 < rand 100) ? [1,2] : {1,2};
}
$_ = { str => Dumper($_), orig => $_ } for @a;
{
my $counter = 0;
my $cv = condvar AnyEvent;
my (@res, @sres);
for my $i (0 .. $#a) {
deserialize $a[$i]{str} =>
sub {
$res[$i] = { obj => \@_, time => time, order => $counter++ };
$cv->send if $counter == @a * 2;
};
serialize $a[$i]{orig} =>
sub {
my ($s, $rd) = @_;
$sres[$i] = {
str => $s,
recursion => $rd,
time => time,
order => $counter++
};
$cv->send if $counter == @a * 2;
};
}
$cv->recv;
for (0 .. $#res) {
ok compare_object($res[$_]{obj}[0], $a[$_]{orig}),
"$_: object deserialized";
ok !$res[$_]{obj}[1], "$_: no error detected";
ok !$res[$_]{obj}[2], "$_: undeserialized tail is empty";
my $dsr = eval $sres[$_]{str};
ok compare_object($dsr, $a[$_]{orig}),
"$_: object serialized";
ok !$sres[$_]{recursion}, "$_: no recursion detected";
}
ok grep({$res[$_]{time} < $res[$_+1]{time} } 0 .. $#res - 1) > 0,
"Random finish time";
ok grep({$res[$_]{order} < $res[$_+1]{order} } 0 .. $#res - 1) > 0,
"Random order";
}
sub rand_string()
{
my $rstr = '';
my @letters = (
qw(й ц у к е н г ш щ з х ъ ф ы в а п р о л д ж э я ч с м и т ь б ю),
map { chr $_ } 0x20 .. 0x7e
);
$rstr .= $letters[rand @letters] for 0 .. -1 + int rand 20;
return $rstr;
}
sub rand_hash($)
{
my ($deep) = @_;
my %h;
return rand_string if $deep <= 0;
for ( 0 .. $deep ) {
my $key = rand_string;
if (3 > rand 10) {
$h{$key} = rand_string;
} elsif (5 > rand 10) {
$h{$key} = rand_hash($deep - 1);
} else {
$h{$key} = rand_array($deep - 1);
}
}
return \%h;
}
sub rand_array($)
{
my @array;
my ($count) = @_;
return rand_string if $count <= 0;
for (0 .. $count) {
if (3 > rand 10) {
push @array, rand_string;
} elsif (5 > rand 10) {
push @array, rand_hash($count - 1);
} else {
push @array, rand_array($count - 1);
}
}
return \@array;
}
sub compare_object($$)
{
my ($o1, $o2) = @_;
return 0 unless ref($o1) eq ref $o2;
return $o1 eq $o2 unless ref $o1; # SCALAR
return compare_object $$o1, $$o2 if 'SCALAR' eq ref $o1; # SCALARREF
return compare_object $$o1, $$o2 if 'REF' eq ref $o1; # REF
if ('ARRAY' eq ref $o1) {
return 0 unless @$o1 == @$o2;
for (0 .. $#$o1) {
return 0 unless compare_object $o1->[$_], $o2->[$_];
}
return 1;
}
if ('HASH' eq ref $o1) {
return 0 unless keys(%$o1) == keys %$o2;
for (keys %$o1) {
return 0 unless exists $o2->{$_};
return 0 unless compare_object $o1->{$_}, $o2->{$_};
}
return 1;
}
die ref $o1;
}
|