Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.rapi.rlib2_unittest.py @ 87fd3ec7

History | View | Annotate | Download (28.6 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 TestParseInstanceCreateRequestVersion1(testutils.GanetiTestCase):
301
  def setUp(self):
302
    testutils.GanetiTestCase.setUp(self)
303

    
304
    self.Parse = rlib2._ParseInstanceCreateRequestVersion1
305

    
306
  def test(self):
307
    disk_variants = [
308
      # No disks
309
      [],
310

    
311
      # Two disks
312
      [{"size": 5, }, {"size": 100, }],
313

    
314
      # Disk with mode
315
      [{"size": 123, "mode": constants.DISK_RDWR, }],
316
      ]
317

    
318
    nic_variants = [
319
      # No NIC
320
      [],
321

    
322
      # Three NICs
323
      [{}, {}, {}],
324

    
325
      # Two NICs
326
      [
327
        { "ip": "192.0.2.6", "mode": constants.NIC_MODE_ROUTED,
328
          "mac": "01:23:45:67:68:9A",
329
        },
330
        { "mode": constants.NIC_MODE_BRIDGED, "link": "br1" },
331
      ],
332
      ]
333

    
334
    beparam_variants = [
335
      None,
336
      {},
337
      { constants.BE_VCPUS: 2, },
338
      { constants.BE_MEMORY: 123, },
339
      { constants.BE_VCPUS: 2,
340
        constants.BE_MEMORY: 1024,
341
        constants.BE_AUTO_BALANCE: True, }
342
      ]
343

    
344
    hvparam_variants = [
345
      None,
346
      { constants.HV_BOOT_ORDER: "anc", },
347
      { constants.HV_KERNEL_PATH: "/boot/fookernel",
348
        constants.HV_ROOT_PATH: "/dev/hda1", },
349
      ]
350

    
351
    for mode in [constants.INSTANCE_CREATE, constants.INSTANCE_IMPORT]:
352
      for nics in nic_variants:
353
        for disk_template in constants.DISK_TEMPLATES:
354
          for disks in disk_variants:
355
            for beparams in beparam_variants:
356
              for hvparams in hvparam_variants:
357
                data = {
358
                  "name": "inst1.example.com",
359
                  "hypervisor": constants.HT_FAKE,
360
                  "disks": disks,
361
                  "nics": nics,
362
                  "mode": mode,
363
                  "disk_template": disk_template,
364
                  "os": "debootstrap",
365
                  }
366

    
367
                if beparams is not None:
368
                  data["beparams"] = beparams
369

    
370
                if hvparams is not None:
371
                  data["hvparams"] = hvparams
372

    
373
                for dry_run in [False, True]:
374
                  op = self.Parse(data, dry_run)
375
                  self.assert_(isinstance(op, opcodes.OpInstanceCreate))
376
                  self.assertEqual(op.mode, mode)
377
                  self.assertEqual(op.disk_template, disk_template)
378
                  self.assertEqual(op.dry_run, dry_run)
379
                  self.assertEqual(len(op.disks), len(disks))
380
                  self.assertEqual(len(op.nics), len(nics))
381

    
382
                  for opdisk, disk in zip(op.disks, disks):
383
                    for key in constants.IDISK_PARAMS:
384
                      self.assertEqual(opdisk.get(key), disk.get(key))
385
                    self.assertFalse("unknown" in opdisk)
386

    
387
                  for opnic, nic in zip(op.nics, nics):
388
                    for key in constants.INIC_PARAMS:
389
                      self.assertEqual(opnic.get(key), nic.get(key))
390
                    self.assertFalse("unknown" in opnic)
391
                    self.assertFalse("foobar" in opnic)
392

    
393
                  if beparams is None:
394
                    self.assertFalse(hasattr(op, "beparams"))
395
                  else:
396
                    self.assertEqualValues(op.beparams, beparams)
397

    
398
                  if hvparams is None:
399
                    self.assertFalse(hasattr(op, "hvparams"))
400
                  else:
401
                    self.assertEqualValues(op.hvparams, hvparams)
402

    
403
  def testLegacyName(self):
404
    name = "inst29128.example.com"
405
    data = {
406
      "name": name,
407
      "disks": [],
408
      "nics": [],
409
      "mode": constants.INSTANCE_CREATE,
410
      "disk_template": constants.DT_PLAIN,
411
      }
412
    op = self.Parse(data, False)
413
    self.assert_(isinstance(op, opcodes.OpInstanceCreate))
414
    self.assertEqual(op.instance_name, name)
415
    self.assertFalse(hasattr(op, "name"))
416

    
417
    # Define both
418
    data = {
419
      "name": name,
420
      "instance_name": "other.example.com",
421
      "disks": [],
422
      "nics": [],
423
      "mode": constants.INSTANCE_CREATE,
424
      "disk_template": constants.DT_PLAIN,
425
      }
426
    self.assertRaises(http.HttpBadRequest, self.Parse, data, False)
427

    
428
  def testLegacyOs(self):
429
    name = "inst4673.example.com"
430
    os = "linux29206"
431
    data = {
432
      "name": name,
433
      "os_type": os,
434
      "disks": [],
435
      "nics": [],
436
      "mode": constants.INSTANCE_CREATE,
437
      "disk_template": constants.DT_PLAIN,
438
      }
439
    op = self.Parse(data, False)
440
    self.assert_(isinstance(op, opcodes.OpInstanceCreate))
441
    self.assertEqual(op.instance_name, name)
442
    self.assertEqual(op.os_type, os)
443
    self.assertFalse(hasattr(op, "os"))
444

    
445
    # Define both
446
    data = {
447
      "instance_name": name,
448
      "os": os,
449
      "os_type": "linux9584",
450
      "disks": [],
451
      "nics": [],
452
      "mode": constants.INSTANCE_CREATE,
453
      "disk_template": constants.DT_PLAIN,
454
      }
455
    self.assertRaises(http.HttpBadRequest, self.Parse, data, False)
456

    
457
  def testErrors(self):
458
    # Test all required fields
459
    reqfields = {
460
      "name": "inst1.example.com",
461
      "disks": [],
462
      "nics": [],
463
      "mode": constants.INSTANCE_CREATE,
464
      "disk_template": constants.DT_PLAIN,
465
      }
466

    
467
    for name in reqfields.keys():
468
      self.assertRaises(http.HttpBadRequest, self.Parse,
469
                        dict(i for i in reqfields.iteritems() if i[0] != name),
470
                        False)
471

    
472
    # Invalid disks and nics
473
    for field in ["disks", "nics"]:
474
      invalid_values = [None, 1, "", {}, [1, 2, 3], ["hda1", "hda2"],
475
                        [{"_unknown_": 999, }]]
476

    
477
      for invvalue in invalid_values:
478
        data = reqfields.copy()
479
        data[field] = invvalue
480
        self.assertRaises(http.HttpBadRequest, self.Parse, data, False)
481

    
482

    
483
class TestParseExportInstanceRequest(testutils.GanetiTestCase):
484
  def setUp(self):
485
    testutils.GanetiTestCase.setUp(self)
486

    
487
    self.Parse = rlib2._ParseExportInstanceRequest
488

    
489
  def test(self):
490
    name = "instmoo"
491
    data = {
492
      "mode": constants.EXPORT_MODE_REMOTE,
493
      "destination": [(1, 2, 3), (99, 99, 99)],
494
      "shutdown": True,
495
      "remove_instance": True,
496
      "x509_key_name": ["name", "hash"],
497
      "destination_x509_ca": "---cert---"
498
      }
499
    op = self.Parse(name, data)
500
    self.assert_(isinstance(op, opcodes.OpBackupExport))
501
    self.assertEqual(op.instance_name, name)
502
    self.assertEqual(op.mode, constants.EXPORT_MODE_REMOTE)
503
    self.assertEqual(op.shutdown, True)
504
    self.assertEqual(op.remove_instance, True)
505
    self.assertEqualValues(op.x509_key_name, ("name", "hash"))
506
    self.assertEqual(op.destination_x509_ca, "---cert---")
507

    
508
  def testDefaults(self):
509
    name = "inst1"
510
    data = {
511
      "destination": "node2",
512
      "shutdown": False,
513
      }
514
    op = self.Parse(name, data)
515
    self.assert_(isinstance(op, opcodes.OpBackupExport))
516
    self.assertEqual(op.instance_name, name)
517
    self.assertEqual(op.target_node, "node2")
518
    self.assertFalse(hasattr(op, "mode"))
519
    self.assertFalse(hasattr(op, "remove_instance"))
520
    self.assertFalse(hasattr(op, "destination"))
521

    
522
  def testErrors(self):
523
    self.assertRaises(http.HttpBadRequest, self.Parse, "err1",
524
                      { "remove_instance": "True", })
525
    self.assertRaises(http.HttpBadRequest, self.Parse, "err1",
526
                      { "remove_instance": "False", })
527

    
528

    
529
class TestParseMigrateInstanceRequest(testutils.GanetiTestCase):
530
  def setUp(self):
531
    testutils.GanetiTestCase.setUp(self)
532

    
533
    self.Parse = rlib2._ParseMigrateInstanceRequest
534

    
535
  def test(self):
536
    name = "instYooho6ek"
537

    
538
    for cleanup in [False, True]:
539
      for mode in constants.HT_MIGRATION_MODES:
540
        data = {
541
          "cleanup": cleanup,
542
          "mode": mode,
543
          }
544
        op = self.Parse(name, data)
545
        self.assert_(isinstance(op, opcodes.OpInstanceMigrate))
546
        self.assertEqual(op.instance_name, name)
547
        self.assertEqual(op.mode, mode)
548
        self.assertEqual(op.cleanup, cleanup)
549

    
550
  def testDefaults(self):
551
    name = "instnohZeex0"
552

    
553
    op = self.Parse(name, {})
554
    self.assert_(isinstance(op, opcodes.OpInstanceMigrate))
555
    self.assertEqual(op.instance_name, name)
556
    self.assertFalse(hasattr(op, "mode"))
557
    self.assertFalse(hasattr(op, "cleanup"))
558

    
559

    
560
class TestParseRenameInstanceRequest(testutils.GanetiTestCase):
561
  def setUp(self):
562
    testutils.GanetiTestCase.setUp(self)
563

    
564
    self.Parse = rlib2._ParseRenameInstanceRequest
565

    
566
  def test(self):
567
    name = "instij0eeph7"
568

    
569
    for new_name in ["ua0aiyoo", "fai3ongi"]:
570
      for ip_check in [False, True]:
571
        for name_check in [False, True]:
572
          data = {
573
            "new_name": new_name,
574
            "ip_check": ip_check,
575
            "name_check": name_check,
576
            }
577

    
578
          op = self.Parse(name, data)
579
          self.assert_(isinstance(op, opcodes.OpInstanceRename))
580
          self.assertEqual(op.instance_name, name)
581
          self.assertEqual(op.new_name, new_name)
582
          self.assertEqual(op.ip_check, ip_check)
583
          self.assertEqual(op.name_check, name_check)
584

    
585
  def testDefaults(self):
586
    name = "instahchie3t"
587

    
588
    for new_name in ["thag9mek", "quees7oh"]:
589
      data = {
590
        "new_name": new_name,
591
        }
592

    
593
      op = self.Parse(name, data)
594
      self.assert_(isinstance(op, opcodes.OpInstanceRename))
595
      self.assertEqual(op.instance_name, name)
596
      self.assertEqual(op.new_name, new_name)
597
      self.assertFalse(hasattr(op, "ip_check"))
598
      self.assertFalse(hasattr(op, "name_check"))
599

    
600

    
601
class TestParseModifyInstanceRequest(testutils.GanetiTestCase):
602
  def setUp(self):
603
    testutils.GanetiTestCase.setUp(self)
604

    
605
    self.Parse = rlib2._ParseModifyInstanceRequest
606

    
607
  def test(self):
608
    name = "instush8gah"
609

    
610
    test_disks = [
611
      [],
612
      [(1, { constants.IDISK_MODE: constants.DISK_RDWR, })],
613
      ]
614

    
615
    for osparams in [{}, { "some": "value", "other": "Hello World", }]:
616
      for hvparams in [{}, { constants.HV_KERNEL_PATH: "/some/kernel", }]:
617
        for beparams in [{}, { constants.BE_MEMORY: 128, }]:
618
          for force in [False, True]:
619
            for nics in [[], [(0, { constants.INIC_IP: "192.0.2.1", })]]:
620
              for disks in test_disks:
621
                for disk_template in constants.DISK_TEMPLATES:
622
                  data = {
623
                    "osparams": osparams,
624
                    "hvparams": hvparams,
625
                    "beparams": beparams,
626
                    "nics": nics,
627
                    "disks": disks,
628
                    "force": force,
629
                    "disk_template": disk_template,
630
                    }
631

    
632
                  op = self.Parse(name, data)
633
                  self.assert_(isinstance(op, opcodes.OpInstanceSetParams))
634
                  self.assertEqual(op.instance_name, name)
635
                  self.assertEqual(op.hvparams, hvparams)
636
                  self.assertEqual(op.beparams, beparams)
637
                  self.assertEqual(op.osparams, osparams)
638
                  self.assertEqual(op.force, force)
639
                  self.assertEqual(op.nics, nics)
640
                  self.assertEqual(op.disks, disks)
641
                  self.assertEqual(op.disk_template, disk_template)
642
                  self.assertFalse(hasattr(op, "remote_node"))
643
                  self.assertFalse(hasattr(op, "os_name"))
644
                  self.assertFalse(hasattr(op, "force_variant"))
645

    
646
  def testDefaults(self):
647
    name = "instir8aish31"
648

    
649
    op = self.Parse(name, {})
650
    self.assert_(isinstance(op, opcodes.OpInstanceSetParams))
651
    self.assertEqual(op.instance_name, name)
652
    for i in ["hvparams", "beparams", "osparams", "force", "nics", "disks",
653
              "disk_template", "remote_node", "os_name", "force_variant"]:
654
      self.assertFalse(hasattr(op, i))
655

    
656

    
657
class TestParseInstanceReinstallRequest(testutils.GanetiTestCase):
658
  def setUp(self):
659
    testutils.GanetiTestCase.setUp(self)
660

    
661
    self.Parse = rlib2._ParseInstanceReinstallRequest
662

    
663
  def _Check(self, ops, name):
664
    expcls = [
665
      opcodes.OpInstanceShutdown,
666
      opcodes.OpInstanceReinstall,
667
      opcodes.OpInstanceStartup,
668
      ]
669

    
670
    self.assert_(compat.all(isinstance(op, exp)
671
                            for op, exp in zip(ops, expcls)))
672
    self.assert_(compat.all(op.instance_name == name for op in ops))
673

    
674
  def test(self):
675
    name = "shoo0tihohma"
676

    
677
    ops = self.Parse(name, {"os": "sys1", "start": True,})
678
    self.assertEqual(len(ops), 3)
679
    self._Check(ops, name)
680
    self.assertEqual(ops[1].os_type, "sys1")
681
    self.assertFalse(ops[1].osparams)
682

    
683
    ops = self.Parse(name, {"os": "sys2", "start": False,})
684
    self.assertEqual(len(ops), 2)
685
    self._Check(ops, name)
686
    self.assertEqual(ops[1].os_type, "sys2")
687

    
688
    osparams = {
689
      "reformat": "1",
690
      }
691
    ops = self.Parse(name, {"os": "sys4035", "start": True,
692
                            "osparams": osparams,})
693
    self.assertEqual(len(ops), 3)
694
    self._Check(ops, name)
695
    self.assertEqual(ops[1].os_type, "sys4035")
696
    self.assertEqual(ops[1].osparams, osparams)
697

    
698
  def testDefaults(self):
699
    name = "noolee0g"
700

    
701
    ops = self.Parse(name, {"os": "linux1"})
702
    self.assertEqual(len(ops), 3)
703
    self._Check(ops, name)
704
    self.assertEqual(ops[1].os_type, "linux1")
705
    self.assertFalse(ops[1].osparams)
706

    
707

    
708
class TestGroupRename(unittest.TestCase):
709
  def test(self):
710
    clfactory = _FakeClientFactory(_FakeClient)
711

    
712
    name = "group608242564"
713
    data = {
714
      "new_name": "ua0aiyoo15112",
715
      }
716

    
717
    handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {}, data,
718
                             clfactory)
