Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.rapi.rlib2_unittest.py @ 4a90bd4f

History | View | Annotate | Download (57.7 kB)

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

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

    
21

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

24
"""
25

    
26

    
27
import unittest
28
import itertools
29
import random
30

    
31
from ganeti import constants
32
from ganeti import opcodes
33
from ganeti import compat
34
from ganeti import http
35
from ganeti import query
36
from ganeti import luxi
37
from ganeti import errors
38
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,
389
       "System update",
390
      ))
391

    
392
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
393

    
394

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

    
404
    cl = clfactory.GetNextClient()
405
    self.assertRaises(IndexError, clfactory.GetNextClient)
406

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

    
415
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
416

    
417

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

    
426
    cl = clfactory.GetNextClient()
427
    self.assertRaises(IndexError, clfactory.GetNextClient)
428

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

    
436
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
437

    
438

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

    
447
    cl = clfactory.GetNextClient()
448
    self.assertRaises(IndexError, clfactory.GetNextClient)
449

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

    
457
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
458

    
459

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

    
467
    cl = clfactory.GetNextClient()
468
    self.assertRaises(IndexError, clfactory.GetNextClient)
469

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

    
477
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
478

    
479

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

    
487
    cl = clfactory.GetNextClient()
488
    self.assertRaises(IndexError, clfactory.GetNextClient)
489

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

    
497
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
498

    
499

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

    
507
    cl = clfactory.GetNextClient()
508
    self.assertRaises(IndexError, clfactory.GetNextClient)
509

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

    
517
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
518

    
519

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

    
530
    cl = clfactory.GetNextClient()
531
    self.assertRaises(IndexError, clfactory.GetNextClient)
532

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

    
542
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
543

    
544

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

    
555
    cl = clfactory.GetNextClient()
556
    self.assertRaises(IndexError, clfactory.GetNextClient)
557

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

    
566
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
567

    
568

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

    
576
    cl = clfactory.GetNextClient()
577
    self.assertRaises(IndexError, clfactory.GetNextClient)
578

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

    
586
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
587

    
588

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

    
600
    cl = clfactory.GetNextClient()
601
    self.assertRaises(IndexError, clfactory.GetNextClient)
602

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

    
612
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
613

    
614
  def testErrors(self):
615
    clfactory = _FakeClientFactory(_FakeClient)
616

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

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

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

    
639

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

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

    
650
      if allocatable is not None:
651
        queryargs["allocatable"] = allocatable
652

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

    
657
      cl = clfactory.GetNextClient()
658
      self.assertRaises(IndexError, clfactory.GetNextClient)
659

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

    
676
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
677

    
678
  def testErrors(self):
679
    clfactory = _FakeClientFactory(_FakeClient)
680

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

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

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

    
707

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

    
719
    cl = clfactory.GetNextClient()
720
    self.assertRaises(IndexError, clfactory.GetNextClient)
721

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

    
731
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
732

    
733
  def testErrors(self):
734
    clfactory = _FakeClientFactory(_FakeClient)
735

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

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

    
752

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

    
761
  def testSetAndDelete(self):
762
    clfactory = _FakeClientFactory(_FakeClient)
763

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

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

    
777
        cl = clfactory.GetNextClient()
778
        self.assertRaises(IndexError, clfactory.GetNextClient)
779

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

    
792
        self.assertRaises(IndexError, cl.GetNextSubmittedJob)
793

    
794

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

    
799
    name = "inst863.example.com"
800

    
801
    disk_variants = [
802
      # No disks
803
      [],
804

    
805
      # Two disks
806
      [{"size": 5, }, {"size": 100, }],
807

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

    
812
    nic_variants = [
813
      # No NIC
814
      [],
815

    
816
      # Three NICs
817
      [{}, {}, {}],
818

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

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

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

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

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

    
870
                  if beparams is not None:
871
                    data["beparams"] = beparams
872

    
873
                  if hvparams is not None:
874
                    data["hvparams"] = hvparams
875

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

    
880
                  cl = clfactory.GetNextClient()
881
                  self.assertRaises(IndexError, clfactory.GetNextClient)
882

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

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

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

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

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

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

    
916
  def testLegacyName(self):
917
    clfactory = _FakeClientFactory(_FakeClient)
918

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

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

    
932
    cl = clfactory.GetNextClient()
933
    self.assertRaises(IndexError, clfactory.GetNextClient)
934

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

    
942
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
943

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

    
951
  def testLegacyOs(self):
952
    clfactory = _FakeClientFactory(_FakeClient)
953

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

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

    
969
    cl = clfactory.GetNextClient()
970
    self.assertRaises(IndexError, clfactory.GetNextClient)
971

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

    
980
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
981

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

    
988
  def testErrors(self):
989
    clfactory = _FakeClientFactory(_FakeClient)
990

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

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

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

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

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

    
1020
  def testVersion(self):
1021
    clfactory = _FakeClientFactory(_FakeClient)
1022

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

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

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

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

    
1042
      self.assertRaises(IndexError, clfactory.GetNextClient)
1043

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

    
1049
    cl = clfactory.GetNextClient()
1050
    self.assertRaises(IndexError, clfactory.GetNextClient)
1051

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

    
1057

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

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

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

    
1076
    cl = clfactory.GetNextClient()
1077
    self.assertRaises(IndexError, clfactory.GetNextClient)
1078

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

    
1092
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1093

    
1094
  def testDefaults(self):
1095
    clfactory = _FakeClientFactory(_FakeClient)
1096

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

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

    
1107
    cl = clfactory.GetNextClient()
1108
    self.assertRaises(IndexError, clfactory.GetNextClient)
1109

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

    
1121
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1122

    
1123
  def testErrors(self):
1124
    clfactory = _FakeClientFactory(_FakeClient)
1125

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

    
1132

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

    
1137
    name = "instYooho6ek"
1138

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

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

    
1150
        cl = clfactory.GetNextClient()
1151
        self.assertRaises(IndexError, clfactory.GetNextClient)
1152

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

    
1162
        self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1163

    
1164
  def testDefaults(self):
1165
    clfactory = _FakeClientFactory(_FakeClient)
1166

    
1167
    name = "instnohZeex0"
1168

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

    
1173
    cl = clfactory.GetNextClient()
1174
    self.assertRaises(IndexError, clfactory.GetNextClient)
1175

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

    
1185
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1186

    
1187

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

    
1192
    name = "instij0eeph7"
1193

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

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

    
1207
          cl = clfactory.GetNextClient()
1208
          self.assertRaises(IndexError, clfactory.GetNextClient)
1209

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

    
1220
          self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1221

    
1222
  def testDefaults(self):
1223
    clfactory = _FakeClientFactory(_FakeClient)
1224

    
1225
    name = "instahchie3t"
1226

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

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

    
1236
      cl = clfactory.GetNextClient()
1237
      self.assertRaises(IndexError, clfactory.GetNextClient)
1238

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

    
1249
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1250

    
1251

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

    
1256
    name = "instush8gah"
1257

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

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

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

    
1284
                  cl = clfactory.GetNextClient()
1285
                  self.assertRaises(IndexError, clfactory.GetNextClient)
1286

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

    
1303
                  self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1304

    
1305
  def testDefaults(self):
1306
    clfactory = _FakeClientFactory(_FakeClient)
1307

    
1308
    name = "instir8aish31"
1309

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

    
1314
    cl = clfactory.GetNextClient()
1315
    self.assertRaises(IndexError, clfactory.GetNextClient)
1316

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

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

    
1326

    
1327
class TestParseInstanceReinstallRequest(testutils.GanetiTestCase):
1328
  def setUp(self):
1329
    testutils.GanetiTestCase.setUp(self)
1330

    
1331
    self.Parse = rlib2._ParseInstanceReinstallRequest
1332

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

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

    
1344
  def test(self):
1345
    name = "shoo0tihohma"
1346

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

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

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

    
1368
  def testDefaults(self):
1369
    name = "noolee0g"
1370

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

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

    
1381

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

    
1386
    name = "group608242564"
1387
    data = {
1388
      "new_name": "ua0aiyoo15112",
1389
      }
1390

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

    
1395
    cl = clfactory.GetNextClient()
1396
    self.assertRaises(IndexError, clfactory.GetNextClient)
1397

    
1398
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1399
    self.assertEqual(job_id, exp_job_id)
1400

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

    
1407
  def testDryRun(self):
1408
    clfactory = _FakeClientFactory(_FakeClient)
1409

    
1410
    name = "group28548"
1411
    data = {
1412
      "new_name": "ua0aiyoo",
1413
      }
1414

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

    
1420
    cl = clfactory.GetNextClient()
1421
    self.assertRaises(IndexError, clfactory.GetNextClient)
1422

    
1423
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1424
    self.assertEqual(job_id, exp_job_id)
1425

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

    
1432

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

    
1437
    name = "inst22568"
1438

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

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

    
1450
      cl = clfactory.GetNextClient()
1451
      self.assertRaises(IndexError, clfactory.GetNextClient)
1452

    
1453
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1454
      self.assertEqual(job_id, exp_job_id)
1455

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

    
1463
  def testDefaults(self):
1464
    clfactory = _FakeClientFactory(_FakeClient)
1465

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

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

    
1475
    cl = clfactory.GetNextClient()
1476
    self.assertRaises(IndexError, clfactory.GetNextClient)
1477

    
1478
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1479
    self.assertEqual(job_id, exp_job_id)
1480

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

    
1488
  def testNoDisks(self):
1489
    clfactory = _FakeClientFactory(_FakeClient)
1490

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

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

    
1502
  def testWrong(self):
1503
    clfactory = _FakeClientFactory(_FakeClient)
1504

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

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

    
1514

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

    
1519
    name = "group6002"
1520

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

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

    
1530
      cl = clfactory.GetNextClient()
1531
      self.assertRaises(IndexError, clfactory.GetNextClient)
1532

    
1533
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1534
      self.assertEqual(job_id, exp_job_id)
1535

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

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

    
1545
    data = {
1546
      "alloc_policy": "_unknown_policy_",
1547
      }
1548

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

    
1554
  def testDefaults(self):
1555
    clfactory = _FakeClientFactory(_FakeClient)
1556

    
1557
    name = "group6679"
1558

    
1559
    handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, {},
1560
                             clfactory)
1561
    job_id = handler.PUT()
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.OpGroupSetParams))
1570
    self.assertEqual(op.group_name, name)
1571
    self.assertFalse(hasattr(op, "alloc_policy"))
1572
    self.assertFalse(hasattr(op, "dry_run"))
1573
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1574

    
1575

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

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

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

    
1591
      cl = clfactory.GetNextClient()
1592
      self.assertRaises(IndexError, clfactory.GetNextClient)
1593

    
1594
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1595
      self.assertEqual(job_id, exp_job_id)
1596

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

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

    
1606
    data = {
1607
      "alloc_policy": "_unknown_policy_",
1608
      }
1609

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

    
1614
  def testDefaults(self):
1615
    clfactory = _FakeClientFactory(_FakeClient)
1616

    
1617
    name = "group15395"
1618
    data = {
1619
      "group_name": name,
1620
      }
1621

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

    
1625
    cl = clfactory.GetNextClient()
1626
    self.assertRaises(IndexError, clfactory.GetNextClient)
1627

    
1628
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1629
    self.assertEqual(job_id, exp_job_id)
1630

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

    
1636
  def testLegacyName(self):
1637
    clfactory = _FakeClientFactory(_FakeClient)
1638

    
1639
    name = "group29852"
1640
    data = {
1641
      "name": name,
1642
      }
1643

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

    
1649
    cl = clfactory.GetNextClient()
1650
    self.assertRaises(IndexError, clfactory.GetNextClient)
1651

    
1652
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1653
    self.assertEqual(job_id, exp_job_id)
1654

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

    
1660

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

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

    
1673
        cl = clfactory.GetNextClient()
1674
        self.assertRaises(IndexError, clfactory.GetNextClient)
1675

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

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

    
1702
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1703

    
1704

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

    
1709
  def tearDown(self):
1710
    self.assertRaises(IndexError, self.clfactory.GetNextClient)
1711

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

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

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

    
1725

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

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

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

    
1744

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

    
1763

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

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

    
1784

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