Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (58.7 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.NODE_EVAC_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.NODE_EVAC_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
      "reason": ["Newly created instance"],
404
      }, {}, clfactory)
405
    job_id = handler.PUT()
406

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

    
410
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
411
    self.assertEqual(job_id, exp_job_id)
412
    self.assertTrue(isinstance(op, opcodes.OpInstanceStartup))
413
    self.assertEqual(op.instance_name, "inst31083")
414
    self.assertTrue(op.no_remember)
415
    self.assertTrue(op.force)
416
    self.assertFalse(op.dry_run)
417
    self.assertEqual(op.reason[0][0], constants.OPCODE_REASON_SRC_USER)
418
    self.assertEqual(op.reason[0][1], "Newly created instance")
419
    self.assertEqual(op.reason[1][0],
420
                     "%s:%s" % (constants.OPCODE_REASON_SRC_RLIB2,
421
                                "instances_name_startup"))
422
    self.assertEqual(op.reason[1][1], "")
423

    
424
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
425

    
426

    
427
class TestInstanceShutdown(unittest.TestCase):
428
  def test(self):
429
    clfactory = _FakeClientFactory(_FakeClient)
430
    handler = _CreateHandler(rlib2.R_2_instances_name_shutdown, ["inst26791"], {
431
      "no_remember": ["0"],
432
      "reason": ["Not used anymore"],
433
      }, {}, clfactory)
434
    job_id = handler.PUT()
435

    
436
    cl = clfactory.GetNextClient()
437
    self.assertRaises(IndexError, clfactory.GetNextClient)
438

    
439
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
440
    self.assertEqual(job_id, exp_job_id)
441
    self.assertTrue(isinstance(op, opcodes.OpInstanceShutdown))
442
    self.assertEqual(op.instance_name, "inst26791")
443
    self.assertFalse(op.no_remember)
444
    self.assertFalse(op.dry_run)
445
    self.assertEqual(op.reason[0][0], constants.OPCODE_REASON_SRC_USER)
446
    self.assertEqual(op.reason[0][1], "Not used anymore")
447
    self.assertEqual(op.reason[1][0],
448
                     "%s:%s" % (constants.OPCODE_REASON_SRC_RLIB2,
449
                                "instances_name_shutdown"))
450
    self.assertEqual(op.reason[1][1], "")
451

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

    
454

    
455
class TestInstanceActivateDisks(unittest.TestCase):
456
  def test(self):
457
    clfactory = _FakeClientFactory(_FakeClient)
458
    handler = _CreateHandler(rlib2.R_2_instances_name_activate_disks, ["xyz"], {
459
      "ignore_size": ["1"],
460
      }, {}, clfactory)
461
    job_id = handler.PUT()
462

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

    
466
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
467
    self.assertEqual(job_id, exp_job_id)
468
    self.assertTrue(isinstance(op, opcodes.OpInstanceActivateDisks))
469
    self.assertEqual(op.instance_name, "xyz")
470
    self.assertTrue(op.ignore_size)
471
    self.assertFalse(hasattr(op, "dry_run"))
472

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

    
475

    
476
class TestInstanceDeactivateDisks(unittest.TestCase):
477
  def test(self):
478
    clfactory = _FakeClientFactory(_FakeClient)
479
    handler = _CreateHandler(rlib2.R_2_instances_name_deactivate_disks,
480
                             ["inst22357"], {}, {}, clfactory)
481
    job_id = handler.PUT()
482

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

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

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

    
495

    
496
class TestInstanceRecreateDisks(unittest.TestCase):
497
  def test(self):
498
    clfactory = _FakeClientFactory(_FakeClient)
499
    handler = _CreateHandler(rlib2.R_2_instances_name_recreate_disks,
500
                             ["inst22357"], {}, {}, clfactory)
501
    job_id = handler.POST()
502

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

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

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

    
515

    
516
class TestInstanceFailover(unittest.TestCase):
517
  def test(self):
518
    clfactory = _FakeClientFactory(_FakeClient)
519
    handler = _CreateHandler(rlib2.R_2_instances_name_failover,
520
                             ["inst12794"], {}, {}, clfactory)
521
    job_id = handler.PUT()
522

    
523
    cl = clfactory.GetNextClient()
524
    self.assertRaises(IndexError, clfactory.GetNextClient)
525

    
526
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
527
    self.assertEqual(job_id, exp_job_id)
528
    self.assertTrue(isinstance(op, opcodes.OpInstanceFailover))
529
    self.assertEqual(op.instance_name, "inst12794")
530
    self.assertFalse(hasattr(op, "dry_run"))
531
    self.assertFalse(hasattr(op, "force"))
532

    
533
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
534

    
535

    
536
class TestInstanceDiskGrow(unittest.TestCase):
537
  def test(self):
538
    clfactory = _FakeClientFactory(_FakeClient)
539
    data = {
540
      "amount": 1024,
541
      }
542
    handler = _CreateHandler(rlib2.R_2_instances_name_disk_grow,
543
                             ["inst10742", "3"], {}, data, clfactory)
544
    job_id = handler.POST()
545

    
546
    cl = clfactory.GetNextClient()
547
    self.assertRaises(IndexError, clfactory.GetNextClient)
548

    
549
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
550
    self.assertEqual(job_id, exp_job_id)
551
    self.assertTrue(isinstance(op, opcodes.OpInstanceGrowDisk))
552
    self.assertEqual(op.instance_name, "inst10742")
553
    self.assertEqual(op.disk, 3)
554
    self.assertEqual(op.amount, 1024)
555
    self.assertFalse(hasattr(op, "dry_run"))
556
    self.assertFalse(hasattr(op, "force"))
557

    
558
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
559

    
560

    
561
class TestBackupPrepare(unittest.TestCase):
562
  def test(self):
563
    clfactory = _FakeClientFactory(_FakeClient)
564
    queryargs = {
565
      "mode": constants.EXPORT_MODE_REMOTE,
566
      }
567
    handler = _CreateHandler(rlib2.R_2_instances_name_prepare_export,
568
                             ["inst17925"], queryargs, {}, clfactory)
569
    job_id = handler.PUT()
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.OpBackupPrepare))
577
    self.assertEqual(op.instance_name, "inst17925")
578
    self.assertEqual(op.mode, constants.EXPORT_MODE_REMOTE)
579
    self.assertFalse(hasattr(op, "dry_run"))
580
    self.assertFalse(hasattr(op, "force"))
