Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.masterd.iallocator_unittest.py @ c1912a48

History | View | Annotate | Download (5.1 kB)

1
#!/usr/bin/python
2
#
3

    
4
# Copyright (C) 2012 Google Inc.
5
#
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful, but
12
# WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
# General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
# 02110-1301, USA.
20

    
21

    
22
"""Script for testing ganeti.masterd.iallocator"""
23

    
24
import unittest
25

    
26
from ganeti import compat
27
from ganeti import constants
28
from ganeti import errors
29
from ganeti import objects
30
from ganeti import ht
31
from ganeti.masterd import iallocator
32

    
33
import testutils
34

    
35

    
36
class _StubIAllocator(object):
37
  def __init__(self, success):
38
    self.success = success
39

    
40

    
41
class TestIAReqMultiInstanceAlloc(unittest.TestCase):
42
  def testResult(self):
43
    good_results = [
44
      # First result (all instances "allocate")
45
      [
46
        [["foo", ["a", "b"]],
47
         ["bar", ["c"]],
48
         ["baz", []]],
49
        []
50
      ],
51
      # Second result (partial "allocate", partial "fail")
52
      [
53
        [["bar", ["c", "b"]],
54
         ["baz", ["a"]]],
55
        ["foo"]
56
      ],
57
      # Third result (all instances "fail")
58
      [
59
        [],
60
        ["foo", "bar", "baz"]
61
      ],
62
      ]
63
    bad_results = [
64
      "foobar",
65
      1234,
66
      [],
67
      [[]],
68
      [[], [], []],
69
      ]
70

    
71
    result_fn = iallocator.IAReqMultiInstanceAlloc.REQ_RESULT
72

    
73
    self.assertTrue(compat.all(map(result_fn, good_results)))
74
    self.assertFalse(compat.any(map(result_fn, bad_results)))
75

    
76

    
77
class TestIARequestBase(unittest.TestCase):
78
  def testValidateResult(self):
79
    class _StubReqBase(iallocator.IARequestBase):
80
      MODE = constants.IALLOCATOR_MODE_ALLOC
81
      REQ_RESULT = ht.TBool
82

    
83
    stub = _StubReqBase()
84
    stub.ValidateResult(_StubIAllocator(True), True)
85
    self.assertRaises(errors.ResultValidationError, stub.ValidateResult,
86
                      _StubIAllocator(True), "foo")
87
    stub.ValidateResult(_StubIAllocator(False), True)
88
    # We don't validate the result if the iallocation request was not successful
89
    stub.ValidateResult(_StubIAllocator(False), "foo")
90

    
91

    
92
class _FakeConfigWithNdParams:
93
  def GetNdParams(self, _):
94
    return None
95

    
96

    
97
class TestComputeBasicNodeData(unittest.TestCase):
98
  def setUp(self):
99
    self.fn = compat.partial(iallocator.IAllocator._ComputeBasicNodeData,
100
                             _FakeConfigWithNdParams())
101

    
102
  def testEmpty(self):
103
    self.assertEqual(self.fn({}, None), {})
104

    
105
  def testSimple(self):
106
    node1 = objects.Node(name="node1",
107
                         primary_ip="192.0.2.1",
108
                         secondary_ip="192.0.2.2",
109
                         offline=False,
110
                         drained=False,
111
                         master_candidate=True,
112
                         master_capable=True,
113
                         group="11112222",
114
                         vm_capable=False)
115

    
116
    node2 = objects.Node(name="node2",
117
                         primary_ip="192.0.2.3",
118
                         secondary_ip="192.0.2.4",
119
                         offline=True,
120
                         drained=False,
121
                         master_candidate=False,
122
                         master_capable=False,
123
                         group="11112222",
124
                         vm_capable=True)
125

    
126
    assert node1 != node2
127

    
128
    ninfo = {
129
      "#unused-1#": node1,
130
      "#unused-2#": node2,
131
      }
132

    
133
    self.assertEqual(self.fn(ninfo, None), {
134
      "node1": {
135
        "tags": [],
136
        "primary_ip": "192.0.2.1",
137
        "secondary_ip": "192.0.2.2",
138
        "offline": False,
139
        "drained": False,
140
        "master_candidate": True,
141
        "group": "11112222",
142
        "master_capable": True,
143
        "vm_capable": False,
144
        "ndparams": None,
145
        },
146
      "node2": {
147
        "tags": [],
148
        "primary_ip": "192.0.2.3",
149
        "secondary_ip": "192.0.2.4",
150
        "offline": True,
151
        "drained": False,
152
        "master_candidate": False,
153
        "group": "11112222",
154
        "master_capable": False,
155
        "vm_capable": True,
156
        "ndparams": None,
157
        },
158
      })
159

    
160
  def testOfflineNode(self):
161
    for whitelist in [None, [], set(), ["node1"], ["node2"]]:
162
      result = self.fn({
163
        "node1": objects.Node(name="node1", offline=True)
164
        }, whitelist)
165
      self.assertEqual(len(result), 1)
166
      self.assertTrue(result["node1"]["offline"])
167

    
168
  def testWhitelist(self):
169
    for whitelist in [None, [], set(), ["node1"], ["node2"]]:
170
      result = self.fn({
171
        "node1": objects.Node(name="node1", offline=False)
172
        }, whitelist)
173
      self.assertEqual(len(result), 1)
174

    
175
      if whitelist is None or "node1" in whitelist:
176
        self.assertFalse(result["node1"]["offline"])
177
      else:
178
        self.assertTrue(result["node1"]["offline"])
179

    
180

    
181
if __name__ == "__main__":
182
  testutils.GanetiTestProgram()