Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.query_unittest.py @ d3b51156

History | View | Annotate | Download (68.2 kB)

1 4ca96421 Michael Hanselmann
#!/usr/bin/python
2 4ca96421 Michael Hanselmann
#
3 4ca96421 Michael Hanselmann
4 8930b0f0 Iustin Pop
# Copyright (C) 2010, 2011, 2012 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 320e34df Michael Hanselmann
    # Duplicate field name
226 320e34df Michael Hanselmann
    self.assertRaises(ValueError, query._PrepareFieldList, [
227 320e34df Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
228 320e34df Michael Hanselmann
       None, 0, lambda *args: None),
229 320e34df Michael Hanselmann
      (query._MakeField("name", "Other", constants.QFT_OTHER, "Other"),
230 320e34df Michael Hanselmann
       None, 0, lambda *args: None),
231 320e34df Michael Hanselmann
      ], [])
232 320e34df Michael Hanselmann
233 4ca96421 Michael Hanselmann
  def testUnknown(self):
234 4ca96421 Michael Hanselmann
    fielddef = query._PrepareFieldList([
235 79b2ca83 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
236 111bf531 Michael Hanselmann
       None, 0, lambda _, item: "name%s" % item),
237 79b2ca83 Michael Hanselmann
      (query._MakeField("other0", "Other0", constants.QFT_TIMESTAMP, "Other"),
238 111bf531 Michael Hanselmann
       None, 0, lambda *args: 1234),
239 79b2ca83 Michael Hanselmann
      (query._MakeField("nodata", "NoData", constants.QFT_NUMBER, "No data"),
240 111bf531 Michael Hanselmann
       None, 0, lambda *args: query._FS_NODATA ),
241 79b2ca83 Michael Hanselmann
      (query._MakeField("unavail", "Unavail", constants.QFT_BOOL, "Unavail"),
242 111bf531 Michael Hanselmann
       None, 0, lambda *args: query._FS_UNAVAIL),
243 d63bd540 Iustin Pop
      ], [])
244 4ca96421 Michael Hanselmann
245 4ca96421 Michael Hanselmann
    for selected in [["foo"], ["Hello", "World"],
246 4ca96421 Michael Hanselmann
                     ["name1", "other", "foo"]]:
247 4ca96421 Michael Hanselmann
      q = query.Query(fielddef, selected)
248 4ca96421 Michael Hanselmann
      self.assertEqual(len(q._fields), len(selected))
249 4ca96421 Michael Hanselmann
      self.assert_(compat.all(len(row) == len(selected)
250 4ca96421 Michael Hanselmann
                              for row in q.Query(_QueryData(range(1, 10)))))
251 4ca96421 Michael Hanselmann
      self.assertEqual(q.Query(_QueryData(range(1, 10))),
252 cfb084ae René Nussbaumer
                       [[(constants.RS_UNKNOWN, None)] * len(selected)
253 4ca96421 Michael Hanselmann
                        for i in range(1, 10)])
254 4ca96421 Michael Hanselmann
      self.assertEqual([fdef.ToDict() for fdef in q.GetFields()],
255 4ca96421 Michael Hanselmann
                       [{ "name": name, "title": name,
256 79b2ca83 Michael Hanselmann
                          "kind": constants.QFT_UNKNOWN,
257 79b2ca83 Michael Hanselmann
                          "doc": "Unknown field '%s'" % name}
258 4ca96421 Michael Hanselmann
                        for name in selected])
259 4ca96421 Michael Hanselmann
260 4ca96421 Michael Hanselmann
    q = query.Query(fielddef, ["name", "other0", "nodata", "unavail"])
261 4ca96421 Michael Hanselmann
    self.assertEqual(len(q._fields), 4)
262 4ca96421 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(_QueryData(range(1, 10))), [
263 4ca96421 Michael Hanselmann
                     ["name%s" % i, 1234, None, None]
264 4ca96421 Michael Hanselmann
                     for i in range(1, 10)
265 4ca96421 Michael Hanselmann
                     ])
266 4ca96421 Michael Hanselmann
267 4ca96421 Michael Hanselmann
    q = query.Query(fielddef, ["name", "other0", "nodata", "unavail", "unk"])
268 4ca96421 Michael Hanselmann
    self.assertEqual(len(q._fields), 5)
269 4ca96421 Michael Hanselmann
    self.assertEqual(q.Query(_QueryData(range(1, 10))),
270 cfb084ae René Nussbaumer
                     [[(constants.RS_NORMAL, "name%s" % i),
271 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 1234),
272 cfb084ae René Nussbaumer
                       (constants.RS_NODATA, None),
273 cfb084ae René Nussbaumer
                       (constants.RS_UNAVAIL, None),
274 cfb084ae René Nussbaumer
                       (constants.RS_UNKNOWN, None)]
275 4ca96421 Michael Hanselmann
                      for i in range(1, 10)])
276 4ca96421 Michael Hanselmann
277 d63bd540 Iustin Pop
  def testAliases(self):
278 d63bd540 Iustin Pop
    fields = [
279 111bf531 Michael Hanselmann
      (query._MakeField("a", "a-title", constants.QFT_TEXT, "Field A"),
280 111bf531 Michael Hanselmann
       None, 0, lambda *args: None),
281 111bf531 Michael Hanselmann
      (query._MakeField("b", "b-title", constants.QFT_TEXT, "Field B"),
282 111bf531 Michael Hanselmann
       None, 0, lambda *args: None),
283 d63bd540 Iustin Pop
      ]
284 d63bd540 Iustin Pop
    # duplicate field
285 d63bd540 Iustin Pop
    self.assertRaises(AssertionError, query._PrepareFieldList, fields,
286 d63bd540 Iustin Pop
                      [("b", "a")])
287 d63bd540 Iustin Pop
    self.assertRaises(AssertionError, query._PrepareFieldList, fields,
288 d63bd540 Iustin Pop
                      [("c", "b"), ("c", "a")])
289 d63bd540 Iustin Pop
    # missing target
290 d63bd540 Iustin Pop
    self.assertRaises(AssertionError, query._PrepareFieldList, fields,
291 d63bd540 Iustin Pop
                      [("c", "d")])
292 d63bd540 Iustin Pop
    fdefs = query._PrepareFieldList(fields, [("c", "b")])
293 d63bd540 Iustin Pop
    self.assertEqual(len(fdefs), 3)
294 d63bd540 Iustin Pop
    self.assertEqual(fdefs["b"][1:], fdefs["c"][1:])
295 d63bd540 Iustin Pop
296 4ca96421 Michael Hanselmann
297 8235fe04 Michael Hanselmann
class TestGetNodeRole(unittest.TestCase):
298 1e28e3b8 Michael Hanselmann
  def test(self):
299 1e28e3b8 Michael Hanselmann
    tested_role = set()
300 1e28e3b8 Michael Hanselmann
301 1e28e3b8 Michael Hanselmann
    checks = [
302 1e28e3b8 Michael Hanselmann
      (constants.NR_MASTER, "node1", objects.Node(name="node1")),
303 1e28e3b8 Michael Hanselmann
      (constants.NR_MCANDIDATE, "master",
304 1e28e3b8 Michael Hanselmann
       objects.Node(name="node1", master_candidate=True)),
305 1e28e3b8 Michael Hanselmann
      (constants.NR_REGULAR, "master", objects.Node(name="node1")),
306 1e28e3b8 Michael Hanselmann
      (constants.NR_DRAINED, "master",
307 1e28e3b8 Michael Hanselmann
       objects.Node(name="node1", drained=True)),
308 1e28e3b8 Michael Hanselmann
      (constants.NR_OFFLINE,
309 1e28e3b8 Michael Hanselmann
       "master", objects.Node(name="node1", offline=True)),
310 1e28e3b8 Michael Hanselmann
      ]
311 8235fe04 Michael Hanselmann
312 1e28e3b8 Michael Hanselmann
    for (role, master_name, node) in checks:
313 1e28e3b8 Michael Hanselmann
      result = query._GetNodeRole(node, master_name)
314 1e28e3b8 Michael Hanselmann
      self.assertEqual(result, role)
315 1e28e3b8 Michael Hanselmann
      tested_role.add(result)
316 8235fe04 Michael Hanselmann
317 1e28e3b8 Michael Hanselmann
    self.assertEqual(tested_role, constants.NR_ALL)
318 8235fe04 Michael Hanselmann
319 8235fe04 Michael Hanselmann
320 8235fe04 Michael Hanselmann
class TestNodeQuery(unittest.TestCase):
321 8235fe04 Michael Hanselmann
  def _Create(self, selected):
322 8235fe04 Michael Hanselmann
    return query.Query(query.NODE_FIELDS, selected)
323 8235fe04 Michael Hanselmann
324 8235fe04 Michael Hanselmann
  def testSimple(self):
325 8930b0f0 Iustin Pop
    cluster = objects.Cluster(cluster_name="testcluster",
326 8930b0f0 Iustin Pop
                              ndparams=constants.NDC_DEFAULTS.copy())
327 8930b0f0 Iustin Pop
    grp1 = objects.NodeGroup(name="default",
328 8930b0f0 Iustin Pop
                             uuid="c0e89160-18e7-11e0-a46e-001d0904baeb",
329 8930b0f0 Iustin Pop
                             alloc_policy=constants.ALLOC_POLICY_PREFERRED,
330 8930b0f0 Iustin Pop
                             ipolicy=objects.MakeEmptyIPolicy(),
331 8930b0f0 Iustin Pop
                             ndparams={},
332 8930b0f0 Iustin Pop
                             )
333 8930b0f0 Iustin Pop
    grp2 = objects.NodeGroup(name="group2",
334 8930b0f0 Iustin Pop
                             uuid="c0e89160-18e7-11e0-a46e-001d0904babe",
335 8930b0f0 Iustin Pop
                             alloc_policy=constants.ALLOC_POLICY_PREFERRED,
336 8930b0f0 Iustin Pop
                             ipolicy=objects.MakeEmptyIPolicy(),
337 8930b0f0 Iustin Pop
                             ndparams={constants.ND_SPINDLE_COUNT: 2},
338 8930b0f0 Iustin Pop
                             )
339 8930b0f0 Iustin Pop
    groups = {grp1.uuid: grp1, grp2.uuid: grp2}
340 8235fe04 Michael Hanselmann
    nodes = [
341 8930b0f0 Iustin Pop
      objects.Node(name="node1", drained=False, group=grp1.uuid, ndparams={}),
342 8930b0f0 Iustin Pop
      objects.Node(name="node2", drained=True, group=grp2.uuid, ndparams={}),
343 8930b0f0 Iustin Pop
      objects.Node(name="node3", drained=False, group=grp1.uuid,
344 8930b0f0 Iustin Pop
                   ndparams={constants.ND_SPINDLE_COUNT: 4}),
345 8235fe04 Michael Hanselmann
      ]
346 8235fe04 Michael Hanselmann
    for live_data in [None, dict.fromkeys([node.name for node in nodes], {})]:
347 8930b0f0 Iustin Pop
      nqd = query.NodeQueryData(nodes, live_data, None, None, None,
348 8930b0f0 Iustin Pop
                                groups, None, cluster)
349 8235fe04 Michael Hanselmann
350 8235fe04 Michael Hanselmann
      q = self._Create(["name", "drained"])
351 8235fe04 Michael Hanselmann
      self.assertEqual(q.RequestedData(), set([query.NQ_CONFIG]))
352 8235fe04 Michael Hanselmann
      self.assertEqual(q.Query(nqd),
353 cfb084ae René Nussbaumer
                       [[(constants.RS_NORMAL, "node1"),
354 cfb084ae René Nussbaumer
                         (constants.RS_NORMAL, False)],
355 cfb084ae René Nussbaumer
                        [(constants.RS_NORMAL, "node2"),
356 cfb084ae René Nussbaumer
                         (constants.RS_NORMAL, True)],
357 cfb084ae René Nussbaumer
                        [(constants.RS_NORMAL, "node3"),
358 cfb084ae René Nussbaumer
                         (constants.RS_NORMAL, False)],
359 8235fe04 Michael Hanselmann
                       ])
360 8235fe04 Michael Hanselmann
      self.assertEqual(q.OldStyleQuery(nqd),
361 8235fe04 Michael Hanselmann
                       [["node1", False],
362 8235fe04 Michael Hanselmann
                        ["node2", True],
363 8235fe04 Michael Hanselmann
                        ["node3", False]])
364 8930b0f0 Iustin Pop
      q = self._Create(["ndp/spindle_count"])
365 8930b0f0 Iustin Pop
      self.assertEqual(q.RequestedData(), set([query.NQ_GROUP]))
366 8930b0f0 Iustin Pop
      self.assertEqual(q.Query(nqd),
367 8930b0f0 Iustin Pop
                       [[(constants.RS_NORMAL,
368 8930b0f0 Iustin Pop
                          constants.NDC_DEFAULTS[constants.ND_SPINDLE_COUNT])],
369 8930b0f0 Iustin Pop
                        [(constants.RS_NORMAL,
370 8930b0f0 Iustin Pop
                          grp2.ndparams[constants.ND_SPINDLE_COUNT])],
371 8930b0f0 Iustin Pop
                        [(constants.RS_NORMAL,
372 8930b0f0 Iustin Pop
                          nodes[2].ndparams[constants.ND_SPINDLE_COUNT])],
373 8930b0f0 Iustin Pop
                       ])
374 8235fe04 Michael Hanselmann
375 8235fe04 Michael Hanselmann
  def test(self):
376 8235fe04 Michael Hanselmann
    selected = query.NODE_FIELDS.keys()
377 8235fe04 Michael Hanselmann
    field_index = dict((field, idx) for idx, field in enumerate(selected))
