Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.query_unittest.py @ 0a9a0e5a

History | View | Annotate | Download (35.3 kB)

1 4ca96421 Michael Hanselmann
#!/usr/bin/python
2 4ca96421 Michael Hanselmann
#
3 4ca96421 Michael Hanselmann
4 e2d188cc Iustin Pop
# Copyright (C) 2010, 2011 Google Inc.
5 4ca96421 Michael Hanselmann
#
6 4ca96421 Michael Hanselmann
# This program is free software; you can redistribute it and/or modify
7 4ca96421 Michael Hanselmann
# it under the terms of the GNU General Public License as published by
8 4ca96421 Michael Hanselmann
# the Free Software Foundation; either version 2 of the License, or
9 4ca96421 Michael Hanselmann
# (at your option) any later version.
10 4ca96421 Michael Hanselmann
#
11 4ca96421 Michael Hanselmann
# This program is distributed in the hope that it will be useful, but
12 4ca96421 Michael Hanselmann
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 4ca96421 Michael Hanselmann
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 4ca96421 Michael Hanselmann
# General Public License for more details.
15 4ca96421 Michael Hanselmann
#
16 4ca96421 Michael Hanselmann
# You should have received a copy of the GNU General Public License
17 4ca96421 Michael Hanselmann
# along with this program; if not, write to the Free Software
18 4ca96421 Michael Hanselmann
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 4ca96421 Michael Hanselmann
# 02110-1301, USA.
20 4ca96421 Michael Hanselmann
21 4ca96421 Michael Hanselmann
22 4ca96421 Michael Hanselmann
"""Script for testing ganeti.query"""
23 4ca96421 Michael Hanselmann
24 4ca96421 Michael Hanselmann
import re
25 4ca96421 Michael Hanselmann
import unittest
26 aa29e95f Michael Hanselmann
import random
27 4ca96421 Michael Hanselmann
28 4ca96421 Michael Hanselmann
from ganeti import constants
29 4ca96421 Michael Hanselmann
from ganeti import utils
30 4ca96421 Michael Hanselmann
from ganeti import compat
31 4ca96421 Michael Hanselmann
from ganeti import errors
32 4ca96421 Michael Hanselmann
from ganeti import query
33 4ca96421 Michael Hanselmann
from ganeti import objects
34 1c8addc6 Michael Hanselmann
from ganeti import cmdlib
35 4ca96421 Michael Hanselmann
36 4ca96421 Michael Hanselmann
import testutils
37 4ca96421 Michael Hanselmann
38 4ca96421 Michael Hanselmann
39 4ca96421 Michael Hanselmann
class TestConstants(unittest.TestCase):
40 4ca96421 Michael Hanselmann
  def test(self):
41 4ca96421 Michael Hanselmann
    self.assertEqual(set(query._VERIFY_FN.keys()),
42 4ca96421 Michael Hanselmann
                     constants.QFT_ALL)
43 4ca96421 Michael Hanselmann
44 4ca96421 Michael Hanselmann
45 4ca96421 Michael Hanselmann
class _QueryData:
46 4ca96421 Michael Hanselmann
  def __init__(self, data, **kwargs):
47 4ca96421 Michael Hanselmann
    self.data = data
48 4ca96421 Michael Hanselmann
49 4ca96421 Michael Hanselmann
    for name, value in kwargs.items():
50 4ca96421 Michael Hanselmann
      setattr(self, name, value)
51 4ca96421 Michael Hanselmann
52 4ca96421 Michael Hanselmann
  def __iter__(self):
53 4ca96421 Michael Hanselmann
    return iter(self.data)
54 4ca96421 Michael Hanselmann
55 4ca96421 Michael Hanselmann
56 4ca96421 Michael Hanselmann
def _GetDiskSize(nr, ctx, item):
57 4ca96421 Michael Hanselmann
  disks = item["disks"]
58 4ca96421 Michael Hanselmann
  try:
59 e2d188cc Iustin Pop
    return disks[nr]
60 4ca96421 Michael Hanselmann
  except IndexError:
61 e2d188cc Iustin Pop
    return query._FS_UNAVAIL
62 4ca96421 Michael Hanselmann
63 4ca96421 Michael Hanselmann
64 4ca96421 Michael Hanselmann
class TestQuery(unittest.TestCase):
65 4ca96421 Michael Hanselmann
  def test(self):
66 4ca96421 Michael Hanselmann
    (STATIC, DISK) = range(10, 12)
67 4ca96421 Michael Hanselmann
68 4ca96421 Michael Hanselmann
    fielddef = query._PrepareFieldList([
69 4ca96421 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT),
70 e2d188cc Iustin Pop
       STATIC, lambda ctx, item: item["name"]),
71 4ca96421 Michael Hanselmann
      (query._MakeField("master", "Master", constants.QFT_BOOL),
72 e2d188cc Iustin Pop
       STATIC, lambda ctx, item: ctx.mastername == item["name"]),
73 4ca96421 Michael Hanselmann
      ] +
74 4ca96421 Michael Hanselmann
      [(query._MakeField("disk%s.size" % i, "DiskSize%s" % i,
75 4ca96421 Michael Hanselmann
                         constants.QFT_UNIT),
76 4ca96421 Michael Hanselmann
        DISK, compat.partial(_GetDiskSize, i))
77 d63bd540 Iustin Pop
       for i in range(4)], [])
78 4ca96421 Michael Hanselmann
79 4ca96421 Michael Hanselmann
    q = query.Query(fielddef, ["name"])
80 4ca96421 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([STATIC]))
81 4ca96421 Michael Hanselmann
    self.assertEqual(len(q._fields), 1)
82 4ca96421 Michael Hanselmann
    self.assertEqual(len(q.GetFields()), 1)
83 4ca96421 Michael Hanselmann
    self.assertEqual(q.GetFields()[0].ToDict(),
84 4ca96421 Michael Hanselmann
      objects.QueryFieldDefinition(name="name",
85 4ca96421 Michael Hanselmann
                                   title="Name",
86 4ca96421 Michael Hanselmann
                                   kind=constants.QFT_TEXT).ToDict())
87 4ca96421 Michael Hanselmann
88 4ca96421 Michael Hanselmann
    # Create data only once query has been prepared
89 4ca96421 Michael Hanselmann
    data = [
90 4ca96421 Michael Hanselmann
      { "name": "node1", "disks": [0, 1, 2], },
91 4ca96421 Michael Hanselmann
      { "name": "node2", "disks": [3, 4], },
92 4ca96421 Michael Hanselmann
      { "name": "node3", "disks": [5, 6, 7], },
93 4ca96421 Michael Hanselmann
      ]
94 4ca96421 Michael Hanselmann
95 4ca96421 Michael Hanselmann
    self.assertEqual(q.Query(_QueryData(data, mastername="node3")),
96 cfb084ae René Nussbaumer
                     [[(constants.RS_NORMAL, "node1")],
97 cfb084ae René Nussbaumer
                      [(constants.RS_NORMAL, "node2")],
98 cfb084ae René Nussbaumer
                      [(constants.RS_NORMAL, "node3")]])
99 4ca96421 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(_QueryData(data, mastername="node3")),
100 4ca96421 Michael Hanselmann
                     [["node1"], ["node2"], ["node3"]])
101 4ca96421 Michael Hanselmann
102 4ca96421 Michael Hanselmann
    q = query.Query(fielddef, ["name", "master"])
103 4ca96421 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([STATIC]))
104 4ca96421 Michael Hanselmann
    self.assertEqual(len(q._fields), 2)
105 4ca96421 Michael Hanselmann
    self.assertEqual(q.Query(_QueryData(data, mastername="node3")),
106 cfb084ae René Nussbaumer
                     [[(constants.RS_NORMAL, "node1"),
107 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, False)],
108 cfb084ae René Nussbaumer
                      [(constants.RS_NORMAL, "node2"),
109 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, False)],
110 cfb084ae René Nussbaumer
                      [(constants.RS_NORMAL, "node3"),
111 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, True)],
112 4ca96421 Michael Hanselmann
                     ])
113 4ca96421 Michael Hanselmann
114 4ca96421 Michael Hanselmann
    q = query.Query(fielddef, ["name", "master", "disk0.size"])
115 4ca96421 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([STATIC, DISK]))
116 4ca96421 Michael Hanselmann
    self.assertEqual(len(q._fields), 3)
117 4ca96421 Michael Hanselmann
    self.assertEqual(q.Query(_QueryData(data, mastername="node2")),
118 cfb084ae René Nussbaumer
                     [[(constants.RS_NORMAL, "node1"),
119 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, False),
120 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 0)],
121 cfb084ae René Nussbaumer
                      [(constants.RS_NORMAL, "node2"),
122 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, True),
123 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 3)],
124 cfb084ae René Nussbaumer
                      [(constants.RS_NORMAL, "node3"),
125 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, False),
126 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 5)],
127 4ca96421 Michael Hanselmann
                     ])
128 4ca96421 Michael Hanselmann
129 4ca96421 Michael Hanselmann
    # With unknown column
130 4ca96421 Michael Hanselmann
    q = query.Query(fielddef, ["disk2.size", "disk1.size", "disk99.size",
131 4ca96421 Michael Hanselmann
                               "disk0.size"])
132 4ca96421 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DISK]))
133 4ca96421 Michael Hanselmann
    self.assertEqual(len(q._fields), 4)
