Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.rapi.rlib2_unittest.py @ 303bc802

History | View | Annotate | Download (55.9 kB)

1
#!/usr/bin/python
2
#
3

    
4
# Copyright (C) 2010, 2012 Google Inc.
5
#
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful, but
12
# WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
# General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
# 02110-1301, USA.
20

    
21

    
22
"""Script for unittesting the RAPI rlib2 module
23

24
"""
25

    
26

    
27
import unittest
28
import itertools
29
import random
30

    
31
from ganeti import constants
32
from ganeti import opcodes
33
from ganeti import compat
34
from ganeti import http
35
from ganeti import query
36
from ganeti import luxi
37
from ganeti import errors
38

    
39
from ganeti.rapi import rlib2
40

    
41
import testutils
42

    
43

    
44
class _FakeRequestPrivateData:
45
  def __init__(self, body_data):
46
    self.body_data = body_data
47

    
48

    
49
class _FakeRequest:
50
  def __init__(self, body_data):
51
    self.private = _FakeRequestPrivateData(body_data)
52

    
53

    
54
def _CreateHandler(cls, items, queryargs, body_data, client_cls):
55
  return cls(items, queryargs, _FakeRequest(body_data),
56
             _client_cls=client_cls)
57

    
58

    
59
class _FakeClient:
60
  def __init__(self, address=None):
61
    self._jobs = []
62

    
63
  def GetNextSubmittedJob(self):
64
    return self._jobs.pop(0)
65

    
66
  def SubmitJob(self, ops):
67
    job_id = str(1 + int(random.random() * 1000000))
68
    self._jobs.append((job_id, ops))
69
    return job_id
70

    
71

    
72
class _FakeClientFactory:
73
  def __init__(self, cls):
74
    self._client_cls = cls
75
    self._clients = []
76

    
77
  def GetNextClient(self):
78
    return self._clients.pop(0)
79

    
80
  def __call__(self, address=None):
81
    cl = self._client_cls(address=address)
82
    self._clients.append(cl)
83
    return cl
84

    
85

    
86
class TestConstants(unittest.TestCase):
87
  def testConsole(self):
88
    # Exporting the console field without authentication might expose
89
    # information
90
    assert "console" in query.INSTANCE_FIELDS
91
    self.assertTrue("console" not in rlib2.I_FIELDS)
92

    
93
  def testFields(self):
94
    checks = {
95
      constants.QR_INSTANCE: rlib2.I_FIELDS,
96
      constants.QR_NODE: rlib2.N_FIELDS,
97
      constants.QR_GROUP: rlib2.G_FIELDS,
98
      }
99

    
100
    for (qr, fields) in checks.items():
101
      self.assertFalse(set(fields) - set(query.ALL_FIELDS[qr].keys()))
102

    
103

    
104
class TestClientConnectError(unittest.TestCase):
105
  @staticmethod
106
  def _FailingClient(address=None):
107
    raise luxi.NoMasterError("test")
108

    
109
  def test(self):
110
    resources = [
111
      rlib2.R_2_groups,
112
      rlib2.R_2_instances,
113
      rlib2.R_2_nodes,
114
      ]
115
    for cls in resources:
116
      handler = _CreateHandler(cls, ["name"], [], None, self._FailingClient)
117
      self.assertRaises(http.HttpBadGateway, handler.GET)
118

    
119

    
120
class TestJobSubmitError(unittest.TestCase):
121
  class _SubmitErrorClient:
122
    def __init__(self, address=None):
123
      pass
124

    
125
    @staticmethod
126
    def SubmitJob(ops):
127
      raise errors.JobQueueFull("test")
128

    
129
  def test(self):
130
    handler = _CreateHandler(rlib2.R_2_redist_config, [], [], None,
131
                             self._SubmitErrorClient)
132
    self.assertRaises(http.HttpServiceUnavailable, handler.PUT)
133

    
134

    
135
class TestClusterModify(unittest.TestCase):
136
  def test(self):
137
    clfactory = _FakeClientFactory(_FakeClient)
138
    handler = _CreateHandler(rlib2.R_2_cluster_modify, [], [], {
139
      "vg_name": "testvg",
140
      "candidate_pool_size": 100,
141
      }, clfactory)
142
    job_id = handler.PUT()
143

    
144
    cl = clfactory.GetNextClient()
145
    self.assertRaises(IndexError, clfactory.GetNextClient)
146

    
147
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
148
    self.assertEqual(job_id, exp_job_id)
149
    self.assertTrue(isinstance(op, opcodes.OpClusterSetParams))
150
    self.assertEqual(op.vg_name, "testvg")
151
    self.assertEqual(op.candidate_pool_size, 100)
152

    
153
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
154

    
155
  def testInvalidValue(self):
156
    for attr in ["vg_name", "candidate_pool_size", "beparams", "_-Unknown#"]:
157
      clfactory = _FakeClientFactory(_FakeClient)
158
      handler = _CreateHandler(rlib2.R_2_cluster_modify, [], [], {
159
        attr: True,
160
        }, clfactory)
161
      self.assertRaises(http.HttpBadRequest, handler.PUT)
162
      self.assertRaises(IndexError, clfactory.GetNextClient)
163

    
164

    
165
class TestRedistConfig(unittest.TestCase):
166
  def test(self):
167
    clfactory = _FakeClientFactory(_FakeClient)
168
    handler = _CreateHandler(rlib2.R_2_redist_config, [], [], None, clfactory)
169
    job_id = handler.PUT()
170

    
171
    cl = clfactory.GetNextClient()
172
    self.assertRaises(IndexError, clfactory.GetNextClient)
173

    
174
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
175
    self.assertEqual(job_id, exp_job_id)
176
    self.assertTrue(isinstance(op, opcodes.OpClusterRedistConf))
177

    
178
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
179

    
180

    
181
class TestNodeMigrate(unittest.TestCase):
182
  def test(self):
183
    clfactory = _FakeClientFactory(_FakeClient)
184
    handler = _CreateHandler(rlib2.R_2_nodes_name_migrate, ["node1"], {}, {
185
      "iallocator": "fooalloc",
186
      }, clfactory)
187
    job_id = handler.POST()
188

    
189
    cl = clfactory.GetNextClient()
190
    self.assertRaises(IndexError, clfactory.GetNextClient)
191

    
192
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
193
    self.assertEqual(job_id, exp_job_id)
194
    self.assertTrue(isinstance(op, opcodes.OpNodeMigrate))
195
    self.assertEqual(op.node_name, "node1")
196
    self.assertEqual(op.iallocator, "fooalloc")
197

    
198
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
199

    
200
  def testQueryArgsConflict(self):
201
    clfactory = _FakeClientFactory(_FakeClient)
202
    handler = _CreateHandler(rlib2.R_2_nodes_name_migrate, ["node2"], {
203
      "live": True,
204
      "mode": constants.HT_MIGRATION_NONLIVE,
205
      }, None, clfactory)
206
    self.assertRaises(http.HttpBadRequest, handler.POST)
207
    self.assertRaises(IndexError, clfactory.GetNextClient)
208

    
209
  def testQueryArgsMode(self):
210
    clfactory = _FakeClientFactory(_FakeClient)
211
    queryargs = {
212
      "mode": [constants.HT_MIGRATION_LIVE],
213
      }
214
    handler = _CreateHandler(rlib2.R_2_nodes_name_migrate, ["node17292"],
215
                             queryargs, None, clfactory)
216
    job_id = handler.POST()
217

    
218
    cl = clfactory.GetNextClient()
219
    self.assertRaises(IndexError, clfactory.GetNextClient)
220

    
221
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
222
    self.assertEqual(job_id, exp_job_id)
223
    self.assertTrue(isinstance(op, opcodes.OpNodeMigrate))
224
    self.assertEqual(op.node_name, "node17292")
225
    self.assertEqual(op.mode, constants.HT_MIGRATION_LIVE)
226

    
227
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
228

    
229
  def testQueryArgsLive(self):
230
    clfactory = _FakeClientFactory(_FakeClient)
231

    
232
    for live in [False, True]:
233
      queryargs = {
234
        "live": [str(int(live))],
235
        }
236
      handler = _CreateHandler(rlib2.R_2_nodes_name_migrate, ["node6940"],
237
                               queryargs, None, clfactory)
238
      job_id = handler.POST()
239

    
240
      cl = clfactory.GetNextClient()
