Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.query_unittest.py @ 8dc76d54

History | View | Annotate | Download (63.2 kB)

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