Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.query_unittest.py @ 14933c17

History | View | Annotate | Download (74.4 kB)

1 4ca96421 Michael Hanselmann
#!/usr/bin/python
2 4ca96421 Michael Hanselmann
#
3 4ca96421 Michael Hanselmann
4 c81b97f2 Iustin Pop
# Copyright (C) 2010, 2011, 2012, 2013 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 da4a52a3 Thomas Thrainer
      nqd = query.NodeQueryData(nodes, live_data, None, 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 1c3231aa Thomas Thrainer
    live_data_node = nodes[4]
427 1c3231aa Thomas Thrainer
    assert live_data_node.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 f43c898d Bernardo Dal Seno
      "cnos": 3,
433 8235fe04 Michael Hanselmann
      "csockets": 4,
434 8235fe04 Michael Hanselmann
      "ctotal": 8,
435 8235fe04 Michael Hanselmann
      "mnode": 128,
436 8235fe04 Michael Hanselmann
      "mfree": 100,
437 8235fe04 Michael Hanselmann
      "mtotal": 4096,
438 8235fe04 Michael Hanselmann
      "dfree": 5 * 1024 * 1024,
439 8235fe04 Michael Hanselmann
      "dtotal": 100 * 1024 * 1024,
440 06fb92cf Bernardo Dal Seno
      "spfree": 0,
441 06fb92cf Bernardo Dal Seno
      "sptotal": 0,
442 8235fe04 Michael Hanselmann
      }
443 8235fe04 Michael Hanselmann
444 8235fe04 Michael Hanselmann
    assert (sorted(query._NODE_LIVE_FIELDS.keys()) ==
445 8235fe04 Michael Hanselmann
            sorted(fake_live_data.keys()))
446 8235fe04 Michael Hanselmann
447 1c3231aa Thomas Thrainer
    live_data = dict.fromkeys([node.uuid for node in nodes], {})
448 1c3231aa Thomas Thrainer
    live_data[live_data_node.uuid] = \
449 8235fe04 Michael Hanselmann
      dict((query._NODE_LIVE_FIELDS[name][2], value)
450 8235fe04 Michael Hanselmann
           for name, value in fake_live_data.items())
451 8235fe04 Michael Hanselmann
452 da4a52a3 Thomas Thrainer
    node_to_primary_uuid = dict((node.uuid, set()) for node in nodes)
453 da4a52a3 Thomas Thrainer
    node_to_primary_uuid[master_node.uuid].update(["inst1", "inst2"])
454 8235fe04 Michael Hanselmann
455 da4a52a3 Thomas Thrainer
    node_to_secondary_uuid = dict((node.uuid, set()) for node in nodes)
456 da4a52a3 Thomas Thrainer
    node_to_secondary_uuid[live_data_node.uuid].update(["instX", "instY",
457 da4a52a3 Thomas Thrainer
                                                        "instZ"])
458 da4a52a3 Thomas Thrainer
459 da4a52a3 Thomas Thrainer
    inst_uuid_to_inst_name = {
460 da4a52a3 Thomas Thrainer
      "inst1": "inst1-name",
461 da4a52a3 Thomas Thrainer
      "inst2": "inst2-name",
462 da4a52a3 Thomas Thrainer
      "instX": "instX-name",
463 da4a52a3 Thomas Thrainer
      "instY": "instY-name",
464 da4a52a3 Thomas Thrainer
      "instZ": "instZ-name"
465 da4a52a3 Thomas Thrainer
    }
466 8235fe04 Michael Hanselmann
467 8235fe04 Michael Hanselmann
    ng_uuid = "492b4b74-8670-478a-b98d-4c53a76238e6"
468 8235fe04 Michael Hanselmann
    groups = {
469 8572f1fe René Nussbaumer
      ng_uuid: objects.NodeGroup(name="ng1", uuid=ng_uuid, ndparams={}),
470 8235fe04 Michael Hanselmann
      }
471 8235fe04 Michael Hanselmann
472 1c3231aa Thomas Thrainer
    oob_not_powered_node = nodes[0]
473 1c3231aa Thomas Thrainer
    oob_not_powered_node.powered = False
474 1c3231aa Thomas Thrainer
    oob_support = dict((node.uuid, False) for node in nodes)
475 1c3231aa Thomas Thrainer
    oob_support[master_node.uuid] = True
476 1c3231aa Thomas Thrainer
    oob_support[oob_not_powered_node.uuid] = True
477 52b5d286 René Nussbaumer
478 8235fe04 Michael Hanselmann
    master_node.group = ng_uuid
479 8235fe04 Michael Hanselmann
480 1c3231aa Thomas Thrainer
    nqd = query.NodeQueryData(nodes, live_data, master_node.uuid,
481 da4a52a3 Thomas Thrainer
                              node_to_primary_uuid, node_to_secondary_uuid,
482 da4a52a3 Thomas Thrainer
                              inst_uuid_to_inst_name, groups, oob_support,
483 da4a52a3 Thomas Thrainer
                              cluster)
484 8235fe04 Michael Hanselmann
    result = q.Query(nqd)
485 8235fe04 Michael Hanselmann
    self.assert_(compat.all(len(row) == len(selected) for row in result))
486 8235fe04 Michael Hanselmann
    self.assertEqual([row[field_index["name"]] for row in result],
487 cfb084ae René Nussbaumer
                     [(constants.RS_NORMAL, name) for name in node_names])
488 8235fe04 Michael Hanselmann
489 8235fe04 Michael Hanselmann
    node_to_row = dict((row[field_index["name"]][1], idx)
490 8235fe04 Michael Hanselmann
                       for idx, row in enumerate(result))
491 8235fe04 Michael Hanselmann
492 8235fe04 Michael Hanselmann
    master_row = result[node_to_row[master_name]]
493 8235fe04 Michael Hanselmann
    self.assert_(master_row[field_index["master"]])
494 8235fe04 Michael Hanselmann
    self.assert_(master_row[field_index["role"]], "M")
495 8235fe04 Michael Hanselmann
    self.assertEqual(master_row[field_index["group"]],
496 cfb084ae René Nussbaumer
                     (constants.RS_NORMAL, "ng1"))
497 8235fe04 Michael Hanselmann
    self.assertEqual(master_row[field_index["group.uuid"]],
498 cfb084ae René Nussbaumer
                     (constants.RS_NORMAL, ng_uuid))
499 145bea54 Michael Hanselmann
    self.assertEqual(master_row[field_index["ctime"]],
500 cfb084ae René Nussbaumer
                     (constants.RS_UNAVAIL, None))
501 145bea54 Michael Hanselmann
    self.assertEqual(master_row[field_index["mtime"]],
502 cfb084ae René Nussbaumer
                     (constants.RS_UNAVAIL, None))
503 8235fe04 Michael Hanselmann
504 8235fe04 Michael Hanselmann
    self.assert_(row[field_index["pip"]] == node.primary_ip and
505 8235fe04 Michael Hanselmann
                 row[field_index["sip"]] == node.secondary_ip and
506 8235fe04 Michael Hanselmann
                 set(row[field_index["tags"]]) == node.GetTags() and
507 8235fe04 Michael Hanselmann
                 row[field_index["serial_no"]] == node.serial_no and
508 8235fe04 Michael Hanselmann
                 row[field_index["role"]] == query._GetNodeRole(node,
509 8235fe04 Michael Hanselmann
                                                                master_name) and
510 8235fe04 Michael Hanselmann
                 (node.name == master_name or
511 8235fe04 Michael Hanselmann
                  (row[field_index["group"]] == "<unknown>" and
512 145bea54 Michael Hanselmann
                   row[field_index["group.uuid"]] is None and
513 cfb084ae René Nussbaumer
                   row[field_index["ctime"]] == (constants.RS_NORMAL,
514 145bea54 Michael Hanselmann
                                                 node.ctime) and
515 cfb084ae René Nussbaumer
                   row[field_index["mtime"]] == (constants.RS_NORMAL,
516 b12d5e2e René Nussbaumer
                                                 node.mtime) and
517 b12d5e2e René Nussbaumer
                   row[field_index["powered"]] == (constants.RS_NORMAL,
518 b12d5e2e René Nussbaumer
                                                   True))) or
519 b12d5e2e René Nussbaumer
                 (node.name == oob_not_powered_node and
520 b12d5e2e René Nussbaumer
                  row[field_index["powered"]] == (constants.RS_NORMAL,
521 b12d5e2e René Nussbaumer
                                                  False)) or
522 b12d5e2e René Nussbaumer
                 row[field_index["powered"]] == (constants.RS_UNAVAIL, None)
523 8235fe04 Michael Hanselmann
                 for row, node in zip(result, nodes))
524 8235fe04 Michael Hanselmann
525 1c3231aa Thomas Thrainer
    live_data_row = result[node_to_row[live_data_node.name]]
526 8235fe04 Michael Hanselmann
527 8235fe04 Michael Hanselmann
    for (field, value) in fake_live_data.items():
528 8235fe04 Michael Hanselmann
      self.assertEqual(live_data_row[field_index[field]],
529 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, value))
530 8235fe04 Michael Hanselmann
531 8235fe04 Michael Hanselmann
    self.assertEqual(master_row[field_index["pinst_cnt"]],
532 cfb084ae René Nussbaumer
                     (constants.RS_NORMAL, 2))
533 8235fe04 Michael Hanselmann
    self.assertEqual(live_data_row[field_index["sinst_cnt"]],
534 cfb084ae René Nussbaumer
                     (constants.RS_NORMAL, 3))
535 8235fe04 Michael Hanselmann
    self.assertEqual(master_row[field_index["pinst_list"]],
536 cfb084ae René Nussbaumer
                     (constants.RS_NORMAL,
537 da4a52a3 Thomas Thrainer
                      [inst_uuid_to_inst_name[uuid] for uuid in
538 da4a52a3 Thomas Thrainer
                       node_to_primary_uuid[master_node.uuid]]))
539 8235fe04 Michael Hanselmann
    self.assertEqual(live_data_row[field_index["sinst_list"]],
540 cfb084ae René Nussbaumer
                     (constants.RS_NORMAL,
541 da4a52a3 Thomas Thrainer
                      utils.NiceSort(
542 da4a52a3 Thomas Thrainer
                        [inst_uuid_to_inst_name[uuid] for uuid in
543 da4a52a3 Thomas Thrainer
                        node_to_secondary_uuid[live_data_node.uuid]])))
544 8235fe04 Michael Hanselmann
545 8235fe04 Michael Hanselmann
  def testGetLiveNodeField(self):
546 8235fe04 Michael Hanselmann
    nodes = [
547 effab4ca Iustin Pop
      objects.Node(name="node1", drained=False, offline=False,
548 effab4ca Iustin Pop
                   vm_capable=True),
549 effab4ca Iustin Pop
      objects.Node(name="node2", drained=True, offline=False,
550 effab4ca Iustin Pop
                   vm_capable=True),
551 effab4ca Iustin Pop
      objects.Node(name="node3", drained=False, offline=False,
552 effab4ca Iustin Pop
                   vm_capable=True),
553 effab4ca Iustin Pop
      objects.Node(name="node4", drained=False, offline=True,
554 effab4ca Iustin Pop
                   vm_capable=True),
555 effab4ca Iustin Pop
      objects.Node(name="node5", drained=False, offline=False,
556 effab4ca Iustin Pop
                   vm_capable=False),
557 8235fe04 Michael Hanselmann
      ]
558 8235fe04 Michael Hanselmann
    live_data = dict.fromkeys([node.name for node in nodes], {})
559 8235fe04 Michael Hanselmann
560 8235fe04 Michael Hanselmann
    # No data
561 da4a52a3 Thomas Thrainer
    nqd = query.NodeQueryData(None, None, None, None, None, None, None, None,
562 da4a52a3 Thomas Thrainer
                              None)
563 8235fe04 Michael Hanselmann
    self.assertEqual(query._GetLiveNodeField("hello", constants.QFT_NUMBER,
564 a6070ef7 Michael Hanselmann
                                             nqd, nodes[0]),
565 e2d188cc Iustin Pop
                     query._FS_NODATA)
566 8235fe04 Michael Hanselmann
567 8235fe04 Michael Hanselmann
    # Missing field
568 8235fe04 Michael Hanselmann
    ctx = _QueryData(None, curlive_data={
569 8235fe04 Michael Hanselmann
      "some": 1,
570 8235fe04 Michael Hanselmann
      "other": 2,
571 8235fe04 Michael Hanselmann
      })
572 8235fe04 Michael Hanselmann
    self.assertEqual(query._GetLiveNodeField("hello", constants.QFT_NUMBER,
573 a6070ef7 Michael Hanselmann
                                             ctx, nodes[0]),
574 e2d188cc Iustin Pop
                     query._FS_UNAVAIL)
575 8235fe04 Michael Hanselmann
576 8235fe04 Michael Hanselmann
    # Wrong format/datatype
577 8235fe04 Michael Hanselmann
    ctx = _QueryData(None, curlive_data={
578 8235fe04 Michael Hanselmann
      "hello": ["Hello World"],
579 8235fe04 Michael Hanselmann
      "other": 2,
580 8235fe04 Michael Hanselmann
      })
581 8235fe04 Michael Hanselmann
    self.assertEqual(query._GetLiveNodeField("hello", constants.QFT_NUMBER,
582 a6070ef7 Michael Hanselmann
                                             ctx, nodes[0]),
583 e2d188cc Iustin Pop
                     query._FS_UNAVAIL)