241
      self.assertRaises(IndexError, clfactory.GetNextClient)
242

    
243
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
244
      self.assertEqual(job_id, exp_job_id)
245
      self.assertTrue(isinstance(op, opcodes.OpNodeMigrate))
246
      self.assertEqual(op.node_name, "node6940")
247
      if live:
248
        self.assertEqual(op.mode, constants.HT_MIGRATION_LIVE)
249
      else:
250
        self.assertEqual(op.mode, constants.HT_MIGRATION_NONLIVE)
251

    
252
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
253

    
254

    
255
class TestNodeEvacuate(unittest.TestCase):
256
  def test(self):
257
    clfactory = _FakeClientFactory(_FakeClient)
258
    handler = _CreateHandler(rlib2.R_2_nodes_name_evacuate, ["node92"], {
259
      "dry-run": ["1"],
260
      }, {
261
      "mode": constants.IALLOCATOR_NEVAC_SEC,
262
      }, clfactory)
263
    job_id = handler.POST()
264

    
265
    cl = clfactory.GetNextClient()
266
    self.assertRaises(IndexError, clfactory.GetNextClient)
267

    
268
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
269
    self.assertEqual(job_id, exp_job_id)
270
    self.assertTrue(isinstance(op, opcodes.OpNodeEvacuate))
271
    self.assertEqual(op.node_name, "node92")
272
    self.assertEqual(op.mode, constants.IALLOCATOR_NEVAC_SEC)
273
    self.assertTrue(op.dry_run)
274

    
275
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
276

    
277

    
278
class TestNodePowercycle(unittest.TestCase):
279
  def test(self):
280
    clfactory = _FakeClientFactory(_FakeClient)
281
    handler = _CreateHandler(rlib2.R_2_nodes_name_powercycle, ["node20744"], {
282
      "force": ["1"],
283
      }, None, clfactory)
284
    job_id = handler.POST()
285

    
286
    cl = clfactory.GetNextClient()
287
    self.assertRaises(IndexError, clfactory.GetNextClient)
288

    
289
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
290
    self.assertEqual(job_id, exp_job_id)
291
    self.assertTrue(isinstance(op, opcodes.OpNodePowercycle))
292
    self.assertEqual(op.node_name, "node20744")
293
    self.assertTrue(op.force)
294

    
295
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
296

    
297

    
298
class TestGroupAssignNodes(unittest.TestCase):
299
  def test(self):
300
    clfactory = _FakeClientFactory(_FakeClient)
301
    handler = _CreateHandler(rlib2.R_2_groups_name_assign_nodes, ["grp-a"], {
302
      "dry-run": ["1"],
303
      "force": ["1"],
304
      }, {
305
      "nodes": ["n2", "n3"],
306
      }, clfactory)
307
    job_id = handler.PUT()
308

    
309
    cl = clfactory.GetNextClient()
310
    self.assertRaises(IndexError, clfactory.GetNextClient)
311

    
312
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
313
    self.assertEqual(job_id, exp_job_id)
314
    self.assertTrue(isinstance(op, opcodes.OpGroupAssignNodes))
315
    self.assertEqual(op.group_name, "grp-a")
316
    self.assertEqual(op.nodes, ["n2", "n3"])
317
    self.assertTrue(op.dry_run)
318
    self.assertTrue(op.force)
319

    
320
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
321

    
322

    
323
class TestInstanceDelete(unittest.TestCase):
324
  def test(self):
325
    clfactory = _FakeClientFactory(_FakeClient)
326
    handler = _CreateHandler(rlib2.R_2_instances_name, ["inst30965"], {
327
      "dry-run": ["1"],
328
      }, {}, clfactory)
329
    job_id = handler.DELETE()
330

    
331
    cl = clfactory.GetNextClient()
332
    self.assertRaises(IndexError, clfactory.GetNextClient)
333

    
334
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
335
    self.assertEqual(job_id, exp_job_id)
336
    self.assertTrue(isinstance(op, opcodes.OpInstanceRemove))
337
    self.assertEqual(op.instance_name, "inst30965")
338
    self.assertTrue(op.dry_run)
339
    self.assertFalse(op.ignore_failures)
340

    
341
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
342

    
343

    
344
class TestInstanceInfo(unittest.TestCase):
345
  def test(self):
346
    clfactory = _FakeClientFactory(_FakeClient)
347
    handler = _CreateHandler(rlib2.R_2_instances_name_info, ["inst31217"], {
348
      "static": ["1"],
349
      }, {}, clfactory)
350
    job_id = handler.GET()
351

    
352
    cl = clfactory.GetNextClient()
353
    self.assertRaises(IndexError, clfactory.GetNextClient)
354

    
355
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
356
    self.assertEqual(job_id, exp_job_id)
357
    self.assertTrue(isinstance(op, opcodes.OpInstanceQueryData))
358
    self.assertEqual(op.instances, ["inst31217"])
359
    self.assertTrue(op.static)
360

    
361
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
362

    
363

    
364
class TestInstanceReboot(unittest.TestCase):
365
  def test(self):
366
    clfactory = _FakeClientFactory(_FakeClient)
367
    handler = _CreateHandler(rlib2.R_2_instances_name_reboot, ["inst847"], {
368
      "dry-run": ["1"],
369
      "ignore_secondaries": ["1"],
370
      }, {}, clfactory)
371
    job_id = handler.POST()
372

    
373
    cl = clfactory.GetNextClient()
374
    self.assertRaises(IndexError, clfactory.GetNextClient)
375

    
376
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
377
    self.assertEqual(job_id, exp_job_id)
378
    self.assertTrue(isinstance(op, opcodes.OpInstanceReboot))
379
    self.assertEqual(op.instance_name, "inst847")
380
    self.assertEqual(op.reboot_type, constants.INSTANCE_REBOOT_HARD)
381
    self.assertTrue(op.ignore_secondaries)
382
    self.assertTrue(op.dry_run)
383

    
384
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
385

    
386

    
387
class TestInstanceStartup(unittest.TestCase):
388
  def test(self):
389
    clfactory = _FakeClientFactory(_FakeClient)
390
    handler = _CreateHandler(rlib2.R_2_instances_name_startup, ["inst31083"], {
391
      "force": ["1"],
392
      "no_remember": ["1"],
393
      }, {}, clfactory)
394
    job_id = handler.PUT()
395

    
396
    cl = clfactory.GetNextClient()
397
    self.assertRaises(IndexError, clfactory.GetNextClient)
398

    
399
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
400
    self.assertEqual(job_id, exp_job_id)
401
    self.assertTrue(isinstance(op, opcodes.OpInstanceStartup))
402
    self.assertEqual(op.instance_name, "inst31083")
403
    self.assertTrue(op.no_remember)
404
    self.assertTrue(op.force)
405
    self.assertFalse(op.dry_run)
406

    
407
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
408

    
409

    
410
class TestInstanceShutdown(unittest.TestCase):
411
  def test(self):
412
    clfactory = _FakeClientFactory(_FakeClient)
413
    handler = _CreateHandler(rlib2.R_2_instances_name_shutdown, ["inst26791"], {
414
      "no_remember": ["0"],
415
      }, {}, clfactory)
416
    job_id = handler.PUT()
417

    
418
    cl = clfactory.GetNextClient()
419
    self.assertRaises(IndexError, clfactory.GetNextClient)
420

    
421
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
422
    self.assertEqual(job_id, exp_job_id)
423
    self.assertTrue(isinstance(op, opcodes.OpInstanceShutdown))
424
    self.assertEqual(op.instance_name, "inst26791")
425
    self.assertFalse(op.no_remember)
426
    self.assertFalse(op.dry_run)
427

    
428
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
429

    
430

    
431
class TestInstanceActivateDisks(unittest.TestCase):
432
  def test(self):
433
    clfactory = _FakeClientFactory(_FakeClient)
434
    handler = _CreateHandler(rlib2.R_2_instances_name_activate_disks, ["xyz"], {
435
      "ignore_size": ["1"],
436
      }, {}, clfactory)
437
    job_id = handler.PUT()
438

    
439
    cl = clfactory.GetNextClient()
440
    self.assertRaises(IndexError, clfactory.GetNextClient)
441

    
442
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
443
    self.assertEqual(job_id, exp_job_id)
444
    self.assertTrue(isinstance(op, opcodes.OpInstanceActivateDisks))
