Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.rapi.rlib2_unittest.py @ 42d4d8b9

History | View | Annotate | Download (55.1 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_MEMORY: 123, },
822
      { constants.BE_VCPUS: 2,
823
        constants.BE_MEMORY: 1024,
824
        constants.BE_AUTO_BALANCE: True, }
825
      ]
826

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

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

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

    
856
                  if beparams is not None:
857
                    data["beparams"] = beparams
858

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

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

    
866
                  cl = clfactory.GetNextClient()
867
                  self.assertRaises(IndexError, clfactory.GetNextClient)
868

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

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

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

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

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

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

    
902
  def testLegacyName(self):
903
    clfactory = _FakeClientFactory(_FakeClient)
904

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

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

    
918
    cl = clfactory.GetNextClient()
919
    self.assertRaises(IndexError, clfactory.GetNextClient)
920

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

    
928
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
929

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

    
937
  def testLegacyOs(self):
938
    clfactory = _FakeClientFactory(_FakeClient)
939

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

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

    
955
    cl = clfactory.GetNextClient()
956
    self.assertRaises(IndexError, clfactory.GetNextClient)
957

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

    
966
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
967

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

    
974
  def testErrors(self):
975
    clfactory = _FakeClientFactory(_FakeClient)
976

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

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

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

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

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

    
1006
  def testVersion(self):
1007
    clfactory = _FakeClientFactory(_FakeClient)
1008

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

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

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

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

    
1028
      self.assertRaises(IndexError, clfactory.GetNextClient)
1029

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

    
1035
    cl = clfactory.GetNextClient()
1036
    self.assertRaises(IndexError, clfactory.GetNextClient)
1037

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

    
1043

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

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

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

    
1062
    cl = clfactory.GetNextClient()
1063
    self.assertRaises(IndexError, clfactory.GetNextClient)
1064

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

    
1078
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1079

    
1080
  def testDefaults(self):
1081
    clfactory = _FakeClientFactory(_FakeClient)
1082

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

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

    
1093
    cl = clfactory.GetNextClient()
1094
    self.assertRaises(IndexError, clfactory.GetNextClient)
1095

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

    
1107
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1108

    
1109
  def testErrors(self):
1110
    clfactory = _FakeClientFactory(_FakeClient)
1111

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

    
1118

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

    
1123
    name = "instYooho6ek"
1124

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

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

    
1136
        cl = clfactory.GetNextClient()
1137
        self.assertRaises(IndexError, clfactory.GetNextClient)
1138

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

    
1148
        self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1149

    
1150
  def testDefaults(self):
1151
    clfactory = _FakeClientFactory(_FakeClient)
1152

    
1153
    name = "instnohZeex0"
1154

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

    
1159
    cl = clfactory.GetNextClient()
1160
    self.assertRaises(IndexError, clfactory.GetNextClient)
1161

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

    
1171
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1172

    
1173

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

    
1178
    name = "instij0eeph7"
1179

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

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

    
1193
          cl = clfactory.GetNextClient()
1194
          self.assertRaises(IndexError, clfactory.GetNextClient)
1195

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

    
1206
          self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1207

    
1208
  def testDefaults(self):
1209
    clfactory = _FakeClientFactory(_FakeClient)
1210

    
1211
    name = "instahchie3t"
1212

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

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

    
1222
      cl = clfactory.GetNextClient()
1223
      self.assertRaises(IndexError, clfactory.GetNextClient)
1224

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

    
1235
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1236

    
1237

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

    
1242
    name = "instush8gah"
1243

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

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

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

    
1270
                  cl = clfactory.GetNextClient()
1271
                  self.assertRaises(IndexError, clfactory.GetNextClient)
1272

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

    
1289
                  self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1290

    
1291
  def testDefaults(self):
1292
    clfactory = _FakeClientFactory(_FakeClient)
1293

    
1294
    name = "instir8aish31"
1295

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

    
1300
    cl = clfactory.GetNextClient()
1301
    self.assertRaises(IndexError, clfactory.GetNextClient)
1302

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

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

    
1312

    
1313
class TestParseInstanceReinstallRequest(testutils.GanetiTestCase):
1314
  def setUp(self):
1315
    testutils.GanetiTestCase.setUp(self)
1316

    
1317
    self.Parse = rlib2._ParseInstanceReinstallRequest
1318

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

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

    
1330
  def test(self):
1331
    name = "shoo0tihohma"
1332

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

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

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

    
1354
  def testDefaults(self):
1355
    name = "noolee0g"
1356

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

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

    
1367

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

    
1372
    name = "group608242564"
1373
    data = {
1374
      "new_name": "ua0aiyoo15112",
1375
      }
1376

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

    
1381
    cl = clfactory.GetNextClient()
1382
    self.assertRaises(IndexError, clfactory.GetNextClient)
1383

    
1384
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1385
    self.assertEqual(job_id, exp_job_id)
1386

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

    
1393
  def testDryRun(self):
1394
    clfactory = _FakeClientFactory(_FakeClient)
1395

    
1396
    name = "group28548"
1397
    data = {
1398
      "new_name": "ua0aiyoo",
1399
      }