378 8235fe04 Michael Hanselmann
379 8235fe04 Michael Hanselmann
    q = self._Create(selected)
380 8235fe04 Michael Hanselmann
    self.assertEqual(q.RequestedData(),
381 8235fe04 Michael Hanselmann
                     set([query.NQ_CONFIG, query.NQ_LIVE, query.NQ_INST,
382 52b5d286 René Nussbaumer
                          query.NQ_GROUP, query.NQ_OOB]))
383 8235fe04 Michael Hanselmann
384 8572f1fe René Nussbaumer
    cluster = objects.Cluster(cluster_name="testcluster",
385 8572f1fe René Nussbaumer
      hvparams=constants.HVC_DEFAULTS,
386 8572f1fe René Nussbaumer
      beparams={
387 8572f1fe René Nussbaumer
        constants.PP_DEFAULT: constants.BEC_DEFAULTS,
388 8572f1fe René Nussbaumer
        },
389 8572f1fe René Nussbaumer
      nicparams={
390 8572f1fe René Nussbaumer
        constants.PP_DEFAULT: constants.NICC_DEFAULTS,
391 8572f1fe René Nussbaumer
        },
392 8572f1fe René Nussbaumer
      ndparams=constants.NDC_DEFAULTS,
393 8572f1fe René Nussbaumer
        )
394 8572f1fe René Nussbaumer
395 8235fe04 Michael Hanselmann
    node_names = ["node%s" % i for i in range(20)]
396 8235fe04 Michael Hanselmann
    master_name = node_names[3]
397 8235fe04 Michael Hanselmann
    nodes = [
398 8235fe04 Michael Hanselmann
      objects.Node(name=name,
399 8235fe04 Michael Hanselmann
                   primary_ip="192.0.2.%s" % idx,
400 8235fe04 Michael Hanselmann
                   secondary_ip="192.0.100.%s" % idx,
401 8235fe04 Michael Hanselmann
                   serial_no=7789 * idx,
402 8235fe04 Michael Hanselmann
                   master_candidate=(name != master_name and idx % 3 == 0),
403 8235fe04 Michael Hanselmann
                   offline=False,
404 8235fe04 Michael Hanselmann
                   drained=False,
405 b12d5e2e René Nussbaumer
                   powered=True,
406 effab4ca Iustin Pop
                   vm_capable=True,
407 8235fe04 Michael Hanselmann
                   master_capable=False,
408 8572f1fe René Nussbaumer
                   ndparams={},
409 8235fe04 Michael Hanselmann
                   group="default",
410 8235fe04 Michael Hanselmann
                   ctime=1290006900,
411 8235fe04 Michael Hanselmann
                   mtime=1290006913,
412 8235fe04 Michael Hanselmann
                   uuid="fd9ccebe-6339-43c9-a82e-94bbe575%04d" % idx)
413 8235fe04 Michael Hanselmann
      for idx, name in enumerate(node_names)
414 8235fe04 Michael Hanselmann
      ]
415 8235fe04 Michael Hanselmann
416 8235fe04 Michael Hanselmann
    master_node = nodes[3]
417 8235fe04 Michael Hanselmann
    master_node.AddTag("masternode")
418 8235fe04 Michael Hanselmann
    master_node.AddTag("another")
419 8235fe04 Michael Hanselmann
    master_node.AddTag("tag")
420 145bea54 Michael Hanselmann
    master_node.ctime = None
421 145bea54 Michael Hanselmann
    master_node.mtime = None
422 8235fe04 Michael Hanselmann
    assert master_node.name == master_name
423 8235fe04 Michael Hanselmann
424 8235fe04 Michael Hanselmann
    live_data_name = node_names[4]
425 8235fe04 Michael Hanselmann
    assert live_data_name != master_name
426 8235fe04 Michael Hanselmann
427 8235fe04 Michael Hanselmann
    fake_live_data = {
428 8235fe04 Michael Hanselmann
      "bootid": "a2504766-498e-4b25-b21e-d23098dc3af4",
429 8235fe04 Michael Hanselmann
      "cnodes": 4,
430 8235fe04 Michael Hanselmann
      "csockets": 4,
431 8235fe04 Michael Hanselmann
      "ctotal": 8,
432 8235fe04 Michael Hanselmann
      "mnode": 128,
433 8235fe04 Michael Hanselmann
      "mfree": 100,
434 8235fe04 Michael Hanselmann
      "mtotal": 4096,
435 8235fe04 Michael Hanselmann
      "dfree": 5 * 1024 * 1024,
436 8235fe04 Michael Hanselmann
      "dtotal": 100 * 1024 * 1024,
437 8235fe04 Michael Hanselmann
      }
438 8235fe04 Michael Hanselmann
439 8235fe04 Michael Hanselmann
    assert (sorted(query._NODE_LIVE_FIELDS.keys()) ==
440 8235fe04 Michael Hanselmann
            sorted(fake_live_data.keys()))
441 8235fe04 Michael Hanselmann
442 8235fe04 Michael Hanselmann
    live_data = dict.fromkeys(node_names, {})
443 8235fe04 Michael Hanselmann
    live_data[live_data_name] = \
444 8235fe04 Michael Hanselmann
      dict((query._NODE_LIVE_FIELDS[name][2], value)
445 8235fe04 Michael Hanselmann
           for name, value in fake_live_data.items())
446 8235fe04 Michael Hanselmann
447 8235fe04 Michael Hanselmann
    node_to_primary = dict((name, set()) for name in node_names)
448 8235fe04 Michael Hanselmann
    node_to_primary[master_name].update(["inst1", "inst2"])
449 8235fe04 Michael Hanselmann
450 8235fe04 Michael Hanselmann
    node_to_secondary = dict((name, set()) for name in node_names)
451 8235fe04 Michael Hanselmann
    node_to_secondary[live_data_name].update(["instX", "instY", "instZ"])
452 8235fe04 Michael Hanselmann
453 8235fe04 Michael Hanselmann
    ng_uuid = "492b4b74-8670-478a-b98d-4c53a76238e6"
454 8235fe04 Michael Hanselmann
    groups = {
455 8572f1fe René Nussbaumer
      ng_uuid: objects.NodeGroup(name="ng1", uuid=ng_uuid, ndparams={}),
456 8235fe04 Michael Hanselmann
      }
457 8235fe04 Michael Hanselmann
458 b12d5e2e René Nussbaumer
    oob_not_powered_node = node_names[0]
459 b12d5e2e René Nussbaumer
    nodes[0].powered = False
460 52b5d286 René Nussbaumer
    oob_support = dict((name, False) for name in node_names)
461 b12d5e2e René Nussbaumer
    oob_support[master_name] = True
462 b12d5e2e René Nussbaumer
    oob_support[oob_not_powered_node] = True
463 52b5d286 René Nussbaumer
464 8235fe04 Michael Hanselmann
    master_node.group = ng_uuid
465 8235fe04 Michael Hanselmann
466 8235fe04 Michael Hanselmann
    nqd = query.NodeQueryData(nodes, live_data, master_name,
467 52b5d286 René Nussbaumer
                              node_to_primary, node_to_secondary, groups,
468 8572f1fe René Nussbaumer
                              oob_support, cluster)
469 8235fe04 Michael Hanselmann
    result = q.Query(nqd)
470 8235fe04 Michael Hanselmann
    self.assert_(compat.all(len(row) == len(selected) for row in result))
471 8235fe04 Michael Hanselmann
    self.assertEqual([row[field_index["name"]] for row in result],
472 cfb084ae René Nussbaumer
                     [(constants.RS_NORMAL, name) for name in node_names])
473 8235fe04 Michael Hanselmann
474 8235fe04 Michael Hanselmann
    node_to_row = dict((row[field_index["name"]][1], idx)
475 8235fe04 Michael Hanselmann
                       for idx, row in enumerate(result))
476 8235fe04 Michael Hanselmann
477 8235fe04 Michael Hanselmann
    master_row = result[node_to_row[master_name]]
478 8235fe04 Michael Hanselmann
    self.assert_(master_row[field_index["master"]])
479 8235fe04 Michael Hanselmann
    self.assert_(master_row[field_index["role"]], "M")
480 8235fe04 Michael Hanselmann
    self.assertEqual(master_row[field_index["group"]],
481 cfb084ae René Nussbaumer
                     (constants.RS_NORMAL, "ng1"))
482 8235fe04 Michael Hanselmann
    self.assertEqual(master_row[field_index["group.uuid"]],
483 cfb084ae René Nussbaumer
                     (constants.RS_NORMAL, ng_uuid))
484 145bea54 Michael Hanselmann
    self.assertEqual(master_row[field_index["ctime"]],
485 cfb084ae René Nussbaumer
                     (constants.RS_UNAVAIL, None))
486 145bea54 Michael Hanselmann
    self.assertEqual(master_row[field_index["mtime"]],
487 cfb084ae René Nussbaumer
                     (constants.RS_UNAVAIL, None))
488 8235fe04 Michael Hanselmann
489 8235fe04 Michael Hanselmann
    self.assert_(row[field_index["pip"]] == node.primary_ip and
490 8235fe04 Michael Hanselmann
                 row[field_index["sip"]] == node.secondary_ip and
491 8235fe04 Michael Hanselmann
                 set(row[field_index["tags"]]) == node.GetTags() and
492 8235fe04 Michael Hanselmann
                 row[field_index["serial_no"]] == node.serial_no and
493 8235fe04 Michael Hanselmann
                 row[field_index["role"]] == query._GetNodeRole(node,
494 8235fe04 Michael Hanselmann
                                                                master_name) and
495 8235fe04 Michael Hanselmann
                 (node.name == master_name or
496 8235fe04 Michael Hanselmann
                  (row[field_index["group"]] == "<unknown>" and
497 145bea54 Michael Hanselmann
                   row[field_index["group.uuid"]] is None and
498 cfb084ae René Nussbaumer
                   row[field_index["ctime"]] == (constants.RS_NORMAL,
499 145bea54 Michael Hanselmann
                                                 node.ctime) and
500 cfb084ae René Nussbaumer
                   row[field_index["mtime"]] == (constants.RS_NORMAL,
501 b12d5e2e René Nussbaumer
                                                 node.mtime) and
502 b12d5e2e René Nussbaumer
                   row[field_index["powered"]] == (constants.RS_NORMAL,
503 b12d5e2e René Nussbaumer
                                                   True))) or
504 b12d5e2e René Nussbaumer
                 (node.name == oob_not_powered_node and
505 b12d5e2e René Nussbaumer
                  row[field_index["powered"]] == (constants.RS_NORMAL,
506 b12d5e2e René Nussbaumer
                                                  False)) or
507 b12d5e2e René Nussbaumer
                 row[field_index["powered"]] == (constants.RS_UNAVAIL, None)
508 8235fe04 Michael Hanselmann
                 for row, node in zip(result, nodes))
509 8235fe04 Michael Hanselmann
510 8235fe04 Michael Hanselmann
    live_data_row = result[node_to_row[live_data_name]]
511 8235fe04 Michael Hanselmann
512 8235fe04 Michael Hanselmann
    for (field, value) in fake_live_data.items():
513 8235fe04 Michael Hanselmann
      self.assertEqual(live_data_row[field_index[field]],
514 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, value))
515 8235fe04 Michael Hanselmann
516 8235fe04 Michael Hanselmann
    self.assertEqual(master_row[field_index["pinst_cnt"]],
517 cfb084ae René Nussbaumer
                     (constants.RS_NORMAL, 2))
518 8235fe04 Michael Hanselmann
    self.assertEqual(live_data_row[field_index["sinst_cnt"]],
519 cfb084ae René Nussbaumer
                     (constants.RS_NORMAL, 3))
520 8235fe04 Michael Hanselmann
    self.assertEqual(master_row[field_index["pinst_list"]],
521 cfb084ae René Nussbaumer
                     (constants.RS_NORMAL,
522 8235fe04 Michael Hanselmann
                      list(node_to_primary[master_name])))
523 8235fe04 Michael Hanselmann
    self.assertEqual(live_data_row[field_index["sinst_list"]],
524 cfb084ae René Nussbaumer
                     (constants.RS_NORMAL,
525 8235fe04 Michael Hanselmann
                      list(node_to_secondary[live_data_name])))
526 8235fe04 Michael Hanselmann
527 8235fe04 Michael Hanselmann
  def testGetLiveNodeField(self):
528 8235fe04 Michael Hanselmann
    nodes = [
529 effab4ca Iustin Pop
      objects.Node(name="node1", drained=False, offline=False,
530 effab4ca Iustin Pop
                   vm_capable=True),
531 effab4ca Iustin Pop
      objects.Node(name="node2", drained=True, offline=False,
532 effab4ca Iustin Pop
                   vm_capable=True),
533 effab4ca Iustin Pop
      objects.Node(name="node3", drained=False, offline=False,
534 effab4ca Iustin Pop
                   vm_capable=True),
535 effab4ca Iustin Pop
      objects.Node(name="node4", drained=False, offline=True,
536 effab4ca Iustin Pop
                   vm_capable=True),
537 effab4ca Iustin Pop
      objects.Node(name="node5", drained=False, offline=False,
538 effab4ca Iustin Pop
                   vm_capable=False),
539 8235fe04 Michael Hanselmann
      ]
540 8235fe04 Michael Hanselmann
    live_data = dict.fromkeys([node.name for node in nodes], {})
541 8235fe04 Michael Hanselmann
542 8235fe04 Michael Hanselmann
    # No data
543 8572f1fe René Nussbaumer
    nqd = query.NodeQueryData(None, None, None, None, None, None, None, None)
