4 # Copyright (C) 2010, 2012, 2013 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"],
373 "reason": ["System update"],
375 job_id = handler.POST()
377 cl = clfactory.GetNextClient()
378 self.assertRaises(IndexError, clfactory.GetNextClient)
380 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
381 self.assertEqual(job_id, exp_job_id)
382 self.assertTrue(isinstance(op, opcodes.OpInstanceReboot))
383 self.assertEqual(op.instance_name, "inst847")
384 self.assertEqual(op.reboot_type, constants.INSTANCE_REBOOT_HARD)
385 self.assertTrue(op.ignore_secondaries)
386 self.assertTrue(op.dry_run)
387 self.assertEqual(op.reason[0][0], constants.OPCODE_REASON_SRC_USER)
388 self.assertEqual(op.reason[0][1], "System update")
389 self.assertEqual(op.reason[1][0],
390 "%s:%s" % (constants.OPCODE_REASON_SRC_RLIB2,
391 "instances_name_reboot"))
392 self.assertEqual(op.reason[1][1], "")
394 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
397 class TestInstanceStartup(unittest.TestCase):
399 clfactory = _FakeClientFactory(_FakeClient)
400 handler = _CreateHandler(rlib2.R_2_instances_name_startup, ["inst31083"], {
402 "no_remember": ["1"],
403 "reason": ["Newly created instance"],
405 job_id = handler.PUT()
407 cl = clfactory.GetNextClient()
408 self.assertRaises(IndexError, clfactory.GetNextClient)
410 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
411 self.assertEqual(job_id, exp_job_id)
412 self.assertTrue(isinstance(op, opcodes.OpInstanceStartup))
413 self.assertEqual(op.instance_name, "inst31083")
414 self.assertTrue(op.no_remember)
415 self.assertTrue(op.force)
416 self.assertFalse(op.dry_run)
417 self.assertEqual(op.reason[0][0], constants.OPCODE_REASON_SRC_USER)
418 self.assertEqual(op.reason[0][1], "Newly created instance")
419 self.assertEqual(op.reason[1][0],
420 "%s:%s" % (constants.OPCODE_REASON_SRC_RLIB2,
421 "instances_name_startup"))
422 self.assertEqual(op.reason[1][1], "")
424 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
427 class TestInstanceShutdown(unittest.TestCase):
429 clfactory = _FakeClientFactory(_FakeClient)
430 handler = _CreateHandler(rlib2.R_2_instances_name_shutdown, ["inst26791"], {
431 "no_remember": ["0"],
432 "reason": ["Not used anymore"],
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.OpInstanceShutdown))
442 self.assertEqual(op.instance_name, "inst26791")
443 self.assertFalse(op.no_remember)
444 self.assertFalse(op.dry_run)
445 self.assertEqual(op.reason[0][0], constants.OPCODE_REASON_SRC_USER)
446 self.assertEqual(op.reason[0][1], "Not used anymore")
447 self.assertEqual(op.reason[1][0],
448 "%s:%s" % (constants.OPCODE_REASON_SRC_RLIB2,
449 "instances_name_shutdown"))
450 self.assertEqual(op.reason[1][1], "")
452 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
455 class TestInstanceActivateDisks(unittest.TestCase):
457 clfactory = _FakeClientFactory(_FakeClient)
458 handler = _CreateHandler(rlib2.R_2_instances_name_activate_disks, ["xyz"], {
459 "ignore_size": ["1"],
461 job_id = handler.PUT()
463 cl = clfactory.GetNextClient()
464 self.assertRaises(IndexError, clfactory.GetNextClient)
466 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
467 self.assertEqual(job_id, exp_job_id)
468 self.assertTrue(isinstance(op, opcodes.OpInstanceActivateDisks))
469 self.assertEqual(op.instance_name, "xyz")
470 self.assertTrue(op.ignore_size)
471 self.assertFalse(hasattr(op, "dry_run"))
473 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
476 class TestInstanceDeactivateDisks(unittest.TestCase):
478 clfactory = _FakeClientFactory(_FakeClient)
479 handler = _CreateHandler(rlib2.R_2_instances_name_deactivate_disks,
480 ["inst22357"], {}, {}, clfactory)
481 job_id = handler.PUT()
483 cl = clfactory.GetNextClient()
484 self.assertRaises(IndexError, clfactory.GetNextClient)
486 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
487 self.assertEqual(job_id, exp_job_id)
488 self.assertTrue(isinstance(op, opcodes.OpInstanceDeactivateDisks))
489 self.assertEqual(op.instance_name, "inst22357")
490 self.assertFalse(hasattr(op, "dry_run"))
491 self.assertFalse(hasattr(op, "force"))
493 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
496 class TestInstanceRecreateDisks(unittest.TestCase):
498 clfactory = _FakeClientFactory(_FakeClient)
499 handler = _CreateHandler(rlib2.R_2_instances_name_recreate_disks,
500 ["inst22357"], {}, {}, clfactory)
501 job_id = handler.POST()
503 cl = clfactory.GetNextClient()
504 self.assertRaises(IndexError, clfactory.GetNextClient)
506 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
507 self.assertEqual(job_id, exp_job_id)
508 self.assertTrue(isinstance(op, opcodes.OpInstanceRecreateDisks))
509 self.assertEqual(op.instance_name, "inst22357")
510 self.assertFalse(hasattr(op, "dry_run"))
511 self.assertFalse(hasattr(op, "force"))
513 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
516 class TestInstanceFailover(unittest.TestCase):
518 clfactory = _FakeClientFactory(_FakeClient)
519 handler = _CreateHandler(rlib2.R_2_instances_name_failover,
520 ["inst12794"], {}, {}, clfactory)
521 job_id = handler.PUT()
523 cl = clfactory.GetNextClient()
524 self.assertRaises(IndexError, clfactory.GetNextClient)
526 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
527 self.assertEqual(job_id, exp_job_id)
528 self.assertTrue(isinstance(op, opcodes.OpInstanceFailover))
529 self.assertEqual(op.instance_name, "inst12794")
530 self.assertFalse(hasattr(op, "dry_run"))
531 self.assertFalse(hasattr(op, "force"))
533 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
536 class TestInstanceDiskGrow(unittest.TestCase):
538 clfactory = _FakeClientFactory(_FakeClient)
542 handler = _CreateHandler(rlib2.R_2_instances_name_disk_grow,
543 ["inst10742", "3"], {}, data, clfactory)
544 job_id = handler.POST()
546 cl = clfactory.GetNextClient()
547 self.assertRaises(IndexError, clfactory.GetNextClient)
549 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
550 self.assertEqual(job_id, exp_job_id)
551 self.assertTrue(isinstance(op, opcodes.OpInstanceGrowDisk))
552 self.assertEqual(op.instance_name, "inst10742")
553 self.assertEqual(op.disk, 3)
554 self.assertEqual(op.amount, 1024)
555 self.assertFalse(hasattr(op, "dry_run"))
556 self.assertFalse(hasattr(op, "force"))
558 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
561 class TestBackupPrepare(unittest.TestCase):
563 clfactory = _FakeClientFactory(_FakeClient)
565 "mode": constants.EXPORT_MODE_REMOTE,
567 handler = _CreateHandler(rlib2.R_2_instances_name_prepare_export,
568 ["inst17925"], queryargs, {}, clfactory)
569 job_id = handler.PUT()
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.OpBackupPrepare))
577 self.assertEqual(op.instance_name, "inst17925")
578 self.assertEqual(op.mode, constants.EXPORT_MODE_REMOTE)
579 self.assertFalse(hasattr(op, "dry_run"))
580 self.assertFalse(hasattr(op, "force"))
582 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
585 class TestGroupRemove(unittest.TestCase):
587 clfactory = _FakeClientFactory(_FakeClient)
588 handler = _CreateHandler(rlib2.R_2_groups_name,
589 ["grp28575"], {}, {}, clfactory)
590 job_id = handler.DELETE()
592 cl = clfactory.GetNextClient()
593 self.assertRaises(IndexError, clfactory.GetNextClient)
595 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
596 self.assertEqual(job_id, exp_job_id)
597 self.assertTrue(isinstance(op, opcodes.OpGroupRemove))
598 self.assertEqual(op.group_name, "grp28575")
599 self.assertFalse(op.dry_run)
600 self.assertFalse(hasattr(op, "force"))
602 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
605 class TestStorageQuery(unittest.TestCase):
607 clfactory = _FakeClientFactory(_FakeClient)
609 "storage_type": constants.ST_LVM_PV,
610 "output_fields": "name,other",
612 handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
613 ["node21075"], queryargs, {}, clfactory)
614 job_id = handler.GET()
616 cl = clfactory.GetNextClient()
617 self.assertRaises(IndexError, clfactory.GetNextClient)
619 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
620 self.assertEqual(job_id, exp_job_id)
621 self.assertTrue(isinstance(op, opcodes.OpNodeQueryStorage))
622 self.assertEqual(op.nodes, ["node21075"])
623 self.assertEqual(op.storage_type, constants.ST_LVM_PV)
624 self.assertEqual(op.output_fields, ["name", "other"])
625 self.assertFalse(hasattr(op, "dry_run"))
626 self.assertFalse(hasattr(op, "force"))
628 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
630 def testErrors(self):
631 clfactory = _FakeClientFactory(_FakeClient)
634 "output_fields": "name,other",
636 handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
637 ["node10538"], queryargs, {}, clfactory)
638 self.assertRaises(http.HttpBadRequest, handler.GET)
641 "storage_type": constants.ST_LVM_VG,
643 handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
644 ["node21273"], queryargs, {}, clfactory)
645 self.assertRaises(http.HttpBadRequest, handler.GET)
648 "storage_type": "##unknown_storage##",
649 "output_fields": "name,other",
651 handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
652 ["node10315"], queryargs, {}, clfactory)
653 self.assertRaises(http.HttpBadRequest, handler.GET)
656 class TestStorageModify(unittest.TestCase):
658 clfactory = _FakeClientFactory(_FakeClient)
660 for allocatable in [None, "1", "0"]:
662 "storage_type": constants.ST_LVM_VG,
666 if allocatable is not None:
667 queryargs["allocatable"] = allocatable
669 handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
670 ["node9292"], queryargs, {}, clfactory)
671 job_id = handler.PUT()
673 cl = clfactory.GetNextClient()
674 self.assertRaises(IndexError, clfactory.GetNextClient)
676 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
677 self.assertEqual(job_id, exp_job_id)
678 self.assertTrue(isinstance(op, opcodes.OpNodeModifyStorage))
679 self.assertEqual(op.node_name, "node9292")
680 self.assertEqual(op.storage_type, constants.ST_LVM_VG)
681 self.assertEqual(op.name, "pv-a")
682 if allocatable is None:
683 self.assertFalse(op.changes)
685 assert allocatable in ("0", "1")
686 self.assertEqual(op.changes, {
687 constants.SF_ALLOCATABLE: (allocatable == "1"),
689 self.assertFalse(hasattr(op, "dry_run"))
690 self.assertFalse(hasattr(op, "force"))
692 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
694 def testErrors(self):
695 clfactory = _FakeClientFactory(_FakeClient)
701 handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
702 ["node26016"], queryargs, {}, clfactory)
703 self.assertRaises(http.HttpBadRequest, handler.PUT)
707 "storage_type": constants.ST_LVM_VG,
709 handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
710 ["node21218"], queryargs, {}, clfactory)
711 self.assertRaises(http.HttpBadRequest, handler.PUT)
715 "storage_type": constants.ST_LVM_VG,
717 "allocatable": "noint",
719 handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
720 ["node30685"], queryargs, {}, clfactory)
721 self.assertRaises(http.HttpBadRequest, handler.PUT)
724 class TestStorageRepair(unittest.TestCase):
726 clfactory = _FakeClientFactory(_FakeClient)
728 "storage_type": constants.ST_LVM_PV,
731 handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
732 ["node19265"], queryargs, {}, clfactory)
733 job_id = handler.PUT()
735 cl = clfactory.GetNextClient()
736 self.assertRaises(IndexError, clfactory.GetNextClient)
738 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
739 self.assertEqual(job_id, exp_job_id)
740 self.assertTrue(isinstance(op, opcodes.OpRepairNodeStorage))
741 self.assertEqual(op.node_name, "node19265")
742 self.assertEqual(op.storage_type, constants.ST_LVM_PV)
743 self.assertEqual(op.name, "pv16611")
744 self.assertFalse(hasattr(op, "dry_run"))
745 self.assertFalse(hasattr(op, "force"))
747 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
749 def testErrors(self):
750 clfactory = _FakeClientFactory(_FakeClient)
756 handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
757 ["node11275"], queryargs, {}, clfactory)
758 self.assertRaises(http.HttpBadRequest, handler.PUT)
762 "storage_type": constants.ST_LVM_VG,
764 handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
765 ["node21218"], queryargs, {}, clfactory)
766 self.assertRaises(http.HttpBadRequest, handler.PUT)
769 class TestTags(unittest.TestCase):
771 rlib2.R_2_instances_name_tags,
772 rlib2.R_2_nodes_name_tags,
773 rlib2.R_2_groups_name_tags,
777 def testSetAndDelete(self):
778 clfactory = _FakeClientFactory(_FakeClient)
780 for method, opcls in [("PUT", opcodes.OpTagsSet),
781 ("DELETE", opcodes.OpTagsDel)]:
782 for idx, handler in enumerate(self.TAG_HANDLERS):
783 dry_run = bool(idx % 2)
784 name = "test%s" % idx
786 "tag": ["foo", "bar", "baz"],
787 "dry-run": str(int(dry_run)),
790 handler = _CreateHandler(handler, [name], queryargs, {}, clfactory)
791 job_id = getattr(handler, method)()
793 cl = clfactory.GetNextClient()
794 self.assertRaises(IndexError, clfactory.GetNextClient)
796 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
797 self.assertEqual(job_id, exp_job_id)
798 self.assertTrue(isinstance(op, opcls))
799 self.assertEqual(op.kind, handler.TAG_LEVEL)
800 if handler.TAG_LEVEL == constants.TAG_CLUSTER:
801 self.assertTrue(op.name is None)
803 self.assertEqual(op.name, name)
804 self.assertEqual(op.tags, ["foo", "bar", "baz"])
805 self.assertEqual(op.dry_run, dry_run)
806 self.assertFalse(hasattr(op, "force"))
808 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
811 class TestInstanceCreation(testutils.GanetiTestCase):
813 clfactory = _FakeClientFactory(_FakeClient)
815 name = "inst863.example.com"
822 [{"size": 5, }, {"size": 100, }],
825 [{"size": 123, "mode": constants.DISK_RDWR, }],
837 { "ip": "192.0.2.6", "mode": constants.NIC_MODE_ROUTED,
838 "mac": "01:23:45:67:68:9A",
840 { "mode": constants.NIC_MODE_BRIDGED, "link": "br1" },
847 { constants.BE_VCPUS: 2, },
848 { constants.BE_MAXMEM: 200, },
849 { constants.BE_MEMORY: 256, },
850 { constants.BE_VCPUS: 2,
851 constants.BE_MAXMEM: 1024,
852 constants.BE_MINMEM: 1024,
853 constants.BE_AUTO_BALANCE: True,
854 constants.BE_ALWAYS_FAILOVER: True, }
859 { constants.HV_BOOT_ORDER: "anc", },
860 { constants.HV_KERNEL_PATH: "/boot/fookernel",
861 constants.HV_ROOT_PATH: "/dev/hda1", },
864 for mode in [constants.INSTANCE_CREATE, constants.INSTANCE_IMPORT]:
865 for nics in nic_variants:
866 for disk_template in constants.DISK_TEMPLATES:
867 for disks in disk_variants:
868 for beparams in beparam_variants:
869 for hvparams in hvparam_variants:
870 for dry_run in [False, True]:
872 "dry-run": str(int(dry_run)),
876 rlib2._REQ_DATA_VERSION: 1,
878 "hypervisor": constants.HT_FAKE,
882 "disk_template": disk_template,
886 if beparams is not None:
887 data["beparams"] = beparams
889 if hvparams is not None:
890 data["hvparams"] = hvparams
892 handler = _CreateHandler(rlib2.R_2_instances, [],
893 queryargs, data, clfactory)
894 job_id = handler.POST()
896 cl = clfactory.GetNextClient()
897 self.assertRaises(IndexError, clfactory.GetNextClient)
899 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
900 self.assertEqual(job_id, exp_job_id)
901 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
903 self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
904 self.assertEqual(op.instance_name, name)
905 self.assertEqual(op.mode, mode)
906 self.assertEqual(op.disk_template, disk_template)
907 self.assertEqual(op.dry_run, dry_run)
908 self.assertEqual(len(op.disks), len(disks))
909 self.assertEqual(len(op.nics), len(nics))
911 for opdisk, disk in zip(op.disks, disks):
912 for key in constants.IDISK_PARAMS:
913 self.assertEqual(opdisk.get(key), disk.get(key))
914 self.assertFalse("unknown" in opdisk)
916 for opnic, nic in zip(op.nics, nics):
917 for key in constants.INIC_PARAMS:
918 self.assertEqual(opnic.get(key), nic.get(key))
919 self.assertFalse("unknown" in opnic)
920 self.assertFalse("foobar" in opnic)
923 self.assertFalse(hasattr(op, "beparams"))
925 self.assertEqualValues(op.beparams, beparams)
928 self.assertFalse(hasattr(op, "hvparams"))
930 self.assertEqualValues(op.hvparams, hvparams)
932 def testLegacyName(self):
933 clfactory = _FakeClientFactory(_FakeClient)
935 name = "inst29128.example.com"
937 rlib2._REQ_DATA_VERSION: 1,
941 "mode": constants.INSTANCE_CREATE,
942 "disk_template": constants.DT_PLAIN,
945 handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
946 job_id = handler.POST()
948 cl = clfactory.GetNextClient()
949 self.assertRaises(IndexError, clfactory.GetNextClient)
951 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
952 self.assertEqual(job_id, exp_job_id)
953 self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
954 self.assertEqual(op.instance_name, name)
955 self.assertFalse(hasattr(op, "name"))
956 self.assertFalse(op.dry_run)
958 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
961 data["instance_name"] = "other.example.com"
962 assert "name" in data and "instance_name" in data
963 handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
964 self.assertRaises(http.HttpBadRequest, handler.POST)
965 self.assertRaises(IndexError, clfactory.GetNextClient)
967 def testLegacyOs(self):
968 clfactory = _FakeClientFactory(_FakeClient)
970 name = "inst4673.example.com"
973 rlib2._REQ_DATA_VERSION: 1,
978 "mode": constants.INSTANCE_CREATE,
979 "disk_template": constants.DT_PLAIN,
982 handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
983 job_id = handler.POST()
985 cl = clfactory.GetNextClient()
986 self.assertRaises(IndexError, clfactory.GetNextClient)
988 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
989 self.assertEqual(job_id, exp_job_id)
990 self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
991 self.assertEqual(op.instance_name, name)
992 self.assertEqual(op.os_type, os)
993 self.assertFalse(hasattr(op, "os"))
994 self.assertFalse(op.dry_run)
996 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
999 data["os"] = "linux9584"
1000 assert "os" in data and "os_type" in data
1001 handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1002 self.assertRaises(http.HttpBadRequest, handler.POST)
1004 def testErrors(self):
1005 clfactory = _FakeClientFactory(_FakeClient)
1007 # Test all required fields
1009 rlib2._REQ_DATA_VERSION: 1,
1010 "name": "inst1.example.com",
1013 "mode": constants.INSTANCE_CREATE,
1014 "disk_template": constants.DT_PLAIN,
1017 for name in reqfields.keys():
1018 data = dict(i for i in reqfields.iteritems() if i[0] != name)
1020 handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1021 self.assertRaises(http.HttpBadRequest, handler.POST)
1022 self.assertRaises(IndexError, clfactory.GetNextClient)
1024 # Invalid disks and nics
1025 for field in ["disks", "nics"]:
1026 invalid_values = [None, 1, "", {}, [1, 2, 3], ["hda1", "hda2"],
1027 [{"_unknown_": False, }]]
1029 for invvalue in invalid_values:
1030 data = reqfields.copy()
1031 data[field] = invvalue
1032 handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1033 self.assertRaises(http.HttpBadRequest, handler.POST)
1034 self.assertRaises(IndexError, clfactory.GetNextClient)
1036 def testVersion(self):
1037 clfactory = _FakeClientFactory(_FakeClient)
1041 "name": "inst1.example.com",
1044 "mode": constants.INSTANCE_CREATE,
1045 "disk_template": constants.DT_PLAIN,
1048 handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1049 self.assertRaises(http.HttpBadRequest, handler.POST)
1051 # Old and incorrect versions
1052 for version in [0, -1, 10483, "Hello World"]:
1053 data[rlib2._REQ_DATA_VERSION] = version
1055 handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1056 self.assertRaises(http.HttpBadRequest, handler.POST)
1058 self.assertRaises(IndexError, clfactory.GetNextClient)
1061 data[rlib2._REQ_DATA_VERSION] = 1
1062 handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
1063 job_id = handler.POST()
1065 cl = clfactory.GetNextClient()
1066 self.assertRaises(IndexError, clfactory.GetNextClient)
1068 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1069 self.assertEqual(job_id, exp_job_id)
1070 self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
1071 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1074 class TestBackupExport(unittest.TestCase):
1076 clfactory = _FakeClientFactory(_FakeClient)
1080 "mode": constants.EXPORT_MODE_REMOTE,
1081 "destination": [(1, 2, 3), (99, 99, 99)],
1083 "remove_instance": True,
1084 "x509_key_name": ["name", "hash"],
1085 "destination_x509_ca": "---cert---"
1088 handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
1090 job_id = handler.PUT()
1092 cl = clfactory.GetNextClient()
1093 self.assertRaises(IndexError, clfactory.GetNextClient)
1095 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1096 self.assertEqual(job_id, exp_job_id)
1097 self.assertTrue(isinstance(op, opcodes.OpBackupExport))
1098 self.assertEqual(op.instance_name, name)
1099 self.assertEqual(op.mode, constants.EXPORT_MODE_REMOTE)
1100 self.assertEqual(op.target_node, [(1, 2, 3), (99, 99, 99)])
1101 self.assertEqual(op.shutdown, True)
1102 self.assertEqual(op.remove_instance, True)
1103 self.assertEqual(op.x509_key_name, ["name", "hash"])
1104 self.assertEqual(op.destination_x509_ca, "---cert---")
1105 self.assertFalse(hasattr(op, "dry_run"))
1106 self.assertFalse(hasattr(op, "force"))
1108 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1110 def testDefaults(self):
1111 clfactory = _FakeClientFactory(_FakeClient)
1115 "destination": "node2",
1119 handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
1121 job_id = handler.PUT()
1123 cl = clfactory.GetNextClient()
1124 self.assertRaises(IndexError, clfactory.GetNextClient)
1126 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1127 self.assertEqual(job_id, exp_job_id)
1128 self.assertTrue(isinstance(op, opcodes.OpBackupExport))
1129 self.assertEqual(op.instance_name, name)
1130 self.assertEqual(op.target_node, "node2")
1131 self.assertFalse(hasattr(op, "mode"))
1132 self.assertFalse(hasattr(op, "remove_instance"))
1133 self.assertFalse(hasattr(op, "destination"))
1134 self.assertFalse(hasattr(op, "dry_run"))
1135 self.assertFalse(hasattr(op, "force"))
1137 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1139 def testErrors(self):
1140 clfactory = _FakeClientFactory(_FakeClient)
1142 for value in ["True", "False"]:
1143 handler = _CreateHandler(rlib2.R_2_instances_name_export, ["err1"], {}, {
1144 "remove_instance": value,
1146 self.assertRaises(http.HttpBadRequest, handler.PUT)
1149 class TestInstanceMigrate(testutils.GanetiTestCase):
1151 clfactory = _FakeClientFactory(_FakeClient)
1153 name = "instYooho6ek"
1155 for cleanup in [False, True]:
1156 for mode in constants.HT_MIGRATION_MODES:
1162 handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {},
1164 job_id = handler.PUT()
1166 cl = clfactory.GetNextClient()
1167 self.assertRaises(IndexError, clfactory.GetNextClient)
1169 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1170 self.assertEqual(job_id, exp_job_id)
1171 self.assertTrue(isinstance(op, opcodes.OpInstanceMigrate))
1172 self.assertEqual(op.instance_name, name)
1173 self.assertEqual(op.mode, mode)
1174 self.assertEqual(op.cleanup, cleanup)
1175 self.assertFalse(hasattr(op, "dry_run"))
1176 self.assertFalse(hasattr(op, "force"))
1178 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1180 def testDefaults(self):
1181 clfactory = _FakeClientFactory(_FakeClient)
1183 name = "instnohZeex0"
1185 handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {}, {},
1187 job_id = handler.PUT()
1189 cl = clfactory.GetNextClient()
1190 self.assertRaises(IndexError, clfactory.GetNextClient)
1192 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1193 self.assertEqual(job_id, exp_job_id)
1194 self.assertTrue(isinstance(op, opcodes.OpInstanceMigrate))
1195 self.assertEqual(op.instance_name, name)
1196 self.assertFalse(hasattr(op, "mode"))
1197 self.assertFalse(hasattr(op, "cleanup"))
1198 self.assertFalse(hasattr(op, "dry_run"))
1199 self.assertFalse(hasattr(op, "force"))
1201 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1204 class TestParseRenameInstanceRequest(testutils.GanetiTestCase):
1206 clfactory = _FakeClientFactory(_FakeClient)
1208 name = "instij0eeph7"
1210 for new_name in ["ua0aiyoo", "fai3ongi"]:
1211 for ip_check in [False, True]:
1212 for name_check in [False, True]:
1214 "new_name": new_name,
1215 "ip_check": ip_check,
1216 "name_check": name_check,
1219 handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
1220 {}, data, clfactory)
1221 job_id = handler.PUT()
1223 cl = clfactory.GetNextClient()
1224 self.assertRaises(IndexError, clfactory.GetNextClient)
1226 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1227 self.assertEqual(job_id, exp_job_id)
1228 self.assertTrue(isinstance(op, opcodes.OpInstanceRename))
1229 self.assertEqual(op.instance_name, name)
1230 self.assertEqual(op.new_name, new_name)
1231 self.assertEqual(op.ip_check, ip_check)
1232 self.assertEqual(op.name_check, name_check)
1233 self.assertFalse(hasattr(op, "dry_run"))
1234 self.assertFalse(hasattr(op, "force"))
1236 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1238 def testDefaults(self):
1239 clfactory = _FakeClientFactory(_FakeClient)
1241 name = "instahchie3t"
1243 for new_name in ["thag9mek", "quees7oh"]:
1245 "new_name": new_name,
1248 handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
1249 {}, data, clfactory)
1250 job_id = handler.PUT()
1252 cl = clfactory.GetNextClient()
1253 self.assertRaises(IndexError, clfactory.GetNextClient)
1255 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1256 self.assertEqual(job_id, exp_job_id)
1257 self.assertTrue(isinstance(op, opcodes.OpInstanceRename))
1258 self.assertEqual(op.instance_name, name)
1259 self.assertEqual(op.new_name, new_name)
1260 self.assertFalse(hasattr(op, "ip_check"))
1261 self.assertFalse(hasattr(op, "name_check"))
1262 self.assertFalse(hasattr(op, "dry_run"))
1263 self.assertFalse(hasattr(op, "force"))
1265 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1268 class TestParseModifyInstanceRequest(unittest.TestCase):
1270 clfactory = _FakeClientFactory(_FakeClient)
1272 name = "instush8gah"
1276 [(1, { constants.IDISK_MODE: constants.DISK_RDWR, })],
1279 for osparams in [{}, { "some": "value", "other": "Hello World", }]:
1280 for hvparams in [{}, { constants.HV_KERNEL_PATH: "/some/kernel", }]:
1281 for beparams in [{}, { constants.BE_MAXMEM: 128, }]:
1282 for force in [False, True]:
1283 for nics in [[], [(0, { constants.INIC_IP: "192.0.2.1", })]]:
1284 for disks in test_disks:
1285 for disk_template in constants.DISK_TEMPLATES:
1287 "osparams": osparams,
1288 "hvparams": hvparams,
1289 "beparams": beparams,
1293 "disk_template": disk_template,
1296 handler = _CreateHandler(rlib2.R_2_instances_name_modify,
1297 [name], {}, data, clfactory)
1298 job_id = handler.PUT()
1300 cl = clfactory.GetNextClient()
1301 self.assertRaises(IndexError, clfactory.GetNextClient)
1303 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1304 self.assertEqual(job_id, exp_job_id)
1305 self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
1306 self.assertEqual(op.instance_name, name)
1307 self.assertEqual(op.hvparams, hvparams)
1308 self.assertEqual(op.beparams, beparams)
1309 self.assertEqual(op.osparams, osparams)
1310 self.assertEqual(op.force, force)
1311 self.assertEqual(op.nics, nics)
1312 self.assertEqual(op.disks, disks)
1313 self.assertEqual(op.disk_template, disk_template)
1314 self.assertFalse(hasattr(op, "remote_node"))
1315 self.assertFalse(hasattr(op, "os_name"))
1316 self.assertFalse(hasattr(op, "force_variant"))
1317 self.assertFalse(hasattr(op, "dry_run"))
1319 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1321 def testDefaults(self):
1322 clfactory = _FakeClientFactory(_FakeClient)
1324 name = "instir8aish31"
1326 handler = _CreateHandler(rlib2.R_2_instances_name_modify,
1327 [name], {}, {}, clfactory)
1328 job_id = handler.PUT()
1330 cl = clfactory.GetNextClient()
1331 self.assertRaises(IndexError, clfactory.GetNextClient)
1333 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1334 self.assertEqual(job_id, exp_job_id)
1335 self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
1336 self.assertEqual(op.instance_name, name)
1338 for i in ["hvparams", "beparams", "osparams", "force", "nics", "disks",
1339 "disk_template", "remote_node", "os_name", "force_variant"]:
1340 self.assertFalse(hasattr(op, i))
1343 class TestParseInstanceReinstallRequest(testutils.GanetiTestCase):
1345 testutils.GanetiTestCase.setUp(self)
1347 self.Parse = rlib2._ParseInstanceReinstallRequest
1349 def _Check(self, ops, name):
1351 opcodes.OpInstanceShutdown,
1352 opcodes.OpInstanceReinstall,
1353 opcodes.OpInstanceStartup,
1356 self.assert_(compat.all(isinstance(op, exp)
1357 for op, exp in zip(ops, expcls)))
1358 self.assert_(compat.all(op.instance_name == name for op in ops))
1361 name = "shoo0tihohma"
1363 ops = self.Parse(name, {"os": "sys1", "start": True,})
1364 self.assertEqual(len(ops), 3)
1365 self._Check(ops, name)
1366 self.assertEqual(ops[1].os_type, "sys1")
1367 self.assertFalse(ops[1].osparams)
1369 ops = self.Parse(name, {"os": "sys2", "start": False,})
1370 self.assertEqual(len(ops), 2)
1371 self._Check(ops, name)
1372 self.assertEqual(ops[1].os_type, "sys2")
1377 ops = self.Parse(name, {"os": "sys4035", "start": True,
1378 "osparams": osparams,})
1379 self.assertEqual(len(ops), 3)
1380 self._Check(ops, name)
1381 self.assertEqual(ops[1].os_type, "sys4035")
1382 self.assertEqual(ops[1].osparams, osparams)
1384 def testDefaults(self):
1387 ops = self.Parse(name, {"os": "linux1"})
1388 self.assertEqual(len(ops), 3)
1389 self._Check(ops, name)
1390 self.assertEqual(ops[1].os_type, "linux1")
1391 self.assertFalse(ops[1].osparams)
1393 def testErrors(self):
1394 self.assertRaises(http.HttpBadRequest, self.Parse,
1395 "foo", "not a dictionary")
1398 class TestGroupRename(unittest.TestCase):
1400 clfactory = _FakeClientFactory(_FakeClient)
1402 name = "group608242564"
1404 "new_name": "ua0aiyoo15112",
1407 handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {}, data,
1409 job_id = handler.PUT()
1411 cl = clfactory.GetNextClient()
1412 self.assertRaises(IndexError, clfactory.GetNextClient)
1414 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1415 self.assertEqual(job_id, exp_job_id)
1417 self.assertTrue(isinstance(op, opcodes.OpGroupRename))
1418 self.assertEqual(op.group_name, name)
1419 self.assertEqual(op.new_name, "ua0aiyoo15112")
1420 self.assertFalse(op.dry_run)
1421 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1423 def testDryRun(self):
1424 clfactory = _FakeClientFactory(_FakeClient)
1428 "new_name": "ua0aiyoo",
1431 handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {
1434 job_id = handler.PUT()
1436 cl = clfactory.GetNextClient()
1437 self.assertRaises(IndexError, clfactory.GetNextClient)
1439 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1440 self.assertEqual(job_id, exp_job_id)
1442 self.assertTrue(isinstance(op, opcodes.OpGroupRename))
1443 self.assertEqual(op.group_name, name)
1444 self.assertEqual(op.new_name, "ua0aiyoo")
1445 self.assertTrue(op.dry_run)
1446 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1449 class TestInstanceReplaceDisks(unittest.TestCase):
1451 clfactory = _FakeClientFactory(_FakeClient)
1455 for disks in [range(1, 4), "1,2,3", "1, 2, 3"]:
1457 "mode": constants.REPLACE_DISK_SEC,
1459 "iallocator": "myalloc",
1462 handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1463 [name], {}, data, clfactory)
1464 job_id = handler.POST()
1466 cl = clfactory.GetNextClient()
1467 self.assertRaises(IndexError, clfactory.GetNextClient)
1469 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1470 self.assertEqual(job_id, exp_job_id)
1472 self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
1473 self.assertEqual(op.instance_name, name)
1474 self.assertEqual(op.mode, constants.REPLACE_DISK_SEC)
1475 self.assertEqual(op.disks, [1, 2, 3])
1476 self.assertEqual(op.iallocator, "myalloc")
1477 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1479 def testDefaults(self):
1480 clfactory = _FakeClientFactory(_FakeClient)
1484 "mode": constants.REPLACE_DISK_AUTO,
1487 handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1488 [name], {}, data, clfactory)
1489 job_id = handler.POST()
1491 cl = clfactory.GetNextClient()
1492 self.assertRaises(IndexError, clfactory.GetNextClient)
1494 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1495 self.assertEqual(job_id, exp_job_id)
1497 self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
1498 self.assertEqual(op.instance_name, name)
1499 self.assertEqual(op.mode, constants.REPLACE_DISK_AUTO)
1500 self.assertFalse(hasattr(op, "iallocator"))
1501 self.assertFalse(hasattr(op, "disks"))
1502 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1504 def testNoDisks(self):
1505 clfactory = _FakeClientFactory(_FakeClient)
1507 handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1508 ["inst20661"], {}, {}, clfactory)
1509 self.assertRaises(http.HttpBadRequest, handler.POST)
1511 for disks in [None, "", {}]:
1512 handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1513 ["inst20661"], {}, {
1516 self.assertRaises(http.HttpBadRequest, handler.POST)
1518 def testWrong(self):
1519 clfactory = _FakeClientFactory(_FakeClient)
1522 "mode": constants.REPLACE_DISK_AUTO,
1523 "disks": "hello world",
1526 handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
1527 ["foo"], {}, data, clfactory)
1528 self.assertRaises(http.HttpBadRequest, handler.POST)
1531 class TestGroupModify(unittest.TestCase):
1533 clfactory = _FakeClientFactory(_FakeClient)
1537 for policy in constants.VALID_ALLOC_POLICIES:
1539 "alloc_policy": policy,
1542 handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, data,
1544 job_id = handler.PUT()
1546 cl = clfactory.GetNextClient()
1547 self.assertRaises(IndexError, clfactory.GetNextClient)
1549 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1550 self.assertEqual(job_id, exp_job_id)
1552 self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
1553 self.assertEqual(op.group_name, name)
1554 self.assertEqual(op.alloc_policy, policy)
1555 self.assertFalse(hasattr(op, "dry_run"))
1556 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1558 def testUnknownPolicy(self):
1559 clfactory = _FakeClientFactory(_FakeClient)
1562 "alloc_policy": "_unknown_policy_",
1565 handler = _CreateHandler(rlib2.R_2_groups_name_modify, ["xyz"], {}, data,
1567 self.assertRaises(http.HttpBadRequest, handler.PUT)
1568 self.assertRaises(IndexError, clfactory.GetNextClient)
1570 def testDefaults(self):
1571 clfactory = _FakeClientFactory(_FakeClient)
1575 handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, {},
1577 job_id = handler.PUT()
1579 cl = clfactory.GetNextClient()
1580 self.assertRaises(IndexError, clfactory.GetNextClient)
1582 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1583 self.assertEqual(job_id, exp_job_id)
1585 self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
1586 self.assertEqual(op.group_name, name)
1587 self.assertFalse(hasattr(op, "alloc_policy"))
1588 self.assertFalse(hasattr(op, "dry_run"))
1589 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1592 class TestGroupAdd(unittest.TestCase):
1595 clfactory = _FakeClientFactory(_FakeClient)
1597 for policy in constants.VALID_ALLOC_POLICIES:
1600 "alloc_policy": policy,
1603 handler = _CreateHandler(rlib2.R_2_groups, [], {}, data,
1605 job_id = handler.POST()
1607 cl = clfactory.GetNextClient()
1608 self.assertRaises(IndexError, clfactory.GetNextClient)
1610 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1611 self.assertEqual(job_id, exp_job_id)
1613 self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1614 self.assertEqual(op.group_name, name)
1615 self.assertEqual(op.alloc_policy, policy)
1616 self.assertFalse(op.dry_run)
1617 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1619 def testUnknownPolicy(self):
1620 clfactory = _FakeClientFactory(_FakeClient)
1623 "alloc_policy": "_unknown_policy_",
1626 handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1627 self.assertRaises(http.HttpBadRequest, handler.POST)
1628 self.assertRaises(IndexError, clfactory.GetNextClient)
1630 def testDefaults(self):
1631 clfactory = _FakeClientFactory(_FakeClient)
1638 handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
1639 job_id = handler.POST()
1641 cl = clfactory.GetNextClient()
1642 self.assertRaises(IndexError, clfactory.GetNextClient)
1644 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1645 self.assertEqual(job_id, exp_job_id)
1647 self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1648 self.assertEqual(op.group_name, name)
1649 self.assertFalse(hasattr(op, "alloc_policy"))
1650 self.assertFalse(op.dry_run)
1652 def testLegacyName(self):
1653 clfactory = _FakeClientFactory(_FakeClient)
1660 handler = _CreateHandler(rlib2.R_2_groups, [], {
1663 job_id = handler.POST()
1665 cl = clfactory.GetNextClient()
1666 self.assertRaises(IndexError, clfactory.GetNextClient)
1668 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1669 self.assertEqual(job_id, exp_job_id)
1671 self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
1672 self.assertEqual(op.group_name, name)
1673 self.assertFalse(hasattr(op, "alloc_policy"))
1674 self.assertTrue(op.dry_run)
1677 class TestNodeRole(unittest.TestCase):
1679 clfactory = _FakeClientFactory(_FakeClient)
1681 for role in rlib2._NR_MAP.values():
1682 handler = _CreateHandler(rlib2.R_2_nodes_name_role,
1683 ["node-z"], {}, role, clfactory)
1684 if role == rlib2._NR_MASTER:
1685 self.assertRaises(http.HttpBadRequest, handler.PUT)
1687 job_id = handler.PUT()
1689 cl = clfactory.GetNextClient()
1690 self.assertRaises(IndexError, clfactory.GetNextClient)
1692 (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
1693 self.assertEqual(job_id, exp_job_id)
1694 self.assertTrue(isinstance(op, opcodes.OpNodeSetParams))
1695 self.assertEqual(op.node_name, "node-z")
1696 self.assertFalse(op.force)
1697 self.assertFalse(hasattr(op, "dry_run"))
1699 if role == rlib2._NR_REGULAR:
1700 self.assertFalse(op.drained)
1701 self.assertFalse(op.offline)
1702 self.assertFalse(op.master_candidate)
1703 elif role == rlib2._NR_MASTER_CANDIDATE:
1704 self.assertFalse(op.drained)
1705 self.assertFalse(op.offline)
1706 self.assertTrue(op.master_candidate)
1707 elif role == rlib2._NR_DRAINED:
1708 self.assertTrue(op.drained)
1709 self.assertFalse(op.offline)
1710 self.assertFalse(op.master_candidate)
1711 elif role == rlib2._NR_OFFLINE:
1712 self.assertFalse(op.drained)
1713 self.assertTrue(op.offline)
1714 self.assertFalse(op.master_candidate)
1716 self.fail("Unknown role '%s'" % role)
1718 self.assertRaises(IndexError, cl.GetNextSubmittedJob)
1721 class TestSimpleResources(unittest.TestCase):
1723 self.clfactory = _FakeClientFactory(_FakeClient)
1726 self.assertRaises(IndexError, self.clfactory.GetNextClient)
1728 def testFeatures(self):
1729 handler = _CreateHandler(rlib2.R_2_features, [], {}, None, self.clfactory)
1730 self.assertEqual(set(handler.GET()), rlib2.ALL_FEATURES)
1732 def testEmpty(self):
1733 for cls in [rlib2.R_root, rlib2.R_2]:
1734 handler = _CreateHandler(cls, [], {}, None, self.clfactory)
1735 self.assertTrue(handler.GET() is None)
1737 def testVersion(self):
1738 handler = _CreateHandler(rlib2.R_version, [], {}, None, self.clfactory)
1739 self.assertEqual(handler.GET(), constants.RAPI_VERSION)
1742 class TestClusterInfo(unittest.TestCase):
1743 class _ClusterInfoClient:
1744 def __init__(self, address=None):
1745 self.cluster_info = None
1747 def QueryClusterInfo(self):
1748 assert self.cluster_info is None
1749 self.cluster_info = object()
1750 return self.cluster_info
1753 clfactory = _FakeClientFactory(self._ClusterInfoClient)
1754 handler = _CreateHandler(rlib2.R_2_info, [], {}, None, clfactory)
1755 result = handler.GET()
1756 cl = clfactory.GetNextClient()
1757 self.assertRaises(IndexError, clfactory.GetNextClient)
1758 self.assertEqual(result, cl.cluster_info)
1761 class TestInstancesMultiAlloc(unittest.TestCase):
1762 def testInstanceUpdate(self):
1763 clfactory = _FakeClientFactory(_FakeClient)
1766 "instance_name": "bar",
1769 "instance_name": "foo",
1773 handler = _CreateHandler(rlib2.R_2_instances_multi_alloc, [], {}, data,
1775 (body, _) = handler.GetPostOpInput()
1776 self.assertTrue(compat.all([inst["OP_ID"] == handler.POST_OPCODE.OP_ID
1777 for inst in body["instances"]]))
1780 class TestPermissions(unittest.TestCase):
1781 def testEquality(self):
1782 self.assertEqual(rlib2.R_2_query.GET_ACCESS, rlib2.R_2_query.PUT_ACCESS)
1783 self.assertEqual(rlib2.R_2_query.GET_ACCESS,
1784 rlib2.R_2_instances_name_console.GET_ACCESS)
1786 def testMethodAccess(self):
1787 for handler in connector.CONNECTOR.values():
1788 for method in baserlib._SUPPORTED_METHODS:
1789 access = baserlib.GetHandlerAccess(handler, method)
1790 self.assertFalse(access is None)
1791 self.assertFalse(set(access) - rapi.RAPI_ACCESS_ALL,
1792 msg=("Handler '%s' uses unknown access options for"
1793 " method %s" % (handler, method)))
1794 self.assertTrue(rapi.RAPI_ACCESS_READ not in access or
1795 rapi.RAPI_ACCESS_WRITE in access,
1796 msg=("Handler '%s' gives query, but not write access"
1797 " for method %s (the latter includes query and"
1798 " should therefore be given as well)" %
1802 if __name__ == "__main__":
1803 testutils.GanetiTestProgram()