719
    job_id = handler.PUT()
720

    
721
    cl = clfactory.GetNextClient()
722
    self.assertRaises(IndexError, clfactory.GetNextClient)
723

    
724
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
725
    self.assertEqual(job_id, exp_job_id)
726

    
727
    self.assertTrue(isinstance(op, opcodes.OpGroupRename))
728
    self.assertEqual(op.group_name, name)
729
    self.assertEqual(op.new_name, "ua0aiyoo15112")
730
    self.assertFalse(op.dry_run)
731
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
732

    
733
  def testDryRun(self):
734
    clfactory = _FakeClientFactory(_FakeClient)
735

    
736
    name = "group28548"
737
    data = {
738
      "new_name": "ua0aiyoo",
739
      }
740

    
741
    handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {
742
      "dry-run": ["1"],
743
      }, data, clfactory)
744
    job_id = handler.PUT()
745

    
746
    cl = clfactory.GetNextClient()
747
    self.assertRaises(IndexError, clfactory.GetNextClient)
748

    
749
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
750
    self.assertEqual(job_id, exp_job_id)
751

    
752
    self.assertTrue(isinstance(op, opcodes.OpGroupRename))
753
    self.assertEqual(op.group_name, name)
754
    self.assertEqual(op.new_name, "ua0aiyoo")
