Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.query_unittest.py @ 9ca8a7c5

History | View | Annotate | Download (63.6 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 1c8addc6 Michael Hanselmann
    q = self._Create(["name", "be/memory", "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 1c8addc6 Michael Hanselmann
          constants.BE_MEMORY: 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 9ca8a7c5 Agata Murawska
        admin_state=True, hypervisor=constants.HT_XEN_PVM, os="linux1",
648 1c8addc6 Michael Hanselmann
        primary_node="node1",
649 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_PLAIN,
650 7c670076 Michael Hanselmann
        disks=[],
651 7c670076 Michael Hanselmann
        osparams={}),
652 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst2", hvparams={}, nics=[],
653 1c8addc6 Michael Hanselmann
        uuid="73a0f8a7-068c-4630-ada2-c3440015ab1a",
654 1c8addc6 Michael Hanselmann
        ctime=1291211000, mtime=1291211077, serial_no=1,
655 9ca8a7c5 Agata Murawska
        admin_state=True, hypervisor=constants.HT_XEN_HVM, os="deb99",
656 1c8addc6 Michael Hanselmann
        primary_node="node5",
657 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DISKLESS,
658 1c8addc6 Michael Hanselmann
        disks=[],
659 1c8addc6 Michael Hanselmann
        beparams={
660 1c8addc6 Michael Hanselmann
          constants.BE_MEMORY: 512,
661 7c670076 Michael Hanselmann
        },
662 7c670076 Michael Hanselmann
        osparams={}),
663 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst3", hvparams={}, beparams={},
664 1c8addc6 Michael Hanselmann
        uuid="11ec8dff-fb61-4850-bfe0-baa1803ff280",
665 1c8addc6 Michael Hanselmann
        ctime=1291011000, mtime=1291013000, serial_no=1923,
666 9ca8a7c5 Agata Murawska
        admin_state=False, hypervisor=constants.HT_KVM, os="busybox",
667 1c8addc6 Michael Hanselmann
        primary_node="node6",
668 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DRBD8,
669 1c8addc6 Michael Hanselmann
        disks=[],
670 1c8addc6 Michael Hanselmann
        nics=[
671 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.99", mac=macs.pop(),
672 1c8addc6 Michael Hanselmann
                      nicparams={
673 1c8addc6 Michael Hanselmann
                        constants.NIC_LINK: constants.DEFAULT_BRIDGE,
674 1c8addc6 Michael Hanselmann
                        }),
675 1c8addc6 Michael Hanselmann
          objects.NIC(ip=None, mac=macs.pop(), nicparams={}),
676 7c670076 Michael Hanselmann
          ],
677 7c670076 Michael Hanselmann
        osparams={}),
678 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst4", hvparams={}, beparams={},
679 1c8addc6 Michael Hanselmann
        uuid="68dab168-3ef5-4c9d-b4d3-801e0672068c",
680 1c8addc6 Michael Hanselmann
        ctime=1291244390, mtime=1291244395, serial_no=25,
681 9ca8a7c5 Agata Murawska
        admin_state=False, hypervisor=constants.HT_XEN_PVM, os="linux1",
682 1c8addc6 Michael Hanselmann
        primary_node="nodeoff2",
683 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DRBD8,
684 1c8addc6 Michael Hanselmann
        disks=[],
685 1c8addc6 Michael Hanselmann
        nics=[
686 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.1", mac=macs.pop(),
687 1c8addc6 Michael Hanselmann
                      nicparams={
688 1c8addc6 Michael Hanselmann
                        constants.NIC_LINK: constants.DEFAULT_BRIDGE,
689 1c8addc6 Michael Hanselmann
                        }),
690 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.2", mac=macs.pop(), nicparams={}),
691 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.3", mac=macs.pop(),
692 1c8addc6 Michael Hanselmann
                      nicparams={
693 1c8addc6 Michael Hanselmann
                        constants.NIC_MODE: constants.NIC_MODE_ROUTED,
694 1c8addc6 Michael Hanselmann
                        }),
695 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.4", mac=macs.pop(),
696 1c8addc6 Michael Hanselmann
                      nicparams={
697 1c8addc6 Michael Hanselmann
                        constants.NIC_MODE: constants.NIC_MODE_BRIDGED,
698 1c8addc6 Michael Hanselmann
                        constants.NIC_LINK: "eth123",
699 1c8addc6 Michael Hanselmann
                        }),
700 7c670076 Michael Hanselmann
          ],
701 7c670076 Michael Hanselmann
        osparams={}),
702 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst5", hvparams={}, nics=[],
703 1c8addc6 Michael Hanselmann
        uuid="0e3dca12-5b42-4e24-98a2-415267545bd0",
704 1c8addc6 Michael Hanselmann
        ctime=1231211000, mtime=1261200000, serial_no=3,
705 9ca8a7c5 Agata Murawska
        admin_state=True, hypervisor=constants.HT_XEN_HVM, os="deb99",
706 1c8addc6 Michael Hanselmann
        primary_node="nodebad2",
707 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DISKLESS,
708 1c8addc6 Michael Hanselmann
        disks=[],
709 1c8addc6 Michael Hanselmann
        beparams={
710 1c8addc6 Michael Hanselmann
          constants.BE_MEMORY: 512,
711 7c670076 Michael Hanselmann
        },
712 7c670076 Michael Hanselmann
        osparams={}),
713 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst6", hvparams={}, nics=[],
714 1c8addc6 Michael Hanselmann
        uuid="72de6580-c8d5-4661-b902-38b5785bb8b3",
715 1c8addc6 Michael Hanselmann
        ctime=7513, mtime=11501, serial_no=13390,
716 9ca8a7c5 Agata Murawska
        admin_state=False, hypervisor=constants.HT_XEN_HVM, os="deb99",
717 1c8addc6 Michael Hanselmann
        primary_node="node7",
718 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DISKLESS,
719 1c8addc6 Michael Hanselmann
        disks=[],
720 1c8addc6 Michael Hanselmann
        beparams={
721 1c8addc6 Michael Hanselmann
          constants.BE_MEMORY: 768,
722 7c670076 Michael Hanselmann
        },
723 7c670076 Michael Hanselmann
        osparams={
724 7c670076 Michael Hanselmann
          "clean_install": "no",
725 7c670076 Michael Hanselmann
          }),
726 145bea54 Michael Hanselmann
      objects.Instance(name="inst7", hvparams={}, nics=[],
727 145bea54 Michael Hanselmann
        uuid="ceec5dc4-b729-4f42-ae28-69b3cd24920e",
728 145bea54 Michael Hanselmann
        ctime=None, mtime=None, serial_no=1947,
729 9ca8a7c5 Agata Murawska
        admin_state=False, hypervisor=constants.HT_XEN_HVM, os="deb99",
730 145bea54 Michael Hanselmann
        primary_node="node6",
731 145bea54 Michael Hanselmann
        disk_template=constants.DT_DISKLESS,
732 145bea54 Michael Hanselmann
        disks=[],
733 7c670076 Michael Hanselmann
        beparams={},
734 7c670076 Michael Hanselmann
        osparams={}),
735 1c8addc6 Michael Hanselmann
      ]
736 1c8addc6 Michael Hanselmann
737 145bea54 Michael Hanselmann
    assert not utils.FindDuplicates(inst.name for inst in instances)
738 145bea54 Michael Hanselmann
739 5d28cb6f Michael Hanselmann
    instbyname = dict((inst.name, inst) for inst in instances)
740 5d28cb6f Michael Hanselmann
741 1c8addc6 Michael Hanselmann
    disk_usage = dict((inst.name,
742 1c8addc6 Michael Hanselmann
                       cmdlib._ComputeDiskSize(inst.disk_template,
743 1c8addc6 Michael Hanselmann
                                               [{"size": disk.size}
744 1c8addc6 Michael Hanselmann
                                                for disk in inst.disks]))
745 1c8addc6 Michael Hanselmann
                      for inst in instances)
746 1c8addc6 Michael Hanselmann
747 1c8addc6 Michael Hanselmann
    inst_bridges = {
748 1c8addc6 Michael Hanselmann
      "inst3": [constants.DEFAULT_BRIDGE, constants.DEFAULT_BRIDGE],
749 1c8addc6 Michael Hanselmann
      "inst4": [constants.DEFAULT_BRIDGE, constants.DEFAULT_BRIDGE,
750 1c8addc6 Michael Hanselmann
                None, "eth123"],
751 1c8addc6 Michael Hanselmann
      }
