Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.rapi.rlib2_unittest.py @ 0dbc732c

History | View | Annotate | Download (33.1 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 TestParseInstanceCreateRequestVersion1(testutils.GanetiTestCase):
409
  def setUp(self):
410
    testutils.GanetiTestCase.setUp(self)
411

    
412
    self.Parse = rlib2._ParseInstanceCreateRequestVersion1
413

    
414
  def test(self):
415
    disk_variants = [
416
      # No disks
417
      [],
418

    
419
      # Two disks
420
      [{"size": 5, }, {"size": 100, }],
421

    
422
      # Disk with mode
423
      [{"size": 123, "mode": constants.DISK_RDWR, }],
424
      ]
425

    
426
    nic_variants = [
427
      # No NIC
428
      [],
429

    
430
      # Three NICs
431
      [{}, {}, {}],
432

    
433
      # Two NICs
434
      [
435
        { "ip": "192.0.2.6", "mode": constants.NIC_MODE_ROUTED,
436
          "mac": "01:23:45:67:68:9A",
437
        },
438
        { "mode": constants.NIC_MODE_BRIDGED, "link": "br1" },
439
      ],
440
      ]
441

    
442
    beparam_variants = [
443
      None,
444
      {},
445
      { constants.BE_VCPUS: 2, },
446
      { constants.BE_MEMORY: 123, },
447
      { constants.BE_VCPUS: 2,
448
        constants.BE_MEMORY: 1024,
449
        constants.BE_AUTO_BALANCE: True, }
450
      ]
451

    
452
    hvparam_variants = [
453
      None,
454
      { constants.HV_BOOT_ORDER: "anc", },
455
      { constants.HV_KERNEL_PATH: "/boot/fookernel",
456
        constants.HV_ROOT_PATH: "/dev/hda1", },
457
      ]
458

    
459
    for mode in [constants.INSTANCE_CREATE, constants.INSTANCE_IMPORT]:
460
      for nics in nic_variants:
461
        for disk_template in constants.DISK_TEMPLATES:
462
          for disks in disk_variants:
463
            for beparams in beparam_variants:
464
              for hvparams in hvparam_variants:
465
                data = {
466
                  "name": "inst1.example.com",
467
                  "hypervisor": constants.HT_FAKE,
468
                  "disks": disks,
469
                  "nics": nics,
470
                  "mode": mode,
471
                  "disk_template": disk_template,
472
                  "os": "debootstrap",
473
                  }
474

    
475
                if beparams is not None:
476
                  data["beparams"] = beparams
477

    
478
                if hvparams is not None:
479
                  data["hvparams"] = hvparams
480

    
481
                for dry_run in [False, True]:
482
                  op = self.Parse(data, dry_run)
483
                  self.assert_(isinstance(op, opcodes.OpInstanceCreate))
484
                  self.assertEqual(op.mode, mode)
485
                  self.assertEqual(op.disk_template, disk_template)
486
                  self.assertEqual(op.dry_run, dry_run)
487
                  self.assertEqual(len(op.disks), len(disks))
488
                  self.assertEqual(len(op.nics), len(nics))
489

    
490
                  for opdisk, disk in zip(op.disks, disks):
491
                    for key in constants.IDISK_PARAMS:
492
                      self.assertEqual(opdisk.get(key), disk.get(key))
493
                    self.assertFalse("unknown" in opdisk)
494

    
495
                  for opnic, nic in zip(op.nics, nics):
496
                    for key in constants.INIC_PARAMS:
497
                      self.assertEqual(opnic.get(key), nic.get(key))
498
                    self.assertFalse("unknown" in opnic)
499
                    self.assertFalse("foobar" in opnic)
500

    
501
                  if beparams is None:
502
                    self.assertFalse(hasattr(op, "beparams"))
503
                  else:
504
                    self.assertEqualValues(op.beparams, beparams)
505

    
506
                  if hvparams is None:
507
                    self.assertFalse(hasattr(op, "hvparams"))
508
                  else:
509
                    self.assertEqualValues(op.hvparams, hvparams)
510

    
511
  def testLegacyName(self):
512
    name = "inst29128.example.com"
513
    data = {
514
      "name": name,
515
      "disks": [],
516
      "nics": [],
517
      "mode": constants.INSTANCE_CREATE,
518
      "disk_template": constants.DT_PLAIN,
519
      }
520
    op = self.Parse(data, False)
521
    self.assert_(isinstance(op, opcodes.OpInstanceCreate))
522
    self.assertEqual(op.instance_name, name)
523
    self.assertFalse(hasattr(op, "name"))
524

    
525
    # Define both
526
    data = {
527
      "name": name,
528
      "instance_name": "other.example.com",
529
      "disks": [],
530
      "nics": [],
531
      "mode": constants.INSTANCE_CREATE,
532
      "disk_template": constants.DT_PLAIN,
533
      }
534
    self.assertRaises(http.HttpBadRequest, self.Parse, data, False)
535

    
536
  def testLegacyOs(self):
537
    name = "inst4673.example.com"
538
    os = "linux29206"
539
    data = {
540
      "name": name,
541
      "os_type": os,
542
      "disks": [],
543
      "nics": [],
544
      "mode": constants.INSTANCE_CREATE,
545
      "disk_template": constants.DT_PLAIN,
546
      }
547
    op = self.Parse(data, False)
548
    self.assert_(isinstance(op, opcodes.OpInstanceCreate))
549
    self.assertEqual(op.instance_name, name)
550
    self.assertEqual(op.os_type, os)
551
    self.assertFalse(hasattr(op, "os"))
552

    
553
    # Define both
554
    data = {
555
      "instance_name": name,
556
      "os": os,
557
      "os_type": "linux9584",
558
      "disks": [],
559
      "nics": [],
560
      "mode": constants.INSTANCE_CREATE,
561
      "disk_template": constants.DT_PLAIN,
562
      }
563
    self.assertRaises(http.HttpBadRequest, self.Parse, data, False)
564

    
565
  def testErrors(self):
566
    # Test all required fields
567
    reqfields = {
568
      "name": "inst1.example.com",
569
      "disks": [],
570
      "nics": [],
571
      "mode": constants.INSTANCE_CREATE,
572
      "disk_template": constants.DT_PLAIN,
573
      }
574

    
575
    for name in reqfields.keys():
576
      self.assertRaises(http.HttpBadRequest, self.Parse,
577
                        dict(i for i in reqfields.iteritems() if i[0] != name),
578
                        False)
579

    
580
    # Invalid disks and nics
581
    for field in ["disks", "nics"]:
582
      invalid_values = [None, 1, "", {}, [1, 2, 3], ["hda1", "hda2"],
583
                        [{"_unknown_": 999, }]]
584

    
585
      for invvalue in invalid_values:
586
        data = reqfields.copy()
587
        data[field] = invvalue
588
        self.assertRaises(http.HttpBadRequest, self.Parse, data, False)
589

    
590

    
591
class TestParseExportInstanceRequest(testutils.GanetiTestCase):
592
  def setUp(self):
593
    testutils.GanetiTestCase.setUp(self)
594

    
595
    self.Parse = rlib2._ParseExportInstanceRequest
596

    
597
  def test(self):
598
    name = "instmoo"
599
    data = {
600
      "mode": constants.EXPORT_MODE_REMOTE,
601
      "destination": [(1, 2, 3), (99, 99, 99)],
602
      "shutdown": True,
603
      "remove_instance": True,
604
      "x509_key_name": ["name", "hash"],
605
      "destination_x509_ca": "---cert---"
606
      }
607
    op = self.Parse(name, data)
608
    self.assert_(isinstance(op, opcodes.OpBackupExport))
609
    self.assertEqual(op.instance_name, name)
610
    self.assertEqual(op.mode, constants.EXPORT_MODE_REMOTE)
611
    self.assertEqual(op.shutdown, True)
612
    self.assertEqual(op.remove_instance, True)
613
    self.assertEqualValues(op.x509_key_name, ("name", "hash"))
614
    self.assertEqual(op.destination_x509_ca, "---cert---")
615

    
616
  def testDefaults(self):
617
    name = "inst1"
618
    data = {
619
      "destination": "node2",
620
      "shutdown": False,
621
      }
622
    op = self.Parse(name, data)
623
    self.assert_(isinstance(op, opcodes.OpBackupExport))
624
    self.assertEqual(op.instance_name, name)
625
    self.assertEqual(op.target_node, "node2")
626
    self.assertFalse(hasattr(op, "mode"))
627
    self.assertFalse(hasattr(op, "remove_instance"))
628
    self.assertFalse(hasattr(op, "destination"))
629

    
630
  def testErrors(self):
631
    self.assertRaises(http.HttpBadRequest, self.Parse, "err1",
632
                      { "remove_instance": "True", })
633
    self.assertRaises(http.HttpBadRequest, self.Parse, "err1",
634
                      { "remove_instance": "False", })
635

    
636

    
637
class TestParseMigrateInstanceRequest(testutils.GanetiTestCase):
638
  def setUp(self):
639
    testutils.GanetiTestCase.setUp(self)
640

    
641
    self.Parse = rlib2._ParseMigrateInstanceRequest
642

    
643
  def test(self):
644
    name = "instYooho6ek"
645

    
646
    for cleanup in [False, True]:
647
      for mode in constants.HT_MIGRATION_MODES:
648
        data = {
649
          "cleanup": cleanup,
650
          "mode": mode,
651
          }
652
        op = self.Parse(name, data)
653
        self.assert_(isinstance(op, opcodes.OpInstanceMigrate))
654
        self.assertEqual(op.instance_name, name)
655
        self.assertEqual(op.mode, mode)
656
        self.assertEqual(op.cleanup, cleanup)
657

    
658
  def testDefaults(self):
659
    name = "instnohZeex0"
660

    
661
    op = self.Parse(name, {})
662
    self.assert_(isinstance(op, opcodes.OpInstanceMigrate))
663
    self.assertEqual(op.instance_name, name)
664
    self.assertFalse(hasattr(op, "mode"))
665
    self.assertFalse(hasattr(op, "cleanup"))
666

    
667

    
668
class TestParseRenameInstanceRequest(testutils.GanetiTestCase):
669
  def setUp(self):
670
    testutils.GanetiTestCase.setUp(self)
671

    
672
    self.Parse = rlib2._ParseRenameInstanceRequest
673

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

    
677
    for new_name in ["ua0aiyoo", "fai3ongi"]:
678
      for ip_check in [False, True]:
679
        for name_check in [False, True]:
680
          data = {
681
            "new_name": new_name,
682
            "ip_check": ip_check,
683
            "name_check": name_check,
684
            }
685

    
686
          op = self.Parse(name, data)
687
          self.assert_(isinstance(op, opcodes.OpInstanceRename))
688
          self.assertEqual(op.instance_name, name)
689
          self.assertEqual(op.new_name, new_name)
690
          self.assertEqual(op.ip_check, ip_check)
691
          self.assertEqual(op.name_check, name_check)
692

    
693
  def testDefaults(self):
694
    name = "instahchie3t"
695

    
696
    for new_name in ["thag9mek", "quees7oh"]:
697
      data = {
698
        "new_name": new_name,
699
        }
700

    
701
      op = self.Parse(name, data)
702
      self.assert_(isinstance(op, opcodes.OpInstanceRename))
703
      self.assertEqual(op.instance_name, name)
704
      self.assertEqual(op.new_name, new_name)
705
      self.assertFalse(hasattr(op, "ip_check"))
706
      self.assertFalse(hasattr(op, "name_check"))
707

    
708

    
709
class TestParseModifyInstanceRequest(testutils.GanetiTestCase):
710
  def setUp(self):
711
    testutils.GanetiTestCase.setUp(self)
712

    
713
    self.Parse = rlib2._ParseModifyInstanceRequest
714

    
715
  def test(self):
716
    name = "instush8gah"
717

    
718
    test_disks = [
719
      [],
720
      [(1, { constants.IDISK_MODE: constants.DISK_RDWR, })],
721
      ]
722

    
723
    for osparams in [{}, { "some": "value", "other": "Hello World", }]:
724
      for hvparams in [{}, { constants.HV_KERNEL_PATH: "/some/kernel", }]:
725
        for beparams in [{}, { constants.BE_MEMORY: 128, }]:
726
          for force in [False, True]:
727
            for nics in [[], [(0, { constants.INIC_IP: "192.0.2.1", })]]:
728
              for disks in test_disks:
729
                for disk_template in constants.DISK_TEMPLATES:
730
                  data = {
731
                    "osparams": osparams,
732
                    "hvparams": hvparams,
733
                    "beparams": beparams,
734
                    "nics": nics,
735
                    "disks": disks,
736
                    "force": force,
737
                    "disk_template": disk_template,
738
                    }
739

    
740
                  op = self.Parse(name, data)
741
                  self.assert_(isinstance(op, opcodes.OpInstanceSetParams))
742
                  self.assertEqual(op.instance_name, name)
743
                  self.assertEqual(op.hvparams, hvparams)
744
                  self.assertEqual(op.beparams, beparams)
745
                  self.assertEqual(op.osparams, osparams)
746
                  self.assertEqual(op.force, force)
747
                  self.assertEqual(op.nics, nics)
748
                  self.assertEqual(op.disks, disks)
749
                  self.assertEqual(op.disk_template, disk_template)
750
                  self.assertFalse(hasattr(op, "remote_node"))
751
                  self.assertFalse(hasattr(op, "os_name"))
752
                  self.assertFalse(hasattr(op, "force_variant"))
753

    
754
  def testDefaults(self):
755
    name = "instir8aish31"
756

    
757
    op = self.Parse(name, {})
758
    self.assert_(isinstance(op, opcodes.OpInstanceSetParams))
759
    self.assertEqual(op.instance_name, name)
760
    for i in ["hvparams", "beparams", "osparams", "force", "nics", "disks",
761
              "disk_template", "remote_node", "os_name", "force_variant"]:
762
      self.assertFalse(hasattr(op, i))
763

    
764

    
765
class TestParseInstanceReinstallRequest(testutils.GanetiTestCase):
766
  def setUp(self):
767
    testutils.GanetiTestCase.setUp(self)
768

    
769
    self.Parse = rlib2._ParseInstanceReinstallRequest
770

    
771
  def _Check(self, ops, name):
772
    expcls = [
773
      opcodes.OpInstanceShutdown,
774
      opcodes.OpInstanceReinstall,
775
      opcodes.OpInstanceStartup,
776
      ]
777

    
778
    self.assert_(compat.all(isinstance(op, exp)
779
                            for op, exp in zip(ops, expcls)))
780
    self.assert_(compat.all(op.instance_name == name for op in ops))
781

    
782
  def test(self):
783
    name = "shoo0tihohma"
784

    
785
    ops = self.Parse(name, {"os": "sys1", "start": True,})
786
    self.assertEqual(len(ops), 3)
787
    self._Check(ops, name)
788
    self.assertEqual(ops[1].os_type, "sys1")
789
    self.assertFalse(ops[1].osparams)
790

    
791
    ops = self.Parse(name, {"os": "sys2", "start": False,})
792
    self.assertEqual(len(ops), 2)
793
    self._Check(ops, name)
794
    self.assertEqual(ops[1].os_type, "sys2")
795

    
796
    osparams = {
797
      "reformat": "1",
798
      }
799
    ops = self.Parse(name, {"os": "sys4035", "start": True,
800
                            "osparams": osparams,})
801
    self.assertEqual(len(ops), 3)
802
    self._Check(ops, name)
803
    self.assertEqual(ops[1].os_type, "sys4035")
804
    self.assertEqual(ops[1].osparams, osparams)
805

    
806
  def testDefaults(self):
807
    name = "noolee0g"
808

    
809
    ops = self.Parse(name, {"os": "linux1"})
810
    self.assertEqual(len(ops), 3)
811
    self._Check(ops, name)
812
    self.assertEqual(ops[1].os_type, "linux1")
813
    self.assertFalse(ops[1].osparams)
814

    
815

    
816
class TestGroupRename(unittest.TestCase):
817
  def test(self):
818
    clfactory = _FakeClientFactory(_FakeClient)
819

    
820
    name = "group608242564"
821
    data = {
822
      "new_name": "ua0aiyoo15112",
823
      }
824

    
825
    handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {}, data,
826
                             clfactory)