755
    self.assertTrue(op.dry_run)
756
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
757

    
758

    
759
class TestParseInstanceReplaceDisksRequest(unittest.TestCase):
760
  def setUp(self):
761
    self.Parse = rlib2._ParseInstanceReplaceDisksRequest
762

    
763
  def test(self):
764
    name = "inst22568"
765

    
766
    for disks in [range(1, 4), "1,2,3", "1, 2, 3"]:
767
      data = {
768
        "mode": constants.REPLACE_DISK_SEC,
769
        "disks": disks,
770
        "iallocator": "myalloc",
771
        }
772

    
773
      op = self.Parse(name, data)
774
      self.assert_(isinstance(op, opcodes.OpInstanceReplaceDisks))
775
      self.assertEqual(op.mode, constants.REPLACE_DISK_SEC)
776
      self.assertEqual(op.disks, [1, 2, 3])
777
      self.assertEqual(op.iallocator, "myalloc")
778

    
779
  def testDefaults(self):
780
    name = "inst11413"
781
    data = {
782
      "mode": constants.REPLACE_DISK_AUTO,
783
      }
784

    
785
    op = self.Parse(name, data)
786
    self.assert_(isinstance(op, opcodes.OpInstanceReplaceDisks))
787
    self.assertEqual(op.mode, constants.REPLACE_DISK_AUTO)
