Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.query_unittest.py @ 560ef132

History | View | Annotate | Download (75.6 kB)

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