584 8235fe04 Michael Hanselmann
585 a6070ef7 Michael Hanselmann
    # Offline node
586 a6070ef7 Michael Hanselmann
    assert nodes[3].offline
587 a6070ef7 Michael Hanselmann
    ctx = _QueryData(None, curlive_data={})
588 a6070ef7 Michael Hanselmann
    self.assertEqual(query._GetLiveNodeField("hello", constants.QFT_NUMBER,
589 a6070ef7 Michael Hanselmann
                                             ctx, nodes[3]),
590 e2d188cc Iustin Pop
                     query._FS_OFFLINE, None)
591 a6070ef7 Michael Hanselmann
592 8235fe04 Michael Hanselmann
    # Wrong field type
593 8235fe04 Michael Hanselmann
    ctx = _QueryData(None, curlive_data={"hello": 123})
594 8235fe04 Michael Hanselmann
    self.assertRaises(AssertionError, query._GetLiveNodeField,
595 a6070ef7 Michael Hanselmann
                      "hello", constants.QFT_BOOL, ctx, nodes[0])
596 8235fe04 Michael Hanselmann
597 effab4ca Iustin Pop
    # Non-vm_capable node
598 effab4ca Iustin Pop
    assert not nodes[4].vm_capable
599 effab4ca Iustin Pop
    ctx = _QueryData(None, curlive_data={})
600 effab4ca Iustin Pop
    self.assertEqual(query._GetLiveNodeField("hello", constants.QFT_NUMBER,
601 effab4ca Iustin Pop
                                             ctx, nodes[4]),
602 effab4ca Iustin Pop
                     query._FS_UNAVAIL, None)
603 effab4ca Iustin Pop
604 8235fe04 Michael Hanselmann
605 1c8addc6 Michael Hanselmann
class TestInstanceQuery(unittest.TestCase):
606 1c8addc6 Michael Hanselmann
  def _Create(self, selected):
607 1c8addc6 Michael Hanselmann
    return query.Query(query.INSTANCE_FIELDS, selected)
608 1c8addc6 Michael Hanselmann
609 1c8addc6 Michael Hanselmann
  def testSimple(self):
610 861610e9 Guido Trotter
    q = self._Create(["name", "be/maxmem", "ip"])
611 1c8addc6 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([query.IQ_CONFIG]))
612 1c8addc6 Michael Hanselmann
613 1c8addc6 Michael Hanselmann
    cluster = objects.Cluster(cluster_name="testcluster",
614 1c8addc6 Michael Hanselmann
      hvparams=constants.HVC_DEFAULTS,
615 1c8addc6 Michael Hanselmann
      beparams={
616 1c8addc6 Michael Hanselmann
        constants.PP_DEFAULT: constants.BEC_DEFAULTS,
617 1c8addc6 Michael Hanselmann
        },
618 1c8addc6 Michael Hanselmann
      nicparams={
619 1c8addc6 Michael Hanselmann
        constants.PP_DEFAULT: constants.NICC_DEFAULTS,
620 7c670076 Michael Hanselmann
        },
621 7c670076 Michael Hanselmann
      os_hvp={},
622 7c670076 Michael Hanselmann
      osparams={})
623 1c8addc6 Michael Hanselmann
624 1c8addc6 Michael Hanselmann
    instances = [
625 7c670076 Michael Hanselmann
      objects.Instance(name="inst1", hvparams={}, beparams={}, osparams={},
626 7c670076 Michael Hanselmann
                       nics=[], os="deb1"),
627 7c670076 Michael Hanselmann
      objects.Instance(name="inst2", hvparams={}, nics=[], osparams={},
628 7c670076 Michael Hanselmann
        os="foomoo",
629 1c8addc6 Michael Hanselmann
        beparams={
630 861610e9 Guido Trotter
          constants.BE_MAXMEM: 512,
631 1c8addc6 Michael Hanselmann
        }),
632 7c670076 Michael Hanselmann
      objects.Instance(name="inst3", hvparams={}, beparams={}, osparams={},
633 7c670076 Michael Hanselmann
        os="dos", nics=[objects.NIC(ip="192.0.2.99", nicparams={})]),
634 1c8addc6 Michael Hanselmann
      ]
635 1c8addc6 Michael Hanselmann
636 5d28cb6f Michael Hanselmann
    iqd = query.InstanceQueryData(instances, cluster, None, [], [], {},
637 1635eec0 Dimitris Aragiorgis
                                  set(), {}, None, None, None)
638 1c8addc6 Michael Hanselmann
    self.assertEqual(q.Query(iqd),
639 cfb084ae René Nussbaumer
      [[(constants.RS_NORMAL, "inst1"),
640 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, 128),
641 cfb084ae René Nussbaumer
        (constants.RS_UNAVAIL, None),
642 1c8addc6 Michael Hanselmann
       ],
643 cfb084ae René Nussbaumer
       [(constants.RS_NORMAL, "inst2"),
644 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, 512),
645 cfb084ae René Nussbaumer
        (constants.RS_UNAVAIL, None),
646 1c8addc6 Michael Hanselmann
       ],
647 cfb084ae René Nussbaumer
       [(constants.RS_NORMAL, "inst3"),
648 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, 128),
649 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, "192.0.2.99"),
650 1c8addc6 Michael Hanselmann
       ]])
651 1c8addc6 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(iqd),
652 1c8addc6 Michael Hanselmann
      [["inst1", 128, None],
653 1c8addc6 Michael Hanselmann
       ["inst2", 512, None],
654 1c8addc6 Michael Hanselmann
       ["inst3", 128, "192.0.2.99"]])
655 1c8addc6 Michael Hanselmann
656 1c8addc6 Michael Hanselmann
  def test(self):
657 1c8addc6 Michael Hanselmann
    selected = query.INSTANCE_FIELDS.keys()
658 1c8addc6 Michael Hanselmann
    fieldidx = dict((field, idx) for idx, field in enumerate(selected))
659 1c8addc6 Michael Hanselmann
660 1c8addc6 Michael Hanselmann
    macs = ["00:11:22:%02x:%02x:%02x" % (i % 255, i % 3, (i * 123) % 255)
661 1c8addc6 Michael Hanselmann
            for i in range(20)]
662 1c8addc6 Michael Hanselmann
663 1c8addc6 Michael Hanselmann
    q = self._Create(selected)
664 1c8addc6 Michael Hanselmann
    self.assertEqual(q.RequestedData(),
665 5d28cb6f Michael Hanselmann
                     set([query.IQ_CONFIG, query.IQ_LIVE, query.IQ_DISKUSAGE,
666 1635eec0 Dimitris Aragiorgis
                          query.IQ_CONSOLE, query.IQ_NODES, query.IQ_NETWORKS]))
667 1c8addc6 Michael Hanselmann
668 1c8addc6 Michael Hanselmann
    cluster = objects.Cluster(cluster_name="testcluster",
669 1c8addc6 Michael Hanselmann
      hvparams=constants.HVC_DEFAULTS,
670 1c8addc6 Michael Hanselmann
      beparams={
671 1c8addc6 Michael Hanselmann
        constants.PP_DEFAULT: constants.BEC_DEFAULTS,
672 1c8addc6 Michael Hanselmann
        },
673 1c8addc6 Michael Hanselmann
      nicparams={
674 1c8addc6 Michael Hanselmann
        constants.PP_DEFAULT: constants.NICC_DEFAULTS,
675 1c8addc6 Michael Hanselmann
        },
676 1c8addc6 Michael Hanselmann
      os_hvp={},
677 7c670076 Michael Hanselmann
      tcpudp_port_pool=set(),
678 7c670076 Michael Hanselmann
      osparams={
679 7c670076 Michael Hanselmann
        "deb99": {
680 7c670076 Michael Hanselmann
          "clean_install": "yes",
681 7c670076 Michael Hanselmann
          },
682 7c670076 Michael Hanselmann
        })
683 1c8addc6 Michael Hanselmann
684 1c3231aa Thomas Thrainer
    offline_nodes = ["nodeoff1-uuid", "nodeoff2-uuid"]
685 1c3231aa Thomas Thrainer
    bad_nodes = ["nodebad1-uuid", "nodebad2-uuid", "nodebad3-uuid"] +\
686 1c3231aa Thomas Thrainer
                offline_nodes
687 1c3231aa Thomas Thrainer
    node_uuids = ["node%s-uuid" % i for i in range(10)] + bad_nodes
688 1c8addc6 Michael Hanselmann
689 1c8addc6 Michael Hanselmann
    instances = [
690 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst1", hvparams={}, beparams={}, nics=[],
691 da4a52a3 Thomas Thrainer
        uuid="inst1-uuid",
692 1c8addc6 Michael Hanselmann
        ctime=1291244000, mtime=1291244400, serial_no=30,
693 2e04d454 Agata Murawska
        admin_state=constants.ADMINST_UP, hypervisor=constants.HT_XEN_PVM,
694 2e04d454 Agata Murawska
        os="linux1",
695 1c3231aa Thomas Thrainer
        primary_node="node1-uuid",
696 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_PLAIN,
697 7c670076 Michael Hanselmann
        disks=[],
698 ca83454f Thomas Thrainer
        disks_active=True,
699 7c670076 Michael Hanselmann
        osparams={}),
700 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst2", hvparams={}, nics=[],
701 da4a52a3 Thomas Thrainer
        uuid="inst2-uuid",
702 1c8addc6 Michael Hanselmann
        ctime=1291211000, mtime=1291211077, serial_no=1,
703 2e04d454 Agata Murawska
        admin_state=constants.ADMINST_UP, hypervisor=constants.HT_XEN_HVM,
704 2e04d454 Agata Murawska
        os="deb99",
705 1c3231aa Thomas Thrainer
        primary_node="node5-uuid",
706 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DISKLESS,
707 1c8addc6 Michael Hanselmann
        disks=[],
708 ca83454f Thomas Thrainer
        disks_active=True,
709 1c8addc6 Michael Hanselmann
        beparams={
710 861610e9 Guido Trotter
          constants.BE_MAXMEM: 512,
711 861610e9 Guido Trotter
          constants.BE_MINMEM: 256,
712 7c670076 Michael Hanselmann
        },
713 7c670076 Michael Hanselmann
        osparams={}),
714 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst3", hvparams={}, beparams={},
715 da4a52a3 Thomas Thrainer
        uuid="inst3-uuid",
716 1c8addc6 Michael Hanselmann
        ctime=1291011000, mtime=1291013000, serial_no=1923,
717 2e04d454 Agata Murawska
        admin_state=constants.ADMINST_DOWN, hypervisor=constants.HT_KVM,
718 2e04d454 Agata Murawska
        os="busybox",
719 1c3231aa Thomas Thrainer
        primary_node="node6-uuid",
720 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DRBD8,
721 1c8addc6 Michael Hanselmann
        disks=[],
722 ca83454f Thomas Thrainer
        disks_active=False,
723 1c8addc6 Michael Hanselmann
        nics=[
724 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.99", mac=macs.pop(),
725 1c8addc6 Michael Hanselmann
                      nicparams={
726 1c8addc6 Michael Hanselmann
                        constants.NIC_LINK: constants.DEFAULT_BRIDGE,
727 1c8addc6 Michael Hanselmann
                        }),
728 1c8addc6 Michael Hanselmann
          objects.NIC(ip=None, mac=macs.pop(), nicparams={}),
729 7c670076 Michael Hanselmann
          ],
730 7c670076 Michael Hanselmann
        osparams={}),
731 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst4", hvparams={}, beparams={},
732 da4a52a3 Thomas Thrainer
        uuid="inst4-uuid",
733 1c8addc6 Michael Hanselmann
        ctime=1291244390, mtime=1291244395, serial_no=25,
734 2e04d454 Agata Murawska
        admin_state=constants.ADMINST_DOWN, hypervisor=constants.HT_XEN_PVM,
735 2e04d454 Agata Murawska
        os="linux1",
736 1c3231aa Thomas Thrainer
        primary_node="nodeoff2-uuid",
737 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DRBD8,
738 1c8addc6 Michael Hanselmann
        disks=[],
739 ca83454f Thomas Thrainer
        disks_active=True,
740 1c8addc6 Michael Hanselmann
        nics=[
741 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.1", mac=macs.pop(),
742 1c8addc6 Michael Hanselmann
                      nicparams={
743 1c8addc6 Michael Hanselmann
                        constants.NIC_LINK: constants.DEFAULT_BRIDGE,
744 1c8addc6 Michael Hanselmann
                        }),
745 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.2", mac=macs.pop(), nicparams={}),
746 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.3", mac=macs.pop(),
747 1c8addc6 Michael Hanselmann
                      nicparams={
748 1c8addc6 Michael Hanselmann
                        constants.NIC_MODE: constants.NIC_MODE_ROUTED,
749 1c8addc6 Michael Hanselmann
                        }),
750 1c8addc6 Michael Hanselmann
          objects.NIC(ip="192.0.2.4", mac=macs.pop(),
751 1c8addc6 Michael Hanselmann
                      nicparams={
752 1c8addc6 Michael Hanselmann
                        constants.NIC_MODE: constants.NIC_MODE_BRIDGED,
753 1c8addc6 Michael Hanselmann
                        constants.NIC_LINK: "eth123",
754 1c8addc6 Michael Hanselmann
                        }),
755 7c670076 Michael Hanselmann
          ],
756 7c670076 Michael Hanselmann
        osparams={}),
757 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst5", hvparams={}, nics=[],
758 da4a52a3 Thomas Thrainer
        uuid="inst5-uuid",
