Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.masterd.iallocator_unittest.py @ 14933c17

History | View | Annotate | Download (8 kB)

1 33b4fa9f René Nussbaumer
#!/usr/bin/python
2 33b4fa9f René Nussbaumer
#
3 33b4fa9f René Nussbaumer
4 33b4fa9f René Nussbaumer
# Copyright (C) 2012 Google Inc.
5 33b4fa9f René Nussbaumer
#
6 33b4fa9f René Nussbaumer
# This program is free software; you can redistribute it and/or modify
7 33b4fa9f René Nussbaumer
# it under the terms of the GNU General Public License as published by
8 33b4fa9f René Nussbaumer
# the Free Software Foundation; either version 2 of the License, or
9 33b4fa9f René Nussbaumer
# (at your option) any later version.
10 33b4fa9f René Nussbaumer
#
11 33b4fa9f René Nussbaumer
# This program is distributed in the hope that it will be useful, but
12 33b4fa9f René Nussbaumer
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 33b4fa9f René Nussbaumer
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 33b4fa9f René Nussbaumer
# General Public License for more details.
15 33b4fa9f René Nussbaumer
#
16 33b4fa9f René Nussbaumer
# You should have received a copy of the GNU General Public License
17 33b4fa9f René Nussbaumer
# along with this program; if not, write to the Free Software
18 33b4fa9f René Nussbaumer
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 33b4fa9f René Nussbaumer
# 02110-1301, USA.
20 33b4fa9f René Nussbaumer
21 33b4fa9f René Nussbaumer
22 33b4fa9f René Nussbaumer
"""Script for testing ganeti.masterd.iallocator"""
23 33b4fa9f René Nussbaumer
24 33b4fa9f René Nussbaumer
import unittest
25 33b4fa9f René Nussbaumer
26 33b4fa9f René Nussbaumer
from ganeti import compat
27 33b4fa9f René Nussbaumer
from ganeti import constants
28 33b4fa9f René Nussbaumer
from ganeti import errors
29 fb60bc6a Michael Hanselmann
from ganeti import objects
30 33b4fa9f René Nussbaumer
from ganeti import ht
31 33b4fa9f René Nussbaumer
from ganeti.masterd import iallocator
32 33b4fa9f René Nussbaumer
33 33b4fa9f René Nussbaumer
import testutils
34 33b4fa9f René Nussbaumer
35 33b4fa9f René Nussbaumer
36 33b4fa9f René Nussbaumer
class _StubIAllocator(object):
37 33b4fa9f René Nussbaumer
  def __init__(self, success):
38 33b4fa9f René Nussbaumer
    self.success = success
39 33b4fa9f René Nussbaumer
40 33b4fa9f René Nussbaumer
41 33b4fa9f René Nussbaumer
class TestIAReqMultiInstanceAlloc(unittest.TestCase):
42 33b4fa9f René Nussbaumer
  def testResult(self):
43 33b4fa9f René Nussbaumer
    good_results = [
44 33b4fa9f René Nussbaumer
      # First result (all instances "allocate")
45 33b4fa9f René Nussbaumer
      [
46 33b4fa9f René Nussbaumer
        [["foo", ["a", "b"]],
47 33b4fa9f René Nussbaumer
         ["bar", ["c"]],
48 33b4fa9f René Nussbaumer
         ["baz", []]],
49 33b4fa9f René Nussbaumer
        []
50 33b4fa9f René Nussbaumer
      ],
51 33b4fa9f René Nussbaumer
      # Second result (partial "allocate", partial "fail")
52 33b4fa9f René Nussbaumer
      [
53 33b4fa9f René Nussbaumer
        [["bar", ["c", "b"]],
54 33b4fa9f René Nussbaumer
         ["baz", ["a"]]],
55 33b4fa9f René Nussbaumer
        ["foo"]
56 33b4fa9f René Nussbaumer
      ],
57 33b4fa9f René Nussbaumer
      # Third result (all instances "fail")
58 33b4fa9f René Nussbaumer
      [
59 33b4fa9f René Nussbaumer
        [],
60 33b4fa9f René Nussbaumer
        ["foo", "bar", "baz"]
61 33b4fa9f René Nussbaumer
      ],
62 33b4fa9f René Nussbaumer
      ]
63 33b4fa9f René Nussbaumer
    bad_results = [
64 33b4fa9f René Nussbaumer
      "foobar",
65 33b4fa9f René Nussbaumer
      1234,
66 33b4fa9f René Nussbaumer
      [],
67 33b4fa9f René Nussbaumer
      [[]],
68 33b4fa9f René Nussbaumer
      [[], [], []],
69 33b4fa9f René Nussbaumer
      ]
70 33b4fa9f René Nussbaumer
71 33b4fa9f René Nussbaumer
    result_fn = iallocator.IAReqMultiInstanceAlloc.REQ_RESULT