752 1c8addc6 Michael Hanselmann
753 1c8addc6 Michael Hanselmann
    live_data = {
754 1c8addc6 Michael Hanselmann
      "inst2": {
755 1c8addc6 Michael Hanselmann
        "vcpus": 3,
756 1c8addc6 Michael Hanselmann
        },
757 1c8addc6 Michael Hanselmann
      "inst4": {
758 1c8addc6 Michael Hanselmann
        "memory": 123,
759 1c8addc6 Michael Hanselmann
        },
760 1c8addc6 Michael Hanselmann
      "inst6": {
761 1c8addc6 Michael Hanselmann
        "memory": 768,
762 1c8addc6 Michael Hanselmann
        },
763 bacae536 Renรฉ Nussbaumer
      "inst7": {
764 bacae536 Renรฉ Nussbaumer
        "vcpus": 3,
765 bacae536 Renรฉ Nussbaumer
        },
766 1c8addc6 Michael Hanselmann
      }
767 bacae536 Renรฉ Nussbaumer
    wrongnode_inst = set(["inst7"])
768 1c8addc6 Michael Hanselmann
769 5d28cb6f Michael Hanselmann
    consinfo = dict((inst.name, None) for inst in instances)
770 5d28cb6f Michael Hanselmann
    consinfo["inst7"] = \
771 5d28cb6f Michael Hanselmann
      objects.InstanceConsole(instance="inst7", kind=constants.CONS_SSH,
772 5d28cb6f Michael Hanselmann
                              host=instbyname["inst7"].primary_node,
773 5d28cb6f Michael Hanselmann
                              user=constants.GANETI_RUNAS,
774 5d28cb6f Michael Hanselmann
                              command=["hostname"]).ToDict()
775 5d28cb6f Michael Hanselmann
776 1c8addc6 Michael Hanselmann
    iqd = query.InstanceQueryData(instances, cluster, disk_usage,
777 e431074f Renรฉ Nussbaumer
                                  offline_nodes, bad_nodes, live_data,
778 fab9573b Michael Hanselmann
                                  wrongnode_inst, consinfo, {}, {})
779 1c8addc6 Michael Hanselmann
    result = q.Query(iqd)
780 1c8addc6 Michael Hanselmann
    self.assertEqual(len(result), len(instances))
781 1c8addc6 Michael Hanselmann
    self.assert_(compat.all(len(row) == len(selected)
782 1c8addc6 Michael Hanselmann
                            for row in result))
783 1c8addc6 Michael Hanselmann
784 1c8addc6 Michael Hanselmann
    assert len(set(bad_nodes) & set(offline_nodes)) == len(offline_nodes), \
785 1c8addc6 Michael Hanselmann
           "Offline nodes not included in bad nodes"
786 1c8addc6 Michael Hanselmann
787 1c8addc6 Michael Hanselmann
    tested_status = set()
788 1c8addc6 Michael Hanselmann
789 1c8addc6 Michael Hanselmann
    for (inst, row) in zip(instances, result):
790 1c8addc6 Michael Hanselmann
      assert inst.primary_node in nodes
791 1c8addc6 Michael Hanselmann
792 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["name"]],
793 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, inst.name))
794 1c8addc6 Michael Hanselmann
795 1c8addc6 Michael Hanselmann
      if inst.primary_node in offline_nodes:
796 61a980a9 Michael Hanselmann
        exp_status = constants.INSTST_NODEOFFLINE
797 1c8addc6 Michael Hanselmann
      elif inst.primary_node in bad_nodes:
798 61a980a9 Michael Hanselmann
        exp_status = constants.INSTST_NODEDOWN
799 1c8addc6 Michael Hanselmann
      elif inst.name in live_data:
800 e431074f Renรฉ Nussbaumer
        if inst.name in wrongnode_inst:
801 61a980a9 Michael Hanselmann
          exp_status = constants.INSTST_WRONGNODE
802 9ca8a7c5 Agata Murawska
        elif inst.admin_state:
803 61a980a9 Michael Hanselmann
          exp_status = constants.INSTST_RUNNING
804 1c8addc6 Michael Hanselmann
        else:
805 61a980a9 Michael Hanselmann
          exp_status = constants.INSTST_ERRORUP
806 9ca8a7c5 Agata Murawska
      elif inst.admin_state:
807 61a980a9 Michael Hanselmann
        exp_status = constants.INSTST_ERRORDOWN
808 1c8addc6 Michael Hanselmann
      else:
809 61a980a9 Michael Hanselmann
        exp_status = constants.INSTST_ADMINDOWN
810 1c8addc6 Michael Hanselmann
811 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["status"]],
812 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, exp_status))
813 1c8addc6 Michael Hanselmann
814 1c8addc6 Michael Hanselmann
      (_, status) = row[fieldidx["status"]]
815 1c8addc6 Michael Hanselmann
      tested_status.add(status)
816 1c8addc6 Michael Hanselmann
817 1c8addc6 Michael Hanselmann
      for (field, livefield) in [("oper_ram", "memory"),
818 1c8addc6 Michael Hanselmann
                                 ("oper_vcpus", "vcpus")]:
819 1c8addc6 Michael Hanselmann
        if inst.primary_node in bad_nodes:
820 cfb084ae Renรฉ Nussbaumer
          exp = (constants.RS_NODATA, None)
821 1c8addc6 Michael Hanselmann
        elif inst.name in live_data:
822 1c8addc6 Michael Hanselmann
          value = live_data[inst.name].get(livefield, None)
823 1c8addc6 Michael Hanselmann
          if value is None:
824 cfb084ae Renรฉ Nussbaumer
            exp = (constants.RS_UNAVAIL, None)
825 1c8addc6 Michael Hanselmann
          else:
826 cfb084ae Renรฉ Nussbaumer
            exp = (constants.RS_NORMAL, value)
827 1c8addc6 Michael Hanselmann
        else:
828 cfb084ae Renรฉ Nussbaumer
          exp = (constants.RS_UNAVAIL, None)
829 1c8addc6 Michael Hanselmann
830 1c8addc6 Michael Hanselmann
        self.assertEqual(row[fieldidx[field]], exp)
831 1c8addc6 Michael Hanselmann
832 1c8addc6 Michael Hanselmann
      bridges = inst_bridges.get(inst.name, [])
833 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["nic.bridges"]],
834 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, bridges))
835 1c8addc6 Michael Hanselmann
      if bridges:
836 1c8addc6 Michael Hanselmann
        self.assertEqual(row[fieldidx["bridge"]],
837 cfb084ae Renรฉ Nussbaumer
                         (constants.RS_NORMAL, bridges[0]))
838 1c8addc6 Michael Hanselmann
      else:
839 1c8addc6 Michael Hanselmann
        self.assertEqual(row[fieldidx["bridge"]],
840 cfb084ae Renรฉ Nussbaumer
                         (constants.RS_UNAVAIL, None))
841 1c8addc6 Michael Hanselmann
842 1c8addc6 Michael Hanselmann
      for i in range(constants.MAX_NICS):
843 1c8addc6 Michael Hanselmann
        if i < len(bridges) and bridges[i] is not None:
844 cfb084ae Renรฉ Nussbaumer
          exp = (constants.RS_NORMAL, bridges[i])
845 1c8addc6 Michael Hanselmann
        else:
846 cfb084ae Renรฉ Nussbaumer
          exp = (constants.RS_UNAVAIL, None)
847 1c8addc6 Michael Hanselmann
        self.assertEqual(row[fieldidx["nic.bridge/%s" % i]], exp)
848 1c8addc6 Michael Hanselmann
849 1c8addc6 Michael Hanselmann
      if inst.primary_node in bad_nodes:
850 cfb084ae Renรฉ Nussbaumer
        exp = (constants.RS_NODATA, None)
851 1c8addc6 Michael Hanselmann
      else:
852 cfb084ae Renรฉ Nussbaumer
        exp = (constants.RS_NORMAL, inst.name in live_data)
853 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["oper_state"]], exp)
854 1c8addc6 Michael Hanselmann
855 7c670076 Michael Hanselmann
      cust_exp = (constants.RS_NORMAL, {})