581

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

    
584

    
585
class TestGroupRemove(unittest.TestCase):
586
  def test(self):
587
    clfactory = _FakeClientFactory(_FakeClient)
588
    handler = _CreateHandler(rlib2.R_2_groups_name,
589
                             ["grp28575"], {}, {}, clfactory)
590
    job_id = handler.DELETE()
591

    
592
    cl = clfactory.GetNextClient()
593
    self.assertRaises(IndexError, clfactory.GetNextClient)
594

    
595
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
596
    self.assertEqual(job_id, exp_job_id)
597
    self.assertTrue(isinstance(op, opcodes.OpGroupRemove))
598
    self.assertEqual(op.group_name, "grp28575")
599
    self.assertFalse(op.dry_run)
600
    self.assertFalse(hasattr(op, "force"))
601

    
602
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
603

    
604

    
605
class TestStorageQuery(unittest.TestCase):
606
  def test(self):
607
    clfactory = _FakeClientFactory(_FakeClient)
608
    queryargs = {
609
      "storage_type": constants.ST_LVM_PV,
610
      "output_fields": "name,other",
611
      }
612
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
613
                             ["node21075"], queryargs, {}, clfactory)
614
    job_id = handler.GET()
615

    
616
    cl = clfactory.GetNextClient()
617
    self.assertRaises(IndexError, clfactory.GetNextClient)
618

    
619
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
620
    self.assertEqual(job_id, exp_job_id)
621
    self.assertTrue(isinstance(op, opcodes.OpNodeQueryStorage))
622
    self.assertEqual(op.nodes, ["node21075"])
623
    self.assertEqual(op.storage_type, constants.ST_LVM_PV)
624
    self.assertEqual(op.output_fields, ["name", "other"])
625
    self.assertFalse(hasattr(op, "dry_run"))
626
    self.assertFalse(hasattr(op, "force"))
627

    
628
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
629

    
630
  def testErrors(self):
631
    clfactory = _FakeClientFactory(_FakeClient)
632

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

    
640
    queryargs = {
641
      "storage_type": constants.ST_LVM_VG,
642
      }
643
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
644
                             ["node21273"], queryargs, {}, clfactory)
645
    self.assertRaises(http.HttpBadRequest, handler.GET)
646

    
647
    queryargs = {
648
      "storage_type": "##unknown_storage##",
649
      "output_fields": "name,other",
650
      }
651
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
652
                             ["node10315"], queryargs, {}, clfactory)
653
    self.assertRaises(http.HttpBadRequest, handler.GET)
654

    
655

    
656
class TestStorageModify(unittest.TestCase):
657
  def test(self):
658
    clfactory = _FakeClientFactory(_FakeClient)
659

    
660
    for allocatable in [None, "1", "0"]:
661
      queryargs = {
662
        "storage_type": constants.ST_LVM_VG,
663
        "name": "pv-a",
664
        }
665

    
666
      if allocatable is not None:
667
        queryargs["allocatable"] = allocatable
668

    
669
      handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
670
                               ["node9292"], queryargs, {}, clfactory)
671
      job_id = handler.PUT()
672

    
673
      cl = clfactory.GetNextClient()
674
      self.assertRaises(IndexError, clfactory.GetNextClient)
675

    
676
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
677
      self.assertEqual(job_id, exp_job_id)
678
      self.assertTrue(isinstance(op, opcodes.OpNodeModifyStorage))
679
      self.assertEqual(op.node_name, "node9292")
680
      self.assertEqual(op.storage_type, constants.ST_LVM_VG)
681
      self.assertEqual(op.name, "pv-a")
682
      if allocatable is None:
683
        self.assertFalse(op.changes)
684
      else:
685
        assert allocatable in ("0", "1")
686
        self.assertEqual(op.changes, {
687
          constants.SF_ALLOCATABLE: (allocatable == "1"),
688
          })
689
      self.assertFalse(hasattr(op, "dry_run"))
690
      self.assertFalse(hasattr(op, "force"))
691

    
692
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
693

    
694
  def testErrors(self):
695
    clfactory = _FakeClientFactory(_FakeClient)
696

    
697
    # No storage type
698
    queryargs = {
699
      "name": "xyz",
700
      }
701
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
702
                             ["node26016"], queryargs, {}, clfactory)
703
    self.assertRaises(http.HttpBadRequest, handler.PUT)
704

    
705
    # No name
706
    queryargs = {
707
      "storage_type": constants.ST_LVM_VG,
708
      }
709
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
710
                             ["node21218"], queryargs, {}, clfactory)
711
    self.assertRaises(http.HttpBadRequest, handler.PUT)
712

    
713
    # Invalid value
714
    queryargs = {
715
      "storage_type": constants.ST_LVM_VG,
716
      "name": "pv-b",
717
      "allocatable": "noint",
718
      }
719
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
720
                             ["node30685"], queryargs, {}, clfactory)
721
    self.assertRaises(http.HttpBadRequest, handler.PUT)
722

    
723

    
724
class TestStorageRepair(unittest.TestCase):
725
  def test(self):
726
    clfactory = _FakeClientFactory(_FakeClient)
727
    queryargs = {
728
      "storage_type": constants.ST_LVM_PV,
729
      "name": "pv16611",
730
      }
731
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
732
                             ["node19265"], queryargs, {}, clfactory)
733
    job_id = handler.PUT()
734

    
735
    cl = clfactory.GetNextClient()
736
    self.assertRaises(IndexError, clfactory.GetNextClient)
737

    
738
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
739
    self.assertEqual(job_id, exp_job_id)
740
    self.assertTrue(isinstance(op, opcodes.OpRepairNodeStorage))
741
    self.assertEqual(op.node_name, "node19265")
742
    self.assertEqual(op.storage_type, constants.ST_LVM_PV)
743
    self.assertEqual(op.name, "pv16611")
744
    self.assertFalse(hasattr(op, "dry_run"))
745
    self.assertFalse(hasattr(op, "force"))
746

    
747
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
748

    
749
  def testErrors(self):
750
    clfactory = _FakeClientFactory(_FakeClient)
751

    
752
    # No storage type
753
    queryargs = {
754
      "name": "xyz",
755
      }
756
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
757
                             ["node11275"], queryargs, {}, clfactory)
758
    self.assertRaises(http.HttpBadRequest, handler.PUT)
759

    
760
    # No name
761
    queryargs = {
762
      "storage_type": constants.ST_LVM_VG,
763
      }