134 4ca96421 Michael Hanselmann
    self.assertEqual(q.Query(_QueryData(data, mastername="node2")),
135 cfb084ae René Nussbaumer
                     [[(constants.RS_NORMAL, 2),
136 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 1),
137 cfb084ae René Nussbaumer
                       (constants.RS_UNKNOWN, None),
138 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 0)],
139 cfb084ae René Nussbaumer
                      [(constants.RS_UNAVAIL, None),
140 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 4),
141 cfb084ae René Nussbaumer
                       (constants.RS_UNKNOWN, None),
142 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 3)],
143 cfb084ae René Nussbaumer
                      [(constants.RS_NORMAL, 7),
144 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 6),
145 cfb084ae René Nussbaumer
                       (constants.RS_UNKNOWN, None),
146 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 5)],
147 4ca96421 Michael Hanselmann
                     ])
148 4ca96421 Michael Hanselmann
    self.assertRaises(errors.OpPrereqError, q.OldStyleQuery,
149 4ca96421 Michael Hanselmann
                      _QueryData(data, mastername="node2"))
150 4ca96421 Michael Hanselmann
    self.assertEqual([fdef.ToDict() for fdef in q.GetFields()], [
151 4ca96421 Michael Hanselmann
                     { "name": "disk2.size", "title": "DiskSize2",
152 4ca96421 Michael Hanselmann
                       "kind": constants.QFT_UNIT, },
153 4ca96421 Michael Hanselmann
                     { "name": "disk1.size", "title": "DiskSize1",
154 4ca96421 Michael Hanselmann
                       "kind": constants.QFT_UNIT, },
155 4ca96421 Michael Hanselmann
                     { "name": "disk99.size", "title": "disk99.size",
156 4ca96421 Michael Hanselmann
                       "kind": constants.QFT_UNKNOWN, },
157 4ca96421 Michael Hanselmann
                     { "name": "disk0.size", "title": "DiskSize0",
158 4ca96421 Michael Hanselmann
                       "kind": constants.QFT_UNIT, },
159 4ca96421 Michael Hanselmann
                     ])
160 4ca96421 Michael Hanselmann
161 4ca96421 Michael Hanselmann
    # Empty query
162 4ca96421 Michael Hanselmann
    q = query.Query(fielddef, [])
163 4ca96421 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([]))
164 4ca96421 Michael Hanselmann
    self.assertEqual(len(q._fields), 0)
165 4ca96421 Michael Hanselmann
    self.assertEqual(q.Query(_QueryData(data, mastername="node2")),
166 4ca96421 Michael Hanselmann
                     [[], [], []])
167 4ca96421 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(_QueryData(data, mastername="node2")),
168 4ca96421 Michael Hanselmann
                     [[], [], []])
169 4ca96421 Michael Hanselmann
    self.assertEqual(q.GetFields(), [])
170 4ca96421 Michael Hanselmann
171 4ca96421 Michael Hanselmann
  def testPrepareFieldList(self):
172 4ca96421 Michael Hanselmann
    # Duplicate titles
173 4ca96421 Michael Hanselmann
    for (a, b) in [("name", "name"), ("NAME", "name")]:
174 4ca96421 Michael Hanselmann
      self.assertRaises(AssertionError, query._PrepareFieldList, [
175 4ca96421 Michael Hanselmann
        (query._MakeField("name", b, constants.QFT_TEXT), None,
176 4ca96421 Michael Hanselmann
         lambda *args: None),
177 4ca96421 Michael Hanselmann
        (query._MakeField("other", a, constants.QFT_TEXT), None,
178 4ca96421 Michael Hanselmann
         lambda *args: None),
179 d63bd540 Iustin Pop
        ], [])
180 4ca96421 Michael Hanselmann
181 4ca96421 Michael Hanselmann
    # Non-lowercase names
182 4ca96421 Michael Hanselmann
    self.assertRaises(AssertionError, query._PrepareFieldList, [
183 4ca96421 Michael Hanselmann
      (query._MakeField("NAME", "Name", constants.QFT_TEXT), None,
184 4ca96421 Michael Hanselmann
       lambda *args: None),
185 d63bd540 Iustin Pop
      ], [])
186 4ca96421 Michael Hanselmann
    self.assertRaises(AssertionError, query._PrepareFieldList, [
187 4ca96421 Michael Hanselmann
      (query._MakeField("Name", "Name", constants.QFT_TEXT), None,
188 4ca96421 Michael Hanselmann
       lambda *args: None),
189 d63bd540 Iustin Pop
      ], [])
190 4ca96421 Michael Hanselmann
191 4ca96421 Michael Hanselmann
    # Empty name
192 4ca96421 Michael Hanselmann
    self.assertRaises(AssertionError, query._PrepareFieldList, [
193 4ca96421 Michael Hanselmann
      (query._MakeField("", "Name", constants.QFT_TEXT), None,
194 4ca96421 Michael Hanselmann
       lambda *args: None),
195 d63bd540 Iustin Pop
      ], [])
196 4ca96421 Michael Hanselmann
197 4ca96421 Michael Hanselmann
    # Empty title
198 4ca96421 Michael Hanselmann
    self.assertRaises(AssertionError, query._PrepareFieldList, [
199 4ca96421 Michael Hanselmann
      (query._MakeField("name", "", constants.QFT_TEXT), None,
200 4ca96421 Michael Hanselmann
       lambda *args: None),
201 d63bd540 Iustin Pop
      ], [])
202 4ca96421 Michael Hanselmann
203 4ca96421 Michael Hanselmann
    # Whitespace in title
204 4ca96421 Michael Hanselmann
    self.assertRaises(AssertionError, query._PrepareFieldList, [
205 4ca96421 Michael Hanselmann
      (query._MakeField("name", "Co lu mn", constants.QFT_TEXT), None,
206 4ca96421 Michael Hanselmann
       lambda *args: None),
207 d63bd540 Iustin Pop
      ], [])
208 4ca96421 Michael Hanselmann
209 4ca96421 Michael Hanselmann
    # No callable function
210 4ca96421 Michael Hanselmann
    self.assertRaises(AssertionError, query._PrepareFieldList, [
211 4ca96421 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT), None, None),
212 d63bd540 Iustin Pop
      ], [])
213 4ca96421 Michael Hanselmann
214 4ca96421 Michael Hanselmann
  def testUnknown(self):
215 4ca96421 Michael Hanselmann
    fielddef = query._PrepareFieldList([
216 4ca96421 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT),
217 e2d188cc Iustin Pop
       None, lambda _, item: "name%s" % item),
218 4ca96421 Michael Hanselmann
      (query._MakeField("other0", "Other0", constants.QFT_TIMESTAMP),
219 e2d188cc Iustin Pop
       None, lambda *args: 1234),
220 4ca96421 Michael Hanselmann
      (query._MakeField("nodata", "NoData", constants.QFT_NUMBER),
221 e2d188cc Iustin Pop
       None, lambda *args: query._FS_NODATA ),
222 4ca96421 Michael Hanselmann
      (query._MakeField("unavail", "Unavail", constants.QFT_BOOL),
223 e2d188cc Iustin Pop
       None, lambda *args: query._FS_UNAVAIL),
224 d63bd540 Iustin Pop
      ], [])
225 4ca96421 Michael Hanselmann
226 4ca96421 Michael Hanselmann
    for selected in [["foo"], ["Hello", "World"],
227 4ca96421 Michael Hanselmann
                     ["name1", "other", "foo"]]:
228 4ca96421 Michael Hanselmann
      q = query.Query(fielddef, selected)
229 4ca96421 Michael Hanselmann
      self.assertEqual(len(q._fields), len(selected))
230 4ca96421 Michael Hanselmann
      self.assert_(compat.all(len(row) == len(selected)
231 4ca96421 Michael Hanselmann
                              for row in q.Query(_QueryData(range(1, 10)))))
232 4ca96421 Michael Hanselmann
      self.assertEqual(q.Query(_QueryData(range(1, 10))),
233 cfb084ae René Nussbaumer
                       [[(constants.RS_UNKNOWN, None)] * len(selected)
234 4ca96421 Michael Hanselmann
                        for i in range(1, 10)])
235 4ca96421 Michael Hanselmann
      self.assertEqual([fdef.ToDict() for fdef in q.GetFields()],
236 4ca96421 Michael Hanselmann
                       [{ "name": name, "title": name,
237 4ca96421 Michael Hanselmann
                          "kind": constants.QFT_UNKNOWN, }
238 4ca96421 Michael Hanselmann
                        for name in selected])
239 4ca96421 Michael Hanselmann
240 4ca96421 Michael Hanselmann
    q = query.Query(fielddef, ["name", "other0", "nodata", "unavail"])
241 4ca96421 Michael Hanselmann
    self.assertEqual(len(q._fields), 4)
242 4ca96421 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(_QueryData(range(1, 10))), [
243 4ca96421 Michael Hanselmann
                     ["name%s" % i, 1234, None, None]
244 4ca96421 Michael Hanselmann
                     for i in range(1, 10)
245 4ca96421 Michael Hanselmann
                     ])
246 4ca96421 Michael Hanselmann
247 4ca96421 Michael Hanselmann
    q = query.Query(fielddef, ["name", "other0", "nodata", "unavail", "unk"])
