Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.query_unittest.py @ d6f58310

History | View | Annotate | Download (66.9 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 d8b7ff5f Adeodato Simo
    self.groups = [
959 d8b7ff5f Adeodato Simo
      objects.NodeGroup(name="default",
960 d8b7ff5f Adeodato Simo
                        uuid="c0e89160-18e7-11e0-a46e-001d0904baeb",
961 edd49f9b Agata Murawska
                        alloc_policy=constants.ALLOC_POLICY_PREFERRED,
962 8930b0f0 Iustin Pop
                        ipolicy=objects.MakeEmptyIPolicy(),
963 8930b0f0 Iustin Pop
                        ndparams={},
964 8930b0f0 Iustin Pop
                        ),
965 d8b7ff5f Adeodato Simo
      objects.NodeGroup(name="restricted",
966 d8b7ff5f Adeodato Simo
                        uuid="d2a40a74-18e7-11e0-9143-001d0904baeb",
967 edd49f9b Agata Murawska
                        alloc_policy=constants.ALLOC_POLICY_LAST_RESORT,
968 8930b0f0 Iustin Pop
                        ipolicy=objects.MakeEmptyIPolicy(),
969 8930b0f0 Iustin Pop
                        ndparams={}
970 8930b0f0 Iustin Pop
                        ),
971 d8b7ff5f Adeodato Simo
      ]
972 edd49f9b Agata Murawska
    self.cluster = objects.Cluster(cluster_name="testcluster",
973 edd49f9b Agata Murawska
      hvparams=constants.HVC_DEFAULTS,
974 edd49f9b Agata Murawska
      beparams={
975 edd49f9b Agata Murawska
        constants.PP_DEFAULT: constants.BEC_DEFAULTS,
976 edd49f9b Agata Murawska
        },
977 edd49f9b Agata Murawska
      nicparams={
978 edd49f9b Agata Murawska
        constants.PP_DEFAULT: constants.NICC_DEFAULTS,
979 edd49f9b Agata Murawska
        },
980 edd49f9b Agata Murawska
      ndparams=constants.NDC_DEFAULTS,
981 edd49f9b Agata Murawska
      ipolicy=constants.IPOLICY_DEFAULTS,
982 edd49f9b Agata Murawska
      )
983 d8b7ff5f Adeodato Simo
984 d8b7ff5f Adeodato Simo
  def _Create(self, selected):
985 d8b7ff5f Adeodato Simo
    return query.Query(query.GROUP_FIELDS, selected)
986 d8b7ff5f Adeodato Simo
987 d8b7ff5f Adeodato Simo
  def testSimple(self):
988 d8b7ff5f Adeodato Simo
    q = self._Create(["name", "uuid", "alloc_policy"])
989 edd49f9b Agata Murawska
    gqd = query.GroupQueryData(self.cluster, self.groups, None, None)
990 d8b7ff5f Adeodato Simo
991 d8b7ff5f Adeodato Simo
    self.assertEqual(q.RequestedData(), set([query.GQ_CONFIG]))
992 d8b7ff5f Adeodato Simo
993 d8b7ff5f Adeodato Simo
    self.assertEqual(q.Query(gqd),
994 cfb084ae Renรฉ Nussbaumer
      [[(constants.RS_NORMAL, "default"),
995 cfb084ae Renรฉ Nussbaumer
        (constants.RS_NORMAL, "c0e89160-18e7-11e0-a46e-001d0904baeb"),
996 cfb084ae Renรฉ Nussbaumer
        (constants.RS_NORMAL, constants.ALLOC_POLICY_PREFERRED)
997 d8b7ff5f Adeodato Simo
        ],
998 cfb084ae Renรฉ Nussbaumer
       [(constants.RS_NORMAL, "restricted"),
999 cfb084ae Renรฉ Nussbaumer
        (constants.RS_NORMAL, "d2a40a74-18e7-11e0-9143-001d0904baeb"),
1000 cfb084ae Renรฉ Nussbaumer
        (constants.RS_NORMAL, constants.ALLOC_POLICY_LAST_RESORT)
1001 d8b7ff5f Adeodato Simo
        ],
1002 d8b7ff5f Adeodato Simo
       ])
1003 d8b7ff5f Adeodato Simo
1004 d8b7ff5f Adeodato Simo
  def testNodes(self):
1005 d8b7ff5f Adeodato Simo
    groups_to_nodes = {
1006 d8b7ff5f Adeodato Simo
      "c0e89160-18e7-11e0-a46e-001d0904baeb": ["node1", "node2"],
1007 d8b7ff5f Adeodato Simo
      "d2a40a74-18e7-11e0-9143-001d0904baeb": ["node1", "node10", "node9"],
1008 d8b7ff5f Adeodato Simo
      }
1009 d8b7ff5f Adeodato Simo
1010 d8b7ff5f Adeodato Simo
    q = self._Create(["name", "node_cnt", "node_list"])
1011 edd49f9b Agata Murawska
    gqd = query.GroupQueryData(self.cluster, self.groups, groups_to_nodes, None)
1012 d8b7ff5f Adeodato Simo
1013 d8b7ff5f Adeodato Simo
    self.assertEqual(q.RequestedData(), set([query.GQ_CONFIG, query.GQ_NODE]))
1014 d8b7ff5f Adeodato Simo
1015 d8b7ff5f Adeodato Simo
    self.assertEqual(q.Query(gqd),
1016 cfb084ae Renรฉ Nussbaumer
                     [[(constants.RS_NORMAL, "default"),
1017 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, 2),
1018 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, ["node1", "node2"]),
1019 d8b7ff5f Adeodato Simo
                       ],
1020 cfb084ae Renรฉ Nussbaumer
                      [(constants.RS_NORMAL, "restricted"),
1021 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, 3),
1022 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, ["node1", "node9", "node10"]),
1023 d8b7ff5f Adeodato Simo
                       ],
1024 d8b7ff5f Adeodato Simo
                      ])
1025 d8b7ff5f Adeodato Simo
1026 d8b7ff5f Adeodato Simo
  def testInstances(self):