1400

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

    
1406
    cl = clfactory.GetNextClient()
1407
    self.assertRaises(IndexError, clfactory.GetNextClient)
1408

    
1409
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1410
    self.assertEqual(job_id, exp_job_id)
1411

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

    
1418

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

    
1423
    name = "inst22568"
1424

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

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

    
1436
      cl = clfactory.GetNextClient()
1437
      self.assertRaises(IndexError, clfactory.GetNextClient)
1438

    
1439
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1440
      self.assertEqual(job_id, exp_job_id)
1441

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

    
1449
  def testDefaults(self):
1450
    clfactory = _FakeClientFactory(_FakeClient)
1451

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

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

    
1461
    cl = clfactory.GetNextClient()
1462
    self.assertRaises(IndexError, clfactory.GetNextClient)
1463

    
1464
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1465
    self.assertEqual(job_id, exp_job_id)
1466

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

    
1474
  def testWrong(self):
1475
    clfactory = _FakeClientFactory(_FakeClient)
1476

    
1477
    data = {
1478
      "mode": constants.REPLACE_DISK_AUTO,
1479
      "disks": "hello world",
1480
      }
1481

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

    
1486

    
1487
class TestGroupModify(unittest.TestCase):
1488
  def test(self):
1489
    clfactory = _FakeClientFactory(_FakeClient)
1490

    
1491
    name = "group6002"
1492

    
1493
    for policy in constants.VALID_ALLOC_POLICIES:
1494
      data = {
1495
        "alloc_policy": policy,
1496
        }
1497

    
1498
      handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, data,
1499
                               clfactory)
1500
      job_id = handler.PUT()
1501

    
1502
      cl = clfactory.GetNextClient()
1503
      self.assertRaises(IndexError, clfactory.GetNextClient)
1504

    
1505
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1506
      self.assertEqual(job_id, exp_job_id)
1507

    
1508
      self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
1509
      self.assertEqual(op.group_name, name)
1510
      self.assertEqual(op.alloc_policy, policy)
1511
      self.assertFalse(hasattr(op, "dry_run"))
1512
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1513

    
1514
  def testUnknownPolicy(self):
1515
    clfactory = _FakeClientFactory(_FakeClient)
1516

    
1517
    data = {
1518
      "alloc_policy": "_unknown_policy_",
1519
      }
1520

    
1521
    handler = _CreateHandler(rlib2.R_2_groups_name_modify, ["xyz"], {}, data,
1522
                             clfactory)
1523
    self.assertRaises(http.HttpBadRequest, handler.PUT)
1524
    self.assertRaises(IndexError, clfactory.GetNextClient)
1525

    
1526
  def testDefaults(self):
1527
    clfactory = _FakeClientFactory(_FakeClient)
1528

    
1529
    name = "group6679"
1530

    
1531
    handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, {},
1532
                             clfactory)
1533
    job_id = handler.PUT()
1534

    
1535
    cl = clfactory.GetNextClient()
1536
    self.assertRaises(IndexError, clfactory.GetNextClient)
1537

    
1538
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1539
    self.assertEqual(job_id, exp_job_id)
1540

    
1541
    self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
1542
    self.assertEqual(op.group_name, name)
1543
    self.assertFalse(hasattr(op, "alloc_policy"))
1544
    self.assertFalse(hasattr(op, "dry_run"))
1545
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1546

    
1547

    
1548
class TestGroupAdd(unittest.TestCase):
1549
  def test(self):
1550
    name = "group3618"
1551
    clfactory = _FakeClientFactory(_FakeClient)
1552

    
1553
    for policy in constants.VALID_ALLOC_POLICIES:
1554
      data = {
1555
        "group_name": name,
1556
        "alloc_policy": policy,
1557
        }
1558

    
1559
      handler = _CreateHandler(rlib2.R_2_groups, [], {}, data,
1560
                               clfactory)
1561
      job_id = handler.POST()
1562

    
1563
      cl = clfactory.GetNextClient()
1564
      self.assertRaises(IndexError, clfactory.GetNextClient)
1565

    
1566
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1567
      self.assertEqual(job_id, exp_job_id)
1568

    
1569
      self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1570
      self.assertEqual(op.group_name, name)
1571
      self.assertEqual(op.alloc_policy, policy)
1572
      self.assertFalse(op.dry_run)
1573
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1574

    
1575
  def testUnknownPolicy(self):
1576
    clfactory = _FakeClientFactory(_FakeClient)
1577

    
1578
    data = {
1579
      "alloc_policy": "_unknown_policy_",
1580
      }
1581

    
1582
    handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1583
    self.assertRaises(http.HttpBadRequest, handler.POST)
1584
    self.assertRaises(IndexError, clfactory.GetNextClient)
1585

    
1586
  def testDefaults(self):
1587
    clfactory = _FakeClientFactory(_FakeClient)
1588

    
1589
    name = "group15395"
1590
    data = {
1591
      "group_name": name,
1592
      }
1593

    
1594
    handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1595
    job_id = handler.POST()
1596

    
1597
    cl = clfactory.GetNextClient()
