Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.query_unittest.py @ 595149d5

History | View | Annotate | Download (73.3 kB)

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