788
    self.assertFalse(hasattr(op, "iallocator"))
789
    self.assertFalse(hasattr(op, "disks"))
790

    
791
  def testWrong(self):
792
    self.assertRaises(http.HttpBadRequest, self.Parse, "inst",
793
                      { "mode": constants.REPLACE_DISK_AUTO,
794
                        "disks": "hello world",
795
                      })
796

    
797

    
798
class TestGroupModify(unittest.TestCase):
799
  def test(self):
800
    clfactory = _FakeClientFactory(_FakeClient)
801

    
802
    name = "group6002"
803

    
804
    for policy in constants.VALID_ALLOC_POLICIES:
805
      data = {
806
        "alloc_policy": policy,
807
        }
808

    
809
      handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, data,
810
                               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

    
819
      self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
820
      self.assertEqual(op.group_name, name)
821
      self.assertEqual(op.alloc_policy, policy)
822
      self.assertFalse(hasattr(op, "dry_run"))
823
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
824

    
825
  def testUnknownPolicy(self):
826
    clfactory = _FakeClientFactory(_FakeClient)
827

    
828
    data = {
829
      "alloc_policy": "_unknown_policy_",
830
      }
831

    
832
    handler = _CreateHandler(rlib2.R_2_groups_name_modify, ["xyz"], {}, data,
833
                             clfactory)