759 1c8addc6 Michael Hanselmann
        ctime=1231211000, mtime=1261200000, serial_no=3,
760 2e04d454 Agata Murawska
        admin_state=constants.ADMINST_UP, hypervisor=constants.HT_XEN_HVM,
761 2e04d454 Agata Murawska
        os="deb99",
762 1c3231aa Thomas Thrainer
        primary_node="nodebad2-uuid",
763 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DISKLESS,
764 1c8addc6 Michael Hanselmann
        disks=[],
765 ca83454f Thomas Thrainer
        disks_active=True,
766 1c8addc6 Michael Hanselmann
        beparams={
767 861610e9 Guido Trotter
          constants.BE_MAXMEM: 512,
768 861610e9 Guido Trotter
          constants.BE_MINMEM: 512,
769 7c670076 Michael Hanselmann
        },
770 7c670076 Michael Hanselmann
        osparams={}),
771 1c8addc6 Michael Hanselmann
      objects.Instance(name="inst6", hvparams={}, nics=[],
772 da4a52a3 Thomas Thrainer
        uuid="inst6-uuid",
773 1c8addc6 Michael Hanselmann
        ctime=7513, mtime=11501, serial_no=13390,
774 2e04d454 Agata Murawska
        admin_state=constants.ADMINST_DOWN, hypervisor=constants.HT_XEN_HVM,
775 2e04d454 Agata Murawska
        os="deb99",
776 1c3231aa Thomas Thrainer
        primary_node="node7-uuid",
777 1c8addc6 Michael Hanselmann
        disk_template=constants.DT_DISKLESS,
778 1c8addc6 Michael Hanselmann
        disks=[],
779 ca83454f Thomas Thrainer
        disks_active=False,
780 1c8addc6 Michael Hanselmann
        beparams={
781 861610e9 Guido Trotter
          constants.BE_MAXMEM: 768,
782 861610e9 Guido Trotter
          constants.BE_MINMEM: 256,
783 7c670076 Michael Hanselmann
        },
784 7c670076 Michael Hanselmann
        osparams={
785 7c670076 Michael Hanselmann
          "clean_install": "no",
786 7c670076 Michael Hanselmann
          }),
787 145bea54 Michael Hanselmann
      objects.Instance(name="inst7", hvparams={}, nics=[],
788 da4a52a3 Thomas Thrainer
        uuid="inst7-uuid",
789 145bea54 Michael Hanselmann
        ctime=None, mtime=None, serial_no=1947,
790 2e04d454 Agata Murawska
        admin_state=constants.ADMINST_DOWN, hypervisor=constants.HT_XEN_HVM,
791 2e04d454 Agata Murawska
        os="deb99",
792 1c3231aa Thomas Thrainer
        primary_node="node6-uuid",
793 2e04d454 Agata Murawska
        disk_template=constants.DT_DISKLESS,
794 2e04d454 Agata Murawska
        disks=[],
795 ca83454f Thomas Thrainer
        disks_active=False,
796 2e04d454 Agata Murawska
        beparams={},
797 2e04d454 Agata Murawska
        osparams={}),
798 2e04d454 Agata Murawska
      objects.Instance(name="inst8", hvparams={}, nics=[],
799 da4a52a3 Thomas Thrainer
        uuid="inst8-uuid",
800 2e04d454 Agata Murawska
        ctime=None, mtime=None, serial_no=19478,
801 2e04d454 Agata Murawska
        admin_state=constants.ADMINST_OFFLINE, hypervisor=constants.HT_XEN_HVM,
802 2e04d454 Agata Murawska
        os="deb99",
803 1c3231aa Thomas Thrainer
        primary_node="node6-uuid",
804 145bea54 Michael Hanselmann
        disk_template=constants.DT_DISKLESS,
805 145bea54 Michael Hanselmann
        disks=[],
806 ca83454f Thomas Thrainer
        disks_active=False,
807 7c670076 Michael Hanselmann
        beparams={},
808 7c670076 Michael Hanselmann
        osparams={}),
809 1c8addc6 Michael Hanselmann
      ]
810 1c8addc6 Michael Hanselmann
811 da4a52a3 Thomas Thrainer
    assert not utils.FindDuplicates(inst.uuid for inst in instances)
812 145bea54 Michael Hanselmann
    assert not utils.FindDuplicates(inst.name for inst in instances)
813 145bea54 Michael Hanselmann
814 5d28cb6f Michael Hanselmann
    instbyname = dict((inst.name, inst) for inst in instances)
815 5d28cb6f Michael Hanselmann
816 da4a52a3 Thomas Thrainer
    disk_usage = dict((inst.uuid,
817 0c77c331 René Nussbaumer
                       gmi.ComputeDiskSize(inst.disk_template,
818 0c77c331 René Nussbaumer
                                           [{"size": disk.size}
819 0c77c331 René Nussbaumer
                                           for disk in inst.disks]))
820 1c8addc6 Michael Hanselmann
                      for inst in instances)
821 1c8addc6 Michael Hanselmann
822 1c8addc6 Michael Hanselmann
    inst_bridges = {
823 da4a52a3 Thomas Thrainer
      "inst3-uuid": [constants.DEFAULT_BRIDGE, constants.DEFAULT_BRIDGE],
824 da4a52a3 Thomas Thrainer
      "inst4-uuid": [constants.DEFAULT_BRIDGE, constants.DEFAULT_BRIDGE,
825 da4a52a3 Thomas Thrainer
                     None, "eth123"],
826 1c8addc6 Michael Hanselmann
      }
827 1c8addc6 Michael Hanselmann
828 1c8addc6 Michael Hanselmann
    live_data = {
829 da4a52a3 Thomas Thrainer
      "inst2-uuid": {
830 1c8addc6 Michael Hanselmann
        "vcpus": 3,
831 1c8addc6 Michael Hanselmann
        },
832 da4a52a3 Thomas Thrainer
      "inst4-uuid": {
833 1c8addc6 Michael Hanselmann
        "memory": 123,
834 1c8addc6 Michael Hanselmann
        },
835 da4a52a3 Thomas Thrainer
      "inst6-uuid": {
836 1c8addc6 Michael Hanselmann
        "memory": 768,
837 1c8addc6 Michael Hanselmann
        },
838 da4a52a3 Thomas Thrainer
      "inst7-uuid": {
839 bacae536 René Nussbaumer
        "vcpus": 3,
840 bacae536 René Nussbaumer
        },
841 1c8addc6 Michael Hanselmann
      }
842 da4a52a3 Thomas Thrainer
    wrongnode_inst = set(["inst7-uuid"])
843 1c8addc6 Michael Hanselmann
844 da4a52a3 Thomas Thrainer
    consinfo = dict((inst.uuid, None) for inst in instances)
845 da4a52a3 Thomas Thrainer
    consinfo["inst7-uuid"] = \
846 5d28cb6f Michael Hanselmann
      objects.InstanceConsole(instance="inst7", kind=constants.CONS_SSH,
847 5d28cb6f Michael Hanselmann
                              host=instbyname["inst7"].primary_node,
848 052783ff Michael Hanselmann
                              user="root",
849 5d28cb6f Michael Hanselmann
                              command=["hostname"]).ToDict()
850 5d28cb6f Michael Hanselmann
851 1c3231aa Thomas Thrainer
    nodes = dict([(uuid, objects.Node(
852 1c3231aa Thomas Thrainer
                           name="%s.example.com" % uuid,
853 1c3231aa Thomas Thrainer
                           uuid=uuid,
854 1c3231aa Thomas Thrainer
                           group="default-uuid"))
855 1c3231aa Thomas Thrainer
                  for uuid in node_uuids])
856 1c3231aa Thomas Thrainer
857 1c8addc6 Michael Hanselmann
    iqd = query.InstanceQueryData(instances, cluster, disk_usage,
858 e431074f René Nussbaumer
                                  offline_nodes, bad_nodes, live_data,
859 1c3231aa Thomas Thrainer
                                  wrongnode_inst, consinfo, nodes, {}, {})
860 1c8addc6 Michael Hanselmann
    result = q.Query(iqd)
861 1c8addc6 Michael Hanselmann
    self.assertEqual(len(result), len(instances))
862 1c8addc6 Michael Hanselmann
    self.assert_(compat.all(len(row) == len(selected)
863 1c8addc6 Michael Hanselmann
                            for row in result))
864 1c8addc6 Michael Hanselmann
865 1c8addc6 Michael Hanselmann
    assert len(set(bad_nodes) & set(offline_nodes)) == len(offline_nodes), \
866 1c8addc6 Michael Hanselmann
           "Offline nodes not included in bad nodes"
867 1c8addc6 Michael Hanselmann
868 1c8addc6 Michael Hanselmann
    tested_status = set()
869 1c8addc6 Michael Hanselmann
870 1c8addc6 Michael Hanselmann
    for (inst, row) in zip(instances, result):
871 1c3231aa Thomas Thrainer
      assert inst.primary_node in node_uuids
872 1c8addc6 Michael Hanselmann
873 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["name"]],
874 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, inst.name))
875 1c8addc6 Michael Hanselmann
876 1c8addc6 Michael Hanselmann
      if inst.primary_node in offline_nodes:
877 61a980a9 Michael Hanselmann
        exp_status = constants.INSTST_NODEOFFLINE
878 1c8addc6 Michael Hanselmann
      elif inst.primary_node in bad_nodes:
879 61a980a9 Michael Hanselmann
        exp_status = constants.INSTST_NODEDOWN
880 da4a52a3 Thomas Thrainer
      elif inst.uuid in live_data:
881 da4a52a3 Thomas Thrainer
        if inst.uuid in wrongnode_inst:
882 61a980a9 Michael Hanselmann
          exp_status = constants.INSTST_WRONGNODE
883 2e04d454 Agata Murawska
        elif inst.admin_state == constants.ADMINST_UP:
884 61a980a9 Michael Hanselmann
          exp_status = constants.INSTST_RUNNING
885 1c8addc6 Michael Hanselmann
        else:
886 61a980a9 Michael Hanselmann
          exp_status = constants.INSTST_ERRORUP
887 2e04d454 Agata Murawska
      elif inst.admin_state == constants.ADMINST_UP:
888 61a980a9 Michael Hanselmann
        exp_status = constants.INSTST_ERRORDOWN
889 2e04d454 Agata Murawska
      elif inst.admin_state == constants.ADMINST_DOWN:
890 61a980a9 Michael Hanselmann
        exp_status = constants.INSTST_ADMINDOWN
891 2e04d454 Agata Murawska
      else:
892 2e04d454 Agata Murawska
        exp_status = constants.INSTST_ADMINOFFLINE
893 1c8addc6 Michael Hanselmann
894 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["status"]],
895 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, exp_status))
896 1c8addc6 Michael Hanselmann
897 1c8addc6 Michael Hanselmann
      (_, status) = row[fieldidx["status"]]
898 1c8addc6 Michael Hanselmann
      tested_status.add(status)
899 1c8addc6 Michael Hanselmann
900 861610e9 Guido Trotter
      #FIXME(dynmem): check oper_ram vs min/max mem
901 861610e9 Guido Trotter
      for (field, livefield) in [("oper_vcpus", "vcpus")]:
902 1c8addc6 Michael Hanselmann
        if inst.primary_node in bad_nodes:
903 cfb084ae René Nussbaumer
          exp = (constants.RS_NODATA, None)
904 da4a52a3 Thomas Thrainer
        elif inst.uuid in live_data:
905 da4a52a3 Thomas Thrainer
          value = live_data[inst.uuid].get(livefield, None)
906 1c8addc6 Michael Hanselmann
          if value is None:
907 cfb084ae René Nussbaumer
            exp = (constants.RS_UNAVAIL, None)
908 1c8addc6 Michael Hanselmann
          else:
909 cfb084ae René Nussbaumer
            exp = (constants.RS_NORMAL, value)
910 1c8addc6 Michael Hanselmann
        else:
911 cfb084ae René Nussbaumer
          exp = (constants.RS_UNAVAIL, None)
912 1c8addc6 Michael Hanselmann
913 1c8addc6 Michael Hanselmann
        self.assertEqual(row[fieldidx[field]], exp)
914 1c8addc6 Michael Hanselmann
915 da4a52a3 Thomas Thrainer
      bridges = inst_bridges.get(inst.uuid, [])
916 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["nic.bridges"]],
917 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, bridges))
918 1c8addc6 Michael Hanselmann
      if bridges:
919 1c8addc6 Michael Hanselmann
        self.assertEqual(row[fieldidx["bridge"]],
920 cfb084ae René Nussbaumer
                         (constants.RS_NORMAL, bridges[0]))
921 1c8addc6 Michael Hanselmann
      else:
922 1c8addc6 Michael Hanselmann
        self.assertEqual(row[fieldidx["bridge"]],
923 cfb084ae René Nussbaumer
                         (constants.RS_UNAVAIL, None))
924 1c8addc6 Michael Hanselmann
925 1c8addc6 Michael Hanselmann
      for i in range(constants.MAX_NICS):
926 1c8addc6 Michael Hanselmann
        if i < len(bridges) and bridges[i] is not None:
927 cfb084ae René Nussbaumer
          exp = (constants.RS_NORMAL, bridges[i])
928 1c8addc6 Michael Hanselmann
        else:
929 cfb084ae René Nussbaumer
          exp = (constants.RS_UNAVAIL, None)
930 1c8addc6 Michael Hanselmann
        self.assertEqual(row[fieldidx["nic.bridge/%s" % i]], exp)
931 1c8addc6 Michael Hanselmann
932 1c8addc6 Michael Hanselmann
      if inst.primary_node in bad_nodes:
933 cfb084ae René Nussbaumer
        exp = (constants.RS_NODATA, None)
934 1c8addc6 Michael Hanselmann
      else:
935 da4a52a3 Thomas Thrainer
        exp = (constants.RS_NORMAL, inst.uuid in live_data)
936 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["oper_state"]], exp)
937 1c8addc6 Michael Hanselmann
938 7c670076 Michael Hanselmann
      cust_exp = (constants.RS_NORMAL, {})
939 7c670076 Michael Hanselmann
      if inst.os == "deb99":
940 da4a52a3 Thomas Thrainer
        if inst.uuid == "inst6-uuid":
941 7c670076 Michael Hanselmann
          exp = (constants.RS_NORMAL, {"clean_install": "no"})
942 7c670076 Michael Hanselmann
          cust_exp = exp
943 7c670076 Michael Hanselmann
        else:
944 7c670076 Michael Hanselmann
          exp = (constants.RS_NORMAL, {"clean_install": "yes"})
945 7c670076 Michael Hanselmann
      else:
946 7c670076 Michael Hanselmann
        exp = (constants.RS_NORMAL, {})
947 7c670076 Michael Hanselmann
      self.assertEqual(row[fieldidx["osparams"]], exp)
948 7c670076 Michael Hanselmann
      self.assertEqual(row[fieldidx["custom_osparams"]], cust_exp)
949 7c670076 Michael Hanselmann
950 da4a52a3 Thomas Thrainer
      usage = disk_usage[inst.uuid]
951 1c8addc6 Michael Hanselmann
      if usage is None:
952 1c8addc6 Michael Hanselmann
        usage = 0
953 1c8addc6 Michael Hanselmann
      self.assertEqual(row[fieldidx["disk_usage"]],
954 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, usage))
955 1c8addc6 Michael Hanselmann
956 4cc4d1fa Michael Hanselmann
      for alias, target in [("sda_size", "disk.size/0"),
957 4cc4d1fa Michael Hanselmann
                            ("sdb_size", "disk.size/1"),
958 4cc4d1fa Michael Hanselmann
                            ("vcpus", "be/vcpus"),
959 4cc4d1fa Michael Hanselmann
                            ("ip", "nic.ip/0"),
960 4cc4d1fa Michael Hanselmann
                            ("mac", "nic.mac/0"),
961 4cc4d1fa Michael Hanselmann
                            ("bridge", "nic.bridge/0"),
962 4cc4d1fa Michael Hanselmann
                            ("nic_mode", "nic.mode/0"),
963 4cc4d1fa Michael Hanselmann
                            ("nic_link", "nic.link/0"),
964 4cc4d1fa Michael Hanselmann
                            ]:
965 4cc4d1fa Michael Hanselmann
        self.assertEqual(row[fieldidx[alias]], row[fieldidx[target]])
966 1c8addc6 Michael Hanselmann
967 145bea54 Michael Hanselmann
      for field in ["ctime", "mtime"]:
968 145bea54 Michael Hanselmann
        if getattr(inst, field) is None:
969 145bea54 Michael Hanselmann
          # No ctime/mtime
970 cfb084ae René Nussbaumer
          exp = (constants.RS_UNAVAIL, None)
971 145bea54 Michael Hanselmann
        else:
972 cfb084ae René Nussbaumer
          exp = (constants.RS_NORMAL, getattr(inst, field))
973 145bea54 Michael Hanselmann
        self.assertEqual(row[fieldidx[field]], exp)
974 145bea54 Michael Hanselmann
975 5d28cb6f Michael Hanselmann
      self._CheckInstanceConsole(inst, row[fieldidx["console"]])
976 5d28cb6f Michael Hanselmann
977 1c8addc6 Michael Hanselmann
    # Ensure all possible status' have been tested
978 61a980a9 Michael Hanselmann
    self.assertEqual(tested_status, constants.INSTST_ALL)
979 1c8addc6 Michael Hanselmann
980 5d28cb6f Michael Hanselmann
  def _CheckInstanceConsole(self, instance, (status, consdata)):
981 5d28cb6f Michael Hanselmann
    if instance.name == "inst7":
982 5d28cb6f Michael Hanselmann
      self.assertEqual(status, constants.RS_NORMAL)
983 5d28cb6f Michael Hanselmann
      console = objects.InstanceConsole.FromDict(consdata)
984 5d28cb6f Michael Hanselmann
      self.assertTrue(console.Validate())
985 5d28cb6f Michael Hanselmann
      self.assertEqual(console.host, instance.primary_node)
986 5d28cb6f Michael Hanselmann
    else:
987 5d28cb6f Michael Hanselmann
      self.assertEqual(status, constants.RS_UNAVAIL)
988 5d28cb6f Michael Hanselmann
989 1c8addc6 Michael Hanselmann
990 d8b7ff5f Adeodato Simo
class TestGroupQuery(unittest.TestCase):
991 d8b7ff5f Adeodato Simo
992 d8b7ff5f Adeodato Simo
  def setUp(self):
993 d3b51156 René Nussbaumer
    self.custom_diskparams = {
994 d3b51156 René Nussbaumer
      constants.DT_DRBD8: {
995 d3b51156 René Nussbaumer
        constants.DRBD_DEFAULT_METAVG: "foobar",
996 d3b51156 René Nussbaumer
      },
997 d3b51156 René Nussbaumer
    }
998 d3b51156 René Nussbaumer
999 d8b7ff5f Adeodato Simo
    self.groups = [
1000 d8b7ff5f Adeodato Simo
      objects.NodeGroup(name="default",
1001 d8b7ff5f Adeodato Simo
                        uuid="c0e89160-18e7-11e0-a46e-001d0904baeb",
1002 edd49f9b Agata Murawska
                        alloc_policy=constants.ALLOC_POLICY_PREFERRED,
1003 8930b0f0 Iustin Pop
                        ipolicy=objects.MakeEmptyIPolicy(),
1004 8930b0f0 Iustin Pop
                        ndparams={},
1005 2c758845 René Nussbaumer
                        diskparams={},
1006 8930b0f0 Iustin Pop
                        ),
1007 d8b7ff5f Adeodato Simo
      objects.NodeGroup(name="restricted",
1008 d8b7ff5f Adeodato Simo
                        uuid="d2a40a74-18e7-11e0-9143-001d0904baeb",
1009 edd49f9b Agata Murawska
                        alloc_policy=constants.ALLOC_POLICY_LAST_RESORT,
1010 8930b0f0 Iustin Pop
                        ipolicy=objects.MakeEmptyIPolicy(),
1011 2c758845 René Nussbaumer
                        ndparams={},
1012 d3b51156 René Nussbaumer
                        diskparams=self.custom_diskparams,
1013 8930b0f0 Iustin Pop
                        ),
1014 d8b7ff5f Adeodato Simo
      ]
1015 edd49f9b Agata Murawska
    self.cluster = objects.Cluster(cluster_name="testcluster",
1016 edd49f9b Agata Murawska
      hvparams=constants.HVC_DEFAULTS,
1017 edd49f9b Agata Murawska
      beparams={
1018 edd49f9b Agata Murawska
        constants.PP_DEFAULT: constants.BEC_DEFAULTS,
1019 edd49f9b Agata Murawska
        },
1020 edd49f9b Agata Murawska
      nicparams={
1021 edd49f9b Agata Murawska
        constants.PP_DEFAULT: constants.NICC_DEFAULTS,
1022 edd49f9b Agata Murawska
        },
1023 edd49f9b Agata Murawska
      ndparams=constants.NDC_DEFAULTS,
1024 edd49f9b Agata Murawska
      ipolicy=constants.IPOLICY_DEFAULTS,
1025 2c758845 René Nussbaumer
      diskparams=constants.DISK_DT_DEFAULTS,
1026 edd49f9b Agata Murawska
      )
1027 d8b7ff5f Adeodato Simo
1028 d8b7ff5f Adeodato Simo
  def _Create(self, selected):
1029 d8b7ff5f Adeodato Simo
    return query.Query(query.GROUP_FIELDS, selected)
1030 d8b7ff5f Adeodato Simo
1031 d8b7ff5f Adeodato Simo
  def testSimple(self):
1032 d8b7ff5f Adeodato Simo
    q = self._Create(["name", "uuid", "alloc_policy"])
1033 2c758845 René Nussbaumer
    gqd = query.GroupQueryData(self.cluster, self.groups, None, None, False)
1034 d8b7ff5f Adeodato Simo
1035 d8b7ff5f Adeodato Simo
    self.assertEqual(q.RequestedData(), set([query.GQ_CONFIG]))
1036 d8b7ff5f Adeodato Simo
1037 d8b7ff5f Adeodato Simo
    self.assertEqual(q.Query(gqd),
1038 cfb084ae René Nussbaumer
      [[(constants.RS_NORMAL, "default"),
1039 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, "c0e89160-18e7-11e0-a46e-001d0904baeb"),
1040 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, constants.ALLOC_POLICY_PREFERRED)
1041 d8b7ff5f Adeodato Simo
        ],
1042 cfb084ae René Nussbaumer
       [(constants.RS_NORMAL, "restricted"),
1043 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, "d2a40a74-18e7-11e0-9143-001d0904baeb"),
1044 cfb084ae René Nussbaumer
        (constants.RS_NORMAL, constants.ALLOC_POLICY_LAST_RESORT)
1045 d8b7ff5f Adeodato Simo
        ],
1046 d8b7ff5f Adeodato Simo
       ])
1047 d8b7ff5f Adeodato Simo
1048 d8b7ff5f Adeodato Simo
  def testNodes(self):
1049 d8b7ff5f Adeodato Simo
    groups_to_nodes = {
1050 d8b7ff5f Adeodato Simo
      "c0e89160-18e7-11e0-a46e-001d0904baeb": ["node1", "node2"],
1051 d8b7ff5f Adeodato Simo
      "d2a40a74-18e7-11e0-9143-001d0904baeb": ["node1", "node10", "node9"],
1052 d8b7ff5f Adeodato Simo
      }
1053 d8b7ff5f Adeodato Simo
1054 d8b7ff5f Adeodato Simo
    q = self._Create(["name", "node_cnt", "node_list"])
1055 2c758845 René Nussbaumer
    gqd = query.GroupQueryData(self.cluster, self.groups, groups_to_nodes, None,
1056 2c758845 René Nussbaumer
                               False)
1057 d8b7ff5f Adeodato Simo
1058 d8b7ff5f Adeodato Simo
    self.assertEqual(q.RequestedData(), set([query.GQ_CONFIG, query.GQ_NODE]))
1059 d8b7ff5f Adeodato Simo
1060 d8b7ff5f Adeodato Simo
    self.assertEqual(q.Query(gqd),
1061 cfb084ae René Nussbaumer
                     [[(constants.RS_NORMAL, "default"),
1062 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 2),
1063 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, ["node1", "node2"]),
1064 d8b7ff5f Adeodato Simo
                       ],
1065 cfb084ae René Nussbaumer
                      [(constants.RS_NORMAL, "restricted"),
1066 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, 3),
1067 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, ["node1", "node9", "node10"]),
1068 d8b7ff5f Adeodato Simo
                       ],
1069 d8b7ff5f Adeodato Simo
                      ])
1070 d8b7ff5f Adeodato Simo
1071 d8b7ff5f Adeodato Simo
  def testInstances(self):
1072 d8b7ff5f Adeodato Simo
    groups_to_instances = {
1073 d8b7ff5f Adeodato Simo
      "c0e89160-18e7-11e0-a46e-001d0904baeb": ["inst1", "inst2"],
1074 d8b7ff5f Adeodato Simo
      "d2a40a74-18e7-11e0-9143-001d0904baeb": ["inst1", "inst10", "inst9"],
1075 d8b7ff5f Adeodato Simo
      }
1076 d8b7ff5f Adeodato Simo
1077 d8b7ff5f Adeodato Simo
    q = self._Create(["pinst_cnt", "pinst_list"])
1078 edd49f9b Agata Murawska
    gqd = query.GroupQueryData(self.cluster, self.groups, None,
1079 2c758845 René Nussbaumer
      groups_to_instances, False)
1080 d8b7ff5f Adeodato Simo
1081 d8b7ff5f Adeodato Simo
    self.assertEqual(q.RequestedData(), set([query.GQ_INST]))
1082 d8b7ff5f Adeodato Simo
1083 d8b7ff5f Adeodato Simo
    self.assertEqual(q.Query(gqd),
1084 cfb084ae René Nussbaumer
                     [[(constants.RS_NORMAL, 2),
1085 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, ["inst1", "inst2"]),
1086 d8b7ff5f Adeodato Simo
                       ],
1087 cfb084ae René Nussbaumer
                      [(constants.RS_NORMAL, 3),
1088 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, ["inst1", "inst9", "inst10"]),
1089 d8b7ff5f Adeodato Simo
                       ],
1090 d8b7ff5f Adeodato Simo
                      ])
1091 d8b7ff5f Adeodato Simo
1092 d3b51156 René Nussbaumer
  def testDiskparams(self):
1093 d3b51156 René Nussbaumer
    q = self._Create(["name", "uuid", "diskparams", "custom_diskparams"])
1094 d3b51156 René Nussbaumer
    gqd = query.GroupQueryData(self.cluster, self.groups, None, None, True)
1095 d3b51156 René Nussbaumer
1096 d3b51156 René Nussbaumer
    self.assertEqual(q.RequestedData(),
1097 d3b51156 René Nussbaumer
                     set([query.GQ_CONFIG, query.GQ_DISKPARAMS]))