856 7c670076 Michael Hanselmann
      if inst.os == "deb99":
857 7c670076 Michael Hanselmann
        if inst.name == "inst6":
858 7c670076 Michael Hanselmann
          exp = (constants.RS_NORMAL, {"clean_install": "no"})
859 7c670076 Michael Hanselmann
          cust_exp = exp
860 7c670076 Michael Hanselmann
        else:
861 7c670076 Michael Hanselmann
          exp = (constants.RS_NORMAL, {"clean_install": "yes"})
862 7c670076 Michael Hanselmann
      else:
863 7c670076 Michael Hanselmann
        exp = (constants.RS_NORMAL, {})
864 7c670076 Michael Hanselmann
      self.assertEqual(row[fieldidx["osparams"]], exp)
865 7c670076 Michael Hanselmann
      self.assertEqual(row[fieldidx["custom_osparams"]], cust_exp)
866 7c670076 Michael Hanselmann
867 1c8addc6 Michael Hanselmann
      usage = disk_usage[inst.name]
868 1c8addc6 Michael Hanselmann
      if usage is None:
869 1c8addc6 Michael Hanselmann
        usage = 0
870 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["disk_usage"]],
871 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, usage))
872 1c8addc6 Michael Hanselmann
873 4cc4d1fa Michael Hanselmann
      for alias, target in [("sda_size", "disk.size/0"),
874 4cc4d1fa Michael Hanselmann
                            ("sdb_size", "disk.size/1"),
875 4cc4d1fa Michael Hanselmann
                            ("vcpus", "be/vcpus"),
876 4cc4d1fa Michael Hanselmann
                            ("ip", "nic.ip/0"),
877 4cc4d1fa Michael Hanselmann
                            ("mac", "nic.mac/0"),
878 4cc4d1fa Michael Hanselmann
                            ("bridge", "nic.bridge/0"),
879 4cc4d1fa Michael Hanselmann
                            ("nic_mode", "nic.mode/0"),
880 4cc4d1fa Michael Hanselmann
                            ("nic_link", "nic.link/0"),
881 4cc4d1fa Michael Hanselmann
                            ]:
882 4cc4d1fa Michael Hanselmann
        self.assertEqual(row[fieldidx[alias]], row[fieldidx[target]])
883 1c8addc6 Michael Hanselmann
884 145bea54 Michael Hanselmann
      for field in ["ctime", "mtime"]:
885 145bea54 Michael Hanselmann
        if getattr(inst, field) is None:
886 145bea54 Michael Hanselmann
          # No ctime/mtime
887 cfb084ae Renรฉ Nussbaumer
          exp = (constants.RS_UNAVAIL, None)
888 145bea54 Michael Hanselmann
        else:
889 cfb084ae Renรฉ Nussbaumer
          exp = (constants.RS_NORMAL, getattr(inst, field))
890 145bea54 Michael Hanselmann
        self.assertEqual(row[fieldidx[field]], exp)
891 145bea54 Michael Hanselmann
892 5d28cb6f Michael Hanselmann
      self._CheckInstanceConsole(inst, row[fieldidx["console"]])
893 5d28cb6f Michael Hanselmann
894 1c8addc6 Michael Hanselmann
    # Ensure all possible status' have been tested
895 61a980a9 Michael Hanselmann
    self.assertEqual(tested_status, constants.INSTST_ALL)
896 1c8addc6 Michael Hanselmann
897 5d28cb6f Michael Hanselmann
  def _CheckInstanceConsole(self, instance, (status, consdata)):
898 5d28cb6f Michael Hanselmann
    if instance.name == "inst7":
899 5d28cb6f Michael Hanselmann
      self.assertEqual(status, constants.RS_NORMAL)
900 5d28cb6f Michael Hanselmann
      console = objects.InstanceConsole.FromDict(consdata)
901 5d28cb6f Michael Hanselmann
      self.assertTrue(console.Validate())
902 5d28cb6f Michael Hanselmann
      self.assertEqual(console.host, instance.primary_node)
903 5d28cb6f Michael Hanselmann
    else:
904 5d28cb6f Michael Hanselmann
      self.assertEqual(status, constants.RS_UNAVAIL)
905 5d28cb6f Michael Hanselmann
906 1c8addc6 Michael Hanselmann
907 d8b7ff5f Adeodato Simo
class TestGroupQuery(unittest.TestCase):
908 d8b7ff5f Adeodato Simo
909 d8b7ff5f Adeodato Simo
  def setUp(self):
910 d8b7ff5f Adeodato Simo
    self.groups = [
911 d8b7ff5f Adeodato Simo
      objects.NodeGroup(name="default",
912 d8b7ff5f Adeodato Simo
                        uuid="c0e89160-18e7-11e0-a46e-001d0904baeb",
913 d8b7ff5f Adeodato Simo
                        alloc_policy=constants.ALLOC_POLICY_PREFERRED),
914 d8b7ff5f Adeodato Simo
      objects.NodeGroup(name="restricted",
915 d8b7ff5f Adeodato Simo
                        uuid="d2a40a74-18e7-11e0-9143-001d0904baeb",
916 d8b7ff5f Adeodato Simo
                        alloc_policy=constants.ALLOC_POLICY_LAST_RESORT),
917 d8b7ff5f Adeodato Simo
      ]
918 d8b7ff5f Adeodato Simo
919 d8b7ff5f Adeodato Simo
  def _Create(self, selected):
920 d8b7ff5f Adeodato Simo
    return query.Query(query.GROUP_FIELDS, selected)
921 d8b7ff5f Adeodato Simo
922 d8b7ff5f Adeodato Simo
  def testSimple(self):
923 d8b7ff5f Adeodato Simo
    q = self._Create(["name", "uuid", "alloc_policy"])
924 d8b7ff5f Adeodato Simo
    gqd = query.GroupQueryData(self.groups, None, None)
925 d8b7ff5f Adeodato Simo
926 d8b7ff5f Adeodato Simo
    self.assertEqual(q.RequestedData(), set([query.GQ_CONFIG]))
927 d8b7ff5f Adeodato Simo
928 d8b7ff5f Adeodato Simo
    self.assertEqual(q.Query(gqd),
929 cfb084ae Renรฉ Nussbaumer
      [[(constants.RS_NORMAL, "default"),
930 cfb084ae Renรฉ Nussbaumer
        (constants.RS_NORMAL, "c0e89160-18e7-11e0-a46e-001d0904baeb"),
931 cfb084ae Renรฉ Nussbaumer
        (constants.RS_NORMAL, constants.ALLOC_POLICY_PREFERRED)
932 d8b7ff5f Adeodato Simo
        ],
933 cfb084ae Renรฉ Nussbaumer
       [(constants.RS_NORMAL, "restricted"),
934 cfb084ae Renรฉ Nussbaumer
        (constants.RS_NORMAL, "d2a40a74-18e7-11e0-9143-001d0904baeb"),
935 cfb084ae Renรฉ Nussbaumer
        (constants.RS_NORMAL, constants.ALLOC_POLICY_LAST_RESORT)
936 d8b7ff5f Adeodato Simo
        ],
937 d8b7ff5f Adeodato Simo
       ])
938 d8b7ff5f Adeodato Simo
939 d8b7ff5f Adeodato Simo
  def testNodes(self):
940 d8b7ff5f Adeodato Simo
    groups_to_nodes = {
941 d8b7ff5f Adeodato Simo
      "c0e89160-18e7-11e0-a46e-001d0904baeb": ["node1", "node2"],
942 d8b7ff5f Adeodato Simo
      "d2a40a74-18e7-11e0-9143-001d0904baeb": ["node1", "node10", "node9"],
943 d8b7ff5f Adeodato Simo
      }
944 d8b7ff5f Adeodato Simo
945 d8b7ff5f Adeodato Simo
    q = self._Create(["name", "node_cnt", "node_list"])
946 d8b7ff5f Adeodato Simo
    gqd = query.GroupQueryData(self.groups, groups_to_nodes, None)
947 d8b7ff5f Adeodato Simo
948 d8b7ff5f Adeodato Simo
    self.assertEqual(q.RequestedData(), set([query.GQ_CONFIG, query.GQ_NODE]))