1027 d8b7ff5f Adeodato Simo
    groups_to_instances = {
1028 d8b7ff5f Adeodato Simo
      "c0e89160-18e7-11e0-a46e-001d0904baeb": ["inst1", "inst2"],
1029 d8b7ff5f Adeodato Simo
      "d2a40a74-18e7-11e0-9143-001d0904baeb": ["inst1", "inst10", "inst9"],
1030 d8b7ff5f Adeodato Simo
      }
1031 d8b7ff5f Adeodato Simo
1032 d8b7ff5f Adeodato Simo
    q = self._Create(["pinst_cnt", "pinst_list"])
1033 edd49f9b Agata Murawska
    gqd = query.GroupQueryData(self.cluster, self.groups, None,
1034 edd49f9b Agata Murawska
      groups_to_instances)
1035 d8b7ff5f Adeodato Simo
1036 d8b7ff5f Adeodato Simo
    self.assertEqual(q.RequestedData(), set([query.GQ_INST]))
1037 d8b7ff5f Adeodato Simo
1038 d8b7ff5f Adeodato Simo
    self.assertEqual(q.Query(gqd),
1039 cfb084ae Renรฉ Nussbaumer
                     [[(constants.RS_NORMAL, 2),
1040 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, ["inst1", "inst2"]),
1041 d8b7ff5f Adeodato Simo
                       ],
1042 cfb084ae Renรฉ Nussbaumer
                      [(constants.RS_NORMAL, 3),
1043 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, ["inst1", "inst9", "inst10"]),
1044 d8b7ff5f Adeodato Simo
                       ],
1045 d8b7ff5f Adeodato Simo
                      ])
1046 d8b7ff5f Adeodato Simo
1047 d8b7ff5f Adeodato Simo
1048 be3a4b14 Michael Hanselmann
class TestOsQuery(unittest.TestCase):
1049 be3a4b14 Michael Hanselmann
  def _Create(self, selected):
1050 be3a4b14 Michael Hanselmann
    return query.Query(query.OS_FIELDS, selected)
1051 be3a4b14 Michael Hanselmann
1052 be3a4b14 Michael Hanselmann
  def test(self):
1053 be3a4b14 Michael Hanselmann
    variants = ["v00", "plain", "v3", "var0", "v33", "v20"]
1054 be3a4b14 Michael Hanselmann
    api_versions = [10, 0, 15, 5]
1055 be3a4b14 Michael Hanselmann
    parameters = ["zpar3", "apar9"]
1056 be3a4b14 Michael Hanselmann
1057 be3a4b14 Michael Hanselmann
    assert variants != sorted(variants) and variants != utils.NiceSort(variants)
1058 be3a4b14 Michael Hanselmann
    assert (api_versions != sorted(api_versions) and
1059 be3a4b14 Michael Hanselmann
            api_versions != utils.NiceSort(variants))
1060 be3a4b14 Michael Hanselmann
    assert (parameters != sorted(parameters) and
1061 be3a4b14 Michael Hanselmann
            parameters != utils.NiceSort(parameters))
1062 be3a4b14 Michael Hanselmann
1063 be3a4b14 Michael Hanselmann
    data = [
1064 be3a4b14 Michael Hanselmann
      query.OsInfo(name="debian", valid=False, hidden=False, blacklisted=False,
1065 be3a4b14 Michael Hanselmann
                   variants=set(), api_versions=set(), parameters=set(),
1066 be3a4b14 Michael Hanselmann
                   node_status={ "some": "status", }),
1067 be3a4b14 Michael Hanselmann
      query.OsInfo(name="dos", valid=True, hidden=False, blacklisted=True,
1068 be3a4b14 Michael Hanselmann
                   variants=set(variants),
1069 be3a4b14 Michael Hanselmann
                   api_versions=set(api_versions),
1070 be3a4b14 Michael Hanselmann
                   parameters=set(parameters),
1071 be3a4b14 Michael Hanselmann
                   node_status={ "some": "other", "status": None, }),
1072 be3a4b14 Michael Hanselmann
      ]
1073 be3a4b14 Michael Hanselmann
1074 be3a4b14 Michael Hanselmann
1075 be3a4b14 Michael Hanselmann
    q = self._Create(["name", "valid", "hidden", "blacklisted", "variants",
1076 be3a4b14 Michael Hanselmann
                      "api_versions", "parameters", "node_status"])
1077 be3a4b14 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([]))
1078 be3a4b14 Michael Hanselmann
    self.assertEqual(q.Query(data),
1079 be3a4b14 Michael Hanselmann
                     [[(constants.RS_NORMAL, "debian"),
1080 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, False),
1081 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, False),
1082 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, False),
1083 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, []),
1084 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, []),
1085 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, []),
1086 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, {"some": "status"})],
1087 be3a4b14 Michael Hanselmann
                      [(constants.RS_NORMAL, "dos"),
1088 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, True),
1089 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, False),
1090 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, True),
1091 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL,
1092 be3a4b14 Michael Hanselmann
                        ["plain", "v00", "v3", "v20", "v33", "var0"]),
1093 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, [0, 5, 10, 15]),
1094 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, ["apar9", "zpar3"]),
1095 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL,
1096 be3a4b14 Michael Hanselmann
                        { "some": "other", "status": None, })
1097 be3a4b14 Michael Hanselmann
                       ]])
1098 be3a4b14 Michael Hanselmann
1099 be3a4b14 Michael Hanselmann
1100 aa29e95f Michael Hanselmann
class TestQueryFields(unittest.TestCase):
1101 aa29e95f Michael Hanselmann
  def testAllFields(self):
1102 e571ee44 Adeodato Simo
    for fielddefs in query.ALL_FIELD_LISTS:
1103 aa29e95f Michael Hanselmann
      result = query.QueryFields(fielddefs, None)
1104 aa29e95f Michael Hanselmann
      self.assert_(isinstance(result, dict))