72 33b4fa9f René Nussbaumer
73 33b4fa9f René Nussbaumer
    self.assertTrue(compat.all(map(result_fn, good_results)))
74 33b4fa9f René Nussbaumer
    self.assertFalse(compat.any(map(result_fn, bad_results)))
75 33b4fa9f René Nussbaumer
76 33b4fa9f René Nussbaumer
77 33b4fa9f René Nussbaumer
class TestIARequestBase(unittest.TestCase):
78 33b4fa9f René Nussbaumer
  def testValidateResult(self):
79 33b4fa9f René Nussbaumer
    class _StubReqBase(iallocator.IARequestBase):
80 33b4fa9f René Nussbaumer
      MODE = constants.IALLOCATOR_MODE_ALLOC
81 33b4fa9f René Nussbaumer
      REQ_RESULT = ht.TBool
82 33b4fa9f René Nussbaumer
83 33b4fa9f René Nussbaumer
    stub = _StubReqBase()
84 33b4fa9f René Nussbaumer
    stub.ValidateResult(_StubIAllocator(True), True)
85 33b4fa9f René Nussbaumer
    self.assertRaises(errors.ResultValidationError, stub.ValidateResult,
86 33b4fa9f René Nussbaumer
                      _StubIAllocator(True), "foo")
87 33b4fa9f René Nussbaumer
    stub.ValidateResult(_StubIAllocator(False), True)
88 33b4fa9f René Nussbaumer
    # We don't validate the result if the iallocation request was not successful
89 33b4fa9f René Nussbaumer
    stub.ValidateResult(_StubIAllocator(False), "foo")
90 33b4fa9f René Nussbaumer
91 33b4fa9f René Nussbaumer
92 fb60bc6a Michael Hanselmann
class _FakeConfigWithNdParams:
93 fb60bc6a Michael Hanselmann
  def GetNdParams(self, _):
94 fb60bc6a Michael Hanselmann
    return None
95 fb60bc6a Michael Hanselmann
96 fb60bc6a Michael Hanselmann
97 fb60bc6a Michael Hanselmann
class TestComputeBasicNodeData(unittest.TestCase):
98 fb60bc6a Michael Hanselmann
  def setUp(self):
99 fb60bc6a Michael Hanselmann
    self.fn = compat.partial(iallocator.IAllocator._ComputeBasicNodeData,
100 fb60bc6a Michael Hanselmann
                             _FakeConfigWithNdParams())
101 fb60bc6a Michael Hanselmann
102 fb60bc6a Michael Hanselmann
  def testEmpty(self):
103 fb60bc6a Michael Hanselmann
    self.assertEqual(self.fn({}, None), {})
104 fb60bc6a Michael Hanselmann
105 fb60bc6a Michael Hanselmann
  def testSimple(self):
106 fb60bc6a Michael Hanselmann
    node1 = objects.Node(name="node1",
107 fb60bc6a Michael Hanselmann
                         primary_ip="192.0.2.1",
108 fb60bc6a Michael Hanselmann
                         secondary_ip="192.0.2.2",
109 fb60bc6a Michael Hanselmann
                         offline=False,
110 fb60bc6a Michael Hanselmann
                         drained=False,
111 fb60bc6a Michael Hanselmann
                         master_candidate=True,
112 fb60bc6a Michael Hanselmann
                         master_capable=True,
113 fb60bc6a Michael Hanselmann
                         group="11112222",
114 fb60bc6a Michael Hanselmann
                         vm_capable=False)
115 fb60bc6a Michael Hanselmann
116 fb60bc6a Michael Hanselmann
    node2 = objects.Node(name="node2",
117 fb60bc6a Michael Hanselmann
                         primary_ip="192.0.2.3",
118 fb60bc6a Michael Hanselmann
                         secondary_ip="192.0.2.4",
119 fb60bc6a Michael Hanselmann
                         offline=True,
120 fb60bc6a Michael Hanselmann
                         drained=False,
121 fb60bc6a Michael Hanselmann
                         master_candidate=False,
122 fb60bc6a Michael Hanselmann
                         master_capable=False,
123 fb60bc6a Michael Hanselmann
                         group="11112222",
124 fb60bc6a Michael Hanselmann
                         vm_capable=True)
125 fb60bc6a Michael Hanselmann
126 fb60bc6a Michael Hanselmann
    assert node1 != node2
127 fb60bc6a Michael Hanselmann
128 fb60bc6a Michael Hanselmann
    ninfo = {
129 fb60bc6a Michael Hanselmann
      "#unused-1#": node1,
130 fb60bc6a Michael Hanselmann
      "#unused-2#": node2,
131 fb60bc6a Michael Hanselmann
      }