764
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
765
                             ["node21218"], queryargs, {}, clfactory)
766
    self.assertRaises(http.HttpBadRequest, handler.PUT)
767

    
768

    
769
class TestTags(unittest.TestCase):
770
  TAG_HANDLERS = [
771
    rlib2.R_2_instances_name_tags,
772
    rlib2.R_2_nodes_name_tags,
773
    rlib2.R_2_groups_name_tags,
774
    rlib2.R_2_tags,
775
    ]
776

    
777
  def testSetAndDelete(self):
778
    clfactory = _FakeClientFactory(_FakeClient)
779

    
780
    for method, opcls in [("PUT", opcodes.OpTagsSet),
781
                          ("DELETE", opcodes.OpTagsDel)]:
782
      for idx, handler in enumerate(self.TAG_HANDLERS):
783
        dry_run = bool(idx % 2)
784
        name = "test%s" % idx
785
        queryargs = {
786
          "tag": ["foo", "bar", "baz"],
787
          "dry-run": str(int(dry_run)),
788
          }
789

    
790
        handler = _CreateHandler(handler, [name], queryargs, {}, clfactory)
791
        job_id = getattr(handler, method)()
792

    
793
        cl = clfactory.GetNextClient()
794
        self.assertRaises(IndexError, clfactory.GetNextClient)
