Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.rapi.rlib2_unittest.py @ 460ef073

History | View | Annotate | Download (49.5 kB)

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

    
4
# Copyright (C) 2010 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

    
39
from ganeti.rapi import rlib2
40

    
41
import testutils
42

    
43

    
44
class _FakeRequestPrivateData:
45
  def __init__(self, body_data):
46
    self.body_data = body_data
47

    
48

    
49
class _FakeRequest:
50
  def __init__(self, body_data):
51
    self.private = _FakeRequestPrivateData(body_data)
52

    
53

    
54
def _CreateHandler(cls, items, queryargs, body_data, client_cls):
55
  return cls(items, queryargs, _FakeRequest(body_data),
56
             _client_cls=client_cls)
57

    
58

    
59
class _FakeClient:
60
  def __init__(self):
61
    self._jobs = []
62

    
63
  def GetNextSubmittedJob(self):
64
    return self._jobs.pop(0)
65

    
66
  def SubmitJob(self, ops):
67
    job_id = str(1 + int(random.random() * 1000000))
68
    self._jobs.append((job_id, ops))
69
    return job_id
70

    
71

    
72
class _FakeClientFactory:
73
  def __init__(self, cls):
74
    self._client_cls = cls
75
    self._clients = []
76

    
77
  def GetNextClient(self):
78
    return self._clients.pop(0)
79

    
80
  def __call__(self):
81
    cl = self._client_cls()
82
    self._clients.append(cl)
83
    return cl
84

    
85

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

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

    
100
    for (qr, fields) in checks.items():
101
      self.assertFalse(set(fields) - set(query.ALL_FIELDS[qr].keys()))
102

    
103

    
104
class TestClientConnectError(unittest.TestCase):
105
  @staticmethod
106
  def _FailingClient():
107
    raise luxi.NoMasterError("test")
108

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

    
119

    
120
class TestJobSubmitError(unittest.TestCase):
121
  class _SubmitErrorClient:
122
    @staticmethod
123
    def SubmitJob(ops):
124
      raise errors.JobQueueFull("test")
125

    
126
  def test(self):
127
    handler = _CreateHandler(rlib2.R_2_redist_config, [], [], None,
128
                             self._SubmitErrorClient)
129
    self.assertRaises(http.HttpServiceUnavailable, handler.PUT)
130

    
131

    
132
class TestClusterModify(unittest.TestCase):
133
  def test(self):
134
    clfactory = _FakeClientFactory(_FakeClient)
135
    handler = _CreateHandler(rlib2.R_2_cluster_modify, [], [], {
136
      "vg_name": "testvg",
137
      "candidate_pool_size": 100,
138
      }, clfactory)
139
    job_id = handler.PUT()
140

    
141
    cl = clfactory.GetNextClient()
142
    self.assertRaises(IndexError, clfactory.GetNextClient)
143

    
144
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
145
    self.assertEqual(job_id, exp_job_id)
146
    self.assertTrue(isinstance(op, opcodes.OpClusterSetParams))
147
    self.assertEqual(op.vg_name, "testvg")
148
    self.assertEqual(op.candidate_pool_size, 100)
149

    
150
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
151

    
152
  def testInvalidValue(self):
153
    for attr in ["vg_name", "candidate_pool_size", "beparams", "_-Unknown#"]:
154
      clfactory = _FakeClientFactory(_FakeClient)
155
      handler = _CreateHandler(rlib2.R_2_cluster_modify, [], [], {
156
        attr: True,
157
        }, clfactory)
158
      self.assertRaises(http.HttpBadRequest, handler.PUT)
159
      self.assertRaises(IndexError, clfactory.GetNextClient)
160

    
161

    
162
class TestRedistConfig(unittest.TestCase):
163
  def test(self):
164
    clfactory = _FakeClientFactory(_FakeClient)
165
    handler = _CreateHandler(rlib2.R_2_redist_config, [], [], None, clfactory)
166
    job_id = handler.PUT()
167

    
168
    cl = clfactory.GetNextClient()
169
    self.assertRaises(IndexError, clfactory.GetNextClient)
170

    
171
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
172
    self.assertEqual(job_id, exp_job_id)
173
    self.assertTrue(isinstance(op, opcodes.OpClusterRedistConf))
174

    
175
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
176

    
177

    
178
class TestNodeMigrate(unittest.TestCase):
179
  def test(self):
180
    clfactory = _FakeClientFactory(_FakeClient)
181
    handler = _CreateHandler(rlib2.R_2_nodes_name_migrate, ["node1"], {}, {
182
      "iallocator": "fooalloc",
183
      }, clfactory)
184
    job_id = handler.POST()
185

    
186
    cl = clfactory.GetNextClient()
187
    self.assertRaises(IndexError, clfactory.GetNextClient)
188

    
189
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
190
    self.assertEqual(job_id, exp_job_id)
191
    self.assertTrue(isinstance(op, opcodes.OpNodeMigrate))
192
    self.assertEqual(op.node_name, "node1")
193
    self.assertEqual(op.iallocator, "fooalloc")
194

    
195
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
196

    
197
  def testQueryArgsConflict(self):
198
    clfactory = _FakeClientFactory(_FakeClient)
199
    handler = _CreateHandler(rlib2.R_2_nodes_name_migrate, ["node2"], {
200
      "live": True,
201
      "mode": constants.HT_MIGRATION_NONLIVE,
202
      }, None, clfactory)
203
    self.assertRaises(http.HttpBadRequest, handler.POST)
204
    self.assertRaises(IndexError, clfactory.GetNextClient)
205

    
206
  def testQueryArgsMode(self):
207
    clfactory = _FakeClientFactory(_FakeClient)
208
    queryargs = {
209
      "mode": [constants.HT_MIGRATION_LIVE],
210
      }
211
    handler = _CreateHandler(rlib2.R_2_nodes_name_migrate, ["node17292"],
212
                             queryargs, None, clfactory)
213
    job_id = handler.POST()
214

    
215
    cl = clfactory.GetNextClient()
216
    self.assertRaises(IndexError, clfactory.GetNextClient)
217

    
218
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
219
    self.assertEqual(job_id, exp_job_id)
220
    self.assertTrue(isinstance(op, opcodes.OpNodeMigrate))
221
    self.assertEqual(op.node_name, "node17292")
222
    self.assertEqual(op.mode, constants.HT_MIGRATION_LIVE)
223

    
224
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
225

    
226
  def testQueryArgsLive(self):
227
    clfactory = _FakeClientFactory(_FakeClient)
228

    
229
    for live in [False, True]:
230
      queryargs = {
231
        "live": [str(int(live))],
232
        }
233
      handler = _CreateHandler(rlib2.R_2_nodes_name_migrate, ["node6940"],
234
                               queryargs, None, clfactory)
235
      job_id = handler.POST()
236

    
237
      cl = clfactory.GetNextClient()