834
    self.assertRaises(http.HttpBadRequest, handler.PUT)
835
    self.assertRaises(IndexError, clfactory.GetNextClient)
836

    
837
  def testDefaults(self):
838
    clfactory = _FakeClientFactory(_FakeClient)
839

    
840
    name = "group6679"
841

    
842
    handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, {},
843
                             clfactory)
844
    job_id = handler.PUT()
845

    
846
    cl = clfactory.GetNextClient()
847
    self.assertRaises(IndexError, clfactory.GetNextClient)
848

    
849
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
850
    self.assertEqual(job_id, exp_job_id)
851

    
852
    self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
853
    self.assertEqual(op.group_name, name)
854
    self.assertFalse(hasattr(op, "alloc_policy"))
855
    self.assertFalse(hasattr(op, "dry_run"))
856
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
857

    
858

    
859
class TestGroupAdd(unittest.TestCase):
860
  def test(self):
861
    name = "group3618"
862
    clfactory = _FakeClientFactory(_FakeClient)
863

    
864
    for policy in constants.VALID_ALLOC_POLICIES:
865
      data = {
866
        "group_name": name,
867
        "alloc_policy": policy,
868
        }
869

    
870
      handler = _CreateHandler(rlib2.R_2_groups, [], {}, data,
871
                               clfactory)
