Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (57.8 kB)

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

    
4
# Copyright (C) 2010, 2012, 2013 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
from ganeti import rapi
39

    
40
from ganeti.rapi import rlib2
41
from ganeti.rapi import baserlib
42
from ganeti.rapi import connector
43

    
44
import testutils
45

    
46

    
47
class _FakeRequestPrivateData:
48
  def __init__(self, body_data):
49
    self.body_data = body_data
50

    
51

    
52
class _FakeRequest:
53
  def __init__(self, body_data):
54
    self.private = _FakeRequestPrivateData(body_data)
55

    
56

    
57
def _CreateHandler(cls, items, queryargs, body_data, client_cls):
58
  return cls(items, queryargs, _FakeRequest(body_data),
59
             _client_cls=client_cls)
60

    
61

    
62
class _FakeClient:
63
  def __init__(self, address=None):
64
    self._jobs = []
65

    
66
  def GetNextSubmittedJob(self):
67
    return self._jobs.pop(0)
68

    
69
  def SubmitJob(self, ops):
70
    job_id = str(1 + int(random.random() * 1000000))
71
    self._jobs.append((job_id, ops))
72
    return job_id
73

    
74

    
75
class _FakeClientFactory:
76
  def __init__(self, cls):
77
    self._client_cls = cls
78
    self._clients = []
79

    
80
  def GetNextClient(self):
81
    return self._clients.pop(0)
82

    
83
  def __call__(self, address=None):
84
    cl = self._client_cls(address=address)
85
    self._clients.append(cl)
86
    return cl
87

    
88

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

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

    
103
    for (qr, fields) in checks.items():
104
      self.assertFalse(set(fields) - set(query.ALL_FIELDS[qr].keys()))
105

    
106

    
107
class TestClientConnectError(unittest.TestCase):
108
  @staticmethod
109
  def _FailingClient(address=None):
110
    raise luxi.NoMasterError("test")
111

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

    
122

    
123
class TestJobSubmitError(unittest.TestCase):
124
  class _SubmitErrorClient:
125
    def __init__(self, address=None):
126
      pass
127

    
128
    @staticmethod
129
    def SubmitJob(ops):
130
      raise errors.JobQueueFull("test")
131

    
132
  def test(self):
133
    handler = _CreateHandler(rlib2.R_2_redist_config, [], [], None,
134
                             self._SubmitErrorClient)
135
    self.assertRaises(http.HttpServiceUnavailable, handler.PUT)
136

    
137

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

    
147
    cl = clfactory.GetNextClient()
148
    self.assertRaises(IndexError, clfactory.GetNextClient)
149

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

    
156
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
157

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

    
167

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

    
174
    cl = clfactory.GetNextClient()
175
    self.assertRaises(IndexError, clfactory.GetNextClient)
176

    
177
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
178
    self.assertEqual(job_id, exp_job_id)
179
    self.assertTrue(isinstance(op, opcodes.OpClusterRedistConf))
180

    
181
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
182

    
183

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

    
192
    cl = clfactory.GetNextClient()
193
    self.assertRaises(IndexError, clfactory.GetNextClient)
194

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

    
201
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
202

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

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

    
221
    cl = clfactory.GetNextClient()
222
    self.assertRaises(IndexError, clfactory.GetNextClient)
223

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

    
230
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
231

    
232
  def testQueryArgsLive(self):
233
    clfactory = _FakeClientFactory(_FakeClient)
234

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

    
243
      cl = clfactory.GetNextClient()
244
      self.assertRaises(IndexError, clfactory.GetNextClient)
245

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

    
255
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
256

    
257

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

    
268
    cl = clfactory.GetNextClient()
269
    self.assertRaises(IndexError, clfactory.GetNextClient)
270

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

    
278
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
279

    
280

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

    
289
    cl = clfactory.GetNextClient()
290
    self.assertRaises(IndexError, clfactory.GetNextClient)
291

    
292
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
293
    self.assertEqual(job_id, exp_job_id)
294
    self.assertTrue(isinstance(op, opcodes.OpNodePowercycle))
295
    self.assertEqual(op.node_name, "node20744")
296
    self.assertTrue(op.force)
297

    
298
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
299

    
300

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

    
312
    cl = clfactory.GetNextClient()
313
    self.assertRaises(IndexError, clfactory.GetNextClient)
314

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

    
323
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
324

    
325

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

    
334
    cl = clfactory.GetNextClient()
335
    self.assertRaises(IndexError, clfactory.GetNextClient)
336

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

    
344
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
345

    
346

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

    
355
    cl = clfactory.GetNextClient()
356
    self.assertRaises(IndexError, clfactory.GetNextClient)
357

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

    
364
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
365

    
366

    
367
class TestInstanceReboot(unittest.TestCase):
368
  def test(self):
369
    clfactory = _FakeClientFactory(_FakeClient)
370
    handler = _CreateHandler(rlib2.R_2_instances_name_reboot, ["inst847"], {
371
      "dry-run": ["1"],
372
      "ignore_secondaries": ["1"],
373
      "reason_text": ["System update"],
374
      }, {}, clfactory)
375
    job_id = handler.POST()
376

    
377
    cl = clfactory.GetNextClient()
378
    self.assertRaises(IndexError, clfactory.GetNextClient)
379

    
380
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
381
    self.assertEqual(job_id, exp_job_id)
382
    self.assertTrue(isinstance(op, opcodes.OpInstanceReboot))
383
    self.assertEqual(op.instance_name, "inst847")
384
    self.assertEqual(op.reboot_type, constants.INSTANCE_REBOOT_HARD)
385
    self.assertTrue(op.ignore_secondaries)
386
    self.assertTrue(op.dry_run)
387
    self.assertEqual(op.reason,
388
                     (constants.INSTANCE_REASON_SOURCE_RAPI, "System update"))
389

    
390
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
391

    
392

    
393
class TestInstanceStartup(unittest.TestCase):
394
  def test(self):
395
    clfactory = _FakeClientFactory(_FakeClient)
396
    handler = _CreateHandler(rlib2.R_2_instances_name_startup, ["inst31083"], {
397
      "force": ["1"],
398
      "no_remember": ["1"],
399
      }, {}, clfactory)
400
    job_id = handler.PUT()
401

    
402
    cl = clfactory.GetNextClient()
403
    self.assertRaises(IndexError, clfactory.GetNextClient)
404

    
405
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
406
    self.assertEqual(job_id, exp_job_id)
407
    self.assertTrue(isinstance(op, opcodes.OpInstanceStartup))
408
    self.assertEqual(op.instance_name, "inst31083")
409
    self.assertTrue(op.no_remember)
410
    self.assertTrue(op.force)
411
    self.assertFalse(op.dry_run)
412

    
413
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
414

    
415

    
416
class TestInstanceShutdown(unittest.TestCase):
417
  def test(self):
418
    clfactory = _FakeClientFactory(_FakeClient)
419
    handler = _CreateHandler(rlib2.R_2_instances_name_shutdown, ["inst26791"], {
420
      "no_remember": ["0"],
421
      }, {}, clfactory)
422
    job_id = handler.PUT()
423

    
424
    cl = clfactory.GetNextClient()
425
    self.assertRaises(IndexError, clfactory.GetNextClient)