238
      self.assertRaises(IndexError, clfactory.GetNextClient)
239

    
240
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
241
      self.assertEqual(job_id, exp_job_id)
242
      self.assertTrue(isinstance(op, opcodes.OpNodeMigrate))
243
      self.assertEqual(op.node_name, "node6940")
244
      if live:
245
        self.assertEqual(op.mode, constants.HT_MIGRATION_LIVE)
246
      else:
247
        self.assertEqual(op.mode, constants.HT_MIGRATION_NONLIVE)
248

    
249
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
250

    
251

    
252
class TestNodeEvacuate(unittest.TestCase):
253
  def test(self):
254
    clfactory = _FakeClientFactory(_FakeClient)
255
    handler = _CreateHandler(rlib2.R_2_nodes_name_evacuate, ["node92"], {
256
      "dry-run": ["1"],
257
      }, {
258
      "mode": constants.IALLOCATOR_NEVAC_SEC,
259
      }, clfactory)
260
    job_id = handler.POST()
261

    
262
    cl = clfactory.GetNextClient()
263
    self.assertRaises(IndexError, clfactory.GetNextClient)
264

    
265
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
266
    self.assertEqual(job_id, exp_job_id)
267
    self.assertTrue(isinstance(op, opcodes.OpNodeEvacuate))
268
    self.assertEqual(op.node_name, "node92")
269
    self.assertEqual(op.mode, constants.IALLOCATOR_NEVAC_SEC)
270
    self.assertTrue(op.dry_run)
271

    
272
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
273

    
274

    
275
class TestGroupAssignNodes(unittest.TestCase):
276
  def test(self):
277
    clfactory = _FakeClientFactory(_FakeClient)
278
    handler = _CreateHandler(rlib2.R_2_groups_name_assign_nodes, ["grp-a"], {
279
      "dry-run": ["1"],
280
      "force": ["1"],
281
      }, {
282
      "nodes": ["n2", "n3"],
283
      }, clfactory)
284
    job_id = handler.PUT()
285

    
286
    cl = clfactory.GetNextClient()
287
    self.assertRaises(IndexError, clfactory.GetNextClient)
288

    
289
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
290
    self.assertEqual(job_id, exp_job_id)
291
    self.assertTrue(isinstance(op, opcodes.OpGroupAssignNodes))
292
    self.assertEqual(op.group_name, "grp-a")
293
    self.assertEqual(op.nodes, ["n2", "n3"])
294
    self.assertTrue(op.dry_run)
295
    self.assertTrue(op.force)
296

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

    
299

    
300
class TestInstanceDelete(unittest.TestCase):
301
  def test(self):
302
    clfactory = _FakeClientFactory(_FakeClient)
303
    handler = _CreateHandler(rlib2.R_2_instances_name, ["inst30965"], {
304
      "dry-run": ["1"],
305
      }, {}, clfactory)
306
    job_id = handler.DELETE()
307

    
308
    cl = clfactory.GetNextClient()
309
    self.assertRaises(IndexError, clfactory.GetNextClient)
310

    
311
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
312
    self.assertEqual(job_id, exp_job_id)
313
    self.assertTrue(isinstance(op, opcodes.OpInstanceRemove))
314
    self.assertEqual(op.instance_name, "inst30965")
315
    self.assertTrue(op.dry_run)
316
    self.assertFalse(op.ignore_failures)
317

    
318
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
319

    
320

    
321
class TestInstanceInfo(unittest.TestCase):
322
  def test(self):
323
    clfactory = _FakeClientFactory(_FakeClient)
324
    handler = _CreateHandler(rlib2.R_2_instances_name_info, ["inst31217"], {
325
      "static": ["1"],
326
      }, {}, clfactory)
327
    job_id = handler.GET()
328

    
329
    cl = clfactory.GetNextClient()
330
    self.assertRaises(IndexError, clfactory.GetNextClient)
331

    
332
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
333
    self.assertEqual(job_id, exp_job_id)
334
    self.assertTrue(isinstance(op, opcodes.OpInstanceQueryData))
335
    self.assertEqual(op.instances, ["inst31217"])
336
    self.assertTrue(op.static)
337

    
338
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
339

    
340

    
341
class TestInstanceReboot(unittest.TestCase):
342
  def test(self):
343
    clfactory = _FakeClientFactory(_FakeClient)
344
    handler = _CreateHandler(rlib2.R_2_instances_name_reboot, ["inst847"], {
345
      "dry-run": ["1"],
346
      "ignore_secondaries": ["1"],
347
      }, {}, clfactory)
348
    job_id = handler.POST()
349

    
350
    cl = clfactory.GetNextClient()
351
    self.assertRaises(IndexError, clfactory.GetNextClient)
352

    
353
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
354
    self.assertEqual(job_id, exp_job_id)
355
    self.assertTrue(isinstance(op, opcodes.OpInstanceReboot))
356
    self.assertEqual(op.instance_name, "inst847")
357
    self.assertEqual(op.reboot_type, constants.INSTANCE_REBOOT_HARD)
358
    self.assertTrue(op.ignore_secondaries)
359
    self.assertTrue(op.dry_run)
360

    
361
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
362

    
363

    
364
class TestInstanceStartup(unittest.TestCase):
365
  def test(self):
366
    clfactory = _FakeClientFactory(_FakeClient)
367
    handler = _CreateHandler(rlib2.R_2_instances_name_startup, ["inst31083"], {
368
      "force": ["1"],
369
      "no_remember": ["1"],
370
      }, {}, clfactory)
371
    job_id = handler.PUT()
372

    
373
    cl = clfactory.GetNextClient()
374
    self.assertRaises(IndexError, clfactory.GetNextClient)
375

    
376
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
377
    self.assertEqual(job_id, exp_job_id)
378
    self.assertTrue(isinstance(op, opcodes.OpInstanceStartup))
379
    self.assertEqual(op.instance_name, "inst31083")
380
    self.assertTrue(op.no_remember)
381
    self.assertTrue(op.force)
382
    self.assertFalse(op.dry_run)
383

    
384
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
385

    
386

    
387
class TestInstanceShutdown(unittest.TestCase):
388
  def test(self):
389
    clfactory = _FakeClientFactory(_FakeClient)
390
    handler = _CreateHandler(rlib2.R_2_instances_name_shutdown, ["inst26791"], {
391
      "no_remember": ["0"],
392
      }, {}, clfactory)
393
    job_id = handler.PUT()
394

    
395
    cl = clfactory.GetNextClient()
396
    self.assertRaises(IndexError, clfactory.GetNextClient)
397

    
398
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
399
    self.assertEqual(job_id, exp_job_id)
400
    self.assertTrue(isinstance(op, opcodes.OpInstanceShutdown))
401
    self.assertEqual(op.instance_name, "inst26791")
402
    self.assertFalse(op.no_remember)
403
    self.assertFalse(op.dry_run)