795

    
796
        (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
797
        self.assertEqual(job_id, exp_job_id)
798
        self.assertTrue(isinstance(op, opcls))
799
        self.assertEqual(op.kind, handler.TAG_LEVEL)
800
        if handler.TAG_LEVEL == constants.TAG_CLUSTER:
801
          self.assertTrue(op.name is None)
802
        else:
803
          self.assertEqual(op.name, name)
804
        self.assertEqual(op.tags, ["foo", "bar", "baz"])
805
        self.assertEqual(op.dry_run, dry_run)
806
        self.assertFalse(hasattr(op, "force"))
807

    
808
        self.assertRaises(IndexError, cl.GetNextSubmittedJob)
809

    
810

    
811
class TestInstanceCreation(testutils.GanetiTestCase):
812
  def test(self):
813
    clfactory = _FakeClientFactory(_FakeClient)
814

    
815
    name = "inst863.example.com"
816

    
817
    disk_variants = [
818
      # No disks
819
      [],
820

    
821
      # Two disks
822
      [{"size": 5, }, {"size": 100, }],
823

    
824
      # Disk with mode
825
      [{"size": 123, "mode": constants.DISK_RDWR, }],
826
      ]
827

    
828
    nic_variants = [
829
      # No NIC
830
      [],
831

    
832
      # Three NICs
833
      [{}, {}, {}],
834

    
835
      # Two NICs
836
      [
837
        { "ip": "192.0.2.6", "mode": constants.NIC_MODE_ROUTED,
838
          "mac": "01:23:45:67:68:9A",
839
        },
840
        { "mode": constants.NIC_MODE_BRIDGED, "link": "br1" },
841
      ],
842
      ]
843

    
844
    beparam_variants = [
845
      None,
846
      {},
847
      { constants.BE_VCPUS: 2, },
848
      { constants.BE_MAXMEM: 200, },
849
      { constants.BE_MEMORY: 256, },
850
      { constants.BE_VCPUS: 2,
851
        constants.BE_MAXMEM: 1024,
852
        constants.BE_MINMEM: 1024,
853
        constants.BE_AUTO_BALANCE: True,
854
        constants.BE_ALWAYS_FAILOVER: True, }
855
      ]
856

    
857
    hvparam_variants = [
858
      None,
859
      { constants.HV_BOOT_ORDER: "anc", },
860
      { constants.HV_KERNEL_PATH: "/boot/fookernel",
861
        constants.HV_ROOT_PATH: "/dev/hda1", },
862
      ]
863

    
864
    for mode in [constants.INSTANCE_CREATE, constants.INSTANCE_IMPORT]:
865
      for nics in nic_variants:
866
        for disk_template in constants.DISK_TEMPLATES:
867
          for disks in disk_variants:
868
            for beparams in beparam_variants:
869
              for hvparams in hvparam_variants:
870
                for dry_run in [False, True]:
871
                  queryargs = {
872
                    "dry-run": str(int(dry_run)),
873
                    }
874

    
875
                  data = {
876
                    rlib2._REQ_DATA_VERSION: 1,
877
                    "name": name,
878
                    "hypervisor": constants.HT_FAKE,
879
                    "disks": disks,
880
                    "nics": nics,
881
                    "mode": mode,
882
                    "disk_template": disk_template,
883
                    "os": "debootstrap",
884
                    }
885

    
886
                  if beparams is not None:
887
                    data["beparams"] = beparams
888

    
889
                  if hvparams is not None:
890
                    data["hvparams"] = hvparams
891

    
892
                  handler = _CreateHandler(rlib2.R_2_instances, [],
893
                                           queryargs, data, clfactory)
894
                  job_id = handler.POST()
895

    
896
                  cl = clfactory.GetNextClient()
897
                  self.assertRaises(IndexError, clfactory.GetNextClient)
898

    
899
                  (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
900
                  self.assertEqual(job_id, exp_job_id)
901
                  self.assertRaises(IndexError, cl.GetNextSubmittedJob)
902

    
903
                  self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
904
                  self.assertEqual(op.instance_name, name)
905
                  self.assertEqual(op.mode, mode)
906
                  self.assertEqual(op.disk_template, disk_template)
907
                  self.assertEqual(op.dry_run, dry_run)
908
                  self.assertEqual(len(op.disks), len(disks))
909
                  self.assertEqual(len(op.nics), len(nics))
910

    
911
                  for opdisk, disk in zip(op.disks, disks):
912
                    for key in constants.IDISK_PARAMS:
913
                      self.assertEqual(opdisk.get(key), disk.get(key))
914
                    self.assertFalse("unknown" in opdisk)
915

    
916
                  for opnic, nic in zip(op.nics, nics):
917
                    for key in constants.INIC_PARAMS:
918
                      self.assertEqual(opnic.get(key), nic.get(key))
919
                    self.assertFalse("unknown" in opnic)
920
                    self.assertFalse("foobar" in opnic)
921

    
922
                  if beparams is None:
923
                    self.assertFalse(hasattr(op, "beparams"))
924
                  else:
925
                    self.assertEqualValues(op.beparams, beparams)
926

    
927
                  if hvparams is None:
928
                    self.assertFalse(hasattr(op, "hvparams"))
929
                  else:
930
                    self.assertEqualValues(op.hvparams, hvparams)
931

    
932
  def testLegacyName(self):
933
    clfactory = _FakeClientFactory(_FakeClient)
934

    
935
    name = "inst29128.example.com"
936
    data = {
937
      rlib2._REQ_DATA_VERSION: 1,
938
      "name": name,
939
      "disks": [],
940
      "nics": [],
941
      "mode": constants.INSTANCE_CREATE,
942
      "disk_template": constants.DT_PLAIN,
943
      }
944

    
945
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
946
    job_id = handler.POST()
947

    
948
    cl = clfactory.GetNextClient()
949
    self.assertRaises(IndexError, clfactory.GetNextClient)
950

    
951
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
952
    self.assertEqual(job_id, exp_job_id)
953
    self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
954
    self.assertEqual(op.instance_name, name)
955
    self.assertFalse(hasattr(op, "name"))
956
    self.assertFalse(op.dry_run)
957

    
958
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
959

    
960
    # Define both
961
    data["instance_name"] = "other.example.com"
962
    assert "name" in data and "instance_name" in data
963
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
964
    self.assertRaises(http.HttpBadRequest, handler.POST)
965
    self.assertRaises(IndexError, clfactory.GetNextClient)
966

    
967
  def testLegacyOs(self):
968
    clfactory = _FakeClientFactory(_FakeClient)
969

    
970
    name = "inst4673.example.com"
971
    os = "linux29206"
972
    data = {
973
      rlib2._REQ_DATA_VERSION: 1,
974
      "name": name,
975
      "os_type": os,
976
      "disks": [],
977
      "nics": [],
978
      "mode": constants.INSTANCE_CREATE,
979
      "disk_template": constants.DT_PLAIN,
980
      }
981

    
982
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
983
    job_id = handler.POST()
984

    
985
    cl = clfactory.GetNextClient()
986
    self.assertRaises(IndexError, clfactory.GetNextClient)
987

    
988
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
989
    self.assertEqual(job_id, exp_job_id)
990
    self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
991
    self.assertEqual(op.instance_name, name)
992
    self.assertEqual(op.os_type, os)
993
    self.assertFalse(hasattr(op, "os"))
994
    self.assertFalse(op.dry_run)
995

    
996
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
997

    
998
    # Define both
999
    data["os"] = "linux9584"
1000
    assert "os" in data and "os_type" in data
1001
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1002
    self.assertRaises(http.HttpBadRequest, handler.POST)
1003

    
1004
  def testErrors(self):
1005
    clfactory = _FakeClientFactory(_FakeClient)
1006

    
1007
    # Test all required fields
1008
    reqfields = {
1009
      rlib2._REQ_DATA_VERSION: 1,
1010
      "name": "inst1.example.com",
1011
      "disks": [],
1012
      "nics": [],
1013
      "mode": constants.INSTANCE_CREATE,
1014
      }
1015

    
1016
    for name in reqfields.keys():
1017
      data = dict(i for i in reqfields.iteritems() if i[0] != name)
1018

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

    
1023
    # Invalid disks and nics
1024
    for field in ["disks", "nics"]:
1025
      invalid_values = [None, 1, "", {}, [1, 2, 3], ["hda1", "hda2"],
1026
                        [{"_unknown_": False, }]]
1027

    
1028
      for invvalue in invalid_values:
1029
        data = reqfields.copy()
1030
        data[field] = invvalue
1031
        handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1032
        self.assertRaises(http.HttpBadRequest, handler.POST)
1033
        self.assertRaises(IndexError, clfactory.GetNextClient)
1034

    
1035
  def testVersion(self):
1036
    clfactory = _FakeClientFactory(_FakeClient)
1037

    
1038
    # No version field
1039
    data = {
1040
      "name": "inst1.example.com",
1041
      "disks": [],
1042
      "nics": [],
1043
      "mode": constants.INSTANCE_CREATE,
1044
      "disk_template": constants.DT_PLAIN,
1045
      }
1046

    
1047
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1048
    self.assertRaises(http.HttpBadRequest, handler.POST)
1049

    
1050
    # Old and incorrect versions
1051
    for version in [0, -1, 10483, "Hello World"]:
1052
      data[rlib2._REQ_DATA_VERSION] = version
1053

    
1054
      handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1055
      self.assertRaises(http.HttpBadRequest, handler.POST)
1056

    
1057
      self.assertRaises(IndexError, clfactory.GetNextClient)
1058

    
1059
    # Correct version
1060
    data[rlib2._REQ_DATA_VERSION] = 1
1061
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1062
    job_id = handler.POST()
1063

    
1064
    cl = clfactory.GetNextClient()
1065
    self.assertRaises(IndexError, clfactory.GetNextClient)
1066

    
1067
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1068
    self.assertEqual(job_id, exp_job_id)
1069
    self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
1070
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1071

    
1072

    
1073
class TestBackupExport(unittest.TestCase):
1074
  def test(self):
1075
    clfactory = _FakeClientFactory(_FakeClient)
1076

    
1077
    name = "instmoo"
1078
    data = {
1079
      "mode": constants.EXPORT_MODE_REMOTE,
1080
      "destination": [(1, 2, 3), (99, 99, 99)],
1081
      "shutdown": True,
1082
      "remove_instance": True,
1083
      "x509_key_name": ["name", "hash"],
1084
      "destination_x509_ca": "---cert---"
1085
      }
1086

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

    
1091
    cl = clfactory.GetNextClient()
1092
    self.assertRaises(IndexError, clfactory.GetNextClient)
1093

    
1094
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1095
    self.assertEqual(job_id, exp_job_id)
1096
    self.assertTrue(isinstance(op, opcodes.OpBackupExport))
1097
    self.assertEqual(op.instance_name, name)
1098
    self.assertEqual(op.mode, constants.EXPORT_MODE_REMOTE)
1099
    self.assertEqual(op.target_node, [(1, 2, 3), (99, 99, 99)])
1100
    self.assertEqual(op.shutdown, True)
1101
    self.assertEqual(op.remove_instance, True)
1102
    self.assertEqual(op.x509_key_name, ["name", "hash"])
1103
    self.assertEqual(op.destination_x509_ca, "---cert---")
1104
    self.assertFalse(hasattr(op, "dry_run"))
1105
    self.assertFalse(hasattr(op, "force"))
1106

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

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

    
1112
    name = "inst1"
1113
    data = {
1114
      "destination": "node2",
1115
      "shutdown": False,
1116
      }
1117

    
1118
    handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
1119
                             data, clfactory)
1120
    job_id = handler.PUT()
1121

    
1122
    cl = clfactory.GetNextClient()
1123
    self.assertRaises(IndexError, clfactory.GetNextClient)
1124

    
1125
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1126
    self.assertEqual(job_id, exp_job_id)
1127
    self.assertTrue(isinstance(op, opcodes.OpBackupExport))
1128
    self.assertEqual(op.instance_name, name)
1129
    self.assertEqual(op.target_node, "node2")
1130
    self.assertFalse(hasattr(op, "mode"))
1131
    self.assertFalse(hasattr(op, "remove_instance"))
1132
    self.assertFalse(hasattr(op, "destination"))
1133
    self.assertFalse(hasattr(op, "dry_run"))
1134
    self.assertFalse(hasattr(op, "force"))
1135

    
1136
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1137

    
1138
  def testErrors(self):
1139
    clfactory = _FakeClientFactory(_FakeClient)
1140

    
1141
    for value in ["True", "False"]:
1142
      handler = _CreateHandler(rlib2.R_2_instances_name_export, ["err1"], {}, {
1143
        "remove_instance": value,
1144
        }, clfactory)
1145
      self.assertRaises(http.HttpBadRequest, handler.PUT)
1146

    
1147

    
1148
class TestInstanceMigrate(testutils.GanetiTestCase):
1149
  def test(self):
1150
    clfactory = _FakeClientFactory(_FakeClient)
1151

    
1152
    name = "instYooho6ek"
1153

    
1154
    for cleanup in [False, True]:
1155
      for mode in constants.HT_MIGRATION_MODES:
1156
        data = {
1157
          "cleanup": cleanup,
1158
          "mode": mode,
1159
          }
1160

    
1161
        handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {},
1162
                                 data, clfactory)
