Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.rapi.rlib2_unittest.py @ bebe7a73

History | View | Annotate | Download (55.8 kB)

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

    
4
# Copyright (C) 2010 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):
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):
81
    cl = self._client_cls()
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():
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
    @staticmethod
123
    def SubmitJob(ops):
124
      raise errors.JobQueueFull("test")
125

    
126
  def test(self):
127
    handler = _CreateHandler(rlib2.R_2_redist_config, [], [], None,
128
                             self._SubmitErrorClient)
129
    self.assertRaises(http.HttpServiceUnavailable, handler.PUT)
130

    
131

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

    
141
    cl = clfactory.GetNextClient()
142
    self.assertRaises(IndexError, clfactory.GetNextClient)
143

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

    
150
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
151

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

    
161

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

    
168
    cl = clfactory.GetNextClient()
169
    self.assertRaises(IndexError, clfactory.GetNextClient)
170

    
171
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
172
    self.assertEqual(job_id, exp_job_id)
173
    self.assertTrue(isinstance(op, opcodes.OpClusterRedistConf))
174

    
175
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
176

    
177

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

    
186
    cl = clfactory.GetNextClient()
187
    self.assertRaises(IndexError, clfactory.GetNextClient)
188

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

    
195
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
196

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

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

    
215
    cl = clfactory.GetNextClient()
216
    self.assertRaises(IndexError, clfactory.GetNextClient)
217

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

    
224
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
225

    
226
  def testQueryArgsLive(self):
227
    clfactory = _FakeClientFactory(_FakeClient)
228

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

    
237
      cl = clfactory.GetNextClient()
238
      self.assertRaises(IndexError, clfactory.GetNextClient)
239

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

    
249
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
250

    
251

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

    
262
    cl = clfactory.GetNextClient()
263
    self.assertRaises(IndexError, clfactory.GetNextClient)
264

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

    
272
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
273

    
274

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

    
283
    cl = clfactory.GetNextClient()
284
    self.assertRaises(IndexError, clfactory.GetNextClient)
285

    
286
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
287
    self.assertEqual(job_id, exp_job_id)
288
    self.assertTrue(isinstance(op, opcodes.OpNodePowercycle))
289
    self.assertEqual(op.node_name, "node20744")
290
    self.assertTrue(op.force)
291

    
292
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
293

    
294

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

    
306
    cl = clfactory.GetNextClient()
307
    self.assertRaises(IndexError, clfactory.GetNextClient)
308

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

    
317
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
318

    
319

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

    
328
    cl = clfactory.GetNextClient()
329
    self.assertRaises(IndexError, clfactory.GetNextClient)
330

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

    
338
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
339

    
340

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

    
349
    cl = clfactory.GetNextClient()
350
    self.assertRaises(IndexError, clfactory.GetNextClient)
351

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

    
358
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
359

    
360

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

    
370
    cl = clfactory.GetNextClient()
371
    self.assertRaises(IndexError, clfactory.GetNextClient)
372

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

    
381
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
382

    
383

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

    
393
    cl = clfactory.GetNextClient()
394
    self.assertRaises(IndexError, clfactory.GetNextClient)
395

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

    
404
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
405

    
406

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

    
415
    cl = clfactory.GetNextClient()
416
    self.assertRaises(IndexError, clfactory.GetNextClient)
417

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

    
425
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
426

    
427

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

    
436
    cl = clfactory.GetNextClient()
437
    self.assertRaises(IndexError, clfactory.GetNextClient)
438

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

    
446
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
447

    
448

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

    
456
    cl = clfactory.GetNextClient()
457
    self.assertRaises(IndexError, clfactory.GetNextClient)
458

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

    
466
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
467

    
468

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

    
476
    cl = clfactory.GetNextClient()
477
    self.assertRaises(IndexError, clfactory.GetNextClient)
478

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

    
486
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
487

    
488

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

    
496
    cl = clfactory.GetNextClient()
497
    self.assertRaises(IndexError, clfactory.GetNextClient)
498

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

    
506
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
507

    
508

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

    
519
    cl = clfactory.GetNextClient()
