Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.query_unittest.py @ 5fa3d337

History | View | Annotate | Download (64.9 kB)

1 4ca96421 Michael Hanselmann
#!/usr/bin/python
2 4ca96421 Michael Hanselmann
#
3 4ca96421 Michael Hanselmann
4 e2d188cc Iustin Pop
# Copyright (C) 2010, 2011 Google Inc.
5 4ca96421 Michael Hanselmann
#
6 4ca96421 Michael Hanselmann
# This program is free software; you can redistribute it and/or modify
7 4ca96421 Michael Hanselmann
# it under the terms of the GNU General Public License as published by
8 4ca96421 Michael Hanselmann
# the Free Software Foundation; either version 2 of the License, or
9 4ca96421 Michael Hanselmann
# (at your option) any later version.
10 4ca96421 Michael Hanselmann
#
11 4ca96421 Michael Hanselmann
# This program is distributed in the hope that it will be useful, but
12 4ca96421 Michael Hanselmann
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 4ca96421 Michael Hanselmann
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 4ca96421 Michael Hanselmann
# General Public License for more details.
15 4ca96421 Michael Hanselmann
#
16 4ca96421 Michael Hanselmann
# You should have received a copy of the GNU General Public License
17 4ca96421 Michael Hanselmann
# along with this program; if not, write to the Free Software
18 4ca96421 Michael Hanselmann
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 4ca96421 Michael Hanselmann
# 02110-1301, USA.
20 4ca96421 Michael Hanselmann
21 4ca96421 Michael Hanselmann
22 4ca96421 Michael Hanselmann
"""Script for testing ganeti.query"""
23 4ca96421 Michael Hanselmann
24 4ca96421 Michael Hanselmann
import re
25 4ca96421 Michael Hanselmann
import unittest
26 aa29e95f Michael Hanselmann
import random
27 4ca96421 Michael Hanselmann
28 4ca96421 Michael Hanselmann
from ganeti import constants
29 4ca96421 Michael Hanselmann
from ganeti import utils
30 4ca96421 Michael Hanselmann
from ganeti import compat
31 4ca96421 Michael Hanselmann
from ganeti import errors
32 4ca96421 Michael Hanselmann
from ganeti import query
33 4ca96421 Michael Hanselmann
from ganeti import objects
34 1c8addc6 Michael Hanselmann
from ganeti import cmdlib
35 4ca96421 Michael Hanselmann
36 4ca96421 Michael Hanselmann
import testutils
37 4ca96421 Michael Hanselmann
38 4ca96421 Michael Hanselmann
39 4ca96421 Michael Hanselmann
class TestConstants(unittest.TestCase):
40 4ca96421 Michael Hanselmann
  def test(self):
41 4ca96421 Michael Hanselmann
    self.assertEqual(set(query._VERIFY_FN.keys()),
42 4ca96421 Michael Hanselmann
                     constants.QFT_ALL)
43 4ca96421 Michael Hanselmann
44 4ca96421 Michael Hanselmann
45 4ca96421 Michael Hanselmann
class _QueryData:
46 4ca96421 Michael Hanselmann
  def __init__(self, data, **kwargs):
47 4ca96421 Michael Hanselmann
    self.data = data
48 4ca96421 Michael Hanselmann
49 4ca96421 Michael Hanselmann
    for name, value in kwargs.items():
50 4ca96421 Michael Hanselmann
      setattr(self, name, value)
51 4ca96421 Michael Hanselmann
52 4ca96421 Michael Hanselmann
  def __iter__(self):
53 4ca96421 Michael Hanselmann
    return iter(self.data)
54 4ca96421 Michael Hanselmann
55 4ca96421 Michael Hanselmann
56 4ca96421 Michael Hanselmann
def _GetDiskSize(nr, ctx, item):
57 4ca96421 Michael Hanselmann
  disks = item["disks"]
58 4ca96421 Michael Hanselmann
  try:
59 e2d188cc Iustin Pop
    return disks[nr]
60 4ca96421 Michael Hanselmann
  except IndexError:
61 e2d188cc Iustin Pop
    return query._FS_UNAVAIL
62 4ca96421 Michael Hanselmann
63 4ca96421 Michael Hanselmann
64 4ca96421 Michael Hanselmann
class TestQuery(unittest.TestCase):
65 4ca96421 Michael Hanselmann
  def test(self):
66 4ca96421 Michael Hanselmann
    (STATIC, DISK) = range(10, 12)
67 4ca96421 Michael Hanselmann
68 4ca96421 Michael Hanselmann
    fielddef = query._PrepareFieldList([
69 79b2ca83 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
70 111bf531 Michael Hanselmann
       STATIC, 0, lambda ctx, item: item["name"]),
71 79b2ca83 Michael Hanselmann
      (query._MakeField("master", "Master", constants.QFT_BOOL, "Master"),
72 111bf531 Michael Hanselmann
       STATIC, 0, lambda ctx, item: ctx.mastername == item["name"]),
73 4ca96421 Michael Hanselmann
      ] +
74 4ca96421 Michael Hanselmann
      [(query._MakeField("disk%s.size" % i, "DiskSize%s" % i,
75 79b2ca83 Michael Hanselmann
                         constants.QFT_UNIT, "Disk size %s" % i),
76 111bf531 Michael Hanselmann
        DISK, 0, compat.partial(_GetDiskSize, i))
77 d63bd540 Iustin Pop
       for i in range(4)], [])
78 4ca96421 Michael Hanselmann
79 4ca96421 Michael Hanselmann
    q = query.Query(fielddef, ["name"])
80 4ca96421 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([STATIC]))
81 4ca96421 Michael Hanselmann
    self.assertEqual(len(q._fields), 1)
82 4ca96421 Michael Hanselmann
    self.assertEqual(len(q.GetFields()), 1)
83 4ca96421 Michael Hanselmann
    self.assertEqual(q.GetFields()[0].ToDict(),
84 4ca96421 Michael Hanselmann
      objects.QueryFieldDefinition(name="name",
85 4ca96421 Michael Hanselmann
                                   title="Name",
86 79b2ca83 Michael Hanselmann
                                   kind=constants.QFT_TEXT,
87 79b2ca83 Michael Hanselmann
                                   doc="Name").ToDict())
88 4ca96421 Michael Hanselmann
89 4ca96421 Michael Hanselmann
    # Create data only once query has been prepared
90 4ca96421 Michael Hanselmann
    data = [
91 4ca96421 Michael Hanselmann
      { "name": "node1", "disks": [0, 1, 2], },
92 4ca96421 Michael Hanselmann
      { "name": "node2", "disks": [3, 4], },
93 4ca96421 Michael Hanselmann
      { "name": "node3", "disks": [5, 6, 7], },
94 4ca96421 Michael Hanselmann
      ]
95 4ca96421 Michael Hanselmann
96 4ca96421 Michael Hanselmann
    self.assertEqual(q.Query(_QueryData(data, mastername="node3")),
97 cfb084ae René Nussbaumer
                     [[(constants.RS_NORMAL, "node1")],
98 cfb084ae René Nussbaumer
                      [(constants.RS_NORMAL, "node2")],
99 cfb084ae René Nussbaumer
                      [(constants.RS_NORMAL, "node3")]])
100 4ca96421 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(_QueryData(data, mastername="node3")),
101 4ca96421 Michael Hanselmann
                     [["node1"], ["node2"], ["node3"]])
102 4ca96421 Michael Hanselmann
103 4ca96421 Michael Hanselmann
    q = query.Query(fielddef, ["name", "master"])
104 4ca96421 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([STATIC]))
105 4ca96421 Michael Hanselmann
    self.assertEqual(len(q._fields), 2)
106 4ca96421 Michael Hanselmann
    self.assertEqual(q.Query(_QueryData(data, mastername="node3")),
107 cfb084ae René Nussbaumer
                     [[(constants.RS_NORMAL, "node1"),
108 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, False)],
109 cfb084ae René Nussbaumer
                      [(constants.RS_NORMAL, "node2"),
110 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, False)],
111 cfb084ae René Nussbaumer
                      [(constants.RS_NORMAL, "node3"),
112 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, True)],
113 4ca96421 Michael Hanselmann
                     ])
114 4ca96421 Michael Hanselmann
115 4ca96421 Michael Hanselmann
    q = query.Query(fielddef, ["name", "master", "disk0.size"])
116 4ca96421 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([STATIC, DISK]))
117 4ca96421 Michael Hanselmann
    self.assertEqual(len(q._fields), 3)
118 4ca96421 Michael Hanselmann
    self.assertEqual(q.Query(_QueryData(data, mastername="node2")),
119 cfb084ae René Nussbaumer
                     [[(constants.RS_NORMAL, "node1"),
120 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, False),
121 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 0)],
122 cfb084ae René Nussbaumer
                      [(constants.RS_NORMAL, "node2"),
123 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, True),
124 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 3)],
125 cfb084ae René Nussbaumer
                      [(constants.RS_NORMAL, "node3"),
126 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, False),
127 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 5)],
128 4ca96421 Michael Hanselmann
                     ])
129 4ca96421 Michael Hanselmann
130 4ca96421 Michael Hanselmann
    # With unknown column
131 4ca96421 Michael Hanselmann
    q = query.Query(fielddef, ["disk2.size", "disk1.size", "disk99.size",
132 4ca96421 Michael Hanselmann
                               "disk0.size"])
133 4ca96421 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DISK]))
134 4ca96421 Michael Hanselmann
    self.assertEqual(len(q._fields), 4)
135 4ca96421 Michael Hanselmann
    self.assertEqual(q.Query(_QueryData(data, mastername="node2")),
136 cfb084ae René Nussbaumer
                     [[(constants.RS_NORMAL, 2),
137 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 1),
138 cfb084ae René Nussbaumer
                       (constants.RS_UNKNOWN, None),
139 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 0)],
140 cfb084ae René Nussbaumer
                      [(constants.RS_UNAVAIL, None),
141 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 4),
142 cfb084ae René Nussbaumer
                       (constants.RS_UNKNOWN, None),
143 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 3)],
144 cfb084ae René Nussbaumer
                      [(constants.RS_NORMAL, 7),
145 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 6),
146 cfb084ae René Nussbaumer
                       (constants.RS_UNKNOWN, None),
147 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 5)],
148 4ca96421 Michael Hanselmann
                     ])
149 4ca96421 Michael Hanselmann
    self.assertRaises(errors.OpPrereqError, q.OldStyleQuery,
150 4ca96421 Michael Hanselmann
                      _QueryData(data, mastername="node2"))
151 4ca96421 Michael Hanselmann
    self.assertEqual([fdef.ToDict() for fdef in q.GetFields()], [
152 4ca96421 Michael Hanselmann
                     { "name": "disk2.size", "title": "DiskSize2",
153 79b2ca83 Michael Hanselmann
                       "kind": constants.QFT_UNIT, "doc": "Disk size 2", },
154 4ca96421 Michael Hanselmann
                     { "name": "disk1.size", "title": "DiskSize1",
155 79b2ca83 Michael Hanselmann
                       "kind": constants.QFT_UNIT, "doc": "Disk size 1", },
156 4ca96421 Michael Hanselmann
                     { "name": "disk99.size", "title": "disk99.size",
157 79b2ca83 Michael Hanselmann
                       "kind": constants.QFT_UNKNOWN,
158 79b2ca83 Michael Hanselmann
                       "doc": "Unknown field 'disk99.size'", },
159 4ca96421 Michael Hanselmann
                     { "name": "disk0.size", "title": "DiskSize0",
160 79b2ca83 Michael Hanselmann
                       "kind": constants.QFT_UNIT, "doc": "Disk size 0", },
161 4ca96421 Michael Hanselmann
                     ])
162 4ca96421 Michael Hanselmann
163 4ca96421 Michael Hanselmann
    # Empty query
164 4ca96421 Michael Hanselmann
    q = query.Query(fielddef, [])
165 4ca96421 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([]))
166 4ca96421 Michael Hanselmann
    self.assertEqual(len(q._fields), 0)
167 4ca96421 Michael Hanselmann
    self.assertEqual(q.Query(_QueryData(data, mastername="node2")),
168 4ca96421 Michael Hanselmann
                     [[], [], []])
169 4ca96421 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(_QueryData(data, mastername="node2")),
170 4ca96421 Michael Hanselmann
                     [[], [], []])
171 4ca96421 Michael Hanselmann
    self.assertEqual(q.GetFields(), [])
172 4ca96421 Michael Hanselmann
173 4ca96421 Michael Hanselmann
  def testPrepareFieldList(self):
174 4ca96421 Michael Hanselmann
    # Duplicate titles
175 4ca96421 Michael Hanselmann
    for (a, b) in [("name", "name"), ("NAME", "name")]:
176 4ca96421 Michael Hanselmann
      self.assertRaises(AssertionError, query._PrepareFieldList, [
177 111bf531 Michael Hanselmann
        (query._MakeField("name", b, constants.QFT_TEXT, "Name"), None, 0,
178 4ca96421 Michael Hanselmann
         lambda *args: None),
179 111bf531 Michael Hanselmann
        (query._MakeField("other", a, constants.QFT_TEXT, "Other"), None, 0,
180 4ca96421 Michael Hanselmann
         lambda *args: None),
181 d63bd540 Iustin Pop
        ], [])
182 4ca96421 Michael Hanselmann
183 4ca96421 Michael Hanselmann
    # Non-lowercase names
184 4ca96421 Michael Hanselmann
    self.assertRaises(AssertionError, query._PrepareFieldList, [
185 111bf531 Michael Hanselmann
      (query._MakeField("NAME", "Name", constants.QFT_TEXT, "Name"), None, 0,
186 4ca96421 Michael Hanselmann
       lambda *args: None),
187 d63bd540 Iustin Pop
      ], [])
