Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.query_unittest.py @ 3b877f08

History | View | Annotate | Download (58 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 79b2ca83 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
70 111bf531 Michael Hanselmann
       STATIC, 0, lambda ctx, item: item["name"]),
71 79b2ca83 Michael Hanselmann
      (query._MakeField("master", "Master", constants.QFT_BOOL, "Master"),
72 111bf531 Michael Hanselmann
       STATIC, 0, 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 79b2ca83 Michael Hanselmann
                         constants.QFT_UNIT, "Disk size %s" % i),
76 111bf531 Michael Hanselmann
        DISK, 0, 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 79b2ca83 Michael Hanselmann
                                   kind=constants.QFT_TEXT,
87 79b2ca83 Michael Hanselmann
                                   doc="Name").ToDict())
88 4ca96421 Michael Hanselmann
89 4ca96421 Michael Hanselmann
    # Create data only once query has been prepared
90 4ca96421 Michael Hanselmann
    data = [
91 4ca96421 Michael Hanselmann
      { "name": "node1", "disks": [0, 1, 2], },
92 4ca96421 Michael Hanselmann
      { "name": "node2", "disks": [3, 4], },
93 4ca96421 Michael Hanselmann
      { "name": "node3", "disks": [5, 6, 7], },
94 4ca96421 Michael Hanselmann
      ]
95 4ca96421 Michael Hanselmann
96 4ca96421 Michael Hanselmann
    self.assertEqual(q.Query(_QueryData(data, mastername="node3")),
97 cfb084ae Renรฉ Nussbaumer
                     [[(constants.RS_NORMAL, "node1")],
98 cfb084ae Renรฉ Nussbaumer
                      [(constants.RS_NORMAL, "node2")],
99 cfb084ae Renรฉ Nussbaumer
                      [(constants.RS_NORMAL, "node3")]])
100 4ca96421 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(_QueryData(data, mastername="node3")),
101 4ca96421 Michael Hanselmann
                     [["node1"], ["node2"], ["node3"]])
102 4ca96421 Michael Hanselmann
103 4ca96421 Michael Hanselmann
    q = query.Query(fielddef, ["name", "master"])
104 4ca96421 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([STATIC]))
105 4ca96421 Michael Hanselmann
    self.assertEqual(len(q._fields), 2)
106 4ca96421 Michael Hanselmann
    self.assertEqual(q.Query(_QueryData(data, mastername="node3")),
107 cfb084ae Renรฉ Nussbaumer
                     [[(constants.RS_NORMAL, "node1"),
108 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, False)],
109 cfb084ae Renรฉ Nussbaumer
                      [(constants.RS_NORMAL, "node2"),
110 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, False)],
111 cfb084ae Renรฉ Nussbaumer
                      [(constants.RS_NORMAL, "node3"),
112 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, True)],
113 4ca96421 Michael Hanselmann
                     ])
114 4ca96421 Michael Hanselmann
115 4ca96421 Michael Hanselmann
    q = query.Query(fielddef, ["name", "master", "disk0.size"])
116 4ca96421 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([STATIC, DISK]))
117 4ca96421 Michael Hanselmann
    self.assertEqual(len(q._fields), 3)
118 4ca96421 Michael Hanselmann
    self.assertEqual(q.Query(_QueryData(data, mastername="node2")),
119 cfb084ae Renรฉ Nussbaumer
                     [[(constants.RS_NORMAL, "node1"),
120 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, False),
121 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, 0)],
122 cfb084ae Renรฉ Nussbaumer
                      [(constants.RS_NORMAL, "node2"),
123 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, True),
124 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, 3)],
125 cfb084ae Renรฉ Nussbaumer
                      [(constants.RS_NORMAL, "node3"),
126 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, False),
127 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, 5)],
128 4ca96421 Michael Hanselmann
                     ])
129 4ca96421 Michael Hanselmann
130 4ca96421 Michael Hanselmann
    # With unknown column
131 4ca96421 Michael Hanselmann
    q = query.Query(fielddef, ["disk2.size", "disk1.size", "disk99.size",
132 4ca96421 Michael Hanselmann
                               "disk0.size"])
133 4ca96421 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DISK]))
134 4ca96421 Michael Hanselmann
    self.assertEqual(len(q._fields), 4)
135 4ca96421 Michael Hanselmann
    self.assertEqual(q.Query(_QueryData(data, mastername="node2")),
136 cfb084ae Renรฉ Nussbaumer
                     [[(constants.RS_NORMAL, 2),
137 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, 1),
138 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_UNKNOWN, None),
139 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, 0)],
140 cfb084ae Renรฉ Nussbaumer
                      [(constants.RS_UNAVAIL, None),
141 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, 4),
142 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_UNKNOWN, None),
143 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, 3)],
144 cfb084ae Renรฉ Nussbaumer
                      [(constants.RS_NORMAL, 7),
145 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, 6),
146 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_UNKNOWN, None),
147 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, 5)],
148 4ca96421 Michael Hanselmann
                     ])
149 4ca96421 Michael Hanselmann
    self.assertRaises(errors.OpPrereqError, q.OldStyleQuery,
150 4ca96421 Michael Hanselmann
                      _QueryData(data, mastername="node2"))
151 4ca96421 Michael Hanselmann
    self.assertEqual([fdef.ToDict() for fdef in q.GetFields()], [
152 4ca96421 Michael Hanselmann
                     { "name": "disk2.size", "title": "DiskSize2",
153 79b2ca83 Michael Hanselmann
                       "kind": constants.QFT_UNIT, "doc": "Disk size 2", },
154 4ca96421 Michael Hanselmann
                     { "name": "disk1.size", "title": "DiskSize1",
155 79b2ca83 Michael Hanselmann
                       "kind": constants.QFT_UNIT, "doc": "Disk size 1", },
156 4ca96421 Michael Hanselmann
                     { "name": "disk99.size", "title": "disk99.size",
157 79b2ca83 Michael Hanselmann
                       "kind": constants.QFT_UNKNOWN,
158 79b2ca83 Michael Hanselmann
                       "doc": "Unknown field 'disk99.size'", },
159 4ca96421 Michael Hanselmann
                     { "name": "disk0.size", "title": "DiskSize0",
160 79b2ca83 Michael Hanselmann
                       "kind": constants.QFT_UNIT, "doc": "Disk size 0", },
161 4ca96421 Michael Hanselmann
                     ])
162 4ca96421 Michael Hanselmann
163 4ca96421 Michael Hanselmann
    # Empty query
164 4ca96421 Michael Hanselmann
    q = query.Query(fielddef, [])
165 4ca96421 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([]))
166 4ca96421 Michael Hanselmann
    self.assertEqual(len(q._fields), 0)
167 4ca96421 Michael Hanselmann
    self.assertEqual(q.Query(_QueryData(data, mastername="node2")),
168 4ca96421 Michael Hanselmann
                     [[], [], []])
169 4ca96421 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(_QueryData(data, mastername="node2")),
170 4ca96421 Michael Hanselmann
                     [[], [], []])
171 4ca96421 Michael Hanselmann
    self.assertEqual(q.GetFields(), [])
172 4ca96421 Michael Hanselmann
173 4ca96421 Michael Hanselmann
  def testPrepareFieldList(self):
174 4ca96421 Michael Hanselmann
    # Duplicate titles
175 4ca96421 Michael Hanselmann
    for (a, b) in [("name", "name"), ("NAME", "name")]:
176 4ca96421 Michael Hanselmann
      self.assertRaises(AssertionError, query._PrepareFieldList, [
177 111bf531 Michael Hanselmann
        (query._MakeField("name", b, constants.QFT_TEXT, "Name"), None, 0,
178 4ca96421 Michael Hanselmann
         lambda *args: None),
179 111bf531 Michael Hanselmann
        (query._MakeField("other", a, constants.QFT_TEXT, "Other"), None, 0,
180 4ca96421 Michael Hanselmann
         lambda *args: None),
181 d63bd540 Iustin Pop
        ], [])
182 4ca96421 Michael Hanselmann
183 4ca96421 Michael Hanselmann
    # Non-lowercase names
184 4ca96421 Michael Hanselmann
    self.assertRaises(AssertionError, query._PrepareFieldList, [
185 111bf531 Michael Hanselmann
      (query._MakeField("NAME", "Name", constants.QFT_TEXT, "Name"), None, 0,
186 4ca96421 Michael Hanselmann
       lambda *args: None),
187 d63bd540 Iustin Pop
      ], [])
188 4ca96421 Michael Hanselmann
    self.assertRaises(AssertionError, query._PrepareFieldList, [
189 111bf531 Michael Hanselmann
      (query._MakeField("Name", "Name", constants.QFT_TEXT, "Name"), None, 0,
190 4ca96421 Michael Hanselmann
       lambda *args: None),
191 d63bd540 Iustin Pop
      ], [])
192 4ca96421 Michael Hanselmann
193 4ca96421 Michael Hanselmann
    # Empty name
194 4ca96421 Michael Hanselmann
    self.assertRaises(AssertionError, query._PrepareFieldList, [
195 111bf531 Michael Hanselmann
      (query._MakeField("", "Name", constants.QFT_TEXT, "Name"), None, 0,
196 4ca96421 Michael Hanselmann
       lambda *args: None),
197 d63bd540 Iustin Pop
      ], [])
198 4ca96421 Michael Hanselmann
199 4ca96421 Michael Hanselmann
    # Empty title
200 4ca96421 Michael Hanselmann
    self.assertRaises(AssertionError, query._PrepareFieldList, [
201 111bf531 Michael Hanselmann
      (query._MakeField("name", "", constants.QFT_TEXT, "Name"), None, 0,
202 4ca96421 Michael Hanselmann
       lambda *args: None),
203 d63bd540 Iustin Pop
      ], [])
204 4ca96421 Michael Hanselmann
205 4ca96421 Michael Hanselmann
    # Whitespace in title
206 4ca96421 Michael Hanselmann
    self.assertRaises(AssertionError, query._PrepareFieldList, [
207 111bf531 Michael Hanselmann
      (query._MakeField("name", "Co lu mn", constants.QFT_TEXT, "Name"),
208 111bf531 Michael Hanselmann
       None, 0, lambda *args: None),
209 d63bd540 Iustin Pop
      ], [])
210 4ca96421 Michael Hanselmann
211 4ca96421 Michael Hanselmann
    # No callable function
212 4ca96421 Michael Hanselmann
    self.assertRaises(AssertionError, query._PrepareFieldList, [
213 79b2ca83 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
214 111bf531 Michael Hanselmann
       None, 0, None),
215 d63bd540 Iustin Pop
      ], [])
216 4ca96421 Michael Hanselmann
217 79b2ca83 Michael Hanselmann
    # Invalid documentation
218 79b2ca83 Michael Hanselmann
    for doc in ["", ".", "Hello world\n", "Hello\nWo\nrld", "Hello World!",
219 79b2ca83 Michael Hanselmann
                "HelloWorld.", "only lowercase", ",", " x y z .\t", "  "]:
220 79b2ca83 Michael Hanselmann
      self.assertRaises(AssertionError, query._PrepareFieldList, [
221 79b2ca83 Michael Hanselmann
        (query._MakeField("name", "Name", constants.QFT_TEXT, doc),
222 111bf531 Michael Hanselmann
        None, 0, lambda *args: None),
223 79b2ca83 Michael Hanselmann
        ], [])
224 79b2ca83 Michael Hanselmann
225 4ca96421 Michael Hanselmann
  def testUnknown(self):
226 4ca96421 Michael Hanselmann
    fielddef = query._PrepareFieldList([
227 79b2ca83 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
228 111bf531 Michael Hanselmann
       None, 0, lambda _, item: "name%s" % item),
229 79b2ca83 Michael Hanselmann
      (query._MakeField("other0", "Other0", constants.QFT_TIMESTAMP, "Other"),
230 111bf531 Michael Hanselmann
       None, 0, lambda *args: 1234),
231 79b2ca83 Michael Hanselmann
      (query._MakeField("nodata", "NoData", constants.QFT_NUMBER, "No data"),
232 111bf531 Michael Hanselmann
       None, 0, lambda *args: query._FS_NODATA ),
233 79b2ca83 Michael Hanselmann
      (query._MakeField("unavail", "Unavail", constants.QFT_BOOL, "Unavail"),
234 111bf531 Michael Hanselmann
       None, 0, lambda *args: query._FS_UNAVAIL),
235 d63bd540 Iustin Pop
      ], [])
236 4ca96421 Michael Hanselmann
237 4ca96421 Michael Hanselmann
    for selected in [["foo"], ["Hello", "World"],
238 4ca96421 Michael Hanselmann
                     ["name1", "other", "foo"]]:
239 4ca96421 Michael Hanselmann
      q = query.Query(fielddef, selected)
240 4ca96421 Michael Hanselmann
      self.assertEqual(len(q._fields), len(selected))
