Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (57.6 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
      }, {}, clfactory)
374
    job_id = handler.POST()
375

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

    
379
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
380
    self.assertEqual(job_id, exp_job_id)
381
    self.assertTrue(isinstance(op, opcodes.OpInstanceReboot))
382
    self.assertEqual(op.instance_name, "inst847")
383
    self.assertEqual(op.reboot_type, constants.INSTANCE_REBOOT_HARD)
384
    self.assertTrue(op.ignore_secondaries)
385
    self.assertTrue(op.dry_run)
386

    
387
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
388

    
389

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

    
399
    cl = clfactory.GetNextClient()
400
    self.assertRaises(IndexError, clfactory.GetNextClient)
401

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

    
410
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
411

    
412

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

    
421
    cl = clfactory.GetNextClient()
422
    self.assertRaises(IndexError, clfactory.GetNextClient)
423

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

    
431
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
432

    
433

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

    
442
    cl = clfactory.GetNextClient()
443
    self.assertRaises(IndexError, clfactory.GetNextClient)
444

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

    
452
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
453

    
454

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

    
462
    cl = clfactory.GetNextClient()
463
    self.assertRaises(IndexError, clfactory.GetNextClient)
464

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

    
472
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
473

    
474

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

    
482
    cl = clfactory.GetNextClient()
483
    self.assertRaises(IndexError, clfactory.GetNextClient)
484

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

    
492
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
493

    
494

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

    
502
    cl = clfactory.GetNextClient()
503
    self.assertRaises(IndexError, clfactory.GetNextClient)
504

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

    
512
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
513

    
514

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

    
525
    cl = clfactory.GetNextClient()
526
    self.assertRaises(IndexError, clfactory.GetNextClient)
527

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

    
537
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
538

    
539

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

    
550
    cl = clfactory.GetNextClient()
551
    self.assertRaises(IndexError, clfactory.GetNextClient)
552

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

    
561
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
562

    
563

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

    
571
    cl = clfactory.GetNextClient()
572
    self.assertRaises(IndexError, clfactory.GetNextClient)
573

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

    
581
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
582

    
583

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

    
595
    cl = clfactory.GetNextClient()
596
    self.assertRaises(IndexError, clfactory.GetNextClient)
597

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

    
607
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
608

    
609
  def testErrors(self):
610
    clfactory = _FakeClientFactory(_FakeClient)
611

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

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

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

    
634

    
635
class TestStorageModify(unittest.TestCase):
636
  def test(self):
637
    clfactory = _FakeClientFactory(_FakeClient)
638

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

    
645
      if allocatable is not None:
646
        queryargs["allocatable"] = allocatable
647

    
648
      handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
649
                               ["node9292"], queryargs, {}, clfactory)
650
      job_id = handler.PUT()
651

    
652
      cl = clfactory.GetNextClient()
653
      self.assertRaises(IndexError, clfactory.GetNextClient)
654

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

    
671
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
672

    
673
  def testErrors(self):
674
    clfactory = _FakeClientFactory(_FakeClient)
675

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

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

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

    
702

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

    
714
    cl = clfactory.GetNextClient()
715
    self.assertRaises(IndexError, clfactory.GetNextClient)
716

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

    
726
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
727

    
728
  def testErrors(self):
729
    clfactory = _FakeClientFactory(_FakeClient)
730

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

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

    
747

    
748
class TestTags(unittest.TestCase):
749
  TAG_HANDLERS = [
750
    rlib2.R_2_instances_name_tags,
751
    rlib2.R_2_nodes_name_tags,
752
    rlib2.R_2_groups_name_tags,
753
    rlib2.R_2_tags,
754
    ]
755

    
756
  def testSetAndDelete(self):
757
    clfactory = _FakeClientFactory(_FakeClient)
758

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

    
769
        handler = _CreateHandler(handler, [name], queryargs, {}, clfactory)
770
        job_id = getattr(handler, method)()
771

    
772
        cl = clfactory.GetNextClient()
773
        self.assertRaises(IndexError, clfactory.GetNextClient)
774

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

    
787
        self.assertRaises(IndexError, cl.GetNextSubmittedJob)
788

    
789

    
790
class TestInstanceCreation(testutils.GanetiTestCase):
791
  def test(self):