544 8235fe04 Michael Hanselmann
    self.assertEqual(query._GetLiveNodeField("hello", constants.QFT_NUMBER,
545 a6070ef7 Michael Hanselmann
                                             nqd, nodes[0]),
546 e2d188cc Iustin Pop
                     query._FS_NODATA)
547 8235fe04 Michael Hanselmann
548 8235fe04 Michael Hanselmann
    # Missing field
549 8235fe04 Michael Hanselmann
    ctx = _QueryData(None, curlive_data={
550 8235fe04 Michael Hanselmann
      "some": 1,
551 8235fe04 Michael Hanselmann
      "other": 2,
552 8235fe04 Michael Hanselmann
      })
553 8235fe04 Michael Hanselmann
    self.assertEqual(query._GetLiveNodeField("hello", constants.QFT_NUMBER,
554 a6070ef7 Michael Hanselmann
                                             ctx, nodes[0]),
555 e2d188cc Iustin Pop
                     query._FS_UNAVAIL)
556 8235fe04 Michael Hanselmann
557 8235fe04 Michael Hanselmann
    # Wrong format/datatype
558 8235fe04 Michael Hanselmann
    ctx = _QueryData(None, curlive_data={
559 8235fe04 Michael Hanselmann
      "hello": ["Hello World"],
560 8235fe04 Michael Hanselmann
      "other": 2,
561 8235fe04 Michael Hanselmann
      })
562 8235fe04 Michael Hanselmann
    self.assertEqual(query._GetLiveNodeField("hello", constants.QFT_NUMBER,
563 a6070ef7 Michael Hanselmann
                                             ctx, nodes[0]),
564 e2d188cc Iustin Pop
                     query._FS_UNAVAIL)
565 8235fe04 Michael Hanselmann
566 a6070ef7 Michael Hanselmann
    # Offline node
567 a6070ef7 Michael Hanselmann
    assert nodes[3].offline
568 a6070ef7 Michael Hanselmann
    ctx = _QueryData(None, curlive_data={})
569 a6070ef7 Michael Hanselmann
    self.assertEqual(query._GetLiveNodeField("hello", constants.QFT_NUMBER,
570 a6070ef7 Michael Hanselmann
                                             ctx, nodes[3]),
571 e2d188cc Iustin Pop
                     query._FS_OFFLINE, None)
572 a6070ef7 Michael Hanselmann
573 8235fe04 Michael Hanselmann
    # Wrong field type
574 8235fe04 Michael Hanselmann
    ctx = _QueryData(None, curlive_data={"hello": 123})
575 8235fe04 Michael Hanselmann
    self.assertRaises(AssertionError, query._GetLiveNodeField,
576 a6070ef7 Michael Hanselmann
                      "hello", constants.QFT_BOOL, ctx, nodes[0])
577 8235fe04 Michael Hanselmann
578 effab4ca Iustin Pop
    # Non-vm_capable node
579 effab4ca Iustin Pop
    assert not nodes[4].vm_capable
580 effab4ca Iustin Pop
    ctx = _QueryData(None, curlive_data={})
581 effab4ca Iustin Pop
    self.assertEqual(query._GetLiveNodeField("hello", constants.QFT_NUMBER,
582 effab4ca Iustin Pop
                                             ctx, nodes[4]),
583 effab4ca Iustin Pop
                     query._FS_UNAVAIL, None)
584 effab4ca Iustin Pop
585 8235fe04 Michael Hanselmann
586 1c8addc6 Michael Hanselmann
class TestInstanceQuery(unittest.TestCase):
587 1c8addc6 Michael Hanselmann
  def _Create(self, selected):
588 1c8addc6 Michael Hanselmann
    return query.Query(query.INSTANCE_FIELDS, selected)
589 1c8addc6 Michael Hanselmann
590 1c8addc6 Michael Hanselmann
  def testSimple(self):
591 861610e9 Guido Trotter
    q = self._Create(["name", "be/maxmem", "ip"])
592 1c8addc6 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([query.IQ_CONFIG]))
593 1c8addc6 Michael Hanselmann
594 1c8addc6 Michael Hanselmann
    cluster = objects.Cluster(cluster_name="testcluster",
595 1c8addc6 Michael Hanselmann
      hvparams=constants.HVC_DEFAULTS,
596 1c8addc6 Michael Hanselmann
      beparams={
597 1c8addc6 Michael Hanselmann
        constants.PP_DEFAULT: constants.BEC_DEFAULTS,
598 1c8addc6 Michael Hanselmann
        },
599 1c8addc6 Michael Hanselmann
      nicparams={
600 1c8addc6 Michael Hanselmann
        constants.PP_DEFAULT: constants.NICC_DEFAULTS,
601 7c670076 Michael Hanselmann
        },
602 7c670076 Michael Hanselmann
      os_hvp={},
603 7c670076 Michael Hanselmann
      osparams={})
604 1c8addc6 Michael Hanselmann
605 1c8addc6 Michael Hanselmann
    instances = [
606 7c670076 Michael Hanselmann
      objects.Instance(name="inst1", hvparams={}, beparams={}, osparams={},
607 7c670076 Michael Hanselmann
                       nics=[], os="deb1"),
608 7c670076 Michael Hanselmann
      objects.Instance(name="inst2", hvparams={}, nics=[], osparams={},
609 7c670076 Michael Hanselmann
        os="foomoo",
610 1c8addc6 Michael Hanselmann
        beparams={
611 861610e9 Guido Trotter
          constants.BE_MAXMEM: 512,
612 1c8addc6 Michael Hanselmann
        }),
613 7c670076 Michael Hanselmann
      objects.Instance(name="inst3", hvparams={}, beparams={}, osparams={},
614 7c670076 Michael Hanselmann
        os="dos", nics=[objects.NIC(ip="192.0.2.99", nicparams={})]),
615 1c8addc6 Michael Hanselmann
      ]
616 1c8addc6 Michael Hanselmann
617 5d28cb6f Michael Hanselmann
    iqd = query.InstanceQueryData(instances, cluster, None, [], [], {},
618 fab9573b Michael Hanselmann
                                  set(), {}, None, None)
619 1c8addc6 Michael Hanselmann
    self.assertEqual(q.Query(iqd),
620 cfb084ae René Nussbaumer
      [[(constants.RS_NORMAL, "inst1"),
621 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, 128),
622 cfb084ae René Nussbaumer
        (constants.RS_UNAVAIL, None),
623 1c8addc6 Michael Hanselmann
       ],
624 cfb084ae René Nussbaumer
       [(constants.RS_NORMAL, "inst2"),
625 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, 512),
626 cfb084ae René Nussbaumer
        (constants.RS_UNAVAIL, None),
627 1c8addc6 Michael Hanselmann
       ],
628 cfb084ae René Nussbaumer
       [(constants.RS_NORMAL, "inst3"),
629 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, 128),
630 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, "192.0.2.99"),
631 1c8addc6 Michael Hanselmann
       ]])
632 1c8addc6 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(iqd),
633 1c8addc6 Michael Hanselmann
      [["inst1", 128, None],
634 1c8addc6 Michael Hanselmann
       ["inst2", 512, None],
635 1c8addc6 Michael Hanselmann
       ["inst3", 128, "192.0.2.99"]])
636 1c8addc6 Michael Hanselmann
637 1c8addc6 Michael Hanselmann
  def test(self):
638 1c8addc6 Michael Hanselmann
    selected = query.INSTANCE_FIELDS.keys()
639 1c8addc6 Michael Hanselmann
    fieldidx = dict((field, idx) for idx, field in enumerate(selected))
640 1c8addc6 Michael Hanselmann
641 1c8addc6 Michael Hanselmann
    macs = ["00:11:22:%02x:%02x:%02x" % (i % 255, i % 3, (i * 123) % 255)
642 1c8addc6 Michael Hanselmann
            for i in range(20)]
643 1c8addc6 Michael Hanselmann
644 1c8addc6 Michael Hanselmann
    q = self._Create(selected)
645 1c8addc6 Michael Hanselmann
    self.assertEqual(q.RequestedData(),
646 5d28cb6f Michael Hanselmann
                     set([query.IQ_CONFIG, query.IQ_LIVE, query.IQ_DISKUSAGE,
647 fab9573b Michael Hanselmann
                          query.IQ_CONSOLE, query.IQ_NODES]))
648 1c8addc6 Michael Hanselmann
649 1c8addc6 Michael Hanselmann
    cluster = objects.Cluster(cluster_name="testcluster",
650 1c8addc6 Michael Hanselmann
      hvparams=constants.HVC_DEFAULTS,
651 1c8addc6 Michael Hanselmann
      beparams={
652 1c8addc6 Michael Hanselmann
        constants.PP_DEFAULT: constants.BEC_DEFAULTS,
653 1c8addc6 Michael Hanselmann
        },
654 1c8addc6 Michael Hanselmann
      nicparams={
655 1c8addc6 Michael Hanselmann
        constants.PP_DEFAULT: constants.NICC_DEFAULTS,
656 1c8addc6 Michael Hanselmann
        },
657 1c8addc6 Michael Hanselmann
      os_hvp={},
658 7c670076 Michael Hanselmann
      tcpudp_port_pool=set(),
659 7c670076 Michael Hanselmann
      osparams={
660 7c670076 Michael Hanselmann
        "deb99": {
661 7c670076 Michael Hanselmann
          "clean_install": "yes",
662 7c670076 Michael Hanselmann
          },
663 7c670076 Michael Hanselmann
        })
664 1c8addc6 Michael Hanselmann
665 1c8addc6 Michael Hanselmann
    offline_nodes = ["nodeoff1", "nodeoff2"]
666 1c8addc6 Michael Hanselmann
    bad_nodes = ["nodebad1", "nodebad2", "nodebad3"] + offline_nodes
667 1c8addc6 Michael Hanselmann
    nodes = ["node%s" % i for i in range(10)] + bad_nodes
668 1c8addc6 Michael Hanselmann
669 1c8addc6 Michael Hanselmann
    instances = [
670 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst1", hvparams={}, beparams={}, nics=[],
671 1c8addc6 Michael Hanselmann
        uuid="f90eccb3-e227-4e3c-bf2a-94a21ca8f9cd",
672 1c8addc6 Michael Hanselmann
        ctime=1291244000, mtime=1291244400, serial_no=30,
673 2e04d454 Agata Murawska
        admin_state=constants.ADMINST_UP, hypervisor=constants.HT_XEN_PVM,
674 2e04d454 Agata Murawska
        os="linux1",
675 1c8addc6 Michael Hanselmann
        primary_node="node1",
676 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_PLAIN,
677 7c670076 Michael Hanselmann
        disks=[],
678 7c670076 Michael Hanselmann
        osparams={}),
679 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst2", hvparams={}, nics=[],
680 1c8addc6 Michael Hanselmann
        uuid="73a0f8a7-068c-4630-ada2-c3440015ab1a",
681 1c8addc6 Michael Hanselmann
        ctime=1291211000, mtime=1291211077, serial_no=1,
682 2e04d454 Agata Murawska
        admin_state=constants.ADMINST_UP, hypervisor=constants.HT_XEN_HVM,
683 2e04d454 Agata Murawska
        os="deb99",
684 1c8addc6 Michael Hanselmann
        primary_node="node5",
685 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DISKLESS,
686 1c8addc6 Michael Hanselmann
        disks=[],
687 1c8addc6 Michael Hanselmann
        beparams={
688 861610e9 Guido Trotter
          constants.BE_MAXMEM: 512,
689 861610e9 Guido Trotter
          constants.BE_MINMEM: 256,
690 7c670076 Michael Hanselmann
        },
691 7c670076 Michael Hanselmann
        osparams={}),
692 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst3", hvparams={}, beparams={},
693 1c8addc6 Michael Hanselmann
        uuid="11ec8dff-fb61-4850-bfe0-baa1803ff280",
694 1c8addc6 Michael Hanselmann
        ctime=1291011000, mtime=1291013000, serial_no=1923,
695 2e04d454 Agata Murawska
        admin_state=constants.ADMINST_DOWN, hypervisor=constants.HT_KVM,
696 2e04d454 Agata Murawska
        os="busybox",
697 1c8addc6 Michael Hanselmann
        primary_node="node6",
698 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DRBD8,
699 1c8addc6 Michael Hanselmann
        disks=[],
700 1c8addc6 Michael Hanselmann
        nics=[
701 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.99", mac=macs.pop(),
702 1c8addc6 Michael Hanselmann
                      nicparams={
703 1c8addc6 Michael Hanselmann
                        constants.NIC_LINK: constants.DEFAULT_BRIDGE,
704 1c8addc6 Michael Hanselmann
                        }),
705 1c8addc6 Michael Hanselmann
          objects.NIC(ip=None, mac=macs.pop(), nicparams={}),
706 7c670076 Michael Hanselmann
          ],
707 7c670076 Michael Hanselmann
        osparams={}),
708 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst4", hvparams={}, beparams={},
709 1c8addc6 Michael Hanselmann
        uuid="68dab168-3ef5-4c9d-b4d3-801e0672068c",
710 1c8addc6 Michael Hanselmann
        ctime=1291244390, mtime=1291244395, serial_no=25,
711 2e04d454 Agata Murawska
        admin_state=constants.ADMINST_DOWN, hypervisor=constants.HT_XEN_PVM,
712 2e04d454 Agata Murawska
        os="linux1",
713 1c8addc6 Michael Hanselmann
        primary_node="nodeoff2",
714 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DRBD8,
715 1c8addc6 Michael Hanselmann
        disks=[],
716 1c8addc6 Michael Hanselmann
        nics=[
717 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.1", mac=macs.pop(),
718 1c8addc6 Michael Hanselmann
                      nicparams={
719 1c8addc6 Michael Hanselmann
                        constants.NIC_LINK: constants.DEFAULT_BRIDGE,
720 1c8addc6 Michael Hanselmann
                        }),