1105 aa29e95f Michael Hanselmann
      response = objects.QueryFieldsResponse.FromDict(result)
1106 aa29e95f Michael Hanselmann
      self.assertEqual([(fdef.name, fdef.title) for fdef in response.fields],
1107 aa29e95f Michael Hanselmann
        [(fdef2.name, fdef2.title)
1108 111bf531 Michael Hanselmann
         for (fdef2, _, _, _) in utils.NiceSort(fielddefs.values(),
1109 111bf531 Michael Hanselmann
                                                key=lambda x: x[0].name)])
1110 aa29e95f Michael Hanselmann
1111 aa29e95f Michael Hanselmann
  def testSomeFields(self):
1112 aa29e95f Michael Hanselmann
    rnd = random.Random(5357)
1113 aa29e95f Michael Hanselmann
1114 aa29e95f Michael Hanselmann
    for _ in range(10):
1115 e571ee44 Adeodato Simo
      for fielddefs in query.ALL_FIELD_LISTS:
1116 e571ee44 Adeodato Simo
        if len(fielddefs) > 20:
1117 e571ee44 Adeodato Simo
          sample_size = rnd.randint(5, 20)
1118 e571ee44 Adeodato Simo
        else:
1119 e571ee44 Adeodato Simo
          sample_size = rnd.randint(1, max(1, len(fielddefs) - 1))
1120 111bf531 Michael Hanselmann
        fields = [fdef for (fdef, _, _, _) in rnd.sample(fielddefs.values(),
1121 111bf531 Michael Hanselmann
                                                         sample_size)]
1122 aa29e95f Michael Hanselmann
        result = query.QueryFields(fielddefs, [fdef.name for fdef in fields])
1123 aa29e95f Michael Hanselmann
        self.assert_(isinstance(result, dict))
1124 aa29e95f Michael Hanselmann
        response = objects.QueryFieldsResponse.FromDict(result)
1125 aa29e95f Michael Hanselmann
        self.assertEqual([(fdef.name, fdef.title) for fdef in response.fields],
1126 aa29e95f Michael Hanselmann
                         [(fdef2.name, fdef2.title) for fdef2 in fields])
1127 aa29e95f Michael Hanselmann
1128 aa29e95f Michael Hanselmann
1129 fb0be379 Michael Hanselmann
class TestQueryFilter(unittest.TestCase):
1130 fb0be379 Michael Hanselmann
  def testRequestedNames(self):
1131 fb0be379 Michael Hanselmann
    for fielddefs in query.ALL_FIELD_LISTS:
1132 d6f58310 Michael Hanselmann
      if "id" in fielddefs:
1133 d6f58310 Michael Hanselmann
        namefield = "id"
1134 d6f58310 Michael Hanselmann
      else:
1135 d6f58310 Michael Hanselmann
        namefield = "name"
1136 d6f58310 Michael Hanselmann
1137 d6f58310 Michael Hanselmann
      assert namefield in fielddefs
1138 d6f58310 Michael Hanselmann
1139 d6f58310 Michael Hanselmann
      innerfilter = [["=", namefield, "x%s" % i] for i in range(4)]
1140 fb0be379 Michael Hanselmann
1141 fb0be379 Michael Hanselmann
      # No name field
1142 d6f58310 Michael Hanselmann
      q = query.Query(fielddefs, [namefield], qfilter=["=", namefield, "abc"],
1143 fb0be379 Michael Hanselmann
                      namefield=None)
1144 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), None)
1145 fb0be379 Michael Hanselmann
1146 fb0be379 Michael Hanselmann
      # No filter
1147 d6f58310 Michael Hanselmann
      q = query.Query(fielddefs, [namefield], qfilter=None, namefield=namefield)
1148 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), None)
1149 fb0be379 Michael Hanselmann
1150 fb0be379 Michael Hanselmann
      # Check empty query
1151 d6f58310 Michael Hanselmann
      q = query.Query(fielddefs, [namefield], qfilter=["|"],
1152 d6f58310 Michael Hanselmann
                      namefield=namefield)
1153 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), None)
1154 fb0be379 Michael Hanselmann
1155 fb0be379 Michael Hanselmann
      # Check order
1156 d6f58310 Michael Hanselmann
      q = query.Query(fielddefs, [namefield], qfilter=["|"] + innerfilter,
1157 d6f58310 Michael Hanselmann
                      namefield=namefield)
1158 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), ["x0", "x1", "x2", "x3"])
1159 fb0be379 Michael Hanselmann
1160 fb0be379 Michael Hanselmann
      # Check reverse order
1161 d6f58310 Michael Hanselmann
      q = query.Query(fielddefs, [namefield],
1162 2e5c33db Iustin Pop
                      qfilter=["|"] + list(reversed(innerfilter)),
1163 d6f58310 Michael Hanselmann
                      namefield=namefield)
1164 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), ["x3", "x2", "x1", "x0"])
1165 fb0be379 Michael Hanselmann
1166 fb0be379 Michael Hanselmann
      # Duplicates
1167 d6f58310 Michael Hanselmann
      q = query.Query(fielddefs, [namefield],
1168 2e5c33db Iustin Pop
                      qfilter=["|"] + innerfilter + list(reversed(innerfilter)),
1169 d6f58310 Michael Hanselmann
                      namefield=namefield)
1170 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), ["x0", "x1", "x2", "x3"])
1171 fb0be379 Michael Hanselmann
1172 fb0be379 Michael Hanselmann
      # Unknown name field
1173 d6f58310 Michael Hanselmann
      self.assertRaises(AssertionError, query.Query, fielddefs, [namefield],
1174 fb0be379 Michael Hanselmann
                        namefield="_unknown_field_")
1175 fb0be379 Michael Hanselmann
1176 fb0be379 Michael Hanselmann
      # Filter with AND
1177 d6f58310 Michael Hanselmann
      q = query.Query(fielddefs, [namefield],
1178 d6f58310 Michael Hanselmann
                      qfilter=["|", ["=", namefield, "foo"],
1179 d6f58310 Michael Hanselmann
                                    ["&", ["=", namefield, ""]]],
1180 d6f58310 Michael Hanselmann
                      namefield=namefield)