792
    clfactory = _FakeClientFactory(_FakeClient)
793

    
794
    name = "inst863.example.com"
795

    
796
    disk_variants = [
797
      # No disks
798
      [],
799

    
800
      # Two disks
801
      [{"size": 5, }, {"size": 100, }],
802

    
803
      # Disk with mode
804
      [{"size": 123, "mode": constants.DISK_RDWR, }],
805
      ]
806

    
807
    nic_variants = [
808
      # No NIC
809
      [],
810

    
811
      # Three NICs
812
      [{}, {}, {}],
813

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

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

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

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

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

    
865
                  if beparams is not None:
866
                    data["beparams"] = beparams
867

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

    
871
                  handler = _CreateHandler(rlib2.R_2_instances, [],
872
                                           queryargs, data, clfactory)
873
                  job_id = handler.POST()
874

    
875
                  cl = clfactory.GetNextClient()
876
                  self.assertRaises(IndexError, clfactory.GetNextClient)
877

    
878
                  (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
879
                  self.assertEqual(job_id, exp_job_id)
880
                  self.assertRaises(IndexError, cl.GetNextSubmittedJob)
881

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

    
890
                  for opdisk, disk in zip(op.disks, disks):
891
                    for key in constants.IDISK_PARAMS:
892
                      self.assertEqual(opdisk.get(key), disk.get(key))
893
                    self.assertFalse("unknown" in opdisk)
894

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

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

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

    
911
  def testLegacyName(self):
912
    clfactory = _FakeClientFactory(_FakeClient)
913

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

    
924
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
925
    job_id = handler.POST()
926

    
927
    cl = clfactory.GetNextClient()
928
    self.assertRaises(IndexError, clfactory.GetNextClient)
929

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

    
937
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
938

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

    
946
  def testLegacyOs(self):
947
    clfactory = _FakeClientFactory(_FakeClient)
948

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

    
961
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
962
    job_id = handler.POST()
963

    
964
    cl = clfactory.GetNextClient()
965
    self.assertRaises(IndexError, clfactory.GetNextClient)
966

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

    
975
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
976

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

    
983
  def testErrors(self):
984
    clfactory = _FakeClientFactory(_FakeClient)
985

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

    
996
    for name in reqfields.keys():
997
      data = dict(i for i in reqfields.iteritems() if i[0] != name)
998

    
999
      handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1000
      self.assertRaises(http.HttpBadRequest, handler.POST)
1001
      self.assertRaises(IndexError, clfactory.GetNextClient)
1002

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

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

    
1015
  def testVersion(self):
1016
    clfactory = _FakeClientFactory(_FakeClient)
1017

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

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

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

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

    
1037
      self.assertRaises(IndexError, clfactory.GetNextClient)
1038

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

    
1044
    cl = clfactory.GetNextClient()
1045
    self.assertRaises(IndexError, clfactory.GetNextClient)
1046

    
1047
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1048
    self.assertEqual(job_id, exp_job_id)
1049
    self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
1050
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1051

    
1052

    
1053
class TestBackupExport(unittest.TestCase):
1054
  def test(self):
1055
    clfactory = _FakeClientFactory(_FakeClient)
1056

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

    
1067
    handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
1068
                             data, clfactory)
1069
    job_id = handler.PUT()
1070

    
1071
    cl = clfactory.GetNextClient()
1072
    self.assertRaises(IndexError, clfactory.GetNextClient)
1073

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

    
1087
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1088

    
1089
  def testDefaults(self):
1090
    clfactory = _FakeClientFactory(_FakeClient)
1091

    
1092
    name = "inst1"
1093
    data = {
1094
      "destination": "node2",
1095
      "shutdown": False,
1096
      }
1097

    
1098
    handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
1099
                             data, clfactory)
1100
    job_id = handler.PUT()
1101

    
1102
    cl = clfactory.GetNextClient()
1103
    self.assertRaises(IndexError, clfactory.GetNextClient)
1104

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

    
1116
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1117

    
1118
  def testErrors(self):
1119
    clfactory = _FakeClientFactory(_FakeClient)
1120

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

    
1127

    
1128
class TestInstanceMigrate(testutils.GanetiTestCase):
1129
  def test(self):
1130
    clfactory = _FakeClientFactory(_FakeClient)