721 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.2", mac=macs.pop(), nicparams={}),
722 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.3", mac=macs.pop(),
723 1c8addc6 Michael Hanselmann
                      nicparams={
724 1c8addc6 Michael Hanselmann
                        constants.NIC_MODE: constants.NIC_MODE_ROUTED,
725 1c8addc6 Michael Hanselmann
                        }),
726 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.4", mac=macs.pop(),
727 1c8addc6 Michael Hanselmann
                      nicparams={
728 1c8addc6 Michael Hanselmann
                        constants.NIC_MODE: constants.NIC_MODE_BRIDGED,
729 1c8addc6 Michael Hanselmann
                        constants.NIC_LINK: "eth123",
730 1c8addc6 Michael Hanselmann
                        }),
731 7c670076 Michael Hanselmann
          ],
732 7c670076 Michael Hanselmann
        osparams={}),
733 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst5", hvparams={}, nics=[],
734 1c8addc6 Michael Hanselmann
        uuid="0e3dca12-5b42-4e24-98a2-415267545bd0",
735 1c8addc6 Michael Hanselmann
        ctime=1231211000, mtime=1261200000, serial_no=3,
736 2e04d454 Agata Murawska
        admin_state=constants.ADMINST_UP, hypervisor=constants.HT_XEN_HVM,
737 2e04d454 Agata Murawska
        os="deb99",
738 1c8addc6 Michael Hanselmann
        primary_node="nodebad2",
739 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DISKLESS,
740 1c8addc6 Michael Hanselmann
        disks=[],
741 1c8addc6 Michael Hanselmann
        beparams={
742 861610e9 Guido Trotter
          constants.BE_MAXMEM: 512,
743 861610e9 Guido Trotter
          constants.BE_MINMEM: 512,
744 7c670076 Michael Hanselmann
        },
745 7c670076 Michael Hanselmann
        osparams={}),
746 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst6", hvparams={}, nics=[],
747 1c8addc6 Michael Hanselmann
        uuid="72de6580-c8d5-4661-b902-38b5785bb8b3",
748 1c8addc6 Michael Hanselmann
        ctime=7513, mtime=11501, serial_no=13390,
749 2e04d454 Agata Murawska
        admin_state=constants.ADMINST_DOWN, hypervisor=constants.HT_XEN_HVM,
750 2e04d454 Agata Murawska
        os="deb99",
751 1c8addc6 Michael Hanselmann
        primary_node="node7",
752 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DISKLESS,
753 1c8addc6 Michael Hanselmann
        disks=[],
754 1c8addc6 Michael Hanselmann
        beparams={
755 861610e9 Guido Trotter
          constants.BE_MAXMEM: 768,
756 861610e9 Guido Trotter
          constants.BE_MINMEM: 256,
757 7c670076 Michael Hanselmann
        },
758 7c670076 Michael Hanselmann
        osparams={
759 7c670076 Michael Hanselmann
          "clean_install": "no",
760 7c670076 Michael Hanselmann
          }),
761 145bea54 Michael Hanselmann
      objects.Instance(name="inst7", hvparams={}, nics=[],
762 145bea54 Michael Hanselmann
        uuid="ceec5dc4-b729-4f42-ae28-69b3cd24920e",
763 145bea54 Michael Hanselmann
        ctime=None, mtime=None, serial_no=1947,
764 2e04d454 Agata Murawska
        admin_state=constants.ADMINST_DOWN, hypervisor=constants.HT_XEN_HVM,
765 2e04d454 Agata Murawska
        os="deb99",
766 2e04d454 Agata Murawska
        primary_node="node6",
767 2e04d454 Agata Murawska
        disk_template=constants.DT_DISKLESS,
768 2e04d454 Agata Murawska
        disks=[],
769 2e04d454 Agata Murawska
        beparams={},
770 2e04d454 Agata Murawska
        osparams={}),
771 2e04d454 Agata Murawska
      objects.Instance(name="inst8", hvparams={}, nics=[],
772 2e04d454 Agata Murawska
        uuid="ceec5dc4-b729-4f42-ae28-69b3cd24920f",
773 2e04d454 Agata Murawska
        ctime=None, mtime=None, serial_no=19478,
774 2e04d454 Agata Murawska
        admin_state=constants.ADMINST_OFFLINE, hypervisor=constants.HT_XEN_HVM,
775 2e04d454 Agata Murawska
        os="deb99",
776 145bea54 Michael Hanselmann
        primary_node="node6",
777 145bea54 Michael Hanselmann
        disk_template=constants.DT_DISKLESS,
778 145bea54 Michael Hanselmann
        disks=[],
779 7c670076 Michael Hanselmann
        beparams={},
780 7c670076 Michael Hanselmann
        osparams={}),
781 1c8addc6 Michael Hanselmann
      ]
782 1c8addc6 Michael Hanselmann
783 145bea54 Michael Hanselmann
    assert not utils.FindDuplicates(inst.name for inst in instances)
784 145bea54 Michael Hanselmann
785 5d28cb6f Michael Hanselmann
    instbyname = dict((inst.name, inst) for inst in instances)
786 5d28cb6f Michael Hanselmann
787 1c8addc6 Michael Hanselmann
    disk_usage = dict((inst.name,
788 1c8addc6 Michael Hanselmann
                       cmdlib._ComputeDiskSize(inst.disk_template,
789 1c8addc6 Michael Hanselmann
                                               [{"size": disk.size}
790 1c8addc6 Michael Hanselmann
                                                for disk in inst.disks]))
791 1c8addc6 Michael Hanselmann
                      for inst in instances)
792 1c8addc6 Michael Hanselmann
793 1c8addc6 Michael Hanselmann
    inst_bridges = {
794 1c8addc6 Michael Hanselmann
      "inst3": [constants.DEFAULT_BRIDGE, constants.DEFAULT_BRIDGE],
795 1c8addc6 Michael Hanselmann
      "inst4": [constants.DEFAULT_BRIDGE, constants.DEFAULT_BRIDGE,
796 1c8addc6 Michael Hanselmann
                None, "eth123"],
797 1c8addc6 Michael Hanselmann
      }
798 1c8addc6 Michael Hanselmann
799 1c8addc6 Michael Hanselmann
    live_data = {
800 1c8addc6 Michael Hanselmann
      "inst2": {
801 1c8addc6 Michael Hanselmann
        "vcpus": 3,
802 1c8addc6 Michael Hanselmann
        },
803 1c8addc6 Michael Hanselmann
      "inst4": {
804 1c8addc6 Michael Hanselmann
        "memory": 123,
805 1c8addc6 Michael Hanselmann
        },
806 1c8addc6 Michael Hanselmann
      "inst6": {
807 1c8addc6 Michael Hanselmann
        "memory": 768,
808 1c8addc6 Michael Hanselmann
        },
809 bacae536 René Nussbaumer
      "inst7": {
810 bacae536 René Nussbaumer
        "vcpus": 3,
811 bacae536 René Nussbaumer
        },
812 1c8addc6 Michael Hanselmann
      }
813 bacae536 René Nussbaumer
    wrongnode_inst = set(["inst7"])
814 1c8addc6 Michael Hanselmann
815 5d28cb6f Michael Hanselmann
    consinfo = dict((inst.name, None) for inst in instances)
816 5d28cb6f Michael Hanselmann
    consinfo["inst7"] = \
817 5d28cb6f Michael Hanselmann
      objects.InstanceConsole(instance="inst7", kind=constants.CONS_SSH,
818 5d28cb6f Michael Hanselmann
                              host=instbyname["inst7"].primary_node,
819 5d28cb6f Michael Hanselmann
                              user=constants.GANETI_RUNAS,
820 5d28cb6f Michael Hanselmann
                              command=["hostname"]).ToDict()
821 5d28cb6f Michael Hanselmann
822 1c8addc6 Michael Hanselmann
    iqd = query.InstanceQueryData(instances, cluster, disk_usage,
823 e431074f René Nussbaumer
                                  offline_nodes, bad_nodes, live_data,
824 fab9573b Michael Hanselmann
                                  wrongnode_inst, consinfo, {}, {})
825 1c8addc6 Michael Hanselmann
    result = q.Query(iqd)
826 1c8addc6 Michael Hanselmann
    self.assertEqual(len(result), len(instances))
827 1c8addc6 Michael Hanselmann
    self.assert_(compat.all(len(row) == len(selected)
828 1c8addc6 Michael Hanselmann
                            for row in result))
829 1c8addc6 Michael Hanselmann
830 1c8addc6 Michael Hanselmann
    assert len(set(bad_nodes) & set(offline_nodes)) == len(offline_nodes), \
831 1c8addc6 Michael Hanselmann
           "Offline nodes not included in bad nodes"
832 1c8addc6 Michael Hanselmann
833 1c8addc6 Michael Hanselmann
    tested_status = set()
834 1c8addc6 Michael Hanselmann
835 1c8addc6 Michael Hanselmann
    for (inst, row) in zip(instances, result):
836 1c8addc6 Michael Hanselmann
      assert inst.primary_node in nodes
837 1c8addc6 Michael Hanselmann
838 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["name"]],
839 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, inst.name))
840 1c8addc6 Michael Hanselmann
841 1c8addc6 Michael Hanselmann
      if inst.primary_node in offline_nodes:
842 61a980a9 Michael Hanselmann
        exp_status = constants.INSTST_NODEOFFLINE
843 1c8addc6 Michael Hanselmann
      elif inst.primary_node in bad_nodes:
844 61a980a9 Michael Hanselmann
        exp_status = constants.INSTST_NODEDOWN
845 1c8addc6 Michael Hanselmann
      elif inst.name in live_data:
846 e431074f René Nussbaumer
        if inst.name in wrongnode_inst:
847 61a980a9 Michael Hanselmann
          exp_status = constants.INSTST_WRONGNODE
848 2e04d454 Agata Murawska
        elif inst.admin_state == constants.ADMINST_UP:
849 61a980a9 Michael Hanselmann
          exp_status = constants.INSTST_RUNNING
850 1c8addc6 Michael Hanselmann
        else:
851 61a980a9 Michael Hanselmann
          exp_status = constants.INSTST_ERRORUP
852 2e04d454 Agata Murawska
      elif inst.admin_state == constants.ADMINST_UP:
853 61a980a9 Michael Hanselmann
        exp_status = constants.INSTST_ERRORDOWN
854 2e04d454 Agata Murawska
      elif inst.admin_state == constants.ADMINST_DOWN:
855 61a980a9 Michael Hanselmann
        exp_status = constants.INSTST_ADMINDOWN
856 2e04d454 Agata Murawska
      else:
857 2e04d454 Agata Murawska
        exp_status = constants.INSTST_ADMINOFFLINE
858 1c8addc6 Michael Hanselmann
859 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["status"]],
860 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, exp_status))
861 1c8addc6 Michael Hanselmann
862 1c8addc6 Michael Hanselmann
      (_, status) = row[fieldidx["status"]]
863 1c8addc6 Michael Hanselmann
      tested_status.add(status)
864 1c8addc6 Michael Hanselmann
865 861610e9 Guido Trotter
      #FIXME(dynmem): check oper_ram vs min/max mem
866 861610e9 Guido Trotter
      for (field, livefield) in [("oper_vcpus", "vcpus")]:
867 1c8addc6 Michael Hanselmann
        if inst.primary_node in bad_nodes:
868 cfb084ae René Nussbaumer
          exp = (constants.RS_NODATA, None)
869 1c8addc6 Michael Hanselmann
        elif inst.name in live_data:
870 1c8addc6 Michael Hanselmann
          value = live_data[inst.name].get(livefield, None)
871 1c8addc6 Michael Hanselmann
          if value is None:
872 cfb084ae René Nussbaumer
            exp = (constants.RS_UNAVAIL, None)
873 1c8addc6 Michael Hanselmann
          else:
874 cfb084ae René Nussbaumer
            exp = (constants.RS_NORMAL, value)
875 1c8addc6 Michael Hanselmann
        else:
876 cfb084ae René Nussbaumer
          exp = (constants.RS_UNAVAIL, None)
877 1c8addc6 Michael Hanselmann
878 1c8addc6 Michael Hanselmann
        self.assertEqual(row[fieldidx[field]], exp)
879 1c8addc6 Michael Hanselmann
880 1c8addc6 Michael Hanselmann
      bridges = inst_bridges.get(inst.name, [])
881 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["nic.bridges"]],
882 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, bridges))
883 1c8addc6 Michael Hanselmann
      if bridges:
884 1c8addc6 Michael Hanselmann
        self.assertEqual(row[fieldidx["bridge"]],
885 cfb084ae René Nussbaumer
                         (constants.RS_NORMAL, bridges[0]))
886 1c8addc6 Michael Hanselmann
      else:
887 1c8addc6 Michael Hanselmann
        self.assertEqual(row[fieldidx["bridge"]],
888 cfb084ae René Nussbaumer
                         (constants.RS_UNAVAIL, None))
889 1c8addc6 Michael Hanselmann
890 1c8addc6 Michael Hanselmann
      for i in range(constants.MAX_NICS):
891 1c8addc6 Michael Hanselmann
        if i < len(bridges) and bridges[i] is not None:
892 cfb084ae René Nussbaumer
          exp = (constants.RS_NORMAL, bridges[i])
893 1c8addc6 Michael Hanselmann
        else:
894 cfb084ae René Nussbaumer
          exp = (constants.RS_UNAVAIL, None)
895 1c8addc6 Michael Hanselmann
        self.assertEqual(row[fieldidx["nic.bridge/%s" % i]], exp)
896 1c8addc6 Michael Hanselmann
897 1c8addc6 Michael Hanselmann
      if inst.primary_node in bad_nodes:
898 cfb084ae René Nussbaumer
        exp = (constants.RS_NODATA, None)
899 1c8addc6 Michael Hanselmann
      else:
900 cfb084ae René Nussbaumer
        exp = (constants.RS_NORMAL, inst.name in live_data)
901 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["oper_state"]], exp)
902 1c8addc6 Michael Hanselmann
903 7c670076 Michael Hanselmann
      cust_exp = (constants.RS_NORMAL, {})
904 7c670076 Michael Hanselmann
      if inst.os == "deb99":
905 7c670076 Michael Hanselmann
        if inst.name == "inst6":
906 7c670076 Michael Hanselmann
          exp = (constants.RS_NORMAL, {"clean_install": "no"})
907 7c670076 Michael Hanselmann
          cust_exp = exp
908 7c670076 Michael Hanselmann
        else:
909 7c670076 Michael Hanselmann
          exp = (constants.RS_NORMAL, {"clean_install": "yes"})
910 7c670076 Michael Hanselmann
      else:
911 7c670076 Michael Hanselmann
        exp = (constants.RS_NORMAL, {})
912 7c670076 Michael Hanselmann
      self.assertEqual(row[fieldidx["osparams"]], exp)
913 7c670076 Michael Hanselmann
      self.assertEqual(row[fieldidx["custom_osparams"]], cust_exp)
914 7c670076 Michael Hanselmann
915 1c8addc6 Michael Hanselmann
      usage = disk_usage[inst.name]
916 1c8addc6 Michael Hanselmann
      if usage is None:
917 1c8addc6 Michael Hanselmann
        usage = 0
918 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["disk_usage"]],
919 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, usage))
920 1c8addc6 Michael Hanselmann
921 4cc4d1fa Michael Hanselmann
      for alias, target in [("sda_size", "disk.size/0"),
922 4cc4d1fa Michael Hanselmann
                            ("sdb_size", "disk.size/1"),
923 4cc4d1fa Michael Hanselmann
                            ("vcpus", "be/vcpus"),
924 4cc4d1fa Michael Hanselmann
                            ("ip", "nic.ip/0"),
925 4cc4d1fa Michael Hanselmann
                            ("mac", "nic.mac/0"),
926 4cc4d1fa Michael Hanselmann
                            ("bridge", "nic.bridge/0"),
927 4cc4d1fa Michael Hanselmann
                            ("nic_mode", "nic.mode/0"),
928 4cc4d1fa Michael Hanselmann
                            ("nic_link", "nic.link/0"),
929 4cc4d1fa Michael Hanselmann
                            ]:
930 4cc4d1fa Michael Hanselmann
        self.assertEqual(row[fieldidx[alias]], row[fieldidx[target]])
931 1c8addc6 Michael Hanselmann
932 145bea54 Michael Hanselmann
      for field in ["ctime", "mtime"]:
933 145bea54 Michael Hanselmann
        if getattr(inst, field) is None:
934 145bea54 Michael Hanselmann
          # No ctime/mtime
935 cfb084ae René Nussbaumer
          exp = (constants.RS_UNAVAIL, None)
936 145bea54 Michael Hanselmann
        else:
937 cfb084ae René Nussbaumer
          exp = (constants.RS_NORMAL, getattr(inst, field))
938 145bea54 Michael Hanselmann
        self.assertEqual(row[fieldidx[field]], exp)
939 145bea54 Michael Hanselmann
940 5d28cb6f Michael Hanselmann
      self._CheckInstanceConsole(inst, row[fieldidx["console"]])
941 5d28cb6f Michael Hanselmann
942 1c8addc6 Michael Hanselmann
    # Ensure all possible status' have been tested
943 61a980a9 Michael Hanselmann
    self.assertEqual(tested_status, constants.INSTST_ALL)
944 1c8addc6 Michael Hanselmann
945 5d28cb6f Michael Hanselmann
  def _CheckInstanceConsole(self, instance, (status, consdata)):
946 5d28cb6f Michael Hanselmann
    if instance.name == "inst7":
947 5d28cb6f Michael Hanselmann
      self.assertEqual(status, constants.RS_NORMAL)
948 5d28cb6f Michael Hanselmann
      console = objects.InstanceConsole.FromDict(consdata)
949 5d28cb6f Michael Hanselmann
      self.assertTrue(console.Validate())
950 5d28cb6f Michael Hanselmann
      self.assertEqual(console.host, instance.primary_node)
951 5d28cb6f Michael Hanselmann
    else:
952 5d28cb6f Michael Hanselmann
      self.assertEqual(status, constants.RS_UNAVAIL)
953 5d28cb6f Michael Hanselmann
954 1c8addc6 Michael Hanselmann
955 d8b7ff5f Adeodato Simo
class TestGroupQuery(unittest.TestCase):
956 d8b7ff5f Adeodato Simo
957 d8b7ff5f Adeodato Simo
  def setUp(self):
958 d3b51156 René Nussbaumer
    self.custom_diskparams = {
959 d3b51156 René Nussbaumer
      constants.DT_DRBD8: {
960 d3b51156 René Nussbaumer
        constants.DRBD_DEFAULT_METAVG: "foobar",
961 d3b51156 René Nussbaumer
      },
962 d3b51156 René Nussbaumer
    }
963 d3b51156 René Nussbaumer
964 d8b7ff5f Adeodato Simo
    self.groups = [
965 d8b7ff5f Adeodato Simo
      objects.NodeGroup(name="default",
966 d8b7ff5f Adeodato Simo
                        uuid="c0e89160-18e7-11e0-a46e-001d0904baeb",
967 edd49f9b Agata Murawska
                        alloc_policy=constants.ALLOC_POLICY_PREFERRED,
968 8930b0f0 Iustin Pop
                        ipolicy=objects.MakeEmptyIPolicy(),
969 8930b0f0 Iustin Pop
                        ndparams={},
970 2c758845 René Nussbaumer
                        diskparams={},
971 8930b0f0 Iustin Pop
                        ),
972 d8b7ff5f Adeodato Simo
      objects.NodeGroup(name="restricted",
973 d8b7ff5f Adeodato Simo
                        uuid="d2a40a74-18e7-11e0-9143-001d0904baeb",
974 edd49f9b Agata Murawska
                        alloc_policy=constants.ALLOC_POLICY_LAST_RESORT,
975 8930b0f0 Iustin Pop
                        ipolicy=objects.MakeEmptyIPolicy(),
976 2c758845 René Nussbaumer
                        ndparams={},
977 d3b51156 René Nussbaumer
                        diskparams=self.custom_diskparams,
978 8930b0f0 Iustin Pop
                        ),
979 d8b7ff5f Adeodato Simo
      ]
980 edd49f9b Agata Murawska
    self.cluster = objects.Cluster(cluster_name="testcluster",
981 edd49f9b Agata Murawska
      hvparams=constants.HVC_DEFAULTS,
982 edd49f9b Agata Murawska
      beparams={
983 edd49f9b Agata Murawska
        constants.PP_DEFAULT: constants.BEC_DEFAULTS,
984 edd49f9b Agata Murawska
        },
985 edd49f9b Agata Murawska
      nicparams={
986 edd49f9b Agata Murawska
        constants.PP_DEFAULT: constants.NICC_DEFAULTS,
987 edd49f9b Agata Murawska
        },
988 edd49f9b Agata Murawska
      ndparams=constants.NDC_DEFAULTS,
989 edd49f9b Agata Murawska
      ipolicy=constants.IPOLICY_DEFAULTS,
990 2c758845 René Nussbaumer
      diskparams=constants.DISK_DT_DEFAULTS,
991 edd49f9b Agata Murawska
      )
992 d8b7ff5f Adeodato Simo
993 d8b7ff5f Adeodato Simo
  def _Create(self, selected):
994 d8b7ff5f Adeodato Simo
    return query.Query(query.GROUP_FIELDS, selected)
995 d8b7ff5f Adeodato Simo
996 d8b7ff5f Adeodato Simo
  def testSimple(self):
997 d8b7ff5f Adeodato Simo
    q = self._Create(["name", "uuid", "alloc_policy"])
998 2c758845 René Nussbaumer
    gqd = query.GroupQueryData(self.cluster, self.groups, None, None, False)
999 d8b7ff5f Adeodato Simo
1000 d8b7ff5f Adeodato Simo
    self.assertEqual(q.RequestedData(), set([query.GQ_CONFIG]))
1001 d8b7ff5f Adeodato Simo
1002 d8b7ff5f Adeodato Simo
    self.assertEqual(q.Query(gqd),
1003 cfb084ae René Nussbaumer
      [[(constants.RS_NORMAL, "default"),
1004 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, "c0e89160-18e7-11e0-a46e-001d0904baeb"),
1005 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, constants.ALLOC_POLICY_PREFERRED)
1006 d8b7ff5f Adeodato Simo
        ],
1007 cfb084ae René Nussbaumer
       [(constants.RS_NORMAL, "restricted"),
1008 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, "d2a40a74-18e7-11e0-9143-001d0904baeb"),
1009 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, constants.ALLOC_POLICY_LAST_RESORT)
1010 d8b7ff5f Adeodato Simo
        ],
1011 d8b7ff5f Adeodato Simo
       ])
1012 d8b7ff5f Adeodato Simo
1013 d8b7ff5f Adeodato Simo
  def testNodes(self):
1014 d8b7ff5f Adeodato Simo
    groups_to_nodes = {
1015 d8b7ff5f Adeodato Simo
      "c0e89160-18e7-11e0-a46e-001d0904baeb": ["node1", "node2"],
1016 d8b7ff5f Adeodato Simo
      "d2a40a74-18e7-11e0-9143-001d0904baeb": ["node1", "node10", "node9"],
1017 d8b7ff5f Adeodato Simo
      }
1018 d8b7ff5f Adeodato Simo
1019 d8b7ff5f Adeodato Simo
    q = self._Create(["name", "node_cnt", "node_list"])
1020 2c758845 René Nussbaumer
    gqd = query.GroupQueryData(self.cluster, self.groups, groups_to_nodes, None,
1021 2c758845 René Nussbaumer
                               False)
1022 d8b7ff5f Adeodato Simo
1023 d8b7ff5f Adeodato Simo
    self.assertEqual(q.RequestedData(), set([query.GQ_CONFIG, query.GQ_NODE]))
1024 d8b7ff5f Adeodato Simo
1025 d8b7ff5f Adeodato Simo
    self.assertEqual(q.Query(gqd),
1026 cfb084ae René Nussbaumer
                     [[(constants.RS_NORMAL, "default"),
1027 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 2),
1028 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, ["node1", "node2"]),
1029 d8b7ff5f Adeodato Simo
                       ],
1030 cfb084ae René Nussbaumer
                      [(constants.RS_NORMAL, "restricted"),
1031 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 3),
1032 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, ["node1", "node9", "node10"]),
1033 d8b7ff5f Adeodato Simo
                       ],
1034 d8b7ff5f Adeodato Simo
                      ])
1035 d8b7ff5f Adeodato Simo
1036 d8b7ff5f Adeodato Simo
  def testInstances(self):
1037 d8b7ff5f Adeodato Simo
    groups_to_instances = {
1038 d8b7ff5f Adeodato Simo
      "c0e89160-18e7-11e0-a46e-001d0904baeb": ["inst1", "inst2"],
1039 d8b7ff5f Adeodato Simo
      "d2a40a74-18e7-11e0-9143-001d0904baeb": ["inst1", "inst10", "inst9"],
1040 d8b7ff5f Adeodato Simo
      }
1041 d8b7ff5f Adeodato Simo
1042 d8b7ff5f Adeodato Simo
    q = self._Create(["pinst_cnt", "pinst_list"])
1043 edd49f9b Agata Murawska
    gqd = query.GroupQueryData(self.cluster, self.groups, None,
1044 2c758845 René Nussbaumer
      groups_to_instances, False)
1045 d8b7ff5f Adeodato Simo
1046 d8b7ff5f Adeodato Simo
    self.assertEqual(q.RequestedData(), set([query.GQ_INST]))
1047 d8b7ff5f Adeodato Simo
1048 d8b7ff5f Adeodato Simo
    self.assertEqual(q.Query(gqd),
1049 cfb084ae René Nussbaumer
                     [[(constants.RS_NORMAL, 2),
1050 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, ["inst1", "inst2"]),
1051 d8b7ff5f Adeodato Simo
                       ],
1052 cfb084ae René Nussbaumer
                      [(constants.RS_NORMAL, 3),
1053 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, ["inst1", "inst9", "inst10"]),
1054 d8b7ff5f Adeodato Simo
                       ],
1055 d8b7ff5f Adeodato Simo
                      ])
1056 d8b7ff5f Adeodato Simo
1057 d3b51156 René Nussbaumer
  def testDiskparams(self):
1058 d3b51156 René Nussbaumer
    q = self._Create(["name", "uuid", "diskparams", "custom_diskparams"])
1059 d3b51156 René Nussbaumer
    gqd = query.GroupQueryData(self.cluster, self.groups, None, None, True)
1060 d3b51156 René Nussbaumer
1061 d3b51156 René Nussbaumer
    self.assertEqual(q.RequestedData(),
1062 d3b51156 René Nussbaumer
                     set([query.GQ_CONFIG, query.GQ_DISKPARAMS]))