827
    job_id = handler.PUT()
828

    
829
    cl = clfactory.GetNextClient()
830
    self.assertRaises(IndexError, clfactory.GetNextClient)
831

    
832
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
833
    self.assertEqual(job_id, exp_job_id)
834

    
835
    self.assertTrue(isinstance(op, opcodes.OpGroupRename))
836
    self.assertEqual(op.group_name, name)
837
    self.assertEqual(op.new_name, "ua0aiyoo15112")
838
    self.assertFalse(op.dry_run)
839
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
840

    
841
  def testDryRun(self):
842
    clfactory = _FakeClientFactory(_FakeClient)
843

    
844
    name = "group28548"
845
    data = {
846
      "new_name": "ua0aiyoo",
847
      }
848

    
849
    handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {
850
      "dry-run": ["1"],
851
      }, data, clfactory)
852
    job_id = handler.PUT()
853

    
854
    cl = clfactory.GetNextClient()
855
    self.assertRaises(IndexError, clfactory.GetNextClient)
856

    
857
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
858
    self.assertEqual(job_id, exp_job_id)
859

    
860
    self.assertTrue(isinstance(op, opcodes.OpGroupRename))
861
    self.assertEqual(op.group_name, name)
862
    self.assertEqual(op.new_name, "ua0aiyoo")