445
    self.assertEqual(op.instance_name, "xyz")
446
    self.assertTrue(op.ignore_size)
447
    self.assertFalse(hasattr(op, "dry_run"))
448

    
449
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
450

    
451

    
452
class TestInstanceDeactivateDisks(unittest.TestCase):
453
  def test(self):
454
    clfactory = _FakeClientFactory(_FakeClient)
455
    handler = _CreateHandler(rlib2.R_2_instances_name_deactivate_disks,
456
                             ["inst22357"], {}, {}, clfactory)
457
    job_id = handler.PUT()
458

    
459
    cl = clfactory.GetNextClient()
460
    self.assertRaises(IndexError, clfactory.GetNextClient)
461

    
462
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
463
    self.assertEqual(job_id, exp_job_id)
464
    self.assertTrue(isinstance(op, opcodes.OpInstanceDeactivateDisks))
465
    self.assertEqual(op.instance_name, "inst22357")
466
    self.assertFalse(hasattr(op, "dry_run"))
467
    self.assertFalse(hasattr(op, "force"))
468

    
469
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
470

    
471

    
472
class TestInstanceRecreateDisks(unittest.TestCase):
473
  def test(self):
474
    clfactory = _FakeClientFactory(_FakeClient)
475
    handler = _CreateHandler(rlib2.R_2_instances_name_recreate_disks,
476
                             ["inst22357"], {}, {}, clfactory)
477
    job_id = handler.POST()
478

    
479
    cl = clfactory.GetNextClient()
480
    self.assertRaises(IndexError, clfactory.GetNextClient)
481

    
482
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
483
    self.assertEqual(job_id, exp_job_id)
484
    self.assertTrue(isinstance(op, opcodes.OpInstanceRecreateDisks))
485
    self.assertEqual(op.instance_name, "inst22357")
486
    self.assertFalse(hasattr(op, "dry_run"))
487
    self.assertFalse(hasattr(op, "force"))
488

    
489
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
490

    
491

    
492
class TestInstanceFailover(unittest.TestCase):
493
  def test(self):
494
    clfactory = _FakeClientFactory(_FakeClient)
495
    handler = _CreateHandler(rlib2.R_2_instances_name_failover,
496
                             ["inst12794"], {}, {}, clfactory)
497
    job_id = handler.PUT()
498

    
499
    cl = clfactory.GetNextClient()
500
    self.assertRaises(IndexError, clfactory.GetNextClient)
501

    
502
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
503
    self.assertEqual(job_id, exp_job_id)
504
    self.assertTrue(isinstance(op, opcodes.OpInstanceFailover))
505
    self.assertEqual(op.instance_name, "inst12794")
506
    self.assertFalse(hasattr(op, "dry_run"))
507
    self.assertFalse(hasattr(op, "force"))
508

    
509
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
510

    
511

    
512
class TestInstanceDiskGrow(unittest.TestCase):
513
  def test(self):
514
    clfactory = _FakeClientFactory(_FakeClient)
515
    data = {
516
      "amount": 1024,
517
      }
518
    handler = _CreateHandler(rlib2.R_2_instances_name_disk_grow,
519
                             ["inst10742", "3"], {}, data, clfactory)
520
    job_id = handler.POST()
521

    
522
    cl = clfactory.GetNextClient()
523
    self.assertRaises(IndexError, clfactory.GetNextClient)
524

    
525
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
526
    self.assertEqual(job_id, exp_job_id)
527
    self.assertTrue(isinstance(op, opcodes.OpInstanceGrowDisk))
528
    self.assertEqual(op.instance_name, "inst10742")
529
    self.assertEqual(op.disk, 3)
530
    self.assertEqual(op.amount, 1024)
531
    self.assertFalse(hasattr(op, "dry_run"))
532
    self.assertFalse(hasattr(op, "force"))
533

    
534
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
535

    
536

    
537
class TestBackupPrepare(unittest.TestCase):
538
  def test(self):
539
    clfactory = _FakeClientFactory(_FakeClient)
540
    queryargs = {
541
      "mode": constants.EXPORT_MODE_REMOTE,
542
      }
543
    handler = _CreateHandler(rlib2.R_2_instances_name_prepare_export,
544
                             ["inst17925"], queryargs, {}, clfactory)
545
    job_id = handler.PUT()
546

    
547
    cl = clfactory.GetNextClient()
548
    self.assertRaises(IndexError, clfactory.GetNextClient)
549

    
550
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
551
    self.assertEqual(job_id, exp_job_id)
552
    self.assertTrue(isinstance(op, opcodes.OpBackupPrepare))
553
    self.assertEqual(op.instance_name, "inst17925")
554
    self.assertEqual(op.mode, constants.EXPORT_MODE_REMOTE)
555
    self.assertFalse(hasattr(op, "dry_run"))
556
    self.assertFalse(hasattr(op, "force"))
557

    
558
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
559

    
560

    
561
class TestGroupRemove(unittest.TestCase):
562
  def test(self):
563
    clfactory = _FakeClientFactory(_FakeClient)
564
    handler = _CreateHandler(rlib2.R_2_groups_name,
565
                             ["grp28575"], {}, {}, clfactory)
566
    job_id = handler.DELETE()
567

    
568
    cl = clfactory.GetNextClient()
569
    self.assertRaises(IndexError, clfactory.GetNextClient)
570

    
571
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
572
    self.assertEqual(job_id, exp_job_id)
573
    self.assertTrue(isinstance(op, opcodes.OpGroupRemove))
574
    self.assertEqual(op.group_name, "grp28575")
575
    self.assertFalse(op.dry_run)
576
    self.assertFalse(hasattr(op, "force"))
577

    
578
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
579

    
580

    
581
class TestStorageQuery(unittest.TestCase):
582
  def test(self):
583
    clfactory = _FakeClientFactory(_FakeClient)
584
    queryargs = {
585
      "storage_type": constants.ST_LVM_PV,
586
      "output_fields": "name,other",
587
      }
588
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
589
                             ["node21075"], queryargs, {}, clfactory)
590
    job_id = handler.GET()
591

    
592
    cl = clfactory.GetNextClient()
593
    self.assertRaises(IndexError, clfactory.GetNextClient)
594

    
595
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
596
    self.assertEqual(job_id, exp_job_id)
597
    self.assertTrue(isinstance(op, opcodes.OpNodeQueryStorage))
598
    self.assertEqual(op.nodes, ["node21075"])
599
    self.assertEqual(op.storage_type, constants.ST_LVM_PV)
600
    self.assertEqual(op.output_fields, ["name", "other"])
601
    self.assertFalse(hasattr(op, "dry_run"))
602
    self.assertFalse(hasattr(op, "force"))
603

    
604
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
605

    
606
  def testErrors(self):
607
    clfactory = _FakeClientFactory(_FakeClient)
608

    
609
    queryargs = {
610
      "output_fields": "name,other",
611
      }
612
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
613
                             ["node10538"], queryargs, {}, clfactory)
614
    self.assertRaises(http.HttpBadRequest, handler.GET)
615

    
616
    queryargs = {
617
      "storage_type": constants.ST_LVM_VG,
618
      }
619
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
620
                             ["node21273"], queryargs, {}, clfactory)
621
    self.assertRaises(http.HttpBadRequest, handler.GET)
622

    
623
    queryargs = {
624
      "storage_type": "##unknown_storage##",
625
      "output_fields": "name,other",
626
      }
627
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
628
                             ["node10315"], queryargs, {}, clfactory)
629
    self.assertRaises(http.HttpBadRequest, handler.GET)
630

    
631

    
632
class TestStorageModify(unittest.TestCase):
633
  def test(self):
634
    clfactory = _FakeClientFactory(_FakeClient)
635

    
636
    for allocatable in [None, "1", "0"]:
637
      queryargs = {
638
        "storage_type": constants.ST_LVM_VG,
639
        "name": "pv-a",
640
        }
641

    
642
      if allocatable is not None:
643
        queryargs["allocatable"] = allocatable
644

    
645
      handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
646
                               ["node9292"], queryargs, {}, clfactory)
647
      job_id = handler.PUT()
648

    
649
      cl = clfactory.GetNextClient()
650
      self.assertRaises(IndexError, clfactory.GetNextClient)
651

    
652
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
653
      self.assertEqual(job_id, exp_job_id)