404

    
405
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
406

    
407

    
408
class TestInstanceActivateDisks(unittest.TestCase):
409
  def test(self):
410
    clfactory = _FakeClientFactory(_FakeClient)
411
    handler = _CreateHandler(rlib2.R_2_instances_name_activate_disks, ["xyz"], {
412
      "ignore_size": ["1"],
413
      }, {}, clfactory)
414
    job_id = handler.PUT()
415

    
416
    cl = clfactory.GetNextClient()
417
    self.assertRaises(IndexError, clfactory.GetNextClient)
418

    
419
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
420
    self.assertEqual(job_id, exp_job_id)
421
    self.assertTrue(isinstance(op, opcodes.OpInstanceActivateDisks))
422
    self.assertEqual(op.instance_name, "xyz")
423
    self.assertTrue(op.ignore_size)
424
    self.assertFalse(hasattr(op, "dry_run"))
425

    
426
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
427

    
428

    
429
class TestInstanceDeactivateDisks(unittest.TestCase):
430
  def test(self):
431
    clfactory = _FakeClientFactory(_FakeClient)
432
    handler = _CreateHandler(rlib2.R_2_instances_name_deactivate_disks,
433
                             ["inst22357"], {}, {}, 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.OpInstanceDeactivateDisks))
442
    self.assertEqual(op.instance_name, "inst22357")
443
    self.assertFalse(hasattr(op, "dry_run"))
444
    self.assertFalse(hasattr(op, "force"))
445

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

    
448

    
449
class TestInstanceFailover(unittest.TestCase):
450
  def test(self):
451
    clfactory = _FakeClientFactory(_FakeClient)
452
    handler = _CreateHandler(rlib2.R_2_instances_name_failover,
453
                             ["inst12794"], {}, {}, 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.OpInstanceFailover))
462
    self.assertEqual(op.instance_name, "inst12794")
463
    self.assertFalse(hasattr(op, "dry_run"))
464
    self.assertFalse(hasattr(op, "force"))
465

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

    
468

    
469
class TestInstanceDiskGrow(unittest.TestCase):
470
  def test(self):
471
    clfactory = _FakeClientFactory(_FakeClient)
472
    data = {
473
      "amount": 1024,
474
      }
475
    handler = _CreateHandler(rlib2.R_2_instances_name_disk_grow,
476
                             ["inst10742", "3"], {}, data, clfactory)
477
    job_id = handler.POST()
478

    
479
    cl = clfactory.GetNextClient()
480
    self.assertRaises(IndexError, clfactory.GetNextClient)
481

    
482
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
483
    self.assertEqual(job_id, exp_job_id)
484
    self.assertTrue(isinstance(op, opcodes.OpInstanceGrowDisk))
485
    self.assertEqual(op.instance_name, "inst10742")
486
    self.assertEqual(op.disk, 3)
487
    self.assertEqual(op.amount, 1024)
488
    self.assertFalse(hasattr(op, "dry_run"))
489
    self.assertFalse(hasattr(op, "force"))
490

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

    
493

    
494
class TestBackupPrepare(unittest.TestCase):
495
  def test(self):
496
    clfactory = _FakeClientFactory(_FakeClient)
497
    queryargs = {
498
      "mode": constants.EXPORT_MODE_REMOTE,
499
      }
500
    handler = _CreateHandler(rlib2.R_2_instances_name_prepare_export,
501
                             ["inst17925"], queryargs, {}, clfactory)
502
    job_id = handler.PUT()
503

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

    
507
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
508
    self.assertEqual(job_id, exp_job_id)
509
    self.assertTrue(isinstance(op, opcodes.OpBackupPrepare))
510
    self.assertEqual(op.instance_name, "inst17925")
511
    self.assertEqual(op.mode, constants.EXPORT_MODE_REMOTE)
512
    self.assertFalse(hasattr(op, "dry_run"))
513
    self.assertFalse(hasattr(op, "force"))
514

    
515
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
516

    
517

    
518
class TestGroupRemove(unittest.TestCase):
519
  def test(self):
520
    clfactory = _FakeClientFactory(_FakeClient)
521
    handler = _CreateHandler(rlib2.R_2_groups_name,
522
                             ["grp28575"], {}, {}, clfactory)
523
    job_id = handler.DELETE()
524

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

    
528
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
529
    self.assertEqual(job_id, exp_job_id)
530
    self.assertTrue(isinstance(op, opcodes.OpGroupRemove))
531
    self.assertEqual(op.group_name, "grp28575")
532
    self.assertFalse(op.dry_run)
533
    self.assertFalse(hasattr(op, "force"))
534

    
535
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
536

    
537

    
538
class TestStorageQuery(unittest.TestCase):
539
  def test(self):
540
    clfactory = _FakeClientFactory(_FakeClient)
541
    queryargs = {
542
      "storage_type": constants.ST_LVM_PV,
543
      "output_fields": "name,other",
544
      }
545
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
546
                             ["node21075"], queryargs, {}, clfactory)
547
    job_id = handler.GET()
548

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

    
552
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
553
    self.assertEqual(job_id, exp_job_id)
554
    self.assertTrue(isinstance(op, opcodes.OpNodeQueryStorage))
555
    self.assertEqual(op.nodes, ["node21075"])
556
    self.assertEqual(op.storage_type, constants.ST_LVM_PV)
557
    self.assertEqual(op.output_fields, ["name", "other"])
558
    self.assertFalse(hasattr(op, "dry_run"))
559
    self.assertFalse(hasattr(op, "force"))
560

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

    
563
  def testErrors(self):
564
    clfactory = _FakeClientFactory(_FakeClient)
565

    
566
    queryargs = {
567
      "output_fields": "name,other",
568
      }
569
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
570
                             ["node10538"], queryargs, {}, clfactory)
571
    self.assertRaises(http.HttpBadRequest, handler.GET)
572

    
573
    queryargs = {
574
      "storage_type": constants.ST_LVM_VG,
575
      }
576
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
577
                             ["node21273"], queryargs, {}, clfactory)
578
    self.assertRaises(http.HttpBadRequest, handler.GET)
579

    
580
    queryargs = {
581
      "storage_type": "##unknown_storage##",
582
      "output_fields": "name,other",
583
      }
584
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
585
                             ["node10315"], queryargs, {}, clfactory)
586
    self.assertRaises(http.HttpBadRequest, handler.GET)
587

    
588

    
589
class TestStorageModify(unittest.TestCase):
590
  def test(self):
591
    clfactory = _FakeClientFactory(_FakeClient)
592

    
593
    for allocatable in [None, "1", "0"]:
594
      queryargs = {
595
        "storage_type": constants.ST_LVM_VG,
596
        "name": "pv-a",
597
        }
598

    
599
      if allocatable is not None:
600
        queryargs["allocatable"] = allocatable
601

    
602
      handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
603
                               ["node9292"], queryargs, {}, clfactory)