1181 fb0be379 Michael Hanselmann
      self.assertTrue(q.RequestedNames() is None)
1182 fb0be379 Michael Hanselmann
1183 fb0be379 Michael Hanselmann
      # Filter with NOT
1184 d6f58310 Michael Hanselmann
      q = query.Query(fielddefs, [namefield],
1185 d6f58310 Michael Hanselmann
                      qfilter=["|", ["=", namefield, "foo"],
1186 d6f58310 Michael Hanselmann
                                    ["!", ["=", namefield, ""]]],
1187 d6f58310 Michael Hanselmann
                      namefield=namefield)
1188 fb0be379 Michael Hanselmann
      self.assertTrue(q.RequestedNames() is None)
1189 fb0be379 Michael Hanselmann
1190 fb0be379 Michael Hanselmann
      # Filter with only OR (names must be in correct order)
1191 d6f58310 Michael Hanselmann
      q = query.Query(fielddefs, [namefield],
1192 d6f58310 Michael Hanselmann
                      qfilter=["|", ["=", namefield, "x17361"],
1193 d6f58310 Michael Hanselmann
                                    ["|", ["=", namefield, "x22015"]],
1194 d6f58310 Michael Hanselmann
                                    ["|", ["|", ["=", namefield, "x13193"]]],
1195 d6f58310 Michael Hanselmann
                                    ["=", namefield, "x15215"]],
1196 d6f58310 Michael Hanselmann
                      namefield=namefield)
1197 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(),
1198 fb0be379 Michael Hanselmann
                       ["x17361", "x22015", "x13193", "x15215"])
1199 fb0be379 Michael Hanselmann
1200 fb0be379 Michael Hanselmann
  @staticmethod
1201 d6f58310 Michael Hanselmann
  def _GenNestedFilter(namefield, op, depth):
1202 d6f58310 Michael Hanselmann
    nested = ["=", namefield, "value"]
1203 fb0be379 Michael Hanselmann
    for i in range(depth):
1204 fb0be379 Michael Hanselmann
      nested = [op, nested]
1205 fb0be379 Michael Hanselmann
    return nested
1206 fb0be379 Michael Hanselmann
1207 fb0be379 Michael Hanselmann
  def testCompileFilter(self):
1208 fb0be379 Michael Hanselmann
    levels_max = query._FilterCompilerHelper._LEVELS_MAX
1209 fb0be379 Michael Hanselmann
1210 fb0be379 Michael Hanselmann
    for fielddefs in query.ALL_FIELD_LISTS:
1211 d6f58310 Michael Hanselmann
      if "id" in fielddefs:
1212 d6f58310 Michael Hanselmann
        namefield = "id"
1213 d6f58310 Michael Hanselmann
      else:
1214 d6f58310 Michael Hanselmann
        namefield = "name"
1215 d6f58310 Michael Hanselmann
1216 d6f58310 Michael Hanselmann
      checks = [
1217 d6f58310 Michael Hanselmann
        [], ["="], ["=", "foo"], ["unknownop"], ["!"],
1218 d6f58310 Michael Hanselmann
        ["=", "_unknown_field", "value"],
1219 d6f58310 Michael Hanselmann
        self._GenNestedFilter(namefield, "|", levels_max),
1220 d6f58310 Michael Hanselmann
        self._GenNestedFilter(namefield, "|", levels_max * 3),
1221 d6f58310 Michael Hanselmann
        self._GenNestedFilter(namefield, "!", levels_max),
1222 d6f58310 Michael Hanselmann
        ]
1223 d6f58310 Michael Hanselmann
1224 2e5c33db Iustin Pop
      for qfilter in checks:
1225 fb0be379 Michael Hanselmann
        self.assertRaises(errors.ParameterError, query._CompileFilter,
1226 2e5c33db Iustin Pop
                          fielddefs, None, qfilter)
1227 fb0be379 Michael Hanselmann
1228 fb0be379 Michael Hanselmann
      for op in ["|", "!"]:
1229 d6f58310 Michael Hanselmann
        qfilter = self._GenNestedFilter(namefield, op, levels_max - 1)
1230 fb0be379 Michael Hanselmann
        self.assertTrue(callable(query._CompileFilter(fielddefs, None,
1231 2e5c33db Iustin Pop
                                                      qfilter)))
1232 fb0be379 Michael Hanselmann
1233 fb0be379 Michael Hanselmann
  def testQueryInputOrder(self):
1234 fb0be379 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1235 fb0be379 Michael Hanselmann
      (query._MakeField("pnode", "PNode", constants.QFT_TEXT, "Primary"),
1236 fb0be379 Michael Hanselmann
       None, 0, lambda ctx, item: item["pnode"]),
1237 fb0be379 Michael Hanselmann
      (query._MakeField("snode", "SNode", constants.QFT_TEXT, "Secondary"),
1238 fb0be379 Michael Hanselmann
       None, 0, lambda ctx, item: item["snode"]),
1239 fb0be379 Michael Hanselmann
      ], [])
1240 fb0be379 Michael Hanselmann
1241 fb0be379 Michael Hanselmann
    data = [
1242 fb0be379 Michael Hanselmann
      { "pnode": "node1", "snode": "node44", },
1243 fb0be379 Michael Hanselmann
      { "pnode": "node30", "snode": "node90", },
1244 fb0be379 Michael Hanselmann
      { "pnode": "node25", "snode": "node1", },
1245 fb0be379 Michael Hanselmann
      { "pnode": "node20", "snode": "node1", },
1246 fb0be379 Michael Hanselmann
      ]
1247 fb0be379 Michael Hanselmann
1248 2e5c33db Iustin Pop
    qfilter = ["|", ["=", "pnode", "node1"], ["=", "snode", "node1"]]
1249 fb0be379 Michael Hanselmann
1250 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "snode"], namefield="pnode",
1251 2e5c33db Iustin Pop
                    qfilter=qfilter)