248 4ca96421 Michael Hanselmann
    self.assertEqual(len(q._fields), 5)
249 4ca96421 Michael Hanselmann
    self.assertEqual(q.Query(_QueryData(range(1, 10))),
250 cfb084ae René Nussbaumer
                     [[(constants.RS_NORMAL, "name%s" % i),
251 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 1234),
252 cfb084ae René Nussbaumer
                       (constants.RS_NODATA, None),
253 cfb084ae René Nussbaumer
                       (constants.RS_UNAVAIL, None),
254 cfb084ae René Nussbaumer
                       (constants.RS_UNKNOWN, None)]
255 4ca96421 Michael Hanselmann
                      for i in range(1, 10)])
256 4ca96421 Michael Hanselmann
257 d63bd540 Iustin Pop
  def testAliases(self):
258 d63bd540 Iustin Pop
    fields = [
259 d63bd540 Iustin Pop
      (query._MakeField("a", "a-title", constants.QFT_TEXT), None,
260 d63bd540 Iustin Pop
       lambda *args: None),
261 d63bd540 Iustin Pop
      (query._MakeField("b", "b-title", constants.QFT_TEXT), None,
262 d63bd540 Iustin Pop
       lambda *args: None),
263 d63bd540 Iustin Pop
      ]
264 d63bd540 Iustin Pop
    # duplicate field
265 d63bd540 Iustin Pop
    self.assertRaises(AssertionError, query._PrepareFieldList, fields,
266 d63bd540 Iustin Pop
                      [("b", "a")])
267 d63bd540 Iustin Pop
    self.assertRaises(AssertionError, query._PrepareFieldList, fields,
268 d63bd540 Iustin Pop
                      [("c", "b"), ("c", "a")])
269 d63bd540 Iustin Pop
    # missing target
270 d63bd540 Iustin Pop
    self.assertRaises(AssertionError, query._PrepareFieldList, fields,
271 d63bd540 Iustin Pop
                      [("c", "d")])
272 d63bd540 Iustin Pop
    fdefs = query._PrepareFieldList(fields, [("c", "b")])
273 d63bd540 Iustin Pop
    self.assertEqual(len(fdefs), 3)
274 d63bd540 Iustin Pop
    self.assertEqual(fdefs["b"][1:], fdefs["c"][1:])
275 d63bd540 Iustin Pop
276 4ca96421 Michael Hanselmann
277 8235fe04 Michael Hanselmann
class TestGetNodeRole(unittest.TestCase):
278 8235fe04 Michael Hanselmann
  def testMaster(self):
279 8235fe04 Michael Hanselmann
    node = objects.Node(name="node1")
280 8235fe04 Michael Hanselmann
    self.assertEqual(query._GetNodeRole(node, "node1"), "M")
281 8235fe04 Michael Hanselmann
282 8235fe04 Michael Hanselmann
  def testMasterCandidate(self):
283 8235fe04 Michael Hanselmann
    node = objects.Node(name="node1", master_candidate=True)
284 8235fe04 Michael Hanselmann
    self.assertEqual(query._GetNodeRole(node, "master"), "C")
285 8235fe04 Michael Hanselmann
286 8235fe04 Michael Hanselmann
  def testRegular(self):
287 8235fe04 Michael Hanselmann
    node = objects.Node(name="node1")
288 8235fe04 Michael Hanselmann
    self.assertEqual(query._GetNodeRole(node, "master"), "R")
289 8235fe04 Michael Hanselmann
290 8235fe04 Michael Hanselmann
  def testDrained(self):
291 8235fe04 Michael Hanselmann
    node = objects.Node(name="node1", drained=True)
292 8235fe04 Michael Hanselmann
    self.assertEqual(query._GetNodeRole(node, "master"), "D")
293 8235fe04 Michael Hanselmann
294 8235fe04 Michael Hanselmann
  def testOffline(self):
295 8235fe04 Michael Hanselmann
    node = objects.Node(name="node1", offline=True)
296 8235fe04 Michael Hanselmann
    self.assertEqual(query._GetNodeRole(node, "master"), "O")
297 8235fe04 Michael Hanselmann
298 8235fe04 Michael Hanselmann
299 8235fe04 Michael Hanselmann
class TestNodeQuery(unittest.TestCase):
300 8235fe04 Michael Hanselmann
  def _Create(self, selected):
301 8235fe04 Michael Hanselmann
    return query.Query(query.NODE_FIELDS, selected)
302 8235fe04 Michael Hanselmann
303 8235fe04 Michael Hanselmann
  def testSimple(self):
304 8235fe04 Michael Hanselmann
    nodes = [
305 8235fe04 Michael Hanselmann
      objects.Node(name="node1", drained=False),
306 8235fe04 Michael Hanselmann
      objects.Node(name="node2", drained=True),
307 8235fe04 Michael Hanselmann
      objects.Node(name="node3", drained=False),
308 8235fe04 Michael Hanselmann
      ]
309 8235fe04 Michael Hanselmann
    for live_data in [None, dict.fromkeys([node.name for node in nodes], {})]:
310 8572f1fe René Nussbaumer
      nqd = query.NodeQueryData(nodes, live_data, None, None, None, None, None,
311 8572f1fe René Nussbaumer
                                None)
312 8235fe04 Michael Hanselmann
313 8235fe04 Michael Hanselmann
      q = self._Create(["name", "drained"])
314 8235fe04 Michael Hanselmann
      self.assertEqual(q.RequestedData(), set([query.NQ_CONFIG]))
315 8235fe04 Michael Hanselmann
      self.assertEqual(q.Query(nqd),
316 cfb084ae René Nussbaumer
                       [[(constants.RS_NORMAL, "node1"),
317 cfb084ae René Nussbaumer
                         (constants.RS_NORMAL, False)],
318 cfb084ae René Nussbaumer
                        [(constants.RS_NORMAL, "node2"),
319 cfb084ae René Nussbaumer
                         (constants.RS_NORMAL, True)],
320 cfb084ae René Nussbaumer
                        [(constants.RS_NORMAL, "node3"),
321 cfb084ae René Nussbaumer
                         (constants.RS_NORMAL, False)],
322 8235fe04 Michael Hanselmann
                       ])
323 8235fe04 Michael Hanselmann
      self.assertEqual(q.OldStyleQuery(nqd),
324 8235fe04 Michael Hanselmann
                       [["node1", False],
325 8235fe04 Michael Hanselmann
                        ["node2", True],
326 8235fe04 Michael Hanselmann
                        ["node3", False]])
327 8235fe04 Michael Hanselmann
328 8235fe04 Michael Hanselmann
  def test(self):
329 8235fe04 Michael Hanselmann
    selected = query.NODE_FIELDS.keys()
330 8235fe04 Michael Hanselmann
    field_index = dict((field, idx) for idx, field in enumerate(selected))
331 8235fe04 Michael Hanselmann
332 8235fe04 Michael Hanselmann
    q = self._Create(selected)
333 8235fe04 Michael Hanselmann
    self.assertEqual(q.RequestedData(),
334 8235fe04 Michael Hanselmann
                     set([query.NQ_CONFIG, query.NQ_LIVE, query.NQ_INST,
335 52b5d286 René Nussbaumer
                          query.NQ_GROUP, query.NQ_OOB]))
336 8235fe04 Michael Hanselmann
337 8572f1fe René Nussbaumer
    cluster = objects.Cluster(cluster_name="testcluster",
338 8572f1fe René Nussbaumer
      hvparams=constants.HVC_DEFAULTS,
339 8572f1fe René Nussbaumer
      beparams={
340 8572f1fe René Nussbaumer
        constants.PP_DEFAULT: constants.BEC_DEFAULTS,
341 8572f1fe René Nussbaumer
        },
342 8572f1fe René Nussbaumer
      nicparams={
343 8572f1fe René Nussbaumer
        constants.PP_DEFAULT: constants.NICC_DEFAULTS,
344 8572f1fe René Nussbaumer
        },
345 8572f1fe René Nussbaumer
      ndparams=constants.NDC_DEFAULTS,
346 8572f1fe René Nussbaumer
        )
347 8572f1fe René Nussbaumer
348 8235fe04 Michael Hanselmann
    node_names = ["node%s" % i for i in range(20)]
349 8235fe04 Michael Hanselmann
    master_name = node_names[3]
350 8235fe04 Michael Hanselmann
    nodes = [
351 8235fe04 Michael Hanselmann
      objects.Node(name=name,
352 8235fe04 Michael Hanselmann
                   primary_ip="192.0.2.%s" % idx,
353 8235fe04 Michael Hanselmann
                   secondary_ip="192.0.100.%s" % idx,
354 8235fe04 Michael Hanselmann
                   serial_no=7789 * idx,
355 8235fe04 Michael Hanselmann
                   master_candidate=(name != master_name and idx % 3 == 0),
356 8235fe04 Michael Hanselmann
                   offline=False,
357 8235fe04 Michael Hanselmann
                   drained=False,
358 effab4ca Iustin Pop
                   vm_capable=True,
359 8235fe04 Michael Hanselmann
                   master_capable=False,
360 8572f1fe René Nussbaumer
                   ndparams={},
361 8235fe04 Michael Hanselmann
                   group="default",
362 8235fe04 Michael Hanselmann
                   ctime=1290006900,
363 8235fe04 Michael Hanselmann
                   mtime=1290006913,
364 8235fe04 Michael Hanselmann
                   uuid="fd9ccebe-6339-43c9-a82e-94bbe575%04d" % idx)
365 8235fe04 Michael Hanselmann
      for idx, name in enumerate(node_names)
366 8235fe04 Michael Hanselmann
      ]