604
      job_id = handler.PUT()
605

    
606
      cl = clfactory.GetNextClient()
607
      self.assertRaises(IndexError, clfactory.GetNextClient)
608

    
609
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
610
      self.assertEqual(job_id, exp_job_id)
611
      self.assertTrue(isinstance(op, opcodes.OpNodeModifyStorage))
612
      self.assertEqual(op.node_name, "node9292")
613
      self.assertEqual(op.storage_type, constants.ST_LVM_VG)
614
      self.assertEqual(op.name, "pv-a")
615
      if allocatable is None:
616
        self.assertFalse(op.changes)
617
      else:
618
        assert allocatable in ("0", "1")
619
        self.assertEqual(op.changes, {
620
          constants.SF_ALLOCATABLE: (allocatable == "1"),
621
          })
622
      self.assertFalse(hasattr(op, "dry_run"))
623
      self.assertFalse(hasattr(op, "force"))
624

    
625
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
626

    
627
  def testErrors(self):
628
    clfactory = _FakeClientFactory(_FakeClient)
629

    
630
    # No storage type
631
    queryargs = {
632
      "name": "xyz",
633
      }
634
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
635
                             ["node26016"], queryargs, {}, clfactory)
636
    self.assertRaises(http.HttpBadRequest, handler.PUT)
637

    
638
    # No name
639
    queryargs = {
640
      "storage_type": constants.ST_LVM_VG,
641
      }
642
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
643
                             ["node21218"], queryargs, {}, clfactory)
644
    self.assertRaises(http.HttpBadRequest, handler.PUT)
645

    
646
    # Invalid value
647
    queryargs = {
648
      "storage_type": constants.ST_LVM_VG,
649
      "name": "pv-b",
650
      "allocatable": "noint",
651
      }
652
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
653
                             ["node30685"], queryargs, {}, clfactory)
654
    self.assertRaises(http.HttpBadRequest, handler.PUT)
655

    
656

    
657
class TestStorageRepair(unittest.TestCase):
658
  def test(self):
659
    clfactory = _FakeClientFactory(_FakeClient)
660
    queryargs = {
661
      "storage_type": constants.ST_LVM_PV,
662
      "name": "pv16611",
663
      }
664
    handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
665
                             ["node19265"], queryargs, {}, clfactory)
666
    job_id = handler.PUT()
667

    
668
    cl = clfactory.GetNextClient()
669
    self.assertRaises(IndexError, clfactory.GetNextClient)
670

    
671
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
672
    self.assertEqual(job_id, exp_job_id)
673
    self.assertTrue(isinstance(op, opcodes.OpRepairNodeStorage))
674
    self.assertEqual(op.node_name, "node19265")
675
    self.assertEqual(op.storage_type, constants.ST_LVM_PV)
676
    self.assertEqual(op.name, "pv16611")
677
    self.assertFalse(hasattr(op, "dry_run"))
678
    self.assertFalse(hasattr(op, "force"))
679

    
680
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
681

    
682
  def testErrors(self):
683
    clfactory = _FakeClientFactory(_FakeClient)
684

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

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

    
701

    
702
class TestTags(unittest.TestCase):
703
  TAG_HANDLERS = [
704
    rlib2.R_2_instances_name_tags,
705
    rlib2.R_2_nodes_name_tags,
706
    rlib2.R_2_groups_name_tags,
707
    rlib2.R_2_tags,
708
    ]
709

    
710
  def testSetAndDelete(self):
711
    clfactory = _FakeClientFactory(_FakeClient)
712

    
713
    for method, opcls in [("PUT", opcodes.OpTagsSet),
714
                          ("DELETE", opcodes.OpTagsDel)]:
715
      for idx, handler in enumerate(self.TAG_HANDLERS):
716
        dry_run = bool(idx % 2)
717
        name = "test%s" % idx
718
        queryargs = {
719
          "tag": ["foo", "bar", "baz"],
720
          "dry-run": str(int(dry_run)),
721
          }
722

    
723
        handler = _CreateHandler(handler, [name], queryargs, {}, clfactory)
724
        job_id = getattr(handler, method)()
725

    
726
        cl = clfactory.GetNextClient()
727
        self.assertRaises(IndexError, clfactory.GetNextClient)