1252 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1253 fb0be379 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1254 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1255 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")],
1256 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")],
1257 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")]])
1258 fb0be379 Michael Hanselmann
1259 fb0be379 Michael Hanselmann
    # Try again with reversed input data
1260 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(reversed(data)),
1261 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")],
1262 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")],
1263 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")]])
1264 fb0be379 Michael Hanselmann
1265 fb0be379 Michael Hanselmann
    # No name field, result must be in incoming order
1266 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "snode"], namefield=None,
1267 2e5c33db Iustin Pop
                    qfilter=qfilter)
1268 fb0be379 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1269 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1270 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")],
1271 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")],
1272 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")]])
1273 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1274 fb0be379 Michael Hanselmann
      ["node1", "node44"],
1275 fb0be379 Michael Hanselmann
      ["node25", "node1"],
1276 fb0be379 Michael Hanselmann
      ["node20", "node1"],
1277 fb0be379 Michael Hanselmann
      ])
1278 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(reversed(data)),
1279 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")],
1280 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")],
1281 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")]])
1282 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(reversed(data)), [
1283 fb0be379 Michael Hanselmann
      ["node20", "node1"],
1284 fb0be379 Michael Hanselmann
      ["node25", "node1"],
1285 fb0be379 Michael Hanselmann
      ["node1", "node44"],
1286 fb0be379 Michael Hanselmann
      ])
1287 fb0be379 Michael Hanselmann
1288 fbc263a9 Michael Hanselmann
    # Name field, but no sorting, result must be in incoming order
1289 fbc263a9 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "snode"], namefield="pnode")
1290 fbc263a9 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1291 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data, sort_by_name=False),
1292 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")],
1293 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node30"), (constants.RS_NORMAL, "node90")],
1294 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")],
1295 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")]])
1296 fbc263a9 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data, sort_by_name=False), [
1297 fbc263a9 Michael Hanselmann
      ["node1", "node44"],
1298 fbc263a9 Michael Hanselmann
      ["node30", "node90"],
1299 fbc263a9 Michael Hanselmann
      ["node25", "node1"],
1300 fbc263a9 Michael Hanselmann
      ["node20", "node1"],
1301 fbc263a9 Michael Hanselmann
      ])
1302 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(reversed(data), sort_by_name=False),
1303 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")],
1304 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")],
1305 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node30"), (constants.RS_NORMAL, "node90")],
1306 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")]])
1307 fbc263a9 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(reversed(data), sort_by_name=False), [
1308 fbc263a9 Michael Hanselmann
      ["node20", "node1"],
1309 fbc263a9 Michael Hanselmann
      ["node25", "node1"],
1310 fbc263a9 Michael Hanselmann
      ["node30", "node90"],
1311 fbc263a9 Michael Hanselmann
      ["node1", "node44"],
1312 fbc263a9 Michael Hanselmann
      ])
1313 fbc263a9 Michael Hanselmann
1314 fbc263a9 Michael Hanselmann
  def testEqualNamesOrder(self):
1315 fbc263a9 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1316 fbc263a9 Michael Hanselmann
      (query._MakeField("pnode", "PNode", constants.QFT_TEXT, "Primary"),
1317 fbc263a9 Michael Hanselmann
       None, 0, lambda ctx, item: item["pnode"]),
1318 fbc263a9 Michael Hanselmann
      (query._MakeField("num", "Num", constants.QFT_NUMBER, "Num"),
1319 fbc263a9 Michael Hanselmann
       None, 0, lambda ctx, item: item["num"]),
1320 fbc263a9 Michael Hanselmann
      ], [])
1321 fbc263a9 Michael Hanselmann
1322 fbc263a9 Michael Hanselmann
    data = [
1323 fbc263a9 Michael Hanselmann
      { "pnode": "node1", "num": 100, },
1324 fbc263a9 Michael Hanselmann
      { "pnode": "node1", "num": 25, },
1325 fbc263a9 Michael Hanselmann
      { "pnode": "node2", "num": 90, },
1326 fbc263a9 Michael Hanselmann
      { "pnode": "node2", "num": 30, },
1327 fbc263a9 Michael Hanselmann
      ]
1328 fbc263a9 Michael Hanselmann
1329 fbc263a9 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "num"], namefield="pnode",
1330 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "pnode", "node1"],
1331 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "node2"],
1332 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "node1"]])
1333 fbc263a9 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1", "node2"],
1334 fbc263a9 Michael Hanselmann
                     msg="Did not return unique names")
1335 fbc263a9 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1336 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data),
1337 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, 100)],
1338 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, 25)],
1339 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, 90)],
1340 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, 30)]])
1341 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data, sort_by_name=False),
1342 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, 100)],
1343 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, 25)],
1344 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, 90)],
1345 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, 30)]])
1346 fbc263a9 Michael Hanselmann
1347 fbc263a9 Michael Hanselmann
    data = [
1348 fbc263a9 Michael Hanselmann
      { "pnode": "nodeX", "num": 50, },
1349 fbc263a9 Michael Hanselmann
      { "pnode": "nodeY", "num": 40, },
1350 fbc263a9 Michael Hanselmann
      { "pnode": "nodeX", "num": 30, },
1351 fbc263a9 Michael Hanselmann
      { "pnode": "nodeX", "num": 20, },
1352 fbc263a9 Michael Hanselmann
      { "pnode": "nodeM", "num": 10, },
1353 fbc263a9 Michael Hanselmann
      ]
1354 fbc263a9 Michael Hanselmann
1355 fbc263a9 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "num"], namefield="pnode",
1356 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "pnode", "nodeX"],
1357 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "nodeY"],
1358 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "nodeY"],
1359 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "nodeY"],
1360 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "nodeM"]])
1361 fbc263a9 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["nodeX", "nodeY", "nodeM"],
1362 fbc263a9 Michael Hanselmann
                     msg="Did not return unique names")
1363 fbc263a9 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1364 fbc263a9 Michael Hanselmann
1365 fbc263a9 Michael Hanselmann
    # First sorted by name, then input order