367 8235fe04 Michael Hanselmann
368 8235fe04 Michael Hanselmann
    master_node = nodes[3]
369 8235fe04 Michael Hanselmann
    master_node.AddTag("masternode")
370 8235fe04 Michael Hanselmann
    master_node.AddTag("another")
371 8235fe04 Michael Hanselmann
    master_node.AddTag("tag")
372 145bea54 Michael Hanselmann
    master_node.ctime = None
373 145bea54 Michael Hanselmann
    master_node.mtime = None
374 8235fe04 Michael Hanselmann
    assert master_node.name == master_name
375 8235fe04 Michael Hanselmann
376 8235fe04 Michael Hanselmann
    live_data_name = node_names[4]
377 8235fe04 Michael Hanselmann
    assert live_data_name != master_name
378 8235fe04 Michael Hanselmann
379 8235fe04 Michael Hanselmann
    fake_live_data = {
380 8235fe04 Michael Hanselmann
      "bootid": "a2504766-498e-4b25-b21e-d23098dc3af4",
381 8235fe04 Michael Hanselmann
      "cnodes": 4,
382 8235fe04 Michael Hanselmann
      "csockets": 4,
383 8235fe04 Michael Hanselmann
      "ctotal": 8,
384 8235fe04 Michael Hanselmann
      "mnode": 128,
385 8235fe04 Michael Hanselmann
      "mfree": 100,
386 8235fe04 Michael Hanselmann
      "mtotal": 4096,
387 8235fe04 Michael Hanselmann
      "dfree": 5 * 1024 * 1024,
388 8235fe04 Michael Hanselmann
      "dtotal": 100 * 1024 * 1024,
389 8235fe04 Michael Hanselmann
      }
390 8235fe04 Michael Hanselmann
391 8235fe04 Michael Hanselmann
    assert (sorted(query._NODE_LIVE_FIELDS.keys()) ==
392 8235fe04 Michael Hanselmann
            sorted(fake_live_data.keys()))
393 8235fe04 Michael Hanselmann
394 8235fe04 Michael Hanselmann
    live_data = dict.fromkeys(node_names, {})
395 8235fe04 Michael Hanselmann
    live_data[live_data_name] = \
396 8235fe04 Michael Hanselmann
      dict((query._NODE_LIVE_FIELDS[name][2], value)
397 8235fe04 Michael Hanselmann
           for name, value in fake_live_data.items())
398 8235fe04 Michael Hanselmann
399 8235fe04 Michael Hanselmann
    node_to_primary = dict((name, set()) for name in node_names)
400 8235fe04 Michael Hanselmann
    node_to_primary[master_name].update(["inst1", "inst2"])
401 8235fe04 Michael Hanselmann
402 8235fe04 Michael Hanselmann
    node_to_secondary = dict((name, set()) for name in node_names)
403 8235fe04 Michael Hanselmann
    node_to_secondary[live_data_name].update(["instX", "instY", "instZ"])
404 8235fe04 Michael Hanselmann
405 8235fe04 Michael Hanselmann
    ng_uuid = "492b4b74-8670-478a-b98d-4c53a76238e6"
406 8235fe04 Michael Hanselmann
    groups = {
407 8572f1fe René Nussbaumer
      ng_uuid: objects.NodeGroup(name="ng1", uuid=ng_uuid, ndparams={}),
408 8235fe04 Michael Hanselmann
      }
409 8235fe04 Michael Hanselmann
410 52b5d286 René Nussbaumer
    oob_support = dict((name, False) for name in node_names)
411 52b5d286 René Nussbaumer
412 8235fe04 Michael Hanselmann
    master_node.group = ng_uuid
413 8235fe04 Michael Hanselmann
414 8235fe04 Michael Hanselmann
    nqd = query.NodeQueryData(nodes, live_data, master_name,
415 52b5d286 René Nussbaumer
                              node_to_primary, node_to_secondary, groups,
416 8572f1fe René Nussbaumer
                              oob_support, cluster)
417 8235fe04 Michael Hanselmann
    result = q.Query(nqd)
418 8235fe04 Michael Hanselmann
    self.assert_(compat.all(len(row) == len(selected) for row in result))
419 8235fe04 Michael Hanselmann
    self.assertEqual([row[field_index["name"]] for row in result],
420 cfb084ae René Nussbaumer
                     [(constants.RS_NORMAL, name) for name in node_names])
421 8235fe04 Michael Hanselmann
422 8235fe04 Michael Hanselmann
    node_to_row = dict((row[field_index["name"]][1], idx)
423 8235fe04 Michael Hanselmann
                       for idx, row in enumerate(result))
424 8235fe04 Michael Hanselmann
425 8235fe04 Michael Hanselmann
    master_row = result[node_to_row[master_name]]
426 8235fe04 Michael Hanselmann
    self.assert_(master_row[field_index["master"]])
427 8235fe04 Michael Hanselmann
    self.assert_(master_row[field_index["role"]], "M")
428 8235fe04 Michael Hanselmann
    self.assertEqual(master_row[field_index["group"]],
429 cfb084ae René Nussbaumer
                     (constants.RS_NORMAL, "ng1"))
430 8235fe04 Michael Hanselmann
    self.assertEqual(master_row[field_index["group.uuid"]],
431 cfb084ae René Nussbaumer
                     (constants.RS_NORMAL, ng_uuid))
432 145bea54 Michael Hanselmann
    self.assertEqual(master_row[field_index["ctime"]],
433 cfb084ae René Nussbaumer
                     (constants.RS_UNAVAIL, None))
434 145bea54 Michael Hanselmann
    self.assertEqual(master_row[field_index["mtime"]],
435 cfb084ae René Nussbaumer
                     (constants.RS_UNAVAIL, None))
436 8235fe04 Michael Hanselmann
437 8235fe04 Michael Hanselmann
    self.assert_(row[field_index["pip"]] == node.primary_ip and
438 8235fe04 Michael Hanselmann
                 row[field_index["sip"]] == node.secondary_ip and
439 8235fe04 Michael Hanselmann
                 set(row[field_index["tags"]]) == node.GetTags() and
440 8235fe04 Michael Hanselmann
                 row[field_index["serial_no"]] == node.serial_no and
441 8235fe04 Michael Hanselmann
                 row[field_index["role"]] == query._GetNodeRole(node,
442 8235fe04 Michael Hanselmann
                                                                master_name) and
443 8235fe04 Michael Hanselmann
                 (node.name == master_name or
444 8235fe04 Michael Hanselmann
                  (row[field_index["group"]] == "<unknown>" and
445 145bea54 Michael Hanselmann
                   row[field_index["group.uuid"]] is None and
446 cfb084ae René Nussbaumer
                   row[field_index["ctime"]] == (constants.RS_NORMAL,
447 145bea54 Michael Hanselmann
                                                 node.ctime) and
448 cfb084ae René Nussbaumer
                   row[field_index["mtime"]] == (constants.RS_NORMAL,
449 145bea54 Michael Hanselmann
                                                 node.mtime)))
450 8235fe04 Michael Hanselmann
                 for row, node in zip(result, nodes))
451 8235fe04 Michael Hanselmann
452 8235fe04 Michael Hanselmann
    live_data_row = result[node_to_row[live_data_name]]
453 8235fe04 Michael Hanselmann
454 8235fe04 Michael Hanselmann
    for (field, value) in fake_live_data.items():
455 8235fe04 Michael Hanselmann
      self.assertEqual(live_data_row[field_index[field]],
456 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, value))
457 8235fe04 Michael Hanselmann
458 8235fe04 Michael Hanselmann
    self.assertEqual(master_row[field_index["pinst_cnt"]],
459 cfb084ae René Nussbaumer
                     (constants.RS_NORMAL, 2))
460 8235fe04 Michael Hanselmann
    self.assertEqual(live_data_row[field_index["sinst_cnt"]],
461 cfb084ae René Nussbaumer
                     (constants.RS_NORMAL, 3))
462 8235fe04 Michael Hanselmann
    self.assertEqual(master_row[field_index["pinst_list"]],
463 cfb084ae René Nussbaumer
                     (constants.RS_NORMAL,
464 8235fe04 Michael Hanselmann
                      list(node_to_primary[master_name])))
465 8235fe04 Michael Hanselmann
    self.assertEqual(live_data_row[field_index["sinst_list"]],
466 cfb084ae René Nussbaumer
                     (constants.RS_NORMAL,
467 8235fe04 Michael Hanselmann
                      list(node_to_secondary[live_data_name])))
468 8235fe04 Michael Hanselmann
469 8235fe04 Michael Hanselmann
  def testGetLiveNodeField(self):