1063 d3b51156 René Nussbaumer
1064 d3b51156 René Nussbaumer
    self.assertEqual(q.Query(gqd),
1065 d3b51156 René Nussbaumer
      [[(constants.RS_NORMAL, "default"),
1066 d3b51156 René Nussbaumer
        (constants.RS_NORMAL, "c0e89160-18e7-11e0-a46e-001d0904baeb"),
1067 d3b51156 René Nussbaumer
        (constants.RS_NORMAL, constants.DISK_DT_DEFAULTS),
1068 d3b51156 René Nussbaumer
        (constants.RS_NORMAL, {}),
1069 d3b51156 René Nussbaumer
        ],
1070 d3b51156 René Nussbaumer
       [(constants.RS_NORMAL, "restricted"),
1071 d3b51156 René Nussbaumer
        (constants.RS_NORMAL, "d2a40a74-18e7-11e0-9143-001d0904baeb"),
1072 d3b51156 René Nussbaumer
        (constants.RS_NORMAL, objects.FillDiskParams(constants.DISK_DT_DEFAULTS,
1073 d3b51156 René Nussbaumer
                                                     self.custom_diskparams)),
1074 d3b51156 René Nussbaumer
        (constants.RS_NORMAL, self.custom_diskparams),
1075 d3b51156 René Nussbaumer
        ],
1076 d3b51156 René Nussbaumer
       ])
1077 d3b51156 René Nussbaumer
1078 d8b7ff5f Adeodato Simo
1079 be3a4b14 Michael Hanselmann
class TestOsQuery(unittest.TestCase):
1080 be3a4b14 Michael Hanselmann
  def _Create(self, selected):
1081 be3a4b14 Michael Hanselmann
    return query.Query(query.OS_FIELDS, selected)
1082 be3a4b14 Michael Hanselmann
1083 be3a4b14 Michael Hanselmann
  def test(self):
1084 be3a4b14 Michael Hanselmann
    variants = ["v00", "plain", "v3", "var0", "v33", "v20"]
1085 be3a4b14 Michael Hanselmann
    api_versions = [10, 0, 15, 5]
1086 be3a4b14 Michael Hanselmann
    parameters = ["zpar3", "apar9"]
1087 be3a4b14 Michael Hanselmann
1088 be3a4b14 Michael Hanselmann
    assert variants != sorted(variants) and variants != utils.NiceSort(variants)
1089 be3a4b14 Michael Hanselmann
    assert (api_versions != sorted(api_versions) and
1090 be3a4b14 Michael Hanselmann
            api_versions != utils.NiceSort(variants))
1091 be3a4b14 Michael Hanselmann
    assert (parameters != sorted(parameters) and
1092 be3a4b14 Michael Hanselmann
            parameters != utils.NiceSort(parameters))
1093 be3a4b14 Michael Hanselmann
1094 be3a4b14 Michael Hanselmann
    data = [
1095 be3a4b14 Michael Hanselmann
      query.OsInfo(name="debian", valid=False, hidden=False, blacklisted=False,
1096 be3a4b14 Michael Hanselmann
                   variants=set(), api_versions=set(), parameters=set(),
1097 be3a4b14 Michael Hanselmann
                   node_status={ "some": "status", }),
1098 be3a4b14 Michael Hanselmann
      query.OsInfo(name="dos", valid=True, hidden=False, blacklisted=True,
1099 be3a4b14 Michael Hanselmann
                   variants=set(variants),
1100 be3a4b14 Michael Hanselmann
                   api_versions=set(api_versions),
1101 be3a4b14 Michael Hanselmann
                   parameters=set(parameters),
1102 be3a4b14 Michael Hanselmann
                   node_status={ "some": "other", "status": None, }),
1103 be3a4b14 Michael Hanselmann
      ]
1104 be3a4b14 Michael Hanselmann
1105 be3a4b14 Michael Hanselmann
1106 be3a4b14 Michael Hanselmann
    q = self._Create(["name", "valid", "hidden", "blacklisted", "variants",
1107 be3a4b14 Michael Hanselmann
                      "api_versions", "parameters", "node_status"])
1108 be3a4b14 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([]))
1109 be3a4b14 Michael Hanselmann
    self.assertEqual(q.Query(data),
1110 be3a4b14 Michael Hanselmann
                     [[(constants.RS_NORMAL, "debian"),
1111 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, False),
1112 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, False),
1113 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, False),
1114 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, []),
1115 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, []),
1116 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, []),
1117 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, {"some": "status"})],
1118 be3a4b14 Michael Hanselmann
                      [(constants.RS_NORMAL, "dos"),
1119 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, True),
1120 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, False),
1121 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, True),
1122 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL,
1123 be3a4b14 Michael Hanselmann
                        ["plain", "v00", "v3", "v20", "v33", "var0"]),
1124 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, [0, 5, 10, 15]),
1125 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, ["apar9", "zpar3"]),
1126 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL,
1127 be3a4b14 Michael Hanselmann
                        { "some": "other", "status": None, })
1128 be3a4b14 Michael Hanselmann
                       ]])
1129 be3a4b14 Michael Hanselmann
1130 be3a4b14 Michael Hanselmann
1131 aa29e95f Michael Hanselmann
class TestQueryFields(unittest.TestCase):
1132 aa29e95f Michael Hanselmann
  def testAllFields(self):
1133 e571ee44 Adeodato Simo
    for fielddefs in query.ALL_FIELD_LISTS:
1134 aa29e95f Michael Hanselmann
      result = query.QueryFields(fielddefs, None)
1135 aa29e95f Michael Hanselmann
      self.assert_(isinstance(result, dict))
1136 aa29e95f Michael Hanselmann
      response = objects.QueryFieldsResponse.FromDict(result)
1137 aa29e95f Michael Hanselmann
      self.assertEqual([(fdef.name, fdef.title) for fdef in response.fields],
1138 aa29e95f Michael Hanselmann
        [(fdef2.name, fdef2.title)
1139 111bf531 Michael Hanselmann
         for (fdef2, _, _, _) in utils.NiceSort(fielddefs.values(),
1140 111bf531 Michael Hanselmann
                                                key=lambda x: x[0].name)])
1141 aa29e95f Michael Hanselmann
1142 aa29e95f Michael Hanselmann
  def testSomeFields(self):
1143 aa29e95f Michael Hanselmann
    rnd = random.Random(5357)
1144 aa29e95f Michael Hanselmann
1145 aa29e95f Michael Hanselmann
    for _ in range(10):
1146 e571ee44 Adeodato Simo
      for fielddefs in query.ALL_FIELD_LISTS:
1147 e571ee44 Adeodato Simo
        if len(fielddefs) > 20:
1148 e571ee44 Adeodato Simo
          sample_size = rnd.randint(5, 20)
1149 e571ee44 Adeodato Simo
        else:
1150 e571ee44 Adeodato Simo
          sample_size = rnd.randint(1, max(1, len(fielddefs) - 1))
1151 111bf531 Michael Hanselmann
        fields = [fdef for (fdef, _, _, _) in rnd.sample(fielddefs.values(),
1152 111bf531 Michael Hanselmann
                                                         sample_size)]
1153 aa29e95f Michael Hanselmann
        result = query.QueryFields(fielddefs, [fdef.name for fdef in fields])
1154 aa29e95f Michael Hanselmann
        self.assert_(isinstance(result, dict))
1155 aa29e95f Michael Hanselmann
        response = objects.QueryFieldsResponse.FromDict(result)
1156 aa29e95f Michael Hanselmann
        self.assertEqual([(fdef.name, fdef.title) for fdef in response.fields],
1157 aa29e95f Michael Hanselmann
                         [(fdef2.name, fdef2.title) for fdef2 in fields])
1158 aa29e95f Michael Hanselmann
1159 aa29e95f Michael Hanselmann
1160 fb0be379 Michael Hanselmann
class TestQueryFilter(unittest.TestCase):
1161 fb0be379 Michael Hanselmann
  def testRequestedNames(self):
1162 0fdf247d Michael Hanselmann
    for (what, fielddefs) in query.ALL_FIELDS.items():
1163 0fdf247d Michael Hanselmann
      if what == constants.QR_JOB:
1164 d6f58310 Michael Hanselmann
        namefield = "id"
1165 0fdf247d Michael Hanselmann
      elif what == constants.QR_EXPORT:
1166 0fdf247d Michael Hanselmann
        namefield = "export"
1167 d6f58310 Michael Hanselmann
      else:
1168 d6f58310 Michael Hanselmann
        namefield = "name"
1169 d6f58310 Michael Hanselmann
1170 d6f58310 Michael Hanselmann
      assert namefield in fielddefs
1171 d6f58310 Michael Hanselmann
1172 d6f58310 Michael Hanselmann
      innerfilter = [["=", namefield, "x%s" % i] for i in range(4)]
1173 fb0be379 Michael Hanselmann
1174 fb0be379 Michael Hanselmann
      # No name field
1175 d6f58310 Michael Hanselmann
      q = query.Query(fielddefs, [namefield], qfilter=["=", namefield, "abc"],
1176 fb0be379 Michael Hanselmann
                      namefield=None)
1177 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), None)
1178 fb0be379 Michael Hanselmann
1179 fb0be379 Michael Hanselmann
      # No filter
1180 d6f58310 Michael Hanselmann
      q = query.Query(fielddefs, [namefield], qfilter=None, namefield=namefield)
1181 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), None)
1182 fb0be379 Michael Hanselmann
1183 fb0be379 Michael Hanselmann
      # Check empty query
1184 d6f58310 Michael Hanselmann
      q = query.Query(fielddefs, [namefield], qfilter=["|"],
1185 d6f58310 Michael Hanselmann
                      namefield=namefield)
1186 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), None)
1187 fb0be379 Michael Hanselmann
1188 fb0be379 Michael Hanselmann
      # Check order
1189 d6f58310 Michael Hanselmann
      q = query.Query(fielddefs, [namefield], qfilter=["|"] + innerfilter,
1190 d6f58310 Michael Hanselmann
                      namefield=namefield)
1191 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), ["x0", "x1", "x2", "x3"])
1192 fb0be379 Michael Hanselmann
1193 fb0be379 Michael Hanselmann
      # Check reverse order
1194 d6f58310 Michael Hanselmann
      q = query.Query(fielddefs, [namefield],
1195 2e5c33db Iustin Pop
                      qfilter=["|"] + list(reversed(innerfilter)),
1196 d6f58310 Michael Hanselmann
                      namefield=namefield)
1197 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), ["x3", "x2", "x1", "x0"])
1198 fb0be379 Michael Hanselmann
1199 fb0be379 Michael Hanselmann
      # Duplicates
1200 d6f58310 Michael Hanselmann
      q = query.Query(fielddefs, [namefield],
1201 2e5c33db Iustin Pop
                      qfilter=["|"] + innerfilter + list(reversed(innerfilter)),
1202 d6f58310 Michael Hanselmann
                      namefield=namefield)
1203 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), ["x0", "x1", "x2", "x3"])
1204 fb0be379 Michael Hanselmann
1205 fb0be379 Michael Hanselmann
      # Unknown name field
1206 d6f58310 Michael Hanselmann
      self.assertRaises(AssertionError, query.Query, fielddefs, [namefield],
1207 fb0be379 Michael Hanselmann
                        namefield="_unknown_field_")
1208 fb0be379 Michael Hanselmann
1209 fb0be379 Michael Hanselmann
      # Filter with AND
1210 d6f58310 Michael Hanselmann
      q = query.Query(fielddefs, [namefield],
1211 d6f58310 Michael Hanselmann
                      qfilter=["|", ["=", namefield, "foo"],
1212 d6f58310 Michael Hanselmann
                                    ["&", ["=", namefield, ""]]],
1213 d6f58310 Michael Hanselmann
                      namefield=namefield)
1214 fb0be379 Michael Hanselmann
      self.assertTrue(q.RequestedNames() is None)
1215 fb0be379 Michael Hanselmann
1216 fb0be379 Michael Hanselmann
      # Filter with NOT
1217 d6f58310 Michael Hanselmann
      q = query.Query(fielddefs, [namefield],
1218 d6f58310 Michael Hanselmann
                      qfilter=["|", ["=", namefield, "foo"],
1219 d6f58310 Michael Hanselmann
                                    ["!", ["=", namefield, ""]]],
1220 d6f58310 Michael Hanselmann
                      namefield=namefield)
1221 fb0be379 Michael Hanselmann
      self.assertTrue(q.RequestedNames() is None)
1222 fb0be379 Michael Hanselmann
1223 fb0be379 Michael Hanselmann
      # Filter with only OR (names must be in correct order)
1224 d6f58310 Michael Hanselmann
      q = query.Query(fielddefs, [namefield],
1225 d6f58310 Michael Hanselmann
                      qfilter=["|", ["=", namefield, "x17361"],
1226 d6f58310 Michael Hanselmann
                                    ["|", ["=", namefield, "x22015"]],
1227 d6f58310 Michael Hanselmann
                                    ["|", ["|", ["=", namefield, "x13193"]]],
1228 d6f58310 Michael Hanselmann
                                    ["=", namefield, "x15215"]],
1229 d6f58310 Michael Hanselmann
                      namefield=namefield)
1230 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(),
1231 fb0be379 Michael Hanselmann
                       ["x17361", "x22015", "x13193", "x15215"])
1232 fb0be379 Michael Hanselmann
1233 fb0be379 Michael Hanselmann
  @staticmethod
1234 d6f58310 Michael Hanselmann
  def _GenNestedFilter(namefield, op, depth):
1235 d6f58310 Michael Hanselmann
    nested = ["=", namefield, "value"]
1236 fb0be379 Michael Hanselmann
    for i in range(depth):
1237 fb0be379 Michael Hanselmann
      nested = [op, nested]
1238 fb0be379 Michael Hanselmann
    return nested
1239 fb0be379 Michael Hanselmann
1240 fb0be379 Michael Hanselmann
  def testCompileFilter(self):
1241 fb0be379 Michael Hanselmann
    levels_max = query._FilterCompilerHelper._LEVELS_MAX
1242 fb0be379 Michael Hanselmann
1243 0fdf247d Michael Hanselmann
    for (what, fielddefs) in query.ALL_FIELDS.items():