1131

    
1132
    name = "instYooho6ek"
1133

    
1134
    for cleanup in [False, True]:
1135
      for mode in constants.HT_MIGRATION_MODES:
1136
        data = {
1137
          "cleanup": cleanup,
1138
          "mode": mode,
1139
          }
1140

    
1141
        handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {},
1142
                                 data, clfactory)
1143
        job_id = handler.PUT()
1144

    
1145
        cl = clfactory.GetNextClient()
1146
        self.assertRaises(IndexError, clfactory.GetNextClient)
1147

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

    
1157
        self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1158

    
1159
  def testDefaults(self):
1160
    clfactory = _FakeClientFactory(_FakeClient)
1161

    
1162
    name = "instnohZeex0"
1163

    
1164
    handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {}, {},
1165
                             clfactory)
1166
    job_id = handler.PUT()
1167

    
1168
    cl = clfactory.GetNextClient()
1169
    self.assertRaises(IndexError, clfactory.GetNextClient)
1170

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

    
1180
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1181

    
1182

    
1183
class TestParseRenameInstanceRequest(testutils.GanetiTestCase):
1184
  def test(self):
1185
    clfactory = _FakeClientFactory(_FakeClient)
1186

    
1187
    name = "instij0eeph7"
1188

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

    
1198
          handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
1199
                                   {}, data, clfactory)
1200
          job_id = handler.PUT()
1201

    
1202
          cl = clfactory.GetNextClient()
1203
          self.assertRaises(IndexError, clfactory.GetNextClient)
1204

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

    
1215
          self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1216

    
1217
  def testDefaults(self):
1218
    clfactory = _FakeClientFactory(_FakeClient)
1219

    
1220
    name = "instahchie3t"
1221

    
1222
    for new_name in ["thag9mek", "quees7oh"]:
1223
      data = {
1224
        "new_name": new_name,
1225
        }
1226

    
1227
      handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
1228
                               {}, data, clfactory)
1229
      job_id = handler.PUT()
1230

    
1231
      cl = clfactory.GetNextClient()
1232
      self.assertRaises(IndexError, clfactory.GetNextClient)
1233

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

    
1244
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1245

    
1246

    
1247
class TestParseModifyInstanceRequest(unittest.TestCase):
1248
  def test(self):
1249
    clfactory = _FakeClientFactory(_FakeClient)
1250

    
1251
    name = "instush8gah"
1252

    
1253
    test_disks = [
1254
      [],
1255
      [(1, { constants.IDISK_MODE: constants.DISK_RDWR, })],
1256
      ]
1257

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

    
1275
                  handler = _CreateHandler(rlib2.R_2_instances_name_modify,
1276
                                           [name], {}, data, clfactory)
1277
                  job_id = handler.PUT()
1278

    
1279
                  cl = clfactory.GetNextClient()
1280
                  self.assertRaises(IndexError, clfactory.GetNextClient)
1281

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

    
1298
                  self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1299

    
1300
  def testDefaults(self):
1301
    clfactory = _FakeClientFactory(_FakeClient)
1302

    
1303
    name = "instir8aish31"
1304

    
1305
    handler = _CreateHandler(rlib2.R_2_instances_name_modify,
1306
                             [name], {}, {}, clfactory)
1307
    job_id = handler.PUT()
1308

    
1309
    cl = clfactory.GetNextClient()
1310
    self.assertRaises(IndexError, clfactory.GetNextClient)
1311

    
1312
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1313
    self.assertEqual(job_id, exp_job_id)
1314
    self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
1315
    self.assertEqual(op.instance_name, name)
1316

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

    
1321

    
1322
class TestParseInstanceReinstallRequest(testutils.GanetiTestCase):
1323
  def setUp(self):
1324
    testutils.GanetiTestCase.setUp(self)
1325

    
1326
    self.Parse = rlib2._ParseInstanceReinstallRequest
1327

    
1328
  def _Check(self, ops, name):
1329
    expcls = [
1330
      opcodes.OpInstanceShutdown,
1331
      opcodes.OpInstanceReinstall,
1332
      opcodes.OpInstanceStartup,
1333
      ]
1334

    
1335
    self.assert_(compat.all(isinstance(op, exp)
1336
                            for op, exp in zip(ops, expcls)))