132 fb60bc6a Michael Hanselmann
133 fb60bc6a Michael Hanselmann
    self.assertEqual(self.fn(ninfo, None), {
134 fb60bc6a Michael Hanselmann
      "node1": {
135 fb60bc6a Michael Hanselmann
        "tags": [],
136 fb60bc6a Michael Hanselmann
        "primary_ip": "192.0.2.1",
137 fb60bc6a Michael Hanselmann
        "secondary_ip": "192.0.2.2",
138 fb60bc6a Michael Hanselmann
        "offline": False,
139 fb60bc6a Michael Hanselmann
        "drained": False,
140 fb60bc6a Michael Hanselmann
        "master_candidate": True,
141 fb60bc6a Michael Hanselmann
        "group": "11112222",
142 fb60bc6a Michael Hanselmann
        "master_capable": True,
143 fb60bc6a Michael Hanselmann
        "vm_capable": False,
144 fb60bc6a Michael Hanselmann
        "ndparams": None,
145 fb60bc6a Michael Hanselmann
        },
146 fb60bc6a Michael Hanselmann
      "node2": {
147 fb60bc6a Michael Hanselmann
        "tags": [],
148 fb60bc6a Michael Hanselmann
        "primary_ip": "192.0.2.3",
149 fb60bc6a Michael Hanselmann
        "secondary_ip": "192.0.2.4",
150 fb60bc6a Michael Hanselmann
        "offline": True,
151 fb60bc6a Michael Hanselmann
        "drained": False,
152 fb60bc6a Michael Hanselmann
        "master_candidate": False,
153 fb60bc6a Michael Hanselmann
        "group": "11112222",
154 fb60bc6a Michael Hanselmann
        "master_capable": False,
155 fb60bc6a Michael Hanselmann
        "vm_capable": True,
156 fb60bc6a Michael Hanselmann
        "ndparams": None,
157 fb60bc6a Michael Hanselmann
        },
158 fb60bc6a Michael Hanselmann
      })
159 fb60bc6a Michael Hanselmann
160 fb60bc6a Michael Hanselmann
  def testOfflineNode(self):
161 fb60bc6a Michael Hanselmann
    for whitelist in [None, [], set(), ["node1"], ["node2"]]:
162 fb60bc6a Michael Hanselmann
      result = self.fn({
163 fb60bc6a Michael Hanselmann
        "node1": objects.Node(name="node1", offline=True)
164 fb60bc6a Michael Hanselmann
        }, whitelist)
165 fb60bc6a Michael Hanselmann
      self.assertEqual(len(result), 1)
166 fb60bc6a Michael Hanselmann
      self.assertTrue(result["node1"]["offline"])
167 fb60bc6a Michael Hanselmann
168 fb60bc6a Michael Hanselmann
  def testWhitelist(self):
169 fb60bc6a Michael Hanselmann
    for whitelist in [None, [], set(), ["node1"], ["node2"]]:
170 fb60bc6a Michael Hanselmann
      result = self.fn({
171 fb60bc6a Michael Hanselmann
        "node1": objects.Node(name="node1", offline=False)
172 fb60bc6a Michael Hanselmann
        }, whitelist)
173 fb60bc6a Michael Hanselmann
      self.assertEqual(len(result), 1)
174 fb60bc6a Michael Hanselmann
175 fb60bc6a Michael Hanselmann
      if whitelist is None or "node1" in whitelist:
176 fb60bc6a Michael Hanselmann
        self.assertFalse(result["node1"]["offline"])
177 fb60bc6a Michael Hanselmann
      else:
178 fb60bc6a Michael Hanselmann
        self.assertTrue(result["node1"]["offline"])
179 fb60bc6a Michael Hanselmann
180 20529708 Helga Velroyen
class TestProcessStorageInfo(unittest.TestCase):
181 20529708 Helga Velroyen
182 20529708 Helga Velroyen
  def setUp(self):
183 20529708 Helga Velroyen
    self.free_storage_file = 23
184 20529708 Helga Velroyen
    self.total_storage_file = 42
185 20529708 Helga Velroyen
    self.free_storage_lvm = 69
186 20529708 Helga Velroyen
    self.total_storage_lvm = 666
187 20529708 Helga Velroyen
    self.space_info = [{"name": "mynode",
188 20529708 Helga Velroyen
                       "type": constants.ST_FILE,
189 20529708 Helga Velroyen
                       "storage_free": self.free_storage_file,
190 20529708 Helga Velroyen
                       "storage_size": self.total_storage_file},
191 20529708 Helga Velroyen
                      {"name": "mynode",
192 20529708 Helga Velroyen
                       "type": constants.ST_LVM_VG,
193 20529708 Helga Velroyen
                       "storage_free": self.free_storage_lvm,
194 20529708 Helga Velroyen
                       "storage_size": self.total_storage_lvm},
195 20529708 Helga Velroyen
                      {"name": "mynode",
196 20529708 Helga Velroyen
                       "type": constants.ST_LVM_PV,
197 20529708 Helga Velroyen
                       "storage_free": 33,
198 20529708 Helga Velroyen
                       "storage_size": 44}]
