Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.rapi.rlib2_unittest.py @ 861610e9

History | View | Annotate | Download (55.7 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
      ]
828

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1045

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1120

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

    
1125
    name = "instYooho6ek"
1126

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

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

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

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

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

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

    
1155
    name = "instnohZeex0"
1156

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

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

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

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

    
1175

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

    
1180
    name = "instij0eeph7"
1181

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

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

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

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

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

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

    
1213
    name = "instahchie3t"
1214

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

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

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

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

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

    
1239

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

    
1244
    name = "instush8gah"
1245

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

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

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

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

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

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

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

    
1296
    name = "instir8aish31"
1297

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

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

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

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

    
1314

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

    
1319
    self.Parse = rlib2._ParseInstanceReinstallRequest
1320

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

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

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

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

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

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

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

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

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

    
1369

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

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

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

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

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

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

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

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

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

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

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

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

    
1420

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

    
1425
    name = "inst22568"
1426

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1502

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

    
1507
    name = "group6002"
1508

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

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

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

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

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

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

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

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

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

    
1545
    name = "group6679"
1546

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

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

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

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

    
1563

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1648

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

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

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

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

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

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

    
1692

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

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

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

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

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

    
1713

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

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

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

    
1732

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