1366 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data, sort_by_name=True),
1367 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "nodeM"), (constants.RS_NORMAL, 10)],
1368 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 50)],
1369 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 30)],
1370 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 20)],
1371 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeY"), (constants.RS_NORMAL, 40)]])
1372 fbc263a9 Michael Hanselmann
1373 fbc263a9 Michael Hanselmann
    # Input order
1374 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data, sort_by_name=False),
1375 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 50)],
1376 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeY"), (constants.RS_NORMAL, 40)],
1377 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 30)],
1378 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 20)],
1379 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeM"), (constants.RS_NORMAL, 10)]])
1380 fbc263a9 Michael Hanselmann
1381 fb0be379 Michael Hanselmann
  def testFilter(self):
1382 fb0be379 Michael Hanselmann
    (DK_A, DK_B) = range(1000, 1002)
1383 fb0be379 Michael Hanselmann
1384 fb0be379 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1385 fb0be379 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1386 fb0be379 Michael Hanselmann
       DK_A, 0, lambda ctx, item: item["name"]),
1387 fb0be379 Michael Hanselmann
      (query._MakeField("other", "Other", constants.QFT_TEXT, "Other"),
1388 fb0be379 Michael Hanselmann
       DK_B, 0, lambda ctx, item: item["other"]),
1389 fb0be379 Michael Hanselmann
      ], [])
1390 fb0be379 Michael Hanselmann
1391 fb0be379 Michael Hanselmann
    data = [
1392 fb0be379 Michael Hanselmann
      { "name": "node1", "other": "foo", },
1393 fb0be379 Michael Hanselmann
      { "name": "node2", "other": "bar", },
1394 fb0be379 Michael Hanselmann
      { "name": "node3", "other": "Hello", },
1395 fb0be379 Michael Hanselmann
      ]
1396 fb0be379 Michael Hanselmann
1397 fb0be379 Michael Hanselmann
    # Empty filter
1398 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1399 2e5c33db Iustin Pop
                    qfilter=["|"])
1400 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1401 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_A, DK_B]))
1402 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [])
1403 fb0be379 Michael Hanselmann
1404 fb0be379 Michael Hanselmann
    # Normal filter
1405 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1406 2e5c33db Iustin Pop
                    qfilter=["=", "name", "node1"])
1407 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1"])
1408 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1409 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "foo")]])
1410 fb0be379 Michael Hanselmann
1411 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1412 2e5c33db Iustin Pop
                    qfilter=(["|", ["=", "name", "node1"],
1413 fb0be379 Michael Hanselmann
                                   ["=", "name", "node3"]]))
1414 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1", "node3"])
1415 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1416 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "foo")],
1417 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, "Hello")]])
1418 fb0be379 Michael Hanselmann
1419 fb0be379 Michael Hanselmann
    # Complex filter
1420 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1421 2e5c33db Iustin Pop
                    qfilter=(["|", ["=", "name", "node1"],
1422 fb0be379 Michael Hanselmann
                                   ["|", ["=", "name", "node3"],
1423 fb0be379 Michael Hanselmann
                                         ["=", "name", "node2"]],
1424 fb0be379 Michael Hanselmann
                                   ["=", "name", "node3"]]))
1425 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1", "node3", "node2"])
1426 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_A, DK_B]))
1427 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1428 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "foo")],
1429 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, "bar")],
1430 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, "Hello")]])
1431 fb0be379 Michael Hanselmann
1432 fb0be379 Michael Hanselmann
    # Filter data type mismatch
1433 fb0be379 Michael Hanselmann
    for i in [-1, 0, 1, 123, [], None, True, False]:
1434 fb0be379 Michael Hanselmann
      self.assertRaises(errors.ParameterError, query.Query,
1435 fb0be379 Michael Hanselmann
                        fielddefs, ["name", "other"], namefield="name",
1436 2e5c33db Iustin Pop
                        qfilter=["=", "name", i])
1437 fb0be379 Michael Hanselmann
1438 fb0be379 Michael Hanselmann
    # Negative filter
1439 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1440 2e5c33db Iustin Pop
                    qfilter=["!", ["|", ["=", "name", "node1"],
1441 fb0be379 Michael Hanselmann
                                        ["=", "name", "node3"]]])
1442 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1443 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1444 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, "bar")]])
1445 fb0be379 Michael Hanselmann
1446 fb0be379 Michael Hanselmann
    # Not equal
1447 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1448 2e5c33db Iustin Pop
                    qfilter=["!=", "name", "node3"])
1449 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
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, "node2"), (constants.RS_NORMAL, "bar")]])
1453 fb0be379 Michael Hanselmann
1454 fb0be379 Michael Hanselmann
    # Data type
1455 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, [], namefield="name",
1456 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "other", "bar"],
1457 fb0be379 Michael Hanselmann
                                  ["=", "name", "foo"]])
1458 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1459 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_A, DK_B]))
1460 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [[]])
1461 fb0be379 Michael Hanselmann
1462 fb0be379 Michael Hanselmann
    # Only one data type
1463 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["other"], namefield="name",
1464 2e5c33db Iustin Pop
                    qfilter=["=", "other", "bar"])
1465 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1466 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_B]))
1467 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [[(constants.RS_NORMAL, "bar")]])
1468 fb0be379 Michael Hanselmann
1469 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, [], namefield="name",
1470 2e5c33db Iustin Pop
                    qfilter=["=", "other", "bar"])
1471 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1472 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_B]))
1473 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [[]])
1474 fb0be379 Michael Hanselmann
1475 fb0be379 Michael Hanselmann
  def testFilterContains(self):
1476 fb0be379 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1477 fb0be379 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1478 fb0be379 Michael Hanselmann
       None, 0, lambda ctx, item: item["name"]),
1479 fb0be379 Michael Hanselmann
      (query._MakeField("other", "Other", constants.QFT_OTHER, "Other"),
1480 fb0be379 Michael Hanselmann
       None, 0, lambda ctx, item: item["other"]),