1163
        job_id = handler.PUT()
1164

    
1165
        cl = clfactory.GetNextClient()
1166
        self.assertRaises(IndexError, clfactory.GetNextClient)
1167

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

    
1177
        self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1178

    
1179
  def testDefaults(self):
1180
    clfactory = _FakeClientFactory(_FakeClient)
1181

    
1182
    name = "instnohZeex0"
1183

    
1184
    handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {}, {},
1185
                             clfactory)
1186
    job_id = handler.PUT()
1187

    
1188
    cl = clfactory.GetNextClient()
1189
    self.assertRaises(IndexError, clfactory.GetNextClient)
1190

    
1191
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1192
    self.assertEqual(job_id, exp_job_id)
1193
    self.assertTrue(isinstance(op, opcodes.OpInstanceMigrate))
1194
    self.assertEqual(op.instance_name, name)
1195
    self.assertFalse(hasattr(op, "mode"))
1196
    self.assertFalse(hasattr(op, "cleanup"))
1197
    self.assertFalse(hasattr(op, "dry_run"))
1198
    self.assertFalse(hasattr(op, "force"))
1199

    
1200
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1201

    
1202

    
1203
class TestParseRenameInstanceRequest(testutils.GanetiTestCase):
1204
  def test(self):
1205
    clfactory = _FakeClientFactory(_FakeClient)
1206

    
1207
    name = "instij0eeph7"
1208

    
1209
    for new_name in ["ua0aiyoo", "fai3ongi"]:
1210
      for ip_check in [False, True]:
1211
        for name_check in [False, True]:
1212
          data = {
1213
            "new_name": new_name,
1214
            "ip_check": ip_check,
1215
            "name_check": name_check,
1216
            }
1217

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

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

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

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

    
1237
  def testDefaults(self):
1238
    clfactory = _FakeClientFactory(_FakeClient)
1239

    
1240
    name = "instahchie3t"
1241

    
1242
    for new_name in ["thag9mek", "quees7oh"]:
1243
      data = {
1244
        "new_name": new_name,
1245
        }
1246

    
1247
      handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
1248
                               {}, data, clfactory)
1249
      job_id = handler.PUT()
1250

    
1251
      cl = clfactory.GetNextClient()
1252
      self.assertRaises(IndexError, clfactory.GetNextClient)
1253

    
1254
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1255
      self.assertEqual(job_id, exp_job_id)
1256
      self.assertTrue(isinstance(op, opcodes.OpInstanceRename))
1257
      self.assertEqual(op.instance_name, name)
1258
      self.assertEqual(op.new_name, new_name)
1259
      self.assertFalse(hasattr(op, "ip_check"))
1260
      self.assertFalse(hasattr(op, "name_check"))
1261
      self.assertFalse(hasattr(op, "dry_run"))
1262
      self.assertFalse(hasattr(op, "force"))
1263

    
1264
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1265

    
1266

    
1267
class TestParseModifyInstanceRequest(unittest.TestCase):
1268
  def test(self):
1269
    clfactory = _FakeClientFactory(_FakeClient)
1270

    
1271
    name = "instush8gah"
1272

    
1273
    test_disks = [
1274
      [],
1275
      [(1, { constants.IDISK_MODE: constants.DISK_RDWR, })],
1276
      ]
1277

    
1278
    for osparams in [{}, { "some": "value", "other": "Hello World", }]:
1279
      for hvparams in [{}, { constants.HV_KERNEL_PATH: "/some/kernel", }]:
1280
        for beparams in [{}, { constants.BE_MAXMEM: 128, }]:
1281
          for force in [False, True]:
1282
            for nics in [[], [(0, { constants.INIC_IP: "192.0.2.1", })]]:
1283
              for disks in test_disks:
1284
                for disk_template in constants.DISK_TEMPLATES:
1285
                  data = {
1286
                    "osparams": osparams,
1287
                    "hvparams": hvparams,
1288
                    "beparams": beparams,
1289
                    "nics": nics,
1290
                    "disks": disks,
1291
                    "force": force,
1292
                    "disk_template": disk_template,
1293
                    }