426

    
427
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
428
    self.assertEqual(job_id, exp_job_id)
429
    self.assertTrue(isinstance(op, opcodes.OpInstanceShutdown))
430
    self.assertEqual(op.instance_name, "inst26791")
431
    self.assertFalse(op.no_remember)
432
    self.assertFalse(op.dry_run)
433

    
434
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
435

    
436

    
437
class TestInstanceActivateDisks(unittest.TestCase):
438
  def test(self):
439
    clfactory = _FakeClientFactory(_FakeClient)
440
    handler = _CreateHandler(rlib2.R_2_instances_name_activate_disks, ["xyz"], {
441
      "ignore_size": ["1"],
442
      }, {}, clfactory)
443
    job_id = handler.PUT()
444

    
445
    cl = clfactory.GetNextClient()
446
    self.assertRaises(IndexError, clfactory.GetNextClient)
447

    
448
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
449
    self.assertEqual(job_id, exp_job_id)
450
    self.assertTrue(isinstance(op, opcodes.OpInstanceActivateDisks))
451
    self.assertEqual(op.instance_name, "xyz")
452
    self.assertTrue(op.ignore_size)
453
    self.assertFalse(hasattr(op, "dry_run"))
454

    
455
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
456

    
457

    
458
class TestInstanceDeactivateDisks(unittest.TestCase):
459
  def test(self):
460
    clfactory = _FakeClientFactory(_FakeClient)
461
    handler = _CreateHandler(rlib2.R_2_instances_name_deactivate_disks,
462
                             ["inst22357"], {}, {}, clfactory)
463
    job_id = handler.PUT()
464

    
465
    cl = clfactory.GetNextClient()
466
    self.assertRaises(IndexError, clfactory.GetNextClient)
467

    
468
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
469
    self.assertEqual(job_id, exp_job_id)
470
    self.assertTrue(isinstance(op, opcodes.OpInstanceDeactivateDisks))
471
    self.assertEqual(op.instance_name, "inst22357")
472
    self.assertFalse(hasattr(op, "dry_run"))
473
    self.assertFalse(hasattr(op, "force"))
474

    
475
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
476

    
477

    
478
class TestInstanceRecreateDisks(unittest.TestCase):
479
  def test(self):
480
    clfactory = _FakeClientFactory(_FakeClient)
481
    handler = _CreateHandler(rlib2.R_2_instances_name_recreate_disks,
482
                             ["inst22357"], {}, {}, clfactory)
483
    job_id = handler.POST()
484

    
485
    cl = clfactory.GetNextClient()
486
    self.assertRaises(IndexError, clfactory.GetNextClient)
487

    
488
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
489
    self.assertEqual(job_id, exp_job_id)
490
    self.assertTrue(isinstance(op, opcodes.OpInstanceRecreateDisks))
491
    self.assertEqual(op.instance_name, "inst22357")
492
    self.assertFalse(hasattr(op, "dry_run"))
493
    self.assertFalse(hasattr(op, "force"))
494

    
495
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
496

    
497

    
498
class TestInstanceFailover(unittest.TestCase):
499
  def test(self):
500
    clfactory = _FakeClientFactory(_FakeClient)
501
    handler = _CreateHandler(rlib2.R_2_instances_name_failover,
502
                             ["inst12794"], {}, {}, clfactory)
503
    job_id = handler.PUT()
504

    
505
    cl = clfactory.GetNextClient()
506
    self.assertRaises(IndexError, clfactory.GetNextClient)
507

    
508
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
509
    self.assertEqual(job_id, exp_job_id)
510
    self.assertTrue(isinstance(op, opcodes.OpInstanceFailover))
511
    self.assertEqual(op.instance_name, "inst12794")
512
    self.assertFalse(hasattr(op, "dry_run"))
513
    self.assertFalse(hasattr(op, "force"))
514

    
515
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
516

    
517

    
518
class TestInstanceDiskGrow(unittest.TestCase):
519
  def test(self):
520
    clfactory = _FakeClientFactory(_FakeClient)
521
    data = {
522
      "amount": 1024,
523
      }
524
    handler = _CreateHandler(rlib2.R_2_instances_name_disk_grow,
525
                             ["inst10742", "3"], {}, data, clfactory)
526
    job_id = handler.POST()
527

    
528
    cl = clfactory.GetNextClient()
529
    self.assertRaises(IndexError, clfactory.GetNextClient)
530

    
531
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
532
    self.assertEqual(job_id, exp_job_id)
533
    self.assertTrue(isinstance(op, opcodes.OpInstanceGrowDisk))
534
    self.assertEqual(op.instance_name, "inst10742")
535
    self.assertEqual(op.disk, 3)
536
    self.assertEqual(op.amount, 1024)
537
    self.assertFalse(hasattr(op, "dry_run"))
538
    self.assertFalse(hasattr(op, "force"))
539

    
540
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
541

    
542

    
543
class TestBackupPrepare(unittest.TestCase):
544
  def test(self):
545
    clfactory = _FakeClientFactory(_FakeClient)
546
    queryargs = {
547
      "mode": constants.EXPORT_MODE_REMOTE,
548
      }
549
    handler = _CreateHandler(rlib2.R_2_instances_name_prepare_export,
550
                             ["inst17925"], queryargs, {}, clfactory)
551
    job_id = handler.PUT()
552

    
553
    cl = clfactory.GetNextClient()
554
    self.assertRaises(IndexError, clfactory.GetNextClient)
555

    
556
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
557
    self.assertEqual(job_id, exp_job_id)
558
    self.assertTrue(isinstance(op, opcodes.OpBackupPrepare))
559
    self.assertEqual(op.instance_name, "inst17925")
560
    self.assertEqual(op.mode, constants.EXPORT_MODE_REMOTE)
561
    self.assertFalse(hasattr(op, "dry_run"))
562
    self.assertFalse(hasattr(op, "force"))
563

    
564
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
565

    
566

    
567
class TestGroupRemove(unittest.TestCase):
568
  def test(self):
569
    clfactory = _FakeClientFactory(_FakeClient)
570
    handler = _CreateHandler(rlib2.R_2_groups_name,
571
                             ["grp28575"], {}, {}, clfactory)
572
    job_id = handler.DELETE()
573

    
574
    cl = clfactory.GetNextClient()
575
    self.assertRaises(IndexError, clfactory.GetNextClient)
576

    
577
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
578
    self.assertEqual(job_id, exp_job_id)
579
    self.assertTrue(isinstance(op, opcodes.OpGroupRemove))
580
    self.assertEqual(op.group_name, "grp28575")
581
    self.assertFalse(op.dry_run)
582
    self.assertFalse(hasattr(op, "force"))
583

    
584
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
585

    
586

    
587
class TestStorageQuery(unittest.TestCase):
588
  def test(self):
589
    clfactory = _FakeClientFactory(_FakeClient)
590
    queryargs = {
591
      "storage_type": constants.ST_LVM_PV,
592
      "output_fields": "name,other",
593
      }
594
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
595
                             ["node21075"], queryargs, {}, clfactory)
596
    job_id = handler.GET()
597

    
598
    cl = clfactory.GetNextClient()
599
    self.assertRaises(IndexError, clfactory.GetNextClient)
