4 # Copyright (C) 2010, 2012 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
38 from ganeti import rapi
40 from ganeti.rapi import rlib2
41 from ganeti.rapi import baserlib
42 from ganeti.rapi import connector
47 class _FakeRequestPrivateData:
48 def __init__(self, body_data):
49 self.body_data = body_data
53 def __init__(self, body_data):
54 self.private = _FakeRequestPrivateData(body_data)
57 def _CreateHandler(cls, items, queryargs, body_data, client_cls):
58 return cls(items, queryargs, _FakeRequest(body_data),
59 _client_cls=client_cls)
63 def __init__(self, address=None):
66 def GetNextSubmittedJob(self):
67 return self._jobs.pop(0)
69 def SubmitJob(self, ops):
70 job_id = str(1 + int(random.random() * 1000000))
71 self._jobs.append((job_id, ops))
75 class _FakeClientFactory:
76 def __init__(self, cls):
77 self._client_cls = cls
80 def GetNextClient(self):
81 return self._clients.pop(0)
83 def __call__(self, address=None):
84 cl = self._client_cls(address=address)
85 self._clients.append(cl)
89 class TestConstants(unittest.TestCase):
90 def testConsole(self):
91 # Exporting the console field without authentication might expose
93 assert "console" in query.INSTANCE_FIELDS
94 self.assertTrue("console" not in rlib2.I_FIELDS)
98 constants.QR_INSTANCE: rlib2.I_FIELDS,
99 constants.QR_NODE: rlib2.N_FIELDS,
100 constants.QR_GROUP: rlib2.G_FIELDS,
103 for (qr, fields) in checks.items():
104 self.assertFalse(set(fields) - set(query.ALL_FIELDS[qr].keys()))
107 class TestClientConnectError(unittest.TestCase):
109 def _FailingClient(address=None):
110 raise luxi.NoMasterError("test")
118 for cls in resources:
119 handler = _CreateHandler(cls, ["name"], [], None, self._FailingClient)
120 self.assertRaises(http.HttpBadGateway, handler.GET)
123 class TestJobSubmitError(unittest.TestCase):
124 class _SubmitErrorClient:
125 def __init__(self, address=None):
130 raise errors.JobQueueFull("test")
133 handler = _CreateHandler(rlib2.R_2_redist_config, [], [], None,
134 self._SubmitErrorClient)
135 self.assertRaises(http.HttpServiceUnavailable, handler.PUT)
138 class TestClusterModify(unittest.TestCase):
140 clfactory = _FakeClientFactory(_FakeClient)
141 handler = _CreateHandler(rlib2.R_2_cluster_modify, [], [], {
143 "candidate_pool_size": 100,
145 job_id = handler.PUT()
147 cl = clfactory.GetNextClient()
148 self.assertRaises(IndexError, clfactory.GetNextClient)
150 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
151 self.assertEqual(job_id, exp_job_id)
152 self.assertTrue(isinstance(op, opcodes.OpClusterSetParams))
153 self.assertEqual(op.vg_name, "testvg")
154 self.assertEqual(op.candidate_pool_size, 100)
156 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
158 def testInvalidValue(self):
159 for attr in ["vg_name", "candidate_pool_size", "beparams", "_-Unknown#"]:
160 clfactory = _FakeClientFactory(_FakeClient)
161 handler = _CreateHandler(rlib2.R_2_cluster_modify, [], [], {
164 self.assertRaises(http.HttpBadRequest, handler.PUT)
165 self.assertRaises(IndexError, clfactory.GetNextClient)
168 class TestRedistConfig(unittest.TestCase):
170 clfactory = _FakeClientFactory(_FakeClient)
171 handler = _CreateHandler(rlib2.R_2_redist_config, [], [], None, clfactory)
172 job_id = handler.PUT()
174 cl = clfactory.GetNextClient()
175 self.assertRaises(IndexError, clfactory.GetNextClient)
177 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
178 self.assertEqual(job_id, exp_job_id)
179 self.assertTrue(isinstance(op, opcodes.OpClusterRedistConf))
181 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
184 class TestNodeMigrate(unittest.TestCase):
186 clfactory = _FakeClientFactory(_FakeClient)
187 handler = _CreateHandler(rlib2.R_2_nodes_name_migrate, ["node1"], {}, {
188 "iallocator": "fooalloc",
190 job_id = handler.POST()
192 cl = clfactory.GetNextClient()
193 self.assertRaises(IndexError, clfactory.GetNextClient)
195 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
196 self.assertEqual(job_id, exp_job_id)
197 self.assertTrue(isinstance(op, opcodes.OpNodeMigrate))
198 self.assertEqual(op.node_name, "node1")
199 self.assertEqual(op.iallocator, "fooalloc")
201 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
203 def testQueryArgsConflict(self):
204 clfactory = _FakeClientFactory(_FakeClient)
205 handler = _CreateHandler(rlib2.R_2_nodes_name_migrate, ["node2"], {
207 "mode": constants.HT_MIGRATION_NONLIVE,
209 self.assertRaises(http.HttpBadRequest, handler.POST)
210 self.assertRaises(IndexError, clfactory.GetNextClient)
212 def testQueryArgsMode(self):
213 clfactory = _FakeClientFactory(_FakeClient)
215 "mode": [constants.HT_MIGRATION_LIVE],
217 handler = _CreateHandler(rlib2.R_2_nodes_name_migrate, ["node17292"],
218 queryargs, None, clfactory)
219 job_id = handler.POST()
221 cl = clfactory.GetNextClient()
222 self.assertRaises(IndexError, clfactory.GetNextClient)
224 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
225 self.assertEqual(job_id, exp_job_id)
226 self.assertTrue(isinstance(op, opcodes.OpNodeMigrate))
227 self.assertEqual(op.node_name, "node17292")
228 self.assertEqual(op.mode, constants.HT_MIGRATION_LIVE)
230 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
232 def testQueryArgsLive(self):
233 clfactory = _FakeClientFactory(_FakeClient)
235 for live in [False, True]:
237 "live": [str(int(live))],
239 handler = _CreateHandler(rlib2.R_2_nodes_name_migrate, ["node6940"],
240 queryargs, None, clfactory)
241 job_id = handler.POST()
243 cl = clfactory.GetNextClient()
244 self.assertRaises(IndexError, clfactory.GetNextClient)
246 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
247 self.assertEqual(job_id, exp_job_id)
248 self.assertTrue(isinstance(op, opcodes.OpNodeMigrate))
249 self.assertEqual(op.node_name, "node6940")
251 self.assertEqual(op.mode, constants.HT_MIGRATION_LIVE)
253 self.assertEqual(op.mode, constants.HT_MIGRATION_NONLIVE)
255 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
258 class TestNodeEvacuate(unittest.TestCase):
260 clfactory = _FakeClientFactory(_FakeClient)
261 handler = _CreateHandler(rlib2.R_2_nodes_name_evacuate, ["node92"], {
264 "mode": constants.IALLOCATOR_NEVAC_SEC,
266 job_id = handler.POST()
268 cl = clfactory.GetNextClient()
269 self.assertRaises(IndexError, clfactory.GetNextClient)
271 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
272 self.assertEqual(job_id, exp_job_id)
273 self.assertTrue(isinstance(op, opcodes.OpNodeEvacuate))
274 self.assertEqual(op.node_name, "node92")
275 self.assertEqual(op.mode, constants.IALLOCATOR_NEVAC_SEC)
276 self.assertTrue(op.dry_run)
278 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
281 class TestNodePowercycle(unittest.TestCase):
283 clfactory = _FakeClientFactory(_FakeClient)
284 handler = _CreateHandler(rlib2.R_2_nodes_name_powercycle, ["node20744"], {
287 job_id = handler.POST()
289 cl = clfactory.GetNextClient()
290 self.assertRaises(IndexError, clfactory.GetNextClient)
292 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
293 self.assertEqual(job_id, exp_job_id)
294 self.assertTrue(isinstance(op, opcodes.OpNodePowercycle))
295 self.assertEqual(op.node_name, "node20744")
296 self.assertTrue(op.force)
298 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
301 class TestGroupAssignNodes(unittest.TestCase):
303 clfactory = _FakeClientFactory(_FakeClient)
304 handler = _CreateHandler(rlib2.R_2_groups_name_assign_nodes, ["grp-a"], {
308 "nodes": ["n2", "n3"],
310 job_id = handler.PUT()
312 cl = clfactory.GetNextClient()
313 self.assertRaises(IndexError, clfactory.GetNextClient)
315 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
316 self.assertEqual(job_id, exp_job_id)
317 self.assertTrue(isinstance(op, opcodes.OpGroupAssignNodes))
318 self.assertEqual(op.group_name, "grp-a")
319 self.assertEqual(op.nodes, ["n2", "n3"])
320 self.assertTrue(op.dry_run)
321 self.assertTrue(op.force)
323 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
326 class TestInstanceDelete(unittest.TestCase):
328 clfactory = _FakeClientFactory(_FakeClient)
329 handler = _CreateHandler(rlib2.R_2_instances_name, ["inst30965"], {
332 job_id = handler.DELETE()
334 cl = clfactory.GetNextClient()
335 self.assertRaises(IndexError, clfactory.GetNextClient)
337 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
338 self.assertEqual(job_id, exp_job_id)
339 self.assertTrue(isinstance(op, opcodes.OpInstanceRemove))
340 self.assertEqual(op.instance_name, "inst30965")
341 self.assertTrue(op.dry_run)
342 self.assertFalse(op.ignore_failures)
344 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
347 class TestInstanceInfo(unittest.TestCase):
349 clfactory = _FakeClientFactory(_FakeClient)
350 handler = _CreateHandler(rlib2.R_2_instances_name_info, ["inst31217"], {
353 job_id = handler.GET()
355 cl = clfactory.GetNextClient()
356 self.assertRaises(IndexError, clfactory.GetNextClient)
358 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
359 self.assertEqual(job_id, exp_job_id)
360 self.assertTrue(isinstance(op, opcodes.OpInstanceQueryData))
361 self.assertEqual(op.instances, ["inst31217"])
362 self.assertTrue(op.static)
364 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
367 class TestInstanceReboot(unittest.TestCase):
369 clfactory = _FakeClientFactory(_FakeClient)
370 handler = _CreateHandler(rlib2.R_2_instances_name_reboot, ["inst847"], {
372 "ignore_secondaries": ["1"],
374 job_id = handler.POST()
376 cl = clfactory.GetNextClient()
377 self.assertRaises(IndexError, clfactory.GetNextClient)
379 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
380 self.assertEqual(job_id, exp_job_id)
381 self.assertTrue(isinstance(op, opcodes.OpInstanceReboot))
382 self.assertEqual(op.instance_name, "inst847")
383 self.assertEqual(op.reboot_type, constants.INSTANCE_REBOOT_HARD)
384 self.assertTrue(op.ignore_secondaries)
385 self.assertTrue(op.dry_run)
387 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
390 class TestInstanceStartup(unittest.TestCase):
392 clfactory = _FakeClientFactory(_FakeClient)
393 handler = _CreateHandler(rlib2.R_2_instances_name_startup, ["inst31083"], {
395 "no_remember": ["1"],
397 job_id = handler.PUT()
399 cl = clfactory.GetNextClient()
400 self.assertRaises(IndexError, clfactory.GetNextClient)
402 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
403 self.assertEqual(job_id, exp_job_id)
404 self.assertTrue(isinstance(op, opcodes.OpInstanceStartup))
405 self.assertEqual(op.instance_name, "inst31083")
406 self.assertTrue(op.no_remember)
407 self.assertTrue(op.force)
408 self.assertFalse(op.dry_run)
410 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
413 class TestInstanceShutdown(unittest.TestCase):
415 clfactory = _FakeClientFactory(_FakeClient)
416 handler = _CreateHandler(rlib2.R_2_instances_name_shutdown, ["inst26791"], {
417 "no_remember": ["0"],
419 job_id = handler.PUT()
421 cl = clfactory.GetNextClient()
422 self.assertRaises(IndexError, clfactory.GetNextClient)
424 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
425 self.assertEqual(job_id, exp_job_id)
426 self.assertTrue(isinstance(op, opcodes.OpInstanceShutdown))
427 self.assertEqual(op.instance_name, "inst26791")
428 self.assertFalse(op.no_remember)
429 self.assertFalse(op.dry_run)
431 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
434 class TestInstanceActivateDisks(unittest.TestCase):
436 clfactory = _FakeClientFactory(_FakeClient)
437 handler = _CreateHandler(rlib2.R_2_instances_name_activate_disks, ["xyz"], {
438 "ignore_size": ["1"],
440 job_id = handler.PUT()
442 cl = clfactory.GetNextClient()
443 self.assertRaises(IndexError, clfactory.GetNextClient)
445 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
446 self.assertEqual(job_id, exp_job_id)
447 self.assertTrue(isinstance(op, opcodes.OpInstanceActivateDisks))
448 self.assertEqual(op.instance_name, "xyz")
449 self.assertTrue(op.ignore_size)
450 self.assertFalse(hasattr(op, "dry_run"))
452 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
455 class TestInstanceDeactivateDisks(unittest.TestCase):
457 clfactory = _FakeClientFactory(_FakeClient)
458 handler = _CreateHandler(rlib2.R_2_instances_name_deactivate_disks,
459 ["inst22357"], {}, {}, clfactory)
460 job_id = handler.PUT()
462 cl = clfactory.GetNextClient()
463 self.assertRaises(IndexError, clfactory.GetNextClient)
465 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
466 self.assertEqual(job_id, exp_job_id)
467 self.assertTrue(isinstance(op, opcodes.OpInstanceDeactivateDisks))
468 self.assertEqual(op.instance_name, "inst22357")
469 self.assertFalse(hasattr(op, "dry_run"))
470 self.assertFalse(hasattr(op, "force"))
472 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
475 class TestInstanceRecreateDisks(unittest.TestCase):
477 clfactory = _FakeClientFactory(_FakeClient)
478 handler = _CreateHandler(rlib2.R_2_instances_name_recreate_disks,
479 ["inst22357"], {}, {}, clfactory)
480 job_id = handler.POST()
482 cl = clfactory.GetNextClient()
483 self.assertRaises(IndexError, clfactory.GetNextClient)
485 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
486 self.assertEqual(job_id, exp_job_id)
487 self.assertTrue(isinstance(op, opcodes.OpInstanceRecreateDisks))
488 self.assertEqual(op.instance_name, "inst22357")
489 self.assertFalse(hasattr(op, "dry_run"))
490 self.assertFalse(hasattr(op, "force"))
492 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
495 class TestInstanceFailover(unittest.TestCase):
497 clfactory = _FakeClientFactory(_FakeClient)
498 handler = _CreateHandler(rlib2.R_2_instances_name_failover,
499 ["inst12794"], {}, {}, clfactory)
500 job_id = handler.PUT()
502 cl = clfactory.GetNextClient()
503 self.assertRaises(IndexError, clfactory.GetNextClient)
505 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
506 self.assertEqual(job_id, exp_job_id)
507 self.assertTrue(isinstance(op, opcodes.OpInstanceFailover))
508 self.assertEqual(op.instance_name, "inst12794")
509 self.assertFalse(hasattr(op, "dry_run"))
510 self.assertFalse(hasattr(op, "force"))
512 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
515 class TestInstanceDiskGrow(unittest.TestCase):
517 clfactory = _FakeClientFactory(_FakeClient)
521 handler = _CreateHandler(rlib2.R_2_instances_name_disk_grow,
522 ["inst10742", "3"], {}, data, clfactory)
523 job_id = handler.POST()
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.OpInstanceGrowDisk))
531 self.assertEqual(op.instance_name, "inst10742")
532 self.assertEqual(op.disk, 3)
533 self.assertEqual(op.amount, 1024)
534 self.assertFalse(hasattr(op, "dry_run"))
535 self.assertFalse(hasattr(op, "force"))
537 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
540 class TestBackupPrepare(unittest.TestCase):
542 clfactory = _FakeClientFactory(_FakeClient)
544 "mode": constants.EXPORT_MODE_REMOTE,
546 handler = _CreateHandler(rlib2.R_2_instances_name_prepare_export,
547 ["inst17925"], queryargs, {}, clfactory)
548 job_id = handler.PUT()
550 cl = clfactory.GetNextClient()
551 self.assertRaises(IndexError, clfactory.GetNextClient)
553 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
554 self.assertEqual(job_id, exp_job_id)
555 self.assertTrue(isinstance(op, opcodes.OpBackupPrepare))
556 self.assertEqual(op.instance_name, "inst17925")
557 self.assertEqual(op.mode, constants.EXPORT_MODE_REMOTE)
558 self.assertFalse(hasattr(op, "dry_run"))
559 self.assertFalse(hasattr(op, "force"))
561 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
564 class TestGroupRemove(unittest.TestCase):
566 clfactory = _FakeClientFactory(_FakeClient)
567 handler = _CreateHandler(rlib2.R_2_groups_name,
568 ["grp28575"], {}, {}, clfactory)
569 job_id = handler.DELETE()
571 cl = clfactory.GetNextClient()
572 self.assertRaises(IndexError, clfactory.GetNextClient)
574 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
575 self.assertEqual(job_id, exp_job_id)
576 self.assertTrue(isinstance(op, opcodes.OpGroupRemove))
577 self.assertEqual(op.group_name, "grp28575")
578 self.assertFalse(op.dry_run)
579 self.assertFalse(hasattr(op, "force"))
581 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
584 class TestStorageQuery(unittest.TestCase):
586 clfactory = _FakeClientFactory(_FakeClient)
588 "storage_type": constants.ST_LVM_PV,
589 "output_fields": "name,other",
591 handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
592 ["node21075"], queryargs, {}, clfactory)
593 job_id = handler.GET()
595 cl = clfactory.GetNextClient()
596 self.assertRaises(IndexError, clfactory.GetNextClient)
598 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
599 self.assertEqual(job_id, exp_job_id)
600 self.assertTrue(isinstance(op, opcodes.OpNodeQueryStorage))
601 self.assertEqual(op.nodes, ["node21075"])
602 self.assertEqual(op.storage_type, constants.ST_LVM_PV)
603 self.assertEqual(op.output_fields, ["name", "other"])
604 self.assertFalse(hasattr(op, "dry_run"))
605 self.assertFalse(hasattr(op, "force"))
607 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
609 def testErrors(self):
610 clfactory = _FakeClientFactory(_FakeClient)
613 "output_fields": "name,other",
615 handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
616 ["node10538"], queryargs, {}, clfactory)
617 self.assertRaises(http.HttpBadRequest, handler.GET)
620 "storage_type": constants.ST_LVM_VG,
622 handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
623 ["node21273"], queryargs, {}, clfactory)
624 self.assertRaises(http.HttpBadRequest, handler.GET)
627 "storage_type": "##unknown_storage##",
628 "output_fields": "name,other",
630 handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
631 ["node10315"], queryargs, {}, clfactory)
632 self.assertRaises(http.HttpBadRequest, handler.GET)
635 class TestStorageModify(unittest.TestCase):
637 clfactory = _FakeClientFactory(_FakeClient)
639 for allocatable in [None, "1", "0"]:
641 "storage_type": constants.ST_LVM_VG,
645 if allocatable is not None:
646 queryargs["allocatable"] = allocatable
648 handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
649 ["node9292"], queryargs, {}, clfactory)
650 job_id = handler.PUT()
652 cl = clfactory.GetNextClient()
653 self.assertRaises(IndexError, clfactory.GetNextClient)
655 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
656 self.assertEqual(job_id, exp_job_id)
657 self.assertTrue(isinstance(op, opcodes.OpNodeModifyStorage))
658 self.assertEqual(op.node_name, "node9292")
659 self.assertEqual(op.storage_type, constants.ST_LVM_VG)
660 self.assertEqual(op.name, "pv-a")
661 if allocatable is None:
662 self.assertFalse(op.changes)
664 assert allocatable in ("0", "1")
665 self.assertEqual(op.changes, {
666 constants.SF_ALLOCATABLE: (allocatable == "1"),
668 self.assertFalse(hasattr(op, "dry_run"))
669 self.assertFalse(hasattr(op, "force"))
671 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
673 def testErrors(self):
674 clfactory = _FakeClientFactory(_FakeClient)
680 handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
681 ["node26016"], queryargs, {}, clfactory)
682 self.assertRaises(http.HttpBadRequest, handler.PUT)
686 "storage_type": constants.ST_LVM_VG,
688 handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
689 ["node21218"], queryargs, {}, clfactory)
690 self.assertRaises(http.HttpBadRequest, handler.PUT)
694 "storage_type": constants.ST_LVM_VG,
696 "allocatable": "noint",
698 handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
699 ["node30685"], queryargs, {}, clfactory)
700 self.assertRaises(http.HttpBadRequest, handler.PUT)
703 class TestStorageRepair(unittest.TestCase):
705 clfactory = _FakeClientFactory(_FakeClient)
707 "storage_type": constants.ST_LVM_PV,
710 handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
711 ["node19265"], queryargs, {}, clfactory)
712 job_id = handler.PUT()
714 cl = clfactory.GetNextClient()
715 self.assertRaises(IndexError, clfactory.GetNextClient)
717 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
718 self.assertEqual(job_id, exp_job_id)
719 self.assertTrue(isinstance(op, opcodes.OpRepairNodeStorage))
720 self.assertEqual(op.node_name, "node19265")
721 self.assertEqual(op.storage_type, constants.ST_LVM_PV)
722 self.assertEqual(op.name, "pv16611")
723 self.assertFalse(hasattr(op, "dry_run"))
724 self.assertFalse(hasattr(op, "force"))
726 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
728 def testErrors(self):
729 clfactory = _FakeClientFactory(_FakeClient)
735 handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
736 ["node11275"], queryargs, {}, clfactory)
737 self.assertRaises(http.HttpBadRequest, handler.PUT)
741 "storage_type": constants.ST_LVM_VG,
743 handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
744 ["node21218"], queryargs, {}, clfactory)
745 self.assertRaises(http.HttpBadRequest, handler.PUT)
748 class TestTags(unittest.TestCase):
750 rlib2.R_2_instances_name_tags,
751 rlib2.R_2_nodes_name_tags,
752 rlib2.R_2_groups_name_tags,
756 def testSetAndDelete(self):
757 clfactory = _FakeClientFactory(_FakeClient)
759 for method, opcls in [("PUT", opcodes.OpTagsSet),
760 ("DELETE", opcodes.OpTagsDel)]:
761 for idx, handler in enumerate(self.TAG_HANDLERS):
762 dry_run = bool(idx % 2)
763 name = "test%s" % idx
765 "tag": ["foo", "bar", "baz"],
766 "dry-run": str(int(dry_run)),
769 handler = _CreateHandler(handler, [name], queryargs, {}, clfactory)
770 job_id = getattr(handler, method)()
772 cl = clfactory.GetNextClient()
773 self.assertRaises(IndexError, clfactory.GetNextClient)
775 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
776 self.assertEqual(job_id, exp_job_id)
777 self.assertTrue(isinstance(op, opcls))
778 self.assertEqual(op.kind, handler.TAG_LEVEL)
779 if handler.TAG_LEVEL == constants.TAG_CLUSTER:
780 self.assertTrue(op.name is None)
782 self.assertEqual(op.name, name)
783 self.assertEqual(op.tags, ["foo", "bar", "baz"])
784 self.assertEqual(op.dry_run, dry_run)
785 self.assertFalse(hasattr(op, "force"))
787 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
790 class TestInstanceCreation(testutils.GanetiTestCase):
792 clfactory = _FakeClientFactory(_FakeClient)
794 name = "inst863.example.com"
801 [{"size": 5, }, {"size": 100, }],
804 [{"size": 123, "mode": constants.DISK_RDWR, }],
816 { "ip": "192.0.2.6", "mode": constants.NIC_MODE_ROUTED,
817 "mac": "01:23:45:67:68:9A",
819 { "mode": constants.NIC_MODE_BRIDGED, "link": "br1" },
826 { constants.BE_VCPUS: 2, },
827 { constants.BE_MAXMEM: 200, },
828 { constants.BE_MEMORY: 256, },
829 { constants.BE_VCPUS: 2,
830 constants.BE_MAXMEM: 1024,
831 constants.BE_MINMEM: 1024,
832 constants.BE_AUTO_BALANCE: True,
833 constants.BE_ALWAYS_FAILOVER: True, }
838 { constants.HV_BOOT_ORDER: "anc", },
839 { constants.HV_KERNEL_PATH: "/boot/fookernel",
840 constants.HV_ROOT_PATH: "/dev/hda1", },
843 for mode in [constants.INSTANCE_CREATE, constants.INSTANCE_IMPORT]:
844 for nics in nic_variants:
845 for disk_template in constants.DISK_TEMPLATES:
846 for disks in disk_variants:
847 for beparams in beparam_variants:
848 for hvparams in hvparam_variants:
849 for dry_run in [False, True]:
851 "dry-run": str(int(dry_run)),
855 rlib2._REQ_DATA_VERSION: 1,
857 "hypervisor": constants.HT_FAKE,
861 "disk_template": disk_template,
865 if beparams is not None:
866 data["beparams"] = beparams
868 if hvparams is not None:
869 data["hvparams"] = hvparams
871 handler = _CreateHandler(rlib2.R_2_instances, [],
872 queryargs, data, clfactory)
873 job_id = handler.POST()
875 cl = clfactory.GetNextClient()
876 self.assertRaises(IndexError, clfactory.GetNextClient)
878 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
879 self.assertEqual(job_id, exp_job_id)
880 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
882 self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
883 self.assertEqual(op.instance_name, name)
884 self.assertEqual(op.mode, mode)
885 self.assertEqual(op.disk_template, disk_template)
886 self.assertEqual(op.dry_run, dry_run)
887 self.assertEqual(len(op.disks), len(disks))
888 self.assertEqual(len(op.nics), len(nics))
890 for opdisk, disk in zip(op.disks, disks):
891 for key in constants.IDISK_PARAMS:
892 self.assertEqual(opdisk.get(key), disk.get(key))
893 self.assertFalse("unknown" in opdisk)
895 for opnic, nic in zip(op.nics, nics):
896 for key in constants.INIC_PARAMS:
897 self.assertEqual(opnic.get(key), nic.get(key))
898 self.assertFalse("unknown" in opnic)
899 self.assertFalse("foobar" in opnic)
902 self.assertFalse(hasattr(op, "beparams"))
904 self.assertEqualValues(op.beparams, beparams)
907 self.assertFalse(hasattr(op, "hvparams"))
909 self.assertEqualValues(op.hvparams, hvparams)
911 def testLegacyName(self):
912 clfactory = _FakeClientFactory(_FakeClient)
914 name = "inst29128.example.com"
916 rlib2._REQ_DATA_VERSION: 1,
920 "mode": constants.INSTANCE_CREATE,
921 "disk_template": constants.DT_PLAIN,
924 handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
925 job_id = handler.POST()
927 cl = clfactory.GetNextClient()
928 self.assertRaises(IndexError, clfactory.GetNextClient)
930 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
931 self.assertEqual(job_id, exp_job_id)
932 self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
933 self.assertEqual(op.instance_name, name)
934 self.assertFalse(hasattr(op, "name"))
935 self.assertFalse(op.dry_run)
937 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
940 data["instance_name"] = "other.example.com"
941 assert "name" in data and "instance_name" in data
942 handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
943 self.assertRaises(http.HttpBadRequest, handler.POST)
944 self.assertRaises(IndexError, clfactory.GetNextClient)
946 def testLegacyOs(self):
947 clfactory = _FakeClientFactory(_FakeClient)
949 name = "inst4673.example.com"
952 rlib2._REQ_DATA_VERSION: 1,
957 "mode": constants.INSTANCE_CREATE,
958 "disk_template": constants.DT_PLAIN,
961 handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
962 job_id = handler.POST()
964 cl = clfactory.GetNextClient()
965 self.assertRaises(IndexError, clfactory.GetNextClient)
967 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
968 self.assertEqual(job_id, exp_job_id)
969 self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
970 self.assertEqual(op.instance_name, name)
971 self.assertEqual(op.os_type, os)
972 self.assertFalse(hasattr(op, "os"))
973 self.assertFalse(op.dry_run)
975 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
978 data["os"] = "linux9584"
979 assert "os" in data and "os_type" in data
980 handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
981 self.assertRaises(http.HttpBadRequest, handler.POST)
983 def testErrors(self):
984 clfactory = _FakeClientFactory(_FakeClient)
986 # Test all required fields
988 rlib2._REQ_DATA_VERSION: 1,
989 "name": "inst1.example.com",
992 "mode": constants.INSTANCE_CREATE,
993 "disk_template": constants.DT_PLAIN,
996 for name in reqfields.keys():
997 data = dict(i for i in reqfields.iteritems() if i[0] != name)
999 handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1000 self.assertRaises(http.HttpBadRequest, handler.POST)
1001 self.assertRaises(IndexError, clfactory.GetNextClient)
1003 # Invalid disks and nics
1004 for field in ["disks", "nics"]:
1005 invalid_values = [None, 1, "", {}, [1, 2, 3], ["hda1", "hda2"],
1006 [{"_unknown_": False, }]]
1008 for invvalue in invalid_values:
1009 data = reqfields.copy()
1010 data[field] = invvalue
1011 handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1012 self.assertRaises(http.HttpBadRequest, handler.POST)
1013 self.assertRaises(IndexError, clfactory.GetNextClient)
1015 def testVersion(self):
1016 clfactory = _FakeClientFactory(_FakeClient)
1020 "name": "inst1.example.com",
1023 "mode": constants.INSTANCE_CREATE,
1024 "disk_template": constants.DT_PLAIN,
1027 handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1028 self.assertRaises(http.HttpBadRequest, handler.POST)
1030 # Old and incorrect versions
1031 for version in [0, -1, 10483, "Hello World"]:
1032 data[rlib2._REQ_DATA_VERSION] = version
1034 handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1035 self.assertRaises(http.HttpBadRequest, handler.POST)
1037 self.assertRaises(IndexError, clfactory.GetNextClient)
1040 data[rlib2._REQ_DATA_VERSION] = 1
1041 handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1042 job_id = handler.POST()
1044 cl = clfactory.GetNextClient()
1045 self.assertRaises(IndexError, clfactory.GetNextClient)
1047 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1048 self.assertEqual(job_id, exp_job_id)
1049 self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
1050 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1053 class TestBackupExport(unittest.TestCase):
1055 clfactory = _FakeClientFactory(_FakeClient)
1059 "mode": constants.EXPORT_MODE_REMOTE,
1060 "destination": [(1, 2, 3), (99, 99, 99)],
1062 "remove_instance": True,
1063 "x509_key_name": ["name", "hash"],
1064 "destination_x509_ca": "---cert---"
1067 handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
1069 job_id = handler.PUT()
1071 cl = clfactory.GetNextClient()
1072 self.assertRaises(IndexError, clfactory.GetNextClient)
1074 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1075 self.assertEqual(job_id, exp_job_id)
1076 self.assertTrue(isinstance(op, opcodes.OpBackupExport))
1077 self.assertEqual(op.instance_name, name)
1078 self.assertEqual(op.mode, constants.EXPORT_MODE_REMOTE)
1079 self.assertEqual(op.target_node, [(1, 2, 3), (99, 99, 99)])
1080 self.assertEqual(op.shutdown, True)
1081 self.assertEqual(op.remove_instance, True)
1082 self.assertEqual(op.x509_key_name, ["name", "hash"])
1083 self.assertEqual(op.destination_x509_ca, "---cert---")
1084 self.assertFalse(hasattr(op, "dry_run"))
1085 self.assertFalse(hasattr(op, "force"))
1087 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1089 def testDefaults(self):
1090 clfactory = _FakeClientFactory(_FakeClient)
1094 "destination": "node2",
1098 handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
1100 job_id = handler.PUT()
1102 cl = clfactory.GetNextClient()
1103 self.assertRaises(IndexError, clfactory.GetNextClient)
1105 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1106 self.assertEqual(job_id, exp_job_id)
1107 self.assertTrue(isinstance(op, opcodes.OpBackupExport))
1108 self.assertEqual(op.instance_name, name)
1109 self.assertEqual(op.target_node, "node2")
1110 self.assertFalse(hasattr(op, "mode"))
1111 self.assertFalse(hasattr(op, "remove_instance"))
1112 self.assertFalse(hasattr(op, "destination"))
1113 self.assertFalse(hasattr(op, "dry_run"))
1114 self.assertFalse(hasattr(op, "force"))
1116 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1118 def testErrors(self):
1119 clfactory = _FakeClientFactory(_FakeClient)
1121 for value in ["True", "False"]:
1122 handler = _CreateHandler(rlib2.R_2_instances_name_export, ["err1"], {}, {
1123 "remove_instance": value,
1125 self.assertRaises(http.HttpBadRequest, handler.PUT)
1128 class TestInstanceMigrate(testutils.GanetiTestCase):
1130 clfactory = _FakeClientFactory(_FakeClient)
1132 name = "instYooho6ek"
1134 for cleanup in [False, True]:
1135 for mode in constants.HT_MIGRATION_MODES:
1141 handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {},
1143 job_id = handler.PUT()
1145 cl = clfactory.GetNextClient()
1146 self.assertRaises(IndexError, clfactory.GetNextClient)
1148 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1149 self.assertEqual(job_id, exp_job_id)
1150 self.assertTrue(isinstance(op, opcodes.OpInstanceMigrate))
1151 self.assertEqual(op.instance_name, name)
1152 self.assertEqual(op.mode, mode)
1153 self.assertEqual(op.cleanup, cleanup)
1154 self.assertFalse(hasattr(op, "dry_run"))
1155 self.assertFalse(hasattr(op, "force"))
1157 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1159 def testDefaults(self):
1160 clfactory = _FakeClientFactory(_FakeClient)
1162 name = "instnohZeex0"
1164 handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {}, {},
1166 job_id = handler.PUT()
1168 cl = clfactory.GetNextClient()
1169 self.assertRaises(IndexError, clfactory.GetNextClient)
1171 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1172 self.assertEqual(job_id, exp_job_id)
1173 self.assertTrue(isinstance(op, opcodes.OpInstanceMigrate))
1174 self.assertEqual(op.instance_name, name)
1175 self.assertFalse(hasattr(op, "mode"))
1176 self.assertFalse(hasattr(op, "cleanup"))
1177 self.assertFalse(hasattr(op, "dry_run"))
1178 self.assertFalse(hasattr(op, "force"))
1180 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1183 class TestParseRenameInstanceRequest(testutils.GanetiTestCase):
1185 clfactory = _FakeClientFactory(_FakeClient)
1187 name = "instij0eeph7"
1189 for new_name in ["ua0aiyoo", "fai3ongi"]:
1190 for ip_check in [False, True]:
1191 for name_check in [False, True]:
1193 "new_name": new_name,
1194 "ip_check": ip_check,
1195 "name_check": name_check,
1198 handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
1199 {}, data, clfactory)
1200 job_id = handler.PUT()
1202 cl = clfactory.GetNextClient()
1203 self.assertRaises(IndexError, clfactory.GetNextClient)
1205 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1206 self.assertEqual(job_id, exp_job_id)
1207 self.assertTrue(isinstance(op, opcodes.OpInstanceRename))
1208 self.assertEqual(op.instance_name, name)
1209 self.assertEqual(op.new_name, new_name)
1210 self.assertEqual(op.ip_check, ip_check)
1211 self.assertEqual(op.name_check, name_check)
1212 self.assertFalse(hasattr(op, "dry_run"))
1213 self.assertFalse(hasattr(op, "force"))
1215 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1217 def testDefaults(self):
1218 clfactory = _FakeClientFactory(_FakeClient)
1220 name = "instahchie3t"
1222 for new_name in ["thag9mek", "quees7oh"]:
1224 "new_name": new_name,
1227 handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
1228 {}, data, clfactory)
1229 job_id = handler.PUT()
1231 cl = clfactory.GetNextClient()
1232 self.assertRaises(IndexError, clfactory.GetNextClient)
1234 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1235 self.assertEqual(job_id, exp_job_id)
1236 self.assertTrue(isinstance(op, opcodes.OpInstanceRename))
1237 self.assertEqual(op.instance_name, name)
1238 self.assertEqual(op.new_name, new_name)
1239 self.assertFalse(hasattr(op, "ip_check"))
1240 self.assertFalse(hasattr(op, "name_check"))
1241 self.assertFalse(hasattr(op, "dry_run"))
1242 self.assertFalse(hasattr(op, "force"))
1244 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1247 class TestParseModifyInstanceRequest(unittest.TestCase):
1249 clfactory = _FakeClientFactory(_FakeClient)
1251 name = "instush8gah"
1255 [(1, { constants.IDISK_MODE: constants.DISK_RDWR, })],
1258 for osparams in [{}, { "some": "value", "other": "Hello World", }]:
1259 for hvparams in [{}, { constants.HV_KERNEL_PATH: "/some/kernel", }]:
1260 for beparams in [{}, { constants.BE_MAXMEM: 128, }]:
1261 for force in [False, True]:
1262 for nics in [[], [(0, { constants.INIC_IP: "192.0.2.1", })]]:
1263 for disks in test_disks:
1264 for disk_template in constants.DISK_TEMPLATES:
1266 "osparams": osparams,
1267 "hvparams": hvparams,
1268 "beparams": beparams,
1272 "disk_template": disk_template,
1275 handler = _CreateHandler(rlib2.R_2_instances_name_modify,
1276 [name], {}, data, clfactory)
1277 job_id = handler.PUT()
1279 cl = clfactory.GetNextClient()
1280 self.assertRaises(IndexError, clfactory.GetNextClient)
1282 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1283 self.assertEqual(job_id, exp_job_id)
1284 self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
1285 self.assertEqual(op.instance_name, name)
1286 self.assertEqual(op.hvparams, hvparams)
1287 self.assertEqual(op.beparams, beparams)
1288 self.assertEqual(op.osparams, osparams)
1289 self.assertEqual(op.force, force)
1290 self.assertEqual(op.nics, nics)
1291 self.assertEqual(op.disks, disks)
1292 self.assertEqual(op.disk_template, disk_template)
1293 self.assertFalse(hasattr(op, "remote_node"))
1294 self.assertFalse(hasattr(op, "os_name"))
1295 self.assertFalse(hasattr(op, "force_variant"))
1296 self.assertFalse(hasattr(op, "dry_run"))
1298 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1300 def testDefaults(self):
1301 clfactory = _FakeClientFactory(_FakeClient)
1303 name = "instir8aish31"
1305 handler = _CreateHandler(rlib2.R_2_instances_name_modify,
1306 [name], {}, {}, clfactory)
1307 job_id = handler.PUT()
1309 cl = clfactory.GetNextClient()
1310 self.assertRaises(IndexError, clfactory.GetNextClient)
1312 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1313 self.assertEqual(job_id, exp_job_id)
1314 self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
1315 self.assertEqual(op.instance_name, name)
1317 for i in ["hvparams", "beparams", "osparams", "force", "nics", "disks",
1318 "disk_template", "remote_node", "os_name", "force_variant"]:
1319 self.assertFalse(hasattr(op, i))
1322 class TestParseInstanceReinstallRequest(testutils.GanetiTestCase):
1324 testutils.GanetiTestCase.setUp(self)
1326 self.Parse = rlib2._ParseInstanceReinstallRequest
1328 def _Check(self, ops, name):
1330 opcodes.OpInstanceShutdown,
1331 opcodes.OpInstanceReinstall,
1332 opcodes.OpInstanceStartup,
1335 self.assert_(compat.all(isinstance(op, exp)
1336 for op, exp in zip(ops, expcls)))
1337 self.assert_(compat.all(op.instance_name == name for op in ops))
1340 name = "shoo0tihohma"
1342 ops = self.Parse(name, {"os": "sys1", "start": True,})
1343 self.assertEqual(len(ops), 3)
1344 self._Check(ops, name)
1345 self.assertEqual(ops[1].os_type, "sys1")
1346 self.assertFalse(ops[1].osparams)
1348 ops = self.Parse(name, {"os": "sys2", "start": False,})
1349 self.assertEqual(len(ops), 2)
1350 self._Check(ops, name)
1351 self.assertEqual(ops[1].os_type, "sys2")
1356 ops = self.Parse(name, {"os": "sys4035", "start": True,
1357 "osparams": osparams,})
1358 self.assertEqual(len(ops), 3)
1359 self._Check(ops, name)
1360 self.assertEqual(ops[1].os_type, "sys4035")
1361 self.assertEqual(ops[1].osparams, osparams)
1363 def testDefaults(self):
1366 ops = self.Parse(name, {"os": "linux1"})
1367 self.assertEqual(len(ops), 3)
1368 self._Check(ops, name)
1369 self.assertEqual(ops[1].os_type, "linux1")
1370 self.assertFalse(ops[1].osparams)
1372 def testErrors(self):
1373 self.assertRaises(http.HttpBadRequest, self.Parse,
1374 "foo", "not a dictionary")
1377 class TestGroupRename(unittest.TestCase):
1379 clfactory = _FakeClientFactory(_FakeClient)
1381 name = "group608242564"
1383 "new_name": "ua0aiyoo15112",
1386 handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {}, data,
1388 job_id = handler.PUT()
1390 cl = clfactory.GetNextClient()
1391 self.assertRaises(IndexError, clfactory.GetNextClient)
1393 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1394 self.assertEqual(job_id, exp_job_id)
1396 self.assertTrue(isinstance(op, opcodes.OpGroupRename))
1397 self.assertEqual(op.group_name, name)
1398 self.assertEqual(op.new_name, "ua0aiyoo15112")
1399 self.assertFalse(op.dry_run)
1400 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1402 def testDryRun(self):
1403 clfactory = _FakeClientFactory(_FakeClient)
1407 "new_name": "ua0aiyoo",
1410 handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {
1413 job_id = handler.PUT()
1415 cl = clfactory.GetNextClient()
1416 self.assertRaises(IndexError, clfactory.GetNextClient)
1418 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1419 self.assertEqual(job_id, exp_job_id)
1421 self.assertTrue(isinstance(op, opcodes.OpGroupRename))
1422 self.assertEqual(op.group_name, name)
1423 self.assertEqual(op.new_name, "ua0aiyoo")
1424 self.assertTrue(op.dry_run)
1425 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1428 class TestInstanceReplaceDisks(unittest.TestCase):
1430 clfactory = _FakeClientFactory(_FakeClient)
1434 for disks in [range(1, 4), "1,2,3", "1, 2, 3"]:
1436 "mode": constants.REPLACE_DISK_SEC,
1438 "iallocator": "myalloc",
1441 handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1442 [name], {}, data, clfactory)
1443 job_id = handler.POST()
1445 cl = clfactory.GetNextClient()
1446 self.assertRaises(IndexError, clfactory.GetNextClient)
1448 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1449 self.assertEqual(job_id, exp_job_id)
1451 self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
1452 self.assertEqual(op.instance_name, name)
1453 self.assertEqual(op.mode, constants.REPLACE_DISK_SEC)
1454 self.assertEqual(op.disks, [1, 2, 3])
1455 self.assertEqual(op.iallocator, "myalloc")
1456 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1458 def testDefaults(self):
1459 clfactory = _FakeClientFactory(_FakeClient)
1463 "mode": constants.REPLACE_DISK_AUTO,
1466 handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1467 [name], {}, data, clfactory)
1468 job_id = handler.POST()
1470 cl = clfactory.GetNextClient()
1471 self.assertRaises(IndexError, clfactory.GetNextClient)
1473 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1474 self.assertEqual(job_id, exp_job_id)
1476 self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
1477 self.assertEqual(op.instance_name, name)
1478 self.assertEqual(op.mode, constants.REPLACE_DISK_AUTO)
1479 self.assertFalse(hasattr(op, "iallocator"))
1480 self.assertFalse(hasattr(op, "disks"))
1481 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1483 def testNoDisks(self):
1484 clfactory = _FakeClientFactory(_FakeClient)
1486 handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1487 ["inst20661"], {}, {}, clfactory)
1488 self.assertRaises(http.HttpBadRequest, handler.POST)
1490 for disks in [None, "", {}]:
1491 handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1492 ["inst20661"], {}, {
1495 self.assertRaises(http.HttpBadRequest, handler.POST)
1497 def testWrong(self):
1498 clfactory = _FakeClientFactory(_FakeClient)
1501 "mode": constants.REPLACE_DISK_AUTO,
1502 "disks": "hello world",
1505 handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1506 ["foo"], {}, data, clfactory)
1507 self.assertRaises(http.HttpBadRequest, handler.POST)
1510 class TestGroupModify(unittest.TestCase):
1512 clfactory = _FakeClientFactory(_FakeClient)
1516 for policy in constants.VALID_ALLOC_POLICIES:
1518 "alloc_policy": policy,
1521 handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, data,
1523 job_id = handler.PUT()
1525 cl = clfactory.GetNextClient()
1526 self.assertRaises(IndexError, clfactory.GetNextClient)
1528 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1529 self.assertEqual(job_id, exp_job_id)
1531 self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
1532 self.assertEqual(op.group_name, name)
1533 self.assertEqual(op.alloc_policy, policy)
1534 self.assertFalse(hasattr(op, "dry_run"))
1535 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1537 def testUnknownPolicy(self):
1538 clfactory = _FakeClientFactory(_FakeClient)
1541 "alloc_policy": "_unknown_policy_",
1544 handler = _CreateHandler(rlib2.R_2_groups_name_modify, ["xyz"], {}, data,
1546 self.assertRaises(http.HttpBadRequest, handler.PUT)
1547 self.assertRaises(IndexError, clfactory.GetNextClient)
1549 def testDefaults(self):
1550 clfactory = _FakeClientFactory(_FakeClient)
1554 handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, {},
1556 job_id = handler.PUT()
1558 cl = clfactory.GetNextClient()
1559 self.assertRaises(IndexError, clfactory.GetNextClient)
1561 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1562 self.assertEqual(job_id, exp_job_id)
1564 self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
1565 self.assertEqual(op.group_name, name)
1566 self.assertFalse(hasattr(op, "alloc_policy"))
1567 self.assertFalse(hasattr(op, "dry_run"))
1568 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1571 class TestGroupAdd(unittest.TestCase):
1574 clfactory = _FakeClientFactory(_FakeClient)
1576 for policy in constants.VALID_ALLOC_POLICIES:
1579 "alloc_policy": policy,
1582 handler = _CreateHandler(rlib2.R_2_groups, [], {}, data,
1584 job_id = handler.POST()
1586 cl = clfactory.GetNextClient()
1587 self.assertRaises(IndexError, clfactory.GetNextClient)
1589 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1590 self.assertEqual(job_id, exp_job_id)
1592 self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1593 self.assertEqual(op.group_name, name)
1594 self.assertEqual(op.alloc_policy, policy)
1595 self.assertFalse(op.dry_run)
1596 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1598 def testUnknownPolicy(self):
1599 clfactory = _FakeClientFactory(_FakeClient)
1602 "alloc_policy": "_unknown_policy_",
1605 handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1606 self.assertRaises(http.HttpBadRequest, handler.POST)
1607 self.assertRaises(IndexError, clfactory.GetNextClient)
1609 def testDefaults(self):
1610 clfactory = _FakeClientFactory(_FakeClient)
1617 handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1618 job_id = handler.POST()
1620 cl = clfactory.GetNextClient()
1621 self.assertRaises(IndexError, clfactory.GetNextClient)
1623 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1624 self.assertEqual(job_id, exp_job_id)
1626 self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1627 self.assertEqual(op.group_name, name)
1628 self.assertFalse(hasattr(op, "alloc_policy"))
1629 self.assertFalse(op.dry_run)
1631 def testLegacyName(self):
1632 clfactory = _FakeClientFactory(_FakeClient)
1639 handler = _CreateHandler(rlib2.R_2_groups, [], {
1642 job_id = handler.POST()
1644 cl = clfactory.GetNextClient()
1645 self.assertRaises(IndexError, clfactory.GetNextClient)
1647 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1648 self.assertEqual(job_id, exp_job_id)
1650 self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1651 self.assertEqual(op.group_name, name)
1652 self.assertFalse(hasattr(op, "alloc_policy"))
1653 self.assertTrue(op.dry_run)
1656 class TestNodeRole(unittest.TestCase):
1658 clfactory = _FakeClientFactory(_FakeClient)
1660 for role in rlib2._NR_MAP.values():
1661 handler = _CreateHandler(rlib2.R_2_nodes_name_role,
1662 ["node-z"], {}, role, clfactory)
1663 if role == rlib2._NR_MASTER:
1664 self.assertRaises(http.HttpBadRequest, handler.PUT)
1666 job_id = handler.PUT()
1668 cl = clfactory.GetNextClient()
1669 self.assertRaises(IndexError, clfactory.GetNextClient)
1671 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1672 self.assertEqual(job_id, exp_job_id)
1673 self.assertTrue(isinstance(op, opcodes.OpNodeSetParams))
1674 self.assertEqual(op.node_name, "node-z")
1675 self.assertFalse(op.force)
1676 self.assertFalse(hasattr(op, "dry_run"))
1678 if role == rlib2._NR_REGULAR:
1679 self.assertFalse(op.drained)
1680 self.assertFalse(op.offline)
1681 self.assertFalse(op.master_candidate)
1682 elif role == rlib2._NR_MASTER_CANDIDATE:
1683 self.assertFalse(op.drained)
1684 self.assertFalse(op.offline)
1685 self.assertTrue(op.master_candidate)
1686 elif role == rlib2._NR_DRAINED:
1687 self.assertTrue(op.drained)
1688 self.assertFalse(op.offline)
1689 self.assertFalse(op.master_candidate)
1690 elif role == rlib2._NR_OFFLINE:
1691 self.assertFalse(op.drained)
1692 self.assertTrue(op.offline)
1693 self.assertFalse(op.master_candidate)
1695 self.fail("Unknown role '%s'" % role)
1697 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1700 class TestSimpleResources(unittest.TestCase):
1702 self.clfactory = _FakeClientFactory(_FakeClient)
1705 self.assertRaises(IndexError, self.clfactory.GetNextClient)
1707 def testFeatures(self):
1708 handler = _CreateHandler(rlib2.R_2_features, [], {}, None, self.clfactory)
1709 self.assertEqual(set(handler.GET()), rlib2.ALL_FEATURES)
1711 def testEmpty(self):
1712 for cls in [rlib2.R_root, rlib2.R_2]:
1713 handler = _CreateHandler(cls, [], {}, None, self.clfactory)
1714 self.assertTrue(handler.GET() is None)
1716 def testVersion(self):
1717 handler = _CreateHandler(rlib2.R_version, [], {}, None, self.clfactory)
1718 self.assertEqual(handler.GET(), constants.RAPI_VERSION)
1721 class TestClusterInfo(unittest.TestCase):
1722 class _ClusterInfoClient:
1723 def __init__(self, address=None):
1724 self.cluster_info = None
1726 def QueryClusterInfo(self):
1727 assert self.cluster_info is None
1728 self.cluster_info = object()
1729 return self.cluster_info
1732 clfactory = _FakeClientFactory(self._ClusterInfoClient)
1733 handler = _CreateHandler(rlib2.R_2_info, [], {}, None, clfactory)
1734 result = handler.GET()
1735 cl = clfactory.GetNextClient()
1736 self.assertRaises(IndexError, clfactory.GetNextClient)
1737 self.assertEqual(result, cl.cluster_info)
1740 class TestInstancesMultiAlloc(unittest.TestCase):
1741 def testInstanceUpdate(self):
1742 clfactory = _FakeClientFactory(_FakeClient)
1745 "instance_name": "bar",
1748 "instance_name": "foo",
1752 handler = _CreateHandler(rlib2.R_2_instances_multi_alloc, [], {}, data,
1754 (body, _) = handler.GetPostOpInput()
1755 self.assertTrue(compat.all([inst["OP_ID"] == handler.POST_OPCODE.OP_ID
1756 for inst in body["instances"]]))
1759 class TestPermissions(unittest.TestCase):
1760 def testEquality(self):
1761 self.assertEqual(rlib2.R_2_query.GET_ACCESS, rlib2.R_2_query.PUT_ACCESS)
1762 self.assertEqual(rlib2.R_2_query.GET_ACCESS,
1763 rlib2.R_2_instances_name_console.GET_ACCESS)
1765 def testMethodAccess(self):
1766 for handler in connector.CONNECTOR.values():
1767 for method in baserlib._SUPPORTED_METHODS:
1768 access = getattr(handler, "%s_ACCESS" % method)
1769 self.assertFalse(set(access) - rapi.RAPI_ACCESS_ALL,
1770 msg=("Handler '%s' uses unknown access options for"
1771 " method %s" % (handler, method)))
1772 self.assertTrue(rapi.RAPI_ACCESS_READ not in access or
1773 rapi.RAPI_ACCESS_WRITE in access,
1774 msg=("Handler '%s' gives query, but not write access"
1775 " for method %s (the latter includes query and"
1776 " should therefore be given as well)" %
1780 if __name__ == "__main__":
1781 testutils.GanetiTestProgram()