199 20529708 Helga Velroyen
200 11aa3ca5 Helga Velroyen
  def testComputeStorageDataFromNodeInfoDefault(self):
201 20529708 Helga Velroyen
    has_lvm = False
202 20529708 Helga Velroyen
    node_name = "mynode"
203 20529708 Helga Velroyen
    (total_disk, free_disk, total_spindles, free_spindles) = \
204 6d11529e Helga Velroyen
        iallocator.IAllocator._ComputeStorageDataFromSpaceInfo(
205 9353adde Helga Velroyen
            self.space_info, node_name, has_lvm)
206 20529708 Helga Velroyen
    # FIXME: right now, iallocator ignores anything else than LVM, adjust
207 20529708 Helga Velroyen
    # this test once that arbitrary storage is supported
208 20529708 Helga Velroyen
    self.assertEqual(0, free_disk)
209 20529708 Helga Velroyen
    self.assertEqual(0, total_disk)
210 20529708 Helga Velroyen
211 11aa3ca5 Helga Velroyen
  def testComputeStorageDataFromNodeInfoLvm(self):
212 11aa3ca5 Helga Velroyen
    has_lvm = True
213 11aa3ca5 Helga Velroyen
    node_name = "mynode"
214 11aa3ca5 Helga Velroyen
    (total_disk, free_disk, total_spindles, free_spindles) = \
215 6d11529e Helga Velroyen
        iallocator.IAllocator._ComputeStorageDataFromSpaceInfo(
216 9353adde Helga Velroyen
            self.space_info, node_name, has_lvm)
217 11aa3ca5 Helga Velroyen
    self.assertEqual(self.free_storage_lvm, free_disk)
218 11aa3ca5 Helga Velroyen
    self.assertEqual(self.total_storage_lvm, total_disk)
219 11aa3ca5 Helga Velroyen
220 e8936ef7 Helga Velroyen
  def testComputeStorageDataFromSpaceInfoByTemplate(self):
221 e8936ef7 Helga Velroyen
    disk_template = constants.DT_FILE
222 e8936ef7 Helga Velroyen
    node_name = "mynode"
223 e8936ef7 Helga Velroyen
    (total_disk, free_disk, total_spindles, free_spindles) = \
224 e8936ef7 Helga Velroyen
        iallocator.IAllocator._ComputeStorageDataFromSpaceInfoByTemplate(
225 e8936ef7 Helga Velroyen
            self.space_info, node_name, disk_template)
226 e8936ef7 Helga Velroyen
    self.assertEqual(self.free_storage_file, free_disk)
227 e8936ef7 Helga Velroyen
    self.assertEqual(self.total_storage_file, total_disk)
228 e8936ef7 Helga Velroyen
229 e8936ef7 Helga Velroyen
  def testComputeStorageDataFromSpaceInfoByTemplateLvm(self):
230 e8936ef7 Helga Velroyen
    disk_template = constants.DT_PLAIN
231 e8936ef7 Helga Velroyen
    node_name = "mynode"
232 e8936ef7 Helga Velroyen
    (total_disk, free_disk, total_spindles, free_spindles) = \
233 e8936ef7 Helga Velroyen
        iallocator.IAllocator._ComputeStorageDataFromSpaceInfoByTemplate(
234 e8936ef7 Helga Velroyen
            self.space_info, node_name, disk_template)
235 e8936ef7 Helga Velroyen
    self.assertEqual(self.free_storage_lvm, free_disk)
236 e8936ef7 Helga Velroyen
    self.assertEqual(self.total_storage_lvm, total_disk)
237 e8936ef7 Helga Velroyen
238 e8936ef7 Helga Velroyen
  def testComputeStorageDataFromSpaceInfoByTemplateNoReport(self):
239 e8936ef7 Helga Velroyen
    disk_template = constants.DT_DISKLESS
240 e8936ef7 Helga Velroyen
    node_name = "mynode"
241 e8936ef7 Helga Velroyen
    (total_disk, free_disk, total_spindles, free_spindles) = \
242 e8936ef7 Helga Velroyen
        iallocator.IAllocator._ComputeStorageDataFromSpaceInfoByTemplate(
243 e8936ef7 Helga Velroyen
            self.space_info, node_name, disk_template)
244 e8936ef7 Helga Velroyen
    self.assertEqual(0, free_disk)
245 e8936ef7 Helga Velroyen
    self.assertEqual(0, total_disk)
246 fb60bc6a Michael Hanselmann
247 33b4fa9f René Nussbaumer
if __name__ == "__main__":
248 33b4fa9f René Nussbaumer
  testutils.GanetiTestProgram()