470 8235fe04 Michael Hanselmann
    nodes = [
471 effab4ca Iustin Pop
      objects.Node(name="node1", drained=False, offline=False,
472 effab4ca Iustin Pop
                   vm_capable=True),
473 effab4ca Iustin Pop
      objects.Node(name="node2", drained=True, offline=False,
474 effab4ca Iustin Pop
                   vm_capable=True),
475 effab4ca Iustin Pop
      objects.Node(name="node3", drained=False, offline=False,
476 effab4ca Iustin Pop
                   vm_capable=True),
477 effab4ca Iustin Pop
      objects.Node(name="node4", drained=False, offline=True,
478 effab4ca Iustin Pop
                   vm_capable=True),
479 effab4ca Iustin Pop
      objects.Node(name="node5", drained=False, offline=False,
480 effab4ca Iustin Pop
                   vm_capable=False),
481 8235fe04 Michael Hanselmann
      ]
482 8235fe04 Michael Hanselmann
    live_data = dict.fromkeys([node.name for node in nodes], {})
483 8235fe04 Michael Hanselmann
484 8235fe04 Michael Hanselmann
    # No data
485 8572f1fe René Nussbaumer
    nqd = query.NodeQueryData(None, None, None, None, None, None, None, None)
486 8235fe04 Michael Hanselmann
    self.assertEqual(query._GetLiveNodeField("hello", constants.QFT_NUMBER,
487 a6070ef7 Michael Hanselmann
                                             nqd, nodes[0]),
488 e2d188cc Iustin Pop
                     query._FS_NODATA)
489 8235fe04 Michael Hanselmann
490 8235fe04 Michael Hanselmann
    # Missing field
491 8235fe04 Michael Hanselmann
    ctx = _QueryData(None, curlive_data={
492 8235fe04 Michael Hanselmann
      "some": 1,
493 8235fe04 Michael Hanselmann
      "other": 2,
494 8235fe04 Michael Hanselmann
      })
495 8235fe04 Michael Hanselmann
    self.assertEqual(query._GetLiveNodeField("hello", constants.QFT_NUMBER,
496 a6070ef7 Michael Hanselmann
                                             ctx, nodes[0]),
497 e2d188cc Iustin Pop
                     query._FS_UNAVAIL)
498 8235fe04 Michael Hanselmann
499 8235fe04 Michael Hanselmann
    # Wrong format/datatype
500 8235fe04 Michael Hanselmann
    ctx = _QueryData(None, curlive_data={
501 8235fe04 Michael Hanselmann
      "hello": ["Hello World"],
502 8235fe04 Michael Hanselmann
      "other": 2,
503 8235fe04 Michael Hanselmann
      })
504 8235fe04 Michael Hanselmann
    self.assertEqual(query._GetLiveNodeField("hello", constants.QFT_NUMBER,
505 a6070ef7 Michael Hanselmann
                                             ctx, nodes[0]),
506 e2d188cc Iustin Pop
                     query._FS_UNAVAIL)
507 8235fe04 Michael Hanselmann
508 a6070ef7 Michael Hanselmann
    # Offline node
509 a6070ef7 Michael Hanselmann
    assert nodes[3].offline
510 a6070ef7 Michael Hanselmann
    ctx = _QueryData(None, curlive_data={})
511 a6070ef7 Michael Hanselmann
    self.assertEqual(query._GetLiveNodeField("hello", constants.QFT_NUMBER,
512 a6070ef7 Michael Hanselmann
                                             ctx, nodes[3]),
513 e2d188cc Iustin Pop
                     query._FS_OFFLINE, None)
514 a6070ef7 Michael Hanselmann
515 8235fe04 Michael Hanselmann
    # Wrong field type
516 8235fe04 Michael Hanselmann
    ctx = _QueryData(None, curlive_data={"hello": 123})
517 8235fe04 Michael Hanselmann
    self.assertRaises(AssertionError, query._GetLiveNodeField,
518 a6070ef7 Michael Hanselmann
                      "hello", constants.QFT_BOOL, ctx, nodes[0])
519 8235fe04 Michael Hanselmann
520 effab4ca Iustin Pop
    # Non-vm_capable node
521 effab4ca Iustin Pop
    assert not nodes[4].vm_capable
522 effab4ca Iustin Pop
    ctx = _QueryData(None, curlive_data={})
523 effab4ca Iustin Pop
    self.assertEqual(query._GetLiveNodeField("hello", constants.QFT_NUMBER,
524 effab4ca Iustin Pop
                                             ctx, nodes[4]),
525 effab4ca Iustin Pop
                     query._FS_UNAVAIL, None)
526 effab4ca Iustin Pop
527 8235fe04 Michael Hanselmann
528 1c8addc6 Michael Hanselmann
class TestInstanceQuery(unittest.TestCase):
529 1c8addc6 Michael Hanselmann
  def _Create(self, selected):
530 1c8addc6 Michael Hanselmann
    return query.Query(query.INSTANCE_FIELDS, selected)
531 1c8addc6 Michael Hanselmann
532 1c8addc6 Michael Hanselmann
  def testSimple(self):
533 1c8addc6 Michael Hanselmann
    q = self._Create(["name", "be/memory", "ip"])
534 1c8addc6 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([query.IQ_CONFIG]))
535 1c8addc6 Michael Hanselmann
536 1c8addc6 Michael Hanselmann
    cluster = objects.Cluster(cluster_name="testcluster",
537 1c8addc6 Michael Hanselmann
      hvparams=constants.HVC_DEFAULTS,
538 1c8addc6 Michael Hanselmann
      beparams={
539 1c8addc6 Michael Hanselmann
        constants.PP_DEFAULT: constants.BEC_DEFAULTS,
540 1c8addc6 Michael Hanselmann
        },
541 1c8addc6 Michael Hanselmann
      nicparams={
542 1c8addc6 Michael Hanselmann
        constants.PP_DEFAULT: constants.NICC_DEFAULTS,
543 1c8addc6 Michael Hanselmann
        })
544 1c8addc6 Michael Hanselmann
545 1c8addc6 Michael Hanselmann
    instances = [
546 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst1", hvparams={}, beparams={}, nics=[]),
547 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst2", hvparams={}, nics=[],
548 1c8addc6 Michael Hanselmann
        beparams={
549 1c8addc6 Michael Hanselmann
          constants.BE_MEMORY: 512,
550 1c8addc6 Michael Hanselmann
        }),
551 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst3", hvparams={}, beparams={},
552 1c8addc6 Michael Hanselmann
        nics=[objects.NIC(ip="192.0.2.99", nicparams={})]),
553 1c8addc6 Michael Hanselmann
      ]
554 1c8addc6 Michael Hanselmann
555 5d28cb6f Michael Hanselmann
    iqd = query.InstanceQueryData(instances, cluster, None, [], [], {},
556 5d28cb6f Michael Hanselmann
                                  set(), {})
557 1c8addc6 Michael Hanselmann
    self.assertEqual(q.Query(iqd),
558 cfb084ae René Nussbaumer
      [[(constants.RS_NORMAL, "inst1"),
559 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, 128),
560 cfb084ae René Nussbaumer
        (constants.RS_UNAVAIL, None),
561 1c8addc6 Michael Hanselmann
       ],
562 cfb084ae René Nussbaumer
       [(constants.RS_NORMAL, "inst2"),
563 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, 512),
564 cfb084ae René Nussbaumer
        (constants.RS_UNAVAIL, None),
565 1c8addc6 Michael Hanselmann
       ],
566 cfb084ae René Nussbaumer
       [(constants.RS_NORMAL, "inst3"),
567 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, 128),
568 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, "192.0.2.99"),
569 1c8addc6 Michael Hanselmann
       ]])
570 1c8addc6 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(iqd),
571 1c8addc6 Michael Hanselmann
      [["inst1", 128, None],
572 1c8addc6 Michael Hanselmann
       ["inst2", 512, None],
573 1c8addc6 Michael Hanselmann
       ["inst3", 128, "192.0.2.99"]])
574 1c8addc6 Michael Hanselmann
575 1c8addc6 Michael Hanselmann
  def test(self):
576 1c8addc6 Michael Hanselmann
    selected = query.INSTANCE_FIELDS.keys()
577 1c8addc6 Michael Hanselmann
    fieldidx = dict((field, idx) for idx, field in enumerate(selected))
578 1c8addc6 Michael Hanselmann
579 1c8addc6 Michael Hanselmann
    macs = ["00:11:22:%02x:%02x:%02x" % (i % 255, i % 3, (i * 123) % 255)
580 1c8addc6 Michael Hanselmann
            for i in range(20)]
581 1c8addc6 Michael Hanselmann
582 1c8addc6 Michael Hanselmann
    q = self._Create(selected)
583 1c8addc6 Michael Hanselmann
    self.assertEqual(q.RequestedData(),
584 5d28cb6f Michael Hanselmann
                     set([query.IQ_CONFIG, query.IQ_LIVE, query.IQ_DISKUSAGE,
585 5d28cb6f Michael Hanselmann
                          query.IQ_CONSOLE]))
586 1c8addc6 Michael Hanselmann
587 1c8addc6 Michael Hanselmann
    cluster = objects.Cluster(cluster_name="testcluster",
588 1c8addc6 Michael Hanselmann
      hvparams=constants.HVC_DEFAULTS,
589 1c8addc6 Michael Hanselmann
      beparams={
590 1c8addc6 Michael Hanselmann
        constants.PP_DEFAULT: constants.BEC_DEFAULTS,
591 1c8addc6 Michael Hanselmann
        },
592 1c8addc6 Michael Hanselmann
      nicparams={
593 1c8addc6 Michael Hanselmann
        constants.PP_DEFAULT: constants.NICC_DEFAULTS,
594 1c8addc6 Michael Hanselmann
        },
595 1c8addc6 Michael Hanselmann
      os_hvp={},
596 1c8addc6 Michael Hanselmann
      tcpudp_port_pool=set())