188 4ca96421 Michael Hanselmann
    self.assertRaises(AssertionError, query._PrepareFieldList, [
189 111bf531 Michael Hanselmann
      (query._MakeField("Name", "Name", constants.QFT_TEXT, "Name"), None, 0,
190 4ca96421 Michael Hanselmann
       lambda *args: None),
191 d63bd540 Iustin Pop
      ], [])
192 4ca96421 Michael Hanselmann
193 4ca96421 Michael Hanselmann
    # Empty name
194 4ca96421 Michael Hanselmann
    self.assertRaises(AssertionError, query._PrepareFieldList, [
195 111bf531 Michael Hanselmann
      (query._MakeField("", "Name", constants.QFT_TEXT, "Name"), None, 0,
196 4ca96421 Michael Hanselmann
       lambda *args: None),
197 d63bd540 Iustin Pop
      ], [])
198 4ca96421 Michael Hanselmann
199 4ca96421 Michael Hanselmann
    # Empty title
200 4ca96421 Michael Hanselmann
    self.assertRaises(AssertionError, query._PrepareFieldList, [
201 111bf531 Michael Hanselmann
      (query._MakeField("name", "", constants.QFT_TEXT, "Name"), None, 0,
202 4ca96421 Michael Hanselmann
       lambda *args: None),
203 d63bd540 Iustin Pop
      ], [])
204 4ca96421 Michael Hanselmann
205 4ca96421 Michael Hanselmann
    # Whitespace in title
206 4ca96421 Michael Hanselmann
    self.assertRaises(AssertionError, query._PrepareFieldList, [
207 111bf531 Michael Hanselmann
      (query._MakeField("name", "Co lu mn", constants.QFT_TEXT, "Name"),
208 111bf531 Michael Hanselmann
       None, 0, lambda *args: None),
209 d63bd540 Iustin Pop
      ], [])
210 4ca96421 Michael Hanselmann
211 4ca96421 Michael Hanselmann
    # No callable function
212 4ca96421 Michael Hanselmann
    self.assertRaises(AssertionError, query._PrepareFieldList, [
213 79b2ca83 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
214 111bf531 Michael Hanselmann
       None, 0, None),
215 d63bd540 Iustin Pop
      ], [])
216 4ca96421 Michael Hanselmann
217 79b2ca83 Michael Hanselmann
    # Invalid documentation
218 79b2ca83 Michael Hanselmann
    for doc in ["", ".", "Hello world\n", "Hello\nWo\nrld", "Hello World!",
219 79b2ca83 Michael Hanselmann
                "HelloWorld.", "only lowercase", ",", " x y z .\t", "  "]:
220 79b2ca83 Michael Hanselmann
      self.assertRaises(AssertionError, query._PrepareFieldList, [
221 79b2ca83 Michael Hanselmann
        (query._MakeField("name", "Name", constants.QFT_TEXT, doc),
222 111bf531 Michael Hanselmann
        None, 0, lambda *args: None),
223 79b2ca83 Michael Hanselmann
        ], [])
224 79b2ca83 Michael Hanselmann
225 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 8235fe04 Michael Hanselmann
    nodes = [
326 8235fe04 Michael Hanselmann
      objects.Node(name="node1", drained=False),
327 8235fe04 Michael Hanselmann
      objects.Node(name="node2", drained=True),
328 8235fe04 Michael Hanselmann
      objects.Node(name="node3", drained=False),
329 8235fe04 Michael Hanselmann
      ]
330 8235fe04 Michael Hanselmann
    for live_data in [None, dict.fromkeys([node.name for node in nodes], {})]:
331 8572f1fe René Nussbaumer
      nqd = query.NodeQueryData(nodes, live_data, None, None, None, None, None,
332 8572f1fe René Nussbaumer
                                None)
333 8235fe04 Michael Hanselmann
334 8235fe04 Michael Hanselmann
      q = self._Create(["name", "drained"])
335 8235fe04 Michael Hanselmann
      self.assertEqual(q.RequestedData(), set([query.NQ_CONFIG]))
336 8235fe04 Michael Hanselmann
      self.assertEqual(q.Query(nqd),
337 cfb084ae René Nussbaumer
                       [[(constants.RS_NORMAL, "node1"),
338 cfb084ae René Nussbaumer
                         (constants.RS_NORMAL, False)],
339 cfb084ae René Nussbaumer
                        [(constants.RS_NORMAL, "node2"),
340 cfb084ae René Nussbaumer
                         (constants.RS_NORMAL, True)],
341 cfb084ae René Nussbaumer
                        [(constants.RS_NORMAL, "node3"),
342 cfb084ae René Nussbaumer
                         (constants.RS_NORMAL, False)],
343 8235fe04 Michael Hanselmann
                       ])
344 8235fe04 Michael Hanselmann
      self.assertEqual(q.OldStyleQuery(nqd),
345 8235fe04 Michael Hanselmann
                       [["node1", False],
346 8235fe04 Michael Hanselmann
                        ["node2", True],
347 8235fe04 Michael Hanselmann
                        ["node3", False]])
348 8235fe04 Michael Hanselmann
349 8235fe04 Michael Hanselmann
  def test(self):
350 8235fe04 Michael Hanselmann
    selected = query.NODE_FIELDS.keys()
351 8235fe04 Michael Hanselmann
    field_index = dict((field, idx) for idx, field in enumerate(selected))
352 8235fe04 Michael Hanselmann
353 8235fe04 Michael Hanselmann
    q = self._Create(selected)
354 8235fe04 Michael Hanselmann
    self.assertEqual(q.RequestedData(),
355 8235fe04 Michael Hanselmann
                     set([query.NQ_CONFIG, query.NQ_LIVE, query.NQ_INST,
356 52b5d286 René Nussbaumer
                          query.NQ_GROUP, query.NQ_OOB]))
357 8235fe04 Michael Hanselmann
358 8572f1fe René Nussbaumer
    cluster = objects.Cluster(cluster_name="testcluster",
359 8572f1fe René Nussbaumer
      hvparams=constants.HVC_DEFAULTS,
360 8572f1fe René Nussbaumer
      beparams={
361 8572f1fe René Nussbaumer
        constants.PP_DEFAULT: constants.BEC_DEFAULTS,
362 8572f1fe René Nussbaumer
        },
363 8572f1fe René Nussbaumer
      nicparams={
364 8572f1fe René Nussbaumer
        constants.PP_DEFAULT: constants.NICC_DEFAULTS,
365 8572f1fe René Nussbaumer
        },
366 8572f1fe René Nussbaumer
      ndparams=constants.NDC_DEFAULTS,
367 8572f1fe René Nussbaumer
        )
368 8572f1fe René Nussbaumer
369 8235fe04 Michael Hanselmann
    node_names = ["node%s" % i for i in range(20)]
370 8235fe04 Michael Hanselmann
    master_name = node_names[3]
371 8235fe04 Michael Hanselmann
    nodes = [
372 8235fe04 Michael Hanselmann
      objects.Node(name=name,
373 8235fe04 Michael Hanselmann
                   primary_ip="192.0.2.%s" % idx,
374 8235fe04 Michael Hanselmann
                   secondary_ip="192.0.100.%s" % idx,
375 8235fe04 Michael Hanselmann
                   serial_no=7789 * idx,
376 8235fe04 Michael Hanselmann
                   master_candidate=(name != master_name and idx % 3 == 0),
377 8235fe04 Michael Hanselmann
                   offline=False,
378 8235fe04 Michael Hanselmann
                   drained=False,
379 b12d5e2e René Nussbaumer
                   powered=True,
380 effab4ca Iustin Pop
                   vm_capable=True,
381 8235fe04 Michael Hanselmann
                   master_capable=False,
382 8572f1fe René Nussbaumer
                   ndparams={},
383 8235fe04 Michael Hanselmann
                   group="default",
384 8235fe04 Michael Hanselmann
                   ctime=1290006900,
385 8235fe04 Michael Hanselmann
                   mtime=1290006913,
386 8235fe04 Michael Hanselmann
                   uuid="fd9ccebe-6339-43c9-a82e-94bbe575%04d" % idx)
387 8235fe04 Michael Hanselmann
      for idx, name in enumerate(node_names)
388 8235fe04 Michael Hanselmann
      ]
389 8235fe04 Michael Hanselmann
390 8235fe04 Michael Hanselmann
    master_node = nodes[3]
391 8235fe04 Michael Hanselmann
    master_node.AddTag("masternode")
392 8235fe04 Michael Hanselmann
    master_node.AddTag("another")
393 8235fe04 Michael Hanselmann
    master_node.AddTag("tag")
394 145bea54 Michael Hanselmann
    master_node.ctime = None
395 145bea54 Michael Hanselmann
    master_node.mtime = None
396 8235fe04 Michael Hanselmann
    assert master_node.name == master_name
397 8235fe04 Michael Hanselmann
398 8235fe04 Michael Hanselmann
    live_data_name = node_names[4]
399 8235fe04 Michael Hanselmann
    assert live_data_name != master_name
400 8235fe04 Michael Hanselmann
401 8235fe04 Michael Hanselmann
    fake_live_data = {
402 8235fe04 Michael Hanselmann
      "bootid": "a2504766-498e-4b25-b21e-d23098dc3af4",
403 8235fe04 Michael Hanselmann
      "cnodes": 4,
404 8235fe04 Michael Hanselmann
      "csockets": 4,
405 8235fe04 Michael Hanselmann
      "ctotal": 8,
406 8235fe04 Michael Hanselmann
      "mnode": 128,
407 8235fe04 Michael Hanselmann
      "mfree": 100,
408 8235fe04 Michael Hanselmann
      "mtotal": 4096,
409 8235fe04 Michael Hanselmann
      "dfree": 5 * 1024 * 1024,
410 8235fe04 Michael Hanselmann
      "dtotal": 100 * 1024 * 1024,
411 8235fe04 Michael Hanselmann
      }
412 8235fe04 Michael Hanselmann
413 8235fe04 Michael Hanselmann
    assert (sorted(query._NODE_LIVE_FIELDS.keys()) ==
414 8235fe04 Michael Hanselmann
            sorted(fake_live_data.keys()))
415 8235fe04 Michael Hanselmann
416 8235fe04 Michael Hanselmann
    live_data = dict.fromkeys(node_names, {})
417 8235fe04 Michael Hanselmann
    live_data[live_data_name] = \
418 8235fe04 Michael Hanselmann
      dict((query._NODE_LIVE_FIELDS[name][2], value)
419 8235fe04 Michael Hanselmann
           for name, value in fake_live_data.items())
420 8235fe04 Michael Hanselmann
421 8235fe04 Michael Hanselmann
    node_to_primary = dict((name, set()) for name in node_names)
422 8235fe04 Michael Hanselmann
    node_to_primary[master_name].update(["inst1", "inst2"])
423 8235fe04 Michael Hanselmann
424 8235fe04 Michael Hanselmann
    node_to_secondary = dict((name, set()) for name in node_names)
425 8235fe04 Michael Hanselmann
    node_to_secondary[live_data_name].update(["instX", "instY", "instZ"])
426 8235fe04 Michael Hanselmann
427 8235fe04 Michael Hanselmann
    ng_uuid = "492b4b74-8670-478a-b98d-4c53a76238e6"
428 8235fe04 Michael Hanselmann
    groups = {
429 8572f1fe René Nussbaumer
      ng_uuid: objects.NodeGroup(name="ng1", uuid=ng_uuid, ndparams={}),
430 8235fe04 Michael Hanselmann
      }
431 8235fe04 Michael Hanselmann
432 b12d5e2e René Nussbaumer
    oob_not_powered_node = node_names[0]
433 b12d5e2e René Nussbaumer
    nodes[0].powered = False
434 52b5d286 René Nussbaumer
    oob_support = dict((name, False) for name in node_names)
435 b12d5e2e René Nussbaumer
    oob_support[master_name] = True
436 b12d5e2e René Nussbaumer
    oob_support[oob_not_powered_node] = True
437 52b5d286 René Nussbaumer
438 8235fe04 Michael Hanselmann
    master_node.group = ng_uuid
439 8235fe04 Michael Hanselmann
440 8235fe04 Michael Hanselmann
    nqd = query.NodeQueryData(nodes, live_data, master_name,
441 52b5d286 René Nussbaumer
                              node_to_primary, node_to_secondary, groups,
442 8572f1fe René Nussbaumer
                              oob_support, cluster)
443 8235fe04 Michael Hanselmann
    result = q.Query(nqd)
444 8235fe04 Michael Hanselmann
    self.assert_(compat.all(len(row) == len(selected) for row in result))
445 8235fe04 Michael Hanselmann
    self.assertEqual([row[field_index["name"]] for row in result],
446 cfb084ae René Nussbaumer
                     [(constants.RS_NORMAL, name) for name in node_names])
447 8235fe04 Michael Hanselmann
448 8235fe04 Michael Hanselmann
    node_to_row = dict((row[field_index["name"]][1], idx)
449 8235fe04 Michael Hanselmann
                       for idx, row in enumerate(result))
450 8235fe04 Michael Hanselmann
451 8235fe04 Michael Hanselmann
    master_row = result[node_to_row[master_name]]
452 8235fe04 Michael Hanselmann
    self.assert_(master_row[field_index["master"]])
453 8235fe04 Michael Hanselmann
    self.assert_(master_row[field_index["role"]], "M")
454 8235fe04 Michael Hanselmann
    self.assertEqual(master_row[field_index["group"]],
455 cfb084ae René Nussbaumer
                     (constants.RS_NORMAL, "ng1"))
456 8235fe04 Michael Hanselmann
    self.assertEqual(master_row[field_index["group.uuid"]],
457 cfb084ae René Nussbaumer
                     (constants.RS_NORMAL, ng_uuid))
458 145bea54 Michael Hanselmann
    self.assertEqual(master_row[field_index["ctime"]],
459 cfb084ae René Nussbaumer
                     (constants.RS_UNAVAIL, None))
