Revision 4fab7cab

b/qa/ganeti-qa.py
173 173
    ("cluster-oob", qa_cluster.TestClusterOob),
174 174
    ("rapi", qa_rapi.TestVersion),
175 175
    ("rapi", qa_rapi.TestEmptyCluster),
176
    ("rapi", qa_rapi.TestRapiQuery),
176 177
    ]:
177 178
    RunTestIf(test, fn)
178 179

  
b/qa/qa_rapi.py
23 23
"""
24 24

  
25 25
import tempfile
26
import random
26 27

  
27 28
from ganeti import utils
28 29
from ganeti import constants
......
30 31
from ganeti import cli
31 32
from ganeti import rapi
32 33
from ganeti import objects
34
from ganeti import query
35
from ganeti import compat
36
from ganeti import qlang
33 37

  
34 38
import ganeti.rapi.client        # pylint: disable-msg=W0611
35 39
import ganeti.rapi.client_utils
......
220 224
      raise qa_error.Error("Non-implemented method didn't fail")
221 225

  
222 226

  
227
def TestRapiQuery():
228
  """Testing resource queries via remote API.
229

  
230
  """
231
  master_name = qa_utils.ResolveNodeName(qa_config.GetMasterNode())
232
  rnd = random.Random(7818)
233

  
234
  for what in constants.QR_VIA_RAPI:
235
    all_fields = query.ALL_FIELDS[what].keys()
236
    rnd.shuffle(all_fields)
237

  
238
    # No fields, should return everything
239
    result = _rapi_client.QueryFields(what)
240
    qresult = objects.QueryFieldsResponse.FromDict(result)
241
    AssertEqual(len(qresult.fields), len(all_fields))
242

  
243
    # One field
244
    result = _rapi_client.QueryFields(what, fields=["name"])
245
    qresult = objects.QueryFieldsResponse.FromDict(result)
246
    AssertEqual(len(qresult.fields), 1)
247

  
248
    # Specify all fields, order must be correct
249
    result = _rapi_client.QueryFields(what, fields=all_fields)
250
    qresult = objects.QueryFieldsResponse.FromDict(result)
251
    AssertEqual(len(qresult.fields), len(all_fields))
252
    AssertEqual([fdef.name for fdef in qresult.fields], all_fields)
253

  
254
    # Unknown field
255
    result = _rapi_client.QueryFields(what, fields=["_unknown!"])
256
    qresult = objects.QueryFieldsResponse.FromDict(result)
257
    AssertEqual(len(qresult.fields), 1)
258
    AssertEqual(qresult.fields[0].name, "_unknown!")
259
    AssertEqual(qresult.fields[0].kind, constants.QFT_UNKNOWN)
260

  
261
    # Try once more, this time without the client
262
    _DoTests([
263
      ("/2/query/%s/fields" % what, None, "GET", None),
264
      ("/2/query/%s/fields?fields=name,name,%s" % (what, all_fields[0]),
265
       None, "GET", None),
266
      ])
267

  
268
    # Try missing query argument
269
    try:
270
      _DoTests([
271
        ("/2/query/%s" % what, None, "GET", None),
272
        ])
273
    except rapi.client.GanetiApiError, err:
274
      AssertEqual(err.code, 400)
275
    else:
276
      raise qa_error.Error("Request missing 'fields' parameter didn't fail")
277

  
278
    def _Check(exp_fields, data):
279
      qresult = objects.QueryResponse.FromDict(data)
280
      AssertEqual([fdef.name for fdef in qresult.fields], exp_fields)
281
      if not isinstance(qresult.data, list):
282
        raise qa_error.Error("Query did not return a list")
283

  
284
    _DoTests([
285
      # Specify fields in query
286
      ("/2/query/%s?fields=%s" % (what, ",".join(all_fields)),
287
       compat.partial(_Check, all_fields), "GET", None),
288

  
289
      ("/2/query/%s?fields=name" % what,
290
       compat.partial(_Check, ["name"]), "GET", None),
291

  
292
      # Note the spaces
293
      ("/2/query/%s?fields=name,%%20name%%09,name%%20" % what,
294
       compat.partial(_Check, ["name"] * 3), "GET", None),
295

  
296
      # PUT with fields in query
297
      ("/2/query/%s?fields=name" % what,
298
       compat.partial(_Check, ["name"]), "PUT", {}),
299

  
300
      # Fields in body
301
      ("/2/query/%s" % what, compat.partial(_Check, all_fields), "PUT", {
302
         "fields": all_fields,
303
         }),
304

  
305
      ("/2/query/%s" % what, compat.partial(_Check, ["name"] * 4), "PUT", {
306
         "fields": ["name"] * 4,
307
         }),
308
      ])
309

  
310
    def _CheckFilter():
311
      _DoTests([
312
        # With filter
313
        ("/2/query/%s" % what, compat.partial(_Check, all_fields), "PUT", {
314
           "fields": all_fields,
315
           "filter": [qlang.OP_TRUE, "name"],
316
           }),
317
        ])
318

  
319
    if what == constants.QR_LOCK:
320
      # Locks can't be filtered
321
      try:
322
        _CheckFilter()
323
      except rapi.client.GanetiApiError, err:
324
        AssertEqual(err.code, 500)
325
      else:
326
        raise qa_error.Error("Filtering locks didn't fail")
327
    else:
328
      _CheckFilter()
329

  
330
    if what == constants.QR_NODE:
331
      # Test with filter
332
      (nodes, ) = _DoTests([("/2/query/%s" % what,
333
        compat.partial(_Check, ["name", "master"]), "PUT", {
334
        "fields": ["name", "master"],
335
        "filter": [qlang.OP_TRUE, "master"],
336
        })])
337
      qresult = objects.QueryResponse.FromDict(nodes)
338
      AssertEqual(qresult.data, [
339
        [[constants.RS_NORMAL, master_name], [constants.RS_NORMAL, True]],
340
        ])
341

  
342

  
223 343
def TestInstance(instance):
224 344
  """Testing getting instance(s) info via remote API.
225 345

  
......
301 421
  def _VerifyTags(data):
302 422
    AssertEqual(sorted(tags), sorted(data))
303 423

  
304
  query = "&".join("tag=%s" % i for i in tags)
424
  queryargs = "&".join("tag=%s" % i for i in tags)
305 425

  
306 426
  # Add tags
307 427
  (job_id, ) = _DoTests([
308
    ("%s?%s" % (uri, query), _VerifyReturnsJob, "PUT", None),
428
    ("%s?%s" % (uri, queryargs), _VerifyReturnsJob, "PUT", None),
309 429
    ])
310 430
  _WaitForRapiJob(job_id)
311 431

  
......
316 436

  
317 437
  # Remove tags
318 438
  (job_id, ) = _DoTests([
319
    ("%s?%s" % (uri, query), _VerifyReturnsJob, "DELETE", None),
439
    ("%s?%s" % (uri, queryargs), _VerifyReturnsJob, "DELETE", None),
320 440
    ])
321 441
  _WaitForRapiJob(job_id)
322 442

  

Also available in: Unified diff