728

    
729
        (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
730
        self.assertEqual(job_id, exp_job_id)
731
        self.assertTrue(isinstance(op, opcls))
732
        self.assertEqual(op.kind, handler.TAG_LEVEL)
733
        if handler.TAG_LEVEL == constants.TAG_CLUSTER:
734
          self.assertTrue(op.name is None)
735
        else:
736
          self.assertEqual(op.name, name)
737
        self.assertEqual(op.tags, ["foo", "bar", "baz"])
738
        self.assertEqual(op.dry_run, dry_run)
739
        self.assertFalse(hasattr(op, "force"))
740

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

    
743

    
744
class TestParseInstanceCreateRequestVersion1(testutils.GanetiTestCase):
745
  def setUp(self):
746
    testutils.GanetiTestCase.setUp(self)
747

    
748
    self.Parse = rlib2._ParseInstanceCreateRequestVersion1
749

    
750
  def test(self):
751
    disk_variants = [
752
      # No disks
753
      [],
754

    
755
      # Two disks
756
      [{"size": 5, }, {"size": 100, }],
757

    
758
      # Disk with mode
759
      [{"size": 123, "mode": constants.DISK_RDWR, }],
760
      ]
761

    
762
    nic_variants = [
763
      # No NIC
764
      [],
765

    
766
      # Three NICs
767
      [{}, {}, {}],
768

    
769
      # Two NICs
770
      [
771
        { "ip": "192.0.2.6", "mode": constants.NIC_MODE_ROUTED,
772
          "mac": "01:23:45:67:68:9A",
773
        },
774
        { "mode": constants.NIC_MODE_BRIDGED, "link": "br1" },
775
      ],
776
      ]
777

    
778
    beparam_variants = [
779
      None,
780
      {},
781
      { constants.BE_VCPUS: 2, },
782
      { constants.BE_MEMORY: 123, },
783
      { constants.BE_VCPUS: 2,
784
        constants.BE_MEMORY: 1024,
785
        constants.BE_AUTO_BALANCE: True, }
786
      ]
787

    
788
    hvparam_variants = [
789
      None,
790
      { constants.HV_BOOT_ORDER: "anc", },
791
      { constants.HV_KERNEL_PATH: "/boot/fookernel",
792
        constants.HV_ROOT_PATH: "/dev/hda1", },
793
      ]
794

    
795
    for mode in [constants.INSTANCE_CREATE, constants.INSTANCE_IMPORT]:
796
      for nics in nic_variants:
797
        for disk_template in constants.DISK_TEMPLATES:
798
          for disks in disk_variants:
799
            for beparams in beparam_variants:
800
              for hvparams in hvparam_variants:
801
                data = {
802
                  "name": "inst1.example.com",
803
                  "hypervisor": constants.HT_FAKE,
804
                  "disks": disks,
805
                  "nics": nics,
806
                  "mode": mode,
807
                  "disk_template": disk_template,
808
                  "os": "debootstrap",
809
                  }
810

    
811
                if beparams is not None:
812
                  data["beparams"] = beparams
813

    
814
                if hvparams is not None:
815
                  data["hvparams"] = hvparams
816

    
817
                for dry_run in [False, True]:
818
                  op = self.Parse(data, dry_run)
819
                  self.assert_(isinstance(op, opcodes.OpInstanceCreate))
820
                  self.assertEqual(op.mode, mode)
821
                  self.assertEqual(op.disk_template, disk_template)
822
                  self.assertEqual(op.dry_run, dry_run)
823
                  self.assertEqual(len(op.disks), len(disks))
824
                  self.assertEqual(len(op.nics), len(nics))
825

    
826
                  for opdisk, disk in zip(op.disks, disks):
827
                    for key in constants.IDISK_PARAMS:
828
                      self.assertEqual(opdisk.get(key), disk.get(key))
829
                    self.assertFalse("unknown" in opdisk)
830

    
831
                  for opnic, nic in zip(op.nics, nics):
832
                    for key in constants.INIC_PARAMS:
833
                      self.assertEqual(opnic.get(key), nic.get(key))
834
                    self.assertFalse("unknown" in opnic)
835
                    self.assertFalse("foobar" in opnic)
836

    
837
                  if beparams is None:
838
                    self.assertFalse(hasattr(op, "beparams"))
839
                  else:
840
                    self.assertEqualValues(op.beparams, beparams)
841

    
842
                  if hvparams is None:
843
                    self.assertFalse(hasattr(op, "hvparams"))
844
                  else:
845
                    self.assertEqualValues(op.hvparams, hvparams)
846

    
847
  def testLegacyName(self):
848
    name = "inst29128.example.com"
849
    data = {
850
      "name": name,
851
      "disks": [],
852
      "nics": [],
853
      "mode": constants.INSTANCE_CREATE,
854
      "disk_template": constants.DT_PLAIN,
855
      }
856
    op = self.Parse(data, False)
857
    self.assert_(isinstance(op, opcodes.OpInstanceCreate))
858
    self.assertEqual(op.instance_name, name)
859
    self.assertFalse(hasattr(op, "name"))
860

    
861
    # Define both
862
    data = {
863
      "name": name,
864
      "instance_name": "other.example.com",
865
      "disks": [],
866
      "nics": [],
867
      "mode": constants.INSTANCE_CREATE,
868
      "disk_template": constants.DT_PLAIN,
869
      }
870
    self.assertRaises(http.HttpBadRequest, self.Parse, data, False)
871

    
872
  def testLegacyOs(self):
873
    name = "inst4673.example.com"
874
    os = "linux29206"
875
    data = {
876
      "name": name,
877
      "os_type": os,
878
      "disks": [],
879
      "nics": [],
880
      "mode": constants.INSTANCE_CREATE,
881
      "disk_template": constants.DT_PLAIN,
882
      }
883
    op = self.Parse(data, False)
884
    self.assert_(isinstance(op, opcodes.OpInstanceCreate))
885
    self.assertEqual(op.instance_name, name)
886
    self.assertEqual(op.os_type, os)
887
    self.assertFalse(hasattr(op, "os"))
888

    
889
    # Define both
890
    data = {
891
      "instance_name": name,
892
      "os": os,
893
      "os_type": "linux9584",
894
      "disks": [],
895
      "nics": [],
896
      "mode": constants.INSTANCE_CREATE,
897
      "disk_template": constants.DT_PLAIN,
898
      }
899
    self.assertRaises(http.HttpBadRequest, self.Parse, data, False)
900

    
901
  def testErrors(self):
902
    # Test all required fields
903
    reqfields = {
904
      "name": "inst1.example.com",
905
      "disks": [],
906
      "nics": [],
907
      "mode": constants.INSTANCE_CREATE,
908
      "disk_template": constants.DT_PLAIN,
909
      }
910

    
911
    for name in reqfields.keys():
912
      self.assertRaises(http.HttpBadRequest, self.Parse,
913
                        dict(i for i in reqfields.iteritems() if i[0] != name),
914
                        False)
915

    
916
    # Invalid disks and nics
917
    for field in ["disks", "nics"]:
918
      invalid_values = [None, 1, "", {}, [1, 2, 3], ["hda1", "hda2"],
919
                        [{"_unknown_": 999, }]]
920

    
921
      for invvalue in invalid_values:
922
        data = reqfields.copy()
923
        data[field] = invvalue
924
        self.assertRaises(http.HttpBadRequest, self.Parse, data, False)
925

    
926

    
927
class TestBackupExport(unittest.TestCase):
928
  def test(self):
929
    clfactory = _FakeClientFactory(_FakeClient)
930

    
931
    name = "instmoo"
932
    data = {
933
      "mode": constants.EXPORT_MODE_REMOTE,
934
      "destination": [(1, 2, 3), (99, 99, 99)],
935
      "shutdown": True,
936
      "remove_instance": True,
937
      "x509_key_name": ["name", "hash"],
938
      "destination_x509_ca": "---cert---"
939
      }
940

    
941
    handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
942
                             data, clfactory)
943
    job_id = handler.PUT()
944

    
945
    cl = clfactory.GetNextClient()
946
    self.assertRaises(IndexError, clfactory.GetNextClient)
947

    
948
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
949
    self.assertEqual(job_id, exp_job_id)
950
    self.assertTrue(isinstance(op, opcodes.OpBackupExport))
951
    self.assertEqual(op.instance_name, name)
952
    self.assertEqual(op.mode, constants.EXPORT_MODE_REMOTE)
953
    self.assertEqual(op.target_node, [(1, 2, 3), (99, 99, 99)])
954
    self.assertEqual(op.shutdown, True)
955
    self.assertEqual(op.remove_instance, True)
956
    self.assertEqual(op.x509_key_name, ["name", "hash"])
957
    self.assertEqual(op.destination_x509_ca, "---cert---")
958
    self.assertFalse(hasattr(op, "dry_run"))
959
    self.assertFalse(hasattr(op, "force"))
960

    
961
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
962

    
963
  def testDefaults(self):
964
    clfactory = _FakeClientFactory(_FakeClient)
965

    
966
    name = "inst1"
967
    data = {
968
      "destination": "node2",
969
      "shutdown": False,
970
      }
971

    
972
    handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
973
                             data, clfactory)
974
    job_id = handler.PUT()
975

    
976
    cl = clfactory.GetNextClient()
977
    self.assertRaises(IndexError, clfactory.GetNextClient)
978

    
979
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
980
    self.assertEqual(job_id, exp_job_id)