654
      self.assertTrue(isinstance(op, opcodes.OpNodeModifyStorage))
655
      self.assertEqual(op.node_name, "node9292")
656
      self.assertEqual(op.storage_type, constants.ST_LVM_VG)
657
      self.assertEqual(op.name, "pv-a")
658
      if allocatable is None:
659
        self.assertFalse(op.changes)
660
      else:
661
        assert allocatable in ("0", "1")
662
        self.assertEqual(op.changes, {
663
          constants.SF_ALLOCATABLE: (allocatable == "1"),
664
          })
665
      self.assertFalse(hasattr(op, "dry_run"))
666
      self.assertFalse(hasattr(op, "force"))
667

    
668
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
669

    
670
  def testErrors(self):
671
    clfactory = _FakeClientFactory(_FakeClient)
672

    
673
    # No storage type
674
    queryargs = {
675
      "name": "xyz",
676
      }
677
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
678
                             ["node26016"], queryargs, {}, clfactory)
679
    self.assertRaises(http.HttpBadRequest, handler.PUT)
680

    
681
    # No name
682
    queryargs = {
683
      "storage_type": constants.ST_LVM_VG,
684
      }
685
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
686
                             ["node21218"], queryargs, {}, clfactory)
687
    self.assertRaises(http.HttpBadRequest, handler.PUT)
688

    
689
    # Invalid value
690
    queryargs = {
691
      "storage_type": constants.ST_LVM_VG,
692
      "name": "pv-b",
693
      "allocatable": "noint",
694
      }
695
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
696
                             ["node30685"], queryargs, {}, clfactory)
697
    self.assertRaises(http.HttpBadRequest, handler.PUT)
698

    
699

    
700
class TestStorageRepair(unittest.TestCase):
701
  def test(self):
702
    clfactory = _FakeClientFactory(_FakeClient)
703
    queryargs = {
704
      "storage_type": constants.ST_LVM_PV,
705
      "name": "pv16611",
706
      }
707
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
708
                             ["node19265"], queryargs, {}, clfactory)
709
    job_id = handler.PUT()
710

    
711
    cl = clfactory.GetNextClient()
712
    self.assertRaises(IndexError, clfactory.GetNextClient)
713

    
714
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
715
    self.assertEqual(job_id, exp_job_id)
716
    self.assertTrue(isinstance(op, opcodes.OpRepairNodeStorage))
717
    self.assertEqual(op.node_name, "node19265")
718
    self.assertEqual(op.storage_type, constants.ST_LVM_PV)
719
    self.assertEqual(op.name, "pv16611")
720
    self.assertFalse(hasattr(op, "dry_run"))
721
    self.assertFalse(hasattr(op, "force"))
722

    
723
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
724

    
725
  def testErrors(self):
726
    clfactory = _FakeClientFactory(_FakeClient)
727

    
728
    # No storage type
729
    queryargs = {
730
      "name": "xyz",
731
      }
732
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
733
                             ["node11275"], queryargs, {}, clfactory)
734
    self.assertRaises(http.HttpBadRequest, handler.PUT)
735

    
736
    # No name
737
    queryargs = {
738
      "storage_type": constants.ST_LVM_VG,
739
      }
740
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
741
                             ["node21218"], queryargs, {}, clfactory)
742
    self.assertRaises(http.HttpBadRequest, handler.PUT)
743

    
744

    
745
class TestTags(unittest.TestCase):
746
  TAG_HANDLERS = [
747
    rlib2.R_2_instances_name_tags,
748
    rlib2.R_2_nodes_name_tags,
749
    rlib2.R_2_groups_name_tags,
750
    rlib2.R_2_tags,
751
    ]
752

    
753
  def testSetAndDelete(self):
754
    clfactory = _FakeClientFactory(_FakeClient)
755

    
756
    for method, opcls in [("PUT", opcodes.OpTagsSet),
757
                          ("DELETE", opcodes.OpTagsDel)]:
758
      for idx, handler in enumerate(self.TAG_HANDLERS):
759
        dry_run = bool(idx % 2)
760
        name = "test%s" % idx
761
        queryargs = {
762
          "tag": ["foo", "bar", "baz"],
763
          "dry-run": str(int(dry_run)),
764
          }
765

    
766
        handler = _CreateHandler(handler, [name], queryargs, {}, clfactory)
767
        job_id = getattr(handler, method)()
768

    
769
        cl = clfactory.GetNextClient()
770
        self.assertRaises(IndexError, clfactory.GetNextClient)