863
    self.assertTrue(op.dry_run)
864
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
865

    
866

    
867
class TestInstanceReplaceDisks(unittest.TestCase):
868
  def test(self):
869
    clfactory = _FakeClientFactory(_FakeClient)
870

    
871
    name = "inst22568"
872

    
873
    for disks in [range(1, 4), "1,2,3", "1, 2, 3"]:
874
      data = {
875
        "mode": constants.REPLACE_DISK_SEC,
876
        "disks": disks,
877
        "iallocator": "myalloc",
878
        }
879

    
880
      handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
881
                               [name], {}, data, clfactory)
882
      job_id = handler.POST()
883

    
884
      cl = clfactory.GetNextClient()
885
      self.assertRaises(IndexError, clfactory.GetNextClient)
886

    
887
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
888
      self.assertEqual(job_id, exp_job_id)
889

    
890
      self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
891
      self.assertEqual(op.instance_name, name)
892
      self.assertEqual(op.mode, constants.REPLACE_DISK_SEC)
893
      self.assertEqual(op.disks, [1, 2, 3])
894
      self.assertEqual(op.iallocator, "myalloc")
895
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
896

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

    
900
    name = "inst11413"
901
    data = {
902
      "mode": constants.REPLACE_DISK_AUTO,
903
      }