520
    self.assertRaises(IndexError, clfactory.GetNextClient)
521

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

    
531
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
532

    
533

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

    
544
    cl = clfactory.GetNextClient()
545
    self.assertRaises(IndexError, clfactory.GetNextClient)
546

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

    
555
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
556

    
557

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

    
565
    cl = clfactory.GetNextClient()
566
    self.assertRaises(IndexError, clfactory.GetNextClient)
567

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

    
575
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
576

    
577

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

    
589
    cl = clfactory.GetNextClient()
590
    self.assertRaises(IndexError, clfactory.GetNextClient)
591

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

    
601
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
602

    
603
  def testErrors(self):
604
    clfactory = _FakeClientFactory(_FakeClient)
605

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

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

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

    
628

    
629
class TestStorageModify(unittest.TestCase):
630
  def test(self):
631
    clfactory = _FakeClientFactory(_FakeClient)
632

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

    
639
      if allocatable is not None:
640
        queryargs["allocatable"] = allocatable
641

    
642
      handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
643
                               ["node9292"], queryargs, {}, clfactory)
644
      job_id = handler.PUT()
645

    
646
      cl = clfactory.GetNextClient()
647
      self.assertRaises(IndexError, clfactory.GetNextClient)
648

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

    
665
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
666

    
667
  def testErrors(self):
668
    clfactory = _FakeClientFactory(_FakeClient)
669

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

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

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

    
696

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

    
708
    cl = clfactory.GetNextClient()
709
    self.assertRaises(IndexError, clfactory.GetNextClient)
710

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

    
720
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
721

    
722
  def testErrors(self):
723
    clfactory = _FakeClientFactory(_FakeClient)
724

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

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

    
741

    
742
class TestTags(unittest.TestCase):
743
  TAG_HANDLERS = [
744
    rlib2.R_2_instances_name_tags,
745
    rlib2.R_2_nodes_name_tags,
746
    rlib2.R_2_groups_name_tags,
747
    rlib2.R_2_tags,
748
    ]
749

    
750
  def testSetAndDelete(self):
751
    clfactory = _FakeClientFactory(_FakeClient)
752

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

    
763
        handler = _CreateHandler(handler, [name], queryargs, {}, clfactory)
764
        job_id = getattr(handler, method)()
765

    
766
        cl = clfactory.GetNextClient()
767
        self.assertRaises(IndexError, clfactory.GetNextClient)
768

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

    
781
        self.assertRaises(IndexError, cl.GetNextSubmittedJob)
782

    
783

    
784
class TestInstanceCreation(testutils.GanetiTestCase):
785
  def test(self):
786
    clfactory = _FakeClientFactory(_FakeClient)
787

    
788
    name = "inst863.example.com"
789

    
790
    disk_variants = [
791
      # No disks
792
      [],
793

    
794
      # Two disks
795
      [{"size": 5, }, {"size": 100, }],
796

    
797
      # Disk with mode
798
      [{"size": 123, "mode": constants.DISK_RDWR, }],
799
      ]