1294

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

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

    
1302
                  (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1303
                  self.assertEqual(job_id, exp_job_id)
1304
                  self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
1305
                  self.assertEqual(op.instance_name, name)
1306
                  self.assertEqual(op.hvparams, hvparams)
1307
                  self.assertEqual(op.beparams, beparams)
1308
                  self.assertEqual(op.osparams, osparams)
1309
                  self.assertEqual(op.force, force)
1310
                  self.assertEqual(op.nics, nics)
1311
                  self.assertEqual(op.disks, disks)
1312
                  self.assertEqual(op.disk_template, disk_template)
1313
                  self.assertFalse(hasattr(op, "remote_node"))
1314
                  self.assertFalse(hasattr(op, "os_name"))
1315
                  self.assertFalse(hasattr(op, "force_variant"))
1316
                  self.assertFalse(hasattr(op, "dry_run"))
1317

    
1318
                  self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1319

    
1320
  def testDefaults(self):
1321
    clfactory = _FakeClientFactory(_FakeClient)
1322

    
1323
    name = "instir8aish31"
1324

    
1325
    handler = _CreateHandler(rlib2.R_2_instances_name_modify,
1326
                             [name], {}, {}, clfactory)
1327
    job_id = handler.PUT()
1328

    
1329
    cl = clfactory.GetNextClient()
1330
    self.assertRaises(IndexError, clfactory.GetNextClient)
1331

    
1332
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1333
    self.assertEqual(job_id, exp_job_id)
1334
    self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
1335
    self.assertEqual(op.instance_name, name)
1336

    
1337
    for i in ["hvparams", "beparams", "osparams", "force", "nics", "disks",
1338
              "disk_template", "remote_node", "os_name", "force_variant"]:
1339
      self.assertFalse(hasattr(op, i))
1340

    
1341

    
1342
class TestParseInstanceReinstallRequest(testutils.GanetiTestCase):
1343
  def setUp(self):
1344
    testutils.GanetiTestCase.setUp(self)
1345

    
1346
    self.Parse = rlib2._ParseInstanceReinstallRequest
1347

    
1348
  def _Check(self, ops, name):
1349
    expcls = [
1350
      opcodes.OpInstanceShutdown,
1351
      opcodes.OpInstanceReinstall,
1352
      opcodes.OpInstanceStartup,
1353
      ]
1354

    
1355
    self.assert_(compat.all(isinstance(op, exp)
1356
                            for op, exp in zip(ops, expcls)))
1357
    self.assert_(compat.all(op.instance_name == name for op in ops))
1358

    
1359
  def test(self):
1360
    name = "shoo0tihohma"
1361

    
1362
    ops = self.Parse(name, {"os": "sys1", "start": True,})
1363
    self.assertEqual(len(ops), 3)
1364
    self._Check(ops, name)
1365
    self.assertEqual(ops[1].os_type, "sys1")
1366
    self.assertFalse(ops[1].osparams)
1367

    
1368
    ops = self.Parse(name, {"os": "sys2", "start": False,})
1369
    self.assertEqual(len(ops), 2)
1370
    self._Check(ops, name)
1371
    self.assertEqual(ops[1].os_type, "sys2")
1372

    
1373
    osparams = {
1374
      "reformat": "1",
1375
      }
1376
    ops = self.Parse(name, {"os": "sys4035", "start": True,
1377
                            "osparams": osparams,})
1378
    self.assertEqual(len(ops), 3)
1379
    self._Check(ops, name)
1380
    self.assertEqual(ops[1].os_type, "sys4035")
1381
    self.assertEqual(ops[1].osparams, osparams)
1382

    
1383
  def testDefaults(self):
1384
    name = "noolee0g"
1385

    
1386
    ops = self.Parse(name, {"os": "linux1"})
1387
    self.assertEqual(len(ops), 3)
1388
    self._Check(ops, name)
1389
    self.assertEqual(ops[1].os_type, "linux1")
1390
    self.assertFalse(ops[1].osparams)
1391

    
1392
  def testErrors(self):
1393
    self.assertRaises(http.HttpBadRequest, self.Parse,
1394
                      "foo", "not a dictionary")
1395

    
1396

    
1397
class TestGroupRename(unittest.TestCase):
1398
  def test(self):
1399
    clfactory = _FakeClientFactory(_FakeClient)
1400

    
1401
    name = "group608242564"
1402
    data = {
1403
      "new_name": "ua0aiyoo15112",
1404
      }
1405

    
1406
    handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {}, data,
1407
                             clfactory)
1408
    job_id = handler.PUT()
1409

    
1410
    cl = clfactory.GetNextClient()
1411
    self.assertRaises(IndexError, clfactory.GetNextClient)
1412

    
1413
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1414
    self.assertEqual(job_id, exp_job_id)
1415

    
1416
    self.assertTrue(isinstance(op, opcodes.OpGroupRename))
1417
    self.assertEqual(op.group_name, name)
1418
    self.assertEqual(op.new_name, "ua0aiyoo15112")
1419
    self.assertFalse(op.dry_run)
1420
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1421

    
1422
  def testDryRun(self):
1423
    clfactory = _FakeClientFactory(_FakeClient)
1424

    
1425
    name = "group28548"
1426
    data = {
1427
      "new_name": "ua0aiyoo",
1428
      }
1429

    
1430
    handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {
1431
      "dry-run": ["1"],
1432
      }, data, clfactory)
1433
    job_id = handler.PUT()
1434

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

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

    
1441
    self.assertTrue(isinstance(op, opcodes.OpGroupRename))
1442
    self.assertEqual(op.group_name, name)
1443
    self.assertEqual(op.new_name, "ua0aiyoo")
1444
    self.assertTrue(op.dry_run)
1445
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1446

    
1447

    
1448
class TestInstanceReplaceDisks(unittest.TestCase):
1449
  def test(self):
1450
    clfactory = _FakeClientFactory(_FakeClient)
1451

    
1452
    name = "inst22568"
1453

    
1454
    for disks in [range(1, 4), "1,2,3", "1, 2, 3"]:
1455
      data = {
1456
        "mode": constants.REPLACE_DISK_SEC,
1457
        "disks": disks,
1458
        "iallocator": "myalloc",
1459
        }
1460

    
1461
      handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1462
                               [name], {}, data, clfactory)
1463
      job_id = handler.POST()
1464

    
1465
      cl = clfactory.GetNextClient()
1466
      self.assertRaises(IndexError, clfactory.GetNextClient)
1467

    
1468
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1469
      self.assertEqual(job_id, exp_job_id)
1470

    
1471
      self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
1472
      self.assertEqual(op.instance_name, name)
1473
      self.assertEqual(op.mode, constants.REPLACE_DISK_SEC)
1474
      self.assertEqual(op.disks, [1, 2, 3])