872
      job_id = handler.POST()
873

    
874
      cl = clfactory.GetNextClient()
875
      self.assertRaises(IndexError, clfactory.GetNextClient)
876

    
877
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
878
      self.assertEqual(job_id, exp_job_id)
879

    
880
      self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
881
      self.assertEqual(op.group_name, name)
882
      self.assertEqual(op.alloc_policy, policy)
883
      self.assertFalse(op.dry_run)
884
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
885

    
886
  def testUnknownPolicy(self):
887
    clfactory = _FakeClientFactory(_FakeClient)
888

    
889
    data = {
890
      "alloc_policy": "_unknown_policy_",
891
      }
892

    
893
    handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
894
    self.assertRaises(http.HttpBadRequest, handler.POST)
895
    self.assertRaises(IndexError, clfactory.GetNextClient)
896

    
897
  def testDefaults(self):
898
    clfactory = _FakeClientFactory(_FakeClient)
899

    
900
    name = "group15395"
901
    data = {
902
      "group_name": name,
903
      }
904

    
905
    handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
906
    job_id = handler.POST()
907

    
908
    cl = clfactory.GetNextClient()
909
    self.assertRaises(IndexError, clfactory.GetNextClient)
910

    
911
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
912
    self.assertEqual(job_id, exp_job_id)
913

    
914
    self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
915
    self.assertEqual(op.group_name, name)
916
    self.assertFalse(hasattr(op, "alloc_policy"))
917
    self.assertFalse(op.dry_run)
918

    
919
  def testLegacyName(self):
920
    clfactory = _FakeClientFactory(_FakeClient)
921

    
922
    name = "group29852"
923
    data = {
924
      "name": name,
925
      }
926

    
927
    handler = _CreateHandler(rlib2.R_2_groups, [], {
928
      "dry-run": ["1"],
929
      }, data, clfactory)
930
    job_id = handler.POST()
931

    
932
    cl = clfactory.GetNextClient()
933
    self.assertRaises(IndexError, clfactory.GetNextClient)
934

    
935
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
936
    self.assertEqual(job_id, exp_job_id)
937

    
938
    self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
939
    self.assertEqual(op.group_name, name)
940
    self.assertFalse(hasattr(op, "alloc_policy"))
941
    self.assertTrue(op.dry_run)
942

    
943

    
944
if __name__ == '__main__':
945
  testutils.GanetiTestProgram()