241 4ca96421 Michael Hanselmann
      self.assert_(compat.all(len(row) == len(selected)
242 4ca96421 Michael Hanselmann
                              for row in q.Query(_QueryData(range(1, 10)))))
243 4ca96421 Michael Hanselmann
      self.assertEqual(q.Query(_QueryData(range(1, 10))),
244 cfb084ae Renรฉ Nussbaumer
                       [[(constants.RS_UNKNOWN, None)] * len(selected)
245 4ca96421 Michael Hanselmann
                        for i in range(1, 10)])
246 4ca96421 Michael Hanselmann
      self.assertEqual([fdef.ToDict() for fdef in q.GetFields()],
247 4ca96421 Michael Hanselmann
                       [{ "name": name, "title": name,
248 79b2ca83 Michael Hanselmann
                          "kind": constants.QFT_UNKNOWN,
249 79b2ca83 Michael Hanselmann
                          "doc": "Unknown field '%s'" % name}
250 4ca96421 Michael Hanselmann
                        for name in selected])
251 4ca96421 Michael Hanselmann
252 4ca96421 Michael Hanselmann
    q = query.Query(fielddef, ["name", "other0", "nodata", "unavail"])
253 4ca96421 Michael Hanselmann
    self.assertEqual(len(q._fields), 4)
254 4ca96421 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(_QueryData(range(1, 10))), [
255 4ca96421 Michael Hanselmann
                     ["name%s" % i, 1234, None, None]
256 4ca96421 Michael Hanselmann
                     for i in range(1, 10)
257 4ca96421 Michael Hanselmann
                     ])
258 4ca96421 Michael Hanselmann
259 4ca96421 Michael Hanselmann
    q = query.Query(fielddef, ["name", "other0", "nodata", "unavail", "unk"])
260 4ca96421 Michael Hanselmann
    self.assertEqual(len(q._fields), 5)
261 4ca96421 Michael Hanselmann
    self.assertEqual(q.Query(_QueryData(range(1, 10))),
262 cfb084ae Renรฉ Nussbaumer
                     [[(constants.RS_NORMAL, "name%s" % i),
263 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, 1234),
264 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NODATA, None),
265 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_UNAVAIL, None),
266 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_UNKNOWN, None)]
267 4ca96421 Michael Hanselmann
                      for i in range(1, 10)])
268 4ca96421 Michael Hanselmann
269 d63bd540 Iustin Pop
  def testAliases(self):
270 d63bd540 Iustin Pop
    fields = [
271 111bf531 Michael Hanselmann
      (query._MakeField("a", "a-title", constants.QFT_TEXT, "Field A"),
272 111bf531 Michael Hanselmann
       None, 0, lambda *args: None),
273 111bf531 Michael Hanselmann
      (query._MakeField("b", "b-title", constants.QFT_TEXT, "Field B"),
274 111bf531 Michael Hanselmann
       None, 0, lambda *args: None),
275 d63bd540 Iustin Pop
      ]
276 d63bd540 Iustin Pop
    # duplicate field
277 d63bd540 Iustin Pop
    self.assertRaises(AssertionError, query._PrepareFieldList, fields,
278 d63bd540 Iustin Pop
                      [("b", "a")])
279 d63bd540 Iustin Pop
    self.assertRaises(AssertionError, query._PrepareFieldList, fields,
280 d63bd540 Iustin Pop
                      [("c", "b"), ("c", "a")])
281 d63bd540 Iustin Pop
    # missing target
282 d63bd540 Iustin Pop
    self.assertRaises(AssertionError, query._PrepareFieldList, fields,
283 d63bd540 Iustin Pop
                      [("c", "d")])
284 d63bd540 Iustin Pop
    fdefs = query._PrepareFieldList(fields, [("c", "b")])
285 d63bd540 Iustin Pop
    self.assertEqual(len(fdefs), 3)
286 d63bd540 Iustin Pop
    self.assertEqual(fdefs["b"][1:], fdefs["c"][1:])
287 d63bd540 Iustin Pop
288 4ca96421 Michael Hanselmann
289 8235fe04 Michael Hanselmann
class TestGetNodeRole(unittest.TestCase):
290 1e28e3b8 Michael Hanselmann
  def test(self):
291 1e28e3b8 Michael Hanselmann
    tested_role = set()
292 1e28e3b8 Michael Hanselmann
293 1e28e3b8 Michael Hanselmann
    checks = [
294 1e28e3b8 Michael Hanselmann
      (constants.NR_MASTER, "node1", objects.Node(name="node1")),
295 1e28e3b8 Michael Hanselmann
      (constants.NR_MCANDIDATE, "master",
296 1e28e3b8 Michael Hanselmann
       objects.Node(name="node1", master_candidate=True)),
297 1e28e3b8 Michael Hanselmann
      (constants.NR_REGULAR, "master", objects.Node(name="node1")),
298 1e28e3b8 Michael Hanselmann
      (constants.NR_DRAINED, "master",
299 1e28e3b8 Michael Hanselmann
       objects.Node(name="node1", drained=True)),
300 1e28e3b8 Michael Hanselmann
      (constants.NR_OFFLINE,
301 1e28e3b8 Michael Hanselmann
       "master", objects.Node(name="node1", offline=True)),
302 1e28e3b8 Michael Hanselmann
      ]
303 8235fe04 Michael Hanselmann
304 1e28e3b8 Michael Hanselmann
    for (role, master_name, node) in checks:
305 1e28e3b8 Michael Hanselmann
      result = query._GetNodeRole(node, master_name)
306 1e28e3b8 Michael Hanselmann
      self.assertEqual(result, role)
307 1e28e3b8 Michael Hanselmann
      tested_role.add(result)
308 8235fe04 Michael Hanselmann
309 1e28e3b8 Michael Hanselmann
    self.assertEqual(tested_role, constants.NR_ALL)
310 8235fe04 Michael Hanselmann
311 8235fe04 Michael Hanselmann
312 8235fe04 Michael Hanselmann
class TestNodeQuery(unittest.TestCase):
313 8235fe04 Michael Hanselmann
  def _Create(self, selected):
314 8235fe04 Michael Hanselmann
    return query.Query(query.NODE_FIELDS, selected)
315 8235fe04 Michael Hanselmann
316 8235fe04 Michael Hanselmann
  def testSimple(self):
317 8235fe04 Michael Hanselmann
    nodes = [
318 8235fe04 Michael Hanselmann
      objects.Node(name="node1", drained=False),
319 8235fe04 Michael Hanselmann
      objects.Node(name="node2", drained=True),
320 8235fe04 Michael Hanselmann
      objects.Node(name="node3", drained=False),
321 8235fe04 Michael Hanselmann
      ]
322 8235fe04 Michael Hanselmann
    for live_data in [None, dict.fromkeys([node.name for node in nodes], {})]:
323 8572f1fe Renรฉ Nussbaumer
      nqd = query.NodeQueryData(nodes, live_data, None, None, None, None, None,
324 8572f1fe Renรฉ Nussbaumer
                                None)
325 8235fe04 Michael Hanselmann
326 8235fe04 Michael Hanselmann
      q = self._Create(["name", "drained"])
327 8235fe04 Michael Hanselmann
      self.assertEqual(q.RequestedData(), set([query.NQ_CONFIG]))
328 8235fe04 Michael Hanselmann
      self.assertEqual(q.Query(nqd),
329 cfb084ae Renรฉ Nussbaumer
                       [[(constants.RS_NORMAL, "node1"),
330 cfb084ae Renรฉ Nussbaumer
                         (constants.RS_NORMAL, False)],
331 cfb084ae Renรฉ Nussbaumer
                        [(constants.RS_NORMAL, "node2"),
332 cfb084ae Renรฉ Nussbaumer
                         (constants.RS_NORMAL, True)],
333 cfb084ae Renรฉ Nussbaumer
                        [(constants.RS_NORMAL, "node3"),
334 cfb084ae Renรฉ Nussbaumer
                         (constants.RS_NORMAL, False)],
335 8235fe04 Michael Hanselmann
                       ])
336 8235fe04 Michael Hanselmann
      self.assertEqual(q.OldStyleQuery(nqd),
337 8235fe04 Michael Hanselmann
                       [["node1", False],
338 8235fe04 Michael Hanselmann
                        ["node2", True],
339 8235fe04 Michael Hanselmann
                        ["node3", False]])
340 8235fe04 Michael Hanselmann
341 8235fe04 Michael Hanselmann
  def test(self):
342 8235fe04 Michael Hanselmann
    selected = query.NODE_FIELDS.keys()
343 8235fe04 Michael Hanselmann
    field_index = dict((field, idx) for idx, field in enumerate(selected))
344 8235fe04 Michael Hanselmann
345 8235fe04 Michael Hanselmann
    q = self._Create(selected)
346 8235fe04 Michael Hanselmann
    self.assertEqual(q.RequestedData(),
347 8235fe04 Michael Hanselmann
                     set([query.NQ_CONFIG, query.NQ_LIVE, query.NQ_INST,
348 52b5d286 Renรฉ Nussbaumer
                          query.NQ_GROUP, query.NQ_OOB]))
349 8235fe04 Michael Hanselmann
350 8572f1fe Renรฉ Nussbaumer
    cluster = objects.Cluster(cluster_name="testcluster",
351 8572f1fe Renรฉ Nussbaumer
      hvparams=constants.HVC_DEFAULTS,
352 8572f1fe Renรฉ Nussbaumer
      beparams={
353 8572f1fe Renรฉ Nussbaumer
        constants.PP_DEFAULT: constants.BEC_DEFAULTS,
354 8572f1fe Renรฉ Nussbaumer
        },
355 8572f1fe Renรฉ Nussbaumer
      nicparams={
356 8572f1fe Renรฉ Nussbaumer
        constants.PP_DEFAULT: constants.NICC_DEFAULTS,
357 8572f1fe Renรฉ Nussbaumer
        },
358 8572f1fe Renรฉ Nussbaumer
      ndparams=constants.NDC_DEFAULTS,
359 8572f1fe Renรฉ Nussbaumer
        )
360 8572f1fe Renรฉ Nussbaumer
361 8235fe04 Michael Hanselmann
    node_names = ["node%s" % i for i in range(20)]
362 8235fe04 Michael Hanselmann
    master_name = node_names[3]
363 8235fe04 Michael Hanselmann
    nodes = [
364 8235fe04 Michael Hanselmann
      objects.Node(name=name,
365 8235fe04 Michael Hanselmann
                   primary_ip="192.0.2.%s" % idx,
366 8235fe04 Michael Hanselmann
                   secondary_ip="192.0.100.%s" % idx,
367 8235fe04 Michael Hanselmann
                   serial_no=7789 * idx,
368 8235fe04 Michael Hanselmann
                   master_candidate=(name != master_name and idx % 3 == 0),
369 8235fe04 Michael Hanselmann
                   offline=False,
370 8235fe04 Michael Hanselmann
                   drained=False,
371 b12d5e2e Renรฉ Nussbaumer
                   powered=True,
372 effab4ca Iustin Pop
                   vm_capable=True,
373 8235fe04 Michael Hanselmann
                   master_capable=False,
374 8572f1fe Renรฉ Nussbaumer
                   ndparams={},
375 8235fe04 Michael Hanselmann
                   group="default",
376 8235fe04 Michael Hanselmann
                   ctime=1290006900,
377 8235fe04 Michael Hanselmann
                   mtime=1290006913,
378 8235fe04 Michael Hanselmann
                   uuid="fd9ccebe-6339-43c9-a82e-94bbe575%04d" % idx)
379 8235fe04 Michael Hanselmann
      for idx, name in enumerate(node_names)
380 8235fe04 Michael Hanselmann
      ]
381 8235fe04 Michael Hanselmann
382 8235fe04 Michael Hanselmann
    master_node = nodes[3]
383 8235fe04 Michael Hanselmann
    master_node.AddTag("masternode")
384 8235fe04 Michael Hanselmann
    master_node.AddTag("another")
385 8235fe04 Michael Hanselmann
    master_node.AddTag("tag")
386 145bea54 Michael Hanselmann
    master_node.ctime = None
387 145bea54 Michael Hanselmann
    master_node.mtime = None
388 8235fe04 Michael Hanselmann
    assert master_node.name == master_name
389 8235fe04 Michael Hanselmann
390 8235fe04 Michael Hanselmann
    live_data_name = node_names[4]
391 8235fe04 Michael Hanselmann
    assert live_data_name != master_name
392 8235fe04 Michael Hanselmann
393 8235fe04 Michael Hanselmann
    fake_live_data = {
394 8235fe04 Michael Hanselmann
      "bootid": "a2504766-498e-4b25-b21e-d23098dc3af4",
395 8235fe04 Michael Hanselmann
      "cnodes": 4,
396 8235fe04 Michael Hanselmann
      "csockets": 4,
397 8235fe04 Michael Hanselmann
      "ctotal": 8,
398 8235fe04 Michael Hanselmann
      "mnode": 128,
399 8235fe04 Michael Hanselmann
      "mfree": 100,
400 8235fe04 Michael Hanselmann
      "mtotal": 4096,
401 8235fe04 Michael Hanselmann
      "dfree": 5 * 1024 * 1024,
402 8235fe04 Michael Hanselmann
      "dtotal": 100 * 1024 * 1024,
403 8235fe04 Michael Hanselmann
      }