1098 d3b51156 René Nussbaumer
1099 d3b51156 René Nussbaumer
    self.assertEqual(q.Query(gqd),
1100 d3b51156 René Nussbaumer
      [[(constants.RS_NORMAL, "default"),
1101 d3b51156 René Nussbaumer
        (constants.RS_NORMAL, "c0e89160-18e7-11e0-a46e-001d0904baeb"),
1102 d3b51156 René Nussbaumer
        (constants.RS_NORMAL, constants.DISK_DT_DEFAULTS),
1103 d3b51156 René Nussbaumer
        (constants.RS_NORMAL, {}),
1104 d3b51156 René Nussbaumer
        ],
1105 d3b51156 René Nussbaumer
       [(constants.RS_NORMAL, "restricted"),
1106 d3b51156 René Nussbaumer
        (constants.RS_NORMAL, "d2a40a74-18e7-11e0-9143-001d0904baeb"),
1107 d3b51156 René Nussbaumer
        (constants.RS_NORMAL, objects.FillDiskParams(constants.DISK_DT_DEFAULTS,
1108 d3b51156 René Nussbaumer
                                                     self.custom_diskparams)),
1109 d3b51156 René Nussbaumer
        (constants.RS_NORMAL, self.custom_diskparams),
1110 d3b51156 René Nussbaumer
        ],
1111 d3b51156 René Nussbaumer
       ])
1112 d3b51156 René Nussbaumer
1113 d8b7ff5f Adeodato Simo
1114 be3a4b14 Michael Hanselmann
class TestOsQuery(unittest.TestCase):
1115 be3a4b14 Michael Hanselmann
  def _Create(self, selected):
1116 be3a4b14 Michael Hanselmann
    return query.Query(query.OS_FIELDS, selected)
1117 be3a4b14 Michael Hanselmann
1118 be3a4b14 Michael Hanselmann
  def test(self):
1119 be3a4b14 Michael Hanselmann
    variants = ["v00", "plain", "v3", "var0", "v33", "v20"]
1120 be3a4b14 Michael Hanselmann
    api_versions = [10, 0, 15, 5]
1121 be3a4b14 Michael Hanselmann
    parameters = ["zpar3", "apar9"]
1122 be3a4b14 Michael Hanselmann
1123 be3a4b14 Michael Hanselmann
    assert variants != sorted(variants) and variants != utils.NiceSort(variants)
1124 be3a4b14 Michael Hanselmann
    assert (api_versions != sorted(api_versions) and
1125 be3a4b14 Michael Hanselmann
            api_versions != utils.NiceSort(variants))
1126 be3a4b14 Michael Hanselmann
    assert (parameters != sorted(parameters) and
1127 be3a4b14 Michael Hanselmann
            parameters != utils.NiceSort(parameters))
1128 be3a4b14 Michael Hanselmann
1129 be3a4b14 Michael Hanselmann
    data = [
1130 be3a4b14 Michael Hanselmann
      query.OsInfo(name="debian", valid=False, hidden=False, blacklisted=False,
1131 be3a4b14 Michael Hanselmann
                   variants=set(), api_versions=set(), parameters=set(),
1132 be3a4b14 Michael Hanselmann
                   node_status={ "some": "status", }),
1133 be3a4b14 Michael Hanselmann
      query.OsInfo(name="dos", valid=True, hidden=False, blacklisted=True,
1134 be3a4b14 Michael Hanselmann
                   variants=set(variants),
1135 be3a4b14 Michael Hanselmann
                   api_versions=set(api_versions),
1136 be3a4b14 Michael Hanselmann
                   parameters=set(parameters),
1137 be3a4b14 Michael Hanselmann
                   node_status={ "some": "other", "status": None, }),
1138 be3a4b14 Michael Hanselmann
      ]
1139 be3a4b14 Michael Hanselmann
1140 be3a4b14 Michael Hanselmann
1141 be3a4b14 Michael Hanselmann
    q = self._Create(["name", "valid", "hidden", "blacklisted", "variants",
1142 be3a4b14 Michael Hanselmann
                      "api_versions", "parameters", "node_status"])
1143 be3a4b14 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([]))
1144 be3a4b14 Michael Hanselmann
    self.assertEqual(q.Query(data),
1145 be3a4b14 Michael Hanselmann
                     [[(constants.RS_NORMAL, "debian"),
1146 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, False),
1147 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, False),
1148 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, False),
1149 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, []),
1150 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, []),
1151 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, []),
1152 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, {"some": "status"})],
1153 be3a4b14 Michael Hanselmann
                      [(constants.RS_NORMAL, "dos"),
1154 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, True),
1155 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, False),
1156 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, True),
1157 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL,
1158 be3a4b14 Michael Hanselmann
                        ["plain", "v00", "v3", "v20", "v33", "var0"]),
1159 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, [0, 5, 10, 15]),
1160 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL, ["apar9", "zpar3"]),
1161 be3a4b14 Michael Hanselmann
                       (constants.RS_NORMAL,
1162 be3a4b14 Michael Hanselmann
                        { "some": "other", "status": None, })
1163 be3a4b14 Michael Hanselmann
                       ]])
1164 be3a4b14 Michael Hanselmann
1165 be3a4b14 Michael Hanselmann
1166 aa29e95f Michael Hanselmann
class TestQueryFields(unittest.TestCase):
1167 aa29e95f Michael Hanselmann
  def testAllFields(self):
1168 e571ee44 Adeodato Simo
    for fielddefs in query.ALL_FIELD_LISTS:
1169 aa29e95f Michael Hanselmann
      result = query.QueryFields(fielddefs, None)
1170 aa29e95f Michael Hanselmann
      self.assert_(isinstance(result, dict))
1171 aa29e95f Michael Hanselmann
      response = objects.QueryFieldsResponse.FromDict(result)
1172 aa29e95f Michael Hanselmann
      self.assertEqual([(fdef.name, fdef.title) for fdef in response.fields],
1173 aa29e95f Michael Hanselmann
        [(fdef2.name, fdef2.title)
1174 111bf531 Michael Hanselmann
         for (fdef2, _, _, _) in utils.NiceSort(fielddefs.values(),
1175 111bf531 Michael Hanselmann
                                                key=lambda x: x[0].name)])
1176 aa29e95f Michael Hanselmann
1177 aa29e95f Michael Hanselmann
  def testSomeFields(self):
1178 aa29e95f Michael Hanselmann
    rnd = random.Random(5357)
1179 aa29e95f Michael Hanselmann
1180 aa29e95f Michael Hanselmann
    for _ in range(10):
1181 e571ee44 Adeodato Simo
      for fielddefs in query.ALL_FIELD_LISTS:
1182 e571ee44 Adeodato Simo
        if len(fielddefs) > 20:
1183 e571ee44 Adeodato Simo
          sample_size = rnd.randint(5, 20)
1184 e571ee44 Adeodato Simo
        else:
1185 e571ee44 Adeodato Simo
          sample_size = rnd.randint(1, max(1, len(fielddefs) - 1))
1186 111bf531 Michael Hanselmann
        fields = [fdef for (fdef, _, _, _) in rnd.sample(fielddefs.values(),
1187 111bf531 Michael Hanselmann
                                                         sample_size)]
1188 aa29e95f Michael Hanselmann
        result = query.QueryFields(fielddefs, [fdef.name for fdef in fields])
1189 aa29e95f Michael Hanselmann
        self.assert_(isinstance(result, dict))
1190 aa29e95f Michael Hanselmann
        response = objects.QueryFieldsResponse.FromDict(result)
1191 aa29e95f Michael Hanselmann
        self.assertEqual([(fdef.name, fdef.title) for fdef in response.fields],
1192 aa29e95f Michael Hanselmann
                         [(fdef2.name, fdef2.title) for fdef2 in fields])
1193 aa29e95f Michael Hanselmann
1194 aa29e95f Michael Hanselmann
1195 fb0be379 Michael Hanselmann
class TestQueryFilter(unittest.TestCase):
1196 fb0be379 Michael Hanselmann
  def testRequestedNames(self):
1197 0fdf247d Michael Hanselmann
    for (what, fielddefs) in query.ALL_FIELDS.items():
1198 0fdf247d Michael Hanselmann
      if what == constants.QR_JOB:
1199 d6f58310 Michael Hanselmann
        namefield = "id"
1200 76b62028 Iustin Pop
        nameval = 123
1201 76b62028 Iustin Pop
        namevalempty = 0
1202 76b62028 Iustin Pop
        genval = lambda i: i * 10
1203 76b62028 Iustin Pop
        randvals = [17361, 22015, 13193, 15215]
1204 d6f58310 Michael Hanselmann
      else:
1205 76b62028 Iustin Pop
        nameval = "abc"
1206 76b62028 Iustin Pop
        namevalempty = ""
1207 76b62028 Iustin Pop
        genval = lambda i: "x%s" % i
1208 76b62028 Iustin Pop
        randvals = ["x17361", "x22015", "x13193", "x15215"]
1209 76b62028 Iustin Pop
        if what == constants.QR_EXPORT:
1210 76b62028 Iustin Pop
          namefield = "export"
1211 76b62028 Iustin Pop
        else:
1212 76b62028 Iustin Pop
          namefield = "name"
1213 d6f58310 Michael Hanselmann
1214 d6f58310 Michael Hanselmann
      assert namefield in fielddefs
1215 d6f58310 Michael Hanselmann
1216 09532dcc Iustin Pop
      reqnames = [genval(i) for i in range(4)]
1217 09532dcc Iustin Pop
      innerfilter = [["=", namefield, v] for v in reqnames]
1218 fb0be379 Michael Hanselmann
1219 fb0be379 Michael Hanselmann
      # No name field
1220 09532dcc Iustin Pop
      q = query.Query(fielddefs, [namefield],
1221 09532dcc Iustin Pop
                      qfilter=["=", namefield, nameval], namefield=None)
1222 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), None)
1223 fb0be379 Michael Hanselmann
1224 fb0be379 Michael Hanselmann
      # No filter
1225 d6f58310 Michael Hanselmann
      q = query.Query(fielddefs, [namefield], qfilter=None, namefield=namefield)
1226 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), None)
1227 fb0be379 Michael Hanselmann
1228 fb0be379 Michael Hanselmann
      # Check empty query
1229 d6f58310 Michael Hanselmann
      q = query.Query(fielddefs, [namefield], qfilter=["|"],
1230 d6f58310 Michael Hanselmann
                      namefield=namefield)
1231 fb0be379 Michael Hanselmann
      self.assertEqual(q.RequestedNames(), None)
1232 fb0be379 Michael Hanselmann
1233 fb0be379 Michael Hanselmann
      # Check order
1234 d6f58310 Michael Hanselmann
      q = query.Query(fielddefs, [namefield], qfilter=["|"] + innerfilter,
1235 d6f58310 Michael Hanselmann
                      namefield=namefield)
1236 09532dcc Iustin Pop
      self.assertEqual(q.RequestedNames(), reqnames)
1237 fb0be379 Michael Hanselmann
1238 fb0be379 Michael Hanselmann
      # Check reverse order
1239 d6f58310 Michael Hanselmann
      q = query.Query(fielddefs, [namefield],
1240 2e5c33db Iustin Pop
                      qfilter=["|"] + list(reversed(innerfilter)),
1241 d6f58310 Michael Hanselmann
                      namefield=namefield)
1242 09532dcc Iustin Pop
      self.assertEqual(q.RequestedNames(), list(reversed(reqnames)))
1243 fb0be379 Michael Hanselmann
1244 fb0be379 Michael Hanselmann
      # Duplicates
1245 d6f58310 Michael Hanselmann
      q = query.Query(fielddefs, [namefield],
1246 2e5c33db Iustin Pop
                      qfilter=["|"] + innerfilter + list(reversed(innerfilter)),
1247 d6f58310 Michael Hanselmann
                      namefield=namefield)
1248 09532dcc Iustin Pop
      self.assertEqual(q.RequestedNames(), reqnames)
1249 fb0be379 Michael Hanselmann
1250 fb0be379 Michael Hanselmann
      # Unknown name field
1251 d6f58310 Michael Hanselmann
      self.assertRaises(AssertionError, query.Query, fielddefs, [namefield],
1252 fb0be379 Michael Hanselmann
                        namefield="_unknown_field_")
1253 fb0be379 Michael Hanselmann
1254 fb0be379 Michael Hanselmann
      # Filter with AND
1255 d6f58310 Michael Hanselmann
      q = query.Query(fielddefs, [namefield],
1256 09532dcc Iustin Pop
                      qfilter=["|", ["=", namefield, nameval],
1257 09532dcc Iustin Pop
                                    ["&", ["=", namefield, namevalempty]]],
1258 d6f58310 Michael Hanselmann
                      namefield=namefield)
1259 fb0be379 Michael Hanselmann
      self.assertTrue(q.RequestedNames() is None)
1260 fb0be379 Michael Hanselmann
1261 fb0be379 Michael Hanselmann
      # Filter with NOT
1262 d6f58310 Michael Hanselmann
      q = query.Query(fielddefs, [namefield],
1263 09532dcc Iustin Pop
                      qfilter=["|", ["=", namefield, nameval],
1264 09532dcc Iustin Pop
                                    ["!", ["=", namefield, namevalempty]]],
1265 d6f58310 Michael Hanselmann
                      namefield=namefield)
1266 fb0be379 Michael Hanselmann
      self.assertTrue(q.RequestedNames() is None)
