Implements tests for MogileFS::Store::retry_on_deadlock
[MogileFS-Server.git] / t / replpolicy.t
bloba11c6cd932e36ba67b43415f28b13e8a1240190d
1 # -*-perl-*-
3 use strict;
4 use warnings;
5 use Test::More tests => 11;
6 use Data::Dumper;
7 use Carp qw(croak);
9 use MogileFS::ReplicationPolicy::MultipleHosts;
12     my %all_devs;
14     for my $i (1..3) {
15         $all_devs{$i} = MogileFS::Test::Device->new(
16             hostid          => 1,
17             id              => $i,
18             state           => "alive",
19             percent_free    => 0,
20             should_get_replicated_files => 0,
21         );
22     }
23     for my $i (4..6) {
24         $all_devs{$i} = MogileFS::Test::Device->new(
25             hostid          => 2,
26             id              => $i,
27             state           => "alive",
28             percent_free    => 0,
29             should_get_replicated_files => 0,
30         );
31     }
32     for my $i (7..9) {
33         $all_devs{$i} = MogileFS::Test::Device->new(
34             hostid          => 3,
35             id              => $i,
36             state           => "alive",
37             percent_free    => .2,
38             should_get_replicated_files => 1,
39         );
40     }
41     for my $i (10..12) {
42         $all_devs{$i} = MogileFS::Test::Device->new(
43             hostid          => 4,
44             id              => $i,
45             state           => "alive",
46             percent_free    => .2,
47             should_get_replicated_files => 1,
48         );
49     }
51     # Now for the actual tests
53     {
54         my $res = run(
55             mindevcount  => 3,
56             policy_class => "MogileFS::ReplicationPolicy::MultipleHosts",
57             on_devs      => [ $all_devs{4}, $all_devs{7}, $all_devs{10} ],
58             all_devs     => \%all_devs,
59         );
61         ok($res->is_happy, "Expected happiness");
62         ok(!$res->too_happy, "... but not too happy");
63     }
65     {
66         my $res = run(
67             mindevcount  => 3,
68             policy_class => "MogileFS::ReplicationPolicy::MultipleHosts",
69             on_devs      => [ $all_devs{1}, $all_devs{4}, $all_devs{7}, $all_devs{10} ],
70             all_devs     => \%all_devs,
71         );
73         ok($res->is_happy, "Expected happiness");
74         ok($res->too_happy, "... and too happy too");
75     }
77     {
78         my $res = run(
79             mindevcount  => 3,
80             policy_class => "MogileFS::ReplicationPolicy::MultipleHosts",
81             on_devs      => [ $all_devs{1}, $all_devs{2}, $all_devs{4} ],
82             all_devs     => \%all_devs,
83         );
85         ok(!$res->is_happy, "Expected unhappiness");
87         my @ideals = $res->copy_to_one_of_ideally;
88         ok(@ideals, "List of ideal devices");
90         my @desperate = $res->copy_to_one_of_desperate;
91         is(@desperate, 0, "Empty list of desperate devices");
92     }
94     {
95         my $res = run(
96             mindevcount  => 3,
97             policy_class => "MogileFS::ReplicationPolicy::MultipleHosts",
98             on_devs      => [ $all_devs{7}, $all_devs{10} ],
99             all_devs     => \%all_devs,
100         );
102         ok(!$res->is_happy, "Expected unhappiness");
104         my @ideals = $res->copy_to_one_of_ideally;
105         is(@ideals, 0, "No ideal devices");
107         my @desperate = $res->copy_to_one_of_desperate;
108         ok(@desperate, "List of desperate devices");
109     }
111     {
112         my $res = run(
113             mindevcount  => 3,
114             policy_class => "MogileFS::ReplicationPolicy::MultipleHosts",
115             on_devs      => [ $all_devs{7}, $all_devs{10}, $all_devs{11} ],
116             all_devs     => \%all_devs,
117         );
119         ok($res->temp_fail, "Expected temporary failure");
120     }
123 sub run {
124     my %args = @_;
126     my $fidid        = delete($args{fidid})        || 1;
127     my $mindevcount  = delete($args{mindevcount})  || croak "mindevcount arg required";
128     my $policy_class = delete($args{policy_class}) || croak "policy_class arg required";
129     my $on_devs      = delete($args{on_devs})      || croak "on_devs arg required";
130     my $all_devs     = delete($args{all_devs})     || croak "all_devs arg required";
131     my $failed      = delete($args{failed})        || {};
133     eval "use $policy_class";
134     my $policy = $policy_class->new;
135     my $class = MogileFS::Test::Class->new(
136         repl_policy_obj => $policy,
137         mindevcount => $mindevcount,
138     );
139     my $devfid = MogileFS::Test::DevFID->new(
140         id    => $fidid,
141         class => $class,
142     );
144     my $polobj = $class->repl_policy_obj;
146     return $polobj->replicate_to(
147         fid      => $fidid,
148         on_devs  => $on_devs,
149         all_devs => $all_devs,
150         failed   => $failed,
151         min      => $mindevcount,
152     );
155 package MogileFS::Test::Device;
157 use MogileFS::DeviceState;
158 use Carp qw(croak);
160 sub new {
161     my $class = shift;
163     my %opts = @_;
165     my $self = bless {}, (ref $class || $class);
167     foreach my $optkey (qw(id hostid state should_get_replicated_files percent_free)) {
168         croak "$optkey argument not supplied" unless exists $opts{$optkey};
169         $self->{$optkey} = delete $opts{$optkey};
170     }
172     croak "Extra args:" if (keys %opts);
174     $self->{dstate} = MogileFS::DeviceState->of_string($self->{state});
176     return $self;
179 sub hostid {
180     return $_[0]->{hostid};
183 sub id {
184     return $_[0]->{id};
187 sub devid {
188     return $_[0]->{id};
191 sub dstate {
192     return $_[0]->{dstate};
195 sub should_get_replicated_files {
196     return $_[0]->{should_get_replicated_files};
199 sub percent_free {
200     return $_[0]->{percent_free};
203 package MogileFS::Test::DevFID;
205 use strict;
206 use warnings;
208 sub new {
209     my $class = shift;
210     my %opts = @_;
212     my $self = bless {}, (ref $class || $class);
214     foreach my $optkey (qw(id class)) {
215         $self->{$optkey} = delete $opts{$optkey} || die("$optkey argument not supplied");
216     }
218     die "Extra args:" if (keys %opts);
220     return $self;
223 sub id {
224     return $_[0]->{id};
227 sub class {
228     return $_[0]->{class};
231 package MogileFS::Test::Class;
233 use strict;
234 use warnings;
236 sub new {
237     my $class = shift;
239     my %opts = @_;
241     my $self = bless {}, (ref $class || $class);
243     foreach my $optkey (qw(repl_policy_obj mindevcount)) {
244         $self->{$optkey} = delete $opts{$optkey} || die("$optkey argument not supplied");
245     }
247     die "Extra args:" if (keys %opts);
249     return $self;
252 sub repl_policy_obj {
253     return $_[0]->{repl_policy_obj};
256 sub mindevcount {
257     return $_[0]->{mindevcount};