460 145bea54 Michael Hanselmann
    self.assertEqual(master_row[field_index["mtime"]],
461 cfb084ae René Nussbaumer
                     (constants.RS_UNAVAIL, None))
462 8235fe04 Michael Hanselmann
463 8235fe04 Michael Hanselmann
    self.assert_(row[field_index["pip"]] == node.primary_ip and
464 8235fe04 Michael Hanselmann
                 row[field_index["sip"]] == node.secondary_ip and
465 8235fe04 Michael Hanselmann
                 set(row[field_index["tags"]]) == node.GetTags() and
466 8235fe04 Michael Hanselmann
                 row[field_index["serial_no"]] == node.serial_no and
467 8235fe04 Michael Hanselmann
                 row[field_index["role"]] == query._GetNodeRole(node,
468 8235fe04 Michael Hanselmann
                                                                master_name) and
469 8235fe04 Michael Hanselmann
                 (node.name == master_name or
470 8235fe04 Michael Hanselmann
                  (row[field_index["group"]] == "<unknown>" and
471 145bea54 Michael Hanselmann
                   row[field_index["group.uuid"]] is None and
472 cfb084ae René Nussbaumer
                   row[field_index["ctime"]] == (constants.RS_NORMAL,
473 145bea54 Michael Hanselmann
                                                 node.ctime) and
474 cfb084ae René Nussbaumer
                   row[field_index["mtime"]] == (constants.RS_NORMAL,
475 b12d5e2e René Nussbaumer
                                                 node.mtime) and
476 b12d5e2e René Nussbaumer
                   row[field_index["powered"]] == (constants.RS_NORMAL,
477 b12d5e2e René Nussbaumer
                                                   True))) or
478 b12d5e2e René Nussbaumer
                 (node.name == oob_not_powered_node and
479 b12d5e2e René Nussbaumer
                  row[field_index["powered"]] == (constants.RS_NORMAL,
480 b12d5e2e René Nussbaumer
                                                  False)) or
481 b12d5e2e René Nussbaumer
                 row[field_index["powered"]] == (constants.RS_UNAVAIL, None)
482 8235fe04 Michael Hanselmann
                 for row, node in zip(result, nodes))
483 8235fe04 Michael Hanselmann
484 8235fe04 Michael Hanselmann
    live_data_row = result[node_to_row[live_data_name]]
485 8235fe04 Michael Hanselmann
486 8235fe04 Michael Hanselmann
    for (field, value) in fake_live_data.items():
487 8235fe04 Michael Hanselmann
      self.assertEqual(live_data_row[field_index[field]],
488 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, value))
489 8235fe04 Michael Hanselmann
490 8235fe04 Michael Hanselmann
    self.assertEqual(master_row[field_index["pinst_cnt"]],
491 cfb084ae René Nussbaumer
                     (constants.RS_NORMAL, 2))
492 8235fe04 Michael Hanselmann
    self.assertEqual(live_data_row[field_index["sinst_cnt"]],
493 cfb084ae René Nussbaumer
                     (constants.RS_NORMAL, 3))
494 8235fe04 Michael Hanselmann
    self.assertEqual(master_row[field_index["pinst_list"]],
495 cfb084ae René Nussbaumer
                     (constants.RS_NORMAL,
496 8235fe04 Michael Hanselmann
                      list(node_to_primary[master_name])))
497 8235fe04 Michael Hanselmann
    self.assertEqual(live_data_row[field_index["sinst_list"]],
498 cfb084ae René Nussbaumer
                     (constants.RS_NORMAL,
499 8235fe04 Michael Hanselmann
                      list(node_to_secondary[live_data_name])))
500 8235fe04 Michael Hanselmann
501 8235fe04 Michael Hanselmann
  def testGetLiveNodeField(self):
502 8235fe04 Michael Hanselmann
    nodes = [
503 effab4ca Iustin Pop
      objects.Node(name="node1", drained=False, offline=False,
504 effab4ca Iustin Pop
                   vm_capable=True),
505 effab4ca Iustin Pop
      objects.Node(name="node2", drained=True, offline=False,
506 effab4ca Iustin Pop
                   vm_capable=True),
507 effab4ca Iustin Pop
      objects.Node(name="node3", drained=False, offline=False,
508 effab4ca Iustin Pop
                   vm_capable=True),
509 effab4ca Iustin Pop
      objects.Node(name="node4", drained=False, offline=True,
510 effab4ca Iustin Pop
                   vm_capable=True),
511 effab4ca Iustin Pop
      objects.Node(name="node5", drained=False, offline=False,
512 effab4ca Iustin Pop
                   vm_capable=False),
513 8235fe04 Michael Hanselmann
      ]
514 8235fe04 Michael Hanselmann
    live_data = dict.fromkeys([node.name for node in nodes], {})
515 8235fe04 Michael Hanselmann
516 8235fe04 Michael Hanselmann
    # No data
517 8572f1fe René Nussbaumer
    nqd = query.NodeQueryData(None, None, None, None, None, None, None, None)
518 8235fe04 Michael Hanselmann
    self.assertEqual(query._GetLiveNodeField("hello", constants.QFT_NUMBER,
519 a6070ef7 Michael Hanselmann
                                             nqd, nodes[0]),
520 e2d188cc Iustin Pop
                     query._FS_NODATA)
521 8235fe04 Michael Hanselmann
522 8235fe04 Michael Hanselmann
    # Missing field
523 8235fe04 Michael Hanselmann
    ctx = _QueryData(None, curlive_data={
524 8235fe04 Michael Hanselmann
      "some": 1,
525 8235fe04 Michael Hanselmann
      "other": 2,
526 8235fe04 Michael Hanselmann
      })
527 8235fe04 Michael Hanselmann
    self.assertEqual(query._GetLiveNodeField("hello", constants.QFT_NUMBER,
528 a6070ef7 Michael Hanselmann
                                             ctx, nodes[0]),
529 e2d188cc Iustin Pop
                     query._FS_UNAVAIL)
530 8235fe04 Michael Hanselmann
531 8235fe04 Michael Hanselmann
    # Wrong format/datatype
532 8235fe04 Michael Hanselmann
    ctx = _QueryData(None, curlive_data={
533 8235fe04 Michael Hanselmann
      "hello": ["Hello World"],
534 8235fe04 Michael Hanselmann
      "other": 2,
535 8235fe04 Michael Hanselmann
      })
536 8235fe04 Michael Hanselmann
    self.assertEqual(query._GetLiveNodeField("hello", constants.QFT_NUMBER,
537 a6070ef7 Michael Hanselmann
                                             ctx, nodes[0]),
538 e2d188cc Iustin Pop
                     query._FS_UNAVAIL)
539 8235fe04 Michael Hanselmann
540 a6070ef7 Michael Hanselmann
    # Offline node
541 a6070ef7 Michael Hanselmann
    assert nodes[3].offline
542 a6070ef7 Michael Hanselmann
    ctx = _QueryData(None, curlive_data={})
543 a6070ef7 Michael Hanselmann
    self.assertEqual(query._GetLiveNodeField("hello", constants.QFT_NUMBER,
544 a6070ef7 Michael Hanselmann
                                             ctx, nodes[3]),
545 e2d188cc Iustin Pop
                     query._FS_OFFLINE, None)
546 a6070ef7 Michael Hanselmann
547 8235fe04 Michael Hanselmann
    # Wrong field type
548 8235fe04 Michael Hanselmann
    ctx = _QueryData(None, curlive_data={"hello": 123})
549 8235fe04 Michael Hanselmann
    self.assertRaises(AssertionError, query._GetLiveNodeField,
550 a6070ef7 Michael Hanselmann
                      "hello", constants.QFT_BOOL, ctx, nodes[0])
551 8235fe04 Michael Hanselmann
552 effab4ca Iustin Pop
    # Non-vm_capable node
553 effab4ca Iustin Pop
    assert not nodes[4].vm_capable
554 effab4ca Iustin Pop
    ctx = _QueryData(None, curlive_data={})
555 effab4ca Iustin Pop
    self.assertEqual(query._GetLiveNodeField("hello", constants.QFT_NUMBER,
556 effab4ca Iustin Pop
                                             ctx, nodes[4]),
557 effab4ca Iustin Pop
                     query._FS_UNAVAIL, None)
558 effab4ca Iustin Pop
559 8235fe04 Michael Hanselmann
560 1c8addc6 Michael Hanselmann
class TestInstanceQuery(unittest.TestCase):
561 1c8addc6 Michael Hanselmann
  def _Create(self, selected):
562 1c8addc6 Michael Hanselmann
    return query.Query(query.INSTANCE_FIELDS, selected)
563 1c8addc6 Michael Hanselmann
564 1c8addc6 Michael Hanselmann
  def testSimple(self):
565 861610e9 Guido Trotter
    q = self._Create(["name", "be/maxmem", "ip"])
566 1c8addc6 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([query.IQ_CONFIG]))
567 1c8addc6 Michael Hanselmann
568 1c8addc6 Michael Hanselmann
    cluster = objects.Cluster(cluster_name="testcluster",
569 1c8addc6 Michael Hanselmann
      hvparams=constants.HVC_DEFAULTS,
570 1c8addc6 Michael Hanselmann
      beparams={
571 1c8addc6 Michael Hanselmann
        constants.PP_DEFAULT: constants.BEC_DEFAULTS,
572 1c8addc6 Michael Hanselmann
        },
573 1c8addc6 Michael Hanselmann
      nicparams={
574 1c8addc6 Michael Hanselmann
        constants.PP_DEFAULT: constants.NICC_DEFAULTS,
575 7c670076 Michael Hanselmann
        },
576 7c670076 Michael Hanselmann
      os_hvp={},
577 7c670076 Michael Hanselmann
      osparams={})
578 1c8addc6 Michael Hanselmann
579 1c8addc6 Michael Hanselmann
    instances = [
580 7c670076 Michael Hanselmann
      objects.Instance(name="inst1", hvparams={}, beparams={}, osparams={},
581 7c670076 Michael Hanselmann
                       nics=[], os="deb1"),
582 7c670076 Michael Hanselmann
      objects.Instance(name="inst2", hvparams={}, nics=[], osparams={},
583 7c670076 Michael Hanselmann
        os="foomoo",
584 1c8addc6 Michael Hanselmann
        beparams={
585 861610e9 Guido Trotter
          constants.BE_MAXMEM: 512,
586 1c8addc6 Michael Hanselmann
        }),
587 7c670076 Michael Hanselmann
      objects.Instance(name="inst3", hvparams={}, beparams={}, osparams={},
588 7c670076 Michael Hanselmann
        os="dos", nics=[objects.NIC(ip="192.0.2.99", nicparams={})]),
589 1c8addc6 Michael Hanselmann
      ]
590 1c8addc6 Michael Hanselmann
591 5d28cb6f Michael Hanselmann
    iqd = query.InstanceQueryData(instances, cluster, None, [], [], {},
592 fab9573b Michael Hanselmann
                                  set(), {}, None, None)
593 1c8addc6 Michael Hanselmann
    self.assertEqual(q.Query(iqd),
594 cfb084ae René Nussbaumer
      [[(constants.RS_NORMAL, "inst1"),
595 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, 128),
596 cfb084ae René Nussbaumer
        (constants.RS_UNAVAIL, None),
597 1c8addc6 Michael Hanselmann
       ],
598 cfb084ae René Nussbaumer
       [(constants.RS_NORMAL, "inst2"),
599 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, 512),
600 cfb084ae René Nussbaumer
        (constants.RS_UNAVAIL, None),
601 1c8addc6 Michael Hanselmann
       ],
602 cfb084ae René Nussbaumer
       [(constants.RS_NORMAL, "inst3"),
603 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, 128),
604 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, "192.0.2.99"),
605 1c8addc6 Michael Hanselmann
       ]])
606 1c8addc6 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(iqd),
607 1c8addc6 Michael Hanselmann
      [["inst1", 128, None],
608 1c8addc6 Michael Hanselmann
       ["inst2", 512, None],
609 1c8addc6 Michael Hanselmann
       ["inst3", 128, "192.0.2.99"]])
610 1c8addc6 Michael Hanselmann
611 1c8addc6 Michael Hanselmann
  def test(self):
612 1c8addc6 Michael Hanselmann
    selected = query.INSTANCE_FIELDS.keys()
613 1c8addc6 Michael Hanselmann
    fieldidx = dict((field, idx) for idx, field in enumerate(selected))
614 1c8addc6 Michael Hanselmann
615 1c8addc6 Michael Hanselmann
    macs = ["00:11:22:%02x:%02x:%02x" % (i % 255, i % 3, (i * 123) % 255)
616 1c8addc6 Michael Hanselmann
            for i in range(20)]
617 1c8addc6 Michael Hanselmann
618 1c8addc6 Michael Hanselmann
    q = self._Create(selected)
619 1c8addc6 Michael Hanselmann
    self.assertEqual(q.RequestedData(),
620 5d28cb6f Michael Hanselmann
                     set([query.IQ_CONFIG, query.IQ_LIVE, query.IQ_DISKUSAGE,
621 fab9573b Michael Hanselmann
                          query.IQ_CONSOLE, query.IQ_NODES]))
622 1c8addc6 Michael Hanselmann
623 1c8addc6 Michael Hanselmann
    cluster = objects.Cluster(cluster_name="testcluster",
624 1c8addc6 Michael Hanselmann
      hvparams=constants.HVC_DEFAULTS,
625 1c8addc6 Michael Hanselmann
      beparams={
626 1c8addc6 Michael Hanselmann
        constants.PP_DEFAULT: constants.BEC_DEFAULTS,
627 1c8addc6 Michael Hanselmann
        },
628 1c8addc6 Michael Hanselmann
      nicparams={
629 1c8addc6 Michael Hanselmann
        constants.PP_DEFAULT: constants.NICC_DEFAULTS,
630 1c8addc6 Michael Hanselmann
        },
631 1c8addc6 Michael Hanselmann
      os_hvp={},
632 7c670076 Michael Hanselmann
      tcpudp_port_pool=set(),
633 7c670076 Michael Hanselmann
      osparams={
634 7c670076 Michael Hanselmann
        "deb99": {
635 7c670076 Michael Hanselmann
          "clean_install": "yes",
636 7c670076 Michael Hanselmann
          },
637 7c670076 Michael Hanselmann
        })