1267 fb0be379 Michael Hanselmann
1268 fb0be379 Michael Hanselmann
      # Filter with only OR (names must be in correct order)
1269 d6f58310 Michael Hanselmann
      q = query.Query(fielddefs, [namefield],
1270 09532dcc Iustin Pop
                      qfilter=["|", ["=", namefield, randvals[0]],
1271 09532dcc Iustin Pop
                                    ["|", ["=", namefield, randvals[1]]],
1272 09532dcc Iustin Pop
                                    ["|", ["|", ["=", namefield, randvals[2]]]],
1273 09532dcc Iustin Pop
                                    ["=", namefield, randvals[3]]],
1274 d6f58310 Michael Hanselmann
                      namefield=namefield)
1275 09532dcc Iustin Pop
      self.assertEqual(q.RequestedNames(), randvals)
1276 fb0be379 Michael Hanselmann
1277 fb0be379 Michael Hanselmann
  @staticmethod
1278 09532dcc Iustin Pop
  def _GenNestedFilter(namefield, op, depth, nameval):
1279 09532dcc Iustin Pop
    nested = ["=", namefield, nameval]
1280 fb0be379 Michael Hanselmann
    for i in range(depth):
1281 fb0be379 Michael Hanselmann
      nested = [op, nested]
1282 fb0be379 Michael Hanselmann
    return nested
1283 fb0be379 Michael Hanselmann
1284 fb0be379 Michael Hanselmann
  def testCompileFilter(self):
1285 fb0be379 Michael Hanselmann
    levels_max = query._FilterCompilerHelper._LEVELS_MAX
1286 fb0be379 Michael Hanselmann
1287 0fdf247d Michael Hanselmann
    for (what, fielddefs) in query.ALL_FIELDS.items():
1288 0fdf247d Michael Hanselmann
      if what == constants.QR_JOB:
1289 d6f58310 Michael Hanselmann
        namefield = "id"
1290 76b62028 Iustin Pop
        nameval = 123
1291 0fdf247d Michael Hanselmann
      elif what == constants.QR_EXPORT:
1292 0fdf247d Michael Hanselmann
        namefield = "export"
1293 76b62028 Iustin Pop
        nameval = "value"
1294 d6f58310 Michael Hanselmann
      else:
1295 d6f58310 Michael Hanselmann
        namefield = "name"
1296 76b62028 Iustin Pop
        nameval = "value"
1297 d6f58310 Michael Hanselmann
1298 d6f58310 Michael Hanselmann
      checks = [
1299 d6f58310 Michael Hanselmann
        [], ["="], ["=", "foo"], ["unknownop"], ["!"],
1300 d6f58310 Michael Hanselmann
        ["=", "_unknown_field", "value"],
1301 09532dcc Iustin Pop
        self._GenNestedFilter(namefield, "|", levels_max, nameval),
1302 09532dcc Iustin Pop
        self._GenNestedFilter(namefield, "|", levels_max * 3, nameval),
1303 09532dcc Iustin Pop
        self._GenNestedFilter(namefield, "!", levels_max, nameval),
1304 d6f58310 Michael Hanselmann
        ]
1305 d6f58310 Michael Hanselmann
1306 2e5c33db Iustin Pop
      for qfilter in checks:
1307 fb0be379 Michael Hanselmann
        self.assertRaises(errors.ParameterError, query._CompileFilter,
1308 2e5c33db Iustin Pop
                          fielddefs, None, qfilter)
1309 fb0be379 Michael Hanselmann
1310 fb0be379 Michael Hanselmann
      for op in ["|", "!"]:
1311 09532dcc Iustin Pop
        qfilter = self._GenNestedFilter(namefield, op, levels_max - 1, nameval)
1312 fb0be379 Michael Hanselmann
        self.assertTrue(callable(query._CompileFilter(fielddefs, None,
1313 2e5c33db Iustin Pop
                                                      qfilter)))
1314 fb0be379 Michael Hanselmann
1315 fb0be379 Michael Hanselmann
  def testQueryInputOrder(self):
1316 fb0be379 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1317 fb0be379 Michael Hanselmann
      (query._MakeField("pnode", "PNode", constants.QFT_TEXT, "Primary"),
1318 fb0be379 Michael Hanselmann
       None, 0, lambda ctx, item: item["pnode"]),
1319 fb0be379 Michael Hanselmann
      (query._MakeField("snode", "SNode", constants.QFT_TEXT, "Secondary"),
1320 fb0be379 Michael Hanselmann
       None, 0, lambda ctx, item: item["snode"]),
1321 fb0be379 Michael Hanselmann
      ], [])
1322 fb0be379 Michael Hanselmann
1323 fb0be379 Michael Hanselmann
    data = [
1324 fb0be379 Michael Hanselmann
      { "pnode": "node1", "snode": "node44", },
1325 fb0be379 Michael Hanselmann
      { "pnode": "node30", "snode": "node90", },
1326 fb0be379 Michael Hanselmann
      { "pnode": "node25", "snode": "node1", },
1327 fb0be379 Michael Hanselmann
      { "pnode": "node20", "snode": "node1", },
1328 fb0be379 Michael Hanselmann
      ]
1329 fb0be379 Michael Hanselmann
1330 2e5c33db Iustin Pop
    qfilter = ["|", ["=", "pnode", "node1"], ["=", "snode", "node1"]]
1331 fb0be379 Michael Hanselmann
1332 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "snode"], namefield="pnode",
1333 2e5c33db Iustin Pop
                    qfilter=qfilter)
1334 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1335 fb0be379 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1336 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1337 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")],
1338 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")],
1339 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")]])
1340 fb0be379 Michael Hanselmann
1341 fb0be379 Michael Hanselmann
    # Try again with reversed input data
1342 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(reversed(data)),
1343 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")],
1344 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")],
1345 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")]])
1346 fb0be379 Michael Hanselmann
1347 fb0be379 Michael Hanselmann
    # No name field, result must be in incoming order
1348 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "snode"], namefield=None,
1349 2e5c33db Iustin Pop
                    qfilter=qfilter)
1350 fb0be379 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1351 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1352 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")],
1353 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")],
1354 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")]])
1355 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1356 fb0be379 Michael Hanselmann
      ["node1", "node44"],
1357 fb0be379 Michael Hanselmann
      ["node25", "node1"],
1358 fb0be379 Michael Hanselmann
      ["node20", "node1"],
1359 fb0be379 Michael Hanselmann
      ])
1360 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(reversed(data)),
1361 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")],
1362 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")],
1363 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")]])
1364 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(reversed(data)), [
1365 fb0be379 Michael Hanselmann
      ["node20", "node1"],
1366 fb0be379 Michael Hanselmann
      ["node25", "node1"],
1367 fb0be379 Michael Hanselmann
      ["node1", "node44"],
1368 fb0be379 Michael Hanselmann
      ])
1369 fb0be379 Michael Hanselmann
1370 fbc263a9 Michael Hanselmann
    # Name field, but no sorting, result must be in incoming order
1371 fbc263a9 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "snode"], namefield="pnode")
1372 fbc263a9 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1373 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data, sort_by_name=False),
1374 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")],
1375 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node30"), (constants.RS_NORMAL, "node90")],
1376 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")],
1377 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")]])
1378 fbc263a9 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data, sort_by_name=False), [
1379 fbc263a9 Michael Hanselmann
      ["node1", "node44"],
1380 fbc263a9 Michael Hanselmann
      ["node30", "node90"],
1381 fbc263a9 Michael Hanselmann
      ["node25", "node1"],
1382 fbc263a9 Michael Hanselmann
      ["node20", "node1"],
1383 fbc263a9 Michael Hanselmann
      ])
1384 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(reversed(data), sort_by_name=False),
1385 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "node20"), (constants.RS_NORMAL, "node1")],
1386 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node25"), (constants.RS_NORMAL, "node1")],
1387 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node30"), (constants.RS_NORMAL, "node90")],
1388 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "node44")]])
1389 fbc263a9 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(reversed(data), sort_by_name=False), [
1390 fbc263a9 Michael Hanselmann
      ["node20", "node1"],
1391 fbc263a9 Michael Hanselmann
      ["node25", "node1"],
1392 fbc263a9 Michael Hanselmann
      ["node30", "node90"],
1393 fbc263a9 Michael Hanselmann
      ["node1", "node44"],
1394 fbc263a9 Michael Hanselmann
      ])
1395 fbc263a9 Michael Hanselmann
1396 fbc263a9 Michael Hanselmann
  def testEqualNamesOrder(self):
1397 fbc263a9 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1398 fbc263a9 Michael Hanselmann
      (query._MakeField("pnode", "PNode", constants.QFT_TEXT, "Primary"),
1399 fbc263a9 Michael Hanselmann
       None, 0, lambda ctx, item: item["pnode"]),
1400 fbc263a9 Michael Hanselmann
      (query._MakeField("num", "Num", constants.QFT_NUMBER, "Num"),
1401 fbc263a9 Michael Hanselmann
       None, 0, lambda ctx, item: item["num"]),
1402 fbc263a9 Michael Hanselmann
      ], [])
1403 fbc263a9 Michael Hanselmann
1404 fbc263a9 Michael Hanselmann
    data = [
1405 fbc263a9 Michael Hanselmann
      { "pnode": "node1", "num": 100, },
1406 fbc263a9 Michael Hanselmann
      { "pnode": "node1", "num": 25, },
1407 fbc263a9 Michael Hanselmann
      { "pnode": "node2", "num": 90, },
1408 fbc263a9 Michael Hanselmann
      { "pnode": "node2", "num": 30, },
1409 fbc263a9 Michael Hanselmann
      ]
1410 fbc263a9 Michael Hanselmann
1411 fbc263a9 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "num"], namefield="pnode",
1412 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "pnode", "node1"],
1413 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "node2"],
1414 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "node1"]])
1415 fbc263a9 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1", "node2"],
1416 fbc263a9 Michael Hanselmann
                     msg="Did not return unique names")
1417 fbc263a9 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1418 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data),
1419 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, 100)],
1420 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, 25)],
1421 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, 90)],
1422 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, 30)]])
1423 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data, sort_by_name=False),
1424 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, 100)],
1425 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, 25)],
1426 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, 90)],
1427 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, 30)]])
1428 fbc263a9 Michael Hanselmann
1429 fbc263a9 Michael Hanselmann
    data = [
1430 fbc263a9 Michael Hanselmann
      { "pnode": "nodeX", "num": 50, },
1431 fbc263a9 Michael Hanselmann
      { "pnode": "nodeY", "num": 40, },
1432 fbc263a9 Michael Hanselmann
      { "pnode": "nodeX", "num": 30, },
1433 fbc263a9 Michael Hanselmann
      { "pnode": "nodeX", "num": 20, },
1434 fbc263a9 Michael Hanselmann
      { "pnode": "nodeM", "num": 10, },
1435 fbc263a9 Michael Hanselmann
      ]
1436 fbc263a9 Michael Hanselmann
1437 fbc263a9 Michael Hanselmann
    q = query.Query(fielddefs, ["pnode", "num"], namefield="pnode",
1438 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "pnode", "nodeX"],
1439 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "nodeY"],
1440 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "nodeY"],
1441 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "nodeY"],
1442 fbc263a9 Michael Hanselmann
                                  ["=", "pnode", "nodeM"]])
1443 fbc263a9 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["nodeX", "nodeY", "nodeM"],
1444 fbc263a9 Michael Hanselmann
                     msg="Did not return unique names")
1445 fbc263a9 Michael Hanselmann
    self.assertFalse(q.RequestedData())
1446 fbc263a9 Michael Hanselmann
1447 fbc263a9 Michael Hanselmann
    # First sorted by name, then input order
1448 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data, sort_by_name=True),
1449 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "nodeM"), (constants.RS_NORMAL, 10)],
1450 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 50)],
1451 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 30)],
1452 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 20)],
1453 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeY"), (constants.RS_NORMAL, 40)]])
1454 fbc263a9 Michael Hanselmann
1455 fbc263a9 Michael Hanselmann
    # Input order
1456 fbc263a9 Michael Hanselmann
    self.assertEqual(q.Query(data, sort_by_name=False),
1457 fbc263a9 Michael Hanselmann
      [[(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 50)],
1458 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeY"), (constants.RS_NORMAL, 40)],
1459 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 30)],
1460 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeX"), (constants.RS_NORMAL, 20)],
1461 fbc263a9 Michael Hanselmann
       [(constants.RS_NORMAL, "nodeM"), (constants.RS_NORMAL, 10)]])
1462 fbc263a9 Michael Hanselmann
1463 fb0be379 Michael Hanselmann
  def testFilter(self):
1464 fb0be379 Michael Hanselmann
    (DK_A, DK_B) = range(1000, 1002)
1465 fb0be379 Michael Hanselmann
1466 fb0be379 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1467 fb0be379 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1468 fb0be379 Michael Hanselmann
       DK_A, 0, lambda ctx, item: item["name"]),
1469 fb0be379 Michael Hanselmann
      (query._MakeField("other", "Other", constants.QFT_TEXT, "Other"),
1470 fb0be379 Michael Hanselmann
       DK_B, 0, lambda ctx, item: item["other"]),
1471 fb0be379 Michael Hanselmann
      ], [])
1472 fb0be379 Michael Hanselmann
1473 fb0be379 Michael Hanselmann
    data = [
1474 fb0be379 Michael Hanselmann
      { "name": "node1", "other": "foo", },
1475 fb0be379 Michael Hanselmann
      { "name": "node2", "other": "bar", },
1476 fb0be379 Michael Hanselmann
      { "name": "node3", "other": "Hello", },
1477 fb0be379 Michael Hanselmann
      ]