904

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

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

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

    
915
    self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
916
    self.assertEqual(op.instance_name, name)
917
    self.assertEqual(op.mode, constants.REPLACE_DISK_AUTO)
918
    self.assertFalse(hasattr(op, "iallocator"))
919
    self.assertFalse(hasattr(op, "disks"))
920
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
921

    
922
  def testWrong(self):
923
    clfactory = _FakeClientFactory(_FakeClient)
924

    
925
    data = {
926
      "mode": constants.REPLACE_DISK_AUTO,
927
      "disks": "hello world",
928
      }
929

    
930
    handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
931
                             ["foo"], {}, data, clfactory)
932
    self.assertRaises(http.HttpBadRequest, handler.POST)
933

    
934

    
935
class TestGroupModify(unittest.TestCase):
936
  def test(self):
937
    clfactory = _FakeClientFactory(_FakeClient)
938

    
939
    name = "group6002"
940

    
941
    for policy in constants.VALID_ALLOC_POLICIES:
942
      data = {
943
        "alloc_policy": policy,
944
        }
945

    
946
      handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, data,
947
                               clfactory)
948
      job_id = handler.PUT()
949

    
950
      cl = clfactory.GetNextClient()
951
      self.assertRaises(IndexError, clfactory.GetNextClient)