949 d8b7ff5f Adeodato Simo
950 d8b7ff5f Adeodato Simo
    self.assertEqual(q.Query(gqd),
951 cfb084ae Renรฉ Nussbaumer
                     [[(constants.RS_NORMAL, "default"),
952 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, 2),
953 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, ["node1", "node2"]),
954 d8b7ff5f Adeodato Simo
                       ],
955 cfb084ae Renรฉ Nussbaumer
                      [(constants.RS_NORMAL, "restricted"),
956 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, 3),
957 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, ["node1", "node9", "node10"]),
958 d8b7ff5f Adeodato Simo
                       ],
959 d8b7ff5f Adeodato Simo
                      ])
960 d8b7ff5f Adeodato Simo
961 d8b7ff5f Adeodato Simo
  def testInstances(self):
962 d8b7ff5f Adeodato Simo
    groups_to_instances = {
963 d8b7ff5f Adeodato Simo
      "c0e89160-18e7-11e0-a46e-001d0904baeb": ["inst1", "inst2"],
964 d8b7ff5f Adeodato Simo
      "d2a40a74-18e7-11e0-9143-001d0904baeb": ["inst1", "inst10", "inst9"],
965 d8b7ff5f Adeodato Simo
      }
966 d8b7ff5f Adeodato Simo
967 d8b7ff5f Adeodato Simo
    q = self._Create(["pinst_cnt", "pinst_list"])
968 d8b7ff5f Adeodato Simo
    gqd = query.GroupQueryData(self.groups, None, groups_to_instances)
969 d8b7ff5f Adeodato Simo
970 d8b7ff5f Adeodato Simo
    self.assertEqual(q.RequestedData(), set([query.GQ_INST]))
971 d8b7ff5f Adeodato Simo
972 d8b7ff5f Adeodato Simo
    self.assertEqual(q.Query(gqd),
973 cfb084ae Renรฉ Nussbaumer
                     [[(constants.RS_NORMAL, 2),
974 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, ["inst1", "inst2"]),
975 d8b7ff5f Adeodato Simo
                       ],
976 cfb084ae Renรฉ Nussbaumer
                      [(constants.RS_NORMAL, 3),
977 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, ["inst1", "inst9", "inst10"]),
978 d8b7ff5f Adeodato Simo
                       ],
979 d8b7ff5f Adeodato Simo
                      ])
980 d8b7ff5f Adeodato Simo
981 d8b7ff5f Adeodato Simo
982 be3a4b14 Michael Hanselmann
class TestOsQuery(unittest.TestCase):
983 be3a4b14 Michael Hanselmann
  def _Create(self, selected):
984 be3a4b14 Michael Hanselmann
    return query.Query(query.OS_FIELDS, selected)
985 be3a4b14 Michael Hanselmann
986 be3a4b14 Michael Hanselmann
  def test(self):
987 be3a4b14 Michael Hanselmann
    variants = ["v00", "plain", "v3", "var0", "v33", "v20"]
988 be3a4b14 Michael Hanselmann
    api_versions = [10, 0, 15, 5]
989 be3a4b14 Michael Hanselmann
    parameters = ["zpar3", "apar9"]
990 be3a4b14 Michael Hanselmann
991 be3a4b14 Michael Hanselmann
    assert variants != sorted(variants) and variants != utils.NiceSort(variants)
992 be3a4b14 Michael Hanselmann
    assert (api_versions != sorted(api_versions) and
993 be3a4b14 Michael Hanselmann
            api_versions != utils.NiceSort(variants))
994 be3a4b14 Michael Hanselmann
    assert (parameters != sorted(parameters) and
995 be3a4b14 Michael Hanselmann
            parameters != utils.NiceSort(parameters))
996 be3a4b14 Michael Hanselmann
997 be3a4b14 Michael Hanselmann
    data = [
998 be3a4b14 Michael Hanselmann
      query.OsInfo(name="debian", valid=False, hidden=False, blacklisted=False,
999 be3a4b14 Michael Hanselmann
                   variants=set(), api_versions=set(), parameters=set(),
1000 be3a4b14 Michael Hanselmann
                   node_status={ "some": "status", }),
1001 be3a4b14 Michael Hanselmann
      query.OsInfo(name="dos", valid=True, hidden=False, blacklisted=True,
1002 be3a4b14 Michael Hanselmann
                   variants=set(variants),
1003 be3a4b14 Michael Hanselmann
                   api_versions=set(api_versions),
1004 be3a4b14 Michael Hanselmann
                   parameters=set(parameters),
1005 be3a4b14 Michael Hanselmann
                   node_status={ "some": "other", "status": None, }),
1006 be3a4b14 Michael Hanselmann
      ]
1007 be3a4b14 Michael Hanselmann
1008 be3a4b14 Michael Hanselmann
1009 be3a4b14 Michael Hanselmann
    q = self._Create(["name", "valid", "hidden", "blacklisted", "variants",
1010 be3a4b14 Michael Hanselmann
                      "api_versions", "parameters", "node_status"])
1011 be3a4b14 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([]))
1012 be3a4b14 Michael Hanselmann
    self.assertEqual(q.Query(data),
1013 be3a4b14 Michael Hanselmann
                     [[(constants.RS_NORMAL, "debian"),
1014 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, False),
1015 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, False),
1016 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, False),
1017 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, []),
1018 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, []),
1019 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, []),
1020 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, {"some": "status"})],
1021 be3a4b14 Michael Hanselmann
                      [(constants.RS_NORMAL, "dos"),
1022 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, True),
1023 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, False),
1024 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, True),
1025 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL,
1026 be3a4b14 Michael Hanselmann
                        ["plain", "v00", "v3", "v20", "v33", "var0"]),
1027 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, [0, 5, 10, 15]),
1028 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, ["apar9", "zpar3"]),
1029 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL,
1030 be3a4b14 Michael Hanselmann
                        { "some": "other", "status": None, })
1031 be3a4b14 Michael Hanselmann
                       ]])
1032 be3a4b14 Michael Hanselmann
1033 be3a4b14 Michael Hanselmann
1034 aa29e95f Michael Hanselmann
class TestQueryFields(unittest.TestCase):
1035 aa29e95f Michael Hanselmann
  def testAllFields(self):
1036 e571ee44 Adeodato Simo
    for fielddefs in query.ALL_FIELD_LISTS:
1037 aa29e95f Michael Hanselmann
      result = query.QueryFields(fielddefs, None)
1038 aa29e95f Michael Hanselmann
      self.assert_(isinstance(result, dict))
1039 aa29e95f Michael Hanselmann
      response = objects.QueryFieldsResponse.FromDict(result)
1040 aa29e95f Michael Hanselmann
      self.assertEqual([(fdef.name, fdef.title) for fdef in response.fields],
1041 aa29e95f Michael Hanselmann
        [(fdef2.name, fdef2.title)
1042 111bf531 Michael Hanselmann
         for (fdef2, _, _, _) in utils.NiceSort(fielddefs.values(),
1043 111bf531 Michael Hanselmann
                                                key=lambda x: x[0].name)])
1044 aa29e95f Michael Hanselmann
1045 aa29e95f Michael Hanselmann
  def testSomeFields(self):
1046 aa29e95f Michael Hanselmann
    rnd = random.Random(5357)
1047 aa29e95f Michael Hanselmann
1048 aa29e95f Michael Hanselmann
    for _ in range(10):
1049 e571ee44 Adeodato Simo
      for fielddefs in query.ALL_FIELD_LISTS:
1050 e571ee44 Adeodato Simo
        if len(fielddefs) > 20:
1051 e571ee44 Adeodato Simo
          sample_size = rnd.randint(5, 20)
1052 e571ee44 Adeodato Simo
        else:
1053 e571ee44 Adeodato Simo
          sample_size = rnd.randint(1, max(1, len(fielddefs) - 1))
1054 111bf531 Michael Hanselmann
        fields = [fdef for (fdef, _, _, _) in rnd.sample(fielddefs.values(),
1055 111bf531 Michael Hanselmann
                                                         sample_size)]
1056 aa29e95f Michael Hanselmann
        result = query.QueryFields(fielddefs, [fdef.name for fdef in fields])
1057 aa29e95f Michael Hanselmann
        self.assert_(isinstance(result, dict))
1058 aa29e95f Michael Hanselmann
        response = objects.QueryFieldsResponse.FromDict(result)