1481 fb0be379 Michael Hanselmann
      ], [])
1482 fb0be379 Michael Hanselmann
1483 fb0be379 Michael Hanselmann
    data = [
1484 fb0be379 Michael Hanselmann
      { "name": "node2", "other": ["x", "y", "bar"], },
1485 fb0be379 Michael Hanselmann
      { "name": "node3", "other": "Hello", },
1486 fb0be379 Michael Hanselmann
      { "name": "node1", "other": ["a", "b", "foo"], },
1487 3b877f08 Michael Hanselmann
      { "name": "empty", "other": []},
1488 fb0be379 Michael Hanselmann
      ]
1489 fb0be379 Michael Hanselmann
1490 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1491 2e5c33db Iustin Pop
                    qfilter=["=[]", "other", "bar"])
1492 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1493 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1494 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"),
1495 fb0be379 Michael Hanselmann
       (constants.RS_NORMAL, ["x", "y", "bar"])],
1496 fb0be379 Michael Hanselmann
      ])
1497 fb0be379 Michael Hanselmann
1498 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1499 2e5c33db Iustin Pop
                    qfilter=["|", ["=[]", "other", "bar"],
1500 fb0be379 Michael Hanselmann
                                  ["=[]", "other", "a"],
1501 fb0be379 Michael Hanselmann
                                  ["=[]", "other", "b"]])
1502 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1503 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1504 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"),
1505 fb0be379 Michael Hanselmann
       (constants.RS_NORMAL, ["a", "b", "foo"])],
1506 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"),
1507 fb0be379 Michael Hanselmann
       (constants.RS_NORMAL, ["x", "y", "bar"])],
1508 fb0be379 Michael Hanselmann
      ])
1509 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1510 fb0be379 Michael Hanselmann
      ["node1", ["a", "b", "foo"]],
1511 fb0be379 Michael Hanselmann
      ["node2", ["x", "y", "bar"]],
1512 fb0be379 Michael Hanselmann
      ])
1513 fb0be379 Michael Hanselmann
1514 3b877f08 Michael Hanselmann
    # Boolean test
1515 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1516 2e5c33db Iustin Pop
                    qfilter=["?", "other"])
1517 3b877f08 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1518 3b877f08 Michael Hanselmann
      ["node1", ["a", "b", "foo"]],
1519 3b877f08 Michael Hanselmann
      ["node2", ["x", "y", "bar"]],
1520 3b877f08 Michael Hanselmann
      ["node3", "Hello"],
1521 3b877f08 Michael Hanselmann
      ])
1522 3b877f08 Michael Hanselmann
1523 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1524 2e5c33db Iustin Pop
                    qfilter=["!", ["?", "other"]])
1525 3b877f08 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1526 3b877f08 Michael Hanselmann
      ["empty", []],
1527 3b877f08 Michael Hanselmann
      ])
1528 3b877f08 Michael Hanselmann
1529 fb0be379 Michael Hanselmann
  def testFilterHostname(self):
1530 fb0be379 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1531 fb0be379 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1532 fb0be379 Michael Hanselmann
       None, query.QFF_HOSTNAME, lambda ctx, item: item["name"]),
1533 fb0be379 Michael Hanselmann
      ], [])
1534 fb0be379 Michael Hanselmann
1535 fb0be379 Michael Hanselmann
    data = [
1536 fb0be379 Michael Hanselmann
      { "name": "node1.example.com", },
1537 fb0be379 Michael Hanselmann
      { "name": "node2.example.com", },
1538 fb0be379 Michael Hanselmann
      { "name": "node2.example.net", },
1539 fb0be379 Michael Hanselmann
      ]
1540 fb0be379 Michael Hanselmann
1541 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1542 2e5c33db Iustin Pop
                    qfilter=["=", "name", "node2"])
1543 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node2"])
1544 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1545 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.com")],
1546 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.net")],
1547 fb0be379 Michael Hanselmann
      ])
1548 fb0be379 Michael Hanselmann
1549 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1550 2e5c33db Iustin Pop
                    qfilter=["=", "name", "node1"])
1551 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1"])
1552 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1553 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node1.example.com")],
1554 fb0be379 Michael Hanselmann
      ])
1555 fb0be379 Michael Hanselmann
1556 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1557 2e5c33db Iustin Pop
                    qfilter=["=", "name", "othername"])
1558 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["othername"])
1559 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [])
1560 fb0be379 Michael Hanselmann
1561 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1562 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "name", "node1.example.com"],
1563 fb0be379 Michael Hanselmann
                                  ["=", "name", "node2"]])
1564 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1.example.com", "node2"])
1565 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1566 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node1.example.com")],
1567 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.com")],
1568 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.net")],
1569 fb0be379 Michael Hanselmann
      ])
1570 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1571 fb0be379 Michael Hanselmann
      ["node1.example.com"],
1572 fb0be379 Michael Hanselmann
      ["node2.example.com"],
1573 fb0be379 Michael Hanselmann
      ["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", "node1"])
1578 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
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
    self.assertEqual(q.OldStyleQuery(data), [
1584 fb0be379 Michael Hanselmann
      ["node2.example.com"],
1585 fb0be379 Michael Hanselmann
      ["node2.example.net"],
1586 fb0be379 Michael Hanselmann
      ])
1587 fb0be379 Michael Hanselmann
1588 3b877f08 Michael Hanselmann
  def testFilterBoolean(self):
1589 3b877f08 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1590 3b877f08 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1591 3b877f08 Michael Hanselmann
       None, query.QFF_HOSTNAME, lambda ctx, item: item["name"]),
1592 3b877f08 Michael Hanselmann
      (query._MakeField("value", "Value", constants.QFT_BOOL, "Value"),
1593 3b877f08 Michael Hanselmann
       None, 0, lambda ctx, item: item["value"]),
1594 3b877f08 Michael Hanselmann
      ], [])
