Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.rapi.rlib2_unittest.py @ 7352d33b

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.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
      "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
      "disk_template": constants.DT_PLAIN,
1015
      }
1016

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1073

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1148

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

    
1153
    name = "instYooho6ek"
1154

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

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

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

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

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

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

    
1183
    name = "instnohZeex0"
1184

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

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

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

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

    
1203

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

    
1208
    name = "instij0eeph7"
1209

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

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

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

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

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

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

    
1241
    name = "instahchie3t"
1242

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

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

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

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

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

    
1267

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

    
1272
    name = "instush8gah"
1273

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

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

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

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

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

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

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

    
1324
    name = "instir8aish31"
1325

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

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

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

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

    
1342

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

    
1347
    self.Parse = rlib2._ParseInstanceReinstallRequest
1348

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

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

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

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

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

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

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

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

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

    
1397

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

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

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

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

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

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

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

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

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

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

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

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

    
1448

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

    
1453
    name = "inst22568"
1454

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1530

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

    
1535
    name = "group6002"
1536

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

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

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

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

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

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

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

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

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

    
1573
    name = "group6679"
1574

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

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

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

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

    
1591

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1676

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

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

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

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

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

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

    
1720

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

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

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

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

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

    
1741

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

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

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

    
1760

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

    
1779

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

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

    
1801

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