1059 aa29e95f Michael Hanselmann
        self.assertEqual([(fdef.name, fdef.title) for fdef in response.fields],
1060 aa29e95f Michael Hanselmann
                         [(fdef2.name, fdef2.title) for fdef2 in fields])
1061 aa29e95f Michael Hanselmann
1062 aa29e95f Michael Hanselmann
1063 fb0be379 Michael Hanselmann
class TestQueryFilter(unittest.TestCase):
1064 fb0be379 Michael Hanselmann
  def testRequestedNames(self):
1065 fb0be379 Michael Hanselmann
    innerfilter = [["=", "name", "x%s" % i] for i in range(4)]
1066 fb0be379 Michael Hanselmann
1067 fb0be379 Michael Hanselmann
    for fielddefs in query.ALL_FIELD_LISTS:
1068 fb0be379 Michael Hanselmann
      assert "name" in fielddefs
1069 fb0be379 Michael Hanselmann
1070 fb0be379 Michael Hanselmann
      # No name field
1071 2e5c33db Iustin Pop
      q = query.Query(fielddefs, ["name"], qfilter=["=", "name", "abc"],
1072 fb0be379 Michael Hanselmann
                      namefield=None)
1073 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), None)
1074 fb0be379 Michael Hanselmann
1075 fb0be379 Michael Hanselmann
      # No filter
1076 2e5c33db Iustin Pop
      q = query.Query(fielddefs, ["name"], qfilter=None, namefield="name")
1077 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), None)
1078 fb0be379 Michael Hanselmann
1079 fb0be379 Michael Hanselmann
      # Check empty query
1080 2e5c33db Iustin Pop
      q = query.Query(fielddefs, ["name"], qfilter=["|"], namefield="name")
1081 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), None)
1082 fb0be379 Michael Hanselmann
1083 fb0be379 Michael Hanselmann
      # Check order
1084 2e5c33db Iustin Pop
      q = query.Query(fielddefs, ["name"], qfilter=["|"] + innerfilter,
1085 fb0be379 Michael Hanselmann
                      namefield="name")
1086 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), ["x0", "x1", "x2", "x3"])
1087 fb0be379 Michael Hanselmann
1088 fb0be379 Michael Hanselmann
      # Check reverse order
1089 fb0be379 Michael Hanselmann
      q = query.Query(fielddefs, ["name"],
1090 2e5c33db Iustin Pop
                      qfilter=["|"] + list(reversed(innerfilter)),
1091 fb0be379 Michael Hanselmann
                      namefield="name")
1092 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), ["x3", "x2", "x1", "x0"])
1093 fb0be379 Michael Hanselmann
1094 fb0be379 Michael Hanselmann
      # Duplicates
1095 fb0be379 Michael Hanselmann
      q = query.Query(fielddefs, ["name"],
1096 2e5c33db Iustin Pop
                      qfilter=["|"] + innerfilter + list(reversed(innerfilter)),
1097 fb0be379 Michael Hanselmann
                      namefield="name")
1098 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), ["x0", "x1", "x2", "x3"])
1099 fb0be379 Michael Hanselmann
1100 fb0be379 Michael Hanselmann
      # Unknown name field
1101 fb0be379 Michael Hanselmann
      self.assertRaises(AssertionError, query.Query, fielddefs, ["name"],
1102 fb0be379 Michael Hanselmann
                        namefield="_unknown_field_")
1103 fb0be379 Michael Hanselmann
1104 fb0be379 Michael Hanselmann
      # Filter with AND
1105 fb0be379 Michael Hanselmann
      q = query.Query(fielddefs, ["name"],
1106 2e5c33db Iustin Pop
                      qfilter=["|", ["=", "name", "foo"],
1107 fb0be379 Michael Hanselmann
                                    ["&", ["=", "name", ""]]],
1108 fb0be379 Michael Hanselmann
                      namefield="name")
1109 fb0be379 Michael Hanselmann
      self.assertTrue(q.RequestedNames() is None)
1110 fb0be379 Michael Hanselmann
1111 fb0be379 Michael Hanselmann
      # Filter with NOT
1112 fb0be379 Michael Hanselmann
      q = query.Query(fielddefs, ["name"],
1113 2e5c33db Iustin Pop
                      qfilter=["|", ["=", "name", "foo"],
1114 fb0be379 Michael Hanselmann
                                    ["!", ["=", "name", ""]]],
1115 fb0be379 Michael Hanselmann
                      namefield="name")
1116 fb0be379 Michael Hanselmann
      self.assertTrue(q.RequestedNames() is None)
1117 fb0be379 Michael Hanselmann
1118 fb0be379 Michael Hanselmann
      # Filter with only OR (names must be in correct order)
1119 fb0be379 Michael Hanselmann
      q = query.Query(fielddefs, ["name"],
1120 2e5c33db Iustin Pop
                      qfilter=["|", ["=", "name", "x17361"],
1121 fb0be379 Michael Hanselmann
                                    ["|", ["=", "name", "x22015"]],
1122 fb0be379 Michael Hanselmann
                                    ["|", ["|", ["=", "name", "x13193"]]],
1123 fb0be379 Michael Hanselmann
                                    ["=", "name", "x15215"]],
1124 fb0be379 Michael Hanselmann
                      namefield="name")
1125 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(),
1126 fb0be379 Michael Hanselmann
                       ["x17361", "x22015", "x13193", "x15215"])
1127 fb0be379 Michael Hanselmann
1128 fb0be379 Michael Hanselmann
  @staticmethod
1129 fb0be379 Michael Hanselmann
  def _GenNestedFilter(op, depth):
1130 fb0be379 Michael Hanselmann
    nested = ["=", "name", "value"]
1131 fb0be379 Michael Hanselmann
    for i in range(depth):
1132 fb0be379 Michael Hanselmann
      nested = [op, nested]
1133 fb0be379 Michael Hanselmann
    return nested
1134 fb0be379 Michael Hanselmann
1135 fb0be379 Michael Hanselmann
  def testCompileFilter(self):
1136 fb0be379 Michael Hanselmann
    levels_max = query._FilterCompilerHelper._LEVELS_MAX
1137 fb0be379 Michael Hanselmann
1138 fb0be379 Michael Hanselmann
    checks = [
1139 fb0be379 Michael Hanselmann
      [], ["="], ["=", "foo"], ["unknownop"], ["!"],
1140 fb0be379 Michael Hanselmann
      ["=", "_unknown_field", "value"],
1141 fb0be379 Michael Hanselmann
      self._GenNestedFilter("|", levels_max),
1142 fb0be379 Michael Hanselmann
      self._GenNestedFilter("|", levels_max * 3),
1143 fb0be379 Michael Hanselmann
      self._GenNestedFilter("!", levels_max),
1144 fb0be379 Michael Hanselmann
      ]
1145 fb0be379 Michael Hanselmann
1146 fb0be379 Michael Hanselmann
    for fielddefs in query.ALL_FIELD_LISTS:
1147 2e5c33db Iustin Pop
      for qfilter in checks:
1148 fb0be379 Michael Hanselmann
        self.assertRaises(errors.ParameterError, query._CompileFilter,
1149 2e5c33db Iustin Pop
                          fielddefs, None, qfilter)
1150 fb0be379 Michael Hanselmann
1151 fb0be379 Michael Hanselmann
      for op in ["|", "!"]:
1152 2e5c33db Iustin Pop
        qfilter = self._GenNestedFilter(op, levels_max - 1)
1153 fb0be379 Michael Hanselmann
        self.assertTrue(callable(query._CompileFilter(fielddefs, None,
1154 2e5c33db Iustin Pop
                                                      qfilter)))
1155 fb0be379 Michael Hanselmann
1156 fb0be379 Michael Hanselmann
  def testQueryInputOrder(self):
1157 fb0be379 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1158 fb0be379 Michael Hanselmann
      (query._MakeField("pnode", "PNode", constants.QFT_TEXT, "Primary"),
1159 fb0be379 Michael Hanselmann
       None, 0, lambda ctx, item: item["pnode"]),
1160 fb0be379 Michael Hanselmann
      (query._MakeField("snode", "SNode", constants.QFT_TEXT, "Secondary"),
1161 fb0be379 Michael Hanselmann
       None, 0, lambda ctx, item: item["snode"]),
1162 fb0be379 Michael Hanselmann
      ], [])