1598
    self.assertRaises(IndexError, clfactory.GetNextClient)
1599

    
1600
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1601
    self.assertEqual(job_id, exp_job_id)
1602

    
1603
    self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1604
    self.assertEqual(op.group_name, name)
1605
    self.assertFalse(hasattr(op, "alloc_policy"))
1606
    self.assertFalse(op.dry_run)
1607

    
1608
  def testLegacyName(self):
1609
    clfactory = _FakeClientFactory(_FakeClient)
1610

    
1611
    name = "group29852"
1612
    data = {
1613
      "name": name,
1614
      }
1615

    
1616
    handler = _CreateHandler(rlib2.R_2_groups, [], {
1617
      "dry-run": ["1"],
1618
      }, data, clfactory)
1619
    job_id = handler.POST()
1620

    
1621
    cl = clfactory.GetNextClient()
1622
    self.assertRaises(IndexError, clfactory.GetNextClient)
1623

    
1624
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1625
    self.assertEqual(job_id, exp_job_id)
1626

    
1627
    self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1628
    self.assertEqual(op.group_name, name)
1629
    self.assertFalse(hasattr(op, "alloc_policy"))
1630
    self.assertTrue(op.dry_run)
1631

    
1632

    
1633
class TestNodeRole(unittest.TestCase):
1634
  def test(self):
1635
    clfactory = _FakeClientFactory(_FakeClient)
1636

    
1637
    for role in rlib2._NR_MAP.values():
1638
      handler = _CreateHandler(rlib2.R_2_nodes_name_role,
1639
                               ["node-z"], {}, role, clfactory)
1640
      if role == rlib2._NR_MASTER:
1641
        self.assertRaises(http.HttpBadRequest, handler.PUT)
1642
      else:
1643
        job_id = handler.PUT()
1644

    
1645
        cl = clfactory.GetNextClient()
1646
        self.assertRaises(IndexError, clfactory.GetNextClient)
1647

    
1648
        (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1649
        self.assertEqual(job_id, exp_job_id)
1650
        self.assertTrue(isinstance(op, opcodes.OpNodeSetParams))
1651
        self.assertEqual(op.node_name, "node-z")
1652
        self.assertFalse(op.force)
1653
        self.assertFalse(hasattr(op, "dry_run"))
1654

    
1655
        if role == rlib2._NR_REGULAR:
1656
          self.assertFalse(op.drained)
1657
          self.assertFalse(op.offline)
1658
          self.assertFalse(op.master_candidate)
1659
        elif role == rlib2._NR_MASTER_CANDIDATE:
1660
          self.assertFalse(op.drained)
1661
          self.assertFalse(op.offline)
1662
          self.assertTrue(op.master_candidate)
1663
        elif role == rlib2._NR_DRAINED:
1664
          self.assertTrue(op.drained)
1665
          self.assertFalse(op.offline)
1666
          self.assertFalse(op.master_candidate)
1667
        elif role == rlib2._NR_OFFLINE:
1668
          self.assertFalse(op.drained)
1669
          self.assertTrue(op.offline)
1670
          self.assertFalse(op.master_candidate)
1671
        else:
1672
          self.fail("Unknown role '%s'" % role)
1673

    
1674
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1675

    
1676

    
1677
class TestSimpleResources(unittest.TestCase):
1678
  def setUp(self):
1679
    self.clfactory = _FakeClientFactory(_FakeClient)
1680

    
1681
  def tearDown(self):
1682
    self.assertRaises(IndexError, self.clfactory.GetNextClient)
1683

    
1684
  def testFeatures(self):
1685
    handler = _CreateHandler(rlib2.R_2_features, [], {}, None, self.clfactory)
1686
    self.assertEqual(set(handler.GET()), rlib2.ALL_FEATURES)
1687

    
1688
  def testEmpty(self):
1689
    for cls in [rlib2.R_root, rlib2.R_2]:
1690
      handler = _CreateHandler(cls, [], {}, None, self.clfactory)
1691
      self.assertTrue(handler.GET() is None)
1692

    
1693
  def testVersion(self):
1694
    handler = _CreateHandler(rlib2.R_version, [], {}, None, self.clfactory)
1695
    self.assertEqual(handler.GET(), constants.RAPI_VERSION)
1696

    
1697

    
1698
class TestClusterInfo(unittest.TestCase):
1699
  class _ClusterInfoClient:
1700
    def __init__(self):
1701
      self.cluster_info = None
1702

    
1703
    def QueryClusterInfo(self):
1704
      assert self.cluster_info is None
1705
      self.cluster_info = object()
1706
      return self.cluster_info
1707

    
1708
  def test(self):
1709
    clfactory = _FakeClientFactory(self._ClusterInfoClient)
1710
    handler = _CreateHandler(rlib2.R_2_info, [], {}, None, clfactory)
1711
    result = handler.GET()
1712
    cl = clfactory.GetNextClient()
1713
    self.assertRaises(IndexError, clfactory.GetNextClient)
1714
    self.assertEqual(result, cl.cluster_info)
1715

    
1716

    
1717
if __name__ == '__main__':
1718
  testutils.GanetiTestProgram()