600

    
601
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
602
    self.assertEqual(job_id, exp_job_id)
603
    self.assertTrue(isinstance(op, opcodes.OpNodeQueryStorage))
604
    self.assertEqual(op.nodes, ["node21075"])
605
    self.assertEqual(op.storage_type, constants.ST_LVM_PV)
606
    self.assertEqual(op.output_fields, ["name", "other"])
607
    self.assertFalse(hasattr(op, "dry_run"))
608
    self.assertFalse(hasattr(op, "force"))
609

    
610
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
611

    
612
  def testErrors(self):
613
    clfactory = _FakeClientFactory(_FakeClient)
614

    
615
    queryargs = {
616
      "output_fields": "name,other",
617
      }
618
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
619
                             ["node10538"], queryargs, {}, clfactory)
620
    self.assertRaises(http.HttpBadRequest, handler.GET)
621

    
622
    queryargs = {
623
      "storage_type": constants.ST_LVM_VG,
624
      }
625
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
626
                             ["node21273"], queryargs, {}, clfactory)
627
    self.assertRaises(http.HttpBadRequest, handler.GET)
628

    
629
    queryargs = {
630
      "storage_type": "##unknown_storage##",
631
      "output_fields": "name,other",
632
      }
633
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
634
                             ["node10315"], queryargs, {}, clfactory)
635
    self.assertRaises(http.HttpBadRequest, handler.GET)
636

    
637

    
638
class TestStorageModify(unittest.TestCase):
639
  def test(self):
640
    clfactory = _FakeClientFactory(_FakeClient)
641

    
642
    for allocatable in [None, "1", "0"]:
643
      queryargs = {
644
        "storage_type": constants.ST_LVM_VG,
645
        "name": "pv-a",
646
        }
647

    
648
      if allocatable is not None:
649
        queryargs["allocatable"] = allocatable
650

    
651
      handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
652
                               ["node9292"], queryargs, {}, clfactory)
653
      job_id = handler.PUT()
654

    
655
      cl = clfactory.GetNextClient()
656
      self.assertRaises(IndexError, clfactory.GetNextClient)
657

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

    
674
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
675

    
676
  def testErrors(self):
677
    clfactory = _FakeClientFactory(_FakeClient)
678

    
679
    # No storage type
680
    queryargs = {
681
      "name": "xyz",
682
      }
683
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
684
                             ["node26016"], queryargs, {}, clfactory)
685
    self.assertRaises(http.HttpBadRequest, handler.PUT)
686

    
687
    # No name
688
    queryargs = {
689
      "storage_type": constants.ST_LVM_VG,
690
      }
691
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
692
                             ["node21218"], queryargs, {}, clfactory)
693
    self.assertRaises(http.HttpBadRequest, handler.PUT)
694

    
695
    # Invalid value
696
    queryargs = {
697
      "storage_type": constants.ST_LVM_VG,
698
      "name": "pv-b",
699
      "allocatable": "noint",
700
      }
701
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
702
                             ["node30685"], queryargs, {}, clfactory)
703
    self.assertRaises(http.HttpBadRequest, handler.PUT)
704

    
705

    
706
class TestStorageRepair(unittest.TestCase):
707
  def test(self):
708
    clfactory = _FakeClientFactory(_FakeClient)
709
    queryargs = {
710
      "storage_type": constants.ST_LVM_PV,
711
      "name": "pv16611",
712
      }
713
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
714
                             ["node19265"], queryargs, {}, clfactory)
715
    job_id = handler.PUT()
716

    
717
    cl = clfactory.GetNextClient()
718
    self.assertRaises(IndexError, clfactory.GetNextClient)
719

    
720
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
721
    self.assertEqual(job_id, exp_job_id)
722
    self.assertTrue(isinstance(op, opcodes.OpRepairNodeStorage))
723
    self.assertEqual(op.node_name, "node19265")
724
    self.assertEqual(op.storage_type, constants.ST_LVM_PV)
725
    self.assertEqual(op.name, "pv16611")
726
    self.assertFalse(hasattr(op, "dry_run"))
727
    self.assertFalse(hasattr(op, "force"))
728

    
729
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
730

    
731
  def testErrors(self):
732
    clfactory = _FakeClientFactory(_FakeClient)
733

    
734
    # No storage type
735
    queryargs = {
736
      "name": "xyz",
737
      }
738
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
739
                             ["node11275"], queryargs, {}, clfactory)
740
    self.assertRaises(http.HttpBadRequest, handler.PUT)
741

    
742
    # No name
743
    queryargs = {
744
      "storage_type": constants.ST_LVM_VG,
745
      }
746
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
747
                             ["node21218"], queryargs, {}, clfactory)
748
    self.assertRaises(http.HttpBadRequest, handler.PUT)
749

    
750

    
751
class TestTags(unittest.TestCase):
752
  TAG_HANDLERS = [
753
    rlib2.R_2_instances_name_tags,
754
    rlib2.R_2_nodes_name_tags,
755
    rlib2.R_2_groups_name_tags,
756
    rlib2.R_2_tags,
757
    ]
758

    
759
  def testSetAndDelete(self):
760
    clfactory = _FakeClientFactory(_FakeClient)
761

    
762
    for method, opcls in [("PUT", opcodes.OpTagsSet),
763
                          ("DELETE", opcodes.OpTagsDel)]:
764
      for idx, handler in enumerate(self.TAG_HANDLERS):
765
        dry_run = bool(idx % 2)
766
        name = "test%s" % idx
767
        queryargs = {
768
          "tag": ["foo", "bar", "baz"],
769
          "dry-run": str(int(dry_run)),
770
          }
771

    
772
        handler = _CreateHandler(handler, [name], queryargs, {}, clfactory)
773
        job_id = getattr(handler, method)()
774

    
775
        cl = clfactory.GetNextClient()
776
        self.assertRaises(IndexError, clfactory.GetNextClient)
