Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.rapi.rlib2_unittest.py @ 86f1f5d4

History | View | Annotate | Download (42.7 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 TestParseInstanceCreateRequestVersion1(testutils.GanetiTestCase):
539
  def setUp(self):
540
    testutils.GanetiTestCase.setUp(self)
541

    
542
    self.Parse = rlib2._ParseInstanceCreateRequestVersion1
543

    
544
  def test(self):
545
    disk_variants = [
546
      # No disks
547
      [],
548

    
549
      # Two disks
550
      [{"size": 5, }, {"size": 100, }],
551

    
552
      # Disk with mode
553
      [{"size": 123, "mode": constants.DISK_RDWR, }],
554
      ]
555

    
556
    nic_variants = [
557
      # No NIC
558
      [],
559

    
560
      # Three NICs
561
      [{}, {}, {}],
562

    
563
      # Two NICs
564
      [
565
        { "ip": "192.0.2.6", "mode": constants.NIC_MODE_ROUTED,
566
          "mac": "01:23:45:67:68:9A",
567
        },
568
        { "mode": constants.NIC_MODE_BRIDGED, "link": "br1" },
569
      ],
570
      ]
571

    
572
    beparam_variants = [
573
      None,
574
      {},
575
      { constants.BE_VCPUS: 2, },
576
      { constants.BE_MEMORY: 123, },
577
      { constants.BE_VCPUS: 2,
578
        constants.BE_MEMORY: 1024,
579
        constants.BE_AUTO_BALANCE: True, }
580
      ]
581

    
582
    hvparam_variants = [
583
      None,
584
      { constants.HV_BOOT_ORDER: "anc", },
585
      { constants.HV_KERNEL_PATH: "/boot/fookernel",
586
        constants.HV_ROOT_PATH: "/dev/hda1", },
587
      ]
588

    
589
    for mode in [constants.INSTANCE_CREATE, constants.INSTANCE_IMPORT]:
590
      for nics in nic_variants:
591
        for disk_template in constants.DISK_TEMPLATES:
592
          for disks in disk_variants:
593
            for beparams in beparam_variants:
594
              for hvparams in hvparam_variants:
595
                data = {
596
                  "name": "inst1.example.com",
597
                  "hypervisor": constants.HT_FAKE,
598
                  "disks": disks,
599
                  "nics": nics,
600
                  "mode": mode,
601
                  "disk_template": disk_template,
602
                  "os": "debootstrap",
603
                  }
604

    
605
                if beparams is not None:
606
                  data["beparams"] = beparams
607

    
608
                if hvparams is not None:
609
                  data["hvparams"] = hvparams
610

    
611
                for dry_run in [False, True]:
612
                  op = self.Parse(data, dry_run)
613
                  self.assert_(isinstance(op, opcodes.OpInstanceCreate))
614
                  self.assertEqual(op.mode, mode)
615
                  self.assertEqual(op.disk_template, disk_template)
616
                  self.assertEqual(op.dry_run, dry_run)
617
                  self.assertEqual(len(op.disks), len(disks))
618
                  self.assertEqual(len(op.nics), len(nics))
619

    
620
                  for opdisk, disk in zip(op.disks, disks):
621
                    for key in constants.IDISK_PARAMS:
622
                      self.assertEqual(opdisk.get(key), disk.get(key))
623
                    self.assertFalse("unknown" in opdisk)
624

    
625
                  for opnic, nic in zip(op.nics, nics):
626
                    for key in constants.INIC_PARAMS:
627
                      self.assertEqual(opnic.get(key), nic.get(key))
628
                    self.assertFalse("unknown" in opnic)
629
                    self.assertFalse("foobar" in opnic)
630

    
631
                  if beparams is None:
632
                    self.assertFalse(hasattr(op, "beparams"))
633
                  else:
634
                    self.assertEqualValues(op.beparams, beparams)
635

    
636
                  if hvparams is None:
637
                    self.assertFalse(hasattr(op, "hvparams"))
638
                  else:
639
                    self.assertEqualValues(op.hvparams, hvparams)
640

    
641
  def testLegacyName(self):
642
    name = "inst29128.example.com"
643
    data = {
644
      "name": name,
645
      "disks": [],
646
      "nics": [],
647
      "mode": constants.INSTANCE_CREATE,
648
      "disk_template": constants.DT_PLAIN,
649
      }
650
    op = self.Parse(data, False)
651
    self.assert_(isinstance(op, opcodes.OpInstanceCreate))
652
    self.assertEqual(op.instance_name, name)
653
    self.assertFalse(hasattr(op, "name"))
654

    
655
    # Define both
656
    data = {
657
      "name": name,
658
      "instance_name": "other.example.com",
659
      "disks": [],
660
      "nics": [],
661
      "mode": constants.INSTANCE_CREATE,
662
      "disk_template": constants.DT_PLAIN,
663
      }
664
    self.assertRaises(http.HttpBadRequest, self.Parse, data, False)
665

    
666
  def testLegacyOs(self):
667
    name = "inst4673.example.com"
668
    os = "linux29206"
669
    data = {
670
      "name": name,
671
      "os_type": os,
672
      "disks": [],
673
      "nics": [],
674
      "mode": constants.INSTANCE_CREATE,
675
      "disk_template": constants.DT_PLAIN,
676
      }
677
    op = self.Parse(data, False)
678
    self.assert_(isinstance(op, opcodes.OpInstanceCreate))
679
    self.assertEqual(op.instance_name, name)
680
    self.assertEqual(op.os_type, os)
681
    self.assertFalse(hasattr(op, "os"))
682

    
683
    # Define both
684
    data = {
685
      "instance_name": name,
686
      "os": os,
687
      "os_type": "linux9584",
688
      "disks": [],
689
      "nics": [],
690
      "mode": constants.INSTANCE_CREATE,
691
      "disk_template": constants.DT_PLAIN,
692
      }
693
    self.assertRaises(http.HttpBadRequest, self.Parse, data, False)
694

    
695
  def testErrors(self):
696
    # Test all required fields
697
    reqfields = {
698
      "name": "inst1.example.com",
699
      "disks": [],
700
      "nics": [],
701
      "mode": constants.INSTANCE_CREATE,
702
      "disk_template": constants.DT_PLAIN,
703
      }
704

    
705
    for name in reqfields.keys():
706
      self.assertRaises(http.HttpBadRequest, self.Parse,
707
                        dict(i for i in reqfields.iteritems() if i[0] != name),
708
                        False)
709

    
710
    # Invalid disks and nics
711
    for field in ["disks", "nics"]:
712
      invalid_values = [None, 1, "", {}, [1, 2, 3], ["hda1", "hda2"],
713
                        [{"_unknown_": 999, }]]
714

    
715
      for invvalue in invalid_values:
716
        data = reqfields.copy()
717
        data[field] = invvalue
718
        self.assertRaises(http.HttpBadRequest, self.Parse, data, False)
719

    
720

    
721
class TestBackupExport(unittest.TestCase):
722
  def test(self):
723
    clfactory = _FakeClientFactory(_FakeClient)
724

    
725
    name = "instmoo"
726
    data = {
727
      "mode": constants.EXPORT_MODE_REMOTE,
728
      "destination": [(1, 2, 3), (99, 99, 99)],
729
      "shutdown": True,
730
      "remove_instance": True,
731
      "x509_key_name": ["name", "hash"],
732
      "destination_x509_ca": "---cert---"
733
      }
734

    
735
    handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
736
                             data, clfactory)