1475
      self.assertEqual(op.iallocator, "myalloc")
1476
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1477

    
1478
  def testDefaults(self):
1479
    clfactory = _FakeClientFactory(_FakeClient)
1480

    
1481
    name = "inst11413"
1482
    data = {
1483
      "mode": constants.REPLACE_DISK_AUTO,
1484
      }
1485

    
1486
    handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1487
                             [name], {}, data, clfactory)
1488
    job_id = handler.POST()
1489

    
1490
    cl = clfactory.GetNextClient()
1491
    self.assertRaises(IndexError, clfactory.GetNextClient)
1492

    
1493
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1494
    self.assertEqual(job_id, exp_job_id)
1495

    
1496
    self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
1497
    self.assertEqual(op.instance_name, name)
1498
    self.assertEqual(op.mode, constants.REPLACE_DISK_AUTO)
1499
    self.assertFalse(hasattr(op, "iallocator"))
1500
    self.assertFalse(hasattr(op, "disks"))
1501
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1502

    
1503
  def testNoDisks(self):
1504
    clfactory = _FakeClientFactory(_FakeClient)
1505

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

    
1510
    for disks in [None, "", {}]:
1511
      handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1512
                               ["inst20661"], {}, {
1513
        "disks": disks,
1514
        }, clfactory)
1515
      self.assertRaises(http.HttpBadRequest, handler.POST)
1516

    
1517
  def testWrong(self):
1518
    clfactory = _FakeClientFactory(_FakeClient)
1519

    
1520
    data = {
1521
      "mode": constants.REPLACE_DISK_AUTO,
1522
      "disks": "hello world",
1523
      }
1524

    
1525
    handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1526
                             ["foo"], {}, data, clfactory)
1527
    self.assertRaises(http.HttpBadRequest, handler.POST)
1528

    
1529

    
1530
class TestGroupModify(unittest.TestCase):
1531
  def test(self):
1532
    clfactory = _FakeClientFactory(_FakeClient)
1533

    
1534
    name = "group6002"
1535

    
1536
    for policy in constants.VALID_ALLOC_POLICIES:
1537
      data = {
1538
        "alloc_policy": policy,
1539
        }
1540

    
1541
      handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, data,
1542
                               clfactory)
1543
      job_id = handler.PUT()
1544

    
1545
      cl = clfactory.GetNextClient()
1546
      self.assertRaises(IndexError, clfactory.GetNextClient)
1547

    
1548
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1549
      self.assertEqual(job_id, exp_job_id)
1550

    
1551
      self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
1552
      self.assertEqual(op.group_name, name)
1553
      self.assertEqual(op.alloc_policy, policy)
1554
      self.assertFalse(hasattr(op, "dry_run"))
1555
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1556

    
1557
  def testUnknownPolicy(self):
1558
    clfactory = _FakeClientFactory(_FakeClient)
1559

    
1560
    data = {
1561
      "alloc_policy": "_unknown_policy_",
1562
      }
1563

    
1564
    handler = _CreateHandler(rlib2.R_2_groups_name_modify, ["xyz"], {}, data,
1565
                             clfactory)
1566
    self.assertRaises(http.HttpBadRequest, handler.PUT)
1567
    self.assertRaises(IndexError, clfactory.GetNextClient)
1568

    
1569
  def testDefaults(self):
1570
    clfactory = _FakeClientFactory(_FakeClient)
1571

    
1572
    name = "group6679"
1573

    
1574
    handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, {},
1575
                             clfactory)
1576
    job_id = handler.PUT()
1577

    
1578
    cl = clfactory.GetNextClient()
1579
    self.assertRaises(IndexError, clfactory.GetNextClient)
1580

    
1581
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1582
    self.assertEqual(job_id, exp_job_id)
1583

    
1584
    self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
1585
    self.assertEqual(op.group_name, name)
1586
    self.assertFalse(hasattr(op, "alloc_policy"))
1587
    self.assertFalse(hasattr(op, "dry_run"))
1588
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1589

    
1590

    
1591
class TestGroupAdd(unittest.TestCase):
1592
  def test(self):
1593
    name = "group3618"
1594
    clfactory = _FakeClientFactory(_FakeClient)
1595

    
1596
    for policy in constants.VALID_ALLOC_POLICIES:
1597
      data = {
1598
        "group_name": name,
1599
        "alloc_policy": policy,
1600
        }
1601

    
1602
      handler = _CreateHandler(rlib2.R_2_groups, [], {}, data,
1603
                               clfactory)
1604
      job_id = handler.POST()
1605

    
1606
      cl = clfactory.GetNextClient()
1607
      self.assertRaises(IndexError, clfactory.GetNextClient)
1608

    
1609
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1610
      self.assertEqual(job_id, exp_job_id)
1611

    
1612
      self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1613
      self.assertEqual(op.group_name, name)
1614
      self.assertEqual(op.alloc_policy, policy)
1615
      self.assertFalse(op.dry_run)
1616
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1617

    
1618
  def testUnknownPolicy(self):
1619
    clfactory = _FakeClientFactory(_FakeClient)
1620

    
1621
    data = {
1622
      "alloc_policy": "_unknown_policy_",
1623
      }
1624

    
1625
    handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1626
    self.assertRaises(http.HttpBadRequest, handler.POST)
1627
    self.assertRaises(IndexError, clfactory.GetNextClient)
1628

    
1629
  def testDefaults(self):
1630
    clfactory = _FakeClientFactory(_FakeClient)
1631

    
1632
    name = "group15395"
1633
    data = {
1634
      "group_name": name,
1635
      }
1636

    
1637
    handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1638
    job_id = handler.POST()
1639

    
1640
    cl = clfactory.GetNextClient()
1641
    self.assertRaises(IndexError, clfactory.GetNextClient)
1642

    
1643
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1644
    self.assertEqual(job_id, exp_job_id)
1645

    
1646
    self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1647
    self.assertEqual(op.group_name, name)
1648
    self.assertFalse(hasattr(op, "alloc_policy"))
1649
    self.assertFalse(op.dry_run)
1650

    
1651
  def testLegacyName(self):
1652
    clfactory = _FakeClientFactory(_FakeClient)
1653

    
1654
    name = "group29852"
1655
    data = {
1656
      "name": name,
1657
      }
1658

    
1659
    handler = _CreateHandler(rlib2.R_2_groups, [], {
1660
      "dry-run": ["1"],
1661
      }, data, clfactory)