777

    
778
        (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
779
        self.assertEqual(job_id, exp_job_id)
780
        self.assertTrue(isinstance(op, opcls))
781
        self.assertEqual(op.kind, handler.TAG_LEVEL)
782
        if handler.TAG_LEVEL == constants.TAG_CLUSTER:
783
          self.assertTrue(op.name is None)
784
        else:
785
          self.assertEqual(op.name, name)
786
        self.assertEqual(op.tags, ["foo", "bar", "baz"])
787
        self.assertEqual(op.dry_run, dry_run)
788
        self.assertFalse(hasattr(op, "force"))
789

    
790
        self.assertRaises(IndexError, cl.GetNextSubmittedJob)
791

    
792

    
793
class TestInstanceCreation(testutils.GanetiTestCase):
794
  def test(self):
795
    clfactory = _FakeClientFactory(_FakeClient)
796

    
797
    name = "inst863.example.com"
798

    
799
    disk_variants = [
800
      # No disks
801
      [],
802

    
803
      # Two disks
804
      [{"size": 5, }, {"size": 100, }],
805

    
806
      # Disk with mode
807
      [{"size": 123, "mode": constants.DISK_RDWR, }],
808
      ]
809

    
810
    nic_variants = [
811
      # No NIC
812
      [],
813

    
814
      # Three NICs
815
      [{}, {}, {}],
816

    
817
      # Two NICs
818
      [
819
        { "ip": "192.0.2.6", "mode": constants.NIC_MODE_ROUTED,
820
          "mac": "01:23:45:67:68:9A",
821
        },
822
        { "mode": constants.NIC_MODE_BRIDGED, "link": "br1" },
823
      ],
824
      ]
825

    
826
    beparam_variants = [
827
      None,
828
      {},
829
      { constants.BE_VCPUS: 2, },
830
      { constants.BE_MAXMEM: 200, },
831
      { constants.BE_MEMORY: 256, },
832
      { constants.BE_VCPUS: 2,
833
        constants.BE_MAXMEM: 1024,
834
        constants.BE_MINMEM: 1024,
835
        constants.BE_AUTO_BALANCE: True,
836
        constants.BE_ALWAYS_FAILOVER: True, }
837
      ]
838

    
839
    hvparam_variants = [
840
      None,
841
      { constants.HV_BOOT_ORDER: "anc", },
842
      { constants.HV_KERNEL_PATH: "/boot/fookernel",
843
        constants.HV_ROOT_PATH: "/dev/hda1", },
844
      ]
845

    
846
    for mode in [constants.INSTANCE_CREATE, constants.INSTANCE_IMPORT]:
847
      for nics in nic_variants:
848
        for disk_template in constants.DISK_TEMPLATES:
849
          for disks in disk_variants:
850
            for beparams in beparam_variants:
851
              for hvparams in hvparam_variants:
852
                for dry_run in [False, True]:
853
                  queryargs = {
854
                    "dry-run": str(int(dry_run)),
855
                    }
856

    
857
                  data = {
858
                    rlib2._REQ_DATA_VERSION: 1,
859
                    "name": name,
860
                    "hypervisor": constants.HT_FAKE,
861
                    "disks": disks,
862
                    "nics": nics,
863
                    "mode": mode,
864
                    "disk_template": disk_template,
865
                    "os": "debootstrap",
866
                    }
867

    
868
                  if beparams is not None:
869
                    data["beparams"] = beparams
870

    
871
                  if hvparams is not None:
872
                    data["hvparams"] = hvparams
873

    
874
                  handler = _CreateHandler(rlib2.R_2_instances, [],
875
                                           queryargs, data, clfactory)
876
                  job_id = handler.POST()
877

    
878
                  cl = clfactory.GetNextClient()
879
                  self.assertRaises(IndexError, clfactory.GetNextClient)
880

    
881
                  (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
882
                  self.assertEqual(job_id, exp_job_id)
883
                  self.assertRaises(IndexError, cl.GetNextSubmittedJob)
884

    
885
                  self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
886
                  self.assertEqual(op.instance_name, name)
887
                  self.assertEqual(op.mode, mode)
888
                  self.assertEqual(op.disk_template, disk_template)
889
                  self.assertEqual(op.dry_run, dry_run)
890
                  self.assertEqual(len(op.disks), len(disks))
891
                  self.assertEqual(len(op.nics), len(nics))
892

    
893
                  for opdisk, disk in zip(op.disks, disks):
894
                    for key in constants.IDISK_PARAMS:
895
                      self.assertEqual(opdisk.get(key), disk.get(key))
896
                    self.assertFalse("unknown" in opdisk)
897

    
898
                  for opnic, nic in zip(op.nics, nics):
899
                    for key in constants.INIC_PARAMS:
900
                      self.assertEqual(opnic.get(key), nic.get(key))
901
                    self.assertFalse("unknown" in opnic)
902
                    self.assertFalse("foobar" in opnic)
903

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

    
909
                  if hvparams is None:
910
                    self.assertFalse(hasattr(op, "hvparams"))
911
                  else:
912
                    self.assertEqualValues(op.hvparams, hvparams)
913

    
914
  def testLegacyName(self):
915
    clfactory = _FakeClientFactory(_FakeClient)
916

    
917
    name = "inst29128.example.com"
918
    data = {
919
      rlib2._REQ_DATA_VERSION: 1,
920
      "name": name,
921
      "disks": [],
922
      "nics": [],
923
      "mode": constants.INSTANCE_CREATE,
924
      "disk_template": constants.DT_PLAIN,
925
      }
926

    
927
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
928
    job_id = handler.POST()
929

    
930
    cl = clfactory.GetNextClient()
931
    self.assertRaises(IndexError, clfactory.GetNextClient)
932

    
933
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
934
    self.assertEqual(job_id, exp_job_id)
935
    self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
936
    self.assertEqual(op.instance_name, name)
937
    self.assertFalse(hasattr(op, "name"))
938
    self.assertFalse(op.dry_run)
939

    
940
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
941

    
942
    # Define both
943
    data["instance_name"] = "other.example.com"
944
    assert "name" in data and "instance_name" in data
945
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
946
    self.assertRaises(http.HttpBadRequest, handler.POST)
947
    self.assertRaises(IndexError, clfactory.GetNextClient)
948

    
949
  def testLegacyOs(self):
950
    clfactory = _FakeClientFactory(_FakeClient)
951

    
952
    name = "inst4673.example.com"
953
    os = "linux29206"
954
    data = {
955
      rlib2._REQ_DATA_VERSION: 1,
956
      "name": name,
957
      "os_type": os,
958
      "disks": [],
959
      "nics": [],
960
      "mode": constants.INSTANCE_CREATE,
961
      "disk_template": constants.DT_PLAIN,
962
      }
963

    
964
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
965
    job_id = handler.POST()
966

    
967
    cl = clfactory.GetNextClient()
968
    self.assertRaises(IndexError, clfactory.GetNextClient)
969

    
970
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
971
    self.assertEqual(job_id, exp_job_id)
972
    self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
973
    self.assertEqual(op.instance_name, name)
974
    self.assertEqual(op.os_type, os)
975
    self.assertFalse(hasattr(op, "os"))
976
    self.assertFalse(op.dry_run)
977

    
978
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
979

    
980
    # Define both
981
    data["os"] = "linux9584"
982
    assert "os" in data and "os_type" in data
983
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
984
    self.assertRaises(http.HttpBadRequest, handler.POST)
985

    
986
  def testErrors(self):
987
    clfactory = _FakeClientFactory(_FakeClient)
988

    
989
    # Test all required fields
990
    reqfields = {
991
      rlib2._REQ_DATA_VERSION: 1,
992
      "name": "inst1.example.com",
993
      "disks": [],
994
      "nics": [],
995
      "mode": constants.INSTANCE_CREATE,
996
      "disk_template": constants.DT_PLAIN,
997
      }
998

    
999
    for name in reqfields.keys():
1000
      data = dict(i for i in reqfields.iteritems() if i[0] != name)
1001

    
1002
      handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1003
      self.assertRaises(http.HttpBadRequest, handler.POST)
1004
      self.assertRaises(IndexError, clfactory.GetNextClient)
1005

    
1006
    # Invalid disks and nics
1007
    for field in ["disks", "nics"]:
1008
      invalid_values = [None, 1, "", {}, [1, 2, 3], ["hda1", "hda2"],
1009
                        [{"_unknown_": False, }]]
1010

    
1011
      for invvalue in invalid_values:
1012
        data = reqfields.copy()
1013
        data[field] = invvalue
1014
        handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1015
        self.assertRaises(http.HttpBadRequest, handler.POST)
1016
        self.assertRaises(IndexError, clfactory.GetNextClient)
1017

    
1018
  def testVersion(self):
1019
    clfactory = _FakeClientFactory(_FakeClient)
1020

    
1021
    # No version field
1022
    data = {
1023
      "name": "inst1.example.com",
1024
      "disks": [],
1025
      "nics": [],
1026
      "mode": constants.INSTANCE_CREATE,
1027
      "disk_template": constants.DT_PLAIN,
1028
      }
1029

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

    
1033
    # Old and incorrect versions
1034
    for version in [0, -1, 10483, "Hello World"]:
1035
      data[rlib2._REQ_DATA_VERSION] = version
1036

    
1037
      handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1038
      self.assertRaises(http.HttpBadRequest, handler.POST)
1039

    
1040
      self.assertRaises(IndexError, clfactory.GetNextClient)
1041

    
1042
    # Correct version
1043
    data[rlib2._REQ_DATA_VERSION] = 1
1044
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1045
    job_id = handler.POST()
1046

    
1047
    cl = clfactory.GetNextClient()
1048
    self.assertRaises(IndexError, clfactory.GetNextClient)
1049

    
1050
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1051
    self.assertEqual(job_id, exp_job_id)
1052
    self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
1053
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1054

    
1055

    
1056
class TestBackupExport(unittest.TestCase):
1057
  def test(self):
1058
    clfactory = _FakeClientFactory(_FakeClient)
1059

    
1060
    name = "instmoo"
1061
    data = {
1062
      "mode": constants.EXPORT_MODE_REMOTE,
1063
      "destination": [(1, 2, 3), (99, 99, 99)],
1064
      "shutdown": True,
1065
      "remove_instance": True,
1066
      "x509_key_name": ["name", "hash"],
1067
      "destination_x509_ca": "---cert---"
1068
      }
1069

    
1070
    handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
1071
                             data, clfactory)
1072
    job_id = handler.PUT()
1073

    
1074
    cl = clfactory.GetNextClient()
1075
    self.assertRaises(IndexError, clfactory.GetNextClient)
1076

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

    
1090
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1091

    
1092
  def testDefaults(self):
1093
    clfactory = _FakeClientFactory(_FakeClient)
1094

    
1095
    name = "inst1"
1096
    data = {
1097
      "destination": "node2",
1098
      "shutdown": False,
1099
      }
1100

    
1101
    handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
1102
                             data, clfactory)