1244 0fdf247d Michael Hanselmann
      if what == constants.QR_JOB:
1245 d6f58310 Michael Hanselmann
        namefield = "id"
1246 0fdf247d Michael Hanselmann
      elif what == constants.QR_EXPORT:
1247 0fdf247d Michael Hanselmann
        namefield = "export"
1248 d6f58310 Michael Hanselmann
      else:
1249 d6f58310 Michael Hanselmann
        namefield = "name"
1250 d6f58310 Michael Hanselmann
1251 d6f58310 Michael Hanselmann
      checks = [
1252 d6f58310 Michael Hanselmann
        [], ["="], ["=", "foo"], ["unknownop"], ["!"],
1253 d6f58310 Michael Hanselmann
        ["=", "_unknown_field", "value"],
1254 d6f58310 Michael Hanselmann
        self._GenNestedFilter(namefield, "|", levels_max),
1255 d6f58310 Michael Hanselmann
        self._GenNestedFilter(namefield, "|", levels_max * 3),
1256 d6f58310 Michael Hanselmann
        self._GenNestedFilter(namefield, "!", levels_max),
1257 d6f58310 Michael Hanselmann
        ]
1258 d6f58310 Michael Hanselmann
1259 2e5c33db Iustin Pop
      for qfilter in checks:
1260 fb0be379 Michael Hanselmann
        self.assertRaises(errors.ParameterError, query._CompileFilter,
1261 2e5c33db Iustin Pop
                          fielddefs, None, qfilter)
1262 fb0be379 Michael Hanselmann
1263 fb0be379 Michael Hanselmann
      for op in ["|", "!"]:
1264 d6f58310 Michael Hanselmann
        qfilter = self._GenNestedFilter(namefield, op, levels_max - 1)
1265 fb0be379 Michael Hanselmann
        self.assertTrue(callable(query._CompileFilter(fielddefs, None,
1266 2e5c33db Iustin Pop
                                                      qfilter)))
1267 fb0be379 Michael Hanselmann
1268 fb0be379 Michael Hanselmann
  def testQueryInputOrder(self):
1269 fb0be379 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1270 fb0be379 Michael Hanselmann
      (query._MakeField("pnode", "PNode", constants.QFT_TEXT, "Primary"),
1271 fb0be379 Michael Hanselmann
       None, 0, lambda ctx, item: item["pnode"]),
1272 fb0be379 Michael Hanselmann
      (query._MakeField("snode", "SNode", constants.QFT_TEXT, "Secondary"),
1273 fb0be379 Michael Hanselmann
       None, 0, lambda ctx, item: item["snode"]),
1274 fb0be379 Michael Hanselmann
      ], [])
1275 fb0be379 Michael Hanselmann
1276 fb0be379 Michael Hanselmann
    data = [
1277 fb0be379 Michael Hanselmann
      { "pnode": "node1", "snode": "node44", },
1278 fb0be379 Michael Hanselmann
      { "pnode": "node30", "snode": "node90", },
1279 fb0be379 Michael Hanselmann
      { "pnode": "node25", "snode": "node1", },
1280 fb0be379 Michael Hanselmann
      { "pnode": "node20", "snode": "node1", },
1281 fb0be379 Michael Hanselmann
      ]
1282 fb0be379 Michael Hanselmann
1283 2e5c33db Iustin Pop
    qfilter = ["|", ["=", "pnode", "node1"], ["=", "snode", "node1"]]
1284 fb0be379 Michael Hanselmann
1285 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "snode"], namefield="pnode",
1286 2e5c33db Iustin Pop
                    qfilter=qfilter)
1287 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1288 fb0be379 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1289 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1290 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")],
1291 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")],
1292 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")]])
1293 fb0be379 Michael Hanselmann
1294 fb0be379 Michael Hanselmann
    # Try again with reversed input data
1295 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(reversed(data)),
1296 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")],
1297 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")],
1298 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")]])
1299 fb0be379 Michael Hanselmann
1300 fb0be379 Michael Hanselmann
    # No name field, result must be in incoming order
1301 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "snode"], namefield=None,
1302 2e5c33db Iustin Pop
                    qfilter=qfilter)
1303 fb0be379 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1304 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1305 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")],
1306 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")],
1307 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")]])
1308 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1309 fb0be379 Michael Hanselmann
      ["node1", "node44"],
1310 fb0be379 Michael Hanselmann
      ["node25", "node1"],
1311 fb0be379 Michael Hanselmann
      ["node20", "node1"],
1312 fb0be379 Michael Hanselmann
      ])
1313 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(reversed(data)),
1314 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")],
1315 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")],
1316 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")]])
1317 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(reversed(data)), [
1318 fb0be379 Michael Hanselmann
      ["node20", "node1"],
1319 fb0be379 Michael Hanselmann
      ["node25", "node1"],
1320 fb0be379 Michael Hanselmann
      ["node1", "node44"],
1321 fb0be379 Michael Hanselmann
      ])
1322 fb0be379 Michael Hanselmann
1323 fbc263a9 Michael Hanselmann
    # Name field, but no sorting, result must be in incoming order
1324 fbc263a9 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "snode"], namefield="pnode")
1325 fbc263a9 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1326 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data, sort_by_name=False),
1327 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")],
1328 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node30"), (constants.RS_NORMAL, "node90")],
1329 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")],
1330 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")]])
1331 fbc263a9 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data, sort_by_name=False), [
1332 fbc263a9 Michael Hanselmann
      ["node1", "node44"],
1333 fbc263a9 Michael Hanselmann
      ["node30", "node90"],
1334 fbc263a9 Michael Hanselmann
      ["node25", "node1"],
1335 fbc263a9 Michael Hanselmann
      ["node20", "node1"],
1336 fbc263a9 Michael Hanselmann
      ])
1337 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(reversed(data), sort_by_name=False),
1338 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")],
1339 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")],
1340 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node30"), (constants.RS_NORMAL, "node90")],
1341 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")]])
1342 fbc263a9 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(reversed(data), sort_by_name=False), [
1343 fbc263a9 Michael Hanselmann
      ["node20", "node1"],
1344 fbc263a9 Michael Hanselmann
      ["node25", "node1"],
1345 fbc263a9 Michael Hanselmann
      ["node30", "node90"],
1346 fbc263a9 Michael Hanselmann
      ["node1", "node44"],
1347 fbc263a9 Michael Hanselmann
      ])
1348 fbc263a9 Michael Hanselmann
1349 fbc263a9 Michael Hanselmann
  def testEqualNamesOrder(self):
1350 fbc263a9 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1351 fbc263a9 Michael Hanselmann
      (query._MakeField("pnode", "PNode", constants.QFT_TEXT, "Primary"),
1352 fbc263a9 Michael Hanselmann
       None, 0, lambda ctx, item: item["pnode"]),
1353 fbc263a9 Michael Hanselmann
      (query._MakeField("num", "Num", constants.QFT_NUMBER, "Num"),
1354 fbc263a9 Michael Hanselmann
       None, 0, lambda ctx, item: item["num"]),
1355 fbc263a9 Michael Hanselmann
      ], [])
1356 fbc263a9 Michael Hanselmann
1357 fbc263a9 Michael Hanselmann
    data = [
1358 fbc263a9 Michael Hanselmann
      { "pnode": "node1", "num": 100, },
1359 fbc263a9 Michael Hanselmann
      { "pnode": "node1", "num": 25, },
1360 fbc263a9 Michael Hanselmann
      { "pnode": "node2", "num": 90, },
1361 fbc263a9 Michael Hanselmann
      { "pnode": "node2", "num": 30, },
1362 fbc263a9 Michael Hanselmann
      ]
1363 fbc263a9 Michael Hanselmann
1364 fbc263a9 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "num"], namefield="pnode",
1365 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "pnode", "node1"],
1366 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "node2"],
1367 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "node1"]])
1368 fbc263a9 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1", "node2"],
1369 fbc263a9 Michael Hanselmann
                     msg="Did not return unique names")
1370 fbc263a9 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1371 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data),
1372 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, 100)],
1373 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, 25)],
1374 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, 90)],
1375 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, 30)]])
1376 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data, sort_by_name=False),
1377 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, 100)],
1378 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, 25)],
1379 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, 90)],
1380 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, 30)]])
1381 fbc263a9 Michael Hanselmann
1382 fbc263a9 Michael Hanselmann
    data = [
1383 fbc263a9 Michael Hanselmann
      { "pnode": "nodeX", "num": 50, },
1384 fbc263a9 Michael Hanselmann
      { "pnode": "nodeY", "num": 40, },
1385 fbc263a9 Michael Hanselmann
      { "pnode": "nodeX", "num": 30, },
1386 fbc263a9 Michael Hanselmann
      { "pnode": "nodeX", "num": 20, },
1387 fbc263a9 Michael Hanselmann
      { "pnode": "nodeM", "num": 10, },
1388 fbc263a9 Michael Hanselmann
      ]
1389 fbc263a9 Michael Hanselmann
1390 fbc263a9 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "num"], namefield="pnode",
1391 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "pnode", "nodeX"],
1392 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "nodeY"],
1393 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "nodeY"],
1394 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "nodeY"],
1395 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "nodeM"]])
1396 fbc263a9 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["nodeX", "nodeY", "nodeM"],
1397 fbc263a9 Michael Hanselmann
                     msg="Did not return unique names")
1398 fbc263a9 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1399 fbc263a9 Michael Hanselmann
1400 fbc263a9 Michael Hanselmann
    # First sorted by name, then input order
1401 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data, sort_by_name=True),
1402 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "nodeM"), (constants.RS_NORMAL, 10)],
1403 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 50)],
1404 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 30)],
1405 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 20)],
1406 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeY"), (constants.RS_NORMAL, 40)]])
1407 fbc263a9 Michael Hanselmann
1408 fbc263a9 Michael Hanselmann
    # Input order
1409 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data, sort_by_name=False),
1410 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 50)],
1411 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeY"), (constants.RS_NORMAL, 40)],
1412 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 30)],
1413 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 20)],
1414 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeM"), (constants.RS_NORMAL, 10)]])
1415 fbc263a9 Michael Hanselmann
1416 fb0be379 Michael Hanselmann
  def testFilter(self):
1417 fb0be379 Michael Hanselmann
    (DK_A, DK_B) = range(1000, 1002)
1418 fb0be379 Michael Hanselmann
1419 fb0be379 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1420 fb0be379 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1421 fb0be379 Michael Hanselmann
       DK_A, 0, lambda ctx, item: item["name"]),
1422 fb0be379 Michael Hanselmann
      (query._MakeField("other", "Other", constants.QFT_TEXT, "Other"),
1423 fb0be379 Michael Hanselmann
       DK_B, 0, lambda ctx, item: item["other"]),
1424 fb0be379 Michael Hanselmann
      ], [])
1425 fb0be379 Michael Hanselmann
1426 fb0be379 Michael Hanselmann
    data = [
1427 fb0be379 Michael Hanselmann
      { "name": "node1", "other": "foo", },
1428 fb0be379 Michael Hanselmann
      { "name": "node2", "other": "bar", },
1429 fb0be379 Michael Hanselmann
      { "name": "node3", "other": "Hello", },
1430 fb0be379 Michael Hanselmann
      ]
1431 fb0be379 Michael Hanselmann
1432 fb0be379 Michael Hanselmann
    # Empty filter
1433 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1434 2e5c33db Iustin Pop
                    qfilter=["|"])
1435 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1436 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_A, DK_B]))
1437 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [])
1438 fb0be379 Michael Hanselmann
1439 fb0be379 Michael Hanselmann
    # Normal filter
1440 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1441 2e5c33db Iustin Pop
                    qfilter=["=", "name", "node1"])
1442 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1"])
1443 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1444 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "foo")]])
1445 fb0be379 Michael Hanselmann
1446 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1447 2e5c33db Iustin Pop
                    qfilter=(["|", ["=", "name", "node1"],
1448 fb0be379 Michael Hanselmann
                                   ["=", "name", "node3"]]))
1449 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1", "node3"])
1450 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1451 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "foo")],
1452 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, "Hello")]])
1453 fb0be379 Michael Hanselmann
1454 fb0be379 Michael Hanselmann
    # Complex filter
1455 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1456 2e5c33db Iustin Pop
                    qfilter=(["|", ["=", "name", "node1"],
1457 fb0be379 Michael Hanselmann
                                   ["|", ["=", "name", "node3"],
1458 fb0be379 Michael Hanselmann
                                         ["=", "name", "node2"]],
1459 fb0be379 Michael Hanselmann
                                   ["=", "name", "node3"]]))
1460 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1", "node3", "node2"])
1461 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_A, DK_B]))
1462 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1463 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "foo")],
1464 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, "bar")],
1465 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, "Hello")]])
1466 fb0be379 Michael Hanselmann
1467 fb0be379 Michael Hanselmann
    # Filter data type mismatch
1468 fb0be379 Michael Hanselmann
    for i in [-1, 0, 1, 123, [], None, True, False]:
1469 fb0be379 Michael Hanselmann
      self.assertRaises(errors.ParameterError, query.Query,
1470 fb0be379 Michael Hanselmann
                        fielddefs, ["name", "other"], namefield="name",
1471 2e5c33db Iustin Pop
                        qfilter=["=", "name", i])
1472 fb0be379 Michael Hanselmann
1473 fb0be379 Michael Hanselmann
    # Negative filter
1474 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1475 2e5c33db Iustin Pop
                    qfilter=["!", ["|", ["=", "name", "node1"],
1476 fb0be379 Michael Hanselmann
                                        ["=", "name", "node3"]]])