1163 fb0be379 Michael Hanselmann
1164 fb0be379 Michael Hanselmann
    data = [
1165 fb0be379 Michael Hanselmann
      { "pnode": "node1", "snode": "node44", },
1166 fb0be379 Michael Hanselmann
      { "pnode": "node30", "snode": "node90", },
1167 fb0be379 Michael Hanselmann
      { "pnode": "node25", "snode": "node1", },
1168 fb0be379 Michael Hanselmann
      { "pnode": "node20", "snode": "node1", },
1169 fb0be379 Michael Hanselmann
      ]
1170 fb0be379 Michael Hanselmann
1171 2e5c33db Iustin Pop
    qfilter = ["|", ["=", "pnode", "node1"], ["=", "snode", "node1"]]
1172 fb0be379 Michael Hanselmann
1173 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "snode"], namefield="pnode",
1174 2e5c33db Iustin Pop
                    qfilter=qfilter)
1175 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1176 fb0be379 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1177 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1178 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")],
1179 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")],
1180 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")]])
1181 fb0be379 Michael Hanselmann
1182 fb0be379 Michael Hanselmann
    # Try again with reversed input data
1183 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(reversed(data)),
1184 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")],
1185 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")],
1186 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")]])
1187 fb0be379 Michael Hanselmann
1188 fb0be379 Michael Hanselmann
    # No name field, result must be in incoming order
1189 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "snode"], namefield=None,
1190 2e5c33db Iustin Pop
                    qfilter=qfilter)
1191 fb0be379 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1192 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1193 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")],
1194 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")],
1195 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")]])
1196 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1197 fb0be379 Michael Hanselmann
      ["node1", "node44"],
1198 fb0be379 Michael Hanselmann
      ["node25", "node1"],
1199 fb0be379 Michael Hanselmann
      ["node20", "node1"],
1200 fb0be379 Michael Hanselmann
      ])
1201 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(reversed(data)),
1202 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")],
1203 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")],
1204 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")]])
1205 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(reversed(data)), [
1206 fb0be379 Michael Hanselmann
      ["node20", "node1"],
1207 fb0be379 Michael Hanselmann
      ["node25", "node1"],
1208 fb0be379 Michael Hanselmann
      ["node1", "node44"],
1209 fb0be379 Michael Hanselmann
      ])
1210 fb0be379 Michael Hanselmann
1211 fbc263a9 Michael Hanselmann
    # Name field, but no sorting, result must be in incoming order
1212 fbc263a9 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "snode"], namefield="pnode")
1213 fbc263a9 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1214 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data, sort_by_name=False),
1215 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")],
1216 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node30"), (constants.RS_NORMAL, "node90")],
1217 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")],
1218 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")]])
1219 fbc263a9 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data, sort_by_name=False), [
1220 fbc263a9 Michael Hanselmann
      ["node1", "node44"],
1221 fbc263a9 Michael Hanselmann
      ["node30", "node90"],
1222 fbc263a9 Michael Hanselmann
      ["node25", "node1"],
1223 fbc263a9 Michael Hanselmann
      ["node20", "node1"],
1224 fbc263a9 Michael Hanselmann
      ])
1225 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(reversed(data), sort_by_name=False),
1226 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")],
1227 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")],
1228 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node30"), (constants.RS_NORMAL, "node90")],
1229 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")]])
1230 fbc263a9 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(reversed(data), sort_by_name=False), [
1231 fbc263a9 Michael Hanselmann
      ["node20", "node1"],
1232 fbc263a9 Michael Hanselmann
      ["node25", "node1"],
1233 fbc263a9 Michael Hanselmann
      ["node30", "node90"],
1234 fbc263a9 Michael Hanselmann
      ["node1", "node44"],
1235 fbc263a9 Michael Hanselmann
      ])
1236 fbc263a9 Michael Hanselmann
1237 fbc263a9 Michael Hanselmann
  def testEqualNamesOrder(self):
1238 fbc263a9 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1239 fbc263a9 Michael Hanselmann
      (query._MakeField("pnode", "PNode", constants.QFT_TEXT, "Primary"),
1240 fbc263a9 Michael Hanselmann
       None, 0, lambda ctx, item: item["pnode"]),
1241 fbc263a9 Michael Hanselmann
      (query._MakeField("num", "Num", constants.QFT_NUMBER, "Num"),
1242 fbc263a9 Michael Hanselmann
       None, 0, lambda ctx, item: item["num"]),
1243 fbc263a9 Michael Hanselmann
      ], [])
1244 fbc263a9 Michael Hanselmann
1245 fbc263a9 Michael Hanselmann
    data = [
1246 fbc263a9 Michael Hanselmann
      { "pnode": "node1", "num": 100, },
1247 fbc263a9 Michael Hanselmann
      { "pnode": "node1", "num": 25, },
1248 fbc263a9 Michael Hanselmann
      { "pnode": "node2", "num": 90, },
1249 fbc263a9 Michael Hanselmann
      { "pnode": "node2", "num": 30, },
1250 fbc263a9 Michael Hanselmann
      ]
1251 fbc263a9 Michael Hanselmann
1252 fbc263a9 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "num"], namefield="pnode",
1253 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "pnode", "node1"],
1254 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "node2"],
1255 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "node1"]])
1256 fbc263a9 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1", "node2"],
1257 fbc263a9 Michael Hanselmann
                     msg="Did not return unique names")
1258 fbc263a9 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1259 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data),
1260 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, 100)],
1261 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, 25)],
1262 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, 90)],
1263 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, 30)]])
1264 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data, sort_by_name=False),
1265 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, 100)],
1266 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, 25)],
1267 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, 90)],
1268 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, 30)]])
1269 fbc263a9 Michael Hanselmann
1270 fbc263a9 Michael Hanselmann
    data = [
1271 fbc263a9 Michael Hanselmann
      { "pnode": "nodeX", "num": 50, },
1272 fbc263a9 Michael Hanselmann
      { "pnode": "nodeY", "num": 40, },
1273 fbc263a9 Michael Hanselmann
      { "pnode": "nodeX", "num": 30, },
1274 fbc263a9 Michael Hanselmann
      { "pnode": "nodeX", "num": 20, },
1275 fbc263a9 Michael Hanselmann
      { "pnode": "nodeM", "num": 10, },
1276 fbc263a9 Michael Hanselmann
      ]
1277 fbc263a9 Michael Hanselmann
1278 fbc263a9 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "num"], namefield="pnode",
1279 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "pnode", "nodeX"],
1280 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "nodeY"],
1281 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "nodeY"],
1282 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "nodeY"],
1283 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "nodeM"]])
1284 fbc263a9 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["nodeX", "nodeY", "nodeM"],
1285 fbc263a9 Michael Hanselmann
                     msg="Did not return unique names")
1286 fbc263a9 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1287 fbc263a9 Michael Hanselmann
1288 fbc263a9 Michael Hanselmann
    # First sorted by name, then input order
1289 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data, sort_by_name=True),
1290 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "nodeM"), (constants.RS_NORMAL, 10)],
1291 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 50)],
1292 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 30)],
1293 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 20)],
1294 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeY"), (constants.RS_NORMAL, 40)]])
1295 fbc263a9 Michael Hanselmann
1296 fbc263a9 Michael Hanselmann
    # Input order
1297 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data, sort_by_name=False),
1298 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 50)],
1299 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeY"), (constants.RS_NORMAL, 40)],
1300 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 30)],
1301 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 20)],
1302 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeM"), (constants.RS_NORMAL, 10)]])
1303 fbc263a9 Michael Hanselmann
1304 fb0be379 Michael Hanselmann
  def testFilter(self):
1305 fb0be379 Michael Hanselmann
    (DK_A, DK_B) = range(1000, 1002)
1306 fb0be379 Michael Hanselmann
1307 fb0be379 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1308 fb0be379 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1309 fb0be379 Michael Hanselmann
       DK_A, 0, lambda ctx, item: item["name"]),
1310 fb0be379 Michael Hanselmann
      (query._MakeField("other", "Other", constants.QFT_TEXT, "Other"),
1311 fb0be379 Michael Hanselmann
       DK_B, 0, lambda ctx, item: item["other"]),
1312 fb0be379 Michael Hanselmann
      ], [])
