Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.rapi.rlib2_unittest.py @ 1f350e0f

History | View | Annotate | Download (58.4 kB)

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

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

    
21

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

24
"""
25

    
26

    
27
import unittest
28
import itertools
29
import random
30

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

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

    
44
import testutils
45

    
46

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

    
51

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

    
56

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

    
61

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

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

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

    
74

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

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

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

    
88

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

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

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

    
106

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

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

    
122

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

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

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

    
137

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

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

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

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

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

    
167

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

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

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

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

    
183

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
257

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

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

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

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

    
280

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

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

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

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

    
300

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

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

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

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

    
325

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

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

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

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

    
346

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

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

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

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

    
366

    
367
class TestInstanceReboot(unittest.TestCase):
368
  def test(self):
369
    clfactory = _FakeClientFactory(_FakeClient)
370
    handler = _CreateHandler(rlib2.R_2_instances_name_reboot, ["inst847"], {
371
      "dry-run": ["1"],
372
      "ignore_secondaries": ["1"],
373
      "reason": ["System update"],
374
      }, {}, clfactory)
375
    job_id = handler.POST()
376

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

    
380
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
381
    self.assertEqual(job_id, exp_job_id)
382
    self.assertTrue(isinstance(op, opcodes.OpInstanceReboot))
383
    self.assertEqual(op.instance_name, "inst847")
384
    self.assertEqual(op.reboot_type, constants.INSTANCE_REBOOT_HARD)
385
    self.assertTrue(op.ignore_secondaries)
386
    self.assertTrue(op.dry_run)
387
    self.assertEqual(op.reason[0][0], constants.OPCODE_REASON_SRC_USER)
388
    self.assertEqual(op.reason[0][1], "System update")
389
    self.assertEqual(op.reason[1][0],
390
                     "%s:%s" % (constants.OPCODE_REASON_SRC_RLIB2,
391
                                "instances_name_reboot"))
392
    self.assertEqual(op.reason[1][1], "")
393

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

    
396

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

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

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

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

    
419

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

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

    
432
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
433
    self.assertEqual(job_id, exp_job_id)
434
    self.assertTrue(isinstance(op, opcodes.OpInstanceShutdown))
435
    self.assertEqual(op.instance_name, "inst26791")
436
    self.assertFalse(op.no_remember)
437
    self.assertFalse(op.dry_run)
438
    self.assertEqual(op.reason[0][0], constants.OPCODE_REASON_SRC_USER)
439
    self.assertEqual(op.reason[0][1], "Not used anymore")
440
    self.assertEqual(op.reason[1][0],
441
                     "%s:%s" % (constants.OPCODE_REASON_SRC_RLIB2,
442
                                "instances_name_shutdown"))
443
    self.assertEqual(op.reason[1][1], "")
444

    
445
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
446

    
447

    
448
class TestInstanceActivateDisks(unittest.TestCase):
449
  def test(self):
450
    clfactory = _FakeClientFactory(_FakeClient)
451
    handler = _CreateHandler(rlib2.R_2_instances_name_activate_disks, ["xyz"], {
452
      "ignore_size": ["1"],
453
      }, {}, clfactory)
454
    job_id = handler.PUT()
455

    
456
    cl = clfactory.GetNextClient()
457
    self.assertRaises(IndexError, clfactory.GetNextClient)
458

    
459
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
460
    self.assertEqual(job_id, exp_job_id)
461
    self.assertTrue(isinstance(op, opcodes.OpInstanceActivateDisks))
462
    self.assertEqual(op.instance_name, "xyz")
463
    self.assertTrue(op.ignore_size)
464
    self.assertFalse(hasattr(op, "dry_run"))
465

    
466
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
467

    
468

    
469
class TestInstanceDeactivateDisks(unittest.TestCase):
470
  def test(self):
471
    clfactory = _FakeClientFactory(_FakeClient)
472
    handler = _CreateHandler(rlib2.R_2_instances_name_deactivate_disks,
473
                             ["inst22357"], {}, {}, clfactory)
474
    job_id = handler.PUT()
475

    
476
    cl = clfactory.GetNextClient()
477
    self.assertRaises(IndexError, clfactory.GetNextClient)
478

    
479
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
480
    self.assertEqual(job_id, exp_job_id)
481
    self.assertTrue(isinstance(op, opcodes.OpInstanceDeactivateDisks))
482
    self.assertEqual(op.instance_name, "inst22357")
483
    self.assertFalse(hasattr(op, "dry_run"))
484
    self.assertFalse(hasattr(op, "force"))
485

    
486
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
487

    
488

    
489
class TestInstanceRecreateDisks(unittest.TestCase):
490
  def test(self):
491
    clfactory = _FakeClientFactory(_FakeClient)
492
    handler = _CreateHandler(rlib2.R_2_instances_name_recreate_disks,
493
                             ["inst22357"], {}, {}, clfactory)
494
    job_id = handler.POST()
495

    
496
    cl = clfactory.GetNextClient()
497
    self.assertRaises(IndexError, clfactory.GetNextClient)
498

    
499
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
500
    self.assertEqual(job_id, exp_job_id)
501
    self.assertTrue(isinstance(op, opcodes.OpInstanceRecreateDisks))
502
    self.assertEqual(op.instance_name, "inst22357")
503
    self.assertFalse(hasattr(op, "dry_run"))
504
    self.assertFalse(hasattr(op, "force"))
505

    
506
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
507

    
508

    
509
class TestInstanceFailover(unittest.TestCase):
510
  def test(self):
511
    clfactory = _FakeClientFactory(_FakeClient)
512
    handler = _CreateHandler(rlib2.R_2_instances_name_failover,
513
                             ["inst12794"], {}, {}, clfactory)
514
    job_id = handler.PUT()
515

    
516
    cl = clfactory.GetNextClient()
517
    self.assertRaises(IndexError, clfactory.GetNextClient)
518

    
519
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
520
    self.assertEqual(job_id, exp_job_id)
521
    self.assertTrue(isinstance(op, opcodes.OpInstanceFailover))
522
    self.assertEqual(op.instance_name, "inst12794")
523
    self.assertFalse(hasattr(op, "dry_run"))
524
    self.assertFalse(hasattr(op, "force"))
525

    
526
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
527

    
528

    
529
class TestInstanceDiskGrow(unittest.TestCase):
530
  def test(self):
531
    clfactory = _FakeClientFactory(_FakeClient)
532
    data = {
533
      "amount": 1024,
534
      }
535
    handler = _CreateHandler(rlib2.R_2_instances_name_disk_grow,
536
                             ["inst10742", "3"], {}, data, clfactory)
537
    job_id = handler.POST()
538

    
539
    cl = clfactory.GetNextClient()
540
    self.assertRaises(IndexError, clfactory.GetNextClient)
541

    
542
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
543
    self.assertEqual(job_id, exp_job_id)
544
    self.assertTrue(isinstance(op, opcodes.OpInstanceGrowDisk))
545
    self.assertEqual(op.instance_name, "inst10742")
546
    self.assertEqual(op.disk, 3)
547
    self.assertEqual(op.amount, 1024)
548
    self.assertFalse(hasattr(op, "dry_run"))
549
    self.assertFalse(hasattr(op, "force"))
550

    
551
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
552

    
553

    
554
class TestBackupPrepare(unittest.TestCase):
555
  def test(self):
556
    clfactory = _FakeClientFactory(_FakeClient)
557
    queryargs = {
558
      "mode": constants.EXPORT_MODE_REMOTE,
559
      }
560
    handler = _CreateHandler(rlib2.R_2_instances_name_prepare_export,
561
                             ["inst17925"], queryargs, {}, clfactory)
562
    job_id = handler.PUT()
563

    
564
    cl = clfactory.GetNextClient()
565
    self.assertRaises(IndexError, clfactory.GetNextClient)
566

    
567
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
568
    self.assertEqual(job_id, exp_job_id)
569
    self.assertTrue(isinstance(op, opcodes.OpBackupPrepare))
570
    self.assertEqual(op.instance_name, "inst17925")
571
    self.assertEqual(op.mode, constants.EXPORT_MODE_REMOTE)
572
    self.assertFalse(hasattr(op, "dry_run"))
573
    self.assertFalse(hasattr(op, "force"))
574

    
575
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
576

    
577

    
578
class TestGroupRemove(unittest.TestCase):
579
  def test(self):
580
    clfactory = _FakeClientFactory(_FakeClient)
581
    handler = _CreateHandler(rlib2.R_2_groups_name,
582
                             ["grp28575"], {}, {}, clfactory)
583
    job_id = handler.DELETE()
584

    
585
    cl = clfactory.GetNextClient()
586
    self.assertRaises(IndexError, clfactory.GetNextClient)
587

    
588
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
589
    self.assertEqual(job_id, exp_job_id)
590
    self.assertTrue(isinstance(op, opcodes.OpGroupRemove))
591
    self.assertEqual(op.group_name, "grp28575")
592
    self.assertFalse(op.dry_run)
593
    self.assertFalse(hasattr(op, "force"))
594

    
595
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
596

    
597

    
598
class TestStorageQuery(unittest.TestCase):
599
  def test(self):
600
    clfactory = _FakeClientFactory(_FakeClient)
601
    queryargs = {
602
      "storage_type": constants.ST_LVM_PV,
603
      "output_fields": "name,other",
604
      }
605
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
606
                             ["node21075"], queryargs, {}, clfactory)
607
    job_id = handler.GET()
608

    
609
    cl = clfactory.GetNextClient()
610
    self.assertRaises(IndexError, clfactory.GetNextClient)
611

    
612
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
613
    self.assertEqual(job_id, exp_job_id)
614
    self.assertTrue(isinstance(op, opcodes.OpNodeQueryStorage))
615
    self.assertEqual(op.nodes, ["node21075"])
616
    self.assertEqual(op.storage_type, constants.ST_LVM_PV)
617
    self.assertEqual(op.output_fields, ["name", "other"])
618
    self.assertFalse(hasattr(op, "dry_run"))
619
    self.assertFalse(hasattr(op, "force"))
620

    
621
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
622

    
623
  def testErrors(self):
624
    clfactory = _FakeClientFactory(_FakeClient)
625

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

    
633
    queryargs = {
634
      "storage_type": constants.ST_LVM_VG,
635
      }
636
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
637
                             ["node21273"], queryargs, {}, clfactory)
638
    self.assertRaises(http.HttpBadRequest, handler.GET)
639

    
640
    queryargs = {
641
      "storage_type": "##unknown_storage##",
642
      "output_fields": "name,other",
643
      }
644
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
645
                             ["node10315"], queryargs, {}, clfactory)
646
    self.assertRaises(http.HttpBadRequest, handler.GET)
647

    
648

    
649
class TestStorageModify(unittest.TestCase):
650
  def test(self):
651
    clfactory = _FakeClientFactory(_FakeClient)
652

    
653
    for allocatable in [None, "1", "0"]:
654
      queryargs = {
655
        "storage_type": constants.ST_LVM_VG,
656
        "name": "pv-a",
657
        }
658

    
659
      if allocatable is not None:
660
        queryargs["allocatable"] = allocatable
661

    
662
      handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
663
                               ["node9292"], queryargs, {}, clfactory)
664
      job_id = handler.PUT()
665

    
666
      cl = clfactory.GetNextClient()
667
      self.assertRaises(IndexError, clfactory.GetNextClient)
668

    
669
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
670
      self.assertEqual(job_id, exp_job_id)
671
      self.assertTrue(isinstance(op, opcodes.OpNodeModifyStorage))
672
      self.assertEqual(op.node_name, "node9292")
673
      self.assertEqual(op.storage_type, constants.ST_LVM_VG)
674
      self.assertEqual(op.name, "pv-a")
675
      if allocatable is None:
676
        self.assertFalse(op.changes)
677
      else:
678
        assert allocatable in ("0", "1")
679
        self.assertEqual(op.changes, {
680
          constants.SF_ALLOCATABLE: (allocatable == "1"),
681
          })
682
      self.assertFalse(hasattr(op, "dry_run"))
683
      self.assertFalse(hasattr(op, "force"))
684

    
685
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
686

    
687
  def testErrors(self):
688
    clfactory = _FakeClientFactory(_FakeClient)
689

    
690
    # No storage type
691
    queryargs = {
692
      "name": "xyz",
693
      }
694
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
695
                             ["node26016"], queryargs, {}, clfactory)
696
    self.assertRaises(http.HttpBadRequest, handler.PUT)
697

    
698
    # No name
699
    queryargs = {
700
      "storage_type": constants.ST_LVM_VG,
701
      }
702
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
703
                             ["node21218"], queryargs, {}, clfactory)
704
    self.assertRaises(http.HttpBadRequest, handler.PUT)
705

    
706
    # Invalid value
707
    queryargs = {
708
      "storage_type": constants.ST_LVM_VG,
709
      "name": "pv-b",
710
      "allocatable": "noint",
711
      }
712
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
713
                             ["node30685"], queryargs, {}, clfactory)
714
    self.assertRaises(http.HttpBadRequest, handler.PUT)
715

    
716

    
717
class TestStorageRepair(unittest.TestCase):
718
  def test(self):
719
    clfactory = _FakeClientFactory(_FakeClient)
720
    queryargs = {
721
      "storage_type": constants.ST_LVM_PV,
722
      "name": "pv16611",
723
      }
724
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
725
                             ["node19265"], queryargs, {}, clfactory)
726
    job_id = handler.PUT()
727

    
728
    cl = clfactory.GetNextClient()
729
    self.assertRaises(IndexError, clfactory.GetNextClient)
730

    
731
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
732
    self.assertEqual(job_id, exp_job_id)
733
    self.assertTrue(isinstance(op, opcodes.OpRepairNodeStorage))
734
    self.assertEqual(op.node_name, "node19265")
735
    self.assertEqual(op.storage_type, constants.ST_LVM_PV)
736
    self.assertEqual(op.name, "pv16611")
737
    self.assertFalse(hasattr(op, "dry_run"))
738
    self.assertFalse(hasattr(op, "force"))
739

    
740
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
741

    
742
  def testErrors(self):
743
    clfactory = _FakeClientFactory(_FakeClient)
744

    
745
    # No storage type
746
    queryargs = {
747
      "name": "xyz",
748
      }
749
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
750
                             ["node11275"], queryargs, {}, clfactory)
751
    self.assertRaises(http.HttpBadRequest, handler.PUT)
752

    
753
    # No name
754
    queryargs = {
755
      "storage_type": constants.ST_LVM_VG,
756
      }
757
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
758
                             ["node21218"], queryargs, {}, clfactory)
759
    self.assertRaises(http.HttpBadRequest, handler.PUT)
760

    
761

    
762
class TestTags(unittest.TestCase):
763
  TAG_HANDLERS = [
764
    rlib2.R_2_instances_name_tags,
765
    rlib2.R_2_nodes_name_tags,
766
    rlib2.R_2_groups_name_tags,
767
    rlib2.R_2_tags,
768
    ]
769

    
770
  def testSetAndDelete(self):
771
    clfactory = _FakeClientFactory(_FakeClient)
772

    
773
    for method, opcls in [("PUT", opcodes.OpTagsSet),
774
                          ("DELETE", opcodes.OpTagsDel)]:
775
      for idx, handler in enumerate(self.TAG_HANDLERS):
776
        dry_run = bool(idx % 2)
777
        name = "test%s" % idx
778
        queryargs = {
779
          "tag": ["foo", "bar", "baz"],
780
          "dry-run": str(int(dry_run)),
781
          }
782

    
783
        handler = _CreateHandler(handler, [name], queryargs, {}, clfactory)
784
        job_id = getattr(handler, method)()
785

    
786
        cl = clfactory.GetNextClient()
787
        self.assertRaises(IndexError, clfactory.GetNextClient)
788

    
789
        (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
790
        self.assertEqual(job_id, exp_job_id)
791
        self.assertTrue(isinstance(op, opcls))
792
        self.assertEqual(op.kind, handler.TAG_LEVEL)
793
        if handler.TAG_LEVEL == constants.TAG_CLUSTER:
794
          self.assertTrue(op.name is None)
795
        else:
796
          self.assertEqual(op.name, name)
797
        self.assertEqual(op.tags, ["foo", "bar", "baz"])
798
        self.assertEqual(op.dry_run, dry_run)
799
        self.assertFalse(hasattr(op, "force"))
800

    
801
        self.assertRaises(IndexError, cl.GetNextSubmittedJob)
802

    
803

    
804
class TestInstanceCreation(testutils.GanetiTestCase):
805
  def test(self):
806
    clfactory = _FakeClientFactory(_FakeClient)
807

    
808
    name = "inst863.example.com"
809

    
810
    disk_variants = [
811
      # No disks
812
      [],
813

    
814
      # Two disks
815
      [{"size": 5, }, {"size": 100, }],
816

    
817
      # Disk with mode
818
      [{"size": 123, "mode": constants.DISK_RDWR, }],
819
      ]
820

    
821
    nic_variants = [
822
      # No NIC
823
      [],
824

    
825
      # Three NICs
826
      [{}, {}, {}],
827

    
828
      # Two NICs
829
      [
830
        { "ip": "192.0.2.6", "mode": constants.NIC_MODE_ROUTED,
831
          "mac": "01:23:45:67:68:9A",
832
        },
833
        { "mode": constants.NIC_MODE_BRIDGED, "link": "br1" },
834
      ],
835
      ]
836

    
837
    beparam_variants = [
838
      None,
839
      {},
840
      { constants.BE_VCPUS: 2, },
841
      { constants.BE_MAXMEM: 200, },
842
      { constants.BE_MEMORY: 256, },
843
      { constants.BE_VCPUS: 2,
844
        constants.BE_MAXMEM: 1024,
845
        constants.BE_MINMEM: 1024,
846
        constants.BE_AUTO_BALANCE: True,
847
        constants.BE_ALWAYS_FAILOVER: True, }
848
      ]
849

    
850
    hvparam_variants = [
851
      None,
852
      { constants.HV_BOOT_ORDER: "anc", },
853
      { constants.HV_KERNEL_PATH: "/boot/fookernel",
854
        constants.HV_ROOT_PATH: "/dev/hda1", },
855
      ]
856

    
857
    for mode in [constants.INSTANCE_CREATE, constants.INSTANCE_IMPORT]:
858
      for nics in nic_variants:
859
        for disk_template in constants.DISK_TEMPLATES:
860
          for disks in disk_variants:
861
            for beparams in beparam_variants:
862
              for hvparams in hvparam_variants:
863
                for dry_run in [False, True]:
864
                  queryargs = {
865
                    "dry-run": str(int(dry_run)),
866
                    }
867

    
868
                  data = {
869
                    rlib2._REQ_DATA_VERSION: 1,
870
                    "name": name,
871
                    "hypervisor": constants.HT_FAKE,
872
                    "disks": disks,
873
                    "nics": nics,
874
                    "mode": mode,
875
                    "disk_template": disk_template,
876
                    "os": "debootstrap",
877
                    }
878

    
879
                  if beparams is not None:
880
                    data["beparams"] = beparams
881

    
882
                  if hvparams is not None:
883
                    data["hvparams"] = hvparams
884

    
885
                  handler = _CreateHandler(rlib2.R_2_instances, [],
886
                                           queryargs, data, clfactory)
887
                  job_id = handler.POST()
888

    
889
                  cl = clfactory.GetNextClient()
890
                  self.assertRaises(IndexError, clfactory.GetNextClient)
891

    
892
                  (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
893
                  self.assertEqual(job_id, exp_job_id)
894
                  self.assertRaises(IndexError, cl.GetNextSubmittedJob)
895

    
896
                  self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
897
                  self.assertEqual(op.instance_name, name)
898
                  self.assertEqual(op.mode, mode)
899
                  self.assertEqual(op.disk_template, disk_template)
900
                  self.assertEqual(op.dry_run, dry_run)
901
                  self.assertEqual(len(op.disks), len(disks))
902
                  self.assertEqual(len(op.nics), len(nics))
903

    
904
                  for opdisk, disk in zip(op.disks, disks):
905
                    for key in constants.IDISK_PARAMS:
906
                      self.assertEqual(opdisk.get(key), disk.get(key))
907
                    self.assertFalse("unknown" in opdisk)
908

    
909
                  for opnic, nic in zip(op.nics, nics):
910
                    for key in constants.INIC_PARAMS:
911
                      self.assertEqual(opnic.get(key), nic.get(key))
912
                    self.assertFalse("unknown" in opnic)
913
                    self.assertFalse("foobar" in opnic)
914

    
915
                  if beparams is None:
916
                    self.assertFalse(hasattr(op, "beparams"))
917
                  else:
918
                    self.assertEqualValues(op.beparams, beparams)
919

    
920
                  if hvparams is None:
921
                    self.assertFalse(hasattr(op, "hvparams"))
922
                  else:
923
                    self.assertEqualValues(op.hvparams, hvparams)
924

    
925
  def testLegacyName(self):
926
    clfactory = _FakeClientFactory(_FakeClient)
927

    
928
    name = "inst29128.example.com"
929
    data = {
930
      rlib2._REQ_DATA_VERSION: 1,
931
      "name": name,
932
      "disks": [],
933
      "nics": [],
934
      "mode": constants.INSTANCE_CREATE,
935
      "disk_template": constants.DT_PLAIN,
936
      }
937

    
938
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
939
    job_id = handler.POST()
940

    
941
    cl = clfactory.GetNextClient()
942
    self.assertRaises(IndexError, clfactory.GetNextClient)
943

    
944
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
945
    self.assertEqual(job_id, exp_job_id)
946
    self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
947
    self.assertEqual(op.instance_name, name)
948
    self.assertFalse(hasattr(op, "name"))
949
    self.assertFalse(op.dry_run)
950

    
951
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
952

    
953
    # Define both
954
    data["instance_name"] = "other.example.com"
955
    assert "name" in data and "instance_name" in data
956
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
957
    self.assertRaises(http.HttpBadRequest, handler.POST)
958
    self.assertRaises(IndexError, clfactory.GetNextClient)
959

    
960
  def testLegacyOs(self):
961
    clfactory = _FakeClientFactory(_FakeClient)
962

    
963
    name = "inst4673.example.com"
964
    os = "linux29206"
965
    data = {
966
      rlib2._REQ_DATA_VERSION: 1,
967
      "name": name,
968
      "os_type": os,
969
      "disks": [],
970
      "nics": [],
971
      "mode": constants.INSTANCE_CREATE,
972
      "disk_template": constants.DT_PLAIN,
973
      }
974

    
975
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
976
    job_id = handler.POST()
977

    
978
    cl = clfactory.GetNextClient()
979
    self.assertRaises(IndexError, clfactory.GetNextClient)
980

    
981
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
982
    self.assertEqual(job_id, exp_job_id)
983
    self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
984
    self.assertEqual(op.instance_name, name)
985
    self.assertEqual(op.os_type, os)
986
    self.assertFalse(hasattr(op, "os"))
987
    self.assertFalse(op.dry_run)
988

    
989
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
990

    
991
    # Define both
992
    data["os"] = "linux9584"
993
    assert "os" in data and "os_type" in data
994
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
995
    self.assertRaises(http.HttpBadRequest, handler.POST)
996

    
997
  def testErrors(self):
998
    clfactory = _FakeClientFactory(_FakeClient)
999

    
1000
    # Test all required fields
1001
    reqfields = {
1002
      rlib2._REQ_DATA_VERSION: 1,
1003
      "name": "inst1.example.com",
1004
      "disks": [],
1005
      "nics": [],
1006
      "mode": constants.INSTANCE_CREATE,
1007
      "disk_template": constants.DT_PLAIN,
1008
      }
1009

    
1010
    for name in reqfields.keys():
1011
      data = dict(i for i in reqfields.iteritems() if i[0] != name)
1012

    
1013
      handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1014
      self.assertRaises(http.HttpBadRequest, handler.POST)
1015
      self.assertRaises(IndexError, clfactory.GetNextClient)
1016

    
1017
    # Invalid disks and nics
1018
    for field in ["disks", "nics"]:
1019
      invalid_values = [None, 1, "", {}, [1, 2, 3], ["hda1", "hda2"],
1020
                        [{"_unknown_": False, }]]
1021

    
1022
      for invvalue in invalid_values:
1023
        data = reqfields.copy()
1024
        data[field] = invvalue
1025
        handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1026
        self.assertRaises(http.HttpBadRequest, handler.POST)
1027
        self.assertRaises(IndexError, clfactory.GetNextClient)
1028

    
1029
  def testVersion(self):
1030
    clfactory = _FakeClientFactory(_FakeClient)
1031

    
1032
    # No version field
1033
    data = {
1034
      "name": "inst1.example.com",
1035
      "disks": [],
1036
      "nics": [],
1037
      "mode": constants.INSTANCE_CREATE,
1038
      "disk_template": constants.DT_PLAIN,
1039
      }
1040

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

    
1044
    # Old and incorrect versions
1045
    for version in [0, -1, 10483, "Hello World"]:
1046
      data[rlib2._REQ_DATA_VERSION] = version
1047

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

    
1051
      self.assertRaises(IndexError, clfactory.GetNextClient)
1052

    
1053
    # Correct version
1054
    data[rlib2._REQ_DATA_VERSION] = 1
1055
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1056
    job_id = handler.POST()
1057

    
1058
    cl = clfactory.GetNextClient()
1059
    self.assertRaises(IndexError, clfactory.GetNextClient)
1060

    
1061
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1062
    self.assertEqual(job_id, exp_job_id)
1063
    self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
1064
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1065

    
1066

    
1067
class TestBackupExport(unittest.TestCase):
1068
  def test(self):
1069
    clfactory = _FakeClientFactory(_FakeClient)
1070

    
1071
    name = "instmoo"
1072
    data = {
1073
      "mode": constants.EXPORT_MODE_REMOTE,
1074
      "destination": [(1, 2, 3), (99, 99, 99)],
1075
      "shutdown": True,
1076
      "remove_instance": True,
1077
      "x509_key_name": ["name", "hash"],
1078
      "destination_x509_ca": "---cert---"
1079
      }
1080

    
1081
    handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
1082
                             data, clfactory)
1083
    job_id = handler.PUT()
1084

    
1085
    cl = clfactory.GetNextClient()
1086
    self.assertRaises(IndexError, clfactory.GetNextClient)
1087

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

    
1101
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1102

    
1103
  def testDefaults(self):
1104
    clfactory = _FakeClientFactory(_FakeClient)
1105

    
1106
    name = "inst1"
1107
    data = {
1108
      "destination": "node2",
1109
      "shutdown": False,
1110
      }
1111

    
1112
    handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
1113
                             data, clfactory)
1114
    job_id = handler.PUT()
1115

    
1116
    cl = clfactory.GetNextClient()
1117
    self.assertRaises(IndexError, clfactory.GetNextClient)
1118

    
1119
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1120
    self.assertEqual(job_id, exp_job_id)
1121
    self.assertTrue(isinstance(op, opcodes.OpBackupExport))
1122
    self.assertEqual(op.instance_name, name)
1123
    self.assertEqual(op.target_node, "node2")
1124
    self.assertFalse(hasattr(op, "mode"))
1125
    self.assertFalse(hasattr(op, "remove_instance"))
1126
    self.assertFalse(hasattr(op, "destination"))
1127
    self.assertFalse(hasattr(op, "dry_run"))
1128
    self.assertFalse(hasattr(op, "force"))
1129

    
1130
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1131

    
1132
  def testErrors(self):
1133
    clfactory = _FakeClientFactory(_FakeClient)
1134

    
1135
    for value in ["True", "False"]:
1136
      handler = _CreateHandler(rlib2.R_2_instances_name_export, ["err1"], {}, {
1137
        "remove_instance": value,
1138
        }, clfactory)
1139
      self.assertRaises(http.HttpBadRequest, handler.PUT)
1140

    
1141

    
1142
class TestInstanceMigrate(testutils.GanetiTestCase):
1143
  def test(self):
1144
    clfactory = _FakeClientFactory(_FakeClient)
1145

    
1146
    name = "instYooho6ek"
1147

    
1148
    for cleanup in [False, True]:
1149
      for mode in constants.HT_MIGRATION_MODES:
1150
        data = {
1151
          "cleanup": cleanup,
1152
          "mode": mode,
1153
          }
1154

    
1155
        handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {},
1156
                                 data, clfactory)
1157
        job_id = handler.PUT()
1158

    
1159
        cl = clfactory.GetNextClient()
1160
        self.assertRaises(IndexError, clfactory.GetNextClient)
1161

    
1162
        (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1163
        self.assertEqual(job_id, exp_job_id)
1164
        self.assertTrue(isinstance(op, opcodes.OpInstanceMigrate))
1165
        self.assertEqual(op.instance_name, name)
1166
        self.assertEqual(op.mode, mode)
1167
        self.assertEqual(op.cleanup, cleanup)
1168
        self.assertFalse(hasattr(op, "dry_run"))
1169
        self.assertFalse(hasattr(op, "force"))
1170

    
1171
        self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1172

    
1173
  def testDefaults(self):
1174
    clfactory = _FakeClientFactory(_FakeClient)
1175

    
1176
    name = "instnohZeex0"
1177

    
1178
    handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {}, {},
1179
                             clfactory)
1180
    job_id = handler.PUT()
1181

    
1182
    cl = clfactory.GetNextClient()
1183
    self.assertRaises(IndexError, clfactory.GetNextClient)
1184

    
1185
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1186
    self.assertEqual(job_id, exp_job_id)
1187
    self.assertTrue(isinstance(op, opcodes.OpInstanceMigrate))
1188
    self.assertEqual(op.instance_name, name)
1189
    self.assertFalse(hasattr(op, "mode"))
1190
    self.assertFalse(hasattr(op, "cleanup"))
1191
    self.assertFalse(hasattr(op, "dry_run"))
1192
    self.assertFalse(hasattr(op, "force"))
1193

    
1194
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1195

    
1196

    
1197
class TestParseRenameInstanceRequest(testutils.GanetiTestCase):
1198
  def test(self):
1199
    clfactory = _FakeClientFactory(_FakeClient)
1200

    
1201
    name = "instij0eeph7"
1202

    
1203
    for new_name in ["ua0aiyoo", "fai3ongi"]:
1204
      for ip_check in [False, True]:
1205
        for name_check in [False, True]:
1206
          data = {
1207
            "new_name": new_name,
1208
            "ip_check": ip_check,
1209
            "name_check": name_check,
1210
            }
1211

    
1212
          handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
1213
                                   {}, data, clfactory)
1214
          job_id = handler.PUT()
1215

    
1216
          cl = clfactory.GetNextClient()
1217
          self.assertRaises(IndexError, clfactory.GetNextClient)
1218

    
1219
          (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1220
          self.assertEqual(job_id, exp_job_id)
1221
          self.assertTrue(isinstance(op, opcodes.OpInstanceRename))
1222
          self.assertEqual(op.instance_name, name)
1223
          self.assertEqual(op.new_name, new_name)
1224
          self.assertEqual(op.ip_check, ip_check)
1225
          self.assertEqual(op.name_check, name_check)
1226
          self.assertFalse(hasattr(op, "dry_run"))
1227
          self.assertFalse(hasattr(op, "force"))
1228

    
1229
          self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1230

    
1231
  def testDefaults(self):
1232
    clfactory = _FakeClientFactory(_FakeClient)
1233

    
1234
    name = "instahchie3t"
1235

    
1236
    for new_name in ["thag9mek", "quees7oh"]:
1237
      data = {
1238
        "new_name": new_name,
1239
        }
1240

    
1241
      handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
1242
                               {}, data, clfactory)
1243
      job_id = handler.PUT()
1244

    
1245
      cl = clfactory.GetNextClient()
1246
      self.assertRaises(IndexError, clfactory.GetNextClient)
1247

    
1248
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1249
      self.assertEqual(job_id, exp_job_id)
1250
      self.assertTrue(isinstance(op, opcodes.OpInstanceRename))
1251
      self.assertEqual(op.instance_name, name)
1252
      self.assertEqual(op.new_name, new_name)
1253
      self.assertFalse(hasattr(op, "ip_check"))
1254
      self.assertFalse(hasattr(op, "name_check"))
1255
      self.assertFalse(hasattr(op, "dry_run"))
1256
      self.assertFalse(hasattr(op, "force"))
1257

    
1258
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1259

    
1260

    
1261
class TestParseModifyInstanceRequest(unittest.TestCase):
1262
  def test(self):
1263
    clfactory = _FakeClientFactory(_FakeClient)
1264

    
1265
    name = "instush8gah"
1266

    
1267
    test_disks = [
1268
      [],
1269
      [(1, { constants.IDISK_MODE: constants.DISK_RDWR, })],
1270
      ]
1271

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

    
1289
                  handler = _CreateHandler(rlib2.R_2_instances_name_modify,
1290
                                           [name], {}, data, clfactory)
1291
                  job_id = handler.PUT()
1292

    
1293
                  cl = clfactory.GetNextClient()
1294
                  self.assertRaises(IndexError, clfactory.GetNextClient)
1295

    
1296
                  (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1297
                  self.assertEqual(job_id, exp_job_id)
1298
                  self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
1299
                  self.assertEqual(op.instance_name, name)
1300
                  self.assertEqual(op.hvparams, hvparams)
1301
                  self.assertEqual(op.beparams, beparams)
1302
                  self.assertEqual(op.osparams, osparams)
1303
                  self.assertEqual(op.force, force)
1304
                  self.assertEqual(op.nics, nics)
1305
                  self.assertEqual(op.disks, disks)
1306
                  self.assertEqual(op.disk_template, disk_template)
1307
                  self.assertFalse(hasattr(op, "remote_node"))
1308
                  self.assertFalse(hasattr(op, "os_name"))
1309
                  self.assertFalse(hasattr(op, "force_variant"))
1310
                  self.assertFalse(hasattr(op, "dry_run"))
1311

    
1312
                  self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1313

    
1314
  def testDefaults(self):
1315
    clfactory = _FakeClientFactory(_FakeClient)
1316

    
1317
    name = "instir8aish31"
1318

    
1319
    handler = _CreateHandler(rlib2.R_2_instances_name_modify,
1320
                             [name], {}, {}, clfactory)
1321
    job_id = handler.PUT()
1322

    
1323
    cl = clfactory.GetNextClient()
1324
    self.assertRaises(IndexError, clfactory.GetNextClient)
1325

    
1326
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1327
    self.assertEqual(job_id, exp_job_id)
1328
    self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
1329
    self.assertEqual(op.instance_name, name)
1330

    
1331
    for i in ["hvparams", "beparams", "osparams", "force", "nics", "disks",
1332
              "disk_template", "remote_node", "os_name", "force_variant"]:
1333
      self.assertFalse(hasattr(op, i))
1334

    
1335

    
1336
class TestParseInstanceReinstallRequest(testutils.GanetiTestCase):
1337
  def setUp(self):
1338
    testutils.GanetiTestCase.setUp(self)
1339

    
1340
    self.Parse = rlib2._ParseInstanceReinstallRequest
1341

    
1342
  def _Check(self, ops, name):
1343
    expcls = [
1344
      opcodes.OpInstanceShutdown,
1345
      opcodes.OpInstanceReinstall,
1346
      opcodes.OpInstanceStartup,
1347
      ]
1348

    
1349
    self.assert_(compat.all(isinstance(op, exp)
1350
                            for op, exp in zip(ops, expcls)))
1351
    self.assert_(compat.all(op.instance_name == name for op in ops))
1352

    
1353
  def test(self):
1354
    name = "shoo0tihohma"
1355

    
1356
    ops = self.Parse(name, {"os": "sys1", "start": True,})
1357
    self.assertEqual(len(ops), 3)
1358
    self._Check(ops, name)
1359
    self.assertEqual(ops[1].os_type, "sys1")
1360
    self.assertFalse(ops[1].osparams)
1361

    
1362
    ops = self.Parse(name, {"os": "sys2", "start": False,})
1363
    self.assertEqual(len(ops), 2)
1364
    self._Check(ops, name)
1365
    self.assertEqual(ops[1].os_type, "sys2")
1366

    
1367
    osparams = {
1368
      "reformat": "1",
1369
      }
1370
    ops = self.Parse(name, {"os": "sys4035", "start": True,
1371
                            "osparams": osparams,})
1372
    self.assertEqual(len(ops), 3)
1373
    self._Check(ops, name)
1374
    self.assertEqual(ops[1].os_type, "sys4035")
1375
    self.assertEqual(ops[1].osparams, osparams)
1376

    
1377
  def testDefaults(self):
1378
    name = "noolee0g"
1379

    
1380
    ops = self.Parse(name, {"os": "linux1"})
1381
    self.assertEqual(len(ops), 3)
1382
    self._Check(ops, name)
1383
    self.assertEqual(ops[1].os_type, "linux1")
1384
    self.assertFalse(ops[1].osparams)
1385

    
1386
  def testErrors(self):
1387
    self.assertRaises(http.HttpBadRequest, self.Parse,
1388
                      "foo", "not a dictionary")
1389

    
1390

    
1391
class TestGroupRename(unittest.TestCase):
1392
  def test(self):
1393
    clfactory = _FakeClientFactory(_FakeClient)
1394

    
1395
    name = "group608242564"
1396
    data = {
1397
      "new_name": "ua0aiyoo15112",
1398
      }
1399

    
1400
    handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {}, data,
1401
                             clfactory)
1402
    job_id = handler.PUT()
1403

    
1404
    cl = clfactory.GetNextClient()
1405
    self.assertRaises(IndexError, clfactory.GetNextClient)
1406

    
1407
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1408
    self.assertEqual(job_id, exp_job_id)
1409

    
1410
    self.assertTrue(isinstance(op, opcodes.OpGroupRename))
1411
    self.assertEqual(op.group_name, name)
1412
    self.assertEqual(op.new_name, "ua0aiyoo15112")
1413
    self.assertFalse(op.dry_run)
1414
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1415

    
1416
  def testDryRun(self):
1417
    clfactory = _FakeClientFactory(_FakeClient)
1418

    
1419
    name = "group28548"
1420
    data = {
1421
      "new_name": "ua0aiyoo",
1422
      }
1423

    
1424
    handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {
1425
      "dry-run": ["1"],
1426
      }, data, clfactory)
1427
    job_id = handler.PUT()
1428

    
1429
    cl = clfactory.GetNextClient()
1430
    self.assertRaises(IndexError, clfactory.GetNextClient)
1431

    
1432
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1433
    self.assertEqual(job_id, exp_job_id)
1434

    
1435
    self.assertTrue(isinstance(op, opcodes.OpGroupRename))
1436
    self.assertEqual(op.group_name, name)
1437
    self.assertEqual(op.new_name, "ua0aiyoo")
1438
    self.assertTrue(op.dry_run)
1439
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1440

    
1441

    
1442
class TestInstanceReplaceDisks(unittest.TestCase):
1443
  def test(self):
1444
    clfactory = _FakeClientFactory(_FakeClient)
1445

    
1446
    name = "inst22568"
1447

    
1448
    for disks in [range(1, 4), "1,2,3", "1, 2, 3"]:
1449
      data = {
1450
        "mode": constants.REPLACE_DISK_SEC,
1451
        "disks": disks,
1452
        "iallocator": "myalloc",
1453
        }
1454

    
1455
      handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1456
                               [name], {}, data, clfactory)
1457
      job_id = handler.POST()
1458

    
1459
      cl = clfactory.GetNextClient()
1460
      self.assertRaises(IndexError, clfactory.GetNextClient)
1461

    
1462
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1463
      self.assertEqual(job_id, exp_job_id)
1464

    
1465
      self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
1466
      self.assertEqual(op.instance_name, name)
1467
      self.assertEqual(op.mode, constants.REPLACE_DISK_SEC)
1468
      self.assertEqual(op.disks, [1, 2, 3])
1469
      self.assertEqual(op.iallocator, "myalloc")
1470
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1471

    
1472
  def testDefaults(self):
1473
    clfactory = _FakeClientFactory(_FakeClient)
1474

    
1475
    name = "inst11413"
1476
    data = {
1477
      "mode": constants.REPLACE_DISK_AUTO,
1478
      }
1479

    
1480
    handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1481
                             [name], {}, data, clfactory)
1482
    job_id = handler.POST()
1483

    
1484
    cl = clfactory.GetNextClient()
1485
    self.assertRaises(IndexError, clfactory.GetNextClient)
1486

    
1487
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1488
    self.assertEqual(job_id, exp_job_id)
1489

    
1490
    self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
1491
    self.assertEqual(op.instance_name, name)
1492
    self.assertEqual(op.mode, constants.REPLACE_DISK_AUTO)
1493
    self.assertFalse(hasattr(op, "iallocator"))
1494
    self.assertFalse(hasattr(op, "disks"))
1495
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1496

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

    
1500
    handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1501
                             ["inst20661"], {}, {}, clfactory)
1502
    self.assertRaises(http.HttpBadRequest, handler.POST)
1503

    
1504
    for disks in [None, "", {}]:
1505
      handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1506
                               ["inst20661"], {}, {
1507
        "disks": disks,
1508
        }, clfactory)
1509
      self.assertRaises(http.HttpBadRequest, handler.POST)
1510

    
1511
  def testWrong(self):
1512
    clfactory = _FakeClientFactory(_FakeClient)
1513

    
1514
    data = {
1515
      "mode": constants.REPLACE_DISK_AUTO,
1516
      "disks": "hello world",
1517
      }
1518

    
1519
    handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1520
                             ["foo"], {}, data, clfactory)
1521
    self.assertRaises(http.HttpBadRequest, handler.POST)
1522

    
1523

    
1524
class TestGroupModify(unittest.TestCase):
1525
  def test(self):
1526
    clfactory = _FakeClientFactory(_FakeClient)
1527

    
1528
    name = "group6002"
1529

    
1530
    for policy in constants.VALID_ALLOC_POLICIES:
1531
      data = {
1532
        "alloc_policy": policy,
1533
        }
1534

    
1535
      handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, data,
1536
                               clfactory)
1537
      job_id = handler.PUT()
1538

    
1539
      cl = clfactory.GetNextClient()
1540
      self.assertRaises(IndexError, clfactory.GetNextClient)
1541

    
1542
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1543
      self.assertEqual(job_id, exp_job_id)
1544

    
1545
      self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
1546
      self.assertEqual(op.group_name, name)
1547
      self.assertEqual(op.alloc_policy, policy)
1548
      self.assertFalse(hasattr(op, "dry_run"))
1549
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1550

    
1551
  def testUnknownPolicy(self):
1552
    clfactory = _FakeClientFactory(_FakeClient)
1553

    
1554
    data = {
1555
      "alloc_policy": "_unknown_policy_",
1556
      }
1557

    
1558
    handler = _CreateHandler(rlib2.R_2_groups_name_modify, ["xyz"], {}, data,
1559
                             clfactory)
1560
    self.assertRaises(http.HttpBadRequest, handler.PUT)
1561
    self.assertRaises(IndexError, clfactory.GetNextClient)
1562

    
1563
  def testDefaults(self):
1564
    clfactory = _FakeClientFactory(_FakeClient)
1565

    
1566
    name = "group6679"
1567

    
1568
    handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, {},
1569
                             clfactory)
1570
    job_id = handler.PUT()
1571

    
1572
    cl = clfactory.GetNextClient()
1573
    self.assertRaises(IndexError, clfactory.GetNextClient)
1574

    
1575
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1576
    self.assertEqual(job_id, exp_job_id)
1577

    
1578
    self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
1579
    self.assertEqual(op.group_name, name)
1580
    self.assertFalse(hasattr(op, "alloc_policy"))
1581
    self.assertFalse(hasattr(op, "dry_run"))
1582
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1583

    
1584

    
1585
class TestGroupAdd(unittest.TestCase):
1586
  def test(self):
1587
    name = "group3618"
1588
    clfactory = _FakeClientFactory(_FakeClient)
1589

    
1590
    for policy in constants.VALID_ALLOC_POLICIES:
1591
      data = {
1592
        "group_name": name,
1593
        "alloc_policy": policy,
1594
        }
1595

    
1596
      handler = _CreateHandler(rlib2.R_2_groups, [], {}, data,
1597
                               clfactory)
1598
      job_id = handler.POST()
1599

    
1600
      cl = clfactory.GetNextClient()
1601
      self.assertRaises(IndexError, clfactory.GetNextClient)
1602

    
1603
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1604
      self.assertEqual(job_id, exp_job_id)
1605

    
1606
      self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1607
      self.assertEqual(op.group_name, name)
1608
      self.assertEqual(op.alloc_policy, policy)
1609
      self.assertFalse(op.dry_run)
1610
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1611

    
1612
  def testUnknownPolicy(self):
1613
    clfactory = _FakeClientFactory(_FakeClient)
1614

    
1615
    data = {
1616
      "alloc_policy": "_unknown_policy_",
1617
      }
1618

    
1619
    handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1620
    self.assertRaises(http.HttpBadRequest, handler.POST)
1621
    self.assertRaises(IndexError, clfactory.GetNextClient)
1622

    
1623
  def testDefaults(self):
1624
    clfactory = _FakeClientFactory(_FakeClient)
1625

    
1626
    name = "group15395"
1627
    data = {
1628
      "group_name": name,
1629
      }
1630

    
1631
    handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1632
    job_id = handler.POST()
1633

    
1634
    cl = clfactory.GetNextClient()
1635
    self.assertRaises(IndexError, clfactory.GetNextClient)
1636

    
1637
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1638
    self.assertEqual(job_id, exp_job_id)
1639

    
1640
    self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1641
    self.assertEqual(op.group_name, name)
1642
    self.assertFalse(hasattr(op, "alloc_policy"))
1643
    self.assertFalse(op.dry_run)
1644

    
1645
  def testLegacyName(self):
1646
    clfactory = _FakeClientFactory(_FakeClient)
1647

    
1648
    name = "group29852"
1649
    data = {
1650
      "name": name,
1651
      }
1652

    
1653
    handler = _CreateHandler(rlib2.R_2_groups, [], {
1654
      "dry-run": ["1"],
1655
      }, data, clfactory)
1656
    job_id = handler.POST()
1657

    
1658
    cl = clfactory.GetNextClient()
1659
    self.assertRaises(IndexError, clfactory.GetNextClient)
1660

    
1661
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1662
    self.assertEqual(job_id, exp_job_id)
1663

    
1664
    self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1665
    self.assertEqual(op.group_name, name)
1666
    self.assertFalse(hasattr(op, "alloc_policy"))
1667
    self.assertTrue(op.dry_run)
1668

    
1669

    
1670
class TestNodeRole(unittest.TestCase):
1671
  def test(self):
1672
    clfactory = _FakeClientFactory(_FakeClient)
1673

    
1674
    for role in rlib2._NR_MAP.values():
1675
      handler = _CreateHandler(rlib2.R_2_nodes_name_role,
1676
                               ["node-z"], {}, role, clfactory)
1677
      if role == rlib2._NR_MASTER:
1678
        self.assertRaises(http.HttpBadRequest, handler.PUT)
1679
      else:
1680
        job_id = handler.PUT()
1681

    
1682
        cl = clfactory.GetNextClient()
1683
        self.assertRaises(IndexError, clfactory.GetNextClient)
1684

    
1685
        (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1686
        self.assertEqual(job_id, exp_job_id)
1687
        self.assertTrue(isinstance(op, opcodes.OpNodeSetParams))
1688
        self.assertEqual(op.node_name, "node-z")
1689
        self.assertFalse(op.force)
1690
        self.assertFalse(hasattr(op, "dry_run"))
1691

    
1692
        if role == rlib2._NR_REGULAR:
1693
          self.assertFalse(op.drained)
1694
          self.assertFalse(op.offline)
1695
          self.assertFalse(op.master_candidate)
1696
        elif role == rlib2._NR_MASTER_CANDIDATE:
1697
          self.assertFalse(op.drained)
1698
          self.assertFalse(op.offline)
1699
          self.assertTrue(op.master_candidate)
1700
        elif role == rlib2._NR_DRAINED:
1701
          self.assertTrue(op.drained)
1702
          self.assertFalse(op.offline)
1703
          self.assertFalse(op.master_candidate)
1704
        elif role == rlib2._NR_OFFLINE:
1705
          self.assertFalse(op.drained)
1706
          self.assertTrue(op.offline)
1707
          self.assertFalse(op.master_candidate)
1708
        else:
1709
          self.fail("Unknown role '%s'" % role)
1710

    
1711
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1712

    
1713

    
1714
class TestSimpleResources(unittest.TestCase):
1715
  def setUp(self):
1716
    self.clfactory = _FakeClientFactory(_FakeClient)
1717

    
1718
  def tearDown(self):
1719
    self.assertRaises(IndexError, self.clfactory.GetNextClient)
1720

    
1721
  def testFeatures(self):
1722
    handler = _CreateHandler(rlib2.R_2_features, [], {}, None, self.clfactory)
1723
    self.assertEqual(set(handler.GET()), rlib2.ALL_FEATURES)
1724

    
1725
  def testEmpty(self):
1726
    for cls in [rlib2.R_root, rlib2.R_2]:
1727
      handler = _CreateHandler(cls, [], {}, None, self.clfactory)
1728
      self.assertTrue(handler.GET() is None)
1729

    
1730
  def testVersion(self):
1731
    handler = _CreateHandler(rlib2.R_version, [], {}, None, self.clfactory)
1732
    self.assertEqual(handler.GET(), constants.RAPI_VERSION)
1733

    
1734

    
1735
class TestClusterInfo(unittest.TestCase):
1736
  class _ClusterInfoClient:
1737
    def __init__(self, address=None):
1738
      self.cluster_info = None
1739

    
1740
    def QueryClusterInfo(self):
1741
      assert self.cluster_info is None
1742
      self.cluster_info = object()
1743
      return self.cluster_info
1744

    
1745
  def test(self):
1746
    clfactory = _FakeClientFactory(self._ClusterInfoClient)
1747
    handler = _CreateHandler(rlib2.R_2_info, [], {}, None, clfactory)
1748
    result = handler.GET()
1749
    cl = clfactory.GetNextClient()
1750
    self.assertRaises(IndexError, clfactory.GetNextClient)
1751
    self.assertEqual(result, cl.cluster_info)
1752

    
1753

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

    
1772

    
1773
class TestPermissions(unittest.TestCase):
1774
  def testEquality(self):
1775
    self.assertEqual(rlib2.R_2_query.GET_ACCESS, rlib2.R_2_query.PUT_ACCESS)
1776
    self.assertEqual(rlib2.R_2_query.GET_ACCESS,
1777
                     rlib2.R_2_instances_name_console.GET_ACCESS)
1778

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

    
1794

    
1795
if __name__ == "__main__":
1796
  testutils.GanetiTestProgram()