1477 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1478 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1479 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, "bar")]])
1480 fb0be379 Michael Hanselmann
1481 fb0be379 Michael Hanselmann
    # Not equal
1482 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1483 2e5c33db Iustin Pop
                    qfilter=["!=", "name", "node3"])
1484 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1485 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1486 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "foo")],
1487 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, "bar")]])
1488 fb0be379 Michael Hanselmann
1489 fb0be379 Michael Hanselmann
    # Data type
1490 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, [], namefield="name",
1491 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "other", "bar"],
1492 fb0be379 Michael Hanselmann
                                  ["=", "name", "foo"]])
1493 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1494 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_A, DK_B]))
1495 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [[]])
1496 fb0be379 Michael Hanselmann
1497 fb0be379 Michael Hanselmann
    # Only one data type
1498 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["other"], namefield="name",
1499 2e5c33db Iustin Pop
                    qfilter=["=", "other", "bar"])
1500 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1501 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_B]))
1502 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [[(constants.RS_NORMAL, "bar")]])
1503 fb0be379 Michael Hanselmann
1504 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, [], namefield="name",
1505 2e5c33db Iustin Pop
                    qfilter=["=", "other", "bar"])
1506 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1507 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_B]))
1508 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [[]])
1509 fb0be379 Michael Hanselmann
1510 fb0be379 Michael Hanselmann
  def testFilterContains(self):
1511 fb0be379 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1512 fb0be379 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1513 fb0be379 Michael Hanselmann
       None, 0, lambda ctx, item: item["name"]),
1514 fb0be379 Michael Hanselmann
      (query._MakeField("other", "Other", constants.QFT_OTHER, "Other"),
1515 fb0be379 Michael Hanselmann
       None, 0, lambda ctx, item: item["other"]),
1516 fb0be379 Michael Hanselmann
      ], [])
1517 fb0be379 Michael Hanselmann
1518 fb0be379 Michael Hanselmann
    data = [
1519 fb0be379 Michael Hanselmann
      { "name": "node2", "other": ["x", "y", "bar"], },
1520 fb0be379 Michael Hanselmann
      { "name": "node3", "other": "Hello", },
1521 fb0be379 Michael Hanselmann
      { "name": "node1", "other": ["a", "b", "foo"], },
1522 3b877f08 Michael Hanselmann
      { "name": "empty", "other": []},
1523 fb0be379 Michael Hanselmann
      ]
1524 fb0be379 Michael Hanselmann
1525 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1526 2e5c33db Iustin Pop
                    qfilter=["=[]", "other", "bar"])
1527 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1528 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1529 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"),
1530 fb0be379 Michael Hanselmann
       (constants.RS_NORMAL, ["x", "y", "bar"])],
1531 fb0be379 Michael Hanselmann
      ])
1532 fb0be379 Michael Hanselmann
1533 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1534 2e5c33db Iustin Pop
                    qfilter=["|", ["=[]", "other", "bar"],
1535 fb0be379 Michael Hanselmann
                                  ["=[]", "other", "a"],
1536 fb0be379 Michael Hanselmann
                                  ["=[]", "other", "b"]])
1537 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1538 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1539 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"),
1540 fb0be379 Michael Hanselmann
       (constants.RS_NORMAL, ["a", "b", "foo"])],
1541 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"),
1542 fb0be379 Michael Hanselmann
       (constants.RS_NORMAL, ["x", "y", "bar"])],
1543 fb0be379 Michael Hanselmann
      ])
1544 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1545 fb0be379 Michael Hanselmann
      ["node1", ["a", "b", "foo"]],
1546 fb0be379 Michael Hanselmann
      ["node2", ["x", "y", "bar"]],
1547 fb0be379 Michael Hanselmann
      ])
1548 fb0be379 Michael Hanselmann
1549 3b877f08 Michael Hanselmann
    # Boolean test
1550 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1551 2e5c33db Iustin Pop
                    qfilter=["?", "other"])
1552 3b877f08 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1553 3b877f08 Michael Hanselmann
      ["node1", ["a", "b", "foo"]],
1554 3b877f08 Michael Hanselmann
      ["node2", ["x", "y", "bar"]],
1555 3b877f08 Michael Hanselmann
      ["node3", "Hello"],
1556 3b877f08 Michael Hanselmann
      ])
1557 3b877f08 Michael Hanselmann
1558 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1559 2e5c33db Iustin Pop
                    qfilter=["!", ["?", "other"]])
1560 3b877f08 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1561 3b877f08 Michael Hanselmann
      ["empty", []],
1562 3b877f08 Michael Hanselmann
      ])
1563 3b877f08 Michael Hanselmann
1564 fb0be379 Michael Hanselmann
  def testFilterHostname(self):
1565 fb0be379 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1566 fb0be379 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1567 fb0be379 Michael Hanselmann
       None, query.QFF_HOSTNAME, lambda ctx, item: item["name"]),
1568 fb0be379 Michael Hanselmann
      ], [])
1569 fb0be379 Michael Hanselmann
1570 fb0be379 Michael Hanselmann
    data = [
1571 fb0be379 Michael Hanselmann
      { "name": "node1.example.com", },
1572 fb0be379 Michael Hanselmann
      { "name": "node2.example.com", },
1573 fb0be379 Michael Hanselmann
      { "name": "node2.example.net", },
1574 fb0be379 Michael Hanselmann
      ]
1575 fb0be379 Michael Hanselmann
1576 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1577 2e5c33db Iustin Pop
                    qfilter=["=", "name", "node2"])
1578 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node2"])
1579 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1580 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.com")],
1581 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.net")],
1582 fb0be379 Michael Hanselmann
      ])
1583 fb0be379 Michael Hanselmann
1584 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1585 2e5c33db Iustin Pop
                    qfilter=["=", "name", "node1"])
1586 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1"])
1587 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1588 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node1.example.com")],
1589 fb0be379 Michael Hanselmann
      ])
1590 fb0be379 Michael Hanselmann
1591 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1592 2e5c33db Iustin Pop
                    qfilter=["=", "name", "othername"])
1593 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["othername"])
1594 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [])
1595 fb0be379 Michael Hanselmann
1596 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1597 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "name", "node1.example.com"],
1598 fb0be379 Michael Hanselmann
                                  ["=", "name", "node2"]])
1599 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1.example.com", "node2"])
1600 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1601 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node1.example.com")],
1602 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.com")],
1603 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.net")],
1604 fb0be379 Michael Hanselmann
      ])
1605 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1606 fb0be379 Michael Hanselmann
      ["node1.example.com"],
1607 fb0be379 Michael Hanselmann
      ["node2.example.com"],
1608 fb0be379 Michael Hanselmann
      ["node2.example.net"],
1609 fb0be379 Michael Hanselmann
      ])
1610 fb0be379 Michael Hanselmann
1611 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1612 2e5c33db Iustin Pop
                    qfilter=["!=", "name", "node1"])
1613 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1614 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1615 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.com")],
1616 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.net")],
1617 fb0be379 Michael Hanselmann
      ])
1618 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1619 fb0be379 Michael Hanselmann
      ["node2.example.com"],
1620 fb0be379 Michael Hanselmann
      ["node2.example.net"],
1621 fb0be379 Michael Hanselmann
      ])
1622 fb0be379 Michael Hanselmann
1623 3b877f08 Michael Hanselmann
  def testFilterBoolean(self):
1624 3b877f08 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1625 3b877f08 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1626 3b877f08 Michael Hanselmann
       None, query.QFF_HOSTNAME, lambda ctx, item: item["name"]),
1627 3b877f08 Michael Hanselmann
      (query._MakeField("value", "Value", constants.QFT_BOOL, "Value"),
1628 3b877f08 Michael Hanselmann
       None, 0, lambda ctx, item: item["value"]),
1629 3b877f08 Michael Hanselmann
      ], [])
1630 3b877f08 Michael Hanselmann
1631 3b877f08 Michael Hanselmann
    data = [
1632 3b877f08 Michael Hanselmann
      { "name": "node1", "value": False, },
1633 3b877f08 Michael Hanselmann
      { "name": "node2", "value": True, },
1634 3b877f08 Michael Hanselmann
      { "name": "node3", "value": True, },
1635 3b877f08 Michael Hanselmann
      ]
1636 3b877f08 Michael Hanselmann
1637 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "value"],
1638 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "value", False],
1639 3b877f08 Michael Hanselmann
                                  ["=", "value", True]])
1640 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1641 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1642 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, False)],
1643 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, True)],
1644 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, True)],
1645 3b877f08 Michael Hanselmann
      ])
1646 3b877f08 Michael Hanselmann
1647 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "value"],
1648 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "value", False],
1649 3b877f08 Michael Hanselmann
                                  ["!", ["=", "value", False]]])
1650 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1651 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1652 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, False)],
1653 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, True)],
1654 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, True)],
1655 3b877f08 Michael Hanselmann
      ])
1656 3b877f08 Michael Hanselmann
1657 3b877f08 Michael Hanselmann
    # Comparing bool with string
1658 3b877f08 Michael Hanselmann
    for i in ["False", "True", "0", "1", "no", "yes", "N", "Y"]:
1659 3b877f08 Michael Hanselmann
      self.assertRaises(errors.ParameterError, query.Query,
1660 3b877f08 Michael Hanselmann
                        fielddefs, ["name", "value"],
1661 2e5c33db Iustin Pop
                        qfilter=["=", "value", i])
1662 3b877f08 Michael Hanselmann
1663 3b877f08 Michael Hanselmann
    # Truth filter
1664 2e5c33db Iustin Pop
    q = query.Query(fielddefs, ["name", "value"], qfilter=["?", "value"])
1665 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1666 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1667 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, True)],
1668 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, True)],
1669 3b877f08 Michael Hanselmann
      ])
1670 3b877f08 Michael Hanselmann
1671 3b877f08 Michael Hanselmann
    # Negative bool filter
1672 2e5c33db Iustin Pop
    q = query.Query(fielddefs, ["name", "value"], qfilter=["!", ["?", "value"]])
1673 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1674 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1675 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, False)],
1676 3b877f08 Michael Hanselmann
      ])
1677 3b877f08 Michael Hanselmann
1678 3b877f08 Michael Hanselmann
    # Complex truth filter
1679 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "value"],
1680 2e5c33db Iustin Pop
                    qfilter=["|", ["&", ["=", "name", "node1"],
1681 3b877f08 Michael Hanselmann
                                        ["!", ["?", "value"]]],
1682 3b877f08 Michael Hanselmann
                                  ["?", "value"]])
1683 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1684 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1685 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, False)],
1686 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, True)],
1687 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, True)],
1688 3b877f08 Michael Hanselmann
      ])
1689 3b877f08 Michael Hanselmann
1690 23d0a608 Michael Hanselmann
  def testFilterRegex(self):
1691 23d0a608 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1692 23d0a608 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1693 23d0a608 Michael Hanselmann
       None, 0, lambda ctx, item: item["name"]),
1694 23d0a608 Michael Hanselmann
      ], [])
1695 23d0a608 Michael Hanselmann
1696 23d0a608 Michael Hanselmann
    data = [
1697 23d0a608 Michael Hanselmann
      { "name": "node1.example.com", },
1698 23d0a608 Michael Hanselmann
      { "name": "node2.site.example.com", },
1699 23d0a608 Michael Hanselmann
      { "name": "node2.example.net", },
1700 23d0a608 Michael Hanselmann
1701 23d0a608 Michael Hanselmann
      # Empty name
1702 23d0a608 Michael Hanselmann
      { "name": "", },
1703 23d0a608 Michael Hanselmann
      ]
1704 23d0a608 Michael Hanselmann
1705 23d0a608 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1706 2e5c33db Iustin Pop
                    qfilter=["=~", "name", "site"])
1707 23d0a608 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1708 23d0a608 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1709 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.site.example.com")],
1710 23d0a608 Michael Hanselmann
      ])
1711 23d0a608 Michael Hanselmann
1712 23d0a608 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1713 2e5c33db Iustin Pop
                    qfilter=["=~", "name", "^node2"])
1714 23d0a608 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1715 23d0a608 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1716 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.net")],
1717 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.site.example.com")],
1718 23d0a608 Michael Hanselmann
      ])
1719 23d0a608 Michael Hanselmann
1720 23d0a608 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1721 2e5c33db Iustin Pop
                    qfilter=["=~", "name", r"(?i)\.COM$"])
1722 23d0a608 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1723 23d0a608 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1724 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node1.example.com")],
1725 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.site.example.com")],
1726 23d0a608 Michael Hanselmann
      ])
1727 23d0a608 Michael Hanselmann
1728 23d0a608 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1729 2e5c33db Iustin Pop
                    qfilter=["=~", "name", r"."])
1730 23d0a608 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1731 23d0a608 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1732 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node1.example.com")],
1733 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.net")],
1734 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.site.example.com")],
1735 23d0a608 Michael Hanselmann
      ])
1736 23d0a608 Michael Hanselmann
1737 23d0a608 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1738 2e5c33db Iustin Pop
                    qfilter=["=~", "name", r"^$"])
1739 23d0a608 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1740 23d0a608 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1741 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "")],
1742 23d0a608 Michael Hanselmann
      ])
1743 23d0a608 Michael Hanselmann
1744 23d0a608 Michael Hanselmann
    # Invalid regular expression
1745 23d0a608 Michael Hanselmann
    self.assertRaises(errors.ParameterError, query.Query, fielddefs, ["name"],
1746 2e5c33db Iustin Pop
                      qfilter=["=~", "name", r"["])
1747 23d0a608 Michael Hanselmann
1748 fb0be379 Michael Hanselmann
1749 4ca96421 Michael Hanselmann
if __name__ == "__main__":
1750 4ca96421 Michael Hanselmann
  testutils.GanetiTestProgram()