1478 fb0be379 Michael Hanselmann
1479 fb0be379 Michael Hanselmann
    # Empty filter
1480 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1481 2e5c33db Iustin Pop
                    qfilter=["|"])
1482 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1483 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_A, DK_B]))
1484 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [])
1485 fb0be379 Michael Hanselmann
1486 fb0be379 Michael Hanselmann
    # Normal filter
1487 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1488 2e5c33db Iustin Pop
                    qfilter=["=", "name", "node1"])
1489 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1"])
1490 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1491 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "foo")]])
1492 fb0be379 Michael Hanselmann
1493 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1494 2e5c33db Iustin Pop
                    qfilter=(["|", ["=", "name", "node1"],
1495 fb0be379 Michael Hanselmann
                                   ["=", "name", "node3"]]))
1496 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1", "node3"])
1497 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1498 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "foo")],
1499 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, "Hello")]])
1500 fb0be379 Michael Hanselmann
1501 fb0be379 Michael Hanselmann
    # Complex filter
1502 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1503 2e5c33db Iustin Pop
                    qfilter=(["|", ["=", "name", "node1"],
1504 fb0be379 Michael Hanselmann
                                   ["|", ["=", "name", "node3"],
1505 fb0be379 Michael Hanselmann
                                         ["=", "name", "node2"]],
1506 fb0be379 Michael Hanselmann
                                   ["=", "name", "node3"]]))
1507 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1", "node3", "node2"])
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
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "foo")],
1511 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, "bar")],
1512 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, "Hello")]])
1513 fb0be379 Michael Hanselmann
1514 fb0be379 Michael Hanselmann
    # Filter data type mismatch
1515 fb0be379 Michael Hanselmann
    for i in [-1, 0, 1, 123, [], None, True, False]:
1516 fb0be379 Michael Hanselmann
      self.assertRaises(errors.ParameterError, query.Query,
1517 fb0be379 Michael Hanselmann
                        fielddefs, ["name", "other"], namefield="name",
1518 2e5c33db Iustin Pop
                        qfilter=["=", "name", i])
1519 fb0be379 Michael Hanselmann
1520 fb0be379 Michael Hanselmann
    # Negative filter
1521 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1522 2e5c33db Iustin Pop
                    qfilter=["!", ["|", ["=", "name", "node1"],
1523 fb0be379 Michael Hanselmann
                                        ["=", "name", "node3"]]])
1524 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1525 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1526 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, "bar")]])
1527 fb0be379 Michael Hanselmann
1528 fb0be379 Michael Hanselmann
    # Not equal
1529 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1530 2e5c33db Iustin Pop
                    qfilter=["!=", "name", "node3"])
1531 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1532 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data),
1533 fb0be379 Michael Hanselmann
      [[(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, "foo")],
1534 fb0be379 Michael Hanselmann
       [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, "bar")]])
1535 fb0be379 Michael Hanselmann
1536 fb0be379 Michael Hanselmann
    # Data type
1537 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, [], namefield="name",
1538 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "other", "bar"],
1539 fb0be379 Michael Hanselmann
                                  ["=", "name", "foo"]])
1540 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1541 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_A, DK_B]))
1542 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [[]])
1543 fb0be379 Michael Hanselmann
1544 fb0be379 Michael Hanselmann
    # Only one data type
1545 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["other"], namefield="name",
1546 2e5c33db Iustin Pop
                    qfilter=["=", "other", "bar"])
1547 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1548 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_B]))
1549 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [[(constants.RS_NORMAL, "bar")]])
1550 fb0be379 Michael Hanselmann
1551 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, [], namefield="name",
1552 2e5c33db Iustin Pop
                    qfilter=["=", "other", "bar"])
1553 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1554 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_B]))
1555 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [[]])
1556 fb0be379 Michael Hanselmann
1557 52aa1efa Michael Hanselmann
    # Data type in boolean operator
1558 52aa1efa Michael Hanselmann
    q = query.Query(fielddefs, [], namefield="name",
1559 52aa1efa Michael Hanselmann
                    qfilter=["?", "name"])
1560 52aa1efa Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1561 52aa1efa Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_A]))
1562 52aa1efa Michael Hanselmann
    self.assertEqual(q.Query(data), [[], [], []])
1563 52aa1efa Michael Hanselmann
1564 52aa1efa Michael Hanselmann
    q = query.Query(fielddefs, [], namefield="name",
1565 52aa1efa Michael Hanselmann
                    qfilter=["!", ["?", "name"]])
1566 52aa1efa Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1567 52aa1efa Michael Hanselmann
    self.assertEqual(q.RequestedData(), set([DK_A]))
1568 52aa1efa Michael Hanselmann
    self.assertEqual(q.Query(data), [])
1569 52aa1efa Michael Hanselmann
1570 fb0be379 Michael Hanselmann
  def testFilterContains(self):
1571 fb0be379 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1572 fb0be379 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1573 fb0be379 Michael Hanselmann
       None, 0, lambda ctx, item: item["name"]),
1574 fb0be379 Michael Hanselmann
      (query._MakeField("other", "Other", constants.QFT_OTHER, "Other"),
1575 fb0be379 Michael Hanselmann
       None, 0, lambda ctx, item: item["other"]),
1576 fb0be379 Michael Hanselmann
      ], [])
1577 fb0be379 Michael Hanselmann
1578 fb0be379 Michael Hanselmann
    data = [
1579 fb0be379 Michael Hanselmann
      { "name": "node2", "other": ["x", "y", "bar"], },
1580 fb0be379 Michael Hanselmann
      { "name": "node3", "other": "Hello", },
1581 fb0be379 Michael Hanselmann
      { "name": "node1", "other": ["a", "b", "foo"], },
1582 3b877f08 Michael Hanselmann
      { "name": "empty", "other": []},
1583 fb0be379 Michael Hanselmann
      ]
1584 fb0be379 Michael Hanselmann
1585 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1586 2e5c33db Iustin Pop
                    qfilter=["=[]", "other", "bar"])
1587 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1588 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1589 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"),
1590 fb0be379 Michael Hanselmann
       (constants.RS_NORMAL, ["x", "y", "bar"])],
1591 fb0be379 Michael Hanselmann
      ])
1592 fb0be379 Michael Hanselmann
1593 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1594 2e5c33db Iustin Pop
                    qfilter=["|", ["=[]", "other", "bar"],
1595 fb0be379 Michael Hanselmann
                                  ["=[]", "other", "a"],
1596 fb0be379 Michael Hanselmann
                                  ["=[]", "other", "b"]])
1597 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1598 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1599 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"),
1600 fb0be379 Michael Hanselmann
       (constants.RS_NORMAL, ["a", "b", "foo"])],
1601 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"),
1602 fb0be379 Michael Hanselmann
       (constants.RS_NORMAL, ["x", "y", "bar"])],
1603 fb0be379 Michael Hanselmann
      ])
1604 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1605 fb0be379 Michael Hanselmann
      ["node1", ["a", "b", "foo"]],
1606 fb0be379 Michael Hanselmann
      ["node2", ["x", "y", "bar"]],
1607 fb0be379 Michael Hanselmann
      ])
1608 fb0be379 Michael Hanselmann
1609 3b877f08 Michael Hanselmann
    # Boolean test
1610 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1611 2e5c33db Iustin Pop
                    qfilter=["?", "other"])
1612 3b877f08 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1613 3b877f08 Michael Hanselmann
      ["node1", ["a", "b", "foo"]],
1614 3b877f08 Michael Hanselmann
      ["node2", ["x", "y", "bar"]],
1615 3b877f08 Michael Hanselmann
      ["node3", "Hello"],
1616 3b877f08 Michael Hanselmann
      ])
1617 3b877f08 Michael Hanselmann
1618 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "other"], namefield="name",
1619 2e5c33db Iustin Pop
                    qfilter=["!", ["?", "other"]])
1620 3b877f08 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1621 3b877f08 Michael Hanselmann
      ["empty", []],
1622 3b877f08 Michael Hanselmann
      ])
1623 3b877f08 Michael Hanselmann
1624 fb0be379 Michael Hanselmann
  def testFilterHostname(self):
1625 fb0be379 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1626 fb0be379 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1627 fb0be379 Michael Hanselmann
       None, query.QFF_HOSTNAME, lambda ctx, item: item["name"]),
1628 fb0be379 Michael Hanselmann
      ], [])
1629 fb0be379 Michael Hanselmann
1630 fb0be379 Michael Hanselmann
    data = [
1631 fb0be379 Michael Hanselmann
      { "name": "node1.example.com", },
1632 fb0be379 Michael Hanselmann
      { "name": "node2.example.com", },
1633 fb0be379 Michael Hanselmann
      { "name": "node2.example.net", },
1634 fb0be379 Michael Hanselmann
      ]
1635 fb0be379 Michael Hanselmann
1636 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1637 2e5c33db Iustin Pop
                    qfilter=["=", "name", "node2"])
1638 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node2"])
1639 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1640 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.com")],
1641 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.net")],
1642 fb0be379 Michael Hanselmann
      ])
1643 fb0be379 Michael Hanselmann
1644 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1645 2e5c33db Iustin Pop
                    qfilter=["=", "name", "node1"])
1646 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1"])
1647 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1648 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node1.example.com")],
1649 fb0be379 Michael Hanselmann
      ])
1650 fb0be379 Michael Hanselmann
1651 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1652 2e5c33db Iustin Pop
                    qfilter=["=", "name", "othername"])
1653 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["othername"])
1654 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [])
1655 fb0be379 Michael Hanselmann
1656 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1657 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "name", "node1.example.com"],
1658 fb0be379 Michael Hanselmann
                                  ["=", "name", "node2"]])
1659 fb0be379 Michael Hanselmann
    self.assertEqual(q.RequestedNames(), ["node1.example.com", "node2"])
1660 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1661 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node1.example.com")],
1662 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.com")],
1663 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.net")],
1664 fb0be379 Michael Hanselmann
      ])
1665 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1666 fb0be379 Michael Hanselmann
      ["node1.example.com"],
1667 fb0be379 Michael Hanselmann
      ["node2.example.com"],
1668 fb0be379 Michael Hanselmann
      ["node2.example.net"],
1669 fb0be379 Michael Hanselmann
      ])
1670 fb0be379 Michael Hanselmann
1671 fb0be379 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1672 2e5c33db Iustin Pop
                    qfilter=["!=", "name", "node1"])
1673 fb0be379 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1674 fb0be379 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1675 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.com")],
1676 fb0be379 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.net")],
1677 fb0be379 Michael Hanselmann
      ])
1678 fb0be379 Michael Hanselmann
    self.assertEqual(q.OldStyleQuery(data), [
1679 fb0be379 Michael Hanselmann
      ["node2.example.com"],
1680 fb0be379 Michael Hanselmann
      ["node2.example.net"],
1681 fb0be379 Michael Hanselmann
      ])
1682 fb0be379 Michael Hanselmann
1683 3b877f08 Michael Hanselmann
  def testFilterBoolean(self):
1684 3b877f08 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1685 3b877f08 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1686 3b877f08 Michael Hanselmann
       None, query.QFF_HOSTNAME, lambda ctx, item: item["name"]),
1687 3b877f08 Michael Hanselmann
      (query._MakeField("value", "Value", constants.QFT_BOOL, "Value"),
1688 3b877f08 Michael Hanselmann
       None, 0, lambda ctx, item: item["value"]),
1689 3b877f08 Michael Hanselmann
      ], [])
1690 3b877f08 Michael Hanselmann
1691 3b877f08 Michael Hanselmann
    data = [
1692 3b877f08 Michael Hanselmann
      { "name": "node1", "value": False, },
1693 3b877f08 Michael Hanselmann
      { "name": "node2", "value": True, },
1694 3b877f08 Michael Hanselmann
      { "name": "node3", "value": True, },
1695 3b877f08 Michael Hanselmann
      ]
1696 3b877f08 Michael Hanselmann
1697 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "value"],
1698 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "value", False],
1699 3b877f08 Michael Hanselmann
                                  ["=", "value", True]])
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
      [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, True)],
1704 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, True)],
1705 3b877f08 Michael Hanselmann
      ])
1706 3b877f08 Michael Hanselmann
1707 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "value"],
1708 2e5c33db Iustin Pop
                    qfilter=["|", ["=", "value", False],
1709 3b877f08 Michael Hanselmann
                                  ["!", ["=", "value", False]]])
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 3b877f08 Michael Hanselmann
    # Comparing bool with string
1718 3b877f08 Michael Hanselmann
    for i in ["False", "True", "0", "1", "no", "yes", "N", "Y"]:
1719 3b877f08 Michael Hanselmann
      self.assertRaises(errors.ParameterError, query.Query,
1720 3b877f08 Michael Hanselmann
                        fielddefs, ["name", "value"],
1721 2e5c33db Iustin Pop
                        qfilter=["=", "value", i])
1722 3b877f08 Michael Hanselmann
1723 3b877f08 Michael Hanselmann
    # Truth filter
1724 2e5c33db Iustin Pop
    q = query.Query(fielddefs, ["name", "value"], qfilter=["?", "value"])
1725 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1726 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1727 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, True)],
1728 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, True)],
1729 3b877f08 Michael Hanselmann
      ])
1730 3b877f08 Michael Hanselmann
1731 3b877f08 Michael Hanselmann
    # Negative bool filter