952

    
953
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
954
      self.assertEqual(job_id, exp_job_id)
955

    
956
      self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
957
      self.assertEqual(op.group_name, name)
958
      self.assertEqual(op.alloc_policy, policy)
959
      self.assertFalse(hasattr(op, "dry_run"))
960
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
961

    
962
  def testUnknownPolicy(self):
963
    clfactory = _FakeClientFactory(_FakeClient)
964

    
965
    data = {
966
      "alloc_policy": "_unknown_policy_",
967
      }
968

    
969
    handler = _CreateHandler(rlib2.R_2_groups_name_modify, ["xyz"], {}, data,
970
                             clfactory)
971
    self.assertRaises(http.HttpBadRequest, handler.PUT)
972
    self.assertRaises(IndexError, clfactory.GetNextClient)
973

    
974
  def testDefaults(self):
975
    clfactory = _FakeClientFactory(_FakeClient)
976

    
977
    name = "group6679"
978

    
979
    handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, {},
980
                             clfactory)
981
    job_id = handler.PUT()
982

    
983
    cl = clfactory.GetNextClient()
984
    self.assertRaises(IndexError, clfactory.GetNextClient)
985

    
986
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
987
    self.assertEqual(job_id, exp_job_id)
988

    
989
    self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
990
    self.assertEqual(op.group_name, name)