771

    
772
        (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
773
        self.assertEqual(job_id, exp_job_id)
774
        self.assertTrue(isinstance(op, opcls))
775
        self.assertEqual(op.kind, handler.TAG_LEVEL)
776
        if handler.TAG_LEVEL == constants.TAG_CLUSTER:
777
          self.assertTrue(op.name is None)
778
        else:
779
          self.assertEqual(op.name, name)
780
        self.assertEqual(op.tags, ["foo", "bar", "baz"])
781
        self.assertEqual(op.dry_run, dry_run)
782
        self.assertFalse(hasattr(op, "force"))
783

    
784
        self.assertRaises(IndexError, cl.GetNextSubmittedJob)
785

    
786

    
787
class TestInstanceCreation(testutils.GanetiTestCase):
788
  def test(self):
789
    clfactory = _FakeClientFactory(_FakeClient)
790

    
791
    name = "inst863.example.com"
792

    
793
    disk_variants = [
794
      # No disks
795
      [],
796

    
797
      # Two disks
798
      [{"size": 5, }, {"size": 100, }],
799

    
800
      # Disk with mode
801
      [{"size": 123, "mode": constants.DISK_RDWR, }],
802
      ]
803

    
804
    nic_variants = [
805
      # No NIC
806
      [],
807

    
808
      # Three NICs
809
      [{}, {}, {}],
810

    
811
      # Two NICs
812
      [
813
        { "ip": "192.0.2.6", "mode": constants.NIC_MODE_ROUTED,
814
          "mac": "01:23:45:67:68:9A",
815
        },
816
        { "mode": constants.NIC_MODE_BRIDGED, "link": "br1" },
817
      ],
818
      ]
819

    
820
    beparam_variants = [
821
      None,
822
      {},
823
      { constants.BE_VCPUS: 2, },
824
      { constants.BE_MAXMEM: 200, },
825
      { constants.BE_MEMORY: 256, },
826
      { constants.BE_VCPUS: 2,
827
        constants.BE_MAXMEM: 1024,
828
        constants.BE_MINMEM: 1024,
829
        constants.BE_AUTO_BALANCE: True,
830
        constants.BE_ALWAYS_FAILOVER: True, }
831
      ]
832

    
833
    hvparam_variants = [
834
      None,
835
      { constants.HV_BOOT_ORDER: "anc", },
836
      { constants.HV_KERNEL_PATH: "/boot/fookernel",
837
        constants.HV_ROOT_PATH: "/dev/hda1", },
838
      ]
839

    
840
    for mode in [constants.INSTANCE_CREATE, constants.INSTANCE_IMPORT]:
841
      for nics in nic_variants:
842
        for disk_template in constants.DISK_TEMPLATES:
843
          for disks in disk_variants:
844
            for beparams in beparam_variants:
845
              for hvparams in hvparam_variants:
846
                for dry_run in [False, True]:
847
                  queryargs = {
848
                    "dry-run": str(int(dry_run)),
849
                    }
850

    
851
                  data = {
852
                    rlib2._REQ_DATA_VERSION: 1,
853
                    "name": name,
854
                    "hypervisor": constants.HT_FAKE,
855
                    "disks": disks,
856
                    "nics": nics,
857
                    "mode": mode,
858
                    "disk_template": disk_template,
859
                    "os": "debootstrap",
860
                    }
861

    
862
                  if beparams is not None:
863
                    data["beparams"] = beparams
864

    
865
                  if hvparams is not None:
866
                    data["hvparams"] = hvparams
867

    
868
                  handler = _CreateHandler(rlib2.R_2_instances, [],
869
                                           queryargs, data, clfactory)
870
                  job_id = handler.POST()
871

    
872
                  cl = clfactory.GetNextClient()
873
                  self.assertRaises(IndexError, clfactory.GetNextClient)
874

    
875
                  (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
876
                  self.assertEqual(job_id, exp_job_id)
877
                  self.assertRaises(IndexError, cl.GetNextSubmittedJob)
878

    
879
                  self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
880
                  self.assertEqual(op.instance_name, name)
881
                  self.assertEqual(op.mode, mode)
882
                  self.assertEqual(op.disk_template, disk_template)
883
                  self.assertEqual(op.dry_run, dry_run)
884
                  self.assertEqual(len(op.disks), len(disks))
885
                  self.assertEqual(len(op.nics), len(nics))
886

    
887
                  for opdisk, disk in zip(op.disks, disks):
888
                    for key in constants.IDISK_PARAMS:
889
                      self.assertEqual(opdisk.get(key), disk.get(key))
890
                    self.assertFalse("unknown" in opdisk)
891

    
892
                  for opnic, nic in zip(op.nics, nics):
893
                    for key in constants.INIC_PARAMS:
894
                      self.assertEqual(opnic.get(key), nic.get(key))
895
                    self.assertFalse("unknown" in opnic)
896
                    self.assertFalse("foobar" in opnic)
897

    
898
                  if beparams is None:
899
                    self.assertFalse(hasattr(op, "beparams"))
900
                  else:
901
                    self.assertEqualValues(op.beparams, beparams)
902

    
903
                  if hvparams is None:
904
                    self.assertFalse(hasattr(op, "hvparams"))
905
                  else:
906
                    self.assertEqualValues(op.hvparams, hvparams)
907

    
908
  def testLegacyName(self):
909
    clfactory = _FakeClientFactory(_FakeClient)
910

    
911
    name = "inst29128.example.com"
912
    data = {
913
      rlib2._REQ_DATA_VERSION: 1,
914
      "name": name,
915
      "disks": [],
916
      "nics": [],
917
      "mode": constants.INSTANCE_CREATE,
918
      "disk_template": constants.DT_PLAIN,
919
      }
920

    
921
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
922
    job_id = handler.POST()
923

    
924
    cl = clfactory.GetNextClient()
925
    self.assertRaises(IndexError, clfactory.GetNextClient)
926

    
927
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
928
    self.assertEqual(job_id, exp_job_id)
929
    self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
930
    self.assertEqual(op.instance_name, name)
931
    self.assertFalse(hasattr(op, "name"))
932
    self.assertFalse(op.dry_run)
933

    
934
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
935

    
936
    # Define both
937
    data["instance_name"] = "other.example.com"
938
    assert "name" in data and "instance_name" in data
939
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
940
    self.assertRaises(http.HttpBadRequest, handler.POST)
941
    self.assertRaises(IndexError, clfactory.GetNextClient)
942

    
943
  def testLegacyOs(self):
944
    clfactory = _FakeClientFactory(_FakeClient)
945

    
946
    name = "inst4673.example.com"
947
    os = "linux29206"
948
    data = {
949
      rlib2._REQ_DATA_VERSION: 1,
950
      "name": name,
951
      "os_type": os,
952
      "disks": [],
953
      "nics": [],
954
      "mode": constants.INSTANCE_CREATE,
955
      "disk_template": constants.DT_PLAIN,
956
      }
957

    
958
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
959
    job_id = handler.POST()
960

    
961
    cl = clfactory.GetNextClient()
962
    self.assertRaises(IndexError, clfactory.GetNextClient)
963

    
964
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
965
    self.assertEqual(job_id, exp_job_id)
966
    self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
967
    self.assertEqual(op.instance_name, name)
968
    self.assertEqual(op.os_type, os)
969
    self.assertFalse(hasattr(op, "os"))
970
    self.assertFalse(op.dry_run)
971

    
972
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
973

    
974
    # Define both
975
    data["os"] = "linux9584"
976
    assert "os" in data and "os_type" in data
977
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
978
    self.assertRaises(http.HttpBadRequest, handler.POST)
979

    
980
  def testErrors(self):
981
    clfactory = _FakeClientFactory(_FakeClient)
982

    
983
    # Test all required fields
984
    reqfields = {
985
      rlib2._REQ_DATA_VERSION: 1,
986
      "name": "inst1.example.com",
987
      "disks": [],
988
      "nics": [],
989
      "mode": constants.INSTANCE_CREATE,
990
      "disk_template": constants.DT_PLAIN,
991
      }
992

    
993
    for name in reqfields.keys():
994
      data = dict(i for i in reqfields.iteritems() if i[0] != name)
995

    
996
      handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
997
      self.assertRaises(http.HttpBadRequest, handler.POST)
998
      self.assertRaises(IndexError, clfactory.GetNextClient)
999

    
1000
    # Invalid disks and nics
1001
    for field in ["disks", "nics"]:
1002
      invalid_values = [None, 1, "", {}, [1, 2, 3], ["hda1", "hda2"],
1003
                        [{"_unknown_": 999, }]]
1004

    
1005
      for invvalue in invalid_values:
1006
        data = reqfields.copy()
1007
        data[field] = invvalue
1008
        handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1009
        self.assertRaises(http.HttpBadRequest, handler.POST)
1010
        self.assertRaises(IndexError, clfactory.GetNextClient)
1011

    
1012
  def testVersion(self):
1013
    clfactory = _FakeClientFactory(_FakeClient)
1014

    
1015
    # No version field
1016
    data = {
1017
      "name": "inst1.example.com",
1018
      "disks": [],
1019
      "nics": [],
1020
      "mode": constants.INSTANCE_CREATE,
1021
      "disk_template": constants.DT_PLAIN,
1022
      }
1023

    
1024
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1025
    self.assertRaises(http.HttpBadRequest, handler.POST)
1026

    
1027
    # Old and incorrect versions
1028
    for version in [0, -1, 10483, "Hello World"]:
1029
      data[rlib2._REQ_DATA_VERSION] = version
1030

    
1031
      handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1032
      self.assertRaises(http.HttpBadRequest, handler.POST)
1033

    
1034
      self.assertRaises(IndexError, clfactory.GetNextClient)
1035

    
1036
    # Correct version
1037
    data[rlib2._REQ_DATA_VERSION] = 1
1038
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1039
    job_id = handler.POST()
1040

    
1041
    cl = clfactory.GetNextClient()
1042
    self.assertRaises(IndexError, clfactory.GetNextClient)
1043

    
1044
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1045
    self.assertEqual(job_id, exp_job_id)
1046
    self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
1047
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1048

    
1049

    
1050
class TestBackupExport(unittest.TestCase):
1051
  def test(self):
1052
    clfactory = _FakeClientFactory(_FakeClient)
1053

    
1054
    name = "instmoo"
1055
    data = {
1056
      "mode": constants.EXPORT_MODE_REMOTE,
1057
      "destination": [(1, 2, 3), (99, 99, 99)],
1058
      "shutdown": True,
1059
      "remove_instance": True,
1060
      "x509_key_name": ["name", "hash"],
1061
      "destination_x509_ca": "---cert---"
1062
      }
1063

    
1064
    handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
1065
                             data, clfactory)
1066
    job_id = handler.PUT()
1067

    
1068
    cl = clfactory.GetNextClient()
1069
    self.assertRaises(IndexError, clfactory.GetNextClient)
1070

    
1071
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1072
    self.assertEqual(job_id, exp_job_id)
1073
    self.assertTrue(isinstance(op, opcodes.OpBackupExport))
1074
    self.assertEqual(op.instance_name, name)
1075
    self.assertEqual(op.mode, constants.EXPORT_MODE_REMOTE)
1076
    self.assertEqual(op.target_node, [(1, 2, 3), (99, 99, 99)])
1077
    self.assertEqual(op.shutdown, True)
1078
    self.assertEqual(op.remove_instance, True)
1079
    self.assertEqual(op.x509_key_name, ["name", "hash"])
1080
    self.assertEqual(op.destination_x509_ca, "---cert---")
1081
    self.assertFalse(hasattr(op, "dry_run"))
1082
    self.assertFalse(hasattr(op, "force"))
1083

    
1084
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1085

    
1086
  def testDefaults(self):
1087
    clfactory = _FakeClientFactory(_FakeClient)
1088

    
1089
    name = "inst1"
1090
    data = {
1091
      "destination": "node2",
1092
      "shutdown": False,
1093
      }
1094

    
1095
    handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
1096
                             data, clfactory)
1097
    job_id = handler.PUT()
1098

    
1099
    cl = clfactory.GetNextClient()
1100
    self.assertRaises(IndexError, clfactory.GetNextClient)