404 8235fe04 Michael Hanselmann
405 8235fe04 Michael Hanselmann
    assert (sorted(query._NODE_LIVE_FIELDS.keys()) ==
406 8235fe04 Michael Hanselmann
            sorted(fake_live_data.keys()))
407 8235fe04 Michael Hanselmann
408 8235fe04 Michael Hanselmann
    live_data = dict.fromkeys(node_names, {})
409 8235fe04 Michael Hanselmann
    live_data[live_data_name] = \
410 8235fe04 Michael Hanselmann
      dict((query._NODE_LIVE_FIELDS[name][2], value)
411 8235fe04 Michael Hanselmann
           for name, value in fake_live_data.items())
412 8235fe04 Michael Hanselmann
413 8235fe04 Michael Hanselmann
    node_to_primary = dict((name, set()) for name in node_names)
414 8235fe04 Michael Hanselmann
    node_to_primary[master_name].update(["inst1", "inst2"])
415 8235fe04 Michael Hanselmann
416 8235fe04 Michael Hanselmann
    node_to_secondary = dict((name, set()) for name in node_names)
417 8235fe04 Michael Hanselmann
    node_to_secondary[live_data_name].update(["instX", "instY", "instZ"])
418 8235fe04 Michael Hanselmann
419 8235fe04 Michael Hanselmann
    ng_uuid = "492b4b74-8670-478a-b98d-4c53a76238e6"
420 8235fe04 Michael Hanselmann
    groups = {
421 8572f1fe Renรฉ Nussbaumer
      ng_uuid: objects.NodeGroup(name="ng1", uuid=ng_uuid, ndparams={}),
422 8235fe04 Michael Hanselmann
      }
423 8235fe04 Michael Hanselmann
424 b12d5e2e Renรฉ Nussbaumer
    oob_not_powered_node = node_names[0]
425 b12d5e2e Renรฉ Nussbaumer
    nodes[0].powered = False
426 52b5d286 Renรฉ Nussbaumer
    oob_support = dict((name, False) for name in node_names)
427 b12d5e2e Renรฉ Nussbaumer
    oob_support[master_name] = True
428 b12d5e2e Renรฉ Nussbaumer
    oob_support[oob_not_powered_node] = True
429 52b5d286 Renรฉ Nussbaumer
430 8235fe04 Michael Hanselmann
    master_node.group = ng_uuid
431 8235fe04 Michael Hanselmann
432 8235fe04 Michael Hanselmann
    nqd = query.NodeQueryData(nodes, live_data, master_name,
433 52b5d286 Renรฉ Nussbaumer
                              node_to_primary, node_to_secondary, groups,
434 8572f1fe Renรฉ Nussbaumer
                              oob_support, cluster)
435 8235fe04 Michael Hanselmann
    result = q.Query(nqd)
436 8235fe04 Michael Hanselmann
    self.assert_(compat.all(len(row) == len(selected) for row in result))
437 8235fe04 Michael Hanselmann
    self.assertEqual([row[field_index["name"]] for row in result],
438 cfb084ae Renรฉ Nussbaumer
                     [(constants.RS_NORMAL, name) for name in node_names])
439 8235fe04 Michael Hanselmann
440 8235fe04 Michael Hanselmann
    node_to_row = dict((row[field_index["name"]][1], idx)
441 8235fe04 Michael Hanselmann
                       for idx, row in enumerate(result))
442 8235fe04 Michael Hanselmann
443 8235fe04 Michael Hanselmann
    master_row = result[node_to_row[master_name]]
444 8235fe04 Michael Hanselmann
    self.assert_(master_row[field_index["master"]])
445 8235fe04 Michael Hanselmann
    self.assert_(master_row[field_index["role"]], "M")
446 8235fe04 Michael Hanselmann
    self.assertEqual(master_row[field_index["group"]],
447 cfb084ae Renรฉ Nussbaumer
                     (constants.RS_NORMAL, "ng1"))
448 8235fe04 Michael Hanselmann
    self.assertEqual(master_row[field_index["group.uuid"]],
449 cfb084ae Renรฉ Nussbaumer
                     (constants.RS_NORMAL, ng_uuid))
450 145bea54 Michael Hanselmann
    self.assertEqual(master_row[field_index["ctime"]],
451 cfb084ae Renรฉ Nussbaumer
                     (constants.RS_UNAVAIL, None))
452 145bea54 Michael Hanselmann
    self.assertEqual(master_row[field_index["mtime"]],
453 cfb084ae Renรฉ Nussbaumer
                     (constants.RS_UNAVAIL, None))
454 8235fe04 Michael Hanselmann
455 8235fe04 Michael Hanselmann
    self.assert_(row[field_index["pip"]] == node.primary_ip and
456 8235fe04 Michael Hanselmann
                 row[field_index["sip"]] == node.secondary_ip and
457 8235fe04 Michael Hanselmann
                 set(row[field_index["tags"]]) == node.GetTags() and
458 8235fe04 Michael Hanselmann
                 row[field_index["serial_no"]] == node.serial_no and
459 8235fe04 Michael Hanselmann
                 row[field_index["role"]] == query._GetNodeRole(node,
460 8235fe04 Michael Hanselmann
                                                                master_name) and
461 8235fe04 Michael Hanselmann
                 (node.name == master_name or
462 8235fe04 Michael Hanselmann
                  (row[field_index["group"]] == "<unknown>" and
463 145bea54 Michael Hanselmann
                   row[field_index["group.uuid"]] is None and
464 cfb084ae Renรฉ Nussbaumer
                   row[field_index["ctime"]] == (constants.RS_NORMAL,
465 145bea54 Michael Hanselmann
                                                 node.ctime) and
466 cfb084ae Renรฉ Nussbaumer
                   row[field_index["mtime"]] == (constants.RS_NORMAL,
467 b12d5e2e Renรฉ Nussbaumer
                                                 node.mtime) and
468 b12d5e2e Renรฉ Nussbaumer
                   row[field_index["powered"]] == (constants.RS_NORMAL,
469 b12d5e2e Renรฉ Nussbaumer
                                                   True))) or
470 b12d5e2e Renรฉ Nussbaumer
                 (node.name == oob_not_powered_node and
471 b12d5e2e Renรฉ Nussbaumer
                  row[field_index["powered"]] == (constants.RS_NORMAL,
472 b12d5e2e Renรฉ Nussbaumer
                                                  False)) or
473 b12d5e2e Renรฉ Nussbaumer
                 row[field_index["powered"]] == (constants.RS_UNAVAIL, None)
474 8235fe04 Michael Hanselmann
                 for row, node in zip(result, nodes))
475 8235fe04 Michael Hanselmann
476 8235fe04 Michael Hanselmann
    live_data_row = result[node_to_row[live_data_name]]
477 8235fe04 Michael Hanselmann
478 8235fe04 Michael Hanselmann
    for (field, value) in fake_live_data.items():
479 8235fe04 Michael Hanselmann
      self.assertEqual(live_data_row[field_index[field]],
480 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, value))
481 8235fe04 Michael Hanselmann
482 8235fe04 Michael Hanselmann
    self.assertEqual(master_row[field_index["pinst_cnt"]],
483 cfb084ae Renรฉ Nussbaumer
                     (constants.RS_NORMAL, 2))
484 8235fe04 Michael Hanselmann
    self.assertEqual(live_data_row[field_index["sinst_cnt"]],
485 cfb084ae Renรฉ Nussbaumer
                     (constants.RS_NORMAL, 3))
486 8235fe04 Michael Hanselmann
    self.assertEqual(master_row[field_index["pinst_list"]],
487 cfb084ae Renรฉ Nussbaumer
                     (constants.RS_NORMAL,
488 8235fe04 Michael Hanselmann
                      list(node_to_primary[master_name])))
489 8235fe04 Michael Hanselmann
    self.assertEqual(live_data_row[field_index["sinst_list"]],
490 cfb084ae Renรฉ Nussbaumer
                     (constants.RS_NORMAL,
491 8235fe04 Michael Hanselmann
                      list(node_to_secondary[live_data_name])))
492 8235fe04 Michael Hanselmann
493 8235fe04 Michael Hanselmann
  def testGetLiveNodeField(self):
494 8235fe04 Michael Hanselmann
    nodes = [
495 effab4ca Iustin Pop
      objects.Node(name="node1", drained=False, offline=False,
496 effab4ca Iustin Pop
                   vm_capable=True),
497 effab4ca Iustin Pop
      objects.Node(name="node2", drained=True, offline=False,
498 effab4ca Iustin Pop
                   vm_capable=True),
499 effab4ca Iustin Pop
      objects.Node(name="node3", drained=False, offline=False,
500 effab4ca Iustin Pop
                   vm_capable=True),
501 effab4ca Iustin Pop
      objects.Node(name="node4", drained=False, offline=True,
502 effab4ca Iustin Pop
                   vm_capable=True),
503 effab4ca Iustin Pop
      objects.Node(name="node5", drained=False, offline=False,
504 effab4ca Iustin Pop
                   vm_capable=False),
505 8235fe04 Michael Hanselmann
      ]
506 8235fe04 Michael Hanselmann
    live_data = dict.fromkeys([node.name for node in nodes], {})
507 8235fe04 Michael Hanselmann
508 8235fe04 Michael Hanselmann
    # No data
509 8572f1fe Renรฉ Nussbaumer
    nqd = query.NodeQueryData(None, None, None, None, None, None, None, None)
510 8235fe04 Michael Hanselmann
    self.assertEqual(query._GetLiveNodeField("hello", constants.QFT_NUMBER,
511 a6070ef7 Michael Hanselmann
                                             nqd, nodes[0]),
512 e2d188cc Iustin Pop
                     query._FS_NODATA)
513 8235fe04 Michael Hanselmann
514 8235fe04 Michael Hanselmann
    # Missing field
515 8235fe04 Michael Hanselmann
    ctx = _QueryData(None, curlive_data={
516 8235fe04 Michael Hanselmann
      "some": 1,
517 8235fe04 Michael Hanselmann
      "other": 2,
518 8235fe04 Michael Hanselmann
      })
519 8235fe04 Michael Hanselmann
    self.assertEqual(query._GetLiveNodeField("hello", constants.QFT_NUMBER,
520 a6070ef7 Michael Hanselmann
                                             ctx, nodes[0]),
521 e2d188cc Iustin Pop
                     query._FS_UNAVAIL)
522 8235fe04 Michael Hanselmann
523 8235fe04 Michael Hanselmann
    # Wrong format/datatype
524 8235fe04 Michael Hanselmann
    ctx = _QueryData(None, curlive_data={
525 8235fe04 Michael Hanselmann
      "hello": ["Hello World"],
526 8235fe04 Michael Hanselmann
      "other": 2,
527 8235fe04 Michael Hanselmann
      })
528 8235fe04 Michael Hanselmann
    self.assertEqual(query._GetLiveNodeField("hello", constants.QFT_NUMBER,
529 a6070ef7 Michael Hanselmann
                                             ctx, nodes[0]),
530 e2d188cc Iustin Pop
                     query._FS_UNAVAIL)
531 8235fe04 Michael Hanselmann
532 a6070ef7 Michael Hanselmann
    # Offline node
533 a6070ef7 Michael Hanselmann
    assert nodes[3].offline
534 a6070ef7 Michael Hanselmann
    ctx = _QueryData(None, curlive_data={})
535 a6070ef7 Michael Hanselmann
    self.assertEqual(query._GetLiveNodeField("hello", constants.QFT_NUMBER,
536 a6070ef7 Michael Hanselmann
                                             ctx, nodes[3]),
537 e2d188cc Iustin Pop
                     query._FS_OFFLINE, None)
538 a6070ef7 Michael Hanselmann
539 8235fe04 Michael Hanselmann
    # Wrong field type
540 8235fe04 Michael Hanselmann
    ctx = _QueryData(None, curlive_data={"hello": 123})
541 8235fe04 Michael Hanselmann
    self.assertRaises(AssertionError, query._GetLiveNodeField,
542 a6070ef7 Michael Hanselmann
                      "hello", constants.QFT_BOOL, ctx, nodes[0])
543 8235fe04 Michael Hanselmann
544 effab4ca Iustin Pop
    # Non-vm_capable node
545 effab4ca Iustin Pop
    assert not nodes[4].vm_capable
546 effab4ca Iustin Pop
    ctx = _QueryData(None, curlive_data={})
547 effab4ca Iustin Pop
    self.assertEqual(query._GetLiveNodeField("hello", constants.QFT_NUMBER,
548 effab4ca Iustin Pop
                                             ctx, nodes[4]),
549 effab4ca Iustin Pop
                     query._FS_UNAVAIL, None)