737
    job_id = handler.PUT()
738

    
739
    cl = clfactory.GetNextClient()
740
    self.assertRaises(IndexError, clfactory.GetNextClient)
741

    
742
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
743
    self.assertEqual(job_id, exp_job_id)
744
    self.assertTrue(isinstance(op, opcodes.OpBackupExport))
745
    self.assertEqual(op.instance_name, name)
746
    self.assertEqual(op.mode, constants.EXPORT_MODE_REMOTE)
747
    self.assertEqual(op.target_node, [(1, 2, 3), (99, 99, 99)])
748
    self.assertEqual(op.shutdown, True)
749
    self.assertEqual(op.remove_instance, True)
750
    self.assertEqual(op.x509_key_name, ["name", "hash"])
751
    self.assertEqual(op.destination_x509_ca, "---cert---")
752
    self.assertFalse(hasattr(op, "dry_run"))
753
    self.assertFalse(hasattr(op, "force"))
754

    
755
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
756

    
757
  def testDefaults(self):
758
    clfactory = _FakeClientFactory(_FakeClient)
759

    
760
    name = "inst1"
761
    data = {
762
      "destination": "node2",
763
      "shutdown": False,
764
      }
765

    
766
    handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
767
                             data, clfactory)
768
    job_id = handler.PUT()