1101

    
1102
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1103
    self.assertEqual(job_id, exp_job_id)
1104
    self.assertTrue(isinstance(op, opcodes.OpBackupExport))
1105
    self.assertEqual(op.instance_name, name)
1106
    self.assertEqual(op.target_node, "node2")
1107
    self.assertFalse(hasattr(op, "mode"))
1108
    self.assertFalse(hasattr(op, "remove_instance"))
1109
    self.assertFalse(hasattr(op, "destination"))
1110
    self.assertFalse(hasattr(op, "dry_run"))
1111
    self.assertFalse(hasattr(op, "force"))
1112

    
1113
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1114

    
1115
  def testErrors(self):
1116
    clfactory = _FakeClientFactory(_FakeClient)
1117

    
1118
    for value in ["True", "False"]:
1119
      handler = _CreateHandler(rlib2.R_2_instances_name_export, ["err1"], {}, {
1120
        "remove_instance": value,
1121
        }, clfactory)
1122
      self.assertRaises(http.HttpBadRequest, handler.PUT)
1123

    
1124

    
1125
class TestInstanceMigrate(testutils.GanetiTestCase):
1126
  def test(self):
1127
    clfactory = _FakeClientFactory(_FakeClient)
1128

    
1129
    name = "instYooho6ek"
1130

    
1131
    for cleanup in [False, True]:
1132
      for mode in constants.HT_MIGRATION_MODES:
1133
        data = {
1134
          "cleanup": cleanup,
1135
          "mode": mode,
1136
          }
1137

    
1138
        handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {},
1139
                                 data, clfactory)
1140
        job_id = handler.PUT()
1141

    
1142
        cl = clfactory.GetNextClient()
1143
        self.assertRaises(IndexError, clfactory.GetNextClient)
1144

    
1145
        (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1146
        self.assertEqual(job_id, exp_job_id)
1147
        self.assertTrue(isinstance(op, opcodes.OpInstanceMigrate))
1148
        self.assertEqual(op.instance_name, name)
1149
        self.assertEqual(op.mode, mode)
1150
        self.assertEqual(op.cleanup, cleanup)
1151
        self.assertFalse(hasattr(op, "dry_run"))
1152
        self.assertFalse(hasattr(op, "force"))
1153

    
1154
        self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1155

    
1156
  def testDefaults(self):
1157
    clfactory = _FakeClientFactory(_FakeClient)
1158

    
1159
    name = "instnohZeex0"
1160

    
1161
    handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {}, {},
1162
                             clfactory)
1163
    job_id = handler.PUT()
1164

    
1165
    cl = clfactory.GetNextClient()
1166
    self.assertRaises(IndexError, clfactory.GetNextClient)
1167

    
1168
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1169
    self.assertEqual(job_id, exp_job_id)
1170
    self.assertTrue(isinstance(op, opcodes.OpInstanceMigrate))
1171
    self.assertEqual(op.instance_name, name)
1172
    self.assertFalse(hasattr(op, "mode"))
1173
    self.assertFalse(hasattr(op, "cleanup"))
1174
    self.assertFalse(hasattr(op, "dry_run"))
1175
    self.assertFalse(hasattr(op, "force"))
1176

    
1177
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1178

    
1179

    
1180
class TestParseRenameInstanceRequest(testutils.GanetiTestCase):
1181
  def test(self):
1182
    clfactory = _FakeClientFactory(_FakeClient)
1183

    
1184
    name = "instij0eeph7"
1185

    
1186
    for new_name in ["ua0aiyoo", "fai3ongi"]:
1187
      for ip_check in [False, True]:
1188
        for name_check in [False, True]:
1189
          data = {
1190
            "new_name": new_name,
1191
            "ip_check": ip_check,
1192
            "name_check": name_check,
1193
            }
1194

    
1195
          handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
1196
                                   {}, data, clfactory)
1197
          job_id = handler.PUT()
1198

    
1199
          cl = clfactory.GetNextClient()
1200
          self.assertRaises(IndexError, clfactory.GetNextClient)
1201

    
1202
          (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1203
          self.assertEqual(job_id, exp_job_id)
1204
          self.assertTrue(isinstance(op, opcodes.OpInstanceRename))
1205
          self.assertEqual(op.instance_name, name)
1206
          self.assertEqual(op.new_name, new_name)
1207
          self.assertEqual(op.ip_check, ip_check)
1208
          self.assertEqual(op.name_check, name_check)
1209
          self.assertFalse(hasattr(op, "dry_run"))
1210
          self.assertFalse(hasattr(op, "force"))
1211

    
1212
          self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1213

    
1214
  def testDefaults(self):
1215
    clfactory = _FakeClientFactory(_FakeClient)
1216

    
1217
    name = "instahchie3t"
1218

    
1219
    for new_name in ["thag9mek", "quees7oh"]:
1220
      data = {
1221
        "new_name": new_name,
1222
        }
1223

    
1224
      handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
1225
                               {}, data, clfactory)
1226
      job_id = handler.PUT()
1227

    
1228
      cl = clfactory.GetNextClient()
1229
      self.assertRaises(IndexError, clfactory.GetNextClient)
1230

    
1231
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1232
      self.assertEqual(job_id, exp_job_id)
1233
      self.assertTrue(isinstance(op, opcodes.OpInstanceRename))
1234
      self.assertEqual(op.instance_name, name)
1235
      self.assertEqual(op.new_name, new_name)
1236
      self.assertFalse(hasattr(op, "ip_check"))
1237
      self.assertFalse(hasattr(op, "name_check"))
1238
      self.assertFalse(hasattr(op, "dry_run"))
1239
      self.assertFalse(hasattr(op, "force"))
1240

    
1241
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1242

    
1243

    
1244
class TestParseModifyInstanceRequest(unittest.TestCase):
1245
  def test(self):
1246
    clfactory = _FakeClientFactory(_FakeClient)
1247

    
1248
    name = "instush8gah"
1249

    
1250
    test_disks = [
1251
      [],
1252
      [(1, { constants.IDISK_MODE: constants.DISK_RDWR, })],
1253
      ]
1254

    
1255
    for osparams in [{}, { "some": "value", "other": "Hello World", }]:
1256
      for hvparams in [{}, { constants.HV_KERNEL_PATH: "/some/kernel", }]:
1257
        for beparams in [{}, { constants.BE_MAXMEM: 128, }]:
1258
          for force in [False, True]:
1259
            for nics in [[], [(0, { constants.INIC_IP: "192.0.2.1", })]]:
1260
              for disks in test_disks:
1261
                for disk_template in constants.DISK_TEMPLATES:
1262
                  data = {
1263
                    "osparams": osparams,
1264
                    "hvparams": hvparams,
1265
                    "beparams": beparams,
1266
                    "nics": nics,
1267
                    "disks": disks,
1268
                    "force": force,
1269
                    "disk_template": disk_template,
1270
                    }
1271

    
1272
                  handler = _CreateHandler(rlib2.R_2_instances_name_modify,
1273
                                           [name], {}, data, clfactory)
1274
                  job_id = handler.PUT()
1275

    
1276
                  cl = clfactory.GetNextClient()
1277
                  self.assertRaises(IndexError, clfactory.GetNextClient)