550 effab4ca Iustin Pop
551 8235fe04 Michael Hanselmann
552 1c8addc6 Michael Hanselmann
class TestInstanceQuery(unittest.TestCase):
553 1c8addc6 Michael Hanselmann
  def _Create(self, selected):
554 1c8addc6 Michael Hanselmann
    return query.Query(query.INSTANCE_FIELDS, selected)
555 1c8addc6 Michael Hanselmann
556 1c8addc6 Michael Hanselmann
  def testSimple(self):
557 1c8addc6 Michael Hanselmann
    q = self._Create(["name", "be/memory", "ip"])
558 1c8addc6 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([query.IQ_CONFIG]))
559 1c8addc6 Michael Hanselmann
560 1c8addc6 Michael Hanselmann
    cluster = objects.Cluster(cluster_name="testcluster",
561 1c8addc6 Michael Hanselmann
      hvparams=constants.HVC_DEFAULTS,
562 1c8addc6 Michael Hanselmann
      beparams={
563 1c8addc6 Michael Hanselmann
        constants.PP_DEFAULT: constants.BEC_DEFAULTS,
564 1c8addc6 Michael Hanselmann
        },
565 1c8addc6 Michael Hanselmann
      nicparams={
566 1c8addc6 Michael Hanselmann
        constants.PP_DEFAULT: constants.NICC_DEFAULTS,
567 1c8addc6 Michael Hanselmann
        })
568 1c8addc6 Michael Hanselmann
569 1c8addc6 Michael Hanselmann
    instances = [
570 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst1", hvparams={}, beparams={}, nics=[]),
571 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst2", hvparams={}, nics=[],
572 1c8addc6 Michael Hanselmann
        beparams={
573 1c8addc6 Michael Hanselmann
          constants.BE_MEMORY: 512,
574 1c8addc6 Michael Hanselmann
        }),
575 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst3", hvparams={}, beparams={},
576 1c8addc6 Michael Hanselmann
        nics=[objects.NIC(ip="192.0.2.99", nicparams={})]),
577 1c8addc6 Michael Hanselmann
      ]
578 1c8addc6 Michael Hanselmann
579 5d28cb6f Michael Hanselmann
    iqd = query.InstanceQueryData(instances, cluster, None, [], [], {},
580 5d28cb6f Michael Hanselmann
                                  set(), {})
581 1c8addc6 Michael Hanselmann
    self.assertEqual(q.Query(iqd),
582 cfb084ae Renรฉ Nussbaumer
      [[(constants.RS_NORMAL, "inst1"),
583 cfb084ae Renรฉ Nussbaumer
        (constants.RS_NORMAL, 128),
584 cfb084ae Renรฉ Nussbaumer
        (constants.RS_UNAVAIL, None),
585 1c8addc6 Michael Hanselmann
       ],
586 cfb084ae Renรฉ Nussbaumer
       [(constants.RS_NORMAL, "inst2"),
587 cfb084ae Renรฉ Nussbaumer
        (constants.RS_NORMAL, 512),
588 cfb084ae Renรฉ Nussbaumer
        (constants.RS_UNAVAIL, None),
589 1c8addc6 Michael Hanselmann
       ],
590 cfb084ae Renรฉ Nussbaumer
       [(constants.RS_NORMAL, "inst3"),
591 cfb084ae Renรฉ Nussbaumer
        (constants.RS_NORMAL, 128),
592 cfb084ae Renรฉ Nussbaumer
        (constants.RS_NORMAL, "192.0.2.99"),
593 1c8addc6 Michael Hanselmann
       ]])
594 1c8addc6 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(iqd),
595 1c8addc6 Michael Hanselmann
      [["inst1", 128, None],
596 1c8addc6 Michael Hanselmann
       ["inst2", 512, None],
597 1c8addc6 Michael Hanselmann
       ["inst3", 128, "192.0.2.99"]])
598 1c8addc6 Michael Hanselmann
599 1c8addc6 Michael Hanselmann
  def test(self):
600 1c8addc6 Michael Hanselmann
    selected = query.INSTANCE_FIELDS.keys()
601 1c8addc6 Michael Hanselmann
    fieldidx = dict((field, idx) for idx, field in enumerate(selected))
602 1c8addc6 Michael Hanselmann
603 1c8addc6 Michael Hanselmann
    macs = ["00:11:22:%02x:%02x:%02x" % (i % 255, i % 3, (i * 123) % 255)
604 1c8addc6 Michael Hanselmann
            for i in range(20)]
605 1c8addc6 Michael Hanselmann
606 1c8addc6 Michael Hanselmann
    q = self._Create(selected)
607 1c8addc6 Michael Hanselmann
    self.assertEqual(q.RequestedData(),
608 5d28cb6f Michael Hanselmann
                     set([query.IQ_CONFIG, query.IQ_LIVE, query.IQ_DISKUSAGE,
609 5d28cb6f Michael Hanselmann
                          query.IQ_CONSOLE]))
610 1c8addc6 Michael Hanselmann
611 1c8addc6 Michael Hanselmann
    cluster = objects.Cluster(cluster_name="testcluster",
612 1c8addc6 Michael Hanselmann
      hvparams=constants.HVC_DEFAULTS,
613 1c8addc6 Michael Hanselmann
      beparams={
614 1c8addc6 Michael Hanselmann
        constants.PP_DEFAULT: constants.BEC_DEFAULTS,
615 1c8addc6 Michael Hanselmann
        },
616 1c8addc6 Michael Hanselmann
      nicparams={
617 1c8addc6 Michael Hanselmann
        constants.PP_DEFAULT: constants.NICC_DEFAULTS,
618 1c8addc6 Michael Hanselmann
        },
619 1c8addc6 Michael Hanselmann
      os_hvp={},
620 1c8addc6 Michael Hanselmann
      tcpudp_port_pool=set())
621 1c8addc6 Michael Hanselmann
622 1c8addc6 Michael Hanselmann
    offline_nodes = ["nodeoff1", "nodeoff2"]
623 1c8addc6 Michael Hanselmann
    bad_nodes = ["nodebad1", "nodebad2", "nodebad3"] + offline_nodes
624 1c8addc6 Michael Hanselmann
    nodes = ["node%s" % i for i in range(10)] + bad_nodes
625 1c8addc6 Michael Hanselmann
626 1c8addc6 Michael Hanselmann
    instances = [
627 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst1", hvparams={}, beparams={}, nics=[],
628 1c8addc6 Michael Hanselmann
        uuid="f90eccb3-e227-4e3c-bf2a-94a21ca8f9cd",
629 1c8addc6 Michael Hanselmann
        ctime=1291244000, mtime=1291244400, serial_no=30,
630 1c8addc6 Michael Hanselmann
        admin_up=True, hypervisor=constants.HT_XEN_PVM, os="linux1",
631 1c8addc6 Michael Hanselmann
        primary_node="node1",
632 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_PLAIN,
633 1c8addc6 Michael Hanselmann
        disks=[]),
634 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst2", hvparams={}, nics=[],
635 1c8addc6 Michael Hanselmann
        uuid="73a0f8a7-068c-4630-ada2-c3440015ab1a",
636 1c8addc6 Michael Hanselmann
        ctime=1291211000, mtime=1291211077, serial_no=1,
637 1c8addc6 Michael Hanselmann
        admin_up=True, hypervisor=constants.HT_XEN_HVM, os="deb99",
638 1c8addc6 Michael Hanselmann
        primary_node="node5",
639 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DISKLESS,
640 1c8addc6 Michael Hanselmann
        disks=[],
641 1c8addc6 Michael Hanselmann
        beparams={
642 1c8addc6 Michael Hanselmann
          constants.BE_MEMORY: 512,
643 1c8addc6 Michael Hanselmann
        }),
644 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst3", hvparams={}, beparams={},
645 1c8addc6 Michael Hanselmann
        uuid="11ec8dff-fb61-4850-bfe0-baa1803ff280",
646 1c8addc6 Michael Hanselmann
        ctime=1291011000, mtime=1291013000, serial_no=1923,
647 1c8addc6 Michael Hanselmann
        admin_up=False, hypervisor=constants.HT_KVM, os="busybox",
648 1c8addc6 Michael Hanselmann
        primary_node="node6",
649 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DRBD8,
650 1c8addc6 Michael Hanselmann
        disks=[],
651 1c8addc6 Michael Hanselmann
        nics=[
652 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.99", mac=macs.pop(),
653 1c8addc6 Michael Hanselmann
                      nicparams={
654 1c8addc6 Michael Hanselmann
                        constants.NIC_LINK: constants.DEFAULT_BRIDGE,
655 1c8addc6 Michael Hanselmann
                        }),
656 1c8addc6 Michael Hanselmann
          objects.NIC(ip=None, mac=macs.pop(), nicparams={}),
657 1c8addc6 Michael Hanselmann
          ]),
658 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst4", hvparams={}, beparams={},
659 1c8addc6 Michael Hanselmann
        uuid="68dab168-3ef5-4c9d-b4d3-801e0672068c",
660 1c8addc6 Michael Hanselmann
        ctime=1291244390, mtime=1291244395, serial_no=25,
661 1c8addc6 Michael Hanselmann
        admin_up=False, hypervisor=constants.HT_XEN_PVM, os="linux1",
662 1c8addc6 Michael Hanselmann
        primary_node="nodeoff2",
663 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DRBD8,
664 1c8addc6 Michael Hanselmann
        disks=[],
665 1c8addc6 Michael Hanselmann
        nics=[
666 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.1", mac=macs.pop(),
667 1c8addc6 Michael Hanselmann
                      nicparams={
668 1c8addc6 Michael Hanselmann
                        constants.NIC_LINK: constants.DEFAULT_BRIDGE,
669 1c8addc6 Michael Hanselmann
                        }),
670 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.2", mac=macs.pop(), nicparams={}),
671 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.3", mac=macs.pop(),
672 1c8addc6 Michael Hanselmann
                      nicparams={
673 1c8addc6 Michael Hanselmann
                        constants.NIC_MODE: constants.NIC_MODE_ROUTED,
674 1c8addc6 Michael Hanselmann
                        }),
675 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.4", mac=macs.pop(),
676 1c8addc6 Michael Hanselmann
                      nicparams={
677 1c8addc6 Michael Hanselmann
                        constants.NIC_MODE: constants.NIC_MODE_BRIDGED,
678 1c8addc6 Michael Hanselmann
                        constants.NIC_LINK: "eth123",
679 1c8addc6 Michael Hanselmann
                        }),
680 1c8addc6 Michael Hanselmann
          ]),
681 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst5", hvparams={}, nics=[],
682 1c8addc6 Michael Hanselmann
        uuid="0e3dca12-5b42-4e24-98a2-415267545bd0",
683 1c8addc6 Michael Hanselmann
        ctime=1231211000, mtime=1261200000, serial_no=3,
684 1c8addc6 Michael Hanselmann
        admin_up=True, hypervisor=constants.HT_XEN_HVM, os="deb99",
685 1c8addc6 Michael Hanselmann
        primary_node="nodebad2",
686 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DISKLESS,
687 1c8addc6 Michael Hanselmann
        disks=[],
688 1c8addc6 Michael Hanselmann
        beparams={
689 1c8addc6 Michael Hanselmann
          constants.BE_MEMORY: 512,
690 1c8addc6 Michael Hanselmann
        }),
691 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst6", hvparams={}, nics=[],
692 1c8addc6 Michael Hanselmann
        uuid="72de6580-c8d5-4661-b902-38b5785bb8b3",
693 1c8addc6 Michael Hanselmann
        ctime=7513, mtime=11501, serial_no=13390,
694 1c8addc6 Michael Hanselmann
        admin_up=False, hypervisor=constants.HT_XEN_HVM, os="deb99",
695 1c8addc6 Michael Hanselmann
        primary_node="node7",
696 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DISKLESS,
697 1c8addc6 Michael Hanselmann
        disks=[],
698 1c8addc6 Michael Hanselmann
        beparams={
699 1c8addc6 Michael Hanselmann
          constants.BE_MEMORY: 768,
700 1c8addc6 Michael Hanselmann
        }),
701 145bea54 Michael Hanselmann
      objects.Instance(name="inst7", hvparams={}, nics=[],
702 145bea54 Michael Hanselmann
        uuid="ceec5dc4-b729-4f42-ae28-69b3cd24920e",
703 145bea54 Michael Hanselmann
        ctime=None, mtime=None, serial_no=1947,
704 145bea54 Michael Hanselmann
        admin_up=False, hypervisor=constants.HT_XEN_HVM, os="deb99",
705 145bea54 Michael Hanselmann
        primary_node="node6",
706 145bea54 Michael Hanselmann
        disk_template=constants.DT_DISKLESS,
707 145bea54 Michael Hanselmann
        disks=[],
708 145bea54 Michael Hanselmann
        beparams={}),