638 1c8addc6 Michael Hanselmann
639 1c8addc6 Michael Hanselmann
    offline_nodes = ["nodeoff1", "nodeoff2"]
640 1c8addc6 Michael Hanselmann
    bad_nodes = ["nodebad1", "nodebad2", "nodebad3"] + offline_nodes
641 1c8addc6 Michael Hanselmann
    nodes = ["node%s" % i for i in range(10)] + bad_nodes
642 1c8addc6 Michael Hanselmann
643 1c8addc6 Michael Hanselmann
    instances = [
644 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst1", hvparams={}, beparams={}, nics=[],
645 1c8addc6 Michael Hanselmann
        uuid="f90eccb3-e227-4e3c-bf2a-94a21ca8f9cd",
646 1c8addc6 Michael Hanselmann
        ctime=1291244000, mtime=1291244400, serial_no=30,
647 2e04d454 Agata Murawska
        admin_state=constants.ADMINST_UP, hypervisor=constants.HT_XEN_PVM,
648 2e04d454 Agata Murawska
        os="linux1",
649 1c8addc6 Michael Hanselmann
        primary_node="node1",
650 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_PLAIN,
651 7c670076 Michael Hanselmann
        disks=[],
652 7c670076 Michael Hanselmann
        osparams={}),
653 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst2", hvparams={}, nics=[],
654 1c8addc6 Michael Hanselmann
        uuid="73a0f8a7-068c-4630-ada2-c3440015ab1a",
655 1c8addc6 Michael Hanselmann
        ctime=1291211000, mtime=1291211077, serial_no=1,
656 2e04d454 Agata Murawska
        admin_state=constants.ADMINST_UP, hypervisor=constants.HT_XEN_HVM,
657 2e04d454 Agata Murawska
        os="deb99",
658 1c8addc6 Michael Hanselmann
        primary_node="node5",
659 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DISKLESS,
660 1c8addc6 Michael Hanselmann
        disks=[],
661 1c8addc6 Michael Hanselmann
        beparams={
662 861610e9 Guido Trotter
          constants.BE_MAXMEM: 512,
663 861610e9 Guido Trotter
          constants.BE_MINMEM: 256,
664 7c670076 Michael Hanselmann
        },
665 7c670076 Michael Hanselmann
        osparams={}),
666 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst3", hvparams={}, beparams={},
667 1c8addc6 Michael Hanselmann
        uuid="11ec8dff-fb61-4850-bfe0-baa1803ff280",
668 1c8addc6 Michael Hanselmann
        ctime=1291011000, mtime=1291013000, serial_no=1923,
669 2e04d454 Agata Murawska
        admin_state=constants.ADMINST_DOWN, hypervisor=constants.HT_KVM,
670 2e04d454 Agata Murawska
        os="busybox",
671 1c8addc6 Michael Hanselmann
        primary_node="node6",
672 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DRBD8,
673 1c8addc6 Michael Hanselmann
        disks=[],
674 1c8addc6 Michael Hanselmann
        nics=[
675 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.99", mac=macs.pop(),
676 1c8addc6 Michael Hanselmann
                      nicparams={
677 1c8addc6 Michael Hanselmann
                        constants.NIC_LINK: constants.DEFAULT_BRIDGE,
678 1c8addc6 Michael Hanselmann
                        }),
679 1c8addc6 Michael Hanselmann
          objects.NIC(ip=None, mac=macs.pop(), nicparams={}),
680 7c670076 Michael Hanselmann
          ],
681 7c670076 Michael Hanselmann
        osparams={}),
682 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst4", hvparams={}, beparams={},
683 1c8addc6 Michael Hanselmann
        uuid="68dab168-3ef5-4c9d-b4d3-801e0672068c",
684 1c8addc6 Michael Hanselmann
        ctime=1291244390, mtime=1291244395, serial_no=25,
685 2e04d454 Agata Murawska
        admin_state=constants.ADMINST_DOWN, hypervisor=constants.HT_XEN_PVM,
686 2e04d454 Agata Murawska
        os="linux1",
687 1c8addc6 Michael Hanselmann
        primary_node="nodeoff2",
688 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DRBD8,
689 1c8addc6 Michael Hanselmann
        disks=[],
690 1c8addc6 Michael Hanselmann
        nics=[
691 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.1", mac=macs.pop(),
692 1c8addc6 Michael Hanselmann
                      nicparams={
693 1c8addc6 Michael Hanselmann
                        constants.NIC_LINK: constants.DEFAULT_BRIDGE,
694 1c8addc6 Michael Hanselmann
                        }),
695 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.2", mac=macs.pop(), nicparams={}),
696 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.3", mac=macs.pop(),
697 1c8addc6 Michael Hanselmann
                      nicparams={
698 1c8addc6 Michael Hanselmann
                        constants.NIC_MODE: constants.NIC_MODE_ROUTED,
699 1c8addc6 Michael Hanselmann
                        }),
700 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.4", mac=macs.pop(),
701 1c8addc6 Michael Hanselmann
                      nicparams={
702 1c8addc6 Michael Hanselmann
                        constants.NIC_MODE: constants.NIC_MODE_BRIDGED,
703 1c8addc6 Michael Hanselmann
                        constants.NIC_LINK: "eth123",
704 1c8addc6 Michael Hanselmann
                        }),
705 7c670076 Michael Hanselmann
          ],
706 7c670076 Michael Hanselmann
        osparams={}),
707 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst5", hvparams={}, nics=[],
708 1c8addc6 Michael Hanselmann
        uuid="0e3dca12-5b42-4e24-98a2-415267545bd0",
709 1c8addc6 Michael Hanselmann
        ctime=1231211000, mtime=1261200000, serial_no=3,
710 2e04d454 Agata Murawska
        admin_state=constants.ADMINST_UP, hypervisor=constants.HT_XEN_HVM,
711 2e04d454 Agata Murawska
        os="deb99",
712 1c8addc6 Michael Hanselmann
        primary_node="nodebad2",
713 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DISKLESS,
714 1c8addc6 Michael Hanselmann
        disks=[],
715 1c8addc6 Michael Hanselmann
        beparams={
716 861610e9 Guido Trotter
          constants.BE_MAXMEM: 512,
717 861610e9 Guido Trotter
          constants.BE_MINMEM: 512,
718 7c670076 Michael Hanselmann
        },
719 7c670076 Michael Hanselmann
        osparams={}),
720 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst6", hvparams={}, nics=[],
721 1c8addc6 Michael Hanselmann
        uuid="72de6580-c8d5-4661-b902-38b5785bb8b3",
722 1c8addc6 Michael Hanselmann
        ctime=7513, mtime=11501, serial_no=13390,
723 2e04d454 Agata Murawska
        admin_state=constants.ADMINST_DOWN, hypervisor=constants.HT_XEN_HVM,
724 2e04d454 Agata Murawska
        os="deb99",
725 1c8addc6 Michael Hanselmann
        primary_node="node7",
726 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DISKLESS,
727 1c8addc6 Michael Hanselmann
        disks=[],
728 1c8addc6 Michael Hanselmann
        beparams={
729 861610e9 Guido Trotter
          constants.BE_MAXMEM: 768,
730 861610e9 Guido Trotter
          constants.BE_MINMEM: 256,
731 7c670076 Michael Hanselmann
        },
732 7c670076 Michael Hanselmann
        osparams={
733 7c670076 Michael Hanselmann
          "clean_install": "no",
734 7c670076 Michael Hanselmann
          }),
735 145bea54 Michael Hanselmann
      objects.Instance(name="inst7", hvparams={}, nics=[],
736 145bea54 Michael Hanselmann
        uuid="ceec5dc4-b729-4f42-ae28-69b3cd24920e",
737 145bea54 Michael Hanselmann
        ctime=None, mtime=None, serial_no=1947,
738 2e04d454 Agata Murawska
        admin_state=constants.ADMINST_DOWN, hypervisor=constants.HT_XEN_HVM,
739 2e04d454 Agata Murawska
        os="deb99",
740 2e04d454 Agata Murawska
        primary_node="node6",
741 2e04d454 Agata Murawska
        disk_template=constants.DT_DISKLESS,
742 2e04d454 Agata Murawska
        disks=[],
743 2e04d454 Agata Murawska
        beparams={},
744 2e04d454 Agata Murawska
        osparams={}),
745 2e04d454 Agata Murawska
      objects.Instance(name="inst8", hvparams={}, nics=[],
746 2e04d454 Agata Murawska
        uuid="ceec5dc4-b729-4f42-ae28-69b3cd24920f",
747 2e04d454 Agata Murawska
        ctime=None, mtime=None, serial_no=19478,
748 2e04d454 Agata Murawska
        admin_state=constants.ADMINST_OFFLINE, hypervisor=constants.HT_XEN_HVM,
749 2e04d454 Agata Murawska
        os="deb99",
750 145bea54 Michael Hanselmann
        primary_node="node6",
751 145bea54 Michael Hanselmann
        disk_template=constants.DT_DISKLESS,
752 145bea54 Michael Hanselmann
        disks=[],
753 7c670076 Michael Hanselmann
        beparams={},
754 7c670076 Michael Hanselmann
        osparams={}),
755 1c8addc6 Michael Hanselmann
      ]
756 1c8addc6 Michael Hanselmann
757 145bea54 Michael Hanselmann
    assert not utils.FindDuplicates(inst.name for inst in instances)
758 145bea54 Michael Hanselmann
759 5d28cb6f Michael Hanselmann
    instbyname = dict((inst.name, inst) for inst in instances)
760 5d28cb6f Michael Hanselmann
761 1c8addc6 Michael Hanselmann
    disk_usage = dict((inst.name,
762 1c8addc6 Michael Hanselmann
                       cmdlib._ComputeDiskSize(inst.disk_template,
763 1c8addc6 Michael Hanselmann
                                               [{"size": disk.size}
764 1c8addc6 Michael Hanselmann
                                                for disk in inst.disks]))
765 1c8addc6 Michael Hanselmann
                      for inst in instances)
766 1c8addc6 Michael Hanselmann
767 1c8addc6 Michael Hanselmann
    inst_bridges = {
768 1c8addc6 Michael Hanselmann
      "inst3": [constants.DEFAULT_BRIDGE, constants.DEFAULT_BRIDGE],
769 1c8addc6 Michael Hanselmann
      "inst4": [constants.DEFAULT_BRIDGE, constants.DEFAULT_BRIDGE,
770 1c8addc6 Michael Hanselmann
                None, "eth123"],
771 1c8addc6 Michael Hanselmann
      }
772 1c8addc6 Michael Hanselmann
773 1c8addc6 Michael Hanselmann
    live_data = {
774 1c8addc6 Michael Hanselmann
      "inst2": {
775 1c8addc6 Michael Hanselmann
        "vcpus": 3,
776 1c8addc6 Michael Hanselmann
        },
777 1c8addc6 Michael Hanselmann
      "inst4": {
778 1c8addc6 Michael Hanselmann
        "memory": 123,
779 1c8addc6 Michael Hanselmann
        },
780 1c8addc6 Michael Hanselmann
      "inst6": {
781 1c8addc6 Michael Hanselmann
        "memory": 768,
782 1c8addc6 Michael Hanselmann
        },
783 bacae536 René Nussbaumer
      "inst7": {
784 bacae536 René Nussbaumer
        "vcpus": 3,
785 bacae536 René Nussbaumer
        },
786 1c8addc6 Michael Hanselmann
      }
787 bacae536 René Nussbaumer
    wrongnode_inst = set(["inst7"])
788 1c8addc6 Michael Hanselmann
789 5d28cb6f Michael Hanselmann
    consinfo = dict((inst.name, None) for inst in instances)
790 5d28cb6f Michael Hanselmann
    consinfo["inst7"] = \
791 5d28cb6f Michael Hanselmann
      objects.InstanceConsole(instance="inst7", kind=constants.CONS_SSH,
792 5d28cb6f Michael Hanselmann
                              host=instbyname["inst7"].primary_node,
793 5d28cb6f Michael Hanselmann
                              user=constants.GANETI_RUNAS,
794 5d28cb6f Michael Hanselmann
                              command=["hostname"]).ToDict()
795 5d28cb6f Michael Hanselmann
796 1c8addc6 Michael Hanselmann
    iqd = query.InstanceQueryData(instances, cluster, disk_usage,
797 e431074f René Nussbaumer
                                  offline_nodes, bad_nodes, live_data,
798 fab9573b Michael Hanselmann
                                  wrongnode_inst, consinfo, {}, {})
799 1c8addc6 Michael Hanselmann
    result = q.Query(iqd)
800 1c8addc6 Michael Hanselmann
    self.assertEqual(len(result), len(instances))
801 1c8addc6 Michael Hanselmann
    self.assert_(compat.all(len(row) == len(selected)
802 1c8addc6 Michael Hanselmann
                            for row in result))
803 1c8addc6 Michael Hanselmann
804 1c8addc6 Michael Hanselmann
    assert len(set(bad_nodes) & set(offline_nodes)) == len(offline_nodes), \
805 1c8addc6 Michael Hanselmann
           "Offline nodes not included in bad nodes"
806 1c8addc6 Michael Hanselmann
807 1c8addc6 Michael Hanselmann
    tested_status = set()
808 1c8addc6 Michael Hanselmann
809 1c8addc6 Michael Hanselmann
    for (inst, row) in zip(instances, result):