1103
    job_id = handler.PUT()
1104

    
1105
    cl = clfactory.GetNextClient()
1106
    self.assertRaises(IndexError, clfactory.GetNextClient)
1107

    
1108
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1109
    self.assertEqual(job_id, exp_job_id)
1110
    self.assertTrue(isinstance(op, opcodes.OpBackupExport))
1111
    self.assertEqual(op.instance_name, name)
1112
    self.assertEqual(op.target_node, "node2")
1113
    self.assertFalse(hasattr(op, "mode"))
1114
    self.assertFalse(hasattr(op, "remove_instance"))
1115
    self.assertFalse(hasattr(op, "destination"))
1116
    self.assertFalse(hasattr(op, "dry_run"))
1117
    self.assertFalse(hasattr(op, "force"))
1118

    
1119
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1120

    
1121
  def testErrors(self):
1122
    clfactory = _FakeClientFactory(_FakeClient)
1123

    
1124
    for value in ["True", "False"]:
1125
      handler = _CreateHandler(rlib2.R_2_instances_name_export, ["err1"], {}, {
1126
        "remove_instance": value,
1127
        }, clfactory)
1128
      self.assertRaises(http.HttpBadRequest, handler.PUT)
1129

    
1130

    
1131
class TestInstanceMigrate(testutils.GanetiTestCase):
1132
  def test(self):
1133
    clfactory = _FakeClientFactory(_FakeClient)
1134

    
1135
    name = "instYooho6ek"
1136

    
1137
    for cleanup in [False, True]:
1138
      for mode in constants.HT_MIGRATION_MODES:
1139
        data = {
1140
          "cleanup": cleanup,
1141
          "mode": mode,
1142
          }
1143

    
1144
        handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {},
1145
                                 data, clfactory)
1146
        job_id = handler.PUT()
1147

    
1148
        cl = clfactory.GetNextClient()
1149
        self.assertRaises(IndexError, clfactory.GetNextClient)
1150

    
1151
        (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1152
        self.assertEqual(job_id, exp_job_id)
1153
        self.assertTrue(isinstance(op, opcodes.OpInstanceMigrate))
1154
        self.assertEqual(op.instance_name, name)
1155
        self.assertEqual(op.mode, mode)
1156
        self.assertEqual(op.cleanup, cleanup)
1157
        self.assertFalse(hasattr(op, "dry_run"))
1158
        self.assertFalse(hasattr(op, "force"))
1159

    
1160
        self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1161

    
1162
  def testDefaults(self):
1163
    clfactory = _FakeClientFactory(_FakeClient)
1164

    
1165
    name = "instnohZeex0"
1166

    
1167
    handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {}, {},
1168
                             clfactory)
1169
    job_id = handler.PUT()
1170

    
1171
    cl = clfactory.GetNextClient()
1172
    self.assertRaises(IndexError, clfactory.GetNextClient)
1173

    
1174
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1175
    self.assertEqual(job_id, exp_job_id)
1176
    self.assertTrue(isinstance(op, opcodes.OpInstanceMigrate))
1177
    self.assertEqual(op.instance_name, name)
1178
    self.assertFalse(hasattr(op, "mode"))
1179
    self.assertFalse(hasattr(op, "cleanup"))
1180
    self.assertFalse(hasattr(op, "dry_run"))
1181
    self.assertFalse(hasattr(op, "force"))
1182

    
1183
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1184

    
1185

    
1186
class TestParseRenameInstanceRequest(testutils.GanetiTestCase):
1187
  def test(self):
1188
    clfactory = _FakeClientFactory(_FakeClient)
1189

    
1190
    name = "instij0eeph7"
1191

    
1192
    for new_name in ["ua0aiyoo", "fai3ongi"]:
1193
      for ip_check in [False, True]:
1194
        for name_check in [False, True]:
1195
          data = {
1196
            "new_name": new_name,
1197
            "ip_check": ip_check,
1198
            "name_check": name_check,
1199
            }
1200

    
1201
          handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
1202
                                   {}, data, clfactory)
1203
          job_id = handler.PUT()
1204

    
1205
          cl = clfactory.GetNextClient()
1206
          self.assertRaises(IndexError, clfactory.GetNextClient)
1207

    
1208
          (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1209
          self.assertEqual(job_id, exp_job_id)
1210
          self.assertTrue(isinstance(op, opcodes.OpInstanceRename))
1211
          self.assertEqual(op.instance_name, name)
1212
          self.assertEqual(op.new_name, new_name)
1213
          self.assertEqual(op.ip_check, ip_check)
1214
          self.assertEqual(op.name_check, name_check)
1215
          self.assertFalse(hasattr(op, "dry_run"))
1216
          self.assertFalse(hasattr(op, "force"))
1217

    
1218
          self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1219

    
1220
  def testDefaults(self):
1221
    clfactory = _FakeClientFactory(_FakeClient)
1222

    
1223
    name = "instahchie3t"
1224

    
1225
    for new_name in ["thag9mek", "quees7oh"]:
1226
      data = {
1227
        "new_name": new_name,
1228
        }
1229

    
1230
      handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
1231
                               {}, data, clfactory)