709 1c8addc6 Michael Hanselmann
      ]
710 1c8addc6 Michael Hanselmann
711 145bea54 Michael Hanselmann
    assert not utils.FindDuplicates(inst.name for inst in instances)
712 145bea54 Michael Hanselmann
713 5d28cb6f Michael Hanselmann
    instbyname = dict((inst.name, inst) for inst in instances)
714 5d28cb6f Michael Hanselmann
715 1c8addc6 Michael Hanselmann
    disk_usage = dict((inst.name,
716 1c8addc6 Michael Hanselmann
                       cmdlib._ComputeDiskSize(inst.disk_template,
717 1c8addc6 Michael Hanselmann
                                               [{"size": disk.size}
718 1c8addc6 Michael Hanselmann
                                                for disk in inst.disks]))
719 1c8addc6 Michael Hanselmann
                      for inst in instances)
720 1c8addc6 Michael Hanselmann
721 1c8addc6 Michael Hanselmann
    inst_bridges = {
722 1c8addc6 Michael Hanselmann
      "inst3": [constants.DEFAULT_BRIDGE, constants.DEFAULT_BRIDGE],
723 1c8addc6 Michael Hanselmann
      "inst4": [constants.DEFAULT_BRIDGE, constants.DEFAULT_BRIDGE,
724 1c8addc6 Michael Hanselmann
                None, "eth123"],
725 1c8addc6 Michael Hanselmann
      }
726 1c8addc6 Michael Hanselmann
727 1c8addc6 Michael Hanselmann
    live_data = {
728 1c8addc6 Michael Hanselmann
      "inst2": {
729 1c8addc6 Michael Hanselmann
        "vcpus": 3,
730 1c8addc6 Michael Hanselmann
        },
731 1c8addc6 Michael Hanselmann
      "inst4": {
732 1c8addc6 Michael Hanselmann
        "memory": 123,
733 1c8addc6 Michael Hanselmann
        },
734 1c8addc6 Michael Hanselmann
      "inst6": {
735 1c8addc6 Michael Hanselmann
        "memory": 768,
736 1c8addc6 Michael Hanselmann
        },
737 bacae536 Renรฉ Nussbaumer
      "inst7": {
738 bacae536 Renรฉ Nussbaumer
        "vcpus": 3,
739 bacae536 Renรฉ Nussbaumer
        },
740 1c8addc6 Michael Hanselmann
      }
741 bacae536 Renรฉ Nussbaumer
    wrongnode_inst = set(["inst7"])
742 1c8addc6 Michael Hanselmann
743 5d28cb6f Michael Hanselmann
    consinfo = dict((inst.name, None) for inst in instances)
744 5d28cb6f Michael Hanselmann
    consinfo["inst7"] = \
745 5d28cb6f Michael Hanselmann
      objects.InstanceConsole(instance="inst7", kind=constants.CONS_SSH,
746 5d28cb6f Michael Hanselmann
                              host=instbyname["inst7"].primary_node,
747 5d28cb6f Michael Hanselmann
                              user=constants.GANETI_RUNAS,
748 5d28cb6f Michael Hanselmann
                              command=["hostname"]).ToDict()
749 5d28cb6f Michael Hanselmann
750 1c8addc6 Michael Hanselmann
    iqd = query.InstanceQueryData(instances, cluster, disk_usage,
751 e431074f Renรฉ Nussbaumer
                                  offline_nodes, bad_nodes, live_data,
752 5d28cb6f Michael Hanselmann
                                  wrongnode_inst, consinfo)
753 1c8addc6 Michael Hanselmann
    result = q.Query(iqd)
754 1c8addc6 Michael Hanselmann
    self.assertEqual(len(result), len(instances))
755 1c8addc6 Michael Hanselmann
    self.assert_(compat.all(len(row) == len(selected)
756 1c8addc6 Michael Hanselmann
                            for row in result))
757 1c8addc6 Michael Hanselmann
758 1c8addc6 Michael Hanselmann
    assert len(set(bad_nodes) & set(offline_nodes)) == len(offline_nodes), \
759 1c8addc6 Michael Hanselmann
           "Offline nodes not included in bad nodes"
760 1c8addc6 Michael Hanselmann
761 1c8addc6 Michael Hanselmann
    tested_status = set()
762 1c8addc6 Michael Hanselmann
763 1c8addc6 Michael Hanselmann
    for (inst, row) in zip(instances, result):
764 1c8addc6 Michael Hanselmann
      assert inst.primary_node in nodes
765 1c8addc6 Michael Hanselmann
766 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["name"]],
767 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, inst.name))
768 1c8addc6 Michael Hanselmann
769 1c8addc6 Michael Hanselmann
      if inst.primary_node in offline_nodes:
770 61a980a9 Michael Hanselmann
        exp_status = constants.INSTST_NODEOFFLINE
771 1c8addc6 Michael Hanselmann
      elif inst.primary_node in bad_nodes:
772 61a980a9 Michael Hanselmann
        exp_status = constants.INSTST_NODEDOWN
773 1c8addc6 Michael Hanselmann
      elif inst.name in live_data:
774 e431074f Renรฉ Nussbaumer
        if inst.name in wrongnode_inst:
775 61a980a9 Michael Hanselmann
          exp_status = constants.INSTST_WRONGNODE
776 e431074f Renรฉ Nussbaumer
        elif inst.admin_up:
777 61a980a9 Michael Hanselmann
          exp_status = constants.INSTST_RUNNING
778 1c8addc6 Michael Hanselmann
        else:
779 61a980a9 Michael Hanselmann
          exp_status = constants.INSTST_ERRORUP
780 1c8addc6 Michael Hanselmann
      elif inst.admin_up:
781 61a980a9 Michael Hanselmann
        exp_status = constants.INSTST_ERRORDOWN
782 1c8addc6 Michael Hanselmann
      else:
783 61a980a9 Michael Hanselmann
        exp_status = constants.INSTST_ADMINDOWN
784 1c8addc6 Michael Hanselmann
785 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["status"]],
786 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, exp_status))
787 1c8addc6 Michael Hanselmann
788 1c8addc6 Michael Hanselmann
      (_, status) = row[fieldidx["status"]]
789 1c8addc6 Michael Hanselmann
      tested_status.add(status)
790 1c8addc6 Michael Hanselmann
791 1c8addc6 Michael Hanselmann
      for (field, livefield) in [("oper_ram", "memory"),
792 1c8addc6 Michael Hanselmann
                                 ("oper_vcpus", "vcpus")]:
793 1c8addc6 Michael Hanselmann
        if inst.primary_node in bad_nodes:
794 cfb084ae Renรฉ Nussbaumer
          exp = (constants.RS_NODATA, None)
795 1c8addc6 Michael Hanselmann
        elif inst.name in live_data:
796 1c8addc6 Michael Hanselmann
          value = live_data[inst.name].get(livefield, None)
797 1c8addc6 Michael Hanselmann
          if value is None:
798 cfb084ae Renรฉ Nussbaumer
            exp = (constants.RS_UNAVAIL, None)
799 1c8addc6 Michael Hanselmann
          else:
800 cfb084ae Renรฉ Nussbaumer
            exp = (constants.RS_NORMAL, value)
801 1c8addc6 Michael Hanselmann
        else:
802 cfb084ae Renรฉ Nussbaumer
          exp = (constants.RS_UNAVAIL, None)
803 1c8addc6 Michael Hanselmann
804 1c8addc6 Michael Hanselmann
        self.assertEqual(row[fieldidx[field]], exp)
805 1c8addc6 Michael Hanselmann
806 1c8addc6 Michael Hanselmann
      bridges = inst_bridges.get(inst.name, [])
807 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["nic.bridges"]],
808 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, bridges))
809 1c8addc6 Michael Hanselmann
      if bridges:
810 1c8addc6 Michael Hanselmann
        self.assertEqual(row[fieldidx["bridge"]],
811 cfb084ae Renรฉ Nussbaumer
                         (constants.RS_NORMAL, bridges[0]))
812 1c8addc6 Michael Hanselmann
      else:
813 1c8addc6 Michael Hanselmann
        self.assertEqual(row[fieldidx["bridge"]],
814 cfb084ae Renรฉ Nussbaumer
                         (constants.RS_UNAVAIL, None))
815 1c8addc6 Michael Hanselmann
816 1c8addc6 Michael Hanselmann
      for i in range(constants.MAX_NICS):
817 1c8addc6 Michael Hanselmann
        if i < len(bridges) and bridges[i] is not None:
818 cfb084ae Renรฉ Nussbaumer
          exp = (constants.RS_NORMAL, bridges[i])
819 1c8addc6 Michael Hanselmann
        else:
820 cfb084ae Renรฉ Nussbaumer
          exp = (constants.RS_UNAVAIL, None)
821 1c8addc6 Michael Hanselmann
        self.assertEqual(row[fieldidx["nic.bridge/%s" % i]], exp)
822 1c8addc6 Michael Hanselmann
823 1c8addc6 Michael Hanselmann
      if inst.primary_node in bad_nodes:
824 cfb084ae Renรฉ Nussbaumer
        exp = (constants.RS_NODATA, None)
825 1c8addc6 Michael Hanselmann
      else:
826 cfb084ae Renรฉ Nussbaumer
        exp = (constants.RS_NORMAL, inst.name in live_data)
827 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["oper_state"]], exp)
828 1c8addc6 Michael Hanselmann
829 1c8addc6 Michael Hanselmann
      usage = disk_usage[inst.name]
830 1c8addc6 Michael Hanselmann
      if usage is None:
831 1c8addc6 Michael Hanselmann
        usage = 0
832 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["disk_usage"]],
833 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, usage))
834 1c8addc6 Michael Hanselmann
835 4cc4d1fa Michael Hanselmann
      for alias, target in [("sda_size", "disk.size/0"),
836 4cc4d1fa Michael Hanselmann
                            ("sdb_size", "disk.size/1"),
837 4cc4d1fa Michael Hanselmann
                            ("vcpus", "be/vcpus"),
838 4cc4d1fa Michael Hanselmann
                            ("ip", "nic.ip/0"),
839 4cc4d1fa Michael Hanselmann
                            ("mac", "nic.mac/0"),
840 4cc4d1fa Michael Hanselmann
                            ("bridge", "nic.bridge/0"),
841 4cc4d1fa Michael Hanselmann
                            ("nic_mode", "nic.mode/0"),
842 4cc4d1fa Michael Hanselmann
                            ("nic_link", "nic.link/0"),
843 4cc4d1fa Michael Hanselmann
                            ]:
844 4cc4d1fa Michael Hanselmann
        self.assertEqual(row[fieldidx[alias]], row[fieldidx[target]])
845 1c8addc6 Michael Hanselmann
846 145bea54 Michael Hanselmann
      for field in ["ctime", "mtime"]:
847 145bea54 Michael Hanselmann
        if getattr(inst, field) is None:
848 145bea54 Michael Hanselmann
          # No ctime/mtime
849 cfb084ae Renรฉ Nussbaumer
          exp = (constants.RS_UNAVAIL, None)
850 145bea54 Michael Hanselmann
        else:
851 cfb084ae Renรฉ Nussbaumer
          exp = (constants.RS_NORMAL, getattr(inst, field))
852 145bea54 Michael Hanselmann
        self.assertEqual(row[fieldidx[field]], exp)
853 145bea54 Michael Hanselmann
854 5d28cb6f Michael Hanselmann
      self._CheckInstanceConsole(inst, row[fieldidx["console"]])
855 5d28cb6f Michael Hanselmann
856 1c8addc6 Michael Hanselmann
    # Ensure all possible status' have been tested
857 61a980a9 Michael Hanselmann
    self.assertEqual(tested_status, constants.INSTST_ALL)
858 1c8addc6 Michael Hanselmann
859 5d28cb6f Michael Hanselmann
  def _CheckInstanceConsole(self, instance, (status, consdata)):
860 5d28cb6f Michael Hanselmann
    if instance.name == "inst7":
861 5d28cb6f Michael Hanselmann
      self.assertEqual(status, constants.RS_NORMAL)
862 5d28cb6f Michael Hanselmann
      console = objects.InstanceConsole.FromDict(consdata)
863 5d28cb6f Michael Hanselmann
      self.assertTrue(console.Validate())
864 5d28cb6f Michael Hanselmann
      self.assertEqual(console.host, instance.primary_node)
865 5d28cb6f Michael Hanselmann
    else:
866 5d28cb6f Michael Hanselmann
      self.assertEqual(status, constants.RS_UNAVAIL)
867 5d28cb6f Michael Hanselmann
868 1c8addc6 Michael Hanselmann
869 d8b7ff5f Adeodato Simo
class TestGroupQuery(unittest.TestCase):
870 d8b7ff5f Adeodato Simo
871 d8b7ff5f Adeodato Simo
  def setUp(self):