981
    self.assertTrue(isinstance(op, opcodes.OpBackupExport))
982
    self.assertEqual(op.instance_name, name)
983
    self.assertEqual(op.target_node, "node2")
984
    self.assertFalse(hasattr(op, "mode"))
985
    self.assertFalse(hasattr(op, "remove_instance"))
986
    self.assertFalse(hasattr(op, "destination"))
987
    self.assertFalse(hasattr(op, "dry_run"))
988
    self.assertFalse(hasattr(op, "force"))
989

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

    
992
  def testErrors(self):
993
    clfactory = _FakeClientFactory(_FakeClient)
994

    
995
    for value in ["True", "False"]:
996
      handler = _CreateHandler(rlib2.R_2_instances_name_export, ["err1"], {}, {
997
        "remove_instance": value,
998
        }, clfactory)
999
      self.assertRaises(http.HttpBadRequest, handler.PUT)
1000

    
1001

    
1002
class TestInstanceMigrate(testutils.GanetiTestCase):
1003
  def test(self):
1004
    clfactory = _FakeClientFactory(_FakeClient)
1005

    
1006
    name = "instYooho6ek"
1007

    
1008
    for cleanup in [False, True]:
1009
      for mode in constants.HT_MIGRATION_MODES:
1010
        data = {
1011
          "cleanup": cleanup,
1012
          "mode": mode,
1013
          }
1014

    
1015
        handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {},
1016
                                 data, clfactory)
1017
        job_id = handler.PUT()
1018

    
1019
        cl = clfactory.GetNextClient()
1020
        self.assertRaises(IndexError, clfactory.GetNextClient)
1021

    
1022
        (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1023
        self.assertEqual(job_id, exp_job_id)
1024
        self.assertTrue(isinstance(op, opcodes.OpInstanceMigrate))
1025
        self.assertEqual(op.instance_name, name)
1026
        self.assertEqual(op.mode, mode)
1027
        self.assertEqual(op.cleanup, cleanup)
1028
        self.assertFalse(hasattr(op, "dry_run"))
1029
        self.assertFalse(hasattr(op, "force"))
1030

    
1031
        self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1032

    
1033
  def testDefaults(self):
1034
    clfactory = _FakeClientFactory(_FakeClient)
1035

    
1036
    name = "instnohZeex0"
1037

    
1038
    handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {}, {},
1039
                             clfactory)
1040
    job_id = handler.PUT()
1041

    
1042
    cl = clfactory.GetNextClient()
1043
    self.assertRaises(IndexError, clfactory.GetNextClient)
1044

    
1045
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1046
    self.assertEqual(job_id, exp_job_id)
1047
    self.assertTrue(isinstance(op, opcodes.OpInstanceMigrate))
1048
    self.assertEqual(op.instance_name, name)
1049
    self.assertFalse(hasattr(op, "mode"))
1050
    self.assertFalse(hasattr(op, "cleanup"))
1051
    self.assertFalse(hasattr(op, "dry_run"))
1052
    self.assertFalse(hasattr(op, "force"))
1053

    
1054
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1055

    
1056

    
1057
class TestParseRenameInstanceRequest(testutils.GanetiTestCase):
1058
  def test(self):
1059
    clfactory = _FakeClientFactory(_FakeClient)
1060

    
1061
    name = "instij0eeph7"
1062

    
1063
    for new_name in ["ua0aiyoo", "fai3ongi"]:
1064
      for ip_check in [False, True]:
1065
        for name_check in [False, True]:
1066
          data = {
1067
            "new_name": new_name,
1068
            "ip_check": ip_check,
1069
            "name_check": name_check,
1070
            }
1071

    
1072
          handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
1073
                                   {}, data, clfactory)
1074
          job_id = handler.PUT()
1075

    
1076
          cl = clfactory.GetNextClient()
1077
          self.assertRaises(IndexError, clfactory.GetNextClient)
1078

    
1079
          (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1080
          self.assertEqual(job_id, exp_job_id)
1081
          self.assertTrue(isinstance(op, opcodes.OpInstanceRename))
1082
          self.assertEqual(op.instance_name, name)
1083
          self.assertEqual(op.new_name, new_name)
1084
          self.assertEqual(op.ip_check, ip_check)
1085
          self.assertEqual(op.name_check, name_check)
1086
          self.assertFalse(hasattr(op, "dry_run"))
1087
          self.assertFalse(hasattr(op, "force"))
1088

    
1089
          self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1090

    
1091
  def testDefaults(self):
1092
    clfactory = _FakeClientFactory(_FakeClient)
1093

    
1094
    name = "instahchie3t"
1095

    
1096
    for new_name in ["thag9mek", "quees7oh"]:
1097
      data = {
1098
        "new_name": new_name,
1099
        }
1100

    
1101
      handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
1102
                               {}, data, clfactory)
1103
      job_id = handler.PUT()
1104

    
1105
      cl = clfactory.GetNextClient()
1106
      self.assertRaises(IndexError, clfactory.GetNextClient)
1107

    
1108
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1109
      self.assertEqual(job_id, exp_job_id)
1110
      self.assertTrue(isinstance(op, opcodes.OpInstanceRename))
1111
      self.assertEqual(op.instance_name, name)
1112
      self.assertEqual(op.new_name, new_name)
1113
      self.assertFalse(hasattr(op, "ip_check"))
1114
      self.assertFalse(hasattr(op, "name_check"))
1115
      self.assertFalse(hasattr(op, "dry_run"))
1116
      self.assertFalse(hasattr(op, "force"))
1117

    
1118
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1119

    
1120

    
1121
class TestParseModifyInstanceRequest(unittest.TestCase):
1122
  def test(self):
1123
    clfactory = _FakeClientFactory(_FakeClient)
1124

    
1125
    name = "instush8gah"
1126

    
1127
    test_disks = [
1128
      [],
1129
      [(1, { constants.IDISK_MODE: constants.DISK_RDWR, })],
1130
      ]
1131

    
1132
    for osparams in [{}, { "some": "value", "other": "Hello World", }]:
1133
      for hvparams in [{}, { constants.HV_KERNEL_PATH: "/some/kernel", }]:
1134
        for beparams in [{}, { constants.BE_MEMORY: 128, }]:
1135
          for force in [False, True]:
1136
            for nics in [[], [(0, { constants.INIC_IP: "192.0.2.1", })]]:
1137
              for disks in test_disks:
1138
                for disk_template in constants.DISK_TEMPLATES:
1139
                  data = {
1140
                    "osparams": osparams,
1141
                    "hvparams": hvparams,
1142
                    "beparams": beparams,
1143
                    "nics": nics,
1144
                    "disks": disks,
1145
                    "force": force,
1146
                    "disk_template": disk_template,
1147
                    }
