~vcs-imports/mogilefs/trunk

« back to all changes in this revision

Viewing changes to server/t/multiple-hosts-replpol.t

  • Committer: hachi
  • Date: 2011-05-27 23:40:03 UTC
  • Revision ID: hachi-20110527234003-hioplx58nt6zb2mx
This has been moved to http://github.com/mogilefs/MogileFS-Server/

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/perl
2
 
 
3
 
use strict;
4
 
use warnings;
5
 
use Test::More;
6
 
use FindBin qw($Bin);
7
 
 
8
 
use MogileFS::Server;
9
 
use MogileFS::Util qw(error_code);
10
 
use MogileFS::ReplicationPolicy::MultipleHosts;
11
 
use MogileFS::Test;
12
 
 
13
 
plan tests => 13;
14
 
 
15
 
# already good.
16
 
is(rr("min=2  h1[d1=X d2=_] h2[d3=X d4=_]"),
17
 
   "all_good", "all good");
18
 
 
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");
22
 
 
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");
26
 
 
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");
30
 
 
31
 
# should desperately try d2, since host2 is down
32
 
is(rr("min=2  h1[d1=X d2=_] h2=down[d3=_ d4=_]"),
33
 
   "desperate(2)");
34
 
 
35
 
# should try host3, since host2 is down
36
 
is(rr("min=2  h1[d1=X d2=_] h2=down[d3=_ d4=_] h3[d5=_ d6=_]"),
37
 
   "ideal(5,6)");
38
 
 
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=_]"),
41
 
   "ideal(1)");
42
 
 
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=_]"),
45
 
   "ideal(1,4)");
46
 
 
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=_]"),
49
 
   "ideal(5)");
50
 
 
51
 
# ... unless that host is down, in which case it's back to 1/4,
52
 
# but desperately
53
 
is(rr("min=3 h1[d1=_ d2=X] h2[d3=X d4=_] h3=down[d5=_]"),
54
 
   "desperate(1,4)");
55
 
 
56
 
# too good, uniq hosts > min
57
 
is(rr("min=2 h1[d1=X d2=_] h2[d3=X d4=_] h3[d5=X]"),
58
 
   "too_good");
59
 
 
60
 
# too good, but but with uniq hosts == min
61
 
is(rr("min=2 h1[d1=X d2=X] h2[d3=X d4=_]"),
62
 
   "too_good");
63
 
 
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]"),
66
 
   "all_good");
67
 
 
68
 
sub rr {
69
 
    my ($state) = @_;
70
 
    my $ostate = $state; # original
71
 
 
72
 
    MogileFS::Host->t_wipe_singletons;
73
 
    MogileFS::Device->t_wipe_singletons;
74
 
    MogileFS::Config->set_config_no_broadcast("min_free_space", 100);
75
 
 
76
 
    my $min = 2;
77
 
    if ($state =~ s/^\bmin=(\d+)\b//) {
78
 
        $min = $1;
79
 
    }
80
 
 
81
 
    my $hosts   = {};
82
 
    my $devs    = {};
83
 
    my $on_devs = [];
84
 
 
85
 
    my $parse_error = sub {
86
 
        die "Can't parse:\n   $ostate\n"
87
 
    };
88
 
    while ($state =~ s/\bh(\d+)(?:=(.+?))?\[(.+?)\]//) {
89
 
        my ($n, $opts, $devstr) = ($1, $2, $3);
90
 
        $opts ||= "";
91
 
        die "dup host $n" if $hosts->{$n};
92
 
 
93
 
        my $h = $hosts->{$n} = MogileFS::Host->of_hostid($n);
94
 
        $h->t_init($opts || "alive");
95
 
 
96
 
        foreach my $ddecl (split(/\s+/, $devstr)) {
97
 
            $ddecl =~ /^d(\d+)=([_X])(?:,(\w+))?$/
98
 
                or $parse_error->();
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);
102
 
            $status ||= "alive";
103
 
            $d->t_init($h->id, $status);
104
 
            if ($on_not eq "X" && $d->dstate->should_have_files) {
105
 
                push @$on_devs, $d;
106
 
            }
107
 
        }
108
 
    }
109
 
    $parse_error->() if $state =~ /\S/;
110
 
 
111
 
    my $polclass = "MogileFS::ReplicationPolicy::MultipleHosts";
112
 
    my $pol = $polclass->new;
113
 
    my $rr = $pol->replicate_to(
114
 
                                fid      => 1,
115
 
                                on_devs  => $on_devs,
116
 
                                all_devs => $devs,
117
 
                                failed   => {},
118
 
                                min      => $min,
119
 
                                );
120
 
    return $rr->t_as_string;
121
 
}
122