872 d8b7ff5f Adeodato Simo
    self.groups = [
873 d8b7ff5f Adeodato Simo
      objects.NodeGroup(name="default",
874 d8b7ff5f Adeodato Simo
                        uuid="c0e89160-18e7-11e0-a46e-001d0904baeb",
875 d8b7ff5f Adeodato Simo
                        alloc_policy=constants.ALLOC_POLICY_PREFERRED),
876 d8b7ff5f Adeodato Simo
      objects.NodeGroup(name="restricted",
877 d8b7ff5f Adeodato Simo
                        uuid="d2a40a74-18e7-11e0-9143-001d0904baeb",
878 d8b7ff5f Adeodato Simo
                        alloc_policy=constants.ALLOC_POLICY_LAST_RESORT),
879 d8b7ff5f Adeodato Simo
      ]
880 d8b7ff5f Adeodato Simo
881 d8b7ff5f Adeodato Simo
  def _Create(self, selected):
882 d8b7ff5f Adeodato Simo
    return query.Query(query.GROUP_FIELDS, selected)
883 d8b7ff5f Adeodato Simo
884 d8b7ff5f Adeodato Simo
  def testSimple(self):
885 d8b7ff5f Adeodato Simo
    q = self._Create(["name", "uuid", "alloc_policy"])
886 d8b7ff5f Adeodato Simo
    gqd = query.GroupQueryData(self.groups, None, None)
887 d8b7ff5f Adeodato Simo
888 d8b7ff5f Adeodato Simo
    self.assertEqual(q.RequestedData(), set([query.GQ_CONFIG]))
889 d8b7ff5f Adeodato Simo
890 d8b7ff5f Adeodato Simo
    self.assertEqual(q.Query(gqd),
891 cfb084ae Renรฉ Nussbaumer
      [[(constants.RS_NORMAL, "default"),
892 cfb084ae Renรฉ Nussbaumer
        (constants.RS_NORMAL, "c0e89160-18e7-11e0-a46e-001d0904baeb"),
893 cfb084ae Renรฉ Nussbaumer
        (constants.RS_NORMAL, constants.ALLOC_POLICY_PREFERRED)
894 d8b7ff5f Adeodato Simo
        ],
895 cfb084ae Renรฉ Nussbaumer
       [(constants.RS_NORMAL, "restricted"),
896 cfb084ae Renรฉ Nussbaumer
        (constants.RS_NORMAL, "d2a40a74-18e7-11e0-9143-001d0904baeb"),
897 cfb084ae Renรฉ Nussbaumer
        (constants.RS_NORMAL, constants.ALLOC_POLICY_LAST_RESORT)
898 d8b7ff5f Adeodato Simo
        ],
899 d8b7ff5f Adeodato Simo
       ])
900 d8b7ff5f Adeodato Simo
901 d8b7ff5f Adeodato Simo
  def testNodes(self):
902 d8b7ff5f Adeodato Simo
    groups_to_nodes = {
903 d8b7ff5f Adeodato Simo
      "c0e89160-18e7-11e0-a46e-001d0904baeb": ["node1", "node2"],
904 d8b7ff5f Adeodato Simo
      "d2a40a74-18e7-11e0-9143-001d0904baeb": ["node1", "node10", "node9"],
905 d8b7ff5f Adeodato Simo
      }
906 d8b7ff5f Adeodato Simo
907 d8b7ff5f Adeodato Simo
    q = self._Create(["name", "node_cnt", "node_list"])
908 d8b7ff5f Adeodato Simo
    gqd = query.GroupQueryData(self.groups, groups_to_nodes, None)
909 d8b7ff5f Adeodato Simo
910 d8b7ff5f Adeodato Simo
    self.assertEqual(q.RequestedData(), set([query.GQ_CONFIG, query.GQ_NODE]))
911 d8b7ff5f Adeodato Simo
912 d8b7ff5f Adeodato Simo
    self.assertEqual(q.Query(gqd),
913 cfb084ae Renรฉ Nussbaumer
                     [[(constants.RS_NORMAL, "default"),
914 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, 2),
915 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, ["node1", "node2"]),
916 d8b7ff5f Adeodato Simo
                       ],
917 cfb084ae Renรฉ Nussbaumer
                      [(constants.RS_NORMAL, "restricted"),
918 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, 3),
919 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, ["node1", "node9", "node10"]),
920 d8b7ff5f Adeodato Simo
                       ],
921 d8b7ff5f Adeodato Simo
                      ])
922 d8b7ff5f Adeodato Simo
923 d8b7ff5f Adeodato Simo
  def testInstances(self):
924 d8b7ff5f Adeodato Simo
    groups_to_instances = {
925 d8b7ff5f Adeodato Simo
      "c0e89160-18e7-11e0-a46e-001d0904baeb": ["inst1", "inst2"],
926 d8b7ff5f Adeodato Simo
      "d2a40a74-18e7-11e0-9143-001d0904baeb": ["inst1", "inst10", "inst9"],
927 d8b7ff5f Adeodato Simo
      }
928 d8b7ff5f Adeodato Simo
929 d8b7ff5f Adeodato Simo
    q = self._Create(["pinst_cnt", "pinst_list"])
930 d8b7ff5f Adeodato Simo
    gqd = query.GroupQueryData(self.groups, None, groups_to_instances)
931 d8b7ff5f Adeodato Simo
932 d8b7ff5f Adeodato Simo
    self.assertEqual(q.RequestedData(), set([query.GQ_INST]))
933 d8b7ff5f Adeodato Simo
934 d8b7ff5f Adeodato Simo
    self.assertEqual(q.Query(gqd),
935 cfb084ae Renรฉ Nussbaumer
                     [[(constants.RS_NORMAL, 2),
936 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, ["inst1", "inst2"]),
937 d8b7ff5f Adeodato Simo
                       ],
938 cfb084ae Renรฉ Nussbaumer
                      [(constants.RS_NORMAL, 3),
939 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, ["inst1", "inst9", "inst10"]),
940 d8b7ff5f Adeodato Simo
                       ],
941 d8b7ff5f Adeodato Simo
                      ])
942 d8b7ff5f Adeodato Simo
943 d8b7ff5f Adeodato Simo
944 aa29e95f Michael Hanselmann
class TestQueryFields(unittest.TestCase):
945 aa29e95f Michael Hanselmann
  def testAllFields(self):
946 e571ee44 Adeodato Simo
    for fielddefs in query.ALL_FIELD_LISTS:
947 aa29e95f Michael Hanselmann
      result = query.QueryFields(fielddefs, None)
948 aa29e95f Michael Hanselmann
      self.assert_(isinstance(result, dict))
949 aa29e95f Michael Hanselmann
      response = objects.QueryFieldsResponse.FromDict(result)
950 aa29e95f Michael Hanselmann
      self.assertEqual([(fdef.name, fdef.title) for fdef in response.fields],
951 aa29e95f Michael Hanselmann
        [(fdef2.name, fdef2.title)
952 111bf531 Michael Hanselmann
         for (fdef2, _, _, _) in utils.NiceSort(fielddefs.values(),
953 111bf531 Michael Hanselmann
                                                key=lambda x: x[0].name)])
954 aa29e95f Michael Hanselmann
955 aa29e95f Michael Hanselmann
  def testSomeFields(self):
956 aa29e95f Michael Hanselmann
    rnd = random.Random(5357)
957 aa29e95f Michael Hanselmann
958 aa29e95f Michael Hanselmann
    for _ in range(10):
959 e571ee44 Adeodato Simo
      for fielddefs in query.ALL_FIELD_LISTS:
960 e571ee44 Adeodato Simo
        if len(fielddefs) > 20:
961 e571ee44 Adeodato Simo
          sample_size = rnd.randint(5, 20)
962 e571ee44 Adeodato Simo
        else:
963 e571ee44 Adeodato Simo
          sample_size = rnd.randint(1, max(1, len(fielddefs) - 1))
964 111bf531 Michael Hanselmann
        fields = [fdef for (fdef, _, _, _) in rnd.sample(fielddefs.values(),
965 111bf531 Michael Hanselmann
                                                         sample_size)]
966 aa29e95f Michael Hanselmann
        result = query.QueryFields(fielddefs, [fdef.name for fdef in fields])
967 aa29e95f Michael Hanselmann
        self.assert_(isinstance(result, dict))
968 aa29e95f Michael Hanselmann
        response = objects.QueryFieldsResponse.FromDict(result)
969 aa29e95f Michael Hanselmann
        self.assertEqual([(fdef.name, fdef.title) for fdef in response.fields],
970 aa29e95f Michael Hanselmann
                         [(fdef2.name, fdef2.title) for fdef2 in fields])
971 aa29e95f Michael Hanselmann
972 aa29e95f Michael Hanselmann
973 fb0be379 Michael Hanselmann
class TestQueryFilter(unittest.TestCase):
974 fb0be379 Michael Hanselmann
  def testRequestedNames(self):
975 fb0be379 Michael Hanselmann
    innerfilter = [["=", "name", "x%s" % i] for i in range(4)]
976 fb0be379 Michael Hanselmann
977 fb0be379 Michael Hanselmann
    for fielddefs in query.ALL_FIELD_LISTS:
978 fb0be379 Michael Hanselmann
      assert "name" in fielddefs
979 fb0be379 Michael Hanselmann
980 fb0be379 Michael Hanselmann
      # No name field
981 fb0be379 Michael Hanselmann
      q = query.Query(fielddefs, ["name"], filter_=["=", "name", "abc"],
982 fb0be379 Michael Hanselmann
                      namefield=None)
983 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), None)
984 fb0be379 Michael Hanselmann
985 fb0be379 Michael Hanselmann
      # No filter
986 fb0be379 Michael Hanselmann
      q = query.Query(fielddefs, ["name"], filter_=None, namefield="name")
987 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), None)
988 fb0be379 Michael Hanselmann
989 fb0be379 Michael Hanselmann
      # Check empty query
990 fb0be379 Michael Hanselmann
      q = query.Query(fielddefs, ["name"], filter_=["|"], namefield="name")
991 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), None)
992 fb0be379 Michael Hanselmann
993 fb0be379 Michael Hanselmann
      # Check order
994 fb0be379 Michael Hanselmann
      q = query.Query(fielddefs, ["name"], filter_=["|"] + innerfilter,
995 fb0be379 Michael Hanselmann
                      namefield="name")
996 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), ["x0", "x1", "x2", "x3"])
997 fb0be379 Michael Hanselmann
998 fb0be379 Michael Hanselmann
      # Check reverse order
999 fb0be379 Michael Hanselmann
      q = query.Query(fielddefs, ["name"],
1000 fb0be379 Michael Hanselmann
                      filter_=["|"] + list(reversed(innerfilter)),
1001 fb0be379 Michael Hanselmann
                      namefield="name")
1002 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), ["x3", "x2", "x1", "x0"])
1003 fb0be379 Michael Hanselmann
1004 fb0be379 Michael Hanselmann
      # Duplicates
1005 fb0be379 Michael Hanselmann
      q = query.Query(fielddefs, ["name"],
1006 fb0be379 Michael Hanselmann
                      filter_=["|"] + innerfilter + list(reversed(innerfilter)),
1007 fb0be379 Michael Hanselmann
                      namefield="name")
1008 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), ["x0", "x1", "x2", "x3"])
1009 fb0be379 Michael Hanselmann
1010 fb0be379 Michael Hanselmann
      # Unknown name field
1011 fb0be379 Michael Hanselmann
      self.assertRaises(AssertionError, query.Query, fielddefs, ["name"],
1012 fb0be379 Michael Hanselmann
                        namefield="_unknown_field_")
1013 fb0be379 Michael Hanselmann
1014 fb0be379 Michael Hanselmann
      # Filter with AND
1015 fb0be379 Michael Hanselmann
      q = query.Query(fielddefs, ["name"],
1016 fb0be379 Michael Hanselmann
                      filter_=["|", ["=", "name", "foo"],
1017 fb0be379 Michael Hanselmann
                                    ["&", ["=", "name", ""]]],
1018 fb0be379 Michael Hanselmann
                      namefield="name")
1019 fb0be379 Michael Hanselmann
      self.assertTrue(q.RequestedNames() is None)
1020 fb0be379 Michael Hanselmann
1021 fb0be379 Michael Hanselmann
      # Filter with NOT
1022 fb0be379 Michael Hanselmann
      q = query.Query(fielddefs, ["name"],
1023 fb0be379 Michael Hanselmann
                      filter_=["|", ["=", "name", "foo"],
1024 fb0be379 Michael Hanselmann
                                    ["!", ["=", "name", ""]]],
1025 fb0be379 Michael Hanselmann
                      namefield="name")
1026 fb0be379 Michael Hanselmann
      self.assertTrue(q.RequestedNames() is None)
1027 fb0be379 Michael Hanselmann
1028 fb0be379 Michael Hanselmann
      # Filter with only OR (names must be in correct order)