769

    
770
    cl = clfactory.GetNextClient()
771
    self.assertRaises(IndexError, clfactory.GetNextClient)
772

    
773
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
774
    self.assertEqual(job_id, exp_job_id)
775
    self.assertTrue(isinstance(op, opcodes.OpBackupExport))
776
    self.assertEqual(op.instance_name, name)
777
    self.assertEqual(op.target_node, "node2")
778
    self.assertFalse(hasattr(op, "mode"))
779
    self.assertFalse(hasattr(op, "remove_instance"))
780
    self.assertFalse(hasattr(op, "destination"))
781
    self.assertFalse(hasattr(op, "dry_run"))
782
    self.assertFalse(hasattr(op, "force"))
783

    
784
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
785

    
786
  def testErrors(self):
787
    clfactory = _FakeClientFactory(_FakeClient)
788

    
789
    for value in ["True", "False"]:
790
      handler = _CreateHandler(rlib2.R_2_instances_name_export, ["err1"], {}, {
791
        "remove_instance": value,
792
        }, clfactory)
793
      self.assertRaises(http.HttpBadRequest, handler.PUT)
794

    
795

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

    
800
    name = "instYooho6ek"
801

    
802
    for cleanup in [False, True]:
803
      for mode in constants.HT_MIGRATION_MODES:
804
        data = {
805
          "cleanup": cleanup,
806
          "mode": mode,
807
          }
808

    
809
        handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {},
810
                                 data, clfactory)
811
        job_id = handler.PUT()
812

    
813
        cl = clfactory.GetNextClient()
814
        self.assertRaises(IndexError, clfactory.GetNextClient)
815

    
816
        (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
817
        self.assertEqual(job_id, exp_job_id)
818
        self.assertTrue(isinstance(op, opcodes.OpInstanceMigrate))
819
        self.assertEqual(op.instance_name, name)
820
        self.assertEqual(op.mode, mode)
821
        self.assertEqual(op.cleanup, cleanup)
822
        self.assertFalse(hasattr(op, "dry_run"))
823
        self.assertFalse(hasattr(op, "force"))
824

    
825
        self.assertRaises(IndexError, cl.GetNextSubmittedJob)
826

    
827
  def testDefaults(self):
828
    clfactory = _FakeClientFactory(_FakeClient)
829

    
830
    name = "instnohZeex0"
831

    
832
    handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {}, {},
833
                             clfactory)
834
    job_id = handler.PUT()
835

    
836
    cl = clfactory.GetNextClient()
837
    self.assertRaises(IndexError, clfactory.GetNextClient)
838

    
839
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
840
    self.assertEqual(job_id, exp_job_id)
841
    self.assertTrue(isinstance(op, opcodes.OpInstanceMigrate))
842
    self.assertEqual(op.instance_name, name)
843
    self.assertFalse(hasattr(op, "mode"))
844
    self.assertFalse(hasattr(op, "cleanup"))
845
    self.assertFalse(hasattr(op, "dry_run"))
846
    self.assertFalse(hasattr(op, "force"))
847

    
848
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
849

    
850

    
851
class TestParseRenameInstanceRequest(testutils.GanetiTestCase):
852
  def test(self):
853
    clfactory = _FakeClientFactory(_FakeClient)
854

    
855
    name = "instij0eeph7"
856

    
857
    for new_name in ["ua0aiyoo", "fai3ongi"]:
858
      for ip_check in [False, True]:
859
        for name_check in [False, True]:
860
          data = {
861
            "new_name": new_name,
862
            "ip_check": ip_check,
863
            "name_check": name_check,
864
            }
865

    
866
          handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
867
                                   {}, data, clfactory)
868
          job_id = handler.PUT()
869

    
870
          cl = clfactory.GetNextClient()
871
          self.assertRaises(IndexError, clfactory.GetNextClient)
