Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.query_unittest.py @ d43a4dd9

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