1595 3b877f08 Michael Hanselmann
1596 3b877f08 Michael Hanselmann
    data = [
1597 3b877f08 Michael Hanselmann
      { "name": "node1", "value": False, },
1598 3b877f08 Michael Hanselmann
      { "name": "node2", "value": True, },
1599 3b877f08 Michael Hanselmann
      { "name": "node3", "value": True, },
1600 3b877f08 Michael Hanselmann
      ]
1601 3b877f08 Michael Hanselmann
1602 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "value"],
1603 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "value", False],
1604 3b877f08 Michael Hanselmann
                                  ["=", "value", True]])
1605 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1606 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1607 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, False)],
1608 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, True)],
1609 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, True)],
1610 3b877f08 Michael Hanselmann
      ])
1611 3b877f08 Michael Hanselmann
1612 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "value"],
1613 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "value", False],
1614 3b877f08 Michael Hanselmann
                                  ["!", ["=", "value", False]]])
1615 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1616 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1617 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, False)],
1618 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, True)],
1619 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, True)],
1620 3b877f08 Michael Hanselmann
      ])
1621 3b877f08 Michael Hanselmann
1622 3b877f08 Michael Hanselmann
    # Comparing bool with string
1623 3b877f08 Michael Hanselmann
    for i in ["False", "True", "0", "1", "no", "yes", "N", "Y"]:
1624 3b877f08 Michael Hanselmann
      self.assertRaises(errors.ParameterError, query.Query,
1625 3b877f08 Michael Hanselmann
                        fielddefs, ["name", "value"],
1626 2e5c33db Iustin Pop
                        qfilter=["=", "value", i])
1627 3b877f08 Michael Hanselmann
1628 3b877f08 Michael Hanselmann
    # Truth filter
1629 2e5c33db Iustin Pop
    q = query.Query(fielddefs, ["name", "value"], qfilter=["?", "value"])
1630 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1631 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1632 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, True)],
1633 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, True)],
1634 3b877f08 Michael Hanselmann
      ])
1635 3b877f08 Michael Hanselmann
1636 3b877f08 Michael Hanselmann
    # Negative bool filter
1637 2e5c33db Iustin Pop
    q = query.Query(fielddefs, ["name", "value"], qfilter=["!", ["?", "value"]])
1638 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1639 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1640 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, False)],
1641 3b877f08 Michael Hanselmann
      ])
1642 3b877f08 Michael Hanselmann
1643 3b877f08 Michael Hanselmann
    # Complex truth filter
1644 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "value"],
1645 2e5c33db Iustin Pop
                    qfilter=["|", ["&", ["=", "name", "node1"],
1646 3b877f08 Michael Hanselmann
                                        ["!", ["?", "value"]]],
1647 3b877f08 Michael Hanselmann
                                  ["?", "value"]])
1648 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1649 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1650 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, False)],
1651 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, True)],
1652 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, True)],
1653 3b877f08 Michael Hanselmann
      ])
1654 3b877f08 Michael Hanselmann
1655 23d0a608 Michael Hanselmann
  def testFilterRegex(self):
1656 23d0a608 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1657 23d0a608 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1658 23d0a608 Michael Hanselmann
       None, 0, lambda ctx, item: item["name"]),
1659 23d0a608 Michael Hanselmann
      ], [])
1660 23d0a608 Michael Hanselmann
1661 23d0a608 Michael Hanselmann
    data = [
1662 23d0a608 Michael Hanselmann
      { "name": "node1.example.com", },
1663 23d0a608 Michael Hanselmann
      { "name": "node2.site.example.com", },
1664 23d0a608 Michael Hanselmann
      { "name": "node2.example.net", },
1665 23d0a608 Michael Hanselmann
1666 23d0a608 Michael Hanselmann
      # Empty name
1667 23d0a608 Michael Hanselmann
      { "name": "", },
1668 23d0a608 Michael Hanselmann
      ]
1669 23d0a608 Michael Hanselmann
1670 23d0a608 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1671 2e5c33db Iustin Pop
                    qfilter=["=~", "name", "site"])
1672 23d0a608 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1673 23d0a608 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1674 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.site.example.com")],
1675 23d0a608 Michael Hanselmann
      ])
1676 23d0a608 Michael Hanselmann
1677 23d0a608 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1678 2e5c33db Iustin Pop
                    qfilter=["=~", "name", "^node2"])
1679 23d0a608 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1680 23d0a608 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1681 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.net")],
1682 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.site.example.com")],
1683 23d0a608 Michael Hanselmann
      ])
1684 23d0a608 Michael Hanselmann
1685 23d0a608 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1686 2e5c33db Iustin Pop
                    qfilter=["=~", "name", r"(?i)\.COM$"])
1687 23d0a608 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1688 23d0a608 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1689 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node1.example.com")],
1690 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.site.example.com")],
1691 23d0a608 Michael Hanselmann
      ])
1692 23d0a608 Michael Hanselmann
1693 23d0a608 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1694 2e5c33db Iustin Pop
                    qfilter=["=~", "name", r"."])
1695 23d0a608 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1696 23d0a608 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1697 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node1.example.com")],
1698 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.net")],
1699 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.site.example.com")],
1700 23d0a608 Michael Hanselmann
      ])
1701 23d0a608 Michael Hanselmann
1702 23d0a608 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1703 2e5c33db Iustin Pop
                    qfilter=["=~", "name", r"^$"])
1704 23d0a608 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1705 23d0a608 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1706 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "")],
1707 23d0a608 Michael Hanselmann
      ])
1708 23d0a608 Michael Hanselmann
1709 23d0a608 Michael Hanselmann
    # Invalid regular expression
1710 23d0a608 Michael Hanselmann
    self.assertRaises(errors.ParameterError, query.Query, fielddefs, ["name"],
1711 2e5c33db Iustin Pop
                      qfilter=["=~", "name", r"["])
1712 23d0a608 Michael Hanselmann
1713 fb0be379 Michael Hanselmann
1714 4ca96421 Michael Hanselmann
if __name__ == "__main__":
1715 4ca96421 Michael Hanselmann
  testutils.GanetiTestProgram()