1278

    
1279
                  (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1280
                  self.assertEqual(job_id, exp_job_id)
1281
                  self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
1282
                  self.assertEqual(op.instance_name, name)
1283
                  self.assertEqual(op.hvparams, hvparams)
1284
                  self.assertEqual(op.beparams, beparams)
1285
                  self.assertEqual(op.osparams, osparams)
1286
                  self.assertEqual(op.force, force)
1287
                  self.assertEqual(op.nics, nics)
1288
                  self.assertEqual(op.disks, disks)
1289
                  self.assertEqual(op.disk_template, disk_template)
1290
                  self.assertFalse(hasattr(op, "remote_node"))
1291
                  self.assertFalse(hasattr(op, "os_name"))
1292
                  self.assertFalse(hasattr(op, "force_variant"))
1293
                  self.assertFalse(hasattr(op, "dry_run"))
1294

    
1295
                  self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1296

    
1297
  def testDefaults(self):
1298
    clfactory = _FakeClientFactory(_FakeClient)
1299

    
1300
    name = "instir8aish31"
1301

    
1302
    handler = _CreateHandler(rlib2.R_2_instances_name_modify,
1303
                             [name], {}, {}, clfactory)
1304
    job_id = handler.PUT()
1305

    
1306
    cl = clfactory.GetNextClient()
1307
    self.assertRaises(IndexError, clfactory.GetNextClient)
1308

    
1309
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1310
    self.assertEqual(job_id, exp_job_id)
1311
    self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
1312
    self.assertEqual(op.instance_name, name)
1313

    
1314
    for i in ["hvparams", "beparams", "osparams", "force", "nics", "disks",
1315
              "disk_template", "remote_node", "os_name", "force_variant"]:
1316
      self.assertFalse(hasattr(op, i))
1317

    
1318

    
1319
class TestParseInstanceReinstallRequest(testutils.GanetiTestCase):
1320
  def setUp(self):
1321
    testutils.GanetiTestCase.setUp(self)
1322

    
1323
    self.Parse = rlib2._ParseInstanceReinstallRequest
1324

    
1325
  def _Check(self, ops, name):
1326
    expcls = [
1327
      opcodes.OpInstanceShutdown,
1328
      opcodes.OpInstanceReinstall,
1329
      opcodes.OpInstanceStartup,
1330
      ]
1331

    
1332
    self.assert_(compat.all(isinstance(op, exp)
1333
                            for op, exp in zip(ops, expcls)))
1334
    self.assert_(compat.all(op.instance_name == name for op in ops))
1335

    
1336
  def test(self):
1337
    name = "shoo0tihohma"
1338

    
1339
    ops = self.Parse(name, {"os": "sys1", "start": True,})
1340
    self.assertEqual(len(ops), 3)
1341
    self._Check(ops, name)
1342
    self.assertEqual(ops[1].os_type, "sys1")
1343
    self.assertFalse(ops[1].osparams)
1344

    
1345
    ops = self.Parse(name, {"os": "sys2", "start": False,})
1346
    self.assertEqual(len(ops), 2)
1347
    self._Check(ops, name)
1348
    self.assertEqual(ops[1].os_type, "sys2")
1349

    
1350
    osparams = {
1351
      "reformat": "1",
1352
      }
1353
    ops = self.Parse(name, {"os": "sys4035", "start": True,
1354
                            "osparams": osparams,})
1355
    self.assertEqual(len(ops), 3)
1356
    self._Check(ops, name)
1357
    self.assertEqual(ops[1].os_type, "sys4035")
1358
    self.assertEqual(ops[1].osparams, osparams)
1359

    
1360
  def testDefaults(self):
1361
    name = "noolee0g"
1362

    
1363
    ops = self.Parse(name, {"os": "linux1"})
1364
    self.assertEqual(len(ops), 3)
1365
    self._Check(ops, name)
1366
    self.assertEqual(ops[1].os_type, "linux1")
1367
    self.assertFalse(ops[1].osparams)
1368

    
1369
  def testErrors(self):
1370
    self.assertRaises(http.HttpBadRequest, self.Parse,
1371
                      "foo", "not a dictionary")
1372

    
1373

    
1374
class TestGroupRename(unittest.TestCase):
1375
  def test(self):
1376
    clfactory = _FakeClientFactory(_FakeClient)
1377

    
1378
    name = "group608242564"
1379
    data = {
1380
      "new_name": "ua0aiyoo15112",
1381
      }
1382

    
1383
    handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {}, data,
1384
                             clfactory)
1385
    job_id = handler.PUT()
1386

    
1387
    cl = clfactory.GetNextClient()
1388
    self.assertRaises(IndexError, clfactory.GetNextClient)
1389

    
1390
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1391
    self.assertEqual(job_id, exp_job_id)
1392

    
1393
    self.assertTrue(isinstance(op, opcodes.OpGroupRename))
1394
    self.assertEqual(op.group_name, name)
1395
    self.assertEqual(op.new_name, "ua0aiyoo15112")
1396
    self.assertFalse(op.dry_run)
1397
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1398

    
1399
  def testDryRun(self):
1400
    clfactory = _FakeClientFactory(_FakeClient)
1401

    
1402
    name = "group28548"
1403
    data = {
1404
      "new_name": "ua0aiyoo",
1405
      }
1406

    
1407
    handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {
1408
      "dry-run": ["1"],
1409
      }, data, clfactory)
1410
    job_id = handler.PUT()
1411

    
1412
    cl = clfactory.GetNextClient()
1413
    self.assertRaises(IndexError, clfactory.GetNextClient)
1414

    
1415
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1416
    self.assertEqual(job_id, exp_job_id)
1417

    
1418
    self.assertTrue(isinstance(op, opcodes.OpGroupRename))
1419
    self.assertEqual(op.group_name, name)
1420
    self.assertEqual(op.new_name, "ua0aiyoo")
1421
    self.assertTrue(op.dry_run)
1422
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1423

    
1424

    
1425
class TestInstanceReplaceDisks(unittest.TestCase):
1426
  def test(self):
1427
    clfactory = _FakeClientFactory(_FakeClient)
1428

    
1429
    name = "inst22568"
1430

    
1431
    for disks in [range(1, 4), "1,2,3", "1, 2, 3"]:
1432
      data = {
1433
        "mode": constants.REPLACE_DISK_SEC,
1434
        "disks": disks,
1435
        "iallocator": "myalloc",
1436
        }
1437

    
1438
      handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1439
                               [name], {}, data, clfactory)
1440
      job_id = handler.POST()
1441

    
1442
      cl = clfactory.GetNextClient()
1443
      self.assertRaises(IndexError, clfactory.GetNextClient)
1444

    
1445
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1446
      self.assertEqual(job_id, exp_job_id)
1447

    
1448
      self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
1449
      self.assertEqual(op.instance_name, name)
1450
      self.assertEqual(op.mode, constants.REPLACE_DISK_SEC)
1451
      self.assertEqual(op.disks, [1, 2, 3])
1452
      self.assertEqual(op.iallocator, "myalloc")
1453
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1454

    
1455
  def testDefaults(self):
1456
    clfactory = _FakeClientFactory(_FakeClient)
1457

    
1458
    name = "inst11413"
1459
    data = {
1460
      "mode": constants.REPLACE_DISK_AUTO,
1461
      }
1462

    
1463
    handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1464
                             [name], {}, data, clfactory)
1465
    job_id = handler.POST()
1466

    
1467
    cl = clfactory.GetNextClient()
1468
    self.assertRaises(IndexError, clfactory.GetNextClient)
1469

    
1470
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1471
    self.assertEqual(job_id, exp_job_id)
1472

    
1473
    self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
1474
    self.assertEqual(op.instance_name, name)
1475
    self.assertEqual(op.mode, constants.REPLACE_DISK_AUTO)
1476
    self.assertFalse(hasattr(op, "iallocator"))
1477
    self.assertFalse(hasattr(op, "disks"))
1478
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1479

    
1480
  def testNoDisks(self):
1481
    clfactory = _FakeClientFactory(_FakeClient)
1482

    
1483
    handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1484
                             ["inst20661"], {}, {}, clfactory)
1485
    self.assertRaises(http.HttpBadRequest, handler.POST)
1486

    
1487
    for disks in [None, "", {}]:
1488
      handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1489
                               ["inst20661"], {}, {
1490
        "disks": disks,
1491
        }, clfactory)
1492
      self.assertRaises(http.HttpBadRequest, handler.POST)
1493

    
1494
  def testWrong(self):
1495
    clfactory = _FakeClientFactory(_FakeClient)
1496

    
1497
    data = {
1498
      "mode": constants.REPLACE_DISK_AUTO,
1499
      "disks": "hello world",
1500
      }
1501

    
1502
    handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1503
                             ["foo"], {}, data, clfactory)
1504
    self.assertRaises(http.HttpBadRequest, handler.POST)
1505

    
1506

    
1507
class TestGroupModify(unittest.TestCase):
1508
  def test(self):
1509
    clfactory = _FakeClientFactory(_FakeClient)
1510

    
1511
    name = "group6002"
1512

    
1513
    for policy in constants.VALID_ALLOC_POLICIES:
1514
      data = {
1515
        "alloc_policy": policy,
1516
        }
1517

    
1518
      handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, data,
1519
                               clfactory)
1520
      job_id = handler.PUT()
1521

    
1522
      cl = clfactory.GetNextClient()
1523
      self.assertRaises(IndexError, clfactory.GetNextClient)
