Statistics
| Branch: | Tag: | Revision:

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

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