1148

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

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

    
1156
                  (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1157
                  self.assertEqual(job_id, exp_job_id)
1158
                  self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
1159
                  self.assertEqual(op.instance_name, name)
1160
                  self.assertEqual(op.hvparams, hvparams)
1161
                  self.assertEqual(op.beparams, beparams)
1162
                  self.assertEqual(op.osparams, osparams)
1163
                  self.assertEqual(op.force, force)
1164
                  self.assertEqual(op.nics, nics)
1165
                  self.assertEqual(op.disks, disks)
1166
                  self.assertEqual(op.disk_template, disk_template)
1167
                  self.assertFalse(hasattr(op, "remote_node"))
1168
                  self.assertFalse(hasattr(op, "os_name"))
1169
                  self.assertFalse(hasattr(op, "force_variant"))
1170
                  self.assertFalse(hasattr(op, "dry_run"))
1171

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

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

    
1177
    name = "instir8aish31"
1178

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

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

    
1186
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1187
    self.assertEqual(job_id, exp_job_id)
1188
    self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
1189
    self.assertEqual(op.instance_name, name)
1190

    
1191
    for i in ["hvparams", "beparams", "osparams", "force", "nics", "disks",
1192
              "disk_template", "remote_node", "os_name", "force_variant"]:
1193
      self.assertFalse(hasattr(op, i))
1194

    
1195

    
1196
class TestParseInstanceReinstallRequest(testutils.GanetiTestCase):
1197
  def setUp(self):
1198
    testutils.GanetiTestCase.setUp(self)
1199

    
1200
    self.Parse = rlib2._ParseInstanceReinstallRequest
1201

    
1202
  def _Check(self, ops, name):
1203
    expcls = [
1204
      opcodes.OpInstanceShutdown,
1205
      opcodes.OpInstanceReinstall,
1206
      opcodes.OpInstanceStartup,
1207
      ]
1208

    
1209
    self.assert_(compat.all(isinstance(op, exp)
1210
                            for op, exp in zip(ops, expcls)))
1211
    self.assert_(compat.all(op.instance_name == name for op in ops))
1212

    
1213
  def test(self):
1214
    name = "shoo0tihohma"
1215

    
1216
    ops = self.Parse(name, {"os": "sys1", "start": True,})
1217
    self.assertEqual(len(ops), 3)
1218
    self._Check(ops, name)
1219
    self.assertEqual(ops[1].os_type, "sys1")
1220
    self.assertFalse(ops[1].osparams)
1221

    
1222
    ops = self.Parse(name, {"os": "sys2", "start": False,})
1223
    self.assertEqual(len(ops), 2)
1224
    self._Check(ops, name)
1225
    self.assertEqual(ops[1].os_type, "sys2")
1226

    
1227
    osparams = {
1228
      "reformat": "1",
1229
      }
1230
    ops = self.Parse(name, {"os": "sys4035", "start": True,
1231
                            "osparams": osparams,})
1232
    self.assertEqual(len(ops), 3)
1233
    self._Check(ops, name)
1234
    self.assertEqual(ops[1].os_type, "sys4035")
1235
    self.assertEqual(ops[1].osparams, osparams)
1236

    
1237
  def testDefaults(self):
1238
    name = "noolee0g"
1239

    
1240
    ops = self.Parse(name, {"os": "linux1"})
1241
    self.assertEqual(len(ops), 3)
1242
    self._Check(ops, name)
1243
    self.assertEqual(ops[1].os_type, "linux1")
1244
    self.assertFalse(ops[1].osparams)
1245

    
1246

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

    
1251
    name = "group608242564"
1252
    data = {
1253
      "new_name": "ua0aiyoo15112",
1254
      }
1255

    
1256
    handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {}, data,
1257
                             clfactory)
1258
    job_id = handler.PUT()
1259

    
1260
    cl = clfactory.GetNextClient()
1261
    self.assertRaises(IndexError, clfactory.GetNextClient)
1262

    
1263
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1264
    self.assertEqual(job_id, exp_job_id)
1265

    
1266
    self.assertTrue(isinstance(op, opcodes.OpGroupRename))
1267
    self.assertEqual(op.group_name, name)
1268
    self.assertEqual(op.new_name, "ua0aiyoo15112")
1269
    self.assertFalse(op.dry_run)
1270
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1271

    
1272
  def testDryRun(self):
1273
    clfactory = _FakeClientFactory(_FakeClient)
1274

    
1275
    name = "group28548"
1276
    data = {
1277
      "new_name": "ua0aiyoo",
1278
      }
1279

    
1280
    handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {
1281
      "dry-run": ["1"],
1282
      }, data, clfactory)
1283
    job_id = handler.PUT()
1284

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

    
1288
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1289
    self.assertEqual(job_id, exp_job_id)
1290

    
1291
    self.assertTrue(isinstance(op, opcodes.OpGroupRename))
1292
    self.assertEqual(op.group_name, name)
1293
    self.assertEqual(op.new_name, "ua0aiyoo")
1294
    self.assertTrue(op.dry_run)
1295
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1296

    
1297

    
1298
class TestInstanceReplaceDisks(unittest.TestCase):
1299
  def test(self):
1300
    clfactory = _FakeClientFactory(_FakeClient)
1301

    
1302
    name = "inst22568"
1303

    
1304
    for disks in [range(1, 4), "1,2,3", "1, 2, 3"]:
1305
      data = {
1306
        "mode": constants.REPLACE_DISK_SEC,
1307
        "disks": disks,
1308
        "iallocator": "myalloc",
1309
        }
1310

    
1311
      handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1312
                               [name], {}, data, clfactory)
1313
      job_id = handler.POST()
1314

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

    
1318
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1319
      self.assertEqual(job_id, exp_job_id)
1320

    
1321
      self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
1322
      self.assertEqual(op.instance_name, name)
1323
      self.assertEqual(op.mode, constants.REPLACE_DISK_SEC)
1324
      self.assertEqual(op.disks, [1, 2, 3])
1325
      self.assertEqual(op.iallocator, "myalloc")
1326
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1327

    
1328
  def testDefaults(self):
1329
    clfactory = _FakeClientFactory(_FakeClient)
1330

    
1331
    name = "inst11413"
1332
    data = {
1333
      "mode": constants.REPLACE_DISK_AUTO,
1334
      }
1335

    
1336
    handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1337
                             [name], {}, data, clfactory)
1338
    job_id = handler.POST()
1339

    
1340
    cl = clfactory.GetNextClient()
1341
    self.assertRaises(IndexError, clfactory.GetNextClient)
1342

    
1343
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1344
    self.assertEqual(job_id, exp_job_id)
1345

    
1346
    self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
1347
    self.assertEqual(op.instance_name, name)
1348
    self.assertEqual(op.mode, constants.REPLACE_DISK_AUTO)
1349
    self.assertFalse(hasattr(op, "iallocator"))
1350
    self.assertFalse(hasattr(op, "disks"))
1351
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1352

    
1353
  def testWrong(self):