1029 fb0be379 Michael Hanselmann
      q = query.Query(fielddefs, ["name"],
1030 fb0be379 Michael Hanselmann
                      filter_=["|", ["=", "name", "x17361"],
1031 fb0be379 Michael Hanselmann
                                    ["|", ["=", "name", "x22015"]],
1032 fb0be379 Michael Hanselmann
                                    ["|", ["|", ["=", "name", "x13193"]]],
1033 fb0be379 Michael Hanselmann
                                    ["=", "name", "x15215"]],
1034 fb0be379 Michael Hanselmann
                      namefield="name")
1035 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(),
1036 fb0be379 Michael Hanselmann
                       ["x17361", "x22015", "x13193", "x15215"])
1037 fb0be379 Michael Hanselmann
1038 fb0be379 Michael Hanselmann
  @staticmethod
1039 fb0be379 Michael Hanselmann
  def _GenNestedFilter(op, depth):
1040 fb0be379 Michael Hanselmann
    nested = ["=", "name", "value"]
1041 fb0be379 Michael Hanselmann
    for i in range(depth):
1042 fb0be379 Michael Hanselmann
      nested = [op, nested]
1043 fb0be379 Michael Hanselmann
    return nested
1044 fb0be379 Michael Hanselmann
1045 fb0be379 Michael Hanselmann
  def testCompileFilter(self):
1046 fb0be379 Michael Hanselmann
    levels_max = query._FilterCompilerHelper._LEVELS_MAX
1047 fb0be379 Michael Hanselmann
1048 fb0be379 Michael Hanselmann
    checks = [
1049 fb0be379 Michael Hanselmann
      [], ["="], ["=", "foo"], ["unknownop"], ["!"],
1050 fb0be379 Michael Hanselmann
      ["=", "_unknown_field", "value"],
1051 fb0be379 Michael Hanselmann
      self._GenNestedFilter("|", levels_max),
1052 fb0be379 Michael Hanselmann
      self._GenNestedFilter("|", levels_max * 3),
1053 fb0be379 Michael Hanselmann
      self._GenNestedFilter("!", levels_max),
1054 fb0be379 Michael Hanselmann
      ]
1055 fb0be379 Michael Hanselmann
1056 fb0be379 Michael Hanselmann
    for fielddefs in query.ALL_FIELD_LISTS:
1057 fb0be379 Michael Hanselmann
      for filter_ in checks:
1058 fb0be379 Michael Hanselmann
        self.assertRaises(errors.ParameterError, query._CompileFilter,
1059 fb0be379 Michael Hanselmann
                          fielddefs, None, filter_)
1060 fb0be379 Michael Hanselmann
1061 fb0be379 Michael Hanselmann
      for op in ["|", "!"]:
1062 fb0be379 Michael Hanselmann
        filter_ = self._GenNestedFilter(op, levels_max - 1)
1063 fb0be379 Michael Hanselmann
        self.assertTrue(callable(query._CompileFilter(fielddefs, None,
1064 fb0be379 Michael Hanselmann
                                                      filter_)))
1065 fb0be379 Michael Hanselmann
1066 fb0be379 Michael Hanselmann
  def testQueryInputOrder(self):
1067 fb0be379 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1068 fb0be379 Michael Hanselmann
      (query._MakeField("pnode", "PNode", constants.QFT_TEXT, "Primary"),
1069 fb0be379 Michael Hanselmann
       None, 0, lambda ctx, item: item["pnode"]),
1070 fb0be379 Michael Hanselmann
      (query._MakeField("snode", "SNode", constants.QFT_TEXT, "Secondary"),
1071 fb0be379 Michael Hanselmann
       None, 0, lambda ctx, item: item["snode"]),
1072 fb0be379 Michael Hanselmann
      ], [])
1073 fb0be379 Michael Hanselmann
1074 fb0be379 Michael Hanselmann
    data = [
1075 fb0be379 Michael Hanselmann
      { "pnode": "node1", "snode": "node44", },
1076 fb0be379 Michael Hanselmann
      { "pnode": "node30", "snode": "node90", },
1077 fb0be379 Michael Hanselmann
      { "pnode": "node25", "snode": "node1", },
1078 fb0be379 Michael Hanselmann
      { "pnode": "node20", "snode": "node1", },
1079 fb0be379 Michael Hanselmann
      ]
1080 fb0be379 Michael Hanselmann
1081 fb0be379 Michael Hanselmann
    filter_ = ["|", ["=", "pnode", "node1"], ["=", "snode", "node1"]]
1082 fb0be379 Michael Hanselmann
1083 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "snode"], namefield="pnode",
1084 fb0be379 Michael Hanselmann
                    filter_=filter_)
1085 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1086 fb0be379 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1087 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1088 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")],
1089 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")],
1090 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")]])
1091 fb0be379 Michael Hanselmann
1092 fb0be379 Michael Hanselmann
    # Try again with reversed input data
1093 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(reversed(data)),
1094 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")],
1095 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")],
1096 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")]])
1097 fb0be379 Michael Hanselmann
1098 fb0be379 Michael Hanselmann
    # No name field, result must be in incoming order
1099 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "snode"], namefield=None,
1100 fb0be379 Michael Hanselmann
                    filter_=filter_)
1101 fb0be379 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1102 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1103 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")],
1104 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")],
1105 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")]])
1106 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1107 fb0be379 Michael Hanselmann
      ["node1", "node44"],
1108 fb0be379 Michael Hanselmann
      ["node25", "node1"],
1109 fb0be379 Michael Hanselmann
      ["node20", "node1"],
1110 fb0be379 Michael Hanselmann
      ])
1111 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(reversed(data)),
1112 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")],
1113 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")],
1114 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")]])
1115 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(reversed(data)), [
1116 fb0be379 Michael Hanselmann
      ["node20", "node1"],
1117 fb0be379 Michael Hanselmann
      ["node25", "node1"],
1118 fb0be379 Michael Hanselmann
      ["node1", "node44"],
1119 fb0be379 Michael Hanselmann
      ])
1120 fb0be379 Michael Hanselmann
1121 fbc263a9 Michael Hanselmann
    # Name field, but no sorting, result must be in incoming order
1122 fbc263a9 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "snode"], namefield="pnode")
1123 fbc263a9 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1124 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data, sort_by_name=False),
1125 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")],
1126 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node30"), (constants.RS_NORMAL, "node90")],
1127 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")],
1128 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")]])
1129 fbc263a9 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data, sort_by_name=False), [
1130 fbc263a9 Michael Hanselmann
      ["node1", "node44"],
1131 fbc263a9 Michael Hanselmann
      ["node30", "node90"],
1132 fbc263a9 Michael Hanselmann
      ["node25", "node1"],
1133 fbc263a9 Michael Hanselmann
      ["node20", "node1"],
1134 fbc263a9 Michael Hanselmann
      ])
1135 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(reversed(data), sort_by_name=False),
1136 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")],
1137 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")],
1138 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node30"), (constants.RS_NORMAL, "node90")],
1139 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")]])
1140 fbc263a9 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(reversed(data), sort_by_name=False), [
1141 fbc263a9 Michael Hanselmann
      ["node20", "node1"],
1142 fbc263a9 Michael Hanselmann
      ["node25", "node1"],
1143 fbc263a9 Michael Hanselmann
      ["node30", "node90"],
1144 fbc263a9 Michael Hanselmann
      ["node1", "node44"],
1145 fbc263a9 Michael Hanselmann
      ])
1146 fbc263a9 Michael Hanselmann
1147 fbc263a9 Michael Hanselmann
  def testEqualNamesOrder(self):
1148 fbc263a9 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1149 fbc263a9 Michael Hanselmann
      (query._MakeField("pnode", "PNode", constants.QFT_TEXT, "Primary"),
1150 fbc263a9 Michael Hanselmann
       None, 0, lambda ctx, item: item["pnode"]),
1151 fbc263a9 Michael Hanselmann
      (query._MakeField("num", "Num", constants.QFT_NUMBER, "Num"),
1152 fbc263a9 Michael Hanselmann
       None, 0, lambda ctx, item: item["num"]),
1153 fbc263a9 Michael Hanselmann
      ], [])
1154 fbc263a9 Michael Hanselmann
1155 fbc263a9 Michael Hanselmann
    data = [
1156 fbc263a9 Michael Hanselmann
      { "pnode": "node1", "num": 100, },
1157 fbc263a9 Michael Hanselmann
      { "pnode": "node1", "num": 25, },
1158 fbc263a9 Michael Hanselmann
      { "pnode": "node2", "num": 90, },
1159 fbc263a9 Michael Hanselmann
      { "pnode": "node2", "num": 30, },
1160 fbc263a9 Michael Hanselmann
      ]
1161 fbc263a9 Michael Hanselmann
1162 fbc263a9 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "num"], namefield="pnode",
1163 fbc263a9 Michael Hanselmann
                    filter_=["|", ["=", "pnode", "node1"],
1164 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "node2"],
1165 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "node1"]])
1166 fbc263a9 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1", "node2"],
1167 fbc263a9 Michael Hanselmann
                     msg="Did not return unique names")
1168 fbc263a9 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1169 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data),
1170 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, 100)],
1171 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, 25)],
1172 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, 90)],
1173 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, 30)]])
1174 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data, sort_by_name=False),
1175 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, 100)],
1176 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, 25)],
1177 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, 90)],
1178 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, 30)]])
1179 fbc263a9 Michael Hanselmann
1180 fbc263a9 Michael Hanselmann
    data = [
1181 fbc263a9 Michael Hanselmann
      { "pnode": "nodeX", "num": 50, },
1182 fbc263a9 Michael Hanselmann
      { "pnode": "nodeY", "num": 40, },
1183 fbc263a9 Michael Hanselmann
      { "pnode": "nodeX", "num": 30, },
1184 fbc263a9 Michael Hanselmann
      { "pnode": "nodeX", "num": 20, },
1185 fbc263a9 Michael Hanselmann
      { "pnode": "nodeM", "num": 10, },
1186 fbc263a9 Michael Hanselmann
      ]
1187 fbc263a9 Michael Hanselmann
1188 fbc263a9 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "num"], namefield="pnode",
1189 fbc263a9 Michael Hanselmann
                    filter_=["|", ["=", "pnode", "nodeX"],
1190 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "nodeY"],
1191 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "nodeY"],
1192 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "nodeY"],
1193 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "nodeM"]])
1194 fbc263a9 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["nodeX", "nodeY", "nodeM"],
1195 fbc263a9 Michael Hanselmann
                     msg="Did not return unique names")
1196 fbc263a9 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1197 fbc263a9 Michael Hanselmann
1198 fbc263a9 Michael Hanselmann
    # First sorted by name, then input order
1199 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data, sort_by_name=True),
1200 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "nodeM"), (constants.RS_NORMAL, 10)],
1201 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 50)],
1202 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 30)],
1203 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 20)],
1204 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeY"), (constants.RS_NORMAL, 40)]])
1205 fbc263a9 Michael Hanselmann
1206 fbc263a9 Michael Hanselmann
    # Input order
1207 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data, sort_by_name=False),
1208 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 50)],
1209 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeY"), (constants.RS_NORMAL, 40)],
1210 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 30)],
1211 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 20)],
1212 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeM"), (constants.RS_NORMAL, 10)]])
1213 fbc263a9 Michael Hanselmann
1214 fb0be379 Michael Hanselmann
  def testFilter(self):
1215 fb0be379 Michael Hanselmann
    (DK_A, DK_B) = range(1000, 1002)
1216 fb0be379 Michael Hanselmann
1217 fb0be379 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1218 fb0be379 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1219 fb0be379 Michael Hanselmann
       DK_A, 0, lambda ctx, item: item["name"]),
1220 fb0be379 Michael Hanselmann
      (query._MakeField("other", "Other", constants.QFT_TEXT, "Other"),
1221 fb0be379 Michael Hanselmann
       DK_B, 0, lambda ctx, item: item["other"]),
1222 fb0be379 Michael Hanselmann
      ], [])
1223 fb0be379 Michael Hanselmann
1224 fb0be379 Michael Hanselmann
    data = [
1225 fb0be379 Michael Hanselmann
      { "name": "node1", "other": "foo", },
1226 fb0be379 Michael Hanselmann
      { "name": "node2", "other": "bar", },
1227 fb0be379 Michael Hanselmann
      { "name": "node3", "other": "Hello", },
1228 fb0be379 Michael Hanselmann
      ]
1229 fb0be379 Michael Hanselmann
1230 fb0be379 Michael Hanselmann
    # Empty filter
1231 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1232 fb0be379 Michael Hanselmann
                    filter_=["|"])
1233 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1234 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_A, DK_B]))
1235 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [])
1236 fb0be379 Michael Hanselmann
1237 fb0be379 Michael Hanselmann
    # Normal filter
1238 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1239 fb0be379 Michael Hanselmann
                    filter_=["=", "name", "node1"])