1732 2e5c33db Iustin Pop
    q = query.Query(fielddefs, ["name", "value"], qfilter=["!", ["?", "value"]])
1733 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1734 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1735 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, False)],
1736 3b877f08 Michael Hanselmann
      ])
1737 3b877f08 Michael Hanselmann
1738 3b877f08 Michael Hanselmann
    # Complex truth filter
1739 3b877f08 Michael Hanselmann
    q = query.Query(fielddefs, ["name", "value"],
1740 2e5c33db Iustin Pop
                    qfilter=["|", ["&", ["=", "name", "node1"],
1741 3b877f08 Michael Hanselmann
                                        ["!", ["?", "value"]]],
1742 3b877f08 Michael Hanselmann
                                  ["?", "value"]])
1743 3b877f08 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1744 3b877f08 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1745 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node1"), (constants.RS_NORMAL, False)],
1746 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node2"), (constants.RS_NORMAL, True)],
1747 3b877f08 Michael Hanselmann
      [(constants.RS_NORMAL, "node3"), (constants.RS_NORMAL, True)],
1748 3b877f08 Michael Hanselmann
      ])
1749 3b877f08 Michael Hanselmann
1750 23d0a608 Michael Hanselmann
  def testFilterRegex(self):
1751 23d0a608 Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1752 23d0a608 Michael Hanselmann
      (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"),
1753 23d0a608 Michael Hanselmann
       None, 0, lambda ctx, item: item["name"]),
1754 23d0a608 Michael Hanselmann
      ], [])
1755 23d0a608 Michael Hanselmann
1756 23d0a608 Michael Hanselmann
    data = [
1757 23d0a608 Michael Hanselmann
      { "name": "node1.example.com", },
1758 23d0a608 Michael Hanselmann
      { "name": "node2.site.example.com", },
1759 23d0a608 Michael Hanselmann
      { "name": "node2.example.net", },
1760 23d0a608 Michael Hanselmann
1761 23d0a608 Michael Hanselmann
      # Empty name
1762 23d0a608 Michael Hanselmann
      { "name": "", },
1763 23d0a608 Michael Hanselmann
      ]
1764 23d0a608 Michael Hanselmann
1765 23d0a608 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1766 2e5c33db Iustin Pop
                    qfilter=["=~", "name", "site"])
1767 23d0a608 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1768 23d0a608 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1769 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.site.example.com")],
1770 23d0a608 Michael Hanselmann
      ])
1771 23d0a608 Michael Hanselmann
1772 23d0a608 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1773 2e5c33db Iustin Pop
                    qfilter=["=~", "name", "^node2"])
1774 23d0a608 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1775 23d0a608 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1776 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.net")],
1777 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.site.example.com")],
1778 23d0a608 Michael Hanselmann
      ])
1779 23d0a608 Michael Hanselmann
1780 23d0a608 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1781 2e5c33db Iustin Pop
                    qfilter=["=~", "name", r"(?i)\.COM$"])
1782 23d0a608 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1783 23d0a608 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1784 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node1.example.com")],
1785 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.site.example.com")],
1786 23d0a608 Michael Hanselmann
      ])
1787 23d0a608 Michael Hanselmann
1788 23d0a608 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1789 2e5c33db Iustin Pop
                    qfilter=["=~", "name", r"."])
1790 23d0a608 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1791 23d0a608 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1792 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node1.example.com")],
1793 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.net")],
1794 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.site.example.com")],
1795 23d0a608 Michael Hanselmann
      ])
1796 23d0a608 Michael Hanselmann
1797 23d0a608 Michael Hanselmann
    q = query.Query(fielddefs, ["name"], namefield="name",
1798 2e5c33db Iustin Pop
                    qfilter=["=~", "name", r"^$"])
1799 23d0a608 Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1800 23d0a608 Michael Hanselmann
    self.assertEqual(q.Query(data), [
1801 23d0a608 Michael Hanselmann
      [(constants.RS_NORMAL, "")],
1802 23d0a608 Michael Hanselmann
      ])
1803 23d0a608 Michael Hanselmann
1804 23d0a608 Michael Hanselmann
    # Invalid regular expression
1805 23d0a608 Michael Hanselmann
    self.assertRaises(errors.ParameterError, query.Query, fielddefs, ["name"],
1806 2e5c33db Iustin Pop
                      qfilter=["=~", "name", r"["])
1807 23d0a608 Michael Hanselmann
1808 ad48eacc Michael Hanselmann
  def testFilterLessGreater(self):
1809 ad48eacc Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1810 ad48eacc Michael Hanselmann
      (query._MakeField("value", "Value", constants.QFT_NUMBER, "Value"),
1811 ad48eacc Michael Hanselmann
       None, 0, lambda ctx, item: item),
1812 ad48eacc Michael Hanselmann
      ], [])
1813 ad48eacc Michael Hanselmann
1814 ad48eacc Michael Hanselmann
    data = range(100)
1815 ad48eacc Michael Hanselmann
1816 ad48eacc Michael Hanselmann
    q = query.Query(fielddefs, ["value"],
1817 ad48eacc Michael Hanselmann
                    qfilter=["<", "value", 20])
1818 ad48eacc Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1819 ad48eacc Michael Hanselmann
    self.assertEqual(q.Query(data),
1820 ad48eacc Michael Hanselmann
                     [[(constants.RS_NORMAL, i)] for i in range(20)])
1821 ad48eacc Michael Hanselmann
1822 ad48eacc Michael Hanselmann
    q = query.Query(fielddefs, ["value"],
1823 ad48eacc Michael Hanselmann
                    qfilter=["<=", "value", 30])
1824 ad48eacc Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1825 ad48eacc Michael Hanselmann
    self.assertEqual(q.Query(data),
1826 ad48eacc Michael Hanselmann
                     [[(constants.RS_NORMAL, i)] for i in range(31)])
1827 ad48eacc Michael Hanselmann
1828 ad48eacc Michael Hanselmann
    q = query.Query(fielddefs, ["value"],
1829 ad48eacc Michael Hanselmann
                    qfilter=[">", "value", 40])
1830 ad48eacc Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1831 ad48eacc Michael Hanselmann
    self.assertEqual(q.Query(data),
1832 ad48eacc Michael Hanselmann
                     [[(constants.RS_NORMAL, i)] for i in range(41, 100)])
1833 ad48eacc Michael Hanselmann
1834 ad48eacc Michael Hanselmann
    q = query.Query(fielddefs, ["value"],
1835 ad48eacc Michael Hanselmann
                    qfilter=[">=", "value", 50])
1836 ad48eacc Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1837 ad48eacc Michael Hanselmann
    self.assertEqual(q.Query(data),
1838 ad48eacc Michael Hanselmann
                     [[(constants.RS_NORMAL, i)] for i in range(50, 100)])
1839 ad48eacc Michael Hanselmann
1840 526f866b Michael Hanselmann
  def testFilterLessGreaterJobId(self):
1841 526f866b Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1842 526f866b Michael Hanselmann
      (query._MakeField("id", "ID", constants.QFT_TEXT, "Job ID"),
1843 526f866b Michael Hanselmann
       None, query.QFF_JOB_ID, lambda ctx, item: item),
1844 526f866b Michael Hanselmann
      ], [])
1845 526f866b Michael Hanselmann
1846 526f866b Michael Hanselmann
    data = ["1", "2", "3", "10", "102", "120", "125", "15", "100", "7"]
1847 526f866b Michael Hanselmann
1848 526f866b Michael Hanselmann
    assert data != utils.NiceSort(data), "Test data should not be sorted"
1849 526f866b Michael Hanselmann
1850 526f866b Michael Hanselmann
    q = query.Query(fielddefs, ["id"], qfilter=["<", "id", "20"])
1851 526f866b Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1852 526f866b Michael Hanselmann
    self.assertEqual(q.Query(data), [
1853 526f866b Michael Hanselmann
      [(constants.RS_NORMAL, "1")],
1854 526f866b Michael Hanselmann
      [(constants.RS_NORMAL, "2")],
1855 526f866b Michael Hanselmann
      [(constants.RS_NORMAL, "3")],
1856 526f866b Michael Hanselmann
      [(constants.RS_NORMAL, "10")],
1857 526f866b Michael Hanselmann
      [(constants.RS_NORMAL, "15")],
1858 526f866b Michael Hanselmann
      [(constants.RS_NORMAL, "7")],
1859 526f866b Michael Hanselmann
      ])
1860 526f866b Michael Hanselmann
1861 526f866b Michael Hanselmann
    q = query.Query(fielddefs, ["id"], qfilter=[">=", "id", "100"])
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, "102")],
1865 526f866b Michael Hanselmann
      [(constants.RS_NORMAL, "120")],
1866 526f866b Michael Hanselmann
      [(constants.RS_NORMAL, "125")],
1867 526f866b Michael Hanselmann
      [(constants.RS_NORMAL, "100")],
1868 526f866b Michael Hanselmann
      ])
1869 526f866b Michael Hanselmann
1870 526f866b Michael Hanselmann
    # Integers are no valid job IDs
1871 526f866b Michael Hanselmann
    self.assertRaises(errors.ParameterError, query.Query,
1872 526f866b Michael Hanselmann
                      fielddefs, ["id"], qfilter=[">=", "id", 10])
1873 526f866b Michael Hanselmann
1874 526f866b Michael Hanselmann
  def testFilterLessGreaterSplitTimestamp(self):
1875 526f866b Michael Hanselmann
    fielddefs = query._PrepareFieldList([
1876 526f866b Michael Hanselmann
      (query._MakeField("ts", "Timestamp", constants.QFT_OTHER, "Timestamp"),
1877 526f866b Michael Hanselmann
       None, query.QFF_SPLIT_TIMESTAMP, lambda ctx, item: item),
1878 526f866b Michael Hanselmann
      ], [])
1879 526f866b Michael Hanselmann
1880 526f866b Michael Hanselmann
    data = [
1881 526f866b Michael Hanselmann
      utils.SplitTime(0),
1882 526f866b Michael Hanselmann
      utils.SplitTime(0.1),
1883 526f866b Michael Hanselmann
      utils.SplitTime(18224.7872),
1884 526f866b Michael Hanselmann
      utils.SplitTime(919896.12623),
1885 526f866b Michael Hanselmann
      utils.SplitTime(999),
1886 526f866b Michael Hanselmann
      utils.SplitTime(989.9999),
1887 526f866b Michael Hanselmann
      ]
1888 526f866b Michael Hanselmann
1889 526f866b Michael Hanselmann
    for i in [0, [0, 0]]:
1890 526f866b Michael Hanselmann
      q = query.Query(fielddefs, ["ts"], qfilter=["<", "ts", i])
1891 526f866b Michael Hanselmann
      self.assertTrue(q.RequestedNames() is None)
1892 526f866b Michael Hanselmann
      self.assertEqual(q.Query(data), [])
1893 526f866b Michael Hanselmann
1894 526f866b Michael Hanselmann
    q = query.Query(fielddefs, ["ts"], qfilter=["<", "ts", 1000])
1895 526f866b Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1896 526f866b Michael Hanselmann
    self.assertEqual(q.Query(data), [
1897 526f866b Michael Hanselmann
      [(constants.RS_NORMAL, (0, 0))],
1898 526f866b Michael Hanselmann
      [(constants.RS_NORMAL, (0, 100000))],
1899 526f866b Michael Hanselmann
      [(constants.RS_NORMAL, (999, 0))],
1900 526f866b Michael Hanselmann
      [(constants.RS_NORMAL, (989, 999900))],
1901 526f866b Michael Hanselmann
      ])
1902 526f866b Michael Hanselmann
1903 526f866b Michael Hanselmann
    q = query.Query(fielddefs, ["ts"], qfilter=[">=", "ts", 5000.3])
1904 526f866b Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1905 526f866b Michael Hanselmann
    self.assertEqual(q.Query(data), [
1906 526f866b Michael Hanselmann
      [(constants.RS_NORMAL, (18224, 787200))],
1907 526f866b Michael Hanselmann
      [(constants.RS_NORMAL, (919896, 126230))],
1908 526f866b Michael Hanselmann
      ])
1909 526f866b Michael Hanselmann
1910 526f866b Michael Hanselmann
    for i in [18224.7772, utils.SplitTime(18224.7772)]:
1911 526f866b Michael Hanselmann
      q = query.Query(fielddefs, ["ts"], qfilter=[">=", "ts", i])
1912 526f866b Michael Hanselmann
      self.assertTrue(q.RequestedNames() is None)
1913 526f866b Michael Hanselmann
      self.assertEqual(q.Query(data), [
1914 526f866b Michael Hanselmann
        [(constants.RS_NORMAL, (18224, 787200))],
1915 526f866b Michael Hanselmann
        [(constants.RS_NORMAL, (919896, 126230))],
1916 526f866b Michael Hanselmann
        ])
1917 526f866b Michael Hanselmann
1918 526f866b Michael Hanselmann
    q = query.Query(fielddefs, ["ts"], qfilter=[">", "ts", 18224.7880])
1919 526f866b Michael Hanselmann
    self.assertTrue(q.RequestedNames() is None)
1920 526f866b Michael Hanselmann
    self.assertEqual(q.Query(data), [
1921 526f866b Michael Hanselmann
      [(constants.RS_NORMAL, (919896, 126230))],
1922 526f866b Michael Hanselmann
      ])
1923 526f866b Michael Hanselmann
1924 fb0be379 Michael Hanselmann
1925 4ca96421 Michael Hanselmann
if __name__ == "__main__":
1926 4ca96421 Michael Hanselmann
  testutils.GanetiTestProgram()