800

    
801
    nic_variants = [
802
      # No NIC
803
      [],
804

    
805
      # Three NICs
806
      [{}, {}, {}],
807

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

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

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

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

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

    
859
                  if beparams is not None:
860
                    data["beparams"] = beparams
861

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

    
865
                  handler = _CreateHandler(rlib2.R_2_instances, [],
866
                                           queryargs, data, clfactory)
867
                  job_id = handler.POST()
868

    
869
                  cl = clfactory.GetNextClient()
870
                  self.assertRaises(IndexError, clfactory.GetNextClient)
871

    
872
                  (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
873
                  self.assertEqual(job_id, exp_job_id)
874
                  self.assertRaises(IndexError, cl.GetNextSubmittedJob)
875

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

    
884
                  for opdisk, disk in zip(op.disks, disks):
885
                    for key in constants.IDISK_PARAMS:
886
                      self.assertEqual(opdisk.get(key), disk.get(key))
887
                    self.assertFalse("unknown" in opdisk)
888

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

    
895
                  if beparams is None:
896
                    self.assertFalse(hasattr(op, "beparams"))
897
                  else:
898
                    self.assertEqualValues(op.beparams, beparams)
899

    
900
                  if hvparams is None:
901
                    self.assertFalse(hasattr(op, "hvparams"))
902
                  else:
903
                    self.assertEqualValues(op.hvparams, hvparams)
904

    
905
  def testLegacyName(self):
906
    clfactory = _FakeClientFactory(_FakeClient)
907

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

    
918
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
919
    job_id = handler.POST()
920

    
921
    cl = clfactory.GetNextClient()
922
    self.assertRaises(IndexError, clfactory.GetNextClient)
923

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

    
931
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
932

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

    
940
  def testLegacyOs(self):
941
    clfactory = _FakeClientFactory(_FakeClient)
942

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

    
955
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
956
    job_id = handler.POST()
957

    
958
    cl = clfactory.GetNextClient()
959
    self.assertRaises(IndexError, clfactory.GetNextClient)
960

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

    
969
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
970

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

    
977
  def testErrors(self):
978
    clfactory = _FakeClientFactory(_FakeClient)
979

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

    
990
    for name in reqfields.keys():
991
      data = dict(i for i in reqfields.iteritems() if i[0] != name)
992

    
993
      handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
994
      self.assertRaises(http.HttpBadRequest, handler.POST)
995
      self.assertRaises(IndexError, clfactory.GetNextClient)
996

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

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

    
1009
  def testVersion(self):
1010
    clfactory = _FakeClientFactory(_FakeClient)
1011

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

    
1021
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1022
    self.assertRaises(http.HttpBadRequest, handler.POST)
1023

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

    
1028
      handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1029
      self.assertRaises(http.HttpBadRequest, handler.POST)
1030

    
1031
      self.assertRaises(IndexError, clfactory.GetNextClient)
1032

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

    
1038
    cl = clfactory.GetNextClient()
1039
    self.assertRaises(IndexError, clfactory.GetNextClient)
1040

    
1041
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1042
    self.assertEqual(job_id, exp_job_id)
1043
    self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
1044
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1045

    
1046

    
1047
class TestBackupExport(unittest.TestCase):
1048
  def test(self):
1049
    clfactory = _FakeClientFactory(_FakeClient)
1050

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

    
1061
    handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
1062
                             data, clfactory)
1063
    job_id = handler.PUT()
1064

    
1065
    cl = clfactory.GetNextClient()
1066
    self.assertRaises(IndexError, clfactory.GetNextClient)
1067

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

    
1081
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1082

    
1083
  def testDefaults(self):
1084
    clfactory = _FakeClientFactory(_FakeClient)
1085

    
1086
    name = "inst1"
1087
    data = {
1088
      "destination": "node2",
1089
      "shutdown": False,
1090
      }
1091

    
1092
    handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
1093
                             data, clfactory)
1094
    job_id = handler.PUT()
1095

    
1096
    cl = clfactory.GetNextClient()
1097
    self.assertRaises(IndexError, clfactory.GetNextClient)
1098

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

    
1110
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1111

    
1112
  def testErrors(self):
1113
    clfactory = _FakeClientFactory(_FakeClient)
1114

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

    
1121

    
1122
class TestInstanceMigrate(testutils.GanetiTestCase):
1123
  def test(self):
1124
    clfactory = _FakeClientFactory(_FakeClient)
1125

    
1126
    name = "instYooho6ek"
1127

    
1128
    for cleanup in [False, True]:
1129
      for mode in constants.HT_MIGRATION_MODES:
1130
        data = {
1131
          "cleanup": cleanup,
1132
          "mode": mode,
1133
          }
1134

    
1135
        handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {},
1136
                                 data, clfactory)
1137
        job_id = handler.PUT()
1138

    
1139
        cl = clfactory.GetNextClient()
1140
        self.assertRaises(IndexError, clfactory.GetNextClient)
1141

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

    
1151
        self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1152

    
1153
  def testDefaults(self):
1154
    clfactory = _FakeClientFactory(_FakeClient)