810 1c8addc6 Michael Hanselmann
      assert inst.primary_node in nodes
811 1c8addc6 Michael Hanselmann
812 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["name"]],
813 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, inst.name))
814 1c8addc6 Michael Hanselmann
815 1c8addc6 Michael Hanselmann
      if inst.primary_node in offline_nodes:
816 61a980a9 Michael Hanselmann
        exp_status = constants.INSTST_NODEOFFLINE
817 1c8addc6 Michael Hanselmann
      elif inst.primary_node in bad_nodes:
818 61a980a9 Michael Hanselmann
        exp_status = constants.INSTST_NODEDOWN
819 1c8addc6 Michael Hanselmann
      elif inst.name in live_data:
820 e431074f René Nussbaumer
        if inst.name in wrongnode_inst:
821 61a980a9 Michael Hanselmann
          exp_status = constants.INSTST_WRONGNODE
822 2e04d454 Agata Murawska
        elif inst.admin_state == constants.ADMINST_UP:
823 61a980a9 Michael Hanselmann
          exp_status = constants.INSTST_RUNNING
824 1c8addc6 Michael Hanselmann
        else:
825 61a980a9 Michael Hanselmann
          exp_status = constants.INSTST_ERRORUP
826 2e04d454 Agata Murawska
      elif inst.admin_state == constants.ADMINST_UP:
827 61a980a9 Michael Hanselmann
        exp_status = constants.INSTST_ERRORDOWN
828 2e04d454 Agata Murawska
      elif inst.admin_state == constants.ADMINST_DOWN:
829 61a980a9 Michael Hanselmann
        exp_status = constants.INSTST_ADMINDOWN
830 2e04d454 Agata Murawska
      else:
831 2e04d454 Agata Murawska
        exp_status = constants.INSTST_ADMINOFFLINE
832 1c8addc6 Michael Hanselmann
833 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["status"]],
834 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, exp_status))
835 1c8addc6 Michael Hanselmann
836 1c8addc6 Michael Hanselmann
      (_, status) = row[fieldidx["status"]]
837 1c8addc6 Michael Hanselmann
      tested_status.add(status)
838 1c8addc6 Michael Hanselmann
839 861610e9 Guido Trotter
      #FIXME(dynmem): check oper_ram vs min/max mem
840 861610e9 Guido Trotter
      for (field, livefield) in [("oper_vcpus", "vcpus")]:
841 1c8addc6 Michael Hanselmann
        if inst.primary_node in bad_nodes:
842 cfb084ae René Nussbaumer
          exp = (constants.RS_NODATA, None)
843 1c8addc6 Michael Hanselmann
        elif inst.name in live_data:
844 1c8addc6 Michael Hanselmann
          value = live_data[inst.name].get(livefield, None)
845 1c8addc6 Michael Hanselmann
          if value is None:
846 cfb084ae René Nussbaumer
            exp = (constants.RS_UNAVAIL, None)
847 1c8addc6 Michael Hanselmann
          else:
848 cfb084ae René Nussbaumer
            exp = (constants.RS_NORMAL, value)
849 1c8addc6 Michael Hanselmann
        else:
850 cfb084ae René Nussbaumer
          exp = (constants.RS_UNAVAIL, None)
851 1c8addc6 Michael Hanselmann
852 1c8addc6 Michael Hanselmann
        self.assertEqual(row[fieldidx[field]], exp)
853 1c8addc6 Michael Hanselmann
854 1c8addc6 Michael Hanselmann
      bridges = inst_bridges.get(inst.name, [])
855 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["nic.bridges"]],
856 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, bridges))
857 1c8addc6 Michael Hanselmann
      if bridges:
858 1c8addc6 Michael Hanselmann
        self.assertEqual(row[fieldidx["bridge"]],
859 cfb084ae René Nussbaumer
                         (constants.RS_NORMAL, bridges[0]))
860 1c8addc6 Michael Hanselmann
      else:
861 1c8addc6 Michael Hanselmann
        self.assertEqual(row[fieldidx["bridge"]],
862 cfb084ae René Nussbaumer
                         (constants.RS_UNAVAIL, None))
863 1c8addc6 Michael Hanselmann
864 1c8addc6 Michael Hanselmann
      for i in range(constants.MAX_NICS):
865 1c8addc6 Michael Hanselmann
        if i < len(bridges) and bridges[i] is not None:
866 cfb084ae René Nussbaumer
          exp = (constants.RS_NORMAL, bridges[i])
867 1c8addc6 Michael Hanselmann
        else:
868 cfb084ae René Nussbaumer
          exp = (constants.RS_UNAVAIL, None)
869 1c8addc6 Michael Hanselmann
        self.assertEqual(row[fieldidx["nic.bridge/%s" % i]], exp)
870 1c8addc6 Michael Hanselmann
871 1c8addc6 Michael Hanselmann
      if inst.primary_node in bad_nodes:
872 cfb084ae René Nussbaumer
        exp = (constants.RS_NODATA, None)
873 1c8addc6 Michael Hanselmann
      else:
874 cfb084ae René Nussbaumer
        exp = (constants.RS_NORMAL, inst.name in live_data)
875 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["oper_state"]], exp)
876 1c8addc6 Michael Hanselmann
877 7c670076 Michael Hanselmann
      cust_exp = (constants.RS_NORMAL, {})
878 7c670076 Michael Hanselmann
      if inst.os == "deb99":
879 7c670076 Michael Hanselmann
        if inst.name == "inst6":
880 7c670076 Michael Hanselmann
          exp = (constants.RS_NORMAL, {"clean_install": "no"})
881 7c670076 Michael Hanselmann
          cust_exp = exp
882 7c670076 Michael Hanselmann
        else:
883 7c670076 Michael Hanselmann
          exp = (constants.RS_NORMAL, {"clean_install": "yes"})
884 7c670076 Michael Hanselmann
      else:
885 7c670076 Michael Hanselmann
        exp = (constants.RS_NORMAL, {})
886 7c670076 Michael Hanselmann
      self.assertEqual(row[fieldidx["osparams"]], exp)
887 7c670076 Michael Hanselmann
      self.assertEqual(row[fieldidx["custom_osparams"]], cust_exp)
888 7c670076 Michael Hanselmann
889 1c8addc6 Michael Hanselmann
      usage = disk_usage[inst.name]
890 1c8addc6 Michael Hanselmann
      if usage is None:
891 1c8addc6 Michael Hanselmann
        usage = 0
892 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["disk_usage"]],
893 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, usage))
894 1c8addc6 Michael Hanselmann
895 4cc4d1fa Michael Hanselmann
      for alias, target in [("sda_size", "disk.size/0"),
896 4cc4d1fa Michael Hanselmann
                            ("sdb_size", "disk.size/1"),
897 4cc4d1fa Michael Hanselmann
                            ("vcpus", "be/vcpus"),
898 4cc4d1fa Michael Hanselmann
                            ("ip", "nic.ip/0"),
899 4cc4d1fa Michael Hanselmann
                            ("mac", "nic.mac/0"),
900 4cc4d1fa Michael Hanselmann
                            ("bridge", "nic.bridge/0"),
901 4cc4d1fa Michael Hanselmann
                            ("nic_mode", "nic.mode/0"),
902 4cc4d1fa Michael Hanselmann
                            ("nic_link", "nic.link/0"),
903 4cc4d1fa Michael Hanselmann
                            ]:
904 4cc4d1fa Michael Hanselmann
        self.assertEqual(row[fieldidx[alias]], row[fieldidx[target]])
905 1c8addc6 Michael Hanselmann
906 145bea54 Michael Hanselmann
      for field in ["ctime", "mtime"]:
907 145bea54 Michael Hanselmann
        if getattr(inst, field) is None:
908 145bea54 Michael Hanselmann
          # No ctime/mtime
909 cfb084ae René Nussbaumer
          exp = (constants.RS_UNAVAIL, None)
910 145bea54 Michael Hanselmann
        else:
911 cfb084ae René Nussbaumer
          exp = (constants.RS_NORMAL, getattr(inst, field))
912 145bea54 Michael Hanselmann
        self.assertEqual(row[fieldidx[field]], exp)
913 145bea54 Michael Hanselmann
914 5d28cb6f Michael Hanselmann
      self._CheckInstanceConsole(inst, row[fieldidx["console"]])
915 5d28cb6f Michael Hanselmann
916 1c8addc6 Michael Hanselmann
    # Ensure all possible status' have been tested
917 61a980a9 Michael Hanselmann
    self.assertEqual(tested_status, constants.INSTST_ALL)
918 1c8addc6 Michael Hanselmann
919 5d28cb6f Michael Hanselmann
  def _CheckInstanceConsole(self, instance, (status, consdata)):
920 5d28cb6f Michael Hanselmann
    if instance.name == "inst7":
921 5d28cb6f Michael Hanselmann
      self.assertEqual(status, constants.RS_NORMAL)
922 5d28cb6f Michael Hanselmann
      console = objects.InstanceConsole.FromDict(consdata)
923 5d28cb6f Michael Hanselmann
      self.assertTrue(console.Validate())
924 5d28cb6f Michael Hanselmann
      self.assertEqual(console.host, instance.primary_node)
925 5d28cb6f Michael Hanselmann
    else:
926 5d28cb6f Michael Hanselmann
      self.assertEqual(status, constants.RS_UNAVAIL)
927 5d28cb6f Michael Hanselmann
928 1c8addc6 Michael Hanselmann
929 d8b7ff5f Adeodato Simo
class TestGroupQuery(unittest.TestCase):
930 d8b7ff5f Adeodato Simo
931 d8b7ff5f Adeodato Simo
  def setUp(self):
932 d8b7ff5f Adeodato Simo
    self.groups = [
933 d8b7ff5f Adeodato Simo
      objects.NodeGroup(name="default",
934 d8b7ff5f Adeodato Simo
                        uuid="c0e89160-18e7-11e0-a46e-001d0904baeb",
935 edd49f9b Agata Murawska
                        alloc_policy=constants.ALLOC_POLICY_PREFERRED,
936 edd49f9b Agata Murawska
                        ipolicy=objects.MakeEmptyIPolicy()),
937 d8b7ff5f Adeodato Simo
      objects.NodeGroup(name="restricted",
938 d8b7ff5f Adeodato Simo
                        uuid="d2a40a74-18e7-11e0-9143-001d0904baeb",
939 edd49f9b Agata Murawska
                        alloc_policy=constants.ALLOC_POLICY_LAST_RESORT,
940 edd49f9b Agata Murawska
                        ipolicy=objects.MakeEmptyIPolicy()),
941 d8b7ff5f Adeodato Simo
      ]
942 edd49f9b Agata Murawska
    self.cluster = objects.Cluster(cluster_name="testcluster",
943 edd49f9b Agata Murawska
      hvparams=constants.HVC_DEFAULTS,
944 edd49f9b Agata Murawska
      beparams={
945 edd49f9b Agata Murawska
        constants.PP_DEFAULT: constants.BEC_DEFAULTS,
946 edd49f9b Agata Murawska
        },
947 edd49f9b Agata Murawska
      nicparams={
948 edd49f9b Agata Murawska
        constants.PP_DEFAULT: constants.NICC_DEFAULTS,
949 edd49f9b Agata Murawska
        },
950 edd49f9b Agata Murawska
      ndparams=constants.NDC_DEFAULTS,
951 edd49f9b Agata Murawska
      ipolicy=constants.IPOLICY_DEFAULTS,
952 edd49f9b Agata Murawska
      )
953 d8b7ff5f Adeodato Simo
954 d8b7ff5f Adeodato Simo
  def _Create(self, selected):
955 d8b7ff5f Adeodato Simo
    return query.Query(query.GROUP_FIELDS, selected)
956 d8b7ff5f Adeodato Simo
957 d8b7ff5f Adeodato Simo
  def testSimple(self):
958 d8b7ff5f Adeodato Simo
    q = self._Create(["name", "uuid", "alloc_policy"])
959 edd49f9b Agata Murawska
    gqd = query.GroupQueryData(self.cluster, self.groups, None, None)
960 d8b7ff5f Adeodato Simo
961 d8b7ff5f Adeodato Simo
    self.assertEqual(q.RequestedData(), set([query.GQ_CONFIG]))
962 d8b7ff5f Adeodato Simo
963 d8b7ff5f Adeodato Simo
    self.assertEqual(q.Query(gqd),
964 cfb084ae René Nussbaumer
      [[(constants.RS_NORMAL, "default"),
965 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, "c0e89160-18e7-11e0-a46e-001d0904baeb"),
966 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, constants.ALLOC_POLICY_PREFERRED)
967 d8b7ff5f Adeodato Simo
        ],
968 cfb084ae René Nussbaumer
       [(constants.RS_NORMAL, "restricted"),
969 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, "d2a40a74-18e7-11e0-9143-001d0904baeb"),
970 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, constants.ALLOC_POLICY_LAST_RESORT)
971 d8b7ff5f Adeodato Simo
        ],
972 d8b7ff5f Adeodato Simo
       ])
973 d8b7ff5f Adeodato Simo
974 d8b7ff5f Adeodato Simo
  def testNodes(self):
975 d8b7ff5f Adeodato Simo
    groups_to_nodes = {
976 d8b7ff5f Adeodato Simo
      "c0e89160-18e7-11e0-a46e-001d0904baeb": ["node1", "node2"],
977 d8b7ff5f Adeodato Simo
      "d2a40a74-18e7-11e0-9143-001d0904baeb": ["node1", "node10", "node9"],
978 d8b7ff5f Adeodato Simo
      }
979 d8b7ff5f Adeodato Simo
980 d8b7ff5f Adeodato Simo
    q = self._Create(["name", "node_cnt", "node_list"])
981 edd49f9b Agata Murawska
    gqd = query.GroupQueryData(self.cluster, self.groups, groups_to_nodes, None)