1232
      job_id = handler.PUT()
1233

    
1234
      cl = clfactory.GetNextClient()
1235
      self.assertRaises(IndexError, clfactory.GetNextClient)
1236

    
1237
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1238
      self.assertEqual(job_id, exp_job_id)
1239
      self.assertTrue(isinstance(op, opcodes.OpInstanceRename))
1240
      self.assertEqual(op.instance_name, name)
1241
      self.assertEqual(op.new_name, new_name)
1242
      self.assertFalse(hasattr(op, "ip_check"))
1243
      self.assertFalse(hasattr(op, "name_check"))
1244
      self.assertFalse(hasattr(op, "dry_run"))
1245
      self.assertFalse(hasattr(op, "force"))
1246

    
1247
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1248

    
1249

    
1250
class TestParseModifyInstanceRequest(unittest.TestCase):
1251
  def test(self):
1252
    clfactory = _FakeClientFactory(_FakeClient)
1253

    
1254
    name = "instush8gah"
1255

    
1256
    test_disks = [
1257
      [],
1258
      [(1, { constants.IDISK_MODE: constants.DISK_RDWR, })],
1259
      ]
1260

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

    
1278
                  handler = _CreateHandler(rlib2.R_2_instances_name_modify,
1279
                                           [name], {}, data, clfactory)
1280
                  job_id = handler.PUT()
1281

    
1282
                  cl = clfactory.GetNextClient()
1283
                  self.assertRaises(IndexError, clfactory.GetNextClient)
1284

    
1285
                  (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1286
                  self.assertEqual(job_id, exp_job_id)
1287
                  self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
1288
                  self.assertEqual(op.instance_name, name)
1289
                  self.assertEqual(op.hvparams, hvparams)
1290
                  self.assertEqual(op.beparams, beparams)
1291
                  self.assertEqual(op.osparams, osparams)
1292
                  self.assertEqual(op.force, force)
1293
                  self.assertEqual(op.nics, nics)
1294
                  self.assertEqual(op.disks, disks)
1295
                  self.assertEqual(op.disk_template, disk_template)
1296
                  self.assertFalse(hasattr(op, "remote_node"))
1297
                  self.assertFalse(hasattr(op, "os_name"))
1298
                  self.assertFalse(hasattr(op, "force_variant"))
1299
                  self.assertFalse(hasattr(op, "dry_run"))
1300

    
1301
                  self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1302

    
1303
  def testDefaults(self):
1304
    clfactory = _FakeClientFactory(_FakeClient)
1305

    
1306
    name = "instir8aish31"
1307

    
1308
    handler = _CreateHandler(rlib2.R_2_instances_name_modify,
1309
                             [name], {}, {}, clfactory)
1310
    job_id = handler.PUT()
1311

    
1312
    cl = clfactory.GetNextClient()
1313
    self.assertRaises(IndexError, clfactory.GetNextClient)
1314

    
1315
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1316
    self.assertEqual(job_id, exp_job_id)
1317
    self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
1318
    self.assertEqual(op.instance_name, name)
1319

    
1320
    for i in ["hvparams", "beparams", "osparams", "force", "nics", "disks",
1321
              "disk_template", "remote_node", "os_name", "force_variant"]:
1322
      self.assertFalse(hasattr(op, i))
1323

    
1324

    
1325
class TestParseInstanceReinstallRequest(testutils.GanetiTestCase):
1326
  def setUp(self):
1327
    testutils.GanetiTestCase.setUp(self)
1328

    
1329
    self.Parse = rlib2._ParseInstanceReinstallRequest
1330

    
1331
  def _Check(self, ops, name):
1332
    expcls = [
1333
      opcodes.OpInstanceShutdown,
1334
      opcodes.OpInstanceReinstall,
1335
      opcodes.OpInstanceStartup,
1336
      ]
1337

    
1338
    self.assert_(compat.all(isinstance(op, exp)
1339
                            for op, exp in zip(ops, expcls)))
1340
    self.assert_(compat.all(op.instance_name == name for op in ops))
1341

    
1342
  def test(self):
1343
    name = "shoo0tihohma"
1344

    
1345
    ops = self.Parse(name, {"os": "sys1", "start": True,})
1346
    self.assertEqual(len(ops), 3)
1347
    self._Check(ops, name)
1348
    self.assertEqual(ops[1].os_type, "sys1")
1349
    self.assertFalse(ops[1].osparams)
1350

    
1351
    ops = self.Parse(name, {"os": "sys2", "start": False,})
1352
    self.assertEqual(len(ops), 2)
1353
    self._Check(ops, name)
1354
    self.assertEqual(ops[1].os_type, "sys2")
1355

    
1356
    osparams = {
1357
      "reformat": "1",
1358
      }
1359
    ops = self.Parse(name, {"os": "sys4035", "start": True,
1360
                            "osparams": osparams,})
1361
    self.assertEqual(len(ops), 3)
1362
    self._Check(ops, name)
1363
    self.assertEqual(ops[1].os_type, "sys4035")
1364
    self.assertEqual(ops[1].osparams, osparams)
1365

    
1366
  def testDefaults(self):
1367
    name = "noolee0g"
1368

    
1369
    ops = self.Parse(name, {"os": "linux1"})
1370
    self.assertEqual(len(ops), 3)
1371
    self._Check(ops, name)
1372
    self.assertEqual(ops[1].os_type, "linux1")
1373
    self.assertFalse(ops[1].osparams)
1374

    
1375
  def testErrors(self):
1376
    self.assertRaises(http.HttpBadRequest, self.Parse,
1377
                      "foo", "not a dictionary")
1378

    
1379

    
1380
class TestGroupRename(unittest.TestCase):
1381
  def test(self):
1382
    clfactory = _FakeClientFactory(_FakeClient)
1383

    
1384
    name = "group608242564"
1385
    data = {
1386
      "new_name": "ua0aiyoo15112",
1387
      }
1388

    
1389
    handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {}, data,
1390
                             clfactory)
1391
    job_id = handler.PUT()
1392

    
1393
    cl = clfactory.GetNextClient()
1394
    self.assertRaises(IndexError, clfactory.GetNextClient)
1395

    
1396
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1397
    self.assertEqual(job_id, exp_job_id)
1398

    
1399
    self.assertTrue(isinstance(op, opcodes.OpGroupRename))
1400
    self.assertEqual(op.group_name, name)
1401
    self.assertEqual(op.new_name, "ua0aiyoo15112")
1402
    self.assertFalse(op.dry_run)
1403
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1404

    
1405
  def testDryRun(self):
1406
    clfactory = _FakeClientFactory(_FakeClient)
1407

    
1408
    name = "group28548"
1409
    data = {
1410
      "new_name": "ua0aiyoo",
1411
      }
1412

    
1413
    handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {
1414
      "dry-run": ["1"],
1415
      }, data, clfactory)