1662
    job_id = handler.POST()
1663

    
1664
    cl = clfactory.GetNextClient()
1665
    self.assertRaises(IndexError, clfactory.GetNextClient)
1666

    
1667
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1668
    self.assertEqual(job_id, exp_job_id)
1669

    
1670
    self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1671
    self.assertEqual(op.group_name, name)
1672
    self.assertFalse(hasattr(op, "alloc_policy"))
1673
    self.assertTrue(op.dry_run)
1674

    
1675

    
1676
class TestNodeRole(unittest.TestCase):
1677
  def test(self):
1678
    clfactory = _FakeClientFactory(_FakeClient)
1679

    
1680
    for role in rlib2._NR_MAP.values():
1681
      handler = _CreateHandler(rlib2.R_2_nodes_name_role,
1682
                               ["node-z"], {}, role, clfactory)
1683
      if role == rlib2._NR_MASTER:
1684
        self.assertRaises(http.HttpBadRequest, handler.PUT)
1685
      else:
1686
        job_id = handler.PUT()
1687

    
1688
        cl = clfactory.GetNextClient()
1689
        self.assertRaises(IndexError, clfactory.GetNextClient)
1690

    
1691
        (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1692
        self.assertEqual(job_id, exp_job_id)
1693
        self.assertTrue(isinstance(op, opcodes.OpNodeSetParams))
1694
        self.assertEqual(op.node_name, "node-z")
1695
        self.assertFalse(op.force)
1696
        self.assertFalse(hasattr(op, "dry_run"))
1697

    
1698
        if role == rlib2._NR_REGULAR:
1699
          self.assertFalse(op.drained)
1700
          self.assertFalse(op.offline)
1701
          self.assertFalse(op.master_candidate)
1702
        elif role == rlib2._NR_MASTER_CANDIDATE:
1703
          self.assertFalse(op.drained)
1704
          self.assertFalse(op.offline)
1705
          self.assertTrue(op.master_candidate)
1706
        elif role == rlib2._NR_DRAINED:
1707
          self.assertTrue(op.drained)
1708
          self.assertFalse(op.offline)
1709
          self.assertFalse(op.master_candidate)
1710
        elif role == rlib2._NR_OFFLINE:
1711
          self.assertFalse(op.drained)
1712
          self.assertTrue(op.offline)
1713
          self.assertFalse(op.master_candidate)
1714
        else:
1715
          self.fail("Unknown role '%s'" % role)
1716

    
1717
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1718

    
1719

    
1720
class TestSimpleResources(unittest.TestCase):
1721
  def setUp(self):
1722
    self.clfactory = _FakeClientFactory(_FakeClient)
1723

    
1724
  def tearDown(self):
1725
    self.assertRaises(IndexError, self.clfactory.GetNextClient)
1726

    
1727
  def testFeatures(self):
1728
    handler = _CreateHandler(rlib2.R_2_features, [], {}, None, self.clfactory)
1729
    self.assertEqual(set(handler.GET()), rlib2.ALL_FEATURES)
1730

    
1731
  def testEmpty(self):
1732
    for cls in [rlib2.R_root, rlib2.R_2]:
1733
      handler = _CreateHandler(cls, [], {}, None, self.clfactory)
1734
      self.assertTrue(handler.GET() is None)
1735

    
1736
  def testVersion(self):
1737
    handler = _CreateHandler(rlib2.R_version, [], {}, None, self.clfactory)
1738
    self.assertEqual(handler.GET(), constants.RAPI_VERSION)
1739

    
1740

    
1741
class TestClusterInfo(unittest.TestCase):
1742
  class _ClusterInfoClient:
1743
    def __init__(self, address=None):
1744
      self.cluster_info = None
1745

    
1746
    def QueryClusterInfo(self):
1747
      assert self.cluster_info is None
1748
      self.cluster_info = object()
1749
      return self.cluster_info
1750

    
1751
  def test(self):
1752
    clfactory = _FakeClientFactory(self._ClusterInfoClient)
1753
    handler = _CreateHandler(rlib2.R_2_info, [], {}, None, clfactory)
1754
    result = handler.GET()
1755
    cl = clfactory.GetNextClient()
1756
    self.assertRaises(IndexError, clfactory.GetNextClient)
1757
    self.assertEqual(result, cl.cluster_info)
1758

    
1759

    
1760
class TestInstancesMultiAlloc(unittest.TestCase):
1761
  def testInstanceUpdate(self):
1762
    clfactory = _FakeClientFactory(_FakeClient)
1763
    data = {
1764
      "instances": [{
1765
        "instance_name": "bar",
1766
        "mode": "create",
1767
        }, {
1768
        "instance_name": "foo",
1769
        "mode": "create",
1770
        }],
1771
      }
1772
    handler = _CreateHandler(rlib2.R_2_instances_multi_alloc, [], {}, data,
1773
                             clfactory)
1774
    (body, _) = handler.GetPostOpInput()
1775
    self.assertTrue(compat.all([inst["OP_ID"] == handler.POST_OPCODE.OP_ID
1776
                                for inst in body["instances"]]))
1777

    
1778

    
1779
class TestPermissions(unittest.TestCase):
1780
  def testEquality(self):
1781
    self.assertEqual(rlib2.R_2_query.GET_ACCESS, rlib2.R_2_query.PUT_ACCESS)
1782
    self.assertEqual(rlib2.R_2_query.GET_ACCESS,
1783
                     rlib2.R_2_instances_name_console.GET_ACCESS)
1784

    
1785
  def testMethodAccess(self):
1786
    for handler in connector.CONNECTOR.values():
1787
      for method in baserlib._SUPPORTED_METHODS:
1788
        access = baserlib.GetHandlerAccess(handler, method)
1789
        self.assertFalse(access is None)
1790
        self.assertFalse(set(access) - rapi.RAPI_ACCESS_ALL,
1791
                         msg=("Handler '%s' uses unknown access options for"
1792
                              " method %s" % (handler, method)))
1793
        self.assertTrue(rapi.RAPI_ACCESS_READ not in access or
1794
                        rapi.RAPI_ACCESS_WRITE in access,
1795
                        msg=("Handler '%s' gives query, but not write access"
1796
                             " for method %s (the latter includes query and"
1797
                             " should therefore be given as well)" %
1798
                             (handler, method)))
1799

    
1800

    
1801
if __name__ == "__main__":
1802
  testutils.GanetiTestProgram()