4 # Copyright (C) 2010 Google Inc.
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.
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.
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
22 """Script for unittesting the RAPI rlib2 module
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
39 from ganeti.rapi import rlib2
44 class _FakeRequestPrivateData:
45 def __init__(self, body_data):
46 self.body_data = body_data
50 def __init__(self, body_data):
51 self.private = _FakeRequestPrivateData(body_data)
54 def _CreateHandler(cls, items, queryargs, body_data, client_cls):
55 return cls(items, queryargs, _FakeRequest(body_data),
56 _client_cls=client_cls)
63 def GetNextSubmittedJob(self):
64 return self._jobs.pop(0)
66 def SubmitJob(self, ops):
67 job_id = str(1 + int(random.random() * 1000000))
68 self._jobs.append((job_id, ops))
72 class _FakeClientFactory:
73 def __init__(self, cls):
74 self._client_cls = cls
77 def GetNextClient(self):
78 return self._clients.pop(0)
81 cl = self._client_cls()
82 self._clients.append(cl)
86 class TestConstants(unittest.TestCase):
87 def testConsole(self):
88 # Exporting the console field without authentication might expose
90 assert "console" in query.INSTANCE_FIELDS
91 self.assertTrue("console" not in rlib2.I_FIELDS)
95 constants.QR_INSTANCE: rlib2.I_FIELDS,
96 constants.QR_NODE: rlib2.N_FIELDS,
97 constants.QR_GROUP: rlib2.G_FIELDS,
100 for (qr, fields) in checks.items():
101 self.assertFalse(set(fields) - set(query.ALL_FIELDS[qr].keys()))
104 class TestClientConnectError(unittest.TestCase):
106 def _FailingClient():
107 raise luxi.NoMasterError("test")
115 for cls in resources:
116 handler = _CreateHandler(cls, ["name"], [], None, self._FailingClient)
117 self.assertRaises(http.HttpBadGateway, handler.GET)
120 class TestJobSubmitError(unittest.TestCase):
121 class _SubmitErrorClient:
124 raise errors.JobQueueFull("test")
127 handler = _CreateHandler(rlib2.R_2_redist_config, [], [], None,
128 self._SubmitErrorClient)
129 self.assertRaises(http.HttpServiceUnavailable, handler.PUT)
132 class TestClusterModify(unittest.TestCase):
134 clfactory = _FakeClientFactory(_FakeClient)
135 handler = _CreateHandler(rlib2.R_2_cluster_modify, [], [], {
137 "candidate_pool_size": 100,
139 job_id = handler.PUT()
141 cl = clfactory.GetNextClient()
142 self.assertRaises(IndexError, clfactory.GetNextClient)
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)
150 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
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, [], [], {
158 self.assertRaises(http.HttpBadRequest, handler.PUT)
159 self.assertRaises(IndexError, clfactory.GetNextClient)
162 class TestRedistConfig(unittest.TestCase):
164 clfactory = _FakeClientFactory(_FakeClient)
165 handler = _CreateHandler(rlib2.R_2_redist_config, [], [], None, clfactory)
166 job_id = handler.PUT()
168 cl = clfactory.GetNextClient()
169 self.assertRaises(IndexError, clfactory.GetNextClient)
171 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
172 self.assertEqual(job_id, exp_job_id)
173 self.assertTrue(isinstance(op, opcodes.OpClusterRedistConf))
175 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
178 class TestNodeMigrate(unittest.TestCase):
180 clfactory = _FakeClientFactory(_FakeClient)
181 handler = _CreateHandler(rlib2.R_2_nodes_name_migrate, ["node1"], {}, {
182 "iallocator": "fooalloc",
184 job_id = handler.POST()
186 cl = clfactory.GetNextClient()
187 self.assertRaises(IndexError, clfactory.GetNextClient)
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")
195 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
197 def testQueryArgsConflict(self):
198 clfactory = _FakeClientFactory(_FakeClient)
199 handler = _CreateHandler(rlib2.R_2_nodes_name_migrate, ["node2"], {
201 "mode": constants.HT_MIGRATION_NONLIVE,
203 self.assertRaises(http.HttpBadRequest, handler.POST)
204 self.assertRaises(IndexError, clfactory.GetNextClient)
206 def testQueryArgsMode(self):
207 clfactory = _FakeClientFactory(_FakeClient)
209 "mode": [constants.HT_MIGRATION_LIVE],
211 handler = _CreateHandler(rlib2.R_2_nodes_name_migrate, ["node17292"],
212 queryargs, None, clfactory)
213 job_id = handler.POST()
215 cl = clfactory.GetNextClient()
216 self.assertRaises(IndexError, clfactory.GetNextClient)
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)
224 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
226 def testQueryArgsLive(self):
227 clfactory = _FakeClientFactory(_FakeClient)
229 for live in [False, True]:
231 "live": [str(int(live))],
233 handler = _CreateHandler(rlib2.R_2_nodes_name_migrate, ["node6940"],
234 queryargs, None, clfactory)
235 job_id = handler.POST()
237 cl = clfactory.GetNextClient()
238 self.assertRaises(IndexError, clfactory.GetNextClient)
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")
245 self.assertEqual(op.mode, constants.HT_MIGRATION_LIVE)
247 self.assertEqual(op.mode, constants.HT_MIGRATION_NONLIVE)
249 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
252 class TestNodeEvacuate(unittest.TestCase):
254 clfactory = _FakeClientFactory(_FakeClient)
255 handler = _CreateHandler(rlib2.R_2_nodes_name_evacuate, ["node92"], {
258 "mode": constants.IALLOCATOR_NEVAC_SEC,
260 job_id = handler.POST()
262 cl = clfactory.GetNextClient()
263 self.assertRaises(IndexError, clfactory.GetNextClient)
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)
272 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
275 class TestGroupAssignNodes(unittest.TestCase):
277 clfactory = _FakeClientFactory(_FakeClient)
278 handler = _CreateHandler(rlib2.R_2_groups_name_assign_nodes, ["grp-a"], {
282 "nodes": ["n2", "n3"],
284 job_id = handler.PUT()
286 cl = clfactory.GetNextClient()
287 self.assertRaises(IndexError, clfactory.GetNextClient)
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)
297 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
300 class TestInstanceDelete(unittest.TestCase):
302 clfactory = _FakeClientFactory(_FakeClient)
303 handler = _CreateHandler(rlib2.R_2_instances_name, ["inst30965"], {
306 job_id = handler.DELETE()
308 cl = clfactory.GetNextClient()
309 self.assertRaises(IndexError, clfactory.GetNextClient)
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)
318 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
321 class TestInstanceInfo(unittest.TestCase):
323 clfactory = _FakeClientFactory(_FakeClient)
324 handler = _CreateHandler(rlib2.R_2_instances_name_info, ["inst31217"], {
327 job_id = handler.GET()
329 cl = clfactory.GetNextClient()
330 self.assertRaises(IndexError, clfactory.GetNextClient)
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)
338 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
341 class TestInstanceReboot(unittest.TestCase):
343 clfactory = _FakeClientFactory(_FakeClient)
344 handler = _CreateHandler(rlib2.R_2_instances_name_reboot, ["inst847"], {
346 "ignore_secondaries": ["1"],
348 job_id = handler.POST()
350 cl = clfactory.GetNextClient()
351 self.assertRaises(IndexError, clfactory.GetNextClient)
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)
361 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
364 class TestInstanceStartup(unittest.TestCase):
366 clfactory = _FakeClientFactory(_FakeClient)
367 handler = _CreateHandler(rlib2.R_2_instances_name_startup, ["inst31083"], {
369 "no_remember": ["1"],
371 job_id = handler.PUT()
373 cl = clfactory.GetNextClient()
374 self.assertRaises(IndexError, clfactory.GetNextClient)
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)
384 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
387 class TestInstanceShutdown(unittest.TestCase):
389 clfactory = _FakeClientFactory(_FakeClient)
390 handler = _CreateHandler(rlib2.R_2_instances_name_shutdown, ["inst26791"], {
391 "no_remember": ["0"],
393 job_id = handler.PUT()
395 cl = clfactory.GetNextClient()
396 self.assertRaises(IndexError, clfactory.GetNextClient)
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)
405 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
408 class TestInstanceActivateDisks(unittest.TestCase):
410 clfactory = _FakeClientFactory(_FakeClient)
411 handler = _CreateHandler(rlib2.R_2_instances_name_activate_disks, ["xyz"], {
412 "ignore_size": ["1"],
414 job_id = handler.PUT()
416 cl = clfactory.GetNextClient()
417 self.assertRaises(IndexError, clfactory.GetNextClient)
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"))
426 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
429 class TestInstanceDeactivateDisks(unittest.TestCase):
431 clfactory = _FakeClientFactory(_FakeClient)
432 handler = _CreateHandler(rlib2.R_2_instances_name_deactivate_disks,
433 ["inst22357"], {}, {}, clfactory)
434 job_id = handler.PUT()
436 cl = clfactory.GetNextClient()
437 self.assertRaises(IndexError, clfactory.GetNextClient)
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"))
446 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
449 class TestInstanceFailover(unittest.TestCase):
451 clfactory = _FakeClientFactory(_FakeClient)
452 handler = _CreateHandler(rlib2.R_2_instances_name_failover,
453 ["inst12794"], {}, {}, clfactory)
454 job_id = handler.PUT()
456 cl = clfactory.GetNextClient()
457 self.assertRaises(IndexError, clfactory.GetNextClient)
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"))
466 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
469 class TestInstanceDiskGrow(unittest.TestCase):
471 clfactory = _FakeClientFactory(_FakeClient)
475 handler = _CreateHandler(rlib2.R_2_instances_name_disk_grow,
476 ["inst10742", "3"], {}, data, clfactory)
477 job_id = handler.POST()
479 cl = clfactory.GetNextClient()
480 self.assertRaises(IndexError, clfactory.GetNextClient)
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"))
491 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
494 class TestBackupPrepare(unittest.TestCase):
496 clfactory = _FakeClientFactory(_FakeClient)
498 "mode": constants.EXPORT_MODE_REMOTE,
500 handler = _CreateHandler(rlib2.R_2_instances_name_prepare_export,
501 ["inst17925"], queryargs, {}, clfactory)
502 job_id = handler.PUT()
504 cl = clfactory.GetNextClient()
505 self.assertRaises(IndexError, clfactory.GetNextClient)
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"))
515 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
518 class TestGroupRemove(unittest.TestCase):
520 clfactory = _FakeClientFactory(_FakeClient)
521 handler = _CreateHandler(rlib2.R_2_groups_name,
522 ["grp28575"], {}, {}, clfactory)
523 job_id = handler.DELETE()
525 cl = clfactory.GetNextClient()
526 self.assertRaises(IndexError, clfactory.GetNextClient)
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"))
535 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
538 class TestParseInstanceCreateRequestVersion1(testutils.GanetiTestCase):
540 testutils.GanetiTestCase.setUp(self)
542 self.Parse = rlib2._ParseInstanceCreateRequestVersion1
550 [{"size": 5, }, {"size": 100, }],
553 [{"size": 123, "mode": constants.DISK_RDWR, }],
565 { "ip": "192.0.2.6", "mode": constants.NIC_MODE_ROUTED,
566 "mac": "01:23:45:67:68:9A",
568 { "mode": constants.NIC_MODE_BRIDGED, "link": "br1" },
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, }
584 { constants.HV_BOOT_ORDER: "anc", },
585 { constants.HV_KERNEL_PATH: "/boot/fookernel",
586 constants.HV_ROOT_PATH: "/dev/hda1", },
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:
596 "name": "inst1.example.com",
597 "hypervisor": constants.HT_FAKE,
601 "disk_template": disk_template,
605 if beparams is not None:
606 data["beparams"] = beparams
608 if hvparams is not None:
609 data["hvparams"] = hvparams
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))
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)
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)
632 self.assertFalse(hasattr(op, "beparams"))
634 self.assertEqualValues(op.beparams, beparams)
637 self.assertFalse(hasattr(op, "hvparams"))
639 self.assertEqualValues(op.hvparams, hvparams)
641 def testLegacyName(self):
642 name = "inst29128.example.com"
647 "mode": constants.INSTANCE_CREATE,
648 "disk_template": constants.DT_PLAIN,
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"))
658 "instance_name": "other.example.com",
661 "mode": constants.INSTANCE_CREATE,
662 "disk_template": constants.DT_PLAIN,
664 self.assertRaises(http.HttpBadRequest, self.Parse, data, False)
666 def testLegacyOs(self):
667 name = "inst4673.example.com"
674 "mode": constants.INSTANCE_CREATE,
675 "disk_template": constants.DT_PLAIN,
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"))
685 "instance_name": name,
687 "os_type": "linux9584",
690 "mode": constants.INSTANCE_CREATE,
691 "disk_template": constants.DT_PLAIN,
693 self.assertRaises(http.HttpBadRequest, self.Parse, data, False)
695 def testErrors(self):
696 # Test all required fields
698 "name": "inst1.example.com",
701 "mode": constants.INSTANCE_CREATE,
702 "disk_template": constants.DT_PLAIN,
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),
710 # Invalid disks and nics
711 for field in ["disks", "nics"]:
712 invalid_values = [None, 1, "", {}, [1, 2, 3], ["hda1", "hda2"],
713 [{"_unknown_": 999, }]]
715 for invvalue in invalid_values:
716 data = reqfields.copy()
717 data[field] = invvalue
718 self.assertRaises(http.HttpBadRequest, self.Parse, data, False)
721 class TestBackupExport(unittest.TestCase):
723 clfactory = _FakeClientFactory(_FakeClient)
727 "mode": constants.EXPORT_MODE_REMOTE,
728 "destination": [(1, 2, 3), (99, 99, 99)],
730 "remove_instance": True,
731 "x509_key_name": ["name", "hash"],
732 "destination_x509_ca": "---cert---"
735 handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
737 job_id = handler.PUT()
739 cl = clfactory.GetNextClient()
740 self.assertRaises(IndexError, clfactory.GetNextClient)
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"))
755 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
757 def testDefaults(self):
758 clfactory = _FakeClientFactory(_FakeClient)
762 "destination": "node2",
766 handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
768 job_id = handler.PUT()
770 cl = clfactory.GetNextClient()
771 self.assertRaises(IndexError, clfactory.GetNextClient)
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"))
784 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
786 def testErrors(self):
787 clfactory = _FakeClientFactory(_FakeClient)
789 for value in ["True", "False"]:
790 handler = _CreateHandler(rlib2.R_2_instances_name_export, ["err1"], {}, {
791 "remove_instance": value,
793 self.assertRaises(http.HttpBadRequest, handler.PUT)
796 class TestInstanceMigrate(testutils.GanetiTestCase):
798 clfactory = _FakeClientFactory(_FakeClient)
800 name = "instYooho6ek"
802 for cleanup in [False, True]:
803 for mode in constants.HT_MIGRATION_MODES:
809 handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {},
811 job_id = handler.PUT()
813 cl = clfactory.GetNextClient()
814 self.assertRaises(IndexError, clfactory.GetNextClient)
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"))
825 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
827 def testDefaults(self):
828 clfactory = _FakeClientFactory(_FakeClient)
830 name = "instnohZeex0"
832 handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {}, {},
834 job_id = handler.PUT()
836 cl = clfactory.GetNextClient()
837 self.assertRaises(IndexError, clfactory.GetNextClient)
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"))
848 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
851 class TestParseRenameInstanceRequest(testutils.GanetiTestCase):
853 clfactory = _FakeClientFactory(_FakeClient)
855 name = "instij0eeph7"
857 for new_name in ["ua0aiyoo", "fai3ongi"]:
858 for ip_check in [False, True]:
859 for name_check in [False, True]:
861 "new_name": new_name,
862 "ip_check": ip_check,
863 "name_check": name_check,
866 handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
868 job_id = handler.PUT()
870 cl = clfactory.GetNextClient()
871 self.assertRaises(IndexError, clfactory.GetNextClient)
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"))
883 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
885 def testDefaults(self):
886 clfactory = _FakeClientFactory(_FakeClient)
888 name = "instahchie3t"
890 for new_name in ["thag9mek", "quees7oh"]:
892 "new_name": new_name,
895 handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
897 job_id = handler.PUT()
899 cl = clfactory.GetNextClient()
900 self.assertRaises(IndexError, clfactory.GetNextClient)
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"))
912 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
915 class TestParseModifyInstanceRequest(unittest.TestCase):
917 clfactory = _FakeClientFactory(_FakeClient)
923 [(1, { constants.IDISK_MODE: constants.DISK_RDWR, })],
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:
934 "osparams": osparams,
935 "hvparams": hvparams,
936 "beparams": beparams,
940 "disk_template": disk_template,
943 handler = _CreateHandler(rlib2.R_2_instances_name_modify,
944 [name], {}, data, clfactory)
945 job_id = handler.PUT()
947 cl = clfactory.GetNextClient()
948 self.assertRaises(IndexError, clfactory.GetNextClient)
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"))
966 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
968 def testDefaults(self):
969 clfactory = _FakeClientFactory(_FakeClient)
971 name = "instir8aish31"
973 handler = _CreateHandler(rlib2.R_2_instances_name_modify,
974 [name], {}, {}, clfactory)
975 job_id = handler.PUT()
977 cl = clfactory.GetNextClient()
978 self.assertRaises(IndexError, clfactory.GetNextClient)
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)
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))
990 class TestParseInstanceReinstallRequest(testutils.GanetiTestCase):
992 testutils.GanetiTestCase.setUp(self)
994 self.Parse = rlib2._ParseInstanceReinstallRequest
996 def _Check(self, ops, name):
998 opcodes.OpInstanceShutdown,
999 opcodes.OpInstanceReinstall,
1000 opcodes.OpInstanceStartup,
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))
1008 name = "shoo0tihohma"
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)
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")
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)
1031 def testDefaults(self):
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)
1041 class TestGroupRename(unittest.TestCase):
1043 clfactory = _FakeClientFactory(_FakeClient)
1045 name = "group608242564"
1047 "new_name": "ua0aiyoo15112",
1050 handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {}, data,
1052 job_id = handler.PUT()
1054 cl = clfactory.GetNextClient()
1055 self.assertRaises(IndexError, clfactory.GetNextClient)
1057 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1058 self.assertEqual(job_id, exp_job_id)
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)
1066 def testDryRun(self):
1067 clfactory = _FakeClientFactory(_FakeClient)
1071 "new_name": "ua0aiyoo",
1074 handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {
1077 job_id = handler.PUT()
1079 cl = clfactory.GetNextClient()
1080 self.assertRaises(IndexError, clfactory.GetNextClient)
1082 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1083 self.assertEqual(job_id, exp_job_id)
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)
1092 class TestInstanceReplaceDisks(unittest.TestCase):
1094 clfactory = _FakeClientFactory(_FakeClient)
1098 for disks in [range(1, 4), "1,2,3", "1, 2, 3"]:
1100 "mode": constants.REPLACE_DISK_SEC,
1102 "iallocator": "myalloc",
1105 handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1106 [name], {}, data, clfactory)
1107 job_id = handler.POST()
1109 cl = clfactory.GetNextClient()
1110 self.assertRaises(IndexError, clfactory.GetNextClient)
1112 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1113 self.assertEqual(job_id, exp_job_id)
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)
1122 def testDefaults(self):
1123 clfactory = _FakeClientFactory(_FakeClient)
1127 "mode": constants.REPLACE_DISK_AUTO,
1130 handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1131 [name], {}, data, clfactory)
1132 job_id = handler.POST()
1134 cl = clfactory.GetNextClient()
1135 self.assertRaises(IndexError, clfactory.GetNextClient)
1137 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1138 self.assertEqual(job_id, exp_job_id)
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)
1147 def testWrong(self):
1148 clfactory = _FakeClientFactory(_FakeClient)
1151 "mode": constants.REPLACE_DISK_AUTO,
1152 "disks": "hello world",
1155 handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1156 ["foo"], {}, data, clfactory)
1157 self.assertRaises(http.HttpBadRequest, handler.POST)
1160 class TestGroupModify(unittest.TestCase):
1162 clfactory = _FakeClientFactory(_FakeClient)
1166 for policy in constants.VALID_ALLOC_POLICIES:
1168 "alloc_policy": policy,
1171 handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, data,
1173 job_id = handler.PUT()
1175 cl = clfactory.GetNextClient()
1176 self.assertRaises(IndexError, clfactory.GetNextClient)
1178 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1179 self.assertEqual(job_id, exp_job_id)
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)
1187 def testUnknownPolicy(self):
1188 clfactory = _FakeClientFactory(_FakeClient)
1191 "alloc_policy": "_unknown_policy_",
1194 handler = _CreateHandler(rlib2.R_2_groups_name_modify, ["xyz"], {}, data,
1196 self.assertRaises(http.HttpBadRequest, handler.PUT)
1197 self.assertRaises(IndexError, clfactory.GetNextClient)
1199 def testDefaults(self):
1200 clfactory = _FakeClientFactory(_FakeClient)
1204 handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, {},
1206 job_id = handler.PUT()
1208 cl = clfactory.GetNextClient()
1209 self.assertRaises(IndexError, clfactory.GetNextClient)
1211 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1212 self.assertEqual(job_id, exp_job_id)
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)
1221 class TestGroupAdd(unittest.TestCase):
1224 clfactory = _FakeClientFactory(_FakeClient)
1226 for policy in constants.VALID_ALLOC_POLICIES:
1229 "alloc_policy": policy,
1232 handler = _CreateHandler(rlib2.R_2_groups, [], {}, data,
1234 job_id = handler.POST()
1236 cl = clfactory.GetNextClient()
1237 self.assertRaises(IndexError, clfactory.GetNextClient)
1239 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1240 self.assertEqual(job_id, exp_job_id)
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)
1248 def testUnknownPolicy(self):
1249 clfactory = _FakeClientFactory(_FakeClient)
1252 "alloc_policy": "_unknown_policy_",
1255 handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1256 self.assertRaises(http.HttpBadRequest, handler.POST)
1257 self.assertRaises(IndexError, clfactory.GetNextClient)
1259 def testDefaults(self):
1260 clfactory = _FakeClientFactory(_FakeClient)
1267 handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1268 job_id = handler.POST()
1270 cl = clfactory.GetNextClient()
1271 self.assertRaises(IndexError, clfactory.GetNextClient)
1273 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1274 self.assertEqual(job_id, exp_job_id)
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)
1281 def testLegacyName(self):
1282 clfactory = _FakeClientFactory(_FakeClient)
1289 handler = _CreateHandler(rlib2.R_2_groups, [], {
1292 job_id = handler.POST()
1294 cl = clfactory.GetNextClient()
1295 self.assertRaises(IndexError, clfactory.GetNextClient)
1297 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1298 self.assertEqual(job_id, exp_job_id)
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)
1306 class TestNodeRole(unittest.TestCase):
1308 clfactory = _FakeClientFactory(_FakeClient)
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)
1316 job_id = handler.PUT()
1318 cl = clfactory.GetNextClient()
1319 self.assertRaises(IndexError, clfactory.GetNextClient)
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"))
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)
1345 self.fail("Unknown role '%s'" % role)
1347 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1350 if __name__ == '__main__':
1351 testutils.GanetiTestProgram()