Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.rapi.rlib2_unittest.py @ 55cec070

History | View | Annotate | Download (58 kB)

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

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

    
21

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

24
"""
25

    
26

    
27
import unittest
28
import itertools
29
import random
30

    
31
from ganeti import constants
32
from ganeti import opcodes
33
from ganeti import compat
34
from ganeti import http
35
from ganeti import query
36
from ganeti import luxi
37
from ganeti import errors
38
from ganeti import rapi
39

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

    
44
import testutils
45

    
46

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

    
51

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

    
56

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

    
61

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

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

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

    
74

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

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

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

    
88

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

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

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

    
106

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

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

    
122

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

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

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

    
137

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

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

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

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

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

    
167

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

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

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

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

    
183

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
257

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

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

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

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

    
280

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

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

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

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

    
300

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

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

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

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

    
325

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

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

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

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

    
346

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

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

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

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

    
366

    
367
class TestInstanceReboot(unittest.TestCase):
368
  def test(self):
369
    clfactory = _FakeClientFactory(_FakeClient)
370
    handler = _CreateHandler(rlib2.R_2_instances_name_reboot, ["inst847"], {
371
      "dry-run": ["1"],
372
      "ignore_secondaries": ["1"],
373
      "reason": ["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[0][0], constants.OPCODE_REASON_SRC_USER)
388
    self.assertEqual(op.reason[0][1], "System update")
389
    self.assertEqual(op.reason[1][0],
390
                     "%s:%s" % (constants.OPCODE_REASON_SRC_RLIB2,
391
                                "instances_name_reboot"))
392
    self.assertEqual(op.reason[1][1], "")
393

    
394
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
395

    
396

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

    
406
    cl = clfactory.GetNextClient()
407
    self.assertRaises(IndexError, clfactory.GetNextClient)
408

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

    
417
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
418

    
419

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

    
428
    cl = clfactory.GetNextClient()
429
    self.assertRaises(IndexError, clfactory.GetNextClient)
430

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

    
438
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
439

    
440

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

    
449
    cl = clfactory.GetNextClient()
450
    self.assertRaises(IndexError, clfactory.GetNextClient)
451

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

    
459
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
460

    
461

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

    
469
    cl = clfactory.GetNextClient()
470
    self.assertRaises(IndexError, clfactory.GetNextClient)
471

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

    
479
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
480

    
481

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

    
489
    cl = clfactory.GetNextClient()
490
    self.assertRaises(IndexError, clfactory.GetNextClient)
491

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

    
499
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
500

    
501

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

    
509
    cl = clfactory.GetNextClient()
510
    self.assertRaises(IndexError, clfactory.GetNextClient)
511

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

    
519
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
520

    
521

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

    
532
    cl = clfactory.GetNextClient()
533
    self.assertRaises(IndexError, clfactory.GetNextClient)
534

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

    
544
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
545

    
546

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

    
557
    cl = clfactory.GetNextClient()
558
    self.assertRaises(IndexError, clfactory.GetNextClient)
559

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

    
568
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
569

    
570

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

    
578
    cl = clfactory.GetNextClient()
579
    self.assertRaises(IndexError, clfactory.GetNextClient)
580

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

    
588
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
589

    
590

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

    
602
    cl = clfactory.GetNextClient()
603
    self.assertRaises(IndexError, clfactory.GetNextClient)
604

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

    
614
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
615

    
616
  def testErrors(self):
617
    clfactory = _FakeClientFactory(_FakeClient)
618

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

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

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

    
641

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

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

    
652
      if allocatable is not None:
653
        queryargs["allocatable"] = allocatable
654

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

    
659
      cl = clfactory.GetNextClient()
660
      self.assertRaises(IndexError, clfactory.GetNextClient)
661

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

    
678
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
679

    
680
  def testErrors(self):
681
    clfactory = _FakeClientFactory(_FakeClient)
682

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

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

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

    
709

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

    
721
    cl = clfactory.GetNextClient()
722
    self.assertRaises(IndexError, clfactory.GetNextClient)
723

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

    
733
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
734

    
735
  def testErrors(self):
736
    clfactory = _FakeClientFactory(_FakeClient)
737

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

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

    
754

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

    
763
  def testSetAndDelete(self):
764
    clfactory = _FakeClientFactory(_FakeClient)
765

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

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

    
779
        cl = clfactory.GetNextClient()
780
        self.assertRaises(IndexError, clfactory.GetNextClient)
781

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

    
794
        self.assertRaises(IndexError, cl.GetNextSubmittedJob)
795

    
796

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

    
801
    name = "inst863.example.com"
802

    
803
    disk_variants = [
804
      # No disks
805
      [],
806

    
807
      # Two disks
808
      [{"size": 5, }, {"size": 100, }],
809

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

    
814
    nic_variants = [
815
      # No NIC
816
      [],
817

    
818
      # Three NICs
819
      [{}, {}, {}],
820

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

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

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

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

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

    
872
                  if beparams is not None:
873
                    data["beparams"] = beparams
874

    
875
                  if hvparams is not None:
876
                    data["hvparams"] = hvparams
877

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

    
882
                  cl = clfactory.GetNextClient()
883
                  self.assertRaises(IndexError, clfactory.GetNextClient)
884

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

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

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

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

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

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

    
918
  def testLegacyName(self):
919
    clfactory = _FakeClientFactory(_FakeClient)
920

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

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

    
934
    cl = clfactory.GetNextClient()
935
    self.assertRaises(IndexError, clfactory.GetNextClient)
936

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

    
944
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
945

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

    
953
  def testLegacyOs(self):
954
    clfactory = _FakeClientFactory(_FakeClient)
955

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

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

    
971
    cl = clfactory.GetNextClient()
972
    self.assertRaises(IndexError, clfactory.GetNextClient)
973

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

    
982
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
983

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

    
990
  def testErrors(self):
991
    clfactory = _FakeClientFactory(_FakeClient)
992

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

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

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

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

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

    
1022
  def testVersion(self):
1023
    clfactory = _FakeClientFactory(_FakeClient)
1024

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

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

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

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

    
1044
      self.assertRaises(IndexError, clfactory.GetNextClient)
1045

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

    
1051
    cl = clfactory.GetNextClient()
1052
    self.assertRaises(IndexError, clfactory.GetNextClient)
1053

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

    
1059

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

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

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

    
1078
    cl = clfactory.GetNextClient()
1079
    self.assertRaises(IndexError, clfactory.GetNextClient)
1080

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

    
1094
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1095

    
1096
  def testDefaults(self):
1097
    clfactory = _FakeClientFactory(_FakeClient)
1098

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

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

    
1109
    cl = clfactory.GetNextClient()
1110
    self.assertRaises(IndexError, clfactory.GetNextClient)
1111

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

    
1123
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1124

    
1125
  def testErrors(self):
1126
    clfactory = _FakeClientFactory(_FakeClient)
1127

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

    
1134

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

    
1139
    name = "instYooho6ek"
1140

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

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

    
1152
        cl = clfactory.GetNextClient()
1153
        self.assertRaises(IndexError, clfactory.GetNextClient)
1154

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

    
1164
        self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1165

    
1166
  def testDefaults(self):
1167
    clfactory = _FakeClientFactory(_FakeClient)
1168

    
1169
    name = "instnohZeex0"
1170

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

    
1175
    cl = clfactory.GetNextClient()
1176
    self.assertRaises(IndexError, clfactory.GetNextClient)
1177

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

    
1187
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1188

    
1189

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

    
1194
    name = "instij0eeph7"
1195

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

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

    
1209
          cl = clfactory.GetNextClient()
1210
          self.assertRaises(IndexError, clfactory.GetNextClient)
1211

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

    
1222
          self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1223

    
1224
  def testDefaults(self):
1225
    clfactory = _FakeClientFactory(_FakeClient)
1226

    
1227
    name = "instahchie3t"
1228

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

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

    
1238
      cl = clfactory.GetNextClient()
1239
      self.assertRaises(IndexError, clfactory.GetNextClient)
1240

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

    
1251
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1252

    
1253

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

    
1258
    name = "instush8gah"
1259

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

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

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

    
1286
                  cl = clfactory.GetNextClient()
1287
                  self.assertRaises(IndexError, clfactory.GetNextClient)
1288

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

    
1305
                  self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1306

    
1307
  def testDefaults(self):
1308
    clfactory = _FakeClientFactory(_FakeClient)
1309

    
1310
    name = "instir8aish31"
1311

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

    
1316
    cl = clfactory.GetNextClient()
1317
    self.assertRaises(IndexError, clfactory.GetNextClient)
1318

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

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

    
1328

    
1329
class TestParseInstanceReinstallRequest(testutils.GanetiTestCase):
1330
  def setUp(self):
1331
    testutils.GanetiTestCase.setUp(self)
1332

    
1333
    self.Parse = rlib2._ParseInstanceReinstallRequest
1334

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

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

    
1346
  def test(self):
1347
    name = "shoo0tihohma"
1348

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

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

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

    
1370
  def testDefaults(self):
1371
    name = "noolee0g"
1372

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

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

    
1383

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

    
1388
    name = "group608242564"
1389
    data = {
1390
      "new_name": "ua0aiyoo15112",
1391
      }
1392

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

    
1397
    cl = clfactory.GetNextClient()
1398
    self.assertRaises(IndexError, clfactory.GetNextClient)
1399

    
1400
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1401
    self.assertEqual(job_id, exp_job_id)
1402

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

    
1409
  def testDryRun(self):
1410
    clfactory = _FakeClientFactory(_FakeClient)
1411

    
1412
    name = "group28548"
1413
    data = {
1414
      "new_name": "ua0aiyoo",
1415
      }
1416

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

    
1422
    cl = clfactory.GetNextClient()
1423
    self.assertRaises(IndexError, clfactory.GetNextClient)
1424

    
1425
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1426
    self.assertEqual(job_id, exp_job_id)
1427

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

    
1434

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

    
1439
    name = "inst22568"
1440

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

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

    
1452
      cl = clfactory.GetNextClient()
1453
      self.assertRaises(IndexError, clfactory.GetNextClient)
1454

    
1455
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1456
      self.assertEqual(job_id, exp_job_id)
1457

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

    
1465
  def testDefaults(self):
1466
    clfactory = _FakeClientFactory(_FakeClient)
1467

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

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

    
1477
    cl = clfactory.GetNextClient()
1478
    self.assertRaises(IndexError, clfactory.GetNextClient)
1479

    
1480
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1481
    self.assertEqual(job_id, exp_job_id)
1482

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

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

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

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

    
1504
  def testWrong(self):
1505
    clfactory = _FakeClientFactory(_FakeClient)
1506

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

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

    
1516

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

    
1521
    name = "group6002"
1522

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

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

    
1532
      cl = clfactory.GetNextClient()
1533
      self.assertRaises(IndexError, clfactory.GetNextClient)
1534

    
1535
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1536
      self.assertEqual(job_id, exp_job_id)
1537

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

    
1544
  def testUnknownPolicy(self):
1545
    clfactory = _FakeClientFactory(_FakeClient)
1546

    
1547
    data = {
1548
      "alloc_policy": "_unknown_policy_",
1549
      }
1550

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

    
1556
  def testDefaults(self):
1557
    clfactory = _FakeClientFactory(_FakeClient)
1558

    
1559
    name = "group6679"
1560

    
1561
    handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, {},
1562
                             clfactory)
1563
    job_id = handler.PUT()
1564

    
1565
    cl = clfactory.GetNextClient()
1566
    self.assertRaises(IndexError, clfactory.GetNextClient)
1567

    
1568
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1569
    self.assertEqual(job_id, exp_job_id)
1570

    
1571
    self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
1572
    self.assertEqual(op.group_name, name)
1573
    self.assertFalse(hasattr(op, "alloc_policy"))
1574
    self.assertFalse(hasattr(op, "dry_run"))
1575
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1576

    
1577

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

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

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

    
1593
      cl = clfactory.GetNextClient()
1594
      self.assertRaises(IndexError, clfactory.GetNextClient)
1595

    
1596
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1597
      self.assertEqual(job_id, exp_job_id)
1598

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

    
1605
  def testUnknownPolicy(self):
1606
    clfactory = _FakeClientFactory(_FakeClient)
1607

    
1608
    data = {
1609
      "alloc_policy": "_unknown_policy_",
1610
      }
1611

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

    
1616
  def testDefaults(self):
1617
    clfactory = _FakeClientFactory(_FakeClient)
1618

    
1619
    name = "group15395"
1620
    data = {
1621
      "group_name": name,
1622
      }
1623

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

    
1627
    cl = clfactory.GetNextClient()
1628
    self.assertRaises(IndexError, clfactory.GetNextClient)
1629

    
1630
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1631
    self.assertEqual(job_id, exp_job_id)
1632

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

    
1638
  def testLegacyName(self):
1639
    clfactory = _FakeClientFactory(_FakeClient)
1640

    
1641
    name = "group29852"
1642
    data = {
1643
      "name": name,
1644
      }
1645

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

    
1651
    cl = clfactory.GetNextClient()
1652
    self.assertRaises(IndexError, clfactory.GetNextClient)
1653

    
1654
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1655
    self.assertEqual(job_id, exp_job_id)
1656

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

    
1662

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

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

    
1675
        cl = clfactory.GetNextClient()
1676
        self.assertRaises(IndexError, clfactory.GetNextClient)
1677

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

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

    
1704
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1705

    
1706

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

    
1711
  def tearDown(self):
1712
    self.assertRaises(IndexError, self.clfactory.GetNextClient)
1713

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

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

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

    
1727

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

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

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

    
1746

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

    
1765

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

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

    
1787

    
1788
if __name__ == "__main__":
1789
  testutils.GanetiTestProgram()