872

    
873
          (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
874
          self.assertEqual(job_id, exp_job_id)
875
          self.assertTrue(isinstance(op, opcodes.OpInstanceRename))
876
          self.assertEqual(op.instance_name, name)
877
          self.assertEqual(op.new_name, new_name)
878
          self.assertEqual(op.ip_check, ip_check)
879
          self.assertEqual(op.name_check, name_check)
880
          self.assertFalse(hasattr(op, "dry_run"))
881
          self.assertFalse(hasattr(op, "force"))
882

    
883
          self.assertRaises(IndexError, cl.GetNextSubmittedJob)
884

    
885
  def testDefaults(self):
886
    clfactory = _FakeClientFactory(_FakeClient)
887

    
888
    name = "instahchie3t"
889

    
890
    for new_name in ["thag9mek", "quees7oh"]:
891
      data = {
892
        "new_name": new_name,
893
        }
894

    
895
      handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
896
                               {}, data, clfactory)
897
      job_id = handler.PUT()
898

    
899
      cl = clfactory.GetNextClient()
900
      self.assertRaises(IndexError, clfactory.GetNextClient)
901

    
902
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
903
      self.assertEqual(job_id, exp_job_id)
904
      self.assertTrue(isinstance(op, opcodes.OpInstanceRename))
905
      self.assertEqual(op.instance_name, name)
906
      self.assertEqual(op.new_name, new_name)
907
      self.assertFalse(hasattr(op, "ip_check"))
908
      self.assertFalse(hasattr(op, "name_check"))
909
      self.assertFalse(hasattr(op, "dry_run"))
910
      self.assertFalse(hasattr(op, "force"))
911

    
912
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
913

    
914

    
915
class TestParseModifyInstanceRequest(unittest.TestCase):
916
  def test(self):
917
    clfactory = _FakeClientFactory(_FakeClient)
918

    
919
    name = "instush8gah"
920

    
921
    test_disks = [
922
      [],
923
      [(1, { constants.IDISK_MODE: constants.DISK_RDWR, })],
924
      ]
925

    
926
    for osparams in [{}, { "some": "value", "other": "Hello World", }]:
927
      for hvparams in [{}, { constants.HV_KERNEL_PATH: "/some/kernel", }]:
928
        for beparams in [{}, { constants.BE_MEMORY: 128, }]:
929
          for force in [False, True]:
930
            for nics in [[], [(0, { constants.INIC_IP: "192.0.2.1", })]]:
931
              for disks in test_disks:
932
                for disk_template in constants.DISK_TEMPLATES:
933
                  data = {
934
                    "osparams": osparams,
935
                    "hvparams": hvparams,
936
                    "beparams": beparams,
937
                    "nics": nics,
938
                    "disks": disks,
939
                    "force": force,
940
                    "disk_template": disk_template,
941
                    }
942

    
943
                  handler = _CreateHandler(rlib2.R_2_instances_name_modify,
944
                                           [name], {}, data, clfactory)
945
                  job_id = handler.PUT()