1416
    job_id = handler.PUT()
1417

    
1418
    cl = clfactory.GetNextClient()
1419
    self.assertRaises(IndexError, clfactory.GetNextClient)
1420

    
1421
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1422
    self.assertEqual(job_id, exp_job_id)
1423

    
1424
    self.assertTrue(isinstance(op, opcodes.OpGroupRename))
1425
    self.assertEqual(op.group_name, name)
1426
    self.assertEqual(op.new_name, "ua0aiyoo")
1427
    self.assertTrue(op.dry_run)
1428
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1429

    
1430

    
1431
class TestInstanceReplaceDisks(unittest.TestCase):
1432
  def test(self):
1433
    clfactory = _FakeClientFactory(_FakeClient)
1434

    
1435
    name = "inst22568"
1436

    
1437
    for disks in [range(1, 4), "1,2,3", "1, 2, 3"]:
1438
      data = {
1439
        "mode": constants.REPLACE_DISK_SEC,
1440
        "disks": disks,
1441
        "iallocator": "myalloc",
1442
        }
1443

    
1444
      handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1445
                               [name], {}, data, clfactory)
1446
      job_id = handler.POST()
1447

    
1448
      cl = clfactory.GetNextClient()
1449
      self.assertRaises(IndexError, clfactory.GetNextClient)
1450

    
1451
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1452
      self.assertEqual(job_id, exp_job_id)
1453

    
1454
      self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
1455
      self.assertEqual(op.instance_name, name)
1456
      self.assertEqual(op.mode, constants.REPLACE_DISK_SEC)
1457
      self.assertEqual(op.disks, [1, 2, 3])
1458
      self.assertEqual(op.iallocator, "myalloc")
1459
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1460

    
1461
  def testDefaults(self):
1462
    clfactory = _FakeClientFactory(_FakeClient)
1463

    
1464
    name = "inst11413"
1465
    data = {
1466
      "mode": constants.REPLACE_DISK_AUTO,
1467
      }
1468

    
1469
    handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1470
                             [name], {}, data, clfactory)
1471
    job_id = handler.POST()
1472

    
1473
    cl = clfactory.GetNextClient()
1474
    self.assertRaises(IndexError, clfactory.GetNextClient)
1475

    
1476
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1477
    self.assertEqual(job_id, exp_job_id)
1478

    
1479
    self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
1480
    self.assertEqual(op.instance_name, name)
1481
    self.assertEqual(op.mode, constants.REPLACE_DISK_AUTO)
1482
    self.assertFalse(hasattr(op, "iallocator"))
1483
    self.assertFalse(hasattr(op, "disks"))
1484
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1485

    
1486
  def testNoDisks(self):
1487
    clfactory = _FakeClientFactory(_FakeClient)
1488

    
1489
    handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1490
                             ["inst20661"], {}, {}, clfactory)
1491
    self.assertRaises(http.HttpBadRequest, handler.POST)
1492

    
1493
    for disks in [None, "", {}]:
1494
      handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1495
                               ["inst20661"], {}, {
1496
        "disks": disks,
1497
        }, clfactory)
1498
      self.assertRaises(http.HttpBadRequest, handler.POST)
1499

    
1500
  def testWrong(self):
1501
    clfactory = _FakeClientFactory(_FakeClient)
1502

    
1503
    data = {
1504
      "mode": constants.REPLACE_DISK_AUTO,
1505
      "disks": "hello world",
1506
      }
1507

    
1508
    handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1509
                             ["foo"], {}, data, clfactory)
1510
    self.assertRaises(http.HttpBadRequest, handler.POST)
1511

    
1512

    
1513
class TestGroupModify(unittest.TestCase):
1514
  def test(self):
1515
    clfactory = _FakeClientFactory(_FakeClient)
1516

    
1517
    name = "group6002"
1518

    
1519
    for policy in constants.VALID_ALLOC_POLICIES:
1520
      data = {
1521
        "alloc_policy": policy,
1522
        }
1523

    
1524
      handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, data,
1525
                               clfactory)
1526
      job_id = handler.PUT()
1527

    
1528
      cl = clfactory.GetNextClient()
1529
      self.assertRaises(IndexError, clfactory.GetNextClient)
1530

    
1531
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1532
      self.assertEqual(job_id, exp_job_id)
1533

    
1534
      self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
1535
      self.assertEqual(op.group_name, name)
1536
      self.assertEqual(op.alloc_policy, policy)
1537
      self.assertFalse(hasattr(op, "dry_run"))
1538
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1539

    
1540
  def testUnknownPolicy(self):
1541
    clfactory = _FakeClientFactory(_FakeClient)
1542

    
1543
    data = {
1544
      "alloc_policy": "_unknown_policy_",
1545
      }
1546

    
1547
    handler = _CreateHandler(rlib2.R_2_groups_name_modify, ["xyz"], {}, data,
1548
                             clfactory)
1549
    self.assertRaises(http.HttpBadRequest, handler.PUT)
1550
    self.assertRaises(IndexError, clfactory.GetNextClient)
1551

    
1552
  def testDefaults(self):
1553
    clfactory = _FakeClientFactory(_FakeClient)
1554

    
1555
    name = "group6679"
1556

    
1557
    handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, {},
1558
                             clfactory)
1559
    job_id = handler.PUT()
1560

    
1561
    cl = clfactory.GetNextClient()
1562
    self.assertRaises(IndexError, clfactory.GetNextClient)
1563

    
1564
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1565
    self.assertEqual(job_id, exp_job_id)
1566

    
1567
    self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
1568
    self.assertEqual(op.group_name, name)
1569
    self.assertFalse(hasattr(op, "alloc_policy"))
1570
    self.assertFalse(hasattr(op, "dry_run"))
1571
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1572

    
1573

    
1574
class TestGroupAdd(unittest.TestCase):
1575
  def test(self):
1576
    name = "group3618"
1577
    clfactory = _FakeClientFactory(_FakeClient)
1578

    
1579
    for policy in constants.VALID_ALLOC_POLICIES:
1580
      data = {
1581
        "group_name": name,
1582
        "alloc_policy": policy,
1583
        }
1584

    
1585
      handler = _CreateHandler(rlib2.R_2_groups, [], {}, data,
1586
                               clfactory)
1587
      job_id = handler.POST()
1588

    
1589
      cl = clfactory.GetNextClient()
1590
      self.assertRaises(IndexError, clfactory.GetNextClient)
1591

    
1592
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1593
      self.assertEqual(job_id, exp_job_id)
1594

    
1595
      self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1596
      self.assertEqual(op.group_name, name)
1597
      self.assertEqual(op.alloc_policy, policy)
1598
      self.assertFalse(op.dry_run)
1599
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1600

    
1601
  def testUnknownPolicy(self):
1602
    clfactory = _FakeClientFactory(_FakeClient)
1603

    
1604
    data = {
1605
      "alloc_policy": "_unknown_policy_",
1606
      }
1607

    
1608
    handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1609
    self.assertRaises(http.HttpBadRequest, handler.POST)
1610
    self.assertRaises(IndexError, clfactory.GetNextClient)
1611

    
1612
  def testDefaults(self):