1313 fb0be379 Michael Hanselmann
1314 fb0be379 Michael Hanselmann
    data = [
1315 fb0be379 Michael Hanselmann
      { "name": "node1", "other": "foo", },
1316 fb0be379 Michael Hanselmann
      { "name": "node2", "other": "bar", },
1317 fb0be379 Michael Hanselmann
      { "name": "node3", "other": "Hello", },
1318 fb0be379 Michael Hanselmann
      ]
1319 fb0be379 Michael Hanselmann
1320 fb0be379 Michael Hanselmann
    # Empty filter
1321 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1322 2e5c33db Iustin Pop
                    qfilter=["|"])
1323 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1324 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_A, DK_B]))
1325 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [])
1326 fb0be379 Michael Hanselmann
1327 fb0be379 Michael Hanselmann
    # Normal filter
1328 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1329 2e5c33db Iustin Pop
                    qfilter=["=", "name", "node1"])
1330 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1"])
1331 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1332 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "foo")]])
1333 fb0be379 Michael Hanselmann
1334 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1335 2e5c33db Iustin Pop
                    qfilter=(["|", ["=", "name", "node1"],
1336 fb0be379 Michael Hanselmann
                                   ["=", "name", "node3"]]))
1337 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1", "node3"])
1338 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1339 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "foo")],
1340 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, "Hello")]])
1341 fb0be379 Michael Hanselmann
1342 fb0be379 Michael Hanselmann
    # Complex filter
1343 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1344 2e5c33db Iustin Pop
                    qfilter=(["|", ["=", "name", "node1"],
1345 fb0be379 Michael Hanselmann
                                   ["|", ["=", "name", "node3"],
1346 fb0be379 Michael Hanselmann
                                         ["=", "name", "node2"]],
1347 fb0be379 Michael Hanselmann
                                   ["=", "name", "node3"]]))
1348 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1", "node3", "node2"])
1349 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_A, DK_B]))
1350 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1351 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "foo")],
1352 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, "bar")],
1353 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, "Hello")]])
1354 fb0be379 Michael Hanselmann
1355 fb0be379 Michael Hanselmann
    # Filter data type mismatch
1356 fb0be379 Michael Hanselmann
    for i in [-1, 0, 1, 123, [], None, True, False]:
1357 fb0be379 Michael Hanselmann
      self.assertRaises(errors.ParameterError, query.Query,
1358 fb0be379 Michael Hanselmann
                        fielddefs, ["name", "other"], namefield="name",
1359 2e5c33db Iustin Pop
                        qfilter=["=", "name", i])
1360 fb0be379 Michael Hanselmann
1361 fb0be379 Michael Hanselmann
    # Negative filter
1362 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1363 2e5c33db Iustin Pop
                    qfilter=["!", ["|", ["=", "name", "node1"],
1364 fb0be379 Michael Hanselmann
                                        ["=", "name", "node3"]]])
1365 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1366 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1367 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, "bar")]])
1368 fb0be379 Michael Hanselmann
1369 fb0be379 Michael Hanselmann
    # Not equal
1370 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1371 2e5c33db Iustin Pop
                    qfilter=["!=", "name", "node3"])
1372 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1373 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1374 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "foo")],
1375 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, "bar")]])
1376 fb0be379 Michael Hanselmann
1377 fb0be379 Michael Hanselmann
    # Data type
1378 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, [], namefield="name",
1379 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "other", "bar"],
1380 fb0be379 Michael Hanselmann
                                  ["=", "name", "foo"]])
1381 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1382 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_A, DK_B]))
1383 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [[]])
1384 fb0be379 Michael Hanselmann
1385 fb0be379 Michael Hanselmann
    # Only one data type
1386 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["other"], namefield="name",
1387 2e5c33db Iustin Pop
                    qfilter=["=", "other", "bar"])
1388 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1389 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_B]))
1390 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [[(constants.RS_NORMAL, "bar")]])
1391 fb0be379 Michael Hanselmann
1392 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, [], namefield="name",
1393 2e5c33db Iustin Pop
                    qfilter=["=", "other", "bar"])
1394 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1395 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_B]))
1396 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [[]])
1397 fb0be379 Michael Hanselmann
1398 fb0be379 Michael Hanselmann
  def testFilterContains(self):
1399 fb0be379 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1400 fb0be379 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1401 fb0be379 Michael Hanselmann
       None, 0, lambda ctx, item: item["name"]),
1402 fb0be379 Michael Hanselmann
      (query._MakeField("other", "Other", constants.QFT_OTHER, "Other"),
1403 fb0be379 Michael Hanselmann
       None, 0, lambda ctx, item: item["other"]),
1404 fb0be379 Michael Hanselmann
      ], [])
1405 fb0be379 Michael Hanselmann
1406 fb0be379 Michael Hanselmann
    data = [
1407 fb0be379 Michael Hanselmann
      { "name": "node2", "other": ["x", "y", "bar"], },
1408 fb0be379 Michael Hanselmann
      { "name": "node3", "other": "Hello", },
1409 fb0be379 Michael Hanselmann
      { "name": "node1", "other": ["a", "b", "foo"], },
1410 3b877f08 Michael Hanselmann
      { "name": "empty", "other": []},
1411 fb0be379 Michael Hanselmann
      ]
1412 fb0be379 Michael Hanselmann
1413 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1414 2e5c33db Iustin Pop
                    qfilter=["=[]", "other", "bar"])
1415 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1416 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1417 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"),
1418 fb0be379 Michael Hanselmann
       (constants.RS_NORMAL, ["x", "y", "bar"])],
1419 fb0be379 Michael Hanselmann
      ])
1420 fb0be379 Michael Hanselmann
1421 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1422 2e5c33db Iustin Pop
                    qfilter=["|", ["=[]", "other", "bar"],
1423 fb0be379 Michael Hanselmann
                                  ["=[]", "other", "a"],
1424 fb0be379 Michael Hanselmann
                                  ["=[]", "other", "b"]])
1425 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1426 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1427 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"),
1428 fb0be379 Michael Hanselmann
       (constants.RS_NORMAL, ["a", "b", "foo"])],
1429 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"),
1430 fb0be379 Michael Hanselmann
       (constants.RS_NORMAL, ["x", "y", "bar"])],
1431 fb0be379 Michael Hanselmann
      ])
1432 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1433 fb0be379 Michael Hanselmann
      ["node1", ["a", "b", "foo"]],
1434 fb0be379 Michael Hanselmann
      ["node2", ["x", "y", "bar"]],
1435 fb0be379 Michael Hanselmann
      ])
1436 fb0be379 Michael Hanselmann
1437 3b877f08 Michael Hanselmann
    # Boolean test
1438 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1439 2e5c33db Iustin Pop
                    qfilter=["?", "other"])
1440 3b877f08 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1441 3b877f08 Michael Hanselmann
      ["node1", ["a", "b", "foo"]],
1442 3b877f08 Michael Hanselmann
      ["node2", ["x", "y", "bar"]],
1443 3b877f08 Michael Hanselmann
      ["node3", "Hello"],
1444 3b877f08 Michael Hanselmann
      ])
1445 3b877f08 Michael Hanselmann
1446 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1447 2e5c33db Iustin Pop
                    qfilter=["!", ["?", "other"]])
1448 3b877f08 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1449 3b877f08 Michael Hanselmann
      ["empty", []],
1450 3b877f08 Michael Hanselmann
      ])
1451 3b877f08 Michael Hanselmann
1452 fb0be379 Michael Hanselmann
  def testFilterHostname(self):
1453 fb0be379 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1454 fb0be379 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1455 fb0be379 Michael Hanselmann
       None, query.QFF_HOSTNAME, lambda ctx, item: item["name"]),
1456 fb0be379 Michael Hanselmann
      ], [])
1457 fb0be379 Michael Hanselmann
1458 fb0be379 Michael Hanselmann
    data = [
1459 fb0be379 Michael Hanselmann
      { "name": "node1.example.com", },
1460 fb0be379 Michael Hanselmann
      { "name": "node2.example.com", },
1461 fb0be379 Michael Hanselmann
      { "name": "node2.example.net", },
1462 fb0be379 Michael Hanselmann
      ]
1463 fb0be379 Michael Hanselmann
1464 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1465 2e5c33db Iustin Pop
                    qfilter=["=", "name", "node2"])
1466 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node2"])
1467 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1468 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.com")],
1469 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.net")],
1470 fb0be379 Michael Hanselmann
      ])