946

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

    
950
                  (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
951
                  self.assertEqual(job_id, exp_job_id)
952
                  self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
953
                  self.assertEqual(op.instance_name, name)
954
                  self.assertEqual(op.hvparams, hvparams)
955
                  self.assertEqual(op.beparams, beparams)
956
                  self.assertEqual(op.osparams, osparams)
957
                  self.assertEqual(op.force, force)
958
                  self.assertEqual(op.nics, nics)
959
                  self.assertEqual(op.disks, disks)
960
                  self.assertEqual(op.disk_template, disk_template)
961
                  self.assertFalse(hasattr(op, "remote_node"))
962
                  self.assertFalse(hasattr(op, "os_name"))
963
                  self.assertFalse(hasattr(op, "force_variant"))
964
                  self.assertFalse(hasattr(op, "dry_run"))
965

    
966
                  self.assertRaises(IndexError, cl.GetNextSubmittedJob)
967

    
968
  def testDefaults(self):
969
    clfactory = _FakeClientFactory(_FakeClient)
970

    
971
    name = "instir8aish31"
972

    
973
    handler = _CreateHandler(rlib2.R_2_instances_name_modify,
974
                             [name], {}, {}, clfactory)
975
    job_id = handler.PUT()
976

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

    
980
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
981
    self.assertEqual(job_id, exp_job_id)
982
    self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
983
    self.assertEqual(op.instance_name, name)
984

    
985
    for i in ["hvparams", "beparams", "osparams", "force", "nics", "disks",
986
              "disk_template", "remote_node", "os_name", "force_variant"]:
987
      self.assertFalse(hasattr(op, i))
988

    
989

    
990
class TestParseInstanceReinstallRequest(testutils.GanetiTestCase):
991
  def setUp(self):
992
    testutils.GanetiTestCase.setUp(self)
993

    
994
    self.Parse = rlib2._ParseInstanceReinstallRequest
995

    
996
  def _Check(self, ops, name):
997
    expcls = [
998
      opcodes.OpInstanceShutdown,
999
      opcodes.OpInstanceReinstall,
1000
      opcodes.OpInstanceStartup,
1001
      ]
1002

    
1003
    self.assert_(compat.all(isinstance(op, exp)
1004
                            for op, exp in zip(ops, expcls)))
1005
    self.assert_(compat.all(op.instance_name == name for op in ops))
1006

    
1007
  def test(self):
1008
    name = "shoo0tihohma"
1009

    
1010
    ops = self.Parse(name, {"os": "sys1", "start": True,})
1011
    self.assertEqual(len(ops), 3)
1012
    self._Check(ops, name)
1013
    self.assertEqual(ops[1].os_type, "sys1")
1014
    self.assertFalse(ops[1].osparams)
1015

    
1016
    ops = self.Parse(name, {"os": "sys2", "start": False,})
1017
    self.assertEqual(len(ops), 2)
1018
    self._Check(ops, name)
1019
    self.assertEqual(ops[1].os_type, "sys2")
1020

    
1021
    osparams = {
1022
      "reformat": "1",
1023
      }
1024
    ops = self.Parse(name, {"os": "sys4035", "start": True,
1025
                            "osparams": osparams,})
1026
    self.assertEqual(len(ops), 3)
1027
    self._Check(ops, name)
1028
    self.assertEqual(ops[1].os_type, "sys4035")
1029
    self.assertEqual(ops[1].osparams, osparams)
1030

    
1031
  def testDefaults(self):
1032
    name = "noolee0g"
1033

    
1034
    ops = self.Parse(name, {"os": "linux1"})
1035
    self.assertEqual(len(ops), 3)
1036
    self._Check(ops, name)
1037
    self.assertEqual(ops[1].os_type, "linux1")
1038
    self.assertFalse(ops[1].osparams)
1039

    
1040

    
1041
class TestGroupRename(unittest.TestCase):
1042
  def test(self):
1043
    clfactory = _FakeClientFactory(_FakeClient)
1044

    
1045
    name = "group608242564"
1046
    data = {
1047
      "new_name": "ua0aiyoo15112",
1048
      }
1049

    
1050
    handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {}, data,
1051
                             clfactory)
1052
    job_id = handler.PUT()
1053

    
1054
    cl = clfactory.GetNextClient()
1055
    self.assertRaises(IndexError, clfactory.GetNextClient)
1056

    
1057
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1058
    self.assertEqual(job_id, exp_job_id)
1059

    
1060
    self.assertTrue(isinstance(op, opcodes.OpGroupRename))
1061
    self.assertEqual(op.group_name, name)
1062
    self.assertEqual(op.new_name, "ua0aiyoo15112")
1063
    self.assertFalse(op.dry_run)
1064
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1065

    
1066
  def testDryRun(self):
1067
    clfactory = _FakeClientFactory(_FakeClient)
1068

    
1069
    name = "group28548"
1070
    data = {
1071
      "new_name": "ua0aiyoo",
1072
      }
1073

    
1074
    handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {
1075
      "dry-run": ["1"],
1076
      }, data, clfactory)
1077
    job_id = handler.PUT()
1078

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

    
1082
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1083
    self.assertEqual(job_id, exp_job_id)
1084

    
1085
    self.assertTrue(isinstance(op, opcodes.OpGroupRename))
1086
    self.assertEqual(op.group_name, name)
1087
    self.assertEqual(op.new_name, "ua0aiyoo")
1088
    self.assertTrue(op.dry_run)
1089
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1090

    
1091

    
1092
class TestInstanceReplaceDisks(unittest.TestCase):
1093
  def test(self):
1094
    clfactory = _FakeClientFactory(_FakeClient)
1095

    
1096
    name = "inst22568"
1097

    
1098
    for disks in [range(1, 4), "1,2,3", "1, 2, 3"]:
1099
      data = {
1100
        "mode": constants.REPLACE_DISK_SEC,
1101
        "disks": disks,
1102
        "iallocator": "myalloc",
1103
        }
1104

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

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

    
1112
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1113
      self.assertEqual(job_id, exp_job_id)
1114

    
1115
      self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
1116
      self.assertEqual(op.instance_name, name)
1117
      self.assertEqual(op.mode, constants.REPLACE_DISK_SEC)
1118
      self.assertEqual(op.disks, [1, 2, 3])
1119
      self.assertEqual(op.iallocator, "myalloc")
1120
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1121

    
1122
  def testDefaults(self):
1123
    clfactory = _FakeClientFactory(_FakeClient)
1124

    
1125
    name = "inst11413"
1126
    data = {
1127
      "mode": constants.REPLACE_DISK_AUTO,
1128
      }
1129

    
1130
    handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1131
                             [name], {}, data, clfactory)
1132
    job_id = handler.POST()
1133

    
1134
    cl = clfactory.GetNextClient()
1135
    self.assertRaises(IndexError, clfactory.GetNextClient)
1136

    
1137
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1138
    self.assertEqual(job_id, exp_job_id)
1139

    
1140
    self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
1141
    self.assertEqual(op.instance_name, name)
1142
    self.assertEqual(op.mode, constants.REPLACE_DISK_AUTO)
1143
    self.assertFalse(hasattr(op, "iallocator"))
1144
    self.assertFalse(hasattr(op, "disks"))
1145
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1146

    
1147
  def testWrong(self):
1148
    clfactory = _FakeClientFactory(_FakeClient)
1149

    
1150
    data = {
1151
      "mode": constants.REPLACE_DISK_AUTO,
1152
      "disks": "hello world",
1153
      }
1154

    
1155
    handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1156
                             ["foo"], {}, data, clfactory)
1157
    self.assertRaises(http.HttpBadRequest, handler.POST)
1158

    
1159

    
1160
class TestGroupModify(unittest.TestCase):
1161
  def test(self):
1162
    clfactory = _FakeClientFactory(_FakeClient)
1163

    
1164
    name = "group6002"
1165

    
1166
    for policy in constants.VALID_ALLOC_POLICIES:
1167
      data = {
1168
        "alloc_policy": policy,
1169
        }
1170

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

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

    
1178
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1179
      self.assertEqual(job_id, exp_job_id)
1180

    
1181
      self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
1182
      self.assertEqual(op.group_name, name)
1183
      self.assertEqual(op.alloc_policy, policy)
1184
      self.assertFalse(hasattr(op, "dry_run"))
1185
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1186

    
1187
  def testUnknownPolicy(self):
1188
    clfactory = _FakeClientFactory(_FakeClient)
1189

    
1190
    data = {
1191
      "alloc_policy": "_unknown_policy_",
1192
      }
1193

    
1194
    handler = _CreateHandler(rlib2.R_2_groups_name_modify, ["xyz"], {}, data,
1195
                             clfactory)
1196
    self.assertRaises(http.HttpBadRequest, handler.PUT)
1197
    self.assertRaises(IndexError, clfactory.GetNextClient)
1198

    
1199
  def testDefaults(self):
1200
    clfactory = _FakeClientFactory(_FakeClient)
1201

    
1202
    name = "group6679"
1203

    
1204
    handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, {},
1205
                             clfactory)
1206
    job_id = handler.PUT()
1207

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

    
1211
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1212
    self.assertEqual(job_id, exp_job_id)
1213

    
1214
    self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
1215
    self.assertEqual(op.group_name, name)
1216
    self.assertFalse(hasattr(op, "alloc_policy"))
1217
    self.assertFalse(hasattr(op, "dry_run"))
1218
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1219

    
1220

    
1221
class TestGroupAdd(unittest.TestCase):
1222
  def test(self):
1223
    name = "group3618"
1224
    clfactory = _FakeClientFactory(_FakeClient)
1225

    
1226
    for policy in constants.VALID_ALLOC_POLICIES:
1227
      data = {
1228
        "group_name": name,
1229
        "alloc_policy": policy,
1230
        }
1231

    
1232
      handler = _CreateHandler(rlib2.R_2_groups, [], {}, data,
1233
                               clfactory)
1234
      job_id = handler.POST()
1235

    
1236
      cl = clfactory.GetNextClient()