1155

    
1156
    name = "instnohZeex0"
1157

    
1158
    handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {}, {},
1159
                             clfactory)
1160
    job_id = handler.PUT()
1161

    
1162
    cl = clfactory.GetNextClient()
1163
    self.assertRaises(IndexError, clfactory.GetNextClient)
1164

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

    
1174
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1175

    
1176

    
1177
class TestParseRenameInstanceRequest(testutils.GanetiTestCase):
1178
  def test(self):
1179
    clfactory = _FakeClientFactory(_FakeClient)
1180

    
1181
    name = "instij0eeph7"
1182

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

    
1192
          handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
1193
                                   {}, data, clfactory)
1194
          job_id = handler.PUT()
1195

    
1196
          cl = clfactory.GetNextClient()
1197
          self.assertRaises(IndexError, clfactory.GetNextClient)
1198

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

    
1209
          self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1210

    
1211
  def testDefaults(self):
1212
    clfactory = _FakeClientFactory(_FakeClient)
1213

    
1214
    name = "instahchie3t"
1215

    
1216
    for new_name in ["thag9mek", "quees7oh"]:
1217
      data = {
1218
        "new_name": new_name,
1219
        }
1220

    
1221
      handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
1222
                               {}, data, clfactory)
1223
      job_id = handler.PUT()
1224

    
1225
      cl = clfactory.GetNextClient()
1226
      self.assertRaises(IndexError, clfactory.GetNextClient)
1227

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

    
1238
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1239

    
1240

    
1241
class TestParseModifyInstanceRequest(unittest.TestCase):
1242
  def test(self):
1243
    clfactory = _FakeClientFactory(_FakeClient)
1244

    
1245
    name = "instush8gah"
1246

    
1247
    test_disks = [
1248
      [],
1249
      [(1, { constants.IDISK_MODE: constants.DISK_RDWR, })],
1250
      ]
1251

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

    
1269
                  handler = _CreateHandler(rlib2.R_2_instances_name_modify,
1270
                                           [name], {}, data, clfactory)
1271
                  job_id = handler.PUT()
1272

    
1273
                  cl = clfactory.GetNextClient()
1274
                  self.assertRaises(IndexError, clfactory.GetNextClient)
1275

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

    
1292
                  self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1293

    
1294
  def testDefaults(self):
1295
    clfactory = _FakeClientFactory(_FakeClient)
1296

    
1297
    name = "instir8aish31"
1298

    
1299
    handler = _CreateHandler(rlib2.R_2_instances_name_modify,
1300
                             [name], {}, {}, clfactory)
1301
    job_id = handler.PUT()
1302

    
1303
    cl = clfactory.GetNextClient()
1304
    self.assertRaises(IndexError, clfactory.GetNextClient)
1305

    
1306
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1307
    self.assertEqual(job_id, exp_job_id)
1308
    self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
1309
    self.assertEqual(op.instance_name, name)
1310

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

    
1315

    
1316
class TestParseInstanceReinstallRequest(testutils.GanetiTestCase):
1317
  def setUp(self):
1318
    testutils.GanetiTestCase.setUp(self)
1319

    
1320
    self.Parse = rlib2._ParseInstanceReinstallRequest
1321

    
1322
  def _Check(self, ops, name):
1323
    expcls = [
1324
      opcodes.OpInstanceShutdown,
1325
      opcodes.OpInstanceReinstall,
1326
      opcodes.OpInstanceStartup,
1327
      ]
1328

    
1329
    self.assert_(compat.all(isinstance(op, exp)
1330
                            for op, exp in zip(ops, expcls)))
1331
    self.assert_(compat.all(op.instance_name == name for op in ops))
1332

    
1333
  def test(self):
1334
    name = "shoo0tihohma"
1335

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

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

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

    
1357
  def testDefaults(self):
1358
    name = "noolee0g"
1359

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

    
1366
  def testErrors(self):
1367
    self.assertRaises(http.HttpBadRequest, self.Parse,
1368
                      "foo", "not a dictionary")
1369

    
1370

    
1371
class TestGroupRename(unittest.TestCase):
1372
  def test(self):