597 1c8addc6 Michael Hanselmann
598 1c8addc6 Michael Hanselmann
    offline_nodes = ["nodeoff1", "nodeoff2"]
599 1c8addc6 Michael Hanselmann
    bad_nodes = ["nodebad1", "nodebad2", "nodebad3"] + offline_nodes
600 1c8addc6 Michael Hanselmann
    nodes = ["node%s" % i for i in range(10)] + bad_nodes
601 1c8addc6 Michael Hanselmann
602 1c8addc6 Michael Hanselmann
    instances = [
603 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst1", hvparams={}, beparams={}, nics=[],
604 1c8addc6 Michael Hanselmann
        uuid="f90eccb3-e227-4e3c-bf2a-94a21ca8f9cd",
605 1c8addc6 Michael Hanselmann
        ctime=1291244000, mtime=1291244400, serial_no=30,
606 1c8addc6 Michael Hanselmann
        admin_up=True, hypervisor=constants.HT_XEN_PVM, os="linux1",
607 1c8addc6 Michael Hanselmann
        primary_node="node1",
608 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_PLAIN,
609 1c8addc6 Michael Hanselmann
        disks=[]),
610 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst2", hvparams={}, nics=[],
611 1c8addc6 Michael Hanselmann
        uuid="73a0f8a7-068c-4630-ada2-c3440015ab1a",
612 1c8addc6 Michael Hanselmann
        ctime=1291211000, mtime=1291211077, serial_no=1,
613 1c8addc6 Michael Hanselmann
        admin_up=True, hypervisor=constants.HT_XEN_HVM, os="deb99",
614 1c8addc6 Michael Hanselmann
        primary_node="node5",
615 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DISKLESS,
616 1c8addc6 Michael Hanselmann
        disks=[],
617 1c8addc6 Michael Hanselmann
        beparams={
618 1c8addc6 Michael Hanselmann
          constants.BE_MEMORY: 512,
619 1c8addc6 Michael Hanselmann
        }),
620 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst3", hvparams={}, beparams={},
621 1c8addc6 Michael Hanselmann
        uuid="11ec8dff-fb61-4850-bfe0-baa1803ff280",
622 1c8addc6 Michael Hanselmann
        ctime=1291011000, mtime=1291013000, serial_no=1923,
623 1c8addc6 Michael Hanselmann
        admin_up=False, hypervisor=constants.HT_KVM, os="busybox",
624 1c8addc6 Michael Hanselmann
        primary_node="node6",
625 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DRBD8,
626 1c8addc6 Michael Hanselmann
        disks=[],
627 1c8addc6 Michael Hanselmann
        nics=[
628 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.99", mac=macs.pop(),
629 1c8addc6 Michael Hanselmann
                      nicparams={
630 1c8addc6 Michael Hanselmann
                        constants.NIC_LINK: constants.DEFAULT_BRIDGE,
631 1c8addc6 Michael Hanselmann
                        }),
632 1c8addc6 Michael Hanselmann
          objects.NIC(ip=None, mac=macs.pop(), nicparams={}),
633 1c8addc6 Michael Hanselmann
          ]),
634 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst4", hvparams={}, beparams={},
635 1c8addc6 Michael Hanselmann
        uuid="68dab168-3ef5-4c9d-b4d3-801e0672068c",
636 1c8addc6 Michael Hanselmann
        ctime=1291244390, mtime=1291244395, serial_no=25,
637 1c8addc6 Michael Hanselmann
        admin_up=False, hypervisor=constants.HT_XEN_PVM, os="linux1",
638 1c8addc6 Michael Hanselmann
        primary_node="nodeoff2",
639 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DRBD8,
640 1c8addc6 Michael Hanselmann
        disks=[],
641 1c8addc6 Michael Hanselmann
        nics=[
642 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.1", mac=macs.pop(),
643 1c8addc6 Michael Hanselmann
                      nicparams={
644 1c8addc6 Michael Hanselmann
                        constants.NIC_LINK: constants.DEFAULT_BRIDGE,
645 1c8addc6 Michael Hanselmann
                        }),
646 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.2", mac=macs.pop(), nicparams={}),
647 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.3", mac=macs.pop(),
648 1c8addc6 Michael Hanselmann
                      nicparams={
649 1c8addc6 Michael Hanselmann
                        constants.NIC_MODE: constants.NIC_MODE_ROUTED,
650 1c8addc6 Michael Hanselmann
                        }),
651 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.4", mac=macs.pop(),
652 1c8addc6 Michael Hanselmann
                      nicparams={
653 1c8addc6 Michael Hanselmann
                        constants.NIC_MODE: constants.NIC_MODE_BRIDGED,
654 1c8addc6 Michael Hanselmann
                        constants.NIC_LINK: "eth123",
655 1c8addc6 Michael Hanselmann
                        }),
656 1c8addc6 Michael Hanselmann
          ]),
657 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst5", hvparams={}, nics=[],
658 1c8addc6 Michael Hanselmann
        uuid="0e3dca12-5b42-4e24-98a2-415267545bd0",
659 1c8addc6 Michael Hanselmann
        ctime=1231211000, mtime=1261200000, serial_no=3,
660 1c8addc6 Michael Hanselmann
        admin_up=True, hypervisor=constants.HT_XEN_HVM, os="deb99",
661 1c8addc6 Michael Hanselmann
        primary_node="nodebad2",
662 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DISKLESS,
663 1c8addc6 Michael Hanselmann
        disks=[],
664 1c8addc6 Michael Hanselmann
        beparams={
665 1c8addc6 Michael Hanselmann
          constants.BE_MEMORY: 512,
666 1c8addc6 Michael Hanselmann
        }),
667 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst6", hvparams={}, nics=[],
668 1c8addc6 Michael Hanselmann
        uuid="72de6580-c8d5-4661-b902-38b5785bb8b3",
669 1c8addc6 Michael Hanselmann
        ctime=7513, mtime=11501, serial_no=13390,
670 1c8addc6 Michael Hanselmann
        admin_up=False, hypervisor=constants.HT_XEN_HVM, os="deb99",
671 1c8addc6 Michael Hanselmann
        primary_node="node7",
672 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DISKLESS,
673 1c8addc6 Michael Hanselmann
        disks=[],
674 1c8addc6 Michael Hanselmann
        beparams={
675 1c8addc6 Michael Hanselmann
          constants.BE_MEMORY: 768,
676 1c8addc6 Michael Hanselmann
        }),
677 145bea54 Michael Hanselmann
      objects.Instance(name="inst7", hvparams={}, nics=[],
678 145bea54 Michael Hanselmann
        uuid="ceec5dc4-b729-4f42-ae28-69b3cd24920e",
679 145bea54 Michael Hanselmann
        ctime=None, mtime=None, serial_no=1947,
680 145bea54 Michael Hanselmann
        admin_up=False, hypervisor=constants.HT_XEN_HVM, os="deb99",
681 145bea54 Michael Hanselmann
        primary_node="node6",
682 145bea54 Michael Hanselmann
        disk_template=constants.DT_DISKLESS,
683 145bea54 Michael Hanselmann
        disks=[],
684 145bea54 Michael Hanselmann
        beparams={}),
685 1c8addc6 Michael Hanselmann
      ]
686 1c8addc6 Michael Hanselmann
687 145bea54 Michael Hanselmann
    assert not utils.FindDuplicates(inst.name for inst in instances)
688 145bea54 Michael Hanselmann
689 5d28cb6f Michael Hanselmann
    instbyname = dict((inst.name, inst) for inst in instances)
690 5d28cb6f Michael Hanselmann
691 1c8addc6 Michael Hanselmann
    disk_usage = dict((inst.name,
692 1c8addc6 Michael Hanselmann
                       cmdlib._ComputeDiskSize(inst.disk_template,
693 1c8addc6 Michael Hanselmann
                                               [{"size": disk.size}
694 1c8addc6 Michael Hanselmann
                                                for disk in inst.disks]))
695 1c8addc6 Michael Hanselmann
                      for inst in instances)
696 1c8addc6 Michael Hanselmann
697 1c8addc6 Michael Hanselmann
    inst_bridges = {
698 1c8addc6 Michael Hanselmann
      "inst3": [constants.DEFAULT_BRIDGE, constants.DEFAULT_BRIDGE],
699 1c8addc6 Michael Hanselmann
      "inst4": [constants.DEFAULT_BRIDGE, constants.DEFAULT_BRIDGE,
700 1c8addc6 Michael Hanselmann
                None, "eth123"],
701 1c8addc6 Michael Hanselmann
      }
702 1c8addc6 Michael Hanselmann
703 1c8addc6 Michael Hanselmann
    live_data = {
704 1c8addc6 Michael Hanselmann
      "inst2": {
705 1c8addc6 Michael Hanselmann
        "vcpus": 3,
706 1c8addc6 Michael Hanselmann
        },
707 1c8addc6 Michael Hanselmann
      "inst4": {
708 1c8addc6 Michael Hanselmann
        "memory": 123,
709 1c8addc6 Michael Hanselmann
        },
710 1c8addc6 Michael Hanselmann
      "inst6": {
711 1c8addc6 Michael Hanselmann
        "memory": 768,
712 1c8addc6 Michael Hanselmann
        },
713 bacae536 René Nussbaumer
      "inst7": {
714 bacae536 René Nussbaumer
        "vcpus": 3,
715 bacae536 René Nussbaumer
        },
716 1c8addc6 Michael Hanselmann
      }