982 d8b7ff5f Adeodato Simo
983 d8b7ff5f Adeodato Simo
    self.assertEqual(q.RequestedData(), set([query.GQ_CONFIG, query.GQ_NODE]))
984 d8b7ff5f Adeodato Simo
985 d8b7ff5f Adeodato Simo
    self.assertEqual(q.Query(gqd),
986 cfb084ae René Nussbaumer
                     [[(constants.RS_NORMAL, "default"),
987 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 2),
988 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, ["node1", "node2"]),
989 d8b7ff5f Adeodato Simo
                       ],
990 cfb084ae René Nussbaumer
                      [(constants.RS_NORMAL, "restricted"),
991 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 3),
992 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, ["node1", "node9", "node10"]),
993 d8b7ff5f Adeodato Simo
                       ],
994 d8b7ff5f Adeodato Simo
                      ])
995 d8b7ff5f Adeodato Simo
996 d8b7ff5f Adeodato Simo
  def testInstances(self):
997 d8b7ff5f Adeodato Simo
    groups_to_instances = {
998 d8b7ff5f Adeodato Simo
      "c0e89160-18e7-11e0-a46e-001d0904baeb": ["inst1", "inst2"],
999 d8b7ff5f Adeodato Simo
      "d2a40a74-18e7-11e0-9143-001d0904baeb": ["inst1", "inst10", "inst9"],
1000 d8b7ff5f Adeodato Simo
      }
1001 d8b7ff5f Adeodato Simo
1002 d8b7ff5f Adeodato Simo
    q = self._Create(["pinst_cnt", "pinst_list"])
1003 edd49f9b Agata Murawska
    gqd = query.GroupQueryData(self.cluster, self.groups, None,
1004 edd49f9b Agata Murawska
      groups_to_instances)
1005 d8b7ff5f Adeodato Simo
1006 d8b7ff5f Adeodato Simo
    self.assertEqual(q.RequestedData(), set([query.GQ_INST]))
1007 d8b7ff5f Adeodato Simo
1008 d8b7ff5f Adeodato Simo
    self.assertEqual(q.Query(gqd),
1009 cfb084ae René Nussbaumer
                     [[(constants.RS_NORMAL, 2),
1010 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, ["inst1", "inst2"]),
1011 d8b7ff5f Adeodato Simo
                       ],
1012 cfb084ae René Nussbaumer
                      [(constants.RS_NORMAL, 3),
1013 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, ["inst1", "inst9", "inst10"]),
1014 d8b7ff5f Adeodato Simo
                       ],
1015 d8b7ff5f Adeodato Simo
                      ])
1016 d8b7ff5f Adeodato Simo
1017 d8b7ff5f Adeodato Simo
1018 be3a4b14 Michael Hanselmann
class TestOsQuery(unittest.TestCase):
1019 be3a4b14 Michael Hanselmann
  def _Create(self, selected):
1020 be3a4b14 Michael Hanselmann
    return query.Query(query.OS_FIELDS, selected)
1021 be3a4b14 Michael Hanselmann
1022 be3a4b14 Michael Hanselmann
  def test(self):
1023 be3a4b14 Michael Hanselmann
    variants = ["v00", "plain", "v3", "var0", "v33", "v20"]
1024 be3a4b14 Michael Hanselmann
    api_versions = [10, 0, 15, 5]
1025 be3a4b14 Michael Hanselmann
    parameters = ["zpar3", "apar9"]
1026 be3a4b14 Michael Hanselmann
1027 be3a4b14 Michael Hanselmann
    assert variants != sorted(variants) and variants != utils.NiceSort(variants)
1028 be3a4b14 Michael Hanselmann
    assert (api_versions != sorted(api_versions) and
1029 be3a4b14 Michael Hanselmann
            api_versions != utils.NiceSort(variants))
1030 be3a4b14 Michael Hanselmann
    assert (parameters != sorted(parameters) and
1031 be3a4b14 Michael Hanselmann
            parameters != utils.NiceSort(parameters))
1032 be3a4b14 Michael Hanselmann
1033 be3a4b14 Michael Hanselmann
    data = [
1034 be3a4b14 Michael Hanselmann
      query.OsInfo(name="debian", valid=False, hidden=False, blacklisted=False,
1035 be3a4b14 Michael Hanselmann
                   variants=set(), api_versions=set(), parameters=set(),
1036 be3a4b14 Michael Hanselmann
                   node_status={ "some": "status", }),
1037 be3a4b14 Michael Hanselmann
      query.OsInfo(name="dos", valid=True, hidden=False, blacklisted=True,
1038 be3a4b14 Michael Hanselmann
                   variants=set(variants),
1039 be3a4b14 Michael Hanselmann
                   api_versions=set(api_versions),
1040 be3a4b14 Michael Hanselmann
                   parameters=set(parameters),
1041 be3a4b14 Michael Hanselmann
                   node_status={ "some": "other", "status": None, }),
1042 be3a4b14 Michael Hanselmann
      ]
1043 be3a4b14 Michael Hanselmann
1044 be3a4b14 Michael Hanselmann
1045 be3a4b14 Michael Hanselmann
    q = self._Create(["name", "valid", "hidden", "blacklisted", "variants",
1046 be3a4b14 Michael Hanselmann
                      "api_versions", "parameters", "node_status"])
1047 be3a4b14 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([]))
1048 be3a4b14 Michael Hanselmann
    self.assertEqual(q.Query(data),
1049 be3a4b14 Michael Hanselmann
                     [[(constants.RS_NORMAL, "debian"),
1050 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, False),
1051 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, False),
1052 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, False),
1053 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, []),
1054 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, []),
1055 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, []),
1056 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, {"some": "status"})],
1057 be3a4b14 Michael Hanselmann
                      [(constants.RS_NORMAL, "dos"),
1058 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, True),
1059 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, False),
1060 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, True),
1061 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL,
1062 be3a4b14 Michael Hanselmann
                        ["plain", "v00", "v3", "v20", "v33", "var0"]),
1063 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, [0, 5, 10, 15]),
1064 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, ["apar9", "zpar3"]),
1065 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL,
1066 be3a4b14 Michael Hanselmann
                        { "some": "other", "status": None, })
1067 be3a4b14 Michael Hanselmann
                       ]])
1068 be3a4b14 Michael Hanselmann
1069 be3a4b14 Michael Hanselmann
1070 aa29e95f Michael Hanselmann
class TestQueryFields(unittest.TestCase):
1071 aa29e95f Michael Hanselmann
  def testAllFields(self):
1072 e571ee44 Adeodato Simo
    for fielddefs in query.ALL_FIELD_LISTS:
1073 aa29e95f Michael Hanselmann
      result = query.QueryFields(fielddefs, None)
1074 aa29e95f Michael Hanselmann
      self.assert_(isinstance(result, dict))
1075 aa29e95f Michael Hanselmann
      response = objects.QueryFieldsResponse.FromDict(result)
1076 aa29e95f Michael Hanselmann
      self.assertEqual([(fdef.name, fdef.title) for fdef in response.fields],
1077 aa29e95f Michael Hanselmann
        [(fdef2.name, fdef2.title)
1078 111bf531 Michael Hanselmann
         for (fdef2, _, _, _) in utils.NiceSort(fielddefs.values(),
1079 111bf531 Michael Hanselmann
                                                key=lambda x: x[0].name)])
1080 aa29e95f Michael Hanselmann
1081 aa29e95f Michael Hanselmann
  def testSomeFields(self):
1082 aa29e95f Michael Hanselmann
    rnd = random.Random(5357)
1083 aa29e95f Michael Hanselmann
1084 aa29e95f Michael Hanselmann
    for _ in range(10):
1085 e571ee44 Adeodato Simo
      for fielddefs in query.ALL_FIELD_LISTS:
1086 e571ee44 Adeodato Simo
        if len(fielddefs) > 20:
1087 e571ee44 Adeodato Simo
          sample_size = rnd.randint(5, 20)
1088 e571ee44 Adeodato Simo
        else:
1089 e571ee44 Adeodato Simo
          sample_size = rnd.randint(1, max(1, len(fielddefs) - 1))
1090 111bf531 Michael Hanselmann
        fields = [fdef for (fdef, _, _, _) in rnd.sample(fielddefs.values(),
1091 111bf531 Michael Hanselmann
                                                         sample_size)]
1092 aa29e95f Michael Hanselmann
        result = query.QueryFields(fielddefs, [fdef.name for fdef in fields])
1093 aa29e95f Michael Hanselmann
        self.assert_(isinstance(result, dict))
1094 aa29e95f Michael Hanselmann
        response = objects.QueryFieldsResponse.FromDict(result)
1095 aa29e95f Michael Hanselmann
        self.assertEqual([(fdef.name, fdef.title) for fdef in response.fields],
1096 aa29e95f Michael Hanselmann
                         [(fdef2.name, fdef2.title) for fdef2 in fields])
1097 aa29e95f Michael Hanselmann
1098 aa29e95f Michael Hanselmann
1099 fb0be379 Michael Hanselmann
class TestQueryFilter(unittest.TestCase):
1100 fb0be379 Michael Hanselmann
  def testRequestedNames(self):
1101 fb0be379 Michael Hanselmann
    innerfilter = [["=", "name", "x%s" % i] for i in range(4)]
1102 fb0be379 Michael Hanselmann
1103 fb0be379 Michael Hanselmann
    for fielddefs in query.ALL_FIELD_LISTS:
1104 fb0be379 Michael Hanselmann
      assert "name" in fielddefs
1105 fb0be379 Michael Hanselmann
1106 fb0be379 Michael Hanselmann
      # No name field
1107 2e5c33db Iustin Pop
      q = query.Query(fielddefs, ["name"], qfilter=["=", "name", "abc"],
1108 fb0be379 Michael Hanselmann
                      namefield=None)
1109 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), None)
1110 fb0be379 Michael Hanselmann
1111 fb0be379 Michael Hanselmann
      # No filter
1112 2e5c33db Iustin Pop
      q = query.Query(fielddefs, ["name"], qfilter=None, namefield="name")
1113 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), None)
1114 fb0be379 Michael Hanselmann
1115 fb0be379 Michael Hanselmann
      # Check empty query
1116 2e5c33db Iustin Pop
      q = query.Query(fielddefs, ["name"], qfilter=["|"], namefield="name")
1117 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), None)
1118 fb0be379 Michael Hanselmann
1119 fb0be379 Michael Hanselmann
      # Check order
1120 2e5c33db Iustin Pop
      q = query.Query(fielddefs, ["name"], qfilter=["|"] + innerfilter,
1121 fb0be379 Michael Hanselmann
                      namefield="name")
1122 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), ["x0", "x1", "x2", "x3"])
1123 fb0be379 Michael Hanselmann
1124 fb0be379 Michael Hanselmann
      # Check reverse order
1125 fb0be379 Michael Hanselmann
      q = query.Query(fielddefs, ["name"],
1126 2e5c33db Iustin Pop
                      qfilter=["|"] + list(reversed(innerfilter)),
1127 fb0be379 Michael Hanselmann
                      namefield="name")
1128 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), ["x3", "x2", "x1", "x0"])
1129 fb0be379 Michael Hanselmann
1130 fb0be379 Michael Hanselmann
      # Duplicates
1131 fb0be379 Michael Hanselmann
      q = query.Query(fielddefs, ["name"],
1132 2e5c33db Iustin Pop
                      qfilter=["|"] + innerfilter + list(reversed(innerfilter)),
1133 fb0be379 Michael Hanselmann
                      namefield="name")
1134 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), ["x0", "x1", "x2", "x3"])
1135 fb0be379 Michael Hanselmann
1136 fb0be379 Michael Hanselmann
      # Unknown name field
1137 fb0be379 Michael Hanselmann
      self.assertRaises(AssertionError, query.Query, fielddefs, ["name"],
1138 fb0be379 Michael Hanselmann
                        namefield="_unknown_field_")
1139 fb0be379 Michael Hanselmann
1140 fb0be379 Michael Hanselmann
      # Filter with AND
1141 fb0be379 Michael Hanselmann
      q = query.Query(fielddefs, ["name"],
1142 2e5c33db Iustin Pop
                      qfilter=["|", ["=", "name", "foo"],
1143 fb0be379 Michael Hanselmann
                                    ["&", ["=", "name", ""]]],
1144 fb0be379 Michael Hanselmann
                      namefield="name")
1145 fb0be379 Michael Hanselmann
      self.assertTrue(q.RequestedNames() is None)
1146 fb0be379 Michael Hanselmann
1147 fb0be379 Michael Hanselmann
      # Filter with NOT
1148 fb0be379 Michael Hanselmann
      q = query.Query(fielddefs, ["name"],
1149 2e5c33db Iustin Pop
                      qfilter=["|", ["=", "name", "foo"],
1150 fb0be379 Michael Hanselmann
                                    ["!", ["=", "name", ""]]],
1151 fb0be379 Michael Hanselmann
                      namefield="name")
1152 fb0be379 Michael Hanselmann
      self.assertTrue(q.RequestedNames() is None)
1153 fb0be379 Michael Hanselmann
1154 fb0be379 Michael Hanselmann
      # Filter with only OR (names must be in correct order)
1155 fb0be379 Michael Hanselmann
      q = query.Query(fielddefs, ["name"],
1156 2e5c33db Iustin Pop
                      qfilter=["|", ["=", "name", "x17361"],
1157 fb0be379 Michael Hanselmann
                                    ["|", ["=", "name", "x22015"]],
1158 fb0be379 Michael Hanselmann
                                    ["|", ["|", ["=", "name", "x13193"]]],
1159 fb0be379 Michael Hanselmann
                                    ["=", "name", "x15215"]],
1160 fb0be379 Michael Hanselmann
                      namefield="name")
1161 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(),
1162 fb0be379 Michael Hanselmann
                       ["x17361", "x22015", "x13193", "x15215"])