1373
    clfactory = _FakeClientFactory(_FakeClient)
1374

    
1375
    name = "group608242564"
1376
    data = {
1377
      "new_name": "ua0aiyoo15112",
1378
      }
1379

    
1380
    handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {}, data,
1381
                             clfactory)
1382
    job_id = handler.PUT()
1383

    
1384
    cl = clfactory.GetNextClient()
1385
    self.assertRaises(IndexError, clfactory.GetNextClient)
1386

    
1387
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1388
    self.assertEqual(job_id, exp_job_id)
1389

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

    
1396
  def testDryRun(self):
1397
    clfactory = _FakeClientFactory(_FakeClient)
1398

    
1399
    name = "group28548"
1400
    data = {
1401
      "new_name": "ua0aiyoo",
1402
      }
1403

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

    
1409
    cl = clfactory.GetNextClient()
1410
    self.assertRaises(IndexError, clfactory.GetNextClient)
1411

    
1412
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1413
    self.assertEqual(job_id, exp_job_id)
1414

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

    
1421

    
1422
class TestInstanceReplaceDisks(unittest.TestCase):
1423
  def test(self):
1424
    clfactory = _FakeClientFactory(_FakeClient)
1425

    
1426
    name = "inst22568"
1427

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

    
1435
      handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1436
                               [name], {}, data, clfactory)
1437
      job_id = handler.POST()
1438

    
1439
      cl = clfactory.GetNextClient()
1440
      self.assertRaises(IndexError, clfactory.GetNextClient)
1441

    
1442
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1443
      self.assertEqual(job_id, exp_job_id)
1444

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

    
1452
  def testDefaults(self):
1453
    clfactory = _FakeClientFactory(_FakeClient)
1454

    
1455
    name = "inst11413"
1456
    data = {
1457
      "mode": constants.REPLACE_DISK_AUTO,
1458
      }
1459

    
1460
    handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1461
                             [name], {}, data, clfactory)
1462
    job_id = handler.POST()
1463

    
1464
    cl = clfactory.GetNextClient()
1465
    self.assertRaises(IndexError, clfactory.GetNextClient)
1466

    
1467
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1468
    self.assertEqual(job_id, exp_job_id)
1469

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

    
1477
  def testNoDisks(self):
1478
    clfactory = _FakeClientFactory(_FakeClient)
1479

    
1480
    handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1481
                             ["inst20661"], {}, {}, clfactory)
1482
    self.assertRaises(http.HttpBadRequest, handler.POST)
1483

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

    
1491
  def testWrong(self):
1492
    clfactory = _FakeClientFactory(_FakeClient)
1493

    
1494
    data = {
1495
      "mode": constants.REPLACE_DISK_AUTO,
1496
      "disks": "hello world",
1497
      }
1498

    
1499
    handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1500
                             ["foo"], {}, data, clfactory)
1501
    self.assertRaises(http.HttpBadRequest, handler.POST)
1502

    
1503

    
1504
class TestGroupModify(unittest.TestCase):
1505
  def test(self):
1506
    clfactory = _FakeClientFactory(_FakeClient)
1507

    
1508
    name = "group6002"
1509

    
1510
    for policy in constants.VALID_ALLOC_POLICIES:
1511
      data = {
1512
        "alloc_policy": policy,
1513
        }
1514

    
1515
      handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, data,
1516
                               clfactory)
1517
      job_id = handler.PUT()
1518

    
1519
      cl = clfactory.GetNextClient()
1520
      self.assertRaises(IndexError, clfactory.GetNextClient)
1521

    
1522
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1523
      self.assertEqual(job_id, exp_job_id)
1524

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

    
1531
  def testUnknownPolicy(self):
1532
    clfactory = _FakeClientFactory(_FakeClient)
1533

    
1534
    data = {
1535
      "alloc_policy": "_unknown_policy_",
1536
      }
1537

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

    
1543
  def testDefaults(self):
1544
    clfactory = _FakeClientFactory(_FakeClient)
1545

    
1546
    name = "group6679"