1613
    clfactory = _FakeClientFactory(_FakeClient)
1614

    
1615
    name = "group15395"
1616
    data = {
1617
      "group_name": name,
1618
      }
1619

    
1620
    handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1621
    job_id = handler.POST()
1622

    
1623
    cl = clfactory.GetNextClient()
1624
    self.assertRaises(IndexError, clfactory.GetNextClient)
1625

    
1626
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1627
    self.assertEqual(job_id, exp_job_id)
1628

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

    
1634
  def testLegacyName(self):
1635
    clfactory = _FakeClientFactory(_FakeClient)
1636

    
1637
    name = "group29852"
1638
    data = {
1639
      "name": name,
1640
      }
1641

    
1642
    handler = _CreateHandler(rlib2.R_2_groups, [], {
1643
      "dry-run": ["1"],
1644
      }, data, clfactory)
1645
    job_id = handler.POST()
1646

    
1647
    cl = clfactory.GetNextClient()
1648
    self.assertRaises(IndexError, clfactory.GetNextClient)
1649

    
1650
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1651
    self.assertEqual(job_id, exp_job_id)
1652

    
1653
    self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1654
    self.assertEqual(op.group_name, name)
1655
    self.assertFalse(hasattr(op, "alloc_policy"))
1656
    self.assertTrue(op.dry_run)
1657

    
1658

    
1659
class TestNodeRole(unittest.TestCase):
1660
  def test(self):
1661
    clfactory = _FakeClientFactory(_FakeClient)
1662

    
1663
    for role in rlib2._NR_MAP.values():
1664
      handler = _CreateHandler(rlib2.R_2_nodes_name_role,
1665
                               ["node-z"], {}, role, clfactory)
1666
      if role == rlib2._NR_MASTER:
1667
        self.assertRaises(http.HttpBadRequest, handler.PUT)
1668
      else:
1669
        job_id = handler.PUT()
1670

    
1671
        cl = clfactory.GetNextClient()
1672
        self.assertRaises(IndexError, clfactory.GetNextClient)
1673

    
1674
        (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1675
        self.assertEqual(job_id, exp_job_id)
1676
        self.assertTrue(isinstance(op, opcodes.OpNodeSetParams))
1677
        self.assertEqual(op.node_name, "node-z")
1678
        self.assertFalse(op.force)
1679
        self.assertFalse(hasattr(op, "dry_run"))
1680

    
1681
        if role == rlib2._NR_REGULAR:
1682
          self.assertFalse(op.drained)
1683
          self.assertFalse(op.offline)
1684
          self.assertFalse(op.master_candidate)
1685
        elif role == rlib2._NR_MASTER_CANDIDATE:
1686
          self.assertFalse(op.drained)
1687
          self.assertFalse(op.offline)
1688
          self.assertTrue(op.master_candidate)
1689
        elif role == rlib2._NR_DRAINED:
1690
          self.assertTrue(op.drained)
1691
          self.assertFalse(op.offline)
1692
          self.assertFalse(op.master_candidate)
1693
        elif role == rlib2._NR_OFFLINE:
1694
          self.assertFalse(op.drained)
1695
          self.assertTrue(op.offline)
1696
          self.assertFalse(op.master_candidate)
1697
        else:
1698
          self.fail("Unknown role '%s'" % role)
1699

    
1700
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1701

    
1702

    
1703
class TestSimpleResources(unittest.TestCase):
1704
  def setUp(self):
1705
    self.clfactory = _FakeClientFactory(_FakeClient)
1706

    
1707
  def tearDown(self):
1708
    self.assertRaises(IndexError, self.clfactory.GetNextClient)
1709

    
1710
  def testFeatures(self):
1711
    handler = _CreateHandler(rlib2.R_2_features, [], {}, None, self.clfactory)
1712
    self.assertEqual(set(handler.GET()), rlib2.ALL_FEATURES)
1713

    
1714
  def testEmpty(self):
1715
    for cls in [rlib2.R_root, rlib2.R_2]:
1716
      handler = _CreateHandler(cls, [], {}, None, self.clfactory)
1717
      self.assertTrue(handler.GET() is None)
1718

    
1719
  def testVersion(self):
1720
    handler = _CreateHandler(rlib2.R_version, [], {}, None, self.clfactory)
1721
    self.assertEqual(handler.GET(), constants.RAPI_VERSION)
1722

    
1723

    
1724
class TestClusterInfo(unittest.TestCase):
1725
  class _ClusterInfoClient:
1726
    def __init__(self, address=None):
1727
      self.cluster_info = None
1728

    
1729
    def QueryClusterInfo(self):
1730
      assert self.cluster_info is None
1731
      self.cluster_info = object()
1732
      return self.cluster_info
1733

    
1734
  def test(self):
1735
    clfactory = _FakeClientFactory(self._ClusterInfoClient)
1736
    handler = _CreateHandler(rlib2.R_2_info, [], {}, None, clfactory)
1737
    result = handler.GET()
1738
    cl = clfactory.GetNextClient()
1739
    self.assertRaises(IndexError, clfactory.GetNextClient)
1740
    self.assertEqual(result, cl.cluster_info)
1741

    
1742

    
1743
class TestInstancesMultiAlloc(unittest.TestCase):
1744
  def testInstanceUpdate(self):
1745
    clfactory = _FakeClientFactory(_FakeClient)
1746
    data = {
1747
      "instances": [{
1748
        "instance_name": "bar",
1749
        "mode": "create",
1750
        }, {
1751
        "instance_name": "foo",
1752
        "mode": "create",
1753
        }],
1754
      }
1755
    handler = _CreateHandler(rlib2.R_2_instances_multi_alloc, [], {}, data,
1756
                             clfactory)
1757
    (body, _) = handler.GetPostOpInput()
1758
    self.assertTrue(compat.all([inst["OP_ID"] == handler.POST_OPCODE.OP_ID
1759
                                for inst in body["instances"]]))
1760

    
1761

    
1762
class TestPermissions(unittest.TestCase):
1763
  def testEquality(self):
1764
    self.assertEqual(rlib2.R_2_query.GET_ACCESS, rlib2.R_2_query.PUT_ACCESS)
1765
    self.assertEqual(rlib2.R_2_query.GET_ACCESS,
1766
                     rlib2.R_2_instances_name_console.GET_ACCESS)
1767

    
1768
  def testMethodAccess(self):
1769
    for handler in connector.CONNECTOR.values():
1770
      for method in baserlib._SUPPORTED_METHODS:
1771
        access = baserlib.GetHandlerAccess(handler, method)
1772
        self.assertFalse(access is None)
1773
        self.assertFalse(set(access) - rapi.RAPI_ACCESS_ALL,
1774
                         msg=("Handler '%s' uses unknown access options for"
1775
                              " method %s" % (handler, method)))
1776
        self.assertTrue(rapi.RAPI_ACCESS_READ not in access or
1777
                        rapi.RAPI_ACCESS_WRITE in access,
1778
                        msg=("Handler '%s' gives query, but not write access"
1779
                             " for method %s (the latter includes query and"
1780
                             " should therefore be given as well)" %
1781
                             (handler, method)))
1782

    
1783

    
1784
if __name__ == "__main__":
1785
  testutils.GanetiTestProgram()