1337
    self.assert_(compat.all(op.instance_name == name for op in ops))
1338

    
1339
  def test(self):
1340
    name = "shoo0tihohma"
1341

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

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

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

    
1363
  def testDefaults(self):
1364
    name = "noolee0g"
1365

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

    
1372
  def testErrors(self):
1373
    self.assertRaises(http.HttpBadRequest, self.Parse,
1374
                      "foo", "not a dictionary")
1375

    
1376

    
1377
class TestGroupRename(unittest.TestCase):
1378
  def test(self):
1379
    clfactory = _FakeClientFactory(_FakeClient)
1380

    
1381
    name = "group608242564"
1382
    data = {
1383
      "new_name": "ua0aiyoo15112",
1384
      }
1385

    
1386
    handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {}, data,
1387
                             clfactory)
1388
    job_id = handler.PUT()
1389

    
1390
    cl = clfactory.GetNextClient()
1391
    self.assertRaises(IndexError, clfactory.GetNextClient)
1392

    
1393
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1394
    self.assertEqual(job_id, exp_job_id)
1395

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

    
1402
  def testDryRun(self):
1403
    clfactory = _FakeClientFactory(_FakeClient)
1404

    
1405
    name = "group28548"
1406
    data = {
1407
      "new_name": "ua0aiyoo",
1408
      }
1409

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

    
1415
    cl = clfactory.GetNextClient()
1416
    self.assertRaises(IndexError, clfactory.GetNextClient)
1417

    
1418
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1419
    self.assertEqual(job_id, exp_job_id)
1420

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

    
1427

    
1428
class TestInstanceReplaceDisks(unittest.TestCase):
1429
  def test(self):
1430
    clfactory = _FakeClientFactory(_FakeClient)
1431

    
1432
    name = "inst22568"
1433

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

    
1441
      handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1442
                               [name], {}, data, clfactory)
1443
      job_id = handler.POST()
1444

    
1445
      cl = clfactory.GetNextClient()
1446
      self.assertRaises(IndexError, clfactory.GetNextClient)
1447

    
1448
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1449
      self.assertEqual(job_id, exp_job_id)
1450

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

    
1458
  def testDefaults(self):
1459
    clfactory = _FakeClientFactory(_FakeClient)
1460

    
1461
    name = "inst11413"
1462
    data = {
1463
      "mode": constants.REPLACE_DISK_AUTO,
1464
      }
1465

    
1466
    handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1467
                             [name], {}, data, clfactory)
1468
    job_id = handler.POST()
1469

    
1470
    cl = clfactory.GetNextClient()
1471
    self.assertRaises(IndexError, clfactory.GetNextClient)
1472

    
1473
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1474
    self.assertEqual(job_id, exp_job_id)
1475

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

    
1483
  def testNoDisks(self):
1484
    clfactory = _FakeClientFactory(_FakeClient)
1485

    
1486
    handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1487
                             ["inst20661"], {}, {}, clfactory)
1488
    self.assertRaises(http.HttpBadRequest, handler.POST)
1489

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

    
1497
  def testWrong(self):
1498
    clfactory = _FakeClientFactory(_FakeClient)
1499

    
1500
    data = {
1501
      "mode": constants.REPLACE_DISK_AUTO,
1502
      "disks": "hello world",
1503
      }
1504

    
1505
    handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1506
                             ["foo"], {}, data, clfactory)
1507
    self.assertRaises(http.HttpBadRequest, handler.POST)
1508

    
1509

    
1510
class TestGroupModify(unittest.TestCase):
1511
  def test(self):
1512
    clfactory = _FakeClientFactory(_FakeClient)
1513

    
1514
    name = "group6002"
1515

    
1516
    for policy in constants.VALID_ALLOC_POLICIES:
1517
      data = {
1518
        "alloc_policy": policy,
1519
        }
1520

    
1521
      handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, data,
1522
                               clfactory)
1523
      job_id = handler.PUT()
1524

    
1525
      cl = clfactory.GetNextClient()
1526
      self.assertRaises(IndexError, clfactory.GetNextClient)
1527

    
1528
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1529
      self.assertEqual(job_id, exp_job_id)
1530

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

    
1537
  def testUnknownPolicy(self):