991
    self.assertFalse(hasattr(op, "alloc_policy"))
992
    self.assertFalse(hasattr(op, "dry_run"))
993
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
994

    
995

    
996
class TestGroupAdd(unittest.TestCase):
997
  def test(self):
998
    name = "group3618"
999
    clfactory = _FakeClientFactory(_FakeClient)
1000

    
1001
    for policy in constants.VALID_ALLOC_POLICIES:
1002
      data = {
1003
        "group_name": name,
1004
        "alloc_policy": policy,
1005
        }
1006

    
1007
      handler = _CreateHandler(rlib2.R_2_groups, [], {}, data,
1008
                               clfactory)
1009
      job_id = handler.POST()
1010

    
1011
      cl = clfactory.GetNextClient()
1012
      self.assertRaises(IndexError, clfactory.GetNextClient)
1013

    
1014
      (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1015
      self.assertEqual(job_id, exp_job_id)
1016

    
1017
      self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1018
      self.assertEqual(op.group_name, name)
1019
      self.assertEqual(op.alloc_policy, policy)
1020
      self.assertFalse(op.dry_run)
1021
      self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1022

    
1023
  def testUnknownPolicy(self):
1024
    clfactory = _FakeClientFactory(_FakeClient)
1025

    
1026
    data = {
1027
      "alloc_policy": "_unknown_policy_",
1028
      }
1029

    
1030
    handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1031
    self.assertRaises(http.HttpBadRequest, handler.POST)
1032
    self.assertRaises(IndexError, clfactory.GetNextClient)
1033

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

    
1037
    name = "group15395"
1038
    data = {
1039
      "group_name": name,
1040
      }
1041

    
1042
    handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1043
    job_id = handler.POST()
1044

    
1045
    cl = clfactory.GetNextClient()
1046
    self.assertRaises(IndexError, clfactory.GetNextClient)
1047

    
1048
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1049
    self.assertEqual(job_id, exp_job_id)
1050

    
1051
    self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1052
    self.assertEqual(op.group_name, name)
1053
    self.assertFalse(hasattr(op, "alloc_policy"))
1054
    self.assertFalse(op.dry_run)
1055

    
1056
  def testLegacyName(self):
1057
    clfactory = _FakeClientFactory(_FakeClient)
1058

    
1059
    name = "group29852"
1060
    data = {
1061
      "name": name,
1062
      }
1063

    
1064
    handler = _CreateHandler(rlib2.R_2_groups, [], {
1065
      "dry-run": ["1"],
1066
      }, data, clfactory)
1067
    job_id = handler.POST()
1068

    
1069
    cl = clfactory.GetNextClient()
1070
    self.assertRaises(IndexError, clfactory.GetNextClient)
1071

    
1072
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1073
    self.assertEqual(job_id, exp_job_id)
1074

    
1075
    self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1076
    self.assertEqual(op.group_name, name)
1077
    self.assertFalse(hasattr(op, "alloc_policy"))
1078
    self.assertTrue(op.dry_run)
1079

    
1080

    
1081
if __name__ == '__main__':
1082
  testutils.GanetiTestProgram()