9
use MogileFS::Util qw(error_code);
10
use MogileFS::ReplicationPolicy::MultipleHosts;
16
is(rr("min=2 h1[d1=X d2=_] h2[d3=X d4=_]"),
17
"all_good", "all good");
19
# need to get it onto host2...
20
is(rr("min=2 h1[d1=X d2=_] h2[d3=_ d4=_]"),
21
"ideal(3,4)", "need host2");
23
# still needs to be on host2, even though 2 copies on host1
24
is(rr("min=2 h1[d1=X d2=X] h2[d3=_ d4=_]"),
25
"ideal(3,4)", "need host2, even though 2 on host1");
27
# anywhere will do. (can happen on, say, rebalance)
28
is(rr("min=2 h1[d1=_ d2=_] h2[d3=_ d4=_]"),
29
"ideal(1,2,3,4)", "anywhere");
31
# should desperately try d2, since host2 is down
32
is(rr("min=2 h1[d1=X d2=_] h2=down[d3=_ d4=_]"),
35
# should try host3, since host2 is down
36
is(rr("min=2 h1[d1=X d2=_] h2=down[d3=_ d4=_] h3[d5=_ d6=_]"),
39
# need a copy on a non-dead disk on host1
40
is(rr("min=2 h1[d1=_ d2=X,dead] h2=alive[d3=X d4=_]"),
43
# this is an ideal move, since we only have 2 unique hosts:
44
is(rr("min=3 h1[d1=_ d2=X] h2[d3=X d4=_]"),
47
# ... but if we have a 3rd host, it's gotta be there
48
is(rr("min=3 h1[d1=_ d2=X] h2[d3=X d4=_] h3[d5=_]"),
51
# ... unless that host is down, in which case it's back to 1/4,
53
is(rr("min=3 h1[d1=_ d2=X] h2[d3=X d4=_] h3=down[d5=_]"),
56
# too good, uniq hosts > min
57
is(rr("min=2 h1[d1=X d2=_] h2[d3=X d4=_] h3[d5=X]"),
60
# too good, but but with uniq hosts == min
61
is(rr("min=2 h1[d1=X d2=X] h2[d3=X d4=_]"),
64
# be happy with 3 copies, even though two are on same host (that's our max unique hosts)
65
is(rr("min=3 h1[d1=_ d2=X] h2[d3=X d4=X]"),
70
my $ostate = $state; # original
72
MogileFS::Host->t_wipe_singletons;
73
MogileFS::Device->t_wipe_singletons;
74
MogileFS::Config->set_config_no_broadcast("min_free_space", 100);
77
if ($state =~ s/^\bmin=(\d+)\b//) {
85
my $parse_error = sub {
86
die "Can't parse:\n $ostate\n"
88
while ($state =~ s/\bh(\d+)(?:=(.+?))?\[(.+?)\]//) {
89
my ($n, $opts, $devstr) = ($1, $2, $3);
91
die "dup host $n" if $hosts->{$n};
93
my $h = $hosts->{$n} = MogileFS::Host->of_hostid($n);
94
$h->t_init($opts || "alive");
96
foreach my $ddecl (split(/\s+/, $devstr)) {
97
$ddecl =~ /^d(\d+)=([_X])(?:,(\w+))?$/
99
my ($dn, $on_not, $status) = ($1, $2, $3);
100
die "dup device $dn" if $devs->{$dn};
101
my $d = $devs->{$dn} = MogileFS::Device->of_devid($dn);
103
$d->t_init($h->id, $status);
104
if ($on_not eq "X" && $d->dstate->should_have_files) {
109
$parse_error->() if $state =~ /\S/;
111
my $polclass = "MogileFS::ReplicationPolicy::MultipleHosts";
112
my $pol = $polclass->new;
113
my $rr = $pol->replicate_to(
120
return $rr->t_as_string;