1163 fb0be379 Michael Hanselmann
1164 fb0be379 Michael Hanselmann
  @staticmethod
1165 fb0be379 Michael Hanselmann
  def _GenNestedFilter(op, depth):
1166 fb0be379 Michael Hanselmann
    nested = ["=", "name", "value"]
1167 fb0be379 Michael Hanselmann
    for i in range(depth):
1168 fb0be379 Michael Hanselmann
      nested = [op, nested]
1169 fb0be379 Michael Hanselmann
    return nested
1170 fb0be379 Michael Hanselmann
1171 fb0be379 Michael Hanselmann
  def testCompileFilter(self):
1172 fb0be379 Michael Hanselmann
    levels_max = query._FilterCompilerHelper._LEVELS_MAX
1173 fb0be379 Michael Hanselmann
1174 fb0be379 Michael Hanselmann
    checks = [
1175 fb0be379 Michael Hanselmann
      [], ["="], ["=", "foo"], ["unknownop"], ["!"],
1176 fb0be379 Michael Hanselmann
      ["=", "_unknown_field", "value"],
1177 fb0be379 Michael Hanselmann
      self._GenNestedFilter("|", levels_max),
1178 fb0be379 Michael Hanselmann
      self._GenNestedFilter("|", levels_max * 3),
1179 fb0be379 Michael Hanselmann
      self._GenNestedFilter("!", levels_max),
1180 fb0be379 Michael Hanselmann
      ]
1181 fb0be379 Michael Hanselmann
1182 fb0be379 Michael Hanselmann
    for fielddefs in query.ALL_FIELD_LISTS:
1183 2e5c33db Iustin Pop
      for qfilter in checks:
1184 fb0be379 Michael Hanselmann
        self.assertRaises(errors.ParameterError, query._CompileFilter,
1185 2e5c33db Iustin Pop
                          fielddefs, None, qfilter)
1186 fb0be379 Michael Hanselmann
1187 fb0be379 Michael Hanselmann
      for op in ["|", "!"]:
1188 2e5c33db Iustin Pop
        qfilter = self._GenNestedFilter(op, levels_max - 1)
1189 fb0be379 Michael Hanselmann
        self.assertTrue(callable(query._CompileFilter(fielddefs, None,
1190 2e5c33db Iustin Pop
                                                      qfilter)))
1191 fb0be379 Michael Hanselmann
1192 fb0be379 Michael Hanselmann
  def testQueryInputOrder(self):
1193 fb0be379 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1194 fb0be379 Michael Hanselmann
      (query._MakeField("pnode", "PNode", constants.QFT_TEXT, "Primary"),
1195 fb0be379 Michael Hanselmann
       None, 0, lambda ctx, item: item["pnode"]),
1196 fb0be379 Michael Hanselmann
      (query._MakeField("snode", "SNode", constants.QFT_TEXT, "Secondary"),
1197 fb0be379 Michael Hanselmann
       None, 0, lambda ctx, item: item["snode"]),
1198 fb0be379 Michael Hanselmann
      ], [])
1199 fb0be379 Michael Hanselmann
1200 fb0be379 Michael Hanselmann
    data = [
1201 fb0be379 Michael Hanselmann
      { "pnode": "node1", "snode": "node44", },
1202 fb0be379 Michael Hanselmann
      { "pnode": "node30", "snode": "node90", },
1203 fb0be379 Michael Hanselmann
      { "pnode": "node25", "snode": "node1", },
1204 fb0be379 Michael Hanselmann
      { "pnode": "node20", "snode": "node1", },
1205 fb0be379 Michael Hanselmann
      ]
1206 fb0be379 Michael Hanselmann
1207 2e5c33db Iustin Pop
    qfilter = ["|", ["=", "pnode", "node1"], ["=", "snode", "node1"]]
1208 fb0be379 Michael Hanselmann
1209 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "snode"], namefield="pnode",
1210 2e5c33db Iustin Pop
                    qfilter=qfilter)
1211 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1212 fb0be379 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1213 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1214 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")],
1215 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")],
1216 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")]])
1217 fb0be379 Michael Hanselmann
1218 fb0be379 Michael Hanselmann
    # Try again with reversed input data
1219 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(reversed(data)),
1220 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")],
1221 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")],
1222 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")]])
1223 fb0be379 Michael Hanselmann
1224 fb0be379 Michael Hanselmann
    # No name field, result must be in incoming order
1225 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "snode"], namefield=None,
1226 2e5c33db Iustin Pop
                    qfilter=qfilter)
1227 fb0be379 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1228 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1229 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")],
1230 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")],
1231 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")]])
1232 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1233 fb0be379 Michael Hanselmann
      ["node1", "node44"],
1234 fb0be379 Michael Hanselmann
      ["node25", "node1"],
1235 fb0be379 Michael Hanselmann
      ["node20", "node1"],
1236 fb0be379 Michael Hanselmann
      ])
1237 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(reversed(data)),
1238 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")],
1239 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")],
1240 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")]])
1241 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(reversed(data)), [
1242 fb0be379 Michael Hanselmann
      ["node20", "node1"],
1243 fb0be379 Michael Hanselmann
      ["node25", "node1"],
1244 fb0be379 Michael Hanselmann
      ["node1", "node44"],
1245 fb0be379 Michael Hanselmann
      ])
1246 fb0be379 Michael Hanselmann
1247 fbc263a9 Michael Hanselmann
    # Name field, but no sorting, result must be in incoming order
1248 fbc263a9 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "snode"], namefield="pnode")
1249 fbc263a9 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1250 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data, sort_by_name=False),
1251 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")],
1252 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node30"), (constants.RS_NORMAL, "node90")],
1253 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")],
1254 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")]])
1255 fbc263a9 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data, sort_by_name=False), [
1256 fbc263a9 Michael Hanselmann
      ["node1", "node44"],
1257 fbc263a9 Michael Hanselmann
      ["node30", "node90"],
1258 fbc263a9 Michael Hanselmann
      ["node25", "node1"],
1259 fbc263a9 Michael Hanselmann
      ["node20", "node1"],
1260 fbc263a9 Michael Hanselmann
      ])
1261 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(reversed(data), sort_by_name=False),
1262 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")],
1263 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")],
1264 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node30"), (constants.RS_NORMAL, "node90")],
1265 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")]])
1266 fbc263a9 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(reversed(data), sort_by_name=False), [
1267 fbc263a9 Michael Hanselmann
      ["node20", "node1"],
1268 fbc263a9 Michael Hanselmann
      ["node25", "node1"],
1269 fbc263a9 Michael Hanselmann
      ["node30", "node90"],
1270 fbc263a9 Michael Hanselmann
      ["node1", "node44"],
1271 fbc263a9 Michael Hanselmann
      ])
1272 fbc263a9 Michael Hanselmann
1273 fbc263a9 Michael Hanselmann
  def testEqualNamesOrder(self):
1274 fbc263a9 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1275 fbc263a9 Michael Hanselmann
      (query._MakeField("pnode", "PNode", constants.QFT_TEXT, "Primary"),
1276 fbc263a9 Michael Hanselmann
       None, 0, lambda ctx, item: item["pnode"]),
1277 fbc263a9 Michael Hanselmann
      (query._MakeField("num", "Num", constants.QFT_NUMBER, "Num"),
1278 fbc263a9 Michael Hanselmann
       None, 0, lambda ctx, item: item["num"]),
1279 fbc263a9 Michael Hanselmann
      ], [])
1280 fbc263a9 Michael Hanselmann
1281 fbc263a9 Michael Hanselmann
    data = [
1282 fbc263a9 Michael Hanselmann
      { "pnode": "node1", "num": 100, },
1283 fbc263a9 Michael Hanselmann
      { "pnode": "node1", "num": 25, },
1284 fbc263a9 Michael Hanselmann
      { "pnode": "node2", "num": 90, },
1285 fbc263a9 Michael Hanselmann
      { "pnode": "node2", "num": 30, },
1286 fbc263a9 Michael Hanselmann
      ]
1287 fbc263a9 Michael Hanselmann
1288 fbc263a9 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "num"], namefield="pnode",
1289 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "pnode", "node1"],
1290 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "node2"],
1291 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "node1"]])
1292 fbc263a9 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1", "node2"],
1293 fbc263a9 Michael Hanselmann
                     msg="Did not return unique names")
1294 fbc263a9 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1295 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data),
1296 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, 100)],
1297 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, 25)],
1298 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, 90)],
1299 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, 30)]])
1300 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data, sort_by_name=False),
1301 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, 100)],
1302 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, 25)],
1303 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, 90)],
1304 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, 30)]])
1305 fbc263a9 Michael Hanselmann
1306 fbc263a9 Michael Hanselmann
    data = [
1307 fbc263a9 Michael Hanselmann
      { "pnode": "nodeX", "num": 50, },
1308 fbc263a9 Michael Hanselmann
      { "pnode": "nodeY", "num": 40, },
1309 fbc263a9 Michael Hanselmann
      { "pnode": "nodeX", "num": 30, },
1310 fbc263a9 Michael Hanselmann
      { "pnode": "nodeX", "num": 20, },
1311 fbc263a9 Michael Hanselmann
      { "pnode": "nodeM", "num": 10, },
1312 fbc263a9 Michael Hanselmann
      ]
1313 fbc263a9 Michael Hanselmann
1314 fbc263a9 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "num"], namefield="pnode",
1315 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "pnode", "nodeX"],
1316 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "nodeY"],
1317 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "nodeY"],
1318 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "nodeY"],
1319 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "nodeM"]])
1320 fbc263a9 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["nodeX", "nodeY", "nodeM"],
1321 fbc263a9 Michael Hanselmann
                     msg="Did not return unique names")
1322 fbc263a9 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1323 fbc263a9 Michael Hanselmann
1324 fbc263a9 Michael Hanselmann
    # First sorted by name, then input order
1325 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data, sort_by_name=True),
1326 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "nodeM"), (constants.RS_NORMAL, 10)],
1327 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 50)],
1328 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 30)],
1329 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 20)],
1330 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeY"), (constants.RS_NORMAL, 40)]])
1331 fbc263a9 Michael Hanselmann
1332 fbc263a9 Michael Hanselmann
    # Input order
1333 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data, sort_by_name=False),
1334 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 50)],
1335 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeY"), (constants.RS_NORMAL, 40)],
1336 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 30)],
1337 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 20)],
1338 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeM"), (constants.RS_NORMAL, 10)]])
1339 fbc263a9 Michael Hanselmann
1340 fb0be379 Michael Hanselmann
  def testFilter(self):
1341 fb0be379 Michael Hanselmann
    (DK_A, DK_B) = range(1000, 1002)
1342 fb0be379 Michael Hanselmann
1343 fb0be379 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1344 fb0be379 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1345 fb0be379 Michael Hanselmann
       DK_A, 0, lambda ctx, item: item["name"]),
1346 fb0be379 Michael Hanselmann
      (query._MakeField("other", "Other", constants.QFT_TEXT, "Other"),
1347 fb0be379 Michael Hanselmann
       DK_B, 0, lambda ctx, item: item["other"]),
1348 fb0be379 Michael Hanselmann
      ], [])
1349 fb0be379 Michael Hanselmann
1350 fb0be379 Michael Hanselmann
    data = [
1351 fb0be379 Michael Hanselmann
      { "name": "node1", "other": "foo", },
1352 fb0be379 Michael Hanselmann
      { "name": "node2", "other": "bar", },
1353 fb0be379 Michael Hanselmann
      { "name": "node3", "other": "Hello", },
1354 fb0be379 Michael Hanselmann
      ]
1355 fb0be379 Michael Hanselmann
1356 fb0be379 Michael Hanselmann
    # Empty filter
1357 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1358 2e5c33db Iustin Pop
                    qfilter=["|"])
1359 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1360 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_A, DK_B]))
1361 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [])
1362 fb0be379 Michael Hanselmann
1363 fb0be379 Michael Hanselmann
    # Normal filter
1364 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1365 2e5c33db Iustin Pop
                    qfilter=["=", "name", "node1"])
1366 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1"])
1367 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1368 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "foo")]])
1369 fb0be379 Michael Hanselmann
1370 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1371 2e5c33db Iustin Pop
                    qfilter=(["|", ["=", "name", "node1"],
1372 fb0be379 Michael Hanselmann
                                   ["=", "name", "node3"]]))
1373 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1", "node3"])
1374 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1375 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "foo")],
1376 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, "Hello")]])
1377 fb0be379 Michael Hanselmann
1378 fb0be379 Michael Hanselmann
    # Complex filter
1379 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1380 2e5c33db Iustin Pop
                    qfilter=(["|", ["=", "name", "node1"],
1381 fb0be379 Michael Hanselmann
                                   ["|", ["=", "name", "node3"],
1382 fb0be379 Michael Hanselmann
                                         ["=", "name", "node2"]],
1383 fb0be379 Michael Hanselmann
                                   ["=", "name", "node3"]]))
1384 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1", "node3", "node2"])
1385 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_A, DK_B]))
1386 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1387 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "foo")],
1388 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, "bar")],
1389 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, "Hello")]])
1390 fb0be379 Michael Hanselmann
1391 fb0be379 Michael Hanselmann
    # Filter data type mismatch
1392 fb0be379 Michael Hanselmann
    for i in [-1, 0, 1, 123, [], None, True, False]:
1393 fb0be379 Michael Hanselmann
      self.assertRaises(errors.ParameterError, query.Query,
1394 fb0be379 Michael Hanselmann
                        fielddefs, ["name", "other"], namefield="name",
1395 2e5c33db Iustin Pop
                        qfilter=["=", "name", i])
1396 fb0be379 Michael Hanselmann
1397 fb0be379 Michael Hanselmann
    # Negative filter
1398 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1399 2e5c33db Iustin Pop
                    qfilter=["!", ["|", ["=", "name", "node1"],
1400 fb0be379 Michael Hanselmann
                                        ["=", "name", "node3"]]])