1524

    
1525
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1526
      self.assertEqual(job_id, exp_job_id)
1527

    
1528
      self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
1529
      self.assertEqual(op.group_name, name)
1530
      self.assertEqual(op.alloc_policy, policy)
1531
      self.assertFalse(hasattr(op, "dry_run"))
1532
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1533

    
1534
  def testUnknownPolicy(self):
1535
    clfactory = _FakeClientFactory(_FakeClient)
1536

    
1537
    data = {
1538
      "alloc_policy": "_unknown_policy_",
1539
      }
1540

    
1541
    handler = _CreateHandler(rlib2.R_2_groups_name_modify, ["xyz"], {}, data,
1542
                             clfactory)
1543
    self.assertRaises(http.HttpBadRequest, handler.PUT)
1544
    self.assertRaises(IndexError, clfactory.GetNextClient)
1545

    
1546
  def testDefaults(self):
1547
    clfactory = _FakeClientFactory(_FakeClient)
1548

    
1549
    name = "group6679"
1550

    
1551
    handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, {},
1552
                             clfactory)
1553
    job_id = handler.PUT()
1554

    
1555
    cl = clfactory.GetNextClient()
1556
    self.assertRaises(IndexError, clfactory.GetNextClient)
1557

    
1558
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1559
    self.assertEqual(job_id, exp_job_id)
1560

    
1561
    self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
1562
    self.assertEqual(op.group_name, name)
1563
    self.assertFalse(hasattr(op, "alloc_policy"))
1564
    self.assertFalse(hasattr(op, "dry_run"))
1565
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1566

    
1567

    
1568
class TestGroupAdd(unittest.TestCase):
1569
  def test(self):
1570
    name = "group3618"
1571
    clfactory = _FakeClientFactory(_FakeClient)
1572

    
1573
    for policy in constants.VALID_ALLOC_POLICIES:
1574
      data = {
1575
        "group_name": name,
1576
        "alloc_policy": policy,
1577
        }
1578

    
1579
      handler = _CreateHandler(rlib2.R_2_groups, [], {}, data,
1580
                               clfactory)
1581
      job_id = handler.POST()
1582

    
1583
      cl = clfactory.GetNextClient()
1584
      self.assertRaises(IndexError, clfactory.GetNextClient)
1585

    
1586
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1587
      self.assertEqual(job_id, exp_job_id)
1588

    
1589
      self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1590
      self.assertEqual(op.group_name, name)
1591
      self.assertEqual(op.alloc_policy, policy)
1592
      self.assertFalse(op.dry_run)
1593
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1594

    
1595
  def testUnknownPolicy(self):
1596
    clfactory = _FakeClientFactory(_FakeClient)
1597

    
1598
    data = {
1599
      "alloc_policy": "_unknown_policy_",
1600
      }
1601

    
1602
    handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1603
    self.assertRaises(http.HttpBadRequest, handler.POST)
1604
    self.assertRaises(IndexError, clfactory.GetNextClient)
1605

    
1606
  def testDefaults(self):
1607
    clfactory = _FakeClientFactory(_FakeClient)
1608

    
1609
    name = "group15395"
1610
    data = {
1611
      "group_name": name,
1612
      }
1613

    
1614
    handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1615
    job_id = handler.POST()
1616

    
1617
    cl = clfactory.GetNextClient()
1618
    self.assertRaises(IndexError, clfactory.GetNextClient)
1619

    
1620
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1621
    self.assertEqual(job_id, exp_job_id)
1622

    
1623
    self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1624
    self.assertEqual(op.group_name, name)
1625
    self.assertFalse(hasattr(op, "alloc_policy"))
1626
    self.assertFalse(op.dry_run)
1627

    
1628
  def testLegacyName(self):
1629
    clfactory = _FakeClientFactory(_FakeClient)
1630

    
1631
    name = "group29852"
1632
    data = {
1633
      "name": name,
1634
      }
1635

    
1636
    handler = _CreateHandler(rlib2.R_2_groups, [], {
1637
      "dry-run": ["1"],
1638
      }, data, clfactory)
1639
    job_id = handler.POST()
1640

    
1641
    cl = clfactory.GetNextClient()
1642
    self.assertRaises(IndexError, clfactory.GetNextClient)
1643

    
1644
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1645
    self.assertEqual(job_id, exp_job_id)
1646

    
1647
    self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1648
    self.assertEqual(op.group_name, name)
1649
    self.assertFalse(hasattr(op, "alloc_policy"))
1650
    self.assertTrue(op.dry_run)
1651

    
1652

    
1653
class TestNodeRole(unittest.TestCase):
1654
  def test(self):
1655
    clfactory = _FakeClientFactory(_FakeClient)
1656

    
1657
    for role in rlib2._NR_MAP.values():
1658
      handler = _CreateHandler(rlib2.R_2_nodes_name_role,
1659
                               ["node-z"], {}, role, clfactory)
1660
      if role == rlib2._NR_MASTER:
1661
        self.assertRaises(http.HttpBadRequest, handler.PUT)
1662
      else:
1663
        job_id = handler.PUT()
1664

    
1665
        cl = clfactory.GetNextClient()
1666
        self.assertRaises(IndexError, clfactory.GetNextClient)
1667

    
1668
        (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1669
        self.assertEqual(job_id, exp_job_id)
1670
        self.assertTrue(isinstance(op, opcodes.OpNodeSetParams))
1671
        self.assertEqual(op.node_name, "node-z")
1672
        self.assertFalse(op.force)
1673
        self.assertFalse(hasattr(op, "dry_run"))
1674

    
1675
        if role == rlib2._NR_REGULAR:
1676
          self.assertFalse(op.drained)
1677
          self.assertFalse(op.offline)
1678
          self.assertFalse(op.master_candidate)
1679
        elif role == rlib2._NR_MASTER_CANDIDATE:
1680
          self.assertFalse(op.drained)
1681
          self.assertFalse(op.offline)
1682
          self.assertTrue(op.master_candidate)
1683
        elif role == rlib2._NR_DRAINED:
1684
          self.assertTrue(op.drained)
1685
          self.assertFalse(op.offline)
1686
          self.assertFalse(op.master_candidate)
1687
        elif role == rlib2._NR_OFFLINE:
1688
          self.assertFalse(op.drained)
1689
          self.assertTrue(op.offline)
1690
          self.assertFalse(op.master_candidate)
1691
        else:
1692
          self.fail("Unknown role '%s'" % role)
1693

    
1694
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1695

    
1696

    
1697
class TestSimpleResources(unittest.TestCase):
1698
  def setUp(self):
1699
    self.clfactory = _FakeClientFactory(_FakeClient)
1700

    
1701
  def tearDown(self):
1702
    self.assertRaises(IndexError, self.clfactory.GetNextClient)
1703

    
1704
  def testFeatures(self):
1705
    handler = _CreateHandler(rlib2.R_2_features, [], {}, None, self.clfactory)
1706
    self.assertEqual(set(handler.GET()), rlib2.ALL_FEATURES)
1707

    
1708
  def testEmpty(self):
1709
    for cls in [rlib2.R_root, rlib2.R_2]:
1710
      handler = _CreateHandler(cls, [], {}, None, self.clfactory)
1711
      self.assertTrue(handler.GET() is None)
1712

    
1713
  def testVersion(self):
1714
    handler = _CreateHandler(rlib2.R_version, [], {}, None, self.clfactory)
1715
    self.assertEqual(handler.GET(), constants.RAPI_VERSION)
1716

    
1717

    
1718
class TestClusterInfo(unittest.TestCase):
1719
  class _ClusterInfoClient:
1720
    def __init__(self, address=None):
1721
      self.cluster_info = None
1722

    
1723
    def QueryClusterInfo(self):
1724
      assert self.cluster_info is None
1725
      self.cluster_info = object()
1726
      return self.cluster_info
1727

    
1728
  def test(self):
1729
    clfactory = _FakeClientFactory(self._ClusterInfoClient)
1730
    handler = _CreateHandler(rlib2.R_2_info, [], {}, None, clfactory)
1731
    result = handler.GET()
1732
    cl = clfactory.GetNextClient()
1733
    self.assertRaises(IndexError, clfactory.GetNextClient)
1734
    self.assertEqual(result, cl.cluster_info)
1735

    
1736

    
1737
if __name__ == '__main__':
1738
  testutils.GanetiTestProgram()