1354
    clfactory = _FakeClientFactory(_FakeClient)
1355

    
1356
    data = {
1357
      "mode": constants.REPLACE_DISK_AUTO,
1358
      "disks": "hello world",
1359
      }
1360

    
1361
    handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1362
                             ["foo"], {}, data, clfactory)
1363
    self.assertRaises(http.HttpBadRequest, handler.POST)
1364

    
1365

    
1366
class TestGroupModify(unittest.TestCase):
1367
  def test(self):
1368
    clfactory = _FakeClientFactory(_FakeClient)
1369

    
1370
    name = "group6002"
1371

    
1372
    for policy in constants.VALID_ALLOC_POLICIES:
1373
      data = {
1374
        "alloc_policy": policy,
1375
        }
1376

    
1377
      handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, data,
1378
                               clfactory)
1379
      job_id = handler.PUT()
1380

    
1381
      cl = clfactory.GetNextClient()
1382
      self.assertRaises(IndexError, clfactory.GetNextClient)
1383

    
1384
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1385
      self.assertEqual(job_id, exp_job_id)
1386

    
1387
      self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
1388
      self.assertEqual(op.group_name, name)
1389
      self.assertEqual(op.alloc_policy, policy)
1390
      self.assertFalse(hasattr(op, "dry_run"))
1391
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1392

    
1393
  def testUnknownPolicy(self):
1394
    clfactory = _FakeClientFactory(_FakeClient)
1395

    
1396
    data = {
1397
      "alloc_policy": "_unknown_policy_",
1398
      }
1399

    
1400
    handler = _CreateHandler(rlib2.R_2_groups_name_modify, ["xyz"], {}, data,
1401
                             clfactory)
1402
    self.assertRaises(http.HttpBadRequest, handler.PUT)
1403
    self.assertRaises(IndexError, clfactory.GetNextClient)
1404

    
1405
  def testDefaults(self):
1406
    clfactory = _FakeClientFactory(_FakeClient)
1407

    
1408
    name = "group6679"
1409

    
1410
    handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, {},
1411
                             clfactory)
1412
    job_id = handler.PUT()
1413

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

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

    
1420
    self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
1421
    self.assertEqual(op.group_name, name)
1422
    self.assertFalse(hasattr(op, "alloc_policy"))
1423
    self.assertFalse(hasattr(op, "dry_run"))
1424
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1425

    
1426

    
1427
class TestGroupAdd(unittest.TestCase):
1428
  def test(self):
1429
    name = "group3618"
1430
    clfactory = _FakeClientFactory(_FakeClient)
1431

    
1432
    for policy in constants.VALID_ALLOC_POLICIES:
1433
      data = {
1434
        "group_name": name,
1435
        "alloc_policy": policy,
1436
        }
1437

    
1438
      handler = _CreateHandler(rlib2.R_2_groups, [], {}, data,
1439
                               clfactory)
1440
      job_id = handler.POST()
1441

    
1442
      cl = clfactory.GetNextClient()
1443
      self.assertRaises(IndexError, clfactory.GetNextClient)
1444

    
1445
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1446
      self.assertEqual(job_id, exp_job_id)
1447

    
1448
      self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1449
      self.assertEqual(op.group_name, name)
1450
      self.assertEqual(op.alloc_policy, policy)
1451
      self.assertFalse(op.dry_run)
1452
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1453

    
1454
  def testUnknownPolicy(self):
1455
    clfactory = _FakeClientFactory(_FakeClient)
1456

    
1457
    data = {
1458
      "alloc_policy": "_unknown_policy_",
1459
      }
1460

    
1461
    handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1462
    self.assertRaises(http.HttpBadRequest, handler.POST)
1463
    self.assertRaises(IndexError, clfactory.GetNextClient)
1464

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

    
1468
    name = "group15395"
1469
    data = {
1470
      "group_name": name,
1471
      }
1472

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

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

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

    
1482
    self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1483
    self.assertEqual(op.group_name, name)
1484
    self.assertFalse(hasattr(op, "alloc_policy"))
1485
    self.assertFalse(op.dry_run)
1486

    
1487
  def testLegacyName(self):
1488
    clfactory = _FakeClientFactory(_FakeClient)
1489

    
1490
    name = "group29852"
1491
    data = {
1492
      "name": name,
1493
      }
1494

    
1495
    handler = _CreateHandler(rlib2.R_2_groups, [], {
1496
      "dry-run": ["1"],
1497
      }, data, clfactory)
1498
    job_id = handler.POST()
1499

    
1500
    cl = clfactory.GetNextClient()
1501
    self.assertRaises(IndexError, clfactory.GetNextClient)
1502

    
1503
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1504
    self.assertEqual(job_id, exp_job_id)
1505

    
1506
    self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1507
    self.assertEqual(op.group_name, name)
1508
    self.assertFalse(hasattr(op, "alloc_policy"))
1509
    self.assertTrue(op.dry_run)
1510

    
1511

    
1512
class TestNodeRole(unittest.TestCase):
1513
  def test(self):
1514
    clfactory = _FakeClientFactory(_FakeClient)
1515

    
1516
    for role in rlib2._NR_MAP.values():
1517
      handler = _CreateHandler(rlib2.R_2_nodes_name_role,
1518
                               ["node-z"], {}, role, clfactory)
1519
      if role == rlib2._NR_MASTER:
1520
        self.assertRaises(http.HttpBadRequest, handler.PUT)
1521
      else:
1522
        job_id = handler.PUT()
1523

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

    
1527
        (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1528
        self.assertEqual(job_id, exp_job_id)
1529
        self.assertTrue(isinstance(op, opcodes.OpNodeSetParams))
1530
        self.assertEqual(op.node_name, "node-z")
1531
        self.assertFalse(op.force)
1532
        self.assertFalse(hasattr(op, "dry_run"))
1533

    
1534
        if role == rlib2._NR_REGULAR:
1535
          self.assertFalse(op.drained)
1536
          self.assertFalse(op.offline)
1537
          self.assertFalse(op.master_candidate)
1538
        elif role == rlib2._NR_MASTER_CANDIDATE:
1539
          self.assertFalse(op.drained)
1540
          self.assertFalse(op.offline)
1541
          self.assertTrue(op.master_candidate)
1542
        elif role == rlib2._NR_DRAINED:
1543
          self.assertTrue(op.drained)
1544
          self.assertFalse(op.offline)
1545
          self.assertFalse(op.master_candidate)
1546
        elif role == rlib2._NR_OFFLINE:
1547
          self.assertFalse(op.drained)
1548
          self.assertTrue(op.offline)
1549
          self.assertFalse(op.master_candidate)
1550
        else:
1551
          self.fail("Unknown role '%s'" % role)
1552

    
1553
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1554

    
1555

    
1556
if __name__ == '__main__':
1557
  testutils.GanetiTestProgram()