717 bacae536 René Nussbaumer
    wrongnode_inst = set(["inst7"])
718 1c8addc6 Michael Hanselmann
719 5d28cb6f Michael Hanselmann
    consinfo = dict((inst.name, None) for inst in instances)
720 5d28cb6f Michael Hanselmann
    consinfo["inst7"] = \
721 5d28cb6f Michael Hanselmann
      objects.InstanceConsole(instance="inst7", kind=constants.CONS_SSH,
722 5d28cb6f Michael Hanselmann
                              host=instbyname["inst7"].primary_node,
723 5d28cb6f Michael Hanselmann
                              user=constants.GANETI_RUNAS,
724 5d28cb6f Michael Hanselmann
                              command=["hostname"]).ToDict()
725 5d28cb6f Michael Hanselmann
726 1c8addc6 Michael Hanselmann
    iqd = query.InstanceQueryData(instances, cluster, disk_usage,
727 e431074f René Nussbaumer
                                  offline_nodes, bad_nodes, live_data,
728 5d28cb6f Michael Hanselmann
                                  wrongnode_inst, consinfo)
729 1c8addc6 Michael Hanselmann
    result = q.Query(iqd)
730 1c8addc6 Michael Hanselmann
    self.assertEqual(len(result), len(instances))
731 1c8addc6 Michael Hanselmann
    self.assert_(compat.all(len(row) == len(selected)
732 1c8addc6 Michael Hanselmann
                            for row in result))
733 1c8addc6 Michael Hanselmann
734 1c8addc6 Michael Hanselmann
    assert len(set(bad_nodes) & set(offline_nodes)) == len(offline_nodes), \
735 1c8addc6 Michael Hanselmann
           "Offline nodes not included in bad nodes"
736 1c8addc6 Michael Hanselmann
737 1c8addc6 Michael Hanselmann
    tested_status = set()
738 1c8addc6 Michael Hanselmann
739 1c8addc6 Michael Hanselmann
    for (inst, row) in zip(instances, result):
740 1c8addc6 Michael Hanselmann
      assert inst.primary_node in nodes
741 1c8addc6 Michael Hanselmann
742 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["name"]],
743 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, inst.name))
744 1c8addc6 Michael Hanselmann
745 1c8addc6 Michael Hanselmann
      if inst.primary_node in offline_nodes:
746 1c8addc6 Michael Hanselmann
        exp_status = "ERROR_nodeoffline"
747 1c8addc6 Michael Hanselmann
      elif inst.primary_node in bad_nodes:
748 1c8addc6 Michael Hanselmann
        exp_status = "ERROR_nodedown"
749 1c8addc6 Michael Hanselmann
      elif inst.name in live_data:
750 e431074f René Nussbaumer
        if inst.name in wrongnode_inst:
751 e431074f René Nussbaumer
          exp_status = "ERROR_wrongnode"
752 e431074f René Nussbaumer
        elif inst.admin_up:
753 1c8addc6 Michael Hanselmann
          exp_status = "running"
754 1c8addc6 Michael Hanselmann
        else:
755 1c8addc6 Michael Hanselmann
          exp_status = "ERROR_up"
756 1c8addc6 Michael Hanselmann
      elif inst.admin_up:
757 1c8addc6 Michael Hanselmann
        exp_status = "ERROR_down"
758 1c8addc6 Michael Hanselmann
      else:
759 1c8addc6 Michael Hanselmann
        exp_status = "ADMIN_down"
760 1c8addc6 Michael Hanselmann
761 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["status"]],
762 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, exp_status))
763 1c8addc6 Michael Hanselmann
764 1c8addc6 Michael Hanselmann
      (_, status) = row[fieldidx["status"]]
765 1c8addc6 Michael Hanselmann
      tested_status.add(status)
766 1c8addc6 Michael Hanselmann
767 1c8addc6 Michael Hanselmann
      for (field, livefield) in [("oper_ram", "memory"),
768 1c8addc6 Michael Hanselmann
                                 ("oper_vcpus", "vcpus")]:
769 1c8addc6 Michael Hanselmann
        if inst.primary_node in bad_nodes:
770 cfb084ae René Nussbaumer
          exp = (constants.RS_NODATA, None)
771 1c8addc6 Michael Hanselmann
        elif inst.name in live_data:
772 1c8addc6 Michael Hanselmann
          value = live_data[inst.name].get(livefield, None)
773 1c8addc6 Michael Hanselmann
          if value is None:
774 cfb084ae René Nussbaumer
            exp = (constants.RS_UNAVAIL, None)
775 1c8addc6 Michael Hanselmann
          else:
776 cfb084ae René Nussbaumer
            exp = (constants.RS_NORMAL, value)
777 1c8addc6 Michael Hanselmann
        else:
778 cfb084ae René Nussbaumer
          exp = (constants.RS_UNAVAIL, None)
779 1c8addc6 Michael Hanselmann
780 1c8addc6 Michael Hanselmann
        self.assertEqual(row[fieldidx[field]], exp)
781 1c8addc6 Michael Hanselmann
782 1c8addc6 Michael Hanselmann
      bridges = inst_bridges.get(inst.name, [])
783 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["nic.bridges"]],
784 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, bridges))
785 1c8addc6 Michael Hanselmann
      if bridges:
786 1c8addc6 Michael Hanselmann
        self.assertEqual(row[fieldidx["bridge"]],
787 cfb084ae René Nussbaumer
                         (constants.RS_NORMAL, bridges[0]))
788 1c8addc6 Michael Hanselmann
      else:
789 1c8addc6 Michael Hanselmann
        self.assertEqual(row[fieldidx["bridge"]],
790 cfb084ae René Nussbaumer
                         (constants.RS_UNAVAIL, None))
791 1c8addc6 Michael Hanselmann
792 1c8addc6 Michael Hanselmann
      for i in range(constants.MAX_NICS):
793 1c8addc6 Michael Hanselmann
        if i < len(bridges) and bridges[i] is not None:
794 cfb084ae René Nussbaumer
          exp = (constants.RS_NORMAL, bridges[i])
795 1c8addc6 Michael Hanselmann
        else:
796 cfb084ae René Nussbaumer
          exp = (constants.RS_UNAVAIL, None)
797 1c8addc6 Michael Hanselmann
        self.assertEqual(row[fieldidx["nic.bridge/%s" % i]], exp)
798 1c8addc6 Michael Hanselmann
799 1c8addc6 Michael Hanselmann
      if inst.primary_node in bad_nodes:
800 cfb084ae René Nussbaumer
        exp = (constants.RS_NODATA, None)
801 1c8addc6 Michael Hanselmann
      else:
802 cfb084ae René Nussbaumer
        exp = (constants.RS_NORMAL, inst.name in live_data)
803 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["oper_state"]], exp)
804 1c8addc6 Michael Hanselmann
805 1c8addc6 Michael Hanselmann
      usage = disk_usage[inst.name]
806 1c8addc6 Michael Hanselmann
      if usage is None:
807 1c8addc6 Michael Hanselmann
        usage = 0
808 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["disk_usage"]],
809 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, usage))
810 1c8addc6 Michael Hanselmann
811 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["sda_size"]], row[fieldidx["disk.size/0"]])
812 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["sdb_size"]], row[fieldidx["disk.size/1"]])
813 1c8addc6 Michael Hanselmann
814 145bea54 Michael Hanselmann
      for field in ["ctime", "mtime"]:
815 145bea54 Michael Hanselmann
        if getattr(inst, field) is None:
816 145bea54 Michael Hanselmann
          # No ctime/mtime
817 cfb084ae René Nussbaumer
          exp = (constants.RS_UNAVAIL, None)
818 145bea54 Michael Hanselmann
        else:
819 cfb084ae René Nussbaumer
          exp = (constants.RS_NORMAL, getattr(inst, field))
820 145bea54 Michael Hanselmann
        self.assertEqual(row[fieldidx[field]], exp)
821 145bea54 Michael Hanselmann
822 5d28cb6f Michael Hanselmann
      self._CheckInstanceConsole(inst, row[fieldidx["console"]])
823 5d28cb6f Michael Hanselmann
824 1c8addc6 Michael Hanselmann
    # Ensure all possible status' have been tested
825 1c8addc6 Michael Hanselmann
    self.assertEqual(tested_status,
826 1c8addc6 Michael Hanselmann
                     set(["ERROR_nodeoffline", "ERROR_nodedown",
827 1c8addc6 Michael Hanselmann
                          "running", "ERROR_up", "ERROR_down",
828 bacae536 René Nussbaumer
                          "ADMIN_down", "ERROR_wrongnode"]))
829 1c8addc6 Michael Hanselmann
830 5d28cb6f Michael Hanselmann
  def _CheckInstanceConsole(self, instance, (status, consdata)):
831 5d28cb6f Michael Hanselmann
    if instance.name == "inst7":
832 5d28cb6f Michael Hanselmann
      self.assertEqual(status, constants.RS_NORMAL)
