Revision d63bd540

b/lib/query.py
277 277
                    (utils.CommaJoin(errors), row))
278 278

  
279 279

  
280
def _PrepareFieldList(fields):
280
def _PrepareFieldList(fields, aliases):
281 281
  """Prepares field list for use by L{Query}.
282 282

  
283 283
  Converts the list to a dictionary and does some verification.
284 284

  
285
  @type fields: list of tuples; (L{objects.QueryFieldDefinition}, data kind,
286
    retrieval function)
287
  @param fields: List of fields, see L{Query.__init__} for a better description
285
  @type fields: list of tuples; (L{objects.QueryFieldDefinition}, data
286
      kind, retrieval function)
287
  @param fields: List of fields, see L{Query.__init__} for a better
288
      description
289
  @type aliases: list of tuples; (alias, target)
290
  @param aliases: list of tuples containing aliases; for each
291
      alias/target pair, a duplicate will be created in the field list
288 292
  @rtype: dict
289 293
  @return: Field dictionary for L{Query}
290 294

  
......
308 312

  
309 313
    result[fdef.name] = field
310 314

  
311
  assert len(result) == len(fields)
315
  for alias, target in aliases:
316
    assert alias not in result, "Alias %s overrides an existing field" % alias
317
    assert target in result, "Missing target %s for alias %s" % (target, alias)
318
    (fdef, k, fn) = result[target]
319
    fdef = fdef.Copy()
320
    fdef.name = alias
321
    result[alias] = (fdef, k, fn)
322

  
323
  assert len(result) == len(fields) + len(aliases)
312 324
  assert compat.all(name == fdef.name
313 325
                    for (name, (fdef, _, _)) in result.items())
314 326

  
......
644 656
  # Add timestamps
645 657
  fields.extend(_GetItemTimestampFields(NQ_CONFIG))
646 658

  
647
  return _PrepareFieldList(fields)
659
  return _PrepareFieldList(fields, [])
648 660

  
649 661

  
650 662
class InstanceQueryData:
......
1119 1131
  fields.extend(_GetInstanceNetworkFields())
1120 1132
  fields.extend(_GetItemTimestampFields(IQ_CONFIG))
1121 1133

  
1122
  return _PrepareFieldList(fields)
1134
  return _PrepareFieldList(fields, [])
1123 1135

  
1124 1136

  
1125 1137
class LockQueryData:
......
1175 1187
     lambda ctx, (name, mode, owners, pending): mode),
1176 1188
    (_MakeField("owner", "Owner", QFT_OTHER), LQ_OWNER, _GetLockOwners),
1177 1189
    (_MakeField("pending", "Pending", QFT_OTHER), LQ_PENDING, _GetLockPending),
1178
    ])
1190
    ], [])
1179 1191

  
1180 1192

  
1181 1193
class GroupQueryData:
......
1247 1259

  
1248 1260
  fields.extend(_GetItemTimestampFields(GQ_CONFIG))
1249 1261

  
1250
  return _PrepareFieldList(fields)
1262
  return _PrepareFieldList(fields, [])
1251 1263

  
1252 1264

  
1253 1265
#: Fields available for node queries
b/test/ganeti.query_unittest.py
74 74
      [(query._MakeField("disk%s.size" % i, "DiskSize%s" % i,
75 75
                         constants.QFT_UNIT),
76 76
        DISK, compat.partial(_GetDiskSize, i))
77
       for i in range(4)])
77
       for i in range(4)], [])
78 78

  
79 79
    q = query.Query(fielddef, ["name"])
80 80
    self.assertEqual(q.RequestedData(), set([STATIC]))
......
176 176
         lambda *args: None),
177 177
        (query._MakeField("other", a, constants.QFT_TEXT), None,
178 178
         lambda *args: None),
179
        ])
179
        ], [])
180 180

  
181 181
    # Non-lowercase names
182 182
    self.assertRaises(AssertionError, query._PrepareFieldList, [
183 183
      (query._MakeField("NAME", "Name", constants.QFT_TEXT), None,
184 184
       lambda *args: None),
185
      ])
185
      ], [])
186 186
    self.assertRaises(AssertionError, query._PrepareFieldList, [
187 187
      (query._MakeField("Name", "Name", constants.QFT_TEXT), None,
188 188
       lambda *args: None),
189
      ])
189
      ], [])
190 190

  
191 191
    # Empty name
192 192
    self.assertRaises(AssertionError, query._PrepareFieldList, [
193 193
      (query._MakeField("", "Name", constants.QFT_TEXT), None,
194 194
       lambda *args: None),
195
      ])
195
      ], [])
196 196

  
197 197
    # Empty title
198 198
    self.assertRaises(AssertionError, query._PrepareFieldList, [
199 199
      (query._MakeField("name", "", constants.QFT_TEXT), None,
200 200
       lambda *args: None),
201
      ])
201
      ], [])
202 202

  
203 203
    # Whitespace in title
204 204
    self.assertRaises(AssertionError, query._PrepareFieldList, [
205 205
      (query._MakeField("name", "Co lu mn", constants.QFT_TEXT), None,
206 206
       lambda *args: None),
207
      ])
207
      ], [])
208 208

  
209 209
    # No callable function
210 210
    self.assertRaises(AssertionError, query._PrepareFieldList, [
211 211
      (query._MakeField("name", "Name", constants.QFT_TEXT), None, None),
212
      ])
212
      ], [])
213 213

  
214 214
  def testUnknown(self):
215 215
    fielddef = query._PrepareFieldList([
......
221 221
       None, lambda *args: query._FS_NODATA ),
222 222
      (query._MakeField("unavail", "Unavail", constants.QFT_BOOL),
223 223
       None, lambda *args: query._FS_UNAVAIL),
224
      ])
224
      ], [])
225 225

  
226 226
    for selected in [["foo"], ["Hello", "World"],
227 227
                     ["name1", "other", "foo"]]:
......
254 254
                       (constants.QRFS_UNKNOWN, None)]
255 255
                      for i in range(1, 10)])
256 256

  
257
  def testAliases(self):
258
    fields = [
259
      (query._MakeField("a", "a-title", constants.QFT_TEXT), None,
260
       lambda *args: None),
261
      (query._MakeField("b", "b-title", constants.QFT_TEXT), None,
262
       lambda *args: None),
263
      ]
264
    # duplicate field
265
    self.assertRaises(AssertionError, query._PrepareFieldList, fields,
266
                      [("b", "a")])
267
    self.assertRaises(AssertionError, query._PrepareFieldList, fields,
268
                      [("c", "b"), ("c", "a")])
269
    # missing target
270
    self.assertRaises(AssertionError, query._PrepareFieldList, fields,
271
                      [("c", "d")])
272
    fdefs = query._PrepareFieldList(fields, [("c", "b")])
273
    self.assertEqual(len(fdefs), 3)
274
    self.assertEqual(fdefs["b"][1:], fdefs["c"][1:])
275

  
257 276

  
258 277
class TestGetNodeRole(unittest.TestCase):
259 278
  def testMaster(self):

Also available in: Unified diff