1237
      self.assertRaises(IndexError, clfactory.GetNextClient)
1238

    
1239
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1240
      self.assertEqual(job_id, exp_job_id)
1241

    
1242
      self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1243
      self.assertEqual(op.group_name, name)
1244
      self.assertEqual(op.alloc_policy, policy)
1245
      self.assertFalse(op.dry_run)
1246
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1247

    
1248
  def testUnknownPolicy(self):
1249
    clfactory = _FakeClientFactory(_FakeClient)
1250

    
1251
    data = {
1252
      "alloc_policy": "_unknown_policy_",
1253
      }
1254

    
1255
    handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1256
    self.assertRaises(http.HttpBadRequest, handler.POST)
1257
    self.assertRaises(IndexError, clfactory.GetNextClient)
1258

    
1259
  def testDefaults(self):
1260
    clfactory = _FakeClientFactory(_FakeClient)
1261

    
1262
    name = "group15395"
1263
    data = {
1264
      "group_name": name,
1265
      }
1266

    
1267
    handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1268
    job_id = handler.POST()
1269

    
1270
    cl = clfactory.GetNextClient()
1271
    self.assertRaises(IndexError, clfactory.GetNextClient)
1272

    
1273
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1274
    self.assertEqual(job_id, exp_job_id)
1275

    
1276
    self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1277
    self.assertEqual(op.group_name, name)
1278
    self.assertFalse(hasattr(op, "alloc_policy"))
1279
    self.assertFalse(op.dry_run)
1280

    
1281
  def testLegacyName(self):
1282
    clfactory = _FakeClientFactory(_FakeClient)
1283

    
1284
    name = "group29852"
1285
    data = {
1286
      "name": name,
1287
      }
1288

    
1289
    handler = _CreateHandler(rlib2.R_2_groups, [], {
1290
      "dry-run": ["1"],
1291
      }, data, clfactory)
1292
    job_id = handler.POST()
1293

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

    
1297
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1298
    self.assertEqual(job_id, exp_job_id)
1299

    
1300
    self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1301
    self.assertEqual(op.group_name, name)
1302
    self.assertFalse(hasattr(op, "alloc_policy"))
1303
    self.assertTrue(op.dry_run)
1304

    
1305

    
1306
class TestNodeRole(unittest.TestCase):
1307
  def test(self):
1308
    clfactory = _FakeClientFactory(_FakeClient)
1309

    
1310
    for role in rlib2._NR_MAP.values():
1311
      handler = _CreateHandler(rlib2.R_2_nodes_name_role,
1312
                               ["node-z"], {}, role, clfactory)
1313
      if role == rlib2._NR_MASTER:
1314
        self.assertRaises(http.HttpBadRequest, handler.PUT)
1315
      else:
1316
        job_id = handler.PUT()
1317

    
1318
        cl = clfactory.GetNextClient()
1319
        self.assertRaises(IndexError, clfactory.GetNextClient)
1320

    
1321
        (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1322
        self.assertEqual(job_id, exp_job_id)
1323
        self.assertTrue(isinstance(op, opcodes.OpNodeSetParams))
1324
        self.assertEqual(op.node_name, "node-z")
1325
        self.assertFalse(op.force)
1326
        self.assertFalse(hasattr(op, "dry_run"))
1327

    
1328
        if role == rlib2._NR_REGULAR:
1329
          self.assertFalse(op.drained)
1330
          self.assertFalse(op.offline)
1331
          self.assertFalse(op.master_candidate)
1332
        elif role == rlib2._NR_MASTER_CANDIDATE:
1333
          self.assertFalse(op.drained)
1334
          self.assertFalse(op.offline)
1335
          self.assertTrue(op.master_candidate)
1336
        elif role == rlib2._NR_DRAINED:
1337
          self.assertTrue(op.drained)
1338
          self.assertFalse(op.offline)
1339
          self.assertFalse(op.master_candidate)
1340
        elif role == rlib2._NR_OFFLINE:
1341
          self.assertFalse(op.drained)
1342
          self.assertTrue(op.offline)
1343
          self.assertFalse(op.master_candidate)
1344
        else:
1345
          self.fail("Unknown role '%s'" % role)
1346

    
1347
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1348

    
1349

    
1350
if __name__ == '__main__':
1351
  testutils.GanetiTestProgram()