import unittest
-import tempfile
+import itertools
+import random
from ganeti import constants
from ganeti import opcodes
from ganeti import compat
from ganeti import http
+from ganeti import query
+from ganeti import luxi
+from ganeti import errors
from ganeti.rapi import rlib2
import testutils
-class TestParseInstanceCreateRequestVersion1(testutils.GanetiTestCase):
- def setUp(self):
- testutils.GanetiTestCase.setUp(self)
+class _FakeRequestPrivateData:
+ def __init__(self, body_data):
+ self.body_data = body_data
+
+
+class _FakeRequest:
+ def __init__(self, body_data):
+ self.private = _FakeRequestPrivateData(body_data)
+
+
+def _CreateHandler(cls, items, queryargs, body_data, client_cls):
+ return cls(items, queryargs, _FakeRequest(body_data),
+ _client_cls=client_cls)
+
+
+class _FakeClient:
+ def __init__(self):
+ self._jobs = []
+
+ def GetNextSubmittedJob(self):
+ return self._jobs.pop(0)
+
+ def SubmitJob(self, ops):
+ job_id = str(1 + int(random.random() * 1000000))
+ self._jobs.append((job_id, ops))
+ return job_id
+
+
+class _FakeClientFactory:
+ def __init__(self, cls):
+ self._client_cls = cls
+ self._clients = []
+
+ def GetNextClient(self):
+ return self._clients.pop(0)
+
+ def __call__(self):
+ cl = self._client_cls()
+ self._clients.append(cl)
+ return cl
+
+
+class TestConstants(unittest.TestCase):
+ def testConsole(self):
+ # Exporting the console field without authentication might expose
+ # information
+ assert "console" in query.INSTANCE_FIELDS
+ self.assertTrue("console" not in rlib2.I_FIELDS)
+
+ def testFields(self):
+ checks = {
+ constants.QR_INSTANCE: rlib2.I_FIELDS,
+ constants.QR_NODE: rlib2.N_FIELDS,
+ constants.QR_GROUP: rlib2.G_FIELDS,
+ }
+
+ for (qr, fields) in checks.items():
+ self.assertFalse(set(fields) - set(query.ALL_FIELDS[qr].keys()))
+
+
+class TestClientConnectError(unittest.TestCase):
+ @staticmethod
+ def _FailingClient():
+ raise luxi.NoMasterError("test")
+
+ def test(self):
+ resources = [
+ rlib2.R_2_groups,
+ rlib2.R_2_instances,
+ rlib2.R_2_nodes,
+ ]
+ for cls in resources:
+ handler = _CreateHandler(cls, ["name"], [], None, self._FailingClient)
+ self.assertRaises(http.HttpBadGateway, handler.GET)
+
+
+class TestJobSubmitError(unittest.TestCase):
+ class _SubmitErrorClient:
+ @staticmethod
+ def SubmitJob(ops):
+ raise errors.JobQueueFull("test")
+
+ def test(self):
+ handler = _CreateHandler(rlib2.R_2_redist_config, [], [], None,
+ self._SubmitErrorClient)
+ self.assertRaises(http.HttpServiceUnavailable, handler.PUT)
+
+
+class TestClusterModify(unittest.TestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+ handler = _CreateHandler(rlib2.R_2_cluster_modify, [], [], {
+ "vg_name": "testvg",
+ "candidate_pool_size": 100,
+ }, clfactory)
+ job_id = handler.PUT()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpClusterSetParams))
+ self.assertEqual(op.vg_name, "testvg")
+ self.assertEqual(op.candidate_pool_size, 100)
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+ def testInvalidValue(self):
+ for attr in ["vg_name", "candidate_pool_size", "beparams", "_-Unknown#"]:
+ clfactory = _FakeClientFactory(_FakeClient)
+ handler = _CreateHandler(rlib2.R_2_cluster_modify, [], [], {
+ attr: True,
+ }, clfactory)
+ self.assertRaises(http.HttpBadRequest, handler.PUT)
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+
+class TestRedistConfig(unittest.TestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+ handler = _CreateHandler(rlib2.R_2_redist_config, [], [], None, clfactory)
+ job_id = handler.PUT()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpClusterRedistConf))
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+
+class TestNodeMigrate(unittest.TestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+ handler = _CreateHandler(rlib2.R_2_nodes_name_migrate, ["node1"], {}, {
+ "iallocator": "fooalloc",
+ }, clfactory)
+ job_id = handler.POST()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpNodeMigrate))
+ self.assertEqual(op.node_name, "node1")
+ self.assertEqual(op.iallocator, "fooalloc")
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+ def testQueryArgsConflict(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+ handler = _CreateHandler(rlib2.R_2_nodes_name_migrate, ["node2"], {
+ "live": True,
+ "mode": constants.HT_MIGRATION_NONLIVE,
+ }, None, clfactory)
+ self.assertRaises(http.HttpBadRequest, handler.POST)
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ def testQueryArgsMode(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+ queryargs = {
+ "mode": [constants.HT_MIGRATION_LIVE],
+ }
+ handler = _CreateHandler(rlib2.R_2_nodes_name_migrate, ["node17292"],
+ queryargs, None, clfactory)
+ job_id = handler.POST()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpNodeMigrate))
+ self.assertEqual(op.node_name, "node17292")
+ self.assertEqual(op.mode, constants.HT_MIGRATION_LIVE)
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+ def testQueryArgsLive(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ for live in [False, True]:
+ queryargs = {
+ "live": [str(int(live))],
+ }
+ handler = _CreateHandler(rlib2.R_2_nodes_name_migrate, ["node6940"],
+ queryargs, None, clfactory)
+ job_id = handler.POST()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpNodeMigrate))
+ self.assertEqual(op.node_name, "node6940")
+ if live:
+ self.assertEqual(op.mode, constants.HT_MIGRATION_LIVE)
+ else:
+ self.assertEqual(op.mode, constants.HT_MIGRATION_NONLIVE)
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+
+class TestNodeEvacuate(unittest.TestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+ handler = _CreateHandler(rlib2.R_2_nodes_name_evacuate, ["node92"], {
+ "dry-run": ["1"],
+ }, {
+ "mode": constants.IALLOCATOR_NEVAC_SEC,
+ }, clfactory)
+ job_id = handler.POST()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpNodeEvacuate))
+ self.assertEqual(op.node_name, "node92")
+ self.assertEqual(op.mode, constants.IALLOCATOR_NEVAC_SEC)
+ self.assertTrue(op.dry_run)
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+
+class TestNodePowercycle(unittest.TestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+ handler = _CreateHandler(rlib2.R_2_nodes_name_powercycle, ["node20744"], {
+ "force": ["1"],
+ }, None, clfactory)
+ job_id = handler.POST()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpNodePowercycle))
+ self.assertEqual(op.node_name, "node20744")
+ self.assertTrue(op.force)
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+
+class TestGroupAssignNodes(unittest.TestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+ handler = _CreateHandler(rlib2.R_2_groups_name_assign_nodes, ["grp-a"], {
+ "dry-run": ["1"],
+ "force": ["1"],
+ }, {
+ "nodes": ["n2", "n3"],
+ }, clfactory)
+ job_id = handler.PUT()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpGroupAssignNodes))
+ self.assertEqual(op.group_name, "grp-a")
+ self.assertEqual(op.nodes, ["n2", "n3"])
+ self.assertTrue(op.dry_run)
+ self.assertTrue(op.force)
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+
+class TestInstanceDelete(unittest.TestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+ handler = _CreateHandler(rlib2.R_2_instances_name, ["inst30965"], {
+ "dry-run": ["1"],
+ }, {}, clfactory)
+ job_id = handler.DELETE()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpInstanceRemove))
+ self.assertEqual(op.instance_name, "inst30965")
+ self.assertTrue(op.dry_run)
+ self.assertFalse(op.ignore_failures)
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+
+class TestInstanceInfo(unittest.TestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+ handler = _CreateHandler(rlib2.R_2_instances_name_info, ["inst31217"], {
+ "static": ["1"],
+ }, {}, clfactory)
+ job_id = handler.GET()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpInstanceQueryData))
+ self.assertEqual(op.instances, ["inst31217"])
+ self.assertTrue(op.static)
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+
+class TestInstanceReboot(unittest.TestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+ handler = _CreateHandler(rlib2.R_2_instances_name_reboot, ["inst847"], {
+ "dry-run": ["1"],
+ "ignore_secondaries": ["1"],
+ }, {}, clfactory)
+ job_id = handler.POST()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpInstanceReboot))
+ self.assertEqual(op.instance_name, "inst847")
+ self.assertEqual(op.reboot_type, constants.INSTANCE_REBOOT_HARD)
+ self.assertTrue(op.ignore_secondaries)
+ self.assertTrue(op.dry_run)
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+
+class TestInstanceStartup(unittest.TestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+ handler = _CreateHandler(rlib2.R_2_instances_name_startup, ["inst31083"], {
+ "force": ["1"],
+ "no_remember": ["1"],
+ }, {}, clfactory)
+ job_id = handler.PUT()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpInstanceStartup))
+ self.assertEqual(op.instance_name, "inst31083")
+ self.assertTrue(op.no_remember)
+ self.assertTrue(op.force)
+ self.assertFalse(op.dry_run)
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+
+class TestInstanceShutdown(unittest.TestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+ handler = _CreateHandler(rlib2.R_2_instances_name_shutdown, ["inst26791"], {
+ "no_remember": ["0"],
+ }, {}, clfactory)
+ job_id = handler.PUT()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpInstanceShutdown))
+ self.assertEqual(op.instance_name, "inst26791")
+ self.assertFalse(op.no_remember)
+ self.assertFalse(op.dry_run)
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+
+class TestInstanceActivateDisks(unittest.TestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+ handler = _CreateHandler(rlib2.R_2_instances_name_activate_disks, ["xyz"], {
+ "ignore_size": ["1"],
+ }, {}, clfactory)
+ job_id = handler.PUT()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpInstanceActivateDisks))
+ self.assertEqual(op.instance_name, "xyz")
+ self.assertTrue(op.ignore_size)
+ self.assertFalse(hasattr(op, "dry_run"))
- self.Parse = rlib2._ParseInstanceCreateRequestVersion1
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+class TestInstanceDeactivateDisks(unittest.TestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+ handler = _CreateHandler(rlib2.R_2_instances_name_deactivate_disks,
+ ["inst22357"], {}, {}, clfactory)
+ job_id = handler.PUT()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpInstanceDeactivateDisks))
+ self.assertEqual(op.instance_name, "inst22357")
+ self.assertFalse(hasattr(op, "dry_run"))
+ self.assertFalse(hasattr(op, "force"))
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+
+class TestInstanceRecreateDisks(unittest.TestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+ handler = _CreateHandler(rlib2.R_2_instances_name_recreate_disks,
+ ["inst22357"], {}, {}, clfactory)
+ job_id = handler.POST()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpInstanceRecreateDisks))
+ self.assertEqual(op.instance_name, "inst22357")
+ self.assertFalse(hasattr(op, "dry_run"))
+ self.assertFalse(hasattr(op, "force"))
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+
+class TestInstanceFailover(unittest.TestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+ handler = _CreateHandler(rlib2.R_2_instances_name_failover,
+ ["inst12794"], {}, {}, clfactory)
+ job_id = handler.PUT()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpInstanceFailover))
+ self.assertEqual(op.instance_name, "inst12794")
+ self.assertFalse(hasattr(op, "dry_run"))
+ self.assertFalse(hasattr(op, "force"))
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+
+class TestInstanceDiskGrow(unittest.TestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+ data = {
+ "amount": 1024,
+ }
+ handler = _CreateHandler(rlib2.R_2_instances_name_disk_grow,
+ ["inst10742", "3"], {}, data, clfactory)
+ job_id = handler.POST()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpInstanceGrowDisk))
+ self.assertEqual(op.instance_name, "inst10742")
+ self.assertEqual(op.disk, 3)
+ self.assertEqual(op.amount, 1024)
+ self.assertFalse(hasattr(op, "dry_run"))
+ self.assertFalse(hasattr(op, "force"))
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+
+class TestBackupPrepare(unittest.TestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+ queryargs = {
+ "mode": constants.EXPORT_MODE_REMOTE,
+ }
+ handler = _CreateHandler(rlib2.R_2_instances_name_prepare_export,
+ ["inst17925"], queryargs, {}, clfactory)
+ job_id = handler.PUT()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpBackupPrepare))
+ self.assertEqual(op.instance_name, "inst17925")
+ self.assertEqual(op.mode, constants.EXPORT_MODE_REMOTE)
+ self.assertFalse(hasattr(op, "dry_run"))
+ self.assertFalse(hasattr(op, "force"))
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+
+class TestGroupRemove(unittest.TestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+ handler = _CreateHandler(rlib2.R_2_groups_name,
+ ["grp28575"], {}, {}, clfactory)
+ job_id = handler.DELETE()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpGroupRemove))
+ self.assertEqual(op.group_name, "grp28575")
+ self.assertFalse(op.dry_run)
+ self.assertFalse(hasattr(op, "force"))
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+
+class TestStorageQuery(unittest.TestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+ queryargs = {
+ "storage_type": constants.ST_LVM_PV,
+ "output_fields": "name,other",
+ }
+ handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
+ ["node21075"], queryargs, {}, clfactory)
+ job_id = handler.GET()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpNodeQueryStorage))
+ self.assertEqual(op.nodes, ["node21075"])
+ self.assertEqual(op.storage_type, constants.ST_LVM_PV)
+ self.assertEqual(op.output_fields, ["name", "other"])
+ self.assertFalse(hasattr(op, "dry_run"))
+ self.assertFalse(hasattr(op, "force"))
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+ def testErrors(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ queryargs = {
+ "output_fields": "name,other",
+ }
+ handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
+ ["node10538"], queryargs, {}, clfactory)
+ self.assertRaises(http.HttpBadRequest, handler.GET)
+
+ queryargs = {
+ "storage_type": constants.ST_LVM_VG,
+ }
+ handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
+ ["node21273"], queryargs, {}, clfactory)
+ self.assertRaises(http.HttpBadRequest, handler.GET)
+
+ queryargs = {
+ "storage_type": "##unknown_storage##",
+ "output_fields": "name,other",
+ }
+ handler = _CreateHandler(rlib2.R_2_nodes_name_storage,
+ ["node10315"], queryargs, {}, clfactory)
+ self.assertRaises(http.HttpBadRequest, handler.GET)
+
+
+class TestStorageModify(unittest.TestCase):
def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ for allocatable in [None, "1", "0"]:
+ queryargs = {
+ "storage_type": constants.ST_LVM_VG,
+ "name": "pv-a",
+ }
+
+ if allocatable is not None:
+ queryargs["allocatable"] = allocatable
+
+ handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
+ ["node9292"], queryargs, {}, clfactory)
+ job_id = handler.PUT()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpNodeModifyStorage))
+ self.assertEqual(op.node_name, "node9292")
+ self.assertEqual(op.storage_type, constants.ST_LVM_VG)
+ self.assertEqual(op.name, "pv-a")
+ if allocatable is None:
+ self.assertFalse(op.changes)
+ else:
+ assert allocatable in ("0", "1")
+ self.assertEqual(op.changes, {
+ constants.SF_ALLOCATABLE: (allocatable == "1"),
+ })
+ self.assertFalse(hasattr(op, "dry_run"))
+ self.assertFalse(hasattr(op, "force"))
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+ def testErrors(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ # No storage type
+ queryargs = {
+ "name": "xyz",
+ }
+ handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
+ ["node26016"], queryargs, {}, clfactory)
+ self.assertRaises(http.HttpBadRequest, handler.PUT)
+
+ # No name
+ queryargs = {
+ "storage_type": constants.ST_LVM_VG,
+ }
+ handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
+ ["node21218"], queryargs, {}, clfactory)
+ self.assertRaises(http.HttpBadRequest, handler.PUT)
+
+ # Invalid value
+ queryargs = {
+ "storage_type": constants.ST_LVM_VG,
+ "name": "pv-b",
+ "allocatable": "noint",
+ }
+ handler = _CreateHandler(rlib2.R_2_nodes_name_storage_modify,
+ ["node30685"], queryargs, {}, clfactory)
+ self.assertRaises(http.HttpBadRequest, handler.PUT)
+
+
+class TestStorageRepair(unittest.TestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+ queryargs = {
+ "storage_type": constants.ST_LVM_PV,
+ "name": "pv16611",
+ }
+ handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
+ ["node19265"], queryargs, {}, clfactory)
+ job_id = handler.PUT()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpRepairNodeStorage))
+ self.assertEqual(op.node_name, "node19265")
+ self.assertEqual(op.storage_type, constants.ST_LVM_PV)
+ self.assertEqual(op.name, "pv16611")
+ self.assertFalse(hasattr(op, "dry_run"))
+ self.assertFalse(hasattr(op, "force"))
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+ def testErrors(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ # No storage type
+ queryargs = {
+ "name": "xyz",
+ }
+ handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
+ ["node11275"], queryargs, {}, clfactory)
+ self.assertRaises(http.HttpBadRequest, handler.PUT)
+
+ # No name
+ queryargs = {
+ "storage_type": constants.ST_LVM_VG,
+ }
+ handler = _CreateHandler(rlib2.R_2_nodes_name_storage_repair,
+ ["node21218"], queryargs, {}, clfactory)
+ self.assertRaises(http.HttpBadRequest, handler.PUT)
+
+
+class TestTags(unittest.TestCase):
+ TAG_HANDLERS = [
+ rlib2.R_2_instances_name_tags,
+ rlib2.R_2_nodes_name_tags,
+ rlib2.R_2_groups_name_tags,
+ rlib2.R_2_tags,
+ ]
+
+ def testSetAndDelete(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ for method, opcls in [("PUT", opcodes.OpTagsSet),
+ ("DELETE", opcodes.OpTagsDel)]:
+ for idx, handler in enumerate(self.TAG_HANDLERS):
+ dry_run = bool(idx % 2)
+ name = "test%s" % idx
+ queryargs = {
+ "tag": ["foo", "bar", "baz"],
+ "dry-run": str(int(dry_run)),
+ }
+
+ handler = _CreateHandler(handler, [name], queryargs, {}, clfactory)
+ job_id = getattr(handler, method)()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcls))
+ self.assertEqual(op.kind, handler.TAG_LEVEL)
+ if handler.TAG_LEVEL == constants.TAG_CLUSTER:
+ self.assertTrue(op.name is None)
+ else:
+ self.assertEqual(op.name, name)
+ self.assertEqual(op.tags, ["foo", "bar", "baz"])
+ self.assertEqual(op.dry_run, dry_run)
+ self.assertFalse(hasattr(op, "force"))
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+
+class TestInstanceCreation(testutils.GanetiTestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ name = "inst863.example.com"
+
disk_variants = [
# No disks
[],
# Disk with mode
[{"size": 123, "mode": constants.DISK_RDWR, }],
-
- # With unknown setting
- [{"size": 123, "unknown": 999 }],
]
nic_variants = [
# Two NICs
[
- { "ip": "1.2.3.4", "mode": constants.NIC_MODE_ROUTED,
+ { "ip": "192.0.2.6", "mode": constants.NIC_MODE_ROUTED,
"mac": "01:23:45:67:68:9A",
},
- { "mode": constants.NIC_MODE_BRIDGED, "link": "n0", "bridge": "br1", },
+ { "mode": constants.NIC_MODE_BRIDGED, "link": "br1" },
],
-
- # Unknown settings
- [{ "unknown": 999, }, { "foobar": "Hello World", }],
]
beparam_variants = [
None,
{},
{ constants.BE_VCPUS: 2, },
- { constants.BE_MEMORY: 123, },
+ { constants.BE_MAXMEM: 200, },
+ { constants.BE_MEMORY: 256, },
{ constants.BE_VCPUS: 2,
- constants.BE_MEMORY: 1024,
- constants.BE_AUTO_BALANCE: True, }
+ constants.BE_MAXMEM: 1024,
+ constants.BE_MINMEM: 1024,
+ constants.BE_AUTO_BALANCE: True,
+ constants.BE_ALWAYS_FAILOVER: True, }
]
hvparam_variants = [
for disks in disk_variants:
for beparams in beparam_variants:
for hvparams in hvparam_variants:
- data = {
- "name": "inst1.example.com",
- "hypervisor": constants.HT_FAKE,
- "disks": disks,
- "nics": nics,
- "mode": mode,
- "disk_template": disk_template,
- }
+ for dry_run in [False, True]:
+ queryargs = {
+ "dry-run": str(int(dry_run)),
+ }
- if beparams is not None:
- data["beparams"] = beparams
+ data = {
+ rlib2._REQ_DATA_VERSION: 1,
+ "name": name,
+ "hypervisor": constants.HT_FAKE,
+ "disks": disks,
+ "nics": nics,
+ "mode": mode,
+ "disk_template": disk_template,
+ "os": "debootstrap",
+ }
- if hvparams is not None:
- data["hvparams"] = hvparams
+ if beparams is not None:
+ data["beparams"] = beparams
- for dry_run in [False, True]:
- op = self.Parse(data, dry_run)
- self.assert_(isinstance(op, opcodes.OpCreateInstance))
+ if hvparams is not None:
+ data["hvparams"] = hvparams
+
+ handler = _CreateHandler(rlib2.R_2_instances, [],
+ queryargs, data, clfactory)
+ job_id = handler.POST()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+ self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
+ self.assertEqual(op.instance_name, name)
self.assertEqual(op.mode, mode)
self.assertEqual(op.disk_template, disk_template)
self.assertEqual(op.dry_run, dry_run)
self.assertFalse("foobar" in opnic)
if beparams is None:
- self.assertEqualValues(op.beparams, {})
+ self.assertFalse(hasattr(op, "beparams"))
else:
self.assertEqualValues(op.beparams, beparams)
if hvparams is None:
- self.assertEqualValues(op.hvparams, {})
+ self.assertFalse(hasattr(op, "hvparams"))
else:
self.assertEqualValues(op.hvparams, hvparams)
+ def testLegacyName(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ name = "inst29128.example.com"
+ data = {
+ rlib2._REQ_DATA_VERSION: 1,
+ "name": name,
+ "disks": [],
+ "nics": [],
+ "mode": constants.INSTANCE_CREATE,
+ "disk_template": constants.DT_PLAIN,
+ }
+
+ handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
+ job_id = handler.POST()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
+ self.assertEqual(op.instance_name, name)
+ self.assertFalse(hasattr(op, "name"))
+ self.assertFalse(op.dry_run)
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+ # Define both
+ data["instance_name"] = "other.example.com"
+ assert "name" in data and "instance_name" in data
+ handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
+ self.assertRaises(http.HttpBadRequest, handler.POST)
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ def testLegacyOs(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ name = "inst4673.example.com"
+ os = "linux29206"
+ data = {
+ rlib2._REQ_DATA_VERSION: 1,
+ "name": name,
+ "os_type": os,
+ "disks": [],
+ "nics": [],
+ "mode": constants.INSTANCE_CREATE,
+ "disk_template": constants.DT_PLAIN,
+ }
+
+ handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
+ job_id = handler.POST()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
+ self.assertEqual(op.instance_name, name)
+ self.assertEqual(op.os_type, os)
+ self.assertFalse(hasattr(op, "os"))
+ self.assertFalse(op.dry_run)
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+ # Define both
+ data["os"] = "linux9584"
+ assert "os" in data and "os_type" in data
+ handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
+ self.assertRaises(http.HttpBadRequest, handler.POST)
+
def testErrors(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
# Test all required fields
reqfields = {
+ rlib2._REQ_DATA_VERSION: 1,
"name": "inst1.example.com",
"disks": [],
"nics": [],
"mode": constants.INSTANCE_CREATE,
- "disk_template": constants.DT_PLAIN
+ "disk_template": constants.DT_PLAIN,
}
for name in reqfields.keys():
- self.assertRaises(http.HttpBadRequest, self.Parse,
- dict(i for i in reqfields.iteritems() if i[0] != name),
- False)
+ data = dict(i for i in reqfields.iteritems() if i[0] != name)
+
+ handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
+ self.assertRaises(http.HttpBadRequest, handler.POST)
+ self.assertRaises(IndexError, clfactory.GetNextClient)
# Invalid disks and nics
for field in ["disks", "nics"]:
- invalid_values = [None, 1, "", {}, [1, 2, 3], ["hda1", "hda2"]]
-
- if field == "disks":
- invalid_values.append([
- # Disks without size
- {},
- { "mode": constants.DISK_RDWR, },
- ])
+ invalid_values = [None, 1, "", {}, [1, 2, 3], ["hda1", "hda2"],
+ [{"_unknown_": 999, }]]
for invvalue in invalid_values:
data = reqfields.copy()
data[field] = invvalue
- self.assertRaises(http.HttpBadRequest, self.Parse, data, False)
+ handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
+ self.assertRaises(http.HttpBadRequest, handler.POST)
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ def testVersion(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ # No version field
+ data = {
+ "name": "inst1.example.com",
+ "disks": [],
+ "nics": [],
+ "mode": constants.INSTANCE_CREATE,
+ "disk_template": constants.DT_PLAIN,
+ }
+
+ handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
+ self.assertRaises(http.HttpBadRequest, handler.POST)
+
+ # Old and incorrect versions
+ for version in [0, -1, 10483, "Hello World"]:
+ data[rlib2._REQ_DATA_VERSION] = version
+
+ handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
+ self.assertRaises(http.HttpBadRequest, handler.POST)
+
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ # Correct version
+ data[rlib2._REQ_DATA_VERSION] = 1
+ handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
+ job_id = handler.POST()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+
+class TestBackupExport(unittest.TestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ name = "instmoo"
+ data = {
+ "mode": constants.EXPORT_MODE_REMOTE,
+ "destination": [(1, 2, 3), (99, 99, 99)],
+ "shutdown": True,
+ "remove_instance": True,
+ "x509_key_name": ["name", "hash"],
+ "destination_x509_ca": "---cert---"
+ }
+
+ handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
+ data, clfactory)
+ job_id = handler.PUT()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpBackupExport))
+ self.assertEqual(op.instance_name, name)
+ self.assertEqual(op.mode, constants.EXPORT_MODE_REMOTE)
+ self.assertEqual(op.target_node, [(1, 2, 3), (99, 99, 99)])
+ self.assertEqual(op.shutdown, True)
+ self.assertEqual(op.remove_instance, True)
+ self.assertEqual(op.x509_key_name, ["name", "hash"])
+ self.assertEqual(op.destination_x509_ca, "---cert---")
+ self.assertFalse(hasattr(op, "dry_run"))
+ self.assertFalse(hasattr(op, "force"))
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+ def testDefaults(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ name = "inst1"
+ data = {
+ "destination": "node2",
+ "shutdown": False,
+ }
+
+ handler = _CreateHandler(rlib2.R_2_instances_name_export, [name], {},
+ data, clfactory)
+ job_id = handler.PUT()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpBackupExport))
+ self.assertEqual(op.instance_name, name)
+ self.assertEqual(op.target_node, "node2")
+ self.assertFalse(hasattr(op, "mode"))
+ self.assertFalse(hasattr(op, "remove_instance"))
+ self.assertFalse(hasattr(op, "destination"))
+ self.assertFalse(hasattr(op, "dry_run"))
+ self.assertFalse(hasattr(op, "force"))
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+ def testErrors(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ for value in ["True", "False"]:
+ handler = _CreateHandler(rlib2.R_2_instances_name_export, ["err1"], {}, {
+ "remove_instance": value,
+ }, clfactory)
+ self.assertRaises(http.HttpBadRequest, handler.PUT)
+
+
+class TestInstanceMigrate(testutils.GanetiTestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ name = "instYooho6ek"
+
+ for cleanup in [False, True]:
+ for mode in constants.HT_MIGRATION_MODES:
+ data = {
+ "cleanup": cleanup,
+ "mode": mode,
+ }
+
+ handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {},
+ data, clfactory)
+ job_id = handler.PUT()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpInstanceMigrate))
+ self.assertEqual(op.instance_name, name)
+ self.assertEqual(op.mode, mode)
+ self.assertEqual(op.cleanup, cleanup)
+ self.assertFalse(hasattr(op, "dry_run"))
+ self.assertFalse(hasattr(op, "force"))
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+ def testDefaults(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ name = "instnohZeex0"
+
+ handler = _CreateHandler(rlib2.R_2_instances_name_migrate, [name], {}, {},
+ clfactory)
+ job_id = handler.PUT()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpInstanceMigrate))
+ self.assertEqual(op.instance_name, name)
+ self.assertFalse(hasattr(op, "mode"))
+ self.assertFalse(hasattr(op, "cleanup"))
+ self.assertFalse(hasattr(op, "dry_run"))
+ self.assertFalse(hasattr(op, "force"))
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+
+class TestParseRenameInstanceRequest(testutils.GanetiTestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ name = "instij0eeph7"
+
+ for new_name in ["ua0aiyoo", "fai3ongi"]:
+ for ip_check in [False, True]:
+ for name_check in [False, True]:
+ data = {
+ "new_name": new_name,
+ "ip_check": ip_check,
+ "name_check": name_check,
+ }
+
+ handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
+ {}, data, clfactory)
+ job_id = handler.PUT()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpInstanceRename))
+ self.assertEqual(op.instance_name, name)
+ self.assertEqual(op.new_name, new_name)
+ self.assertEqual(op.ip_check, ip_check)
+ self.assertEqual(op.name_check, name_check)
+ self.assertFalse(hasattr(op, "dry_run"))
+ self.assertFalse(hasattr(op, "force"))
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+ def testDefaults(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ name = "instahchie3t"
+
+ for new_name in ["thag9mek", "quees7oh"]:
+ data = {
+ "new_name": new_name,
+ }
+
+ handler = _CreateHandler(rlib2.R_2_instances_name_rename, [name],
+ {}, data, clfactory)
+ job_id = handler.PUT()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpInstanceRename))
+ self.assertEqual(op.instance_name, name)
+ self.assertEqual(op.new_name, new_name)
+ self.assertFalse(hasattr(op, "ip_check"))
+ self.assertFalse(hasattr(op, "name_check"))
+ self.assertFalse(hasattr(op, "dry_run"))
+ self.assertFalse(hasattr(op, "force"))
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+
+class TestParseModifyInstanceRequest(unittest.TestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ name = "instush8gah"
+
+ test_disks = [
+ [],
+ [(1, { constants.IDISK_MODE: constants.DISK_RDWR, })],
+ ]
+
+ for osparams in [{}, { "some": "value", "other": "Hello World", }]:
+ for hvparams in [{}, { constants.HV_KERNEL_PATH: "/some/kernel", }]:
+ for beparams in [{}, { constants.BE_MAXMEM: 128, }]:
+ for force in [False, True]:
+ for nics in [[], [(0, { constants.INIC_IP: "192.0.2.1", })]]:
+ for disks in test_disks:
+ for disk_template in constants.DISK_TEMPLATES:
+ data = {
+ "osparams": osparams,
+ "hvparams": hvparams,
+ "beparams": beparams,
+ "nics": nics,
+ "disks": disks,
+ "force": force,
+ "disk_template": disk_template,
+ }
+
+ handler = _CreateHandler(rlib2.R_2_instances_name_modify,
+ [name], {}, data, clfactory)
+ job_id = handler.PUT()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
+ self.assertEqual(op.instance_name, name)
+ self.assertEqual(op.hvparams, hvparams)
+ self.assertEqual(op.beparams, beparams)
+ self.assertEqual(op.osparams, osparams)
+ self.assertEqual(op.force, force)
+ self.assertEqual(op.nics, nics)
+ self.assertEqual(op.disks, disks)
+ self.assertEqual(op.disk_template, disk_template)
+ self.assertFalse(hasattr(op, "remote_node"))
+ self.assertFalse(hasattr(op, "os_name"))
+ self.assertFalse(hasattr(op, "force_variant"))
+ self.assertFalse(hasattr(op, "dry_run"))
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+ def testDefaults(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ name = "instir8aish31"
+
+ handler = _CreateHandler(rlib2.R_2_instances_name_modify,
+ [name], {}, {}, clfactory)
+ job_id = handler.PUT()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpInstanceSetParams))
+ self.assertEqual(op.instance_name, name)
+
+ for i in ["hvparams", "beparams", "osparams", "force", "nics", "disks",
+ "disk_template", "remote_node", "os_name", "force_variant"]:
+ self.assertFalse(hasattr(op, i))
+
+
+class TestParseInstanceReinstallRequest(testutils.GanetiTestCase):
+ def setUp(self):
+ testutils.GanetiTestCase.setUp(self)
+
+ self.Parse = rlib2._ParseInstanceReinstallRequest
+
+ def _Check(self, ops, name):
+ expcls = [
+ opcodes.OpInstanceShutdown,
+ opcodes.OpInstanceReinstall,
+ opcodes.OpInstanceStartup,
+ ]
+
+ self.assert_(compat.all(isinstance(op, exp)
+ for op, exp in zip(ops, expcls)))
+ self.assert_(compat.all(op.instance_name == name for op in ops))
+
+ def test(self):
+ name = "shoo0tihohma"
+
+ ops = self.Parse(name, {"os": "sys1", "start": True,})
+ self.assertEqual(len(ops), 3)
+ self._Check(ops, name)
+ self.assertEqual(ops[1].os_type, "sys1")
+ self.assertFalse(ops[1].osparams)
+
+ ops = self.Parse(name, {"os": "sys2", "start": False,})
+ self.assertEqual(len(ops), 2)
+ self._Check(ops, name)
+ self.assertEqual(ops[1].os_type, "sys2")
+
+ osparams = {
+ "reformat": "1",
+ }
+ ops = self.Parse(name, {"os": "sys4035", "start": True,
+ "osparams": osparams,})
+ self.assertEqual(len(ops), 3)
+ self._Check(ops, name)
+ self.assertEqual(ops[1].os_type, "sys4035")
+ self.assertEqual(ops[1].osparams, osparams)
+
+ def testDefaults(self):
+ name = "noolee0g"
+
+ ops = self.Parse(name, {"os": "linux1"})
+ self.assertEqual(len(ops), 3)
+ self._Check(ops, name)
+ self.assertEqual(ops[1].os_type, "linux1")
+ self.assertFalse(ops[1].osparams)
+
+ def testErrors(self):
+ self.assertRaises(http.HttpBadRequest, self.Parse,
+ "foo", "not a dictionary")
+
+
+class TestGroupRename(unittest.TestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ name = "group608242564"
+ data = {
+ "new_name": "ua0aiyoo15112",
+ }
+
+ handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {}, data,
+ clfactory)
+ job_id = handler.PUT()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+
+ self.assertTrue(isinstance(op, opcodes.OpGroupRename))
+ self.assertEqual(op.group_name, name)
+ self.assertEqual(op.new_name, "ua0aiyoo15112")
+ self.assertFalse(op.dry_run)
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+ def testDryRun(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ name = "group28548"
+ data = {
+ "new_name": "ua0aiyoo",
+ }
+
+ handler = _CreateHandler(rlib2.R_2_groups_name_rename, [name], {
+ "dry-run": ["1"],
+ }, data, clfactory)
+ job_id = handler.PUT()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+
+ self.assertTrue(isinstance(op, opcodes.OpGroupRename))
+ self.assertEqual(op.group_name, name)
+ self.assertEqual(op.new_name, "ua0aiyoo")
+ self.assertTrue(op.dry_run)
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+
+class TestInstanceReplaceDisks(unittest.TestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ name = "inst22568"
+
+ for disks in [range(1, 4), "1,2,3", "1, 2, 3"]:
+ data = {
+ "mode": constants.REPLACE_DISK_SEC,
+ "disks": disks,
+ "iallocator": "myalloc",
+ }
+
+ handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
+ [name], {}, data, clfactory)
+ job_id = handler.POST()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+
+ self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
+ self.assertEqual(op.instance_name, name)
+ self.assertEqual(op.mode, constants.REPLACE_DISK_SEC)
+ self.assertEqual(op.disks, [1, 2, 3])
+ self.assertEqual(op.iallocator, "myalloc")
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+ def testDefaults(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ name = "inst11413"
+ data = {
+ "mode": constants.REPLACE_DISK_AUTO,
+ }
+
+ handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
+ [name], {}, data, clfactory)
+ job_id = handler.POST()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+
+ self.assertTrue(isinstance(op, opcodes.OpInstanceReplaceDisks))
+ self.assertEqual(op.instance_name, name)
+ self.assertEqual(op.mode, constants.REPLACE_DISK_AUTO)
+ self.assertFalse(hasattr(op, "iallocator"))
+ self.assertFalse(hasattr(op, "disks"))
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+ def testNoDisks(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
+ ["inst20661"], {}, {}, clfactory)
+ self.assertRaises(http.HttpBadRequest, handler.POST)
+
+ for disks in [None, "", {}]:
+ handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
+ ["inst20661"], {}, {
+ "disks": disks,
+ }, clfactory)
+ self.assertRaises(http.HttpBadRequest, handler.POST)
+
+ def testWrong(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ data = {
+ "mode": constants.REPLACE_DISK_AUTO,
+ "disks": "hello world",
+ }
+
+ handler = _CreateHandler(rlib2.R_2_instances_name_replace_disks,
+ ["foo"], {}, data, clfactory)
+ self.assertRaises(http.HttpBadRequest, handler.POST)
+
+
+class TestGroupModify(unittest.TestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ name = "group6002"
+
+ for policy in constants.VALID_ALLOC_POLICIES:
+ data = {
+ "alloc_policy": policy,
+ }
+
+ handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, data,
+ clfactory)
+ job_id = handler.PUT()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+
+ self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
+ self.assertEqual(op.group_name, name)
+ self.assertEqual(op.alloc_policy, policy)
+ self.assertFalse(hasattr(op, "dry_run"))
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+ def testUnknownPolicy(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ data = {
+ "alloc_policy": "_unknown_policy_",
+ }
+
+ handler = _CreateHandler(rlib2.R_2_groups_name_modify, ["xyz"], {}, data,
+ clfactory)
+ self.assertRaises(http.HttpBadRequest, handler.PUT)
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ def testDefaults(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ name = "group6679"
+
+ handler = _CreateHandler(rlib2.R_2_groups_name_modify, [name], {}, {},
+ clfactory)
+ job_id = handler.PUT()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+
+ self.assertTrue(isinstance(op, opcodes.OpGroupSetParams))
+ self.assertEqual(op.group_name, name)
+ self.assertFalse(hasattr(op, "alloc_policy"))
+ self.assertFalse(hasattr(op, "dry_run"))
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+
+class TestGroupAdd(unittest.TestCase):
+ def test(self):
+ name = "group3618"
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ for policy in constants.VALID_ALLOC_POLICIES:
+ data = {
+ "group_name": name,
+ "alloc_policy": policy,
+ }
+
+ handler = _CreateHandler(rlib2.R_2_groups, [], {}, data,
+ clfactory)
+ job_id = handler.POST()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+
+ self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
+ self.assertEqual(op.group_name, name)
+ self.assertEqual(op.alloc_policy, policy)
+ self.assertFalse(op.dry_run)
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+ def testUnknownPolicy(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ data = {
+ "alloc_policy": "_unknown_policy_",
+ }
+
+ handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
+ self.assertRaises(http.HttpBadRequest, handler.POST)
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ def testDefaults(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ name = "group15395"
+ data = {
+ "group_name": name,
+ }
+
+ handler = _CreateHandler(rlib2.R_2_groups, [], {}, data, clfactory)
+ job_id = handler.POST()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+
+ self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
+ self.assertEqual(op.group_name, name)
+ self.assertFalse(hasattr(op, "alloc_policy"))
+ self.assertFalse(op.dry_run)
+
+ def testLegacyName(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ name = "group29852"
+ data = {
+ "name": name,
+ }
+
+ handler = _CreateHandler(rlib2.R_2_groups, [], {
+ "dry-run": ["1"],
+ }, data, clfactory)
+ job_id = handler.POST()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+
+ self.assertTrue(isinstance(op, opcodes.OpGroupAdd))
+ self.assertEqual(op.group_name, name)
+ self.assertFalse(hasattr(op, "alloc_policy"))
+ self.assertTrue(op.dry_run)
+
+
+class TestNodeRole(unittest.TestCase):
+ def test(self):
+ clfactory = _FakeClientFactory(_FakeClient)
+
+ for role in rlib2._NR_MAP.values():
+ handler = _CreateHandler(rlib2.R_2_nodes_name_role,
+ ["node-z"], {}, role, clfactory)
+ if role == rlib2._NR_MASTER:
+ self.assertRaises(http.HttpBadRequest, handler.PUT)
+ else:
+ job_id = handler.PUT()
+
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+
+ (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
+ self.assertEqual(job_id, exp_job_id)
+ self.assertTrue(isinstance(op, opcodes.OpNodeSetParams))
+ self.assertEqual(op.node_name, "node-z")
+ self.assertFalse(op.force)
+ self.assertFalse(hasattr(op, "dry_run"))
+
+ if role == rlib2._NR_REGULAR:
+ self.assertFalse(op.drained)
+ self.assertFalse(op.offline)
+ self.assertFalse(op.master_candidate)
+ elif role == rlib2._NR_MASTER_CANDIDATE:
+ self.assertFalse(op.drained)
+ self.assertFalse(op.offline)
+ self.assertTrue(op.master_candidate)
+ elif role == rlib2._NR_DRAINED:
+ self.assertTrue(op.drained)
+ self.assertFalse(op.offline)
+ self.assertFalse(op.master_candidate)
+ elif role == rlib2._NR_OFFLINE:
+ self.assertFalse(op.drained)
+ self.assertTrue(op.offline)
+ self.assertFalse(op.master_candidate)
+ else:
+ self.fail("Unknown role '%s'" % role)
+
+ self.assertRaises(IndexError, cl.GetNextSubmittedJob)
+
+
+class TestSimpleResources(unittest.TestCase):
+ def setUp(self):
+ self.clfactory = _FakeClientFactory(_FakeClient)
+
+ def tearDown(self):
+ self.assertRaises(IndexError, self.clfactory.GetNextClient)
+
+ def testFeatures(self):
+ handler = _CreateHandler(rlib2.R_2_features, [], {}, None, self.clfactory)
+ self.assertEqual(set(handler.GET()), rlib2.ALL_FEATURES)
+
+ def testEmpty(self):
+ for cls in [rlib2.R_root, rlib2.R_2]:
+ handler = _CreateHandler(cls, [], {}, None, self.clfactory)
+ self.assertTrue(handler.GET() is None)
+
+ def testVersion(self):
+ handler = _CreateHandler(rlib2.R_version, [], {}, None, self.clfactory)
+ self.assertEqual(handler.GET(), constants.RAPI_VERSION)
+
+
+class TestClusterInfo(unittest.TestCase):
+ class _ClusterInfoClient:
+ def __init__(self):
+ self.cluster_info = None
+
+ def QueryClusterInfo(self):
+ assert self.cluster_info is None
+ self.cluster_info = object()
+ return self.cluster_info
+
+ def test(self):
+ clfactory = _FakeClientFactory(self._ClusterInfoClient)
+ handler = _CreateHandler(rlib2.R_2_info, [], {}, None, clfactory)
+ result = handler.GET()
+ cl = clfactory.GetNextClient()
+ self.assertRaises(IndexError, clfactory.GetNextClient)
+ self.assertEqual(result, cl.cluster_info)
if __name__ == '__main__':