1547

    
1548
    handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, {},
1549
                             clfactory)
1550
    job_id = handler.PUT()
1551

    
1552
    cl = clfactory.GetNextClient()
1553
    self.assertRaises(IndexError, clfactory.GetNextClient)
1554

    
1555
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1556
    self.assertEqual(job_id, exp_job_id)
1557

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

    
1564

    
1565
class TestGroupAdd(unittest.TestCase):
1566
  def test(self):
1567
    name = "group3618"
1568
    clfactory = _FakeClientFactory(_FakeClient)
1569

    
1570
    for policy in constants.VALID_ALLOC_POLICIES:
1571
      data = {
1572
        "group_name": name,
1573
        "alloc_policy": policy,
1574
        }
1575

    
1576
      handler = _CreateHandler(rlib2.R_2_groups, [], {}, data,
1577
                               clfactory)
1578
      job_id = handler.POST()
1579

    
1580
      cl = clfactory.GetNextClient()
1581
      self.assertRaises(IndexError, clfactory.GetNextClient)
1582

    
1583
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1584
      self.assertEqual(job_id, exp_job_id)
1585

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

    
1592
  def testUnknownPolicy(self):
1593
    clfactory = _FakeClientFactory(_FakeClient)
1594

    
1595
    data = {
1596
      "alloc_policy": "_unknown_policy_",
1597
      }
1598

    
1599
    handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1600
    self.assertRaises(http.HttpBadRequest, handler.POST)
1601
    self.assertRaises(IndexError, clfactory.GetNextClient)
1602

    
1603
  def testDefaults(self):
1604
    clfactory = _FakeClientFactory(_FakeClient)
1605

    
1606
    name = "group15395"
1607
    data = {
1608
      "group_name": name,
1609
      }
1610

    
1611
    handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1612
    job_id = handler.POST()
1613

    
1614
    cl = clfactory.GetNextClient()
1615
    self.assertRaises(IndexError, clfactory.GetNextClient)
1616

    
1617
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1618
    self.assertEqual(job_id, exp_job_id)
1619

    
1620
    self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1621
    self.assertEqual(op.group_name, name)
1622
    self.assertFalse(hasattr(op, "alloc_policy"))
1623
    self.assertFalse(op.dry_run)
1624

    
1625
  def testLegacyName(self):
1626
    clfactory = _FakeClientFactory(_FakeClient)
1627

    
1628
    name = "group29852"
1629
    data = {
1630
      "name": name,
1631
      }
1632

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

    
1638
    cl = clfactory.GetNextClient()
1639
    self.assertRaises(IndexError, clfactory.GetNextClient)
1640

    
1641
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1642
    self.assertEqual(job_id, exp_job_id)
1643

    
1644
    self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1645
    self.assertEqual(op.group_name, name)
1646
    self.assertFalse(hasattr(op, "alloc_policy"))
1647
    self.assertTrue(op.dry_run)
1648

    
1649

    
1650
class TestNodeRole(unittest.TestCase):
1651
  def test(self):
1652
    clfactory = _FakeClientFactory(_FakeClient)
1653

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

    
1662
        cl = clfactory.GetNextClient()
1663
        self.assertRaises(IndexError, clfactory.GetNextClient)
1664

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

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

    
1691
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1692

    
1693

    
1694
class TestSimpleResources(unittest.TestCase):
1695
  def setUp(self):
1696
    self.clfactory = _FakeClientFactory(_FakeClient)
1697

    
1698
  def tearDown(self):
1699
    self.assertRaises(IndexError, self.clfactory.GetNextClient)
1700

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

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

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

    
1714

    
1715
class TestClusterInfo(unittest.TestCase):
1716
  class _ClusterInfoClient:
1717
    def __init__(self):
1718
      self.cluster_info = None
1719

    
1720
    def QueryClusterInfo(self):
1721
      assert self.cluster_info is None
1722
      self.cluster_info = object()
1723
      return self.cluster_info
1724

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

    
1733

    
1734
if __name__ == '__main__':
1735
  testutils.GanetiTestProgram()