833 5d28cb6f Michael Hanselmann
      console = objects.InstanceConsole.FromDict(consdata)
834 5d28cb6f Michael Hanselmann
      self.assertTrue(console.Validate())
835 5d28cb6f Michael Hanselmann
      self.assertEqual(console.host, instance.primary_node)
836 5d28cb6f Michael Hanselmann
    else:
837 5d28cb6f Michael Hanselmann
      self.assertEqual(status, constants.RS_UNAVAIL)
838 5d28cb6f Michael Hanselmann
839 1c8addc6 Michael Hanselmann
840 d8b7ff5f Adeodato Simo
class TestGroupQuery(unittest.TestCase):
841 d8b7ff5f Adeodato Simo
842 d8b7ff5f Adeodato Simo
  def setUp(self):
843 d8b7ff5f Adeodato Simo
    self.groups = [
844 d8b7ff5f Adeodato Simo
      objects.NodeGroup(name="default",
845 d8b7ff5f Adeodato Simo
                        uuid="c0e89160-18e7-11e0-a46e-001d0904baeb",
846 d8b7ff5f Adeodato Simo
                        alloc_policy=constants.ALLOC_POLICY_PREFERRED),
847 d8b7ff5f Adeodato Simo
      objects.NodeGroup(name="restricted",
848 d8b7ff5f Adeodato Simo
                        uuid="d2a40a74-18e7-11e0-9143-001d0904baeb",
849 d8b7ff5f Adeodato Simo
                        alloc_policy=constants.ALLOC_POLICY_LAST_RESORT),
850 d8b7ff5f Adeodato Simo
      ]
851 d8b7ff5f Adeodato Simo
852 d8b7ff5f Adeodato Simo
  def _Create(self, selected):
853 d8b7ff5f Adeodato Simo
    return query.Query(query.GROUP_FIELDS, selected)
854 d8b7ff5f Adeodato Simo
855 d8b7ff5f Adeodato Simo
  def testSimple(self):
856 d8b7ff5f Adeodato Simo
    q = self._Create(["name", "uuid", "alloc_policy"])
857 d8b7ff5f Adeodato Simo
    gqd = query.GroupQueryData(self.groups, None, None)
858 d8b7ff5f Adeodato Simo
859 d8b7ff5f Adeodato Simo
    self.assertEqual(q.RequestedData(), set([query.GQ_CONFIG]))
860 d8b7ff5f Adeodato Simo
861 d8b7ff5f Adeodato Simo
    self.assertEqual(q.Query(gqd),
862 cfb084ae René Nussbaumer
      [[(constants.RS_NORMAL, "default"),
863 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, "c0e89160-18e7-11e0-a46e-001d0904baeb"),
864 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, constants.ALLOC_POLICY_PREFERRED)
865 d8b7ff5f Adeodato Simo
        ],
866 cfb084ae René Nussbaumer
       [(constants.RS_NORMAL, "restricted"),
867 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, "d2a40a74-18e7-11e0-9143-001d0904baeb"),
868 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, constants.ALLOC_POLICY_LAST_RESORT)
869 d8b7ff5f Adeodato Simo
        ],
870 d8b7ff5f Adeodato Simo
       ])
871 d8b7ff5f Adeodato Simo
872 d8b7ff5f Adeodato Simo
  def testNodes(self):
873 d8b7ff5f Adeodato Simo
    groups_to_nodes = {
874 d8b7ff5f Adeodato Simo
      "c0e89160-18e7-11e0-a46e-001d0904baeb": ["node1", "node2"],
875 d8b7ff5f Adeodato Simo
      "d2a40a74-18e7-11e0-9143-001d0904baeb": ["node1", "node10", "node9"],
876 d8b7ff5f Adeodato Simo
      }
877 d8b7ff5f Adeodato Simo
878 d8b7ff5f Adeodato Simo
    q = self._Create(["name", "node_cnt", "node_list"])
879 d8b7ff5f Adeodato Simo
    gqd = query.GroupQueryData(self.groups, groups_to_nodes, None)
880 d8b7ff5f Adeodato Simo
881 d8b7ff5f Adeodato Simo
    self.assertEqual(q.RequestedData(), set([query.GQ_CONFIG, query.GQ_NODE]))
882 d8b7ff5f Adeodato Simo
883 d8b7ff5f Adeodato Simo
    self.assertEqual(q.Query(gqd),
884 cfb084ae René Nussbaumer
                     [[(constants.RS_NORMAL, "default"),
885 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 2),
886 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, ["node1", "node2"]),
887 d8b7ff5f Adeodato Simo
                       ],
888 cfb084ae René Nussbaumer
                      [(constants.RS_NORMAL, "restricted"),
889 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 3),
890 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, ["node1", "node9", "node10"]),
891 d8b7ff5f Adeodato Simo
                       ],
892 d8b7ff5f Adeodato Simo
                      ])
893 d8b7ff5f Adeodato Simo
894 d8b7ff5f Adeodato Simo
  def testInstances(self):
895 d8b7ff5f Adeodato Simo
    groups_to_instances = {
896 d8b7ff5f Adeodato Simo
      "c0e89160-18e7-11e0-a46e-001d0904baeb": ["inst1", "inst2"],
897 d8b7ff5f Adeodato Simo
      "d2a40a74-18e7-11e0-9143-001d0904baeb": ["inst1", "inst10", "inst9"],
898 d8b7ff5f Adeodato Simo
      }
899 d8b7ff5f Adeodato Simo
900 d8b7ff5f Adeodato Simo
    q = self._Create(["pinst_cnt", "pinst_list"])
901 d8b7ff5f Adeodato Simo
    gqd = query.GroupQueryData(self.groups, None, groups_to_instances)
902 d8b7ff5f Adeodato Simo
903 d8b7ff5f Adeodato Simo
    self.assertEqual(q.RequestedData(), set([query.GQ_INST]))
904 d8b7ff5f Adeodato Simo
905 d8b7ff5f Adeodato Simo
    self.assertEqual(q.Query(gqd),
906 cfb084ae René Nussbaumer
                     [[(constants.RS_NORMAL, 2),
907 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, ["inst1", "inst2"]),
908 d8b7ff5f Adeodato Simo
                       ],
909 cfb084ae René Nussbaumer
                      [(constants.RS_NORMAL, 3),
910 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, ["inst1", "inst9", "inst10"]),
911 d8b7ff5f Adeodato Simo
                       ],
912 d8b7ff5f Adeodato Simo
                      ])
913 d8b7ff5f Adeodato Simo
914 d8b7ff5f Adeodato Simo
915 aa29e95f Michael Hanselmann
class TestQueryFields(unittest.TestCase):
916 aa29e95f Michael Hanselmann
  def testAllFields(self):
917 e571ee44 Adeodato Simo
    for fielddefs in query.ALL_FIELD_LISTS:
918 aa29e95f Michael Hanselmann
      result = query.QueryFields(fielddefs, None)
919 aa29e95f Michael Hanselmann
      self.assert_(isinstance(result, dict))
920 aa29e95f Michael Hanselmann
      response = objects.QueryFieldsResponse.FromDict(result)
921 aa29e95f Michael Hanselmann
      self.assertEqual([(fdef.name, fdef.title) for fdef in response.fields],
922 aa29e95f Michael Hanselmann
        [(fdef2.name, fdef2.title)
923 aa29e95f Michael Hanselmann
         for (fdef2, _, _) in utils.NiceSort(fielddefs.values(),
924 aa29e95f Michael Hanselmann
                                             key=lambda x: x[0].name)])
925 aa29e95f Michael Hanselmann
926 aa29e95f Michael Hanselmann
  def testSomeFields(self):
927 aa29e95f Michael Hanselmann
    rnd = random.Random(5357)
928 aa29e95f Michael Hanselmann
929 aa29e95f Michael Hanselmann
    for _ in range(10):
930 e571ee44 Adeodato Simo
      for fielddefs in query.ALL_FIELD_LISTS:
931 e571ee44 Adeodato Simo
        if len(fielddefs) > 20:
932 e571ee44 Adeodato Simo
          sample_size = rnd.randint(5, 20)
933 e571ee44 Adeodato Simo
        else:
934 e571ee44 Adeodato Simo
          sample_size = rnd.randint(1, max(1, len(fielddefs) - 1))
935 e571ee44 Adeodato Simo
        fields = [fdef for (fdef, _, _) in rnd.sample(fielddefs.values(),
936 e571ee44 Adeodato Simo
                                                      sample_size)]
937 aa29e95f Michael Hanselmann
        result = query.QueryFields(fielddefs, [fdef.name for fdef in fields])
938 aa29e95f Michael Hanselmann
        self.assert_(isinstance(result, dict))
939 aa29e95f Michael Hanselmann
        response = objects.QueryFieldsResponse.FromDict(result)
940 aa29e95f Michael Hanselmann
        self.assertEqual([(fdef.name, fdef.title) for fdef in response.fields],
941 aa29e95f Michael Hanselmann
                         [(fdef2.name, fdef2.title) for fdef2 in fields])
942 aa29e95f Michael Hanselmann
943 aa29e95f Michael Hanselmann
944 4ca96421 Michael Hanselmann
if __name__ == "__main__":
945 4ca96421 Michael Hanselmann
  testutils.GanetiTestProgram()