1471 fb0be379 Michael Hanselmann
1472 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1473 2e5c33db Iustin Pop
                    qfilter=["=", "name", "node1"])
1474 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1"])
1475 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1476 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node1.example.com")],
1477 fb0be379 Michael Hanselmann
      ])
1478 fb0be379 Michael Hanselmann
1479 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1480 2e5c33db Iustin Pop
                    qfilter=["=", "name", "othername"])
1481 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["othername"])
1482 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [])
1483 fb0be379 Michael Hanselmann
1484 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1485 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "name", "node1.example.com"],
1486 fb0be379 Michael Hanselmann
                                  ["=", "name", "node2"]])
1487 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1.example.com", "node2"])
1488 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1489 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node1.example.com")],
1490 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.com")],
1491 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.net")],
1492 fb0be379 Michael Hanselmann
      ])
1493 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1494 fb0be379 Michael Hanselmann
      ["node1.example.com"],
1495 fb0be379 Michael Hanselmann
      ["node2.example.com"],
1496 fb0be379 Michael Hanselmann
      ["node2.example.net"],
1497 fb0be379 Michael Hanselmann
      ])
1498 fb0be379 Michael Hanselmann
1499 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1500 2e5c33db Iustin Pop
                    qfilter=["!=", "name", "node1"])
1501 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1502 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1503 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.com")],
1504 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.net")],
1505 fb0be379 Michael Hanselmann
      ])
1506 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1507 fb0be379 Michael Hanselmann
      ["node2.example.com"],
1508 fb0be379 Michael Hanselmann
      ["node2.example.net"],
1509 fb0be379 Michael Hanselmann
      ])
1510 fb0be379 Michael Hanselmann
1511 3b877f08 Michael Hanselmann
  def testFilterBoolean(self):
1512 3b877f08 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1513 3b877f08 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1514 3b877f08 Michael Hanselmann
       None, query.QFF_HOSTNAME, lambda ctx, item: item["name"]),
1515 3b877f08 Michael Hanselmann
      (query._MakeField("value", "Value", constants.QFT_BOOL, "Value"),
1516 3b877f08 Michael Hanselmann
       None, 0, lambda ctx, item: item["value"]),
1517 3b877f08 Michael Hanselmann
      ], [])
1518 3b877f08 Michael Hanselmann
1519 3b877f08 Michael Hanselmann
    data = [
1520 3b877f08 Michael Hanselmann
      { "name": "node1", "value": False, },
1521 3b877f08 Michael Hanselmann
      { "name": "node2", "value": True, },
1522 3b877f08 Michael Hanselmann
      { "name": "node3", "value": True, },
1523 3b877f08 Michael Hanselmann
      ]
1524 3b877f08 Michael Hanselmann
1525 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "value"],
1526 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "value", False],
1527 3b877f08 Michael Hanselmann
                                  ["=", "value", True]])
1528 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1529 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1530 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, False)],
1531 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, True)],
1532 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, True)],
1533 3b877f08 Michael Hanselmann
      ])
1534 3b877f08 Michael Hanselmann
1535 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "value"],
1536 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "value", False],
1537 3b877f08 Michael Hanselmann
                                  ["!", ["=", "value", False]]])
1538 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1539 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1540 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, False)],
1541 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, True)],
1542 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, True)],
1543 3b877f08 Michael Hanselmann
      ])
1544 3b877f08 Michael Hanselmann
1545 3b877f08 Michael Hanselmann
    # Comparing bool with string
1546 3b877f08 Michael Hanselmann
    for i in ["False", "True", "0", "1", "no", "yes", "N", "Y"]:
1547 3b877f08 Michael Hanselmann
      self.assertRaises(errors.ParameterError, query.Query,
1548 3b877f08 Michael Hanselmann
                        fielddefs, ["name", "value"],
1549 2e5c33db Iustin Pop
                        qfilter=["=", "value", i])
1550 3b877f08 Michael Hanselmann
1551 3b877f08 Michael Hanselmann
    # Truth filter
1552 2e5c33db Iustin Pop
    q = query.Query(fielddefs, ["name", "value"], qfilter=["?", "value"])
1553 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1554 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1555 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, True)],
1556 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, True)],
1557 3b877f08 Michael Hanselmann
      ])
1558 3b877f08 Michael Hanselmann
1559 3b877f08 Michael Hanselmann
    # Negative bool filter
1560 2e5c33db Iustin Pop
    q = query.Query(fielddefs, ["name", "value"], qfilter=["!", ["?", "value"]])
1561 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1562 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1563 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, False)],
1564 3b877f08 Michael Hanselmann
      ])
1565 3b877f08 Michael Hanselmann
1566 3b877f08 Michael Hanselmann
    # Complex truth filter
1567 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "value"],
1568 2e5c33db Iustin Pop
                    qfilter=["|", ["&", ["=", "name", "node1"],
1569 3b877f08 Michael Hanselmann
                                        ["!", ["?", "value"]]],
1570 3b877f08 Michael Hanselmann
                                  ["?", "value"]])
1571 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1572 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1573 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, False)],
1574 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, True)],
1575 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, True)],
1576 3b877f08 Michael Hanselmann
      ])
1577 3b877f08 Michael Hanselmann
1578 23d0a608 Michael Hanselmann
  def testFilterRegex(self):
1579 23d0a608 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1580 23d0a608 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1581 23d0a608 Michael Hanselmann
       None, 0, lambda ctx, item: item["name"]),
1582 23d0a608 Michael Hanselmann
      ], [])
1583 23d0a608 Michael Hanselmann
1584 23d0a608 Michael Hanselmann
    data = [
1585 23d0a608 Michael Hanselmann
      { "name": "node1.example.com", },
1586 23d0a608 Michael Hanselmann
      { "name": "node2.site.example.com", },
1587 23d0a608 Michael Hanselmann
      { "name": "node2.example.net", },
1588 23d0a608 Michael Hanselmann
1589 23d0a608 Michael Hanselmann
      # Empty name
1590 23d0a608 Michael Hanselmann
      { "name": "", },
1591 23d0a608 Michael Hanselmann
      ]
1592 23d0a608 Michael Hanselmann
1593 23d0a608 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1594 2e5c33db Iustin Pop
                    qfilter=["=~", "name", "site"])
1595 23d0a608 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1596 23d0a608 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1597 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.site.example.com")],
1598 23d0a608 Michael Hanselmann
      ])
1599 23d0a608 Michael Hanselmann
1600 23d0a608 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1601 2e5c33db Iustin Pop
                    qfilter=["=~", "name", "^node2"])
1602 23d0a608 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1603 23d0a608 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1604 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.net")],
1605 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.site.example.com")],
1606 23d0a608 Michael Hanselmann
      ])
1607 23d0a608 Michael Hanselmann
1608 23d0a608 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1609 2e5c33db Iustin Pop
                    qfilter=["=~", "name", r"(?i)\.COM$"])
1610 23d0a608 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1611 23d0a608 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1612 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node1.example.com")],
1613 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.site.example.com")],
1614 23d0a608 Michael Hanselmann
      ])
1615 23d0a608 Michael Hanselmann
1616 23d0a608 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1617 2e5c33db Iustin Pop
                    qfilter=["=~", "name", r"."])
1618 23d0a608 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1619 23d0a608 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1620 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node1.example.com")],
1621 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.net")],
1622 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.site.example.com")],
1623 23d0a608 Michael Hanselmann
      ])
1624 23d0a608 Michael Hanselmann
1625 23d0a608 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1626 2e5c33db Iustin Pop
                    qfilter=["=~", "name", r"^$"])
1627 23d0a608 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1628 23d0a608 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1629 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "")],
1630 23d0a608 Michael Hanselmann
      ])
1631 23d0a608 Michael Hanselmann
1632 23d0a608 Michael Hanselmann
    # Invalid regular expression
1633 23d0a608 Michael Hanselmann
    self.assertRaises(errors.ParameterError, query.Query, fielddefs, ["name"],
1634 2e5c33db Iustin Pop
                      qfilter=["=~", "name", r"["])
1635 23d0a608 Michael Hanselmann
1636 fb0be379 Michael Hanselmann
1637 4ca96421 Michael Hanselmann
if __name__ == "__main__":
1638 4ca96421 Michael Hanselmann
  testutils.GanetiTestProgram()