1240 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1"])
1241 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1242 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "foo")]])
1243 fb0be379 Michael Hanselmann
1244 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1245 fb0be379 Michael Hanselmann
                    filter_=(["|", ["=", "name", "node1"],
1246 fb0be379 Michael Hanselmann
                                   ["=", "name", "node3"]]))
1247 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1", "node3"])
1248 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1249 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "foo")],
1250 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, "Hello")]])
1251 fb0be379 Michael Hanselmann
1252 fb0be379 Michael Hanselmann
    # Complex filter
1253 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1254 fb0be379 Michael Hanselmann
                    filter_=(["|", ["=", "name", "node1"],
1255 fb0be379 Michael Hanselmann
                                   ["|", ["=", "name", "node3"],
1256 fb0be379 Michael Hanselmann
                                         ["=", "name", "node2"]],
1257 fb0be379 Michael Hanselmann
                                   ["=", "name", "node3"]]))
1258 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1", "node3", "node2"])
1259 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_A, DK_B]))
1260 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1261 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "foo")],
1262 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, "bar")],
1263 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, "Hello")]])
1264 fb0be379 Michael Hanselmann
1265 fb0be379 Michael Hanselmann
    # Filter data type mismatch
1266 fb0be379 Michael Hanselmann
    for i in [-1, 0, 1, 123, [], None, True, False]:
1267 fb0be379 Michael Hanselmann
      self.assertRaises(errors.ParameterError, query.Query,
1268 fb0be379 Michael Hanselmann
                        fielddefs, ["name", "other"], namefield="name",
1269 fb0be379 Michael Hanselmann
                        filter_=["=", "name", i])
1270 fb0be379 Michael Hanselmann
1271 fb0be379 Michael Hanselmann
    # Negative filter
1272 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1273 fb0be379 Michael Hanselmann
                    filter_=["!", ["|", ["=", "name", "node1"],
1274 fb0be379 Michael Hanselmann
                                        ["=", "name", "node3"]]])
1275 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1276 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1277 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, "bar")]])
1278 fb0be379 Michael Hanselmann
1279 fb0be379 Michael Hanselmann
    # Not equal
1280 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1281 fb0be379 Michael Hanselmann
                    filter_=["!=", "name", "node3"])
1282 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1283 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1284 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "foo")],
1285 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, "bar")]])
1286 fb0be379 Michael Hanselmann
1287 fb0be379 Michael Hanselmann
    # Data type
1288 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, [], namefield="name",
1289 fb0be379 Michael Hanselmann
                    filter_=["|", ["=", "other", "bar"],
1290 fb0be379 Michael Hanselmann
                                  ["=", "name", "foo"]])
1291 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1292 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_A, DK_B]))
1293 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [[]])
1294 fb0be379 Michael Hanselmann
1295 fb0be379 Michael Hanselmann
    # Only one data type
1296 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["other"], namefield="name",
1297 fb0be379 Michael Hanselmann
                    filter_=["=", "other", "bar"])
1298 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1299 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_B]))
1300 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [[(constants.RS_NORMAL, "bar")]])
1301 fb0be379 Michael Hanselmann
1302 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, [], namefield="name",
1303 fb0be379 Michael Hanselmann
                    filter_=["=", "other", "bar"])
1304 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1305 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_B]))
1306 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [[]])
1307 fb0be379 Michael Hanselmann
1308 fb0be379 Michael Hanselmann
  def testFilterContains(self):
1309 fb0be379 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1310 fb0be379 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1311 fb0be379 Michael Hanselmann
       None, 0, lambda ctx, item: item["name"]),
1312 fb0be379 Michael Hanselmann
      (query._MakeField("other", "Other", constants.QFT_OTHER, "Other"),
1313 fb0be379 Michael Hanselmann
       None, 0, lambda ctx, item: item["other"]),
1314 fb0be379 Michael Hanselmann
      ], [])
1315 fb0be379 Michael Hanselmann
1316 fb0be379 Michael Hanselmann
    data = [
1317 fb0be379 Michael Hanselmann
      { "name": "node2", "other": ["x", "y", "bar"], },
1318 fb0be379 Michael Hanselmann
      { "name": "node3", "other": "Hello", },
1319 fb0be379 Michael Hanselmann
      { "name": "node1", "other": ["a", "b", "foo"], },
1320 3b877f08 Michael Hanselmann
      { "name": "empty", "other": []},
1321 fb0be379 Michael Hanselmann
      ]
1322 fb0be379 Michael Hanselmann
1323 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1324 fb0be379 Michael Hanselmann
                    filter_=["=[]", "other", "bar"])
1325 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1326 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1327 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"),
1328 fb0be379 Michael Hanselmann
       (constants.RS_NORMAL, ["x", "y", "bar"])],
1329 fb0be379 Michael Hanselmann
      ])
1330 fb0be379 Michael Hanselmann
1331 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1332 fb0be379 Michael Hanselmann
                    filter_=["|", ["=[]", "other", "bar"],
1333 fb0be379 Michael Hanselmann
                                  ["=[]", "other", "a"],
1334 fb0be379 Michael Hanselmann
                                  ["=[]", "other", "b"]])
1335 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1336 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1337 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"),
1338 fb0be379 Michael Hanselmann
       (constants.RS_NORMAL, ["a", "b", "foo"])],
1339 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"),
1340 fb0be379 Michael Hanselmann
       (constants.RS_NORMAL, ["x", "y", "bar"])],
1341 fb0be379 Michael Hanselmann
      ])
1342 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1343 fb0be379 Michael Hanselmann
      ["node1", ["a", "b", "foo"]],
1344 fb0be379 Michael Hanselmann
      ["node2", ["x", "y", "bar"]],
1345 fb0be379 Michael Hanselmann
      ])
1346 fb0be379 Michael Hanselmann
1347 3b877f08 Michael Hanselmann
    # Boolean test
1348 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1349 3b877f08 Michael Hanselmann
                    filter_=["?", "other"])
1350 3b877f08 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1351 3b877f08 Michael Hanselmann
      ["node1", ["a", "b", "foo"]],
1352 3b877f08 Michael Hanselmann
      ["node2", ["x", "y", "bar"]],
1353 3b877f08 Michael Hanselmann
      ["node3", "Hello"],
1354 3b877f08 Michael Hanselmann
      ])
1355 3b877f08 Michael Hanselmann
1356 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1357 3b877f08 Michael Hanselmann
                    filter_=["!", ["?", "other"]])
1358 3b877f08 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1359 3b877f08 Michael Hanselmann
      ["empty", []],
1360 3b877f08 Michael Hanselmann
      ])
1361 3b877f08 Michael Hanselmann
1362 fb0be379 Michael Hanselmann
  def testFilterHostname(self):
1363 fb0be379 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1364 fb0be379 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1365 fb0be379 Michael Hanselmann
       None, query.QFF_HOSTNAME, lambda ctx, item: item["name"]),
1366 fb0be379 Michael Hanselmann
      ], [])
1367 fb0be379 Michael Hanselmann
1368 fb0be379 Michael Hanselmann
    data = [
1369 fb0be379 Michael Hanselmann
      { "name": "node1.example.com", },
1370 fb0be379 Michael Hanselmann
      { "name": "node2.example.com", },
1371 fb0be379 Michael Hanselmann
      { "name": "node2.example.net", },
1372 fb0be379 Michael Hanselmann
      ]
1373 fb0be379 Michael Hanselmann
1374 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1375 fb0be379 Michael Hanselmann
                    filter_=["=", "name", "node2"])
1376 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node2"])
1377 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1378 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.com")],
1379 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.net")],
1380 fb0be379 Michael Hanselmann
      ])
1381 fb0be379 Michael Hanselmann
1382 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1383 fb0be379 Michael Hanselmann
                    filter_=["=", "name", "node1"])
1384 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1"])
1385 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1386 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node1.example.com")],
1387 fb0be379 Michael Hanselmann
      ])
1388 fb0be379 Michael Hanselmann
1389 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1390 fb0be379 Michael Hanselmann
                    filter_=["=", "name", "othername"])
1391 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["othername"])
1392 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [])
1393 fb0be379 Michael Hanselmann
1394 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1395 fb0be379 Michael Hanselmann
                    filter_=["|", ["=", "name", "node1.example.com"],
1396 fb0be379 Michael Hanselmann
                                  ["=", "name", "node2"]])
1397 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1.example.com", "node2"])
1398 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1399 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node1.example.com")],
1400 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.com")],
1401 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.net")],
1402 fb0be379 Michael Hanselmann
      ])
1403 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1404 fb0be379 Michael Hanselmann
      ["node1.example.com"],
1405 fb0be379 Michael Hanselmann
      ["node2.example.com"],
1406 fb0be379 Michael Hanselmann
      ["node2.example.net"],
1407 fb0be379 Michael Hanselmann
      ])
1408 fb0be379 Michael Hanselmann
1409 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1410 fb0be379 Michael Hanselmann
                    filter_=["!=", "name", "node1"])
1411 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1412 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1413 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.com")],
1414 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.net")],
1415 fb0be379 Michael Hanselmann
      ])
1416 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1417 fb0be379 Michael Hanselmann
      ["node2.example.com"],
1418 fb0be379 Michael Hanselmann
      ["node2.example.net"],
1419 fb0be379 Michael Hanselmann
      ])
1420 fb0be379 Michael Hanselmann
1421 3b877f08 Michael Hanselmann
  def testFilterBoolean(self):
1422 3b877f08 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1423 3b877f08 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1424 3b877f08 Michael Hanselmann
       None, query.QFF_HOSTNAME, lambda ctx, item: item["name"]),
1425 3b877f08 Michael Hanselmann
      (query._MakeField("value", "Value", constants.QFT_BOOL, "Value"),
1426 3b877f08 Michael Hanselmann
       None, 0, lambda ctx, item: item["value"]),
1427 3b877f08 Michael Hanselmann
      ], [])
1428 3b877f08 Michael Hanselmann
1429 3b877f08 Michael Hanselmann
    data = [
1430 3b877f08 Michael Hanselmann
      { "name": "node1", "value": False, },
1431 3b877f08 Michael Hanselmann
      { "name": "node2", "value": True, },
1432 3b877f08 Michael Hanselmann
      { "name": "node3", "value": True, },
1433 3b877f08 Michael Hanselmann
      ]
1434 3b877f08 Michael Hanselmann
1435 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "value"],
1436 3b877f08 Michael Hanselmann
                    filter_=["|", ["=", "value", False],
1437 3b877f08 Michael Hanselmann
                                  ["=", "value", True]])
1438 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1439 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1440 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, False)],
1441 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, True)],
1442 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, True)],
1443 3b877f08 Michael Hanselmann
      ])
1444 3b877f08 Michael Hanselmann
1445 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "value"],
1446 3b877f08 Michael Hanselmann
                    filter_=["|", ["=", "value", False],
1447 3b877f08 Michael Hanselmann
                                  ["!", ["=", "value", False]]])
1448 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1449 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1450 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, False)],
1451 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, True)],
1452 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, True)],
1453 3b877f08 Michael Hanselmann
      ])
1454 3b877f08 Michael Hanselmann
1455 3b877f08 Michael Hanselmann
    # Comparing bool with string
1456 3b877f08 Michael Hanselmann
    for i in ["False", "True", "0", "1", "no", "yes", "N", "Y"]:
1457 3b877f08 Michael Hanselmann
      self.assertRaises(errors.ParameterError, query.Query,
1458 3b877f08 Michael Hanselmann
                        fielddefs, ["name", "value"],
1459 3b877f08 Michael Hanselmann
                        filter_=["=", "value", i])
1460 3b877f08 Michael Hanselmann
1461 3b877f08 Michael Hanselmann
    # Truth filter
1462 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "value"], filter_=["?", "value"])
1463 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1464 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1465 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, True)],
1466 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, True)],
1467 3b877f08 Michael Hanselmann
      ])
1468 3b877f08 Michael Hanselmann
1469 3b877f08 Michael Hanselmann
    # Negative bool filter
1470 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "value"], filter_=["!", ["?", "value"]])
1471 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1472 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1473 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, False)],
1474 3b877f08 Michael Hanselmann
      ])
1475 3b877f08 Michael Hanselmann
1476 3b877f08 Michael Hanselmann
    # Complex truth filter
1477 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "value"],
1478 3b877f08 Michael Hanselmann
                    filter_=["|", ["&", ["=", "name", "node1"],
1479 3b877f08 Michael Hanselmann
                                        ["!", ["?", "value"]]],
1480 3b877f08 Michael Hanselmann
                                  ["?", "value"]])
1481 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1482 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1483 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, False)],
1484 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, True)],
1485 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, True)],
1486 3b877f08 Michael Hanselmann
      ])
1487 3b877f08 Michael Hanselmann
1488 fb0be379 Michael Hanselmann
1489 4ca96421 Michael Hanselmann
if __name__ == "__main__":
1490 4ca96421 Michael Hanselmann
  testutils.GanetiTestProgram()