1538
    clfactory = _FakeClientFactory(_FakeClient)
1539

    
1540
    data = {
1541
      "alloc_policy": "_unknown_policy_",
1542
      }
1543

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

    
1549
  def testDefaults(self):
1550
    clfactory = _FakeClientFactory(_FakeClient)
1551

    
1552
    name = "group6679"
1553

    
1554
    handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, {},
1555
                             clfactory)
1556
    job_id = handler.PUT()
1557

    
1558
    cl = clfactory.GetNextClient()
1559
    self.assertRaises(IndexError, clfactory.GetNextClient)
1560

    
1561
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1562
    self.assertEqual(job_id, exp_job_id)
1563

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

    
1570

    
1571
class TestGroupAdd(unittest.TestCase):
1572
  def test(self):
1573
    name = "group3618"
1574
    clfactory = _FakeClientFactory(_FakeClient)
1575

    
1576
    for policy in constants.VALID_ALLOC_POLICIES:
1577
      data = {
1578
        "group_name": name,
1579
        "alloc_policy": policy,
1580
        }
1581

    
1582
      handler = _CreateHandler(rlib2.R_2_groups, [], {}, data,
1583
                               clfactory)
1584
      job_id = handler.POST()
1585

    
1586
      cl = clfactory.GetNextClient()
1587
      self.assertRaises(IndexError, clfactory.GetNextClient)
1588

    
1589
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1590
      self.assertEqual(job_id, exp_job_id)
1591

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

    
1598
  def testUnknownPolicy(self):
1599
    clfactory = _FakeClientFactory(_FakeClient)
1600

    
1601
    data = {
1602
      "alloc_policy": "_unknown_policy_",
1603
      }
1604

    
1605
    handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1606
    self.assertRaises(http.HttpBadRequest, handler.POST)
1607
    self.assertRaises(IndexError, clfactory.GetNextClient)
1608

    
1609
  def testDefaults(self):
1610
    clfactory = _FakeClientFactory(_FakeClient)
1611

    
1612
    name = "group15395"
1613
    data = {
1614
      "group_name": name,
1615
      }
1616

    
1617
    handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1618
    job_id = handler.POST()
1619

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

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

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

    
1631
  def testLegacyName(self):
1632
    clfactory = _FakeClientFactory(_FakeClient)
1633

    
1634
    name = "group29852"
1635
    data = {
1636
      "name": name,
1637
      }
1638

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

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

    
1647
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1648
    self.assertEqual(job_id, exp_job_id)
1649

    
1650
    self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1651
    self.assertEqual(op.group_name, name)
1652
    self.assertFalse(hasattr(op, "alloc_policy"))
1653
    self.assertTrue(op.dry_run)
1654

    
1655

    
1656
class TestNodeRole(unittest.TestCase):
1657
  def test(self):
1658
    clfactory = _FakeClientFactory(_FakeClient)
1659

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

    
1668
        cl = clfactory.GetNextClient()
1669
        self.assertRaises(IndexError, clfactory.GetNextClient)
1670

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

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

    
1697
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1698

    
1699

    
1700
class TestSimpleResources(unittest.TestCase):
1701
  def setUp(self):
1702
    self.clfactory = _FakeClientFactory(_FakeClient)
1703

    
1704
  def tearDown(self):
1705
    self.assertRaises(IndexError, self.clfactory.GetNextClient)
1706

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

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

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

    
1720

    
1721
class TestClusterInfo(unittest.TestCase):
1722
  class _ClusterInfoClient:
1723
    def __init__(self, address=None):
1724
      self.cluster_info = None
1725

    
1726
    def QueryClusterInfo(self):
1727
      assert self.cluster_info is None
1728
      self.cluster_info = object()
1729
      return self.cluster_info
1730

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

    
1739

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

    
1758

    
1759
class TestPermissions(unittest.TestCase):
1760
  def testEquality(self):
1761
    self.assertEqual(rlib2.R_2_query.GET_ACCESS, rlib2.R_2_query.PUT_ACCESS)
1762
    self.assertEqual(rlib2.R_2_query.GET_ACCESS,
1763
                     rlib2.R_2_instances_name_console.GET_ACCESS)
1764

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

    
1779

    
1780
if __name__ == "__main__":
1781
  testutils.GanetiTestProgram()