1401 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1402 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1403 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, "bar")]])
1404 fb0be379 Michael Hanselmann
1405 fb0be379 Michael Hanselmann
    # Not equal
1406 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1407 2e5c33db Iustin Pop
                    qfilter=["!=", "name", "node3"])
1408 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1409 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1410 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "foo")],
1411 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, "bar")]])
1412 fb0be379 Michael Hanselmann
1413 fb0be379 Michael Hanselmann
    # Data type
1414 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, [], namefield="name",
1415 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "other", "bar"],
1416 fb0be379 Michael Hanselmann
                                  ["=", "name", "foo"]])
1417 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1418 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_A, DK_B]))
1419 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [[]])
1420 fb0be379 Michael Hanselmann
1421 fb0be379 Michael Hanselmann
    # Only one data type
1422 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["other"], namefield="name",
1423 2e5c33db Iustin Pop
                    qfilter=["=", "other", "bar"])
1424 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1425 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_B]))
1426 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [[(constants.RS_NORMAL, "bar")]])
1427 fb0be379 Michael Hanselmann
1428 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, [], namefield="name",
1429 2e5c33db Iustin Pop
                    qfilter=["=", "other", "bar"])
1430 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1431 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_B]))
1432 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [[]])
1433 fb0be379 Michael Hanselmann
1434 fb0be379 Michael Hanselmann
  def testFilterContains(self):
1435 fb0be379 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1436 fb0be379 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1437 fb0be379 Michael Hanselmann
       None, 0, lambda ctx, item: item["name"]),
1438 fb0be379 Michael Hanselmann
      (query._MakeField("other", "Other", constants.QFT_OTHER, "Other"),
1439 fb0be379 Michael Hanselmann
       None, 0, lambda ctx, item: item["other"]),
1440 fb0be379 Michael Hanselmann
      ], [])
1441 fb0be379 Michael Hanselmann
1442 fb0be379 Michael Hanselmann
    data = [
1443 fb0be379 Michael Hanselmann
      { "name": "node2", "other": ["x", "y", "bar"], },
1444 fb0be379 Michael Hanselmann
      { "name": "node3", "other": "Hello", },
1445 fb0be379 Michael Hanselmann
      { "name": "node1", "other": ["a", "b", "foo"], },
1446 3b877f08 Michael Hanselmann
      { "name": "empty", "other": []},
1447 fb0be379 Michael Hanselmann
      ]
1448 fb0be379 Michael Hanselmann
1449 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1450 2e5c33db Iustin Pop
                    qfilter=["=[]", "other", "bar"])
1451 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1452 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1453 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"),
1454 fb0be379 Michael Hanselmann
       (constants.RS_NORMAL, ["x", "y", "bar"])],
1455 fb0be379 Michael Hanselmann
      ])
1456 fb0be379 Michael Hanselmann
1457 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1458 2e5c33db Iustin Pop
                    qfilter=["|", ["=[]", "other", "bar"],
1459 fb0be379 Michael Hanselmann
                                  ["=[]", "other", "a"],
1460 fb0be379 Michael Hanselmann
                                  ["=[]", "other", "b"]])
1461 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1462 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1463 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"),
1464 fb0be379 Michael Hanselmann
       (constants.RS_NORMAL, ["a", "b", "foo"])],
1465 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"),
1466 fb0be379 Michael Hanselmann
       (constants.RS_NORMAL, ["x", "y", "bar"])],
1467 fb0be379 Michael Hanselmann
      ])
1468 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1469 fb0be379 Michael Hanselmann
      ["node1", ["a", "b", "foo"]],
1470 fb0be379 Michael Hanselmann
      ["node2", ["x", "y", "bar"]],
1471 fb0be379 Michael Hanselmann
      ])
1472 fb0be379 Michael Hanselmann
1473 3b877f08 Michael Hanselmann
    # Boolean test
1474 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1475 2e5c33db Iustin Pop
                    qfilter=["?", "other"])
1476 3b877f08 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1477 3b877f08 Michael Hanselmann
      ["node1", ["a", "b", "foo"]],
1478 3b877f08 Michael Hanselmann
      ["node2", ["x", "y", "bar"]],
1479 3b877f08 Michael Hanselmann
      ["node3", "Hello"],
1480 3b877f08 Michael Hanselmann
      ])
1481 3b877f08 Michael Hanselmann
1482 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1483 2e5c33db Iustin Pop
                    qfilter=["!", ["?", "other"]])
1484 3b877f08 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1485 3b877f08 Michael Hanselmann
      ["empty", []],
1486 3b877f08 Michael Hanselmann
      ])
1487 3b877f08 Michael Hanselmann
1488 fb0be379 Michael Hanselmann
  def testFilterHostname(self):
1489 fb0be379 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1490 fb0be379 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1491 fb0be379 Michael Hanselmann
       None, query.QFF_HOSTNAME, lambda ctx, item: item["name"]),
1492 fb0be379 Michael Hanselmann
      ], [])
1493 fb0be379 Michael Hanselmann
1494 fb0be379 Michael Hanselmann
    data = [
1495 fb0be379 Michael Hanselmann
      { "name": "node1.example.com", },
1496 fb0be379 Michael Hanselmann
      { "name": "node2.example.com", },
1497 fb0be379 Michael Hanselmann
      { "name": "node2.example.net", },
1498 fb0be379 Michael Hanselmann
      ]
1499 fb0be379 Michael Hanselmann
1500 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1501 2e5c33db Iustin Pop
                    qfilter=["=", "name", "node2"])
1502 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node2"])
1503 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1504 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.com")],
1505 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.net")],
1506 fb0be379 Michael Hanselmann
      ])
1507 fb0be379 Michael Hanselmann
1508 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1509 2e5c33db Iustin Pop
                    qfilter=["=", "name", "node1"])
1510 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1"])
1511 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1512 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node1.example.com")],
1513 fb0be379 Michael Hanselmann
      ])
1514 fb0be379 Michael Hanselmann
1515 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1516 2e5c33db Iustin Pop
                    qfilter=["=", "name", "othername"])
1517 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["othername"])
1518 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [])
1519 fb0be379 Michael Hanselmann
1520 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1521 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "name", "node1.example.com"],
1522 fb0be379 Michael Hanselmann
                                  ["=", "name", "node2"]])
1523 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1.example.com", "node2"])
1524 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1525 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node1.example.com")],
1526 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.com")],
1527 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.net")],
1528 fb0be379 Michael Hanselmann
      ])
1529 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1530 fb0be379 Michael Hanselmann
      ["node1.example.com"],
1531 fb0be379 Michael Hanselmann
      ["node2.example.com"],
1532 fb0be379 Michael Hanselmann
      ["node2.example.net"],
1533 fb0be379 Michael Hanselmann
      ])
1534 fb0be379 Michael Hanselmann
1535 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1536 2e5c33db Iustin Pop
                    qfilter=["!=", "name", "node1"])
1537 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1538 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1539 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.com")],
1540 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.net")],
1541 fb0be379 Michael Hanselmann
      ])
1542 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1543 fb0be379 Michael Hanselmann
      ["node2.example.com"],
1544 fb0be379 Michael Hanselmann
      ["node2.example.net"],
1545 fb0be379 Michael Hanselmann
      ])
1546 fb0be379 Michael Hanselmann
1547 3b877f08 Michael Hanselmann
  def testFilterBoolean(self):
1548 3b877f08 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1549 3b877f08 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1550 3b877f08 Michael Hanselmann
       None, query.QFF_HOSTNAME, lambda ctx, item: item["name"]),
1551 3b877f08 Michael Hanselmann
      (query._MakeField("value", "Value", constants.QFT_BOOL, "Value"),
1552 3b877f08 Michael Hanselmann
       None, 0, lambda ctx, item: item["value"]),
1553 3b877f08 Michael Hanselmann
      ], [])
1554 3b877f08 Michael Hanselmann
1555 3b877f08 Michael Hanselmann
    data = [
1556 3b877f08 Michael Hanselmann
      { "name": "node1", "value": False, },
1557 3b877f08 Michael Hanselmann
      { "name": "node2", "value": True, },
1558 3b877f08 Michael Hanselmann
      { "name": "node3", "value": True, },
1559 3b877f08 Michael Hanselmann
      ]
1560 3b877f08 Michael Hanselmann
1561 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "value"],
1562 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "value", False],
1563 3b877f08 Michael Hanselmann
                                  ["=", "value", True]])
1564 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1565 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1566 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, False)],
1567 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, True)],
1568 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, True)],
1569 3b877f08 Michael Hanselmann
      ])
1570 3b877f08 Michael Hanselmann
1571 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "value"],
1572 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "value", False],
1573 3b877f08 Michael Hanselmann
                                  ["!", ["=", "value", False]]])
1574 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1575 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1576 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, False)],
1577 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, True)],
1578 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, True)],
1579 3b877f08 Michael Hanselmann
      ])
1580 3b877f08 Michael Hanselmann
1581 3b877f08 Michael Hanselmann
    # Comparing bool with string
1582 3b877f08 Michael Hanselmann
    for i in ["False", "True", "0", "1", "no", "yes", "N", "Y"]:
1583 3b877f08 Michael Hanselmann
      self.assertRaises(errors.ParameterError, query.Query,
1584 3b877f08 Michael Hanselmann
                        fielddefs, ["name", "value"],
1585 2e5c33db Iustin Pop
                        qfilter=["=", "value", i])
1586 3b877f08 Michael Hanselmann
1587 3b877f08 Michael Hanselmann
    # Truth filter
1588 2e5c33db Iustin Pop
    q = query.Query(fielddefs, ["name", "value"], qfilter=["?", "value"])
1589 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1590 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1591 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, True)],
1592 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, True)],
1593 3b877f08 Michael Hanselmann
      ])
1594 3b877f08 Michael Hanselmann
1595 3b877f08 Michael Hanselmann
    # Negative bool filter
1596 2e5c33db Iustin Pop
    q = query.Query(fielddefs, ["name", "value"], qfilter=["!", ["?", "value"]])
1597 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1598 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1599 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, False)],
1600 3b877f08 Michael Hanselmann
      ])
1601 3b877f08 Michael Hanselmann
1602 3b877f08 Michael Hanselmann
    # Complex truth filter
1603 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "value"],
1604 2e5c33db Iustin Pop
                    qfilter=["|", ["&", ["=", "name", "node1"],
1605 3b877f08 Michael Hanselmann
                                        ["!", ["?", "value"]]],
1606 3b877f08 Michael Hanselmann
                                  ["?", "value"]])
1607 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1608 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1609 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, False)],
1610 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, True)],
1611 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, True)],
1612 3b877f08 Michael Hanselmann
      ])
1613 3b877f08 Michael Hanselmann
1614 23d0a608 Michael Hanselmann
  def testFilterRegex(self):
1615 23d0a608 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1616 23d0a608 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1617 23d0a608 Michael Hanselmann
       None, 0, lambda ctx, item: item["name"]),
1618 23d0a608 Michael Hanselmann
      ], [])
1619 23d0a608 Michael Hanselmann
1620 23d0a608 Michael Hanselmann
    data = [
1621 23d0a608 Michael Hanselmann
      { "name": "node1.example.com", },
1622 23d0a608 Michael Hanselmann
      { "name": "node2.site.example.com", },
1623 23d0a608 Michael Hanselmann
      { "name": "node2.example.net", },
1624 23d0a608 Michael Hanselmann
1625 23d0a608 Michael Hanselmann
      # Empty name
1626 23d0a608 Michael Hanselmann
      { "name": "", },
1627 23d0a608 Michael Hanselmann
      ]
1628 23d0a608 Michael Hanselmann
1629 23d0a608 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1630 2e5c33db Iustin Pop
                    qfilter=["=~", "name", "site"])
1631 23d0a608 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1632 23d0a608 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1633 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.site.example.com")],
1634 23d0a608 Michael Hanselmann
      ])
1635 23d0a608 Michael Hanselmann
1636 23d0a608 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1637 2e5c33db Iustin Pop
                    qfilter=["=~", "name", "^node2"])
1638 23d0a608 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1639 23d0a608 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1640 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.net")],
1641 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.site.example.com")],
1642 23d0a608 Michael Hanselmann
      ])
1643 23d0a608 Michael Hanselmann
1644 23d0a608 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1645 2e5c33db Iustin Pop
                    qfilter=["=~", "name", r"(?i)\.COM$"])
1646 23d0a608 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1647 23d0a608 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1648 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node1.example.com")],
1649 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.site.example.com")],
1650 23d0a608 Michael Hanselmann
      ])
1651 23d0a608 Michael Hanselmann
1652 23d0a608 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1653 2e5c33db Iustin Pop
                    qfilter=["=~", "name", r"."])
1654 23d0a608 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1655 23d0a608 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1656 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node1.example.com")],
1657 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.net")],
1658 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.site.example.com")],
1659 23d0a608 Michael Hanselmann
      ])
1660 23d0a608 Michael Hanselmann
1661 23d0a608 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1662 2e5c33db Iustin Pop
                    qfilter=["=~", "name", r"^$"])
1663 23d0a608 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1664 23d0a608 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1665 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "")],
1666 23d0a608 Michael Hanselmann
      ])
1667 23d0a608 Michael Hanselmann
1668 23d0a608 Michael Hanselmann
    # Invalid regular expression
1669 23d0a608 Michael Hanselmann
    self.assertRaises(errors.ParameterError, query.Query, fielddefs, ["name"],
1670 2e5c33db Iustin Pop
                      qfilter=["=~", "name", r"["])
1671 23d0a608 Michael Hanselmann
1672 fb0be379 Michael Hanselmann
1673 4ca96421 Michael Hanselmann
if __name__ == "__main__":
1674 4ca96421 Michael Hanselmann
  testutils.GanetiTestProgram()