X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/3175ade6ed74dd5570590572bd780f2e3f58d97f..99ccf8b915722aaed2029d189b3d522d5a6c8760:/test/ganeti.rapi.rlib2_unittest.py diff --git a/test/ganeti.rapi.rlib2_unittest.py b/test/ganeti.rapi.rlib2_unittest.py index 74b5780..cde68ce 100755 --- a/test/ganeti.rapi.rlib2_unittest.py +++ b/test/ganeti.rapi.rlib2_unittest.py @@ -272,6 +272,26 @@ class TestNodeEvacuate(unittest.TestCase): 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) @@ -405,13 +425,368 @@ class TestInstanceShutdown(unittest.TestCase): self.assertRaises(IndexError, cl.GetNextSubmittedJob) -class TestParseInstanceCreateRequestVersion1(testutils.GanetiTestCase): - def setUp(self): - testutils.GanetiTestCase.setUp(self) +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.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) - self.Parse = rlib2._ParseInstanceCreateRequestVersion1 + # 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 [], @@ -443,10 +818,13 @@ class TestParseInstanceCreateRequestVersion1(testutils.GanetiTestCase): 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 = [ @@ -462,25 +840,41 @@ class TestParseInstanceCreateRequestVersion1(testutils.GanetiTestCase): 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, - "os": "debootstrap", - } - - if beparams is not None: - data["beparams"] = beparams - - if hvparams is not None: - data["hvparams"] = hvparams - for dry_run in [False, True]: - op = self.Parse(data, dry_run) - self.assert_(isinstance(op, opcodes.OpInstanceCreate)) + queryargs = { + "dry-run": str(int(dry_run)), + } + + 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 beparams is not None: + data["beparams"] = beparams + + 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) @@ -509,34 +903,47 @@ class TestParseInstanceCreateRequestVersion1(testutils.GanetiTestCase): 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, } - op = self.Parse(data, False) - self.assert_(isinstance(op, opcodes.OpInstanceCreate)) + + 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 = { - "name": name, - "instance_name": "other.example.com", - "disks": [], - "nics": [], - "mode": constants.INSTANCE_CREATE, - "disk_template": constants.DT_PLAIN, - } - self.assertRaises(http.HttpBadRequest, self.Parse, data, False) + 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": [], @@ -544,27 +951,35 @@ class TestParseInstanceCreateRequestVersion1(testutils.GanetiTestCase): "mode": constants.INSTANCE_CREATE, "disk_template": constants.DT_PLAIN, } - op = self.Parse(data, False) - self.assert_(isinstance(op, opcodes.OpInstanceCreate)) + + 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 = { - "instance_name": name, - "os": os, - "os_type": "linux9584", - "disks": [], - "nics": [], - "mode": constants.INSTANCE_CREATE, - "disk_template": constants.DT_PLAIN, - } - self.assertRaises(http.HttpBadRequest, self.Parse, data, False) + 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": [], @@ -573,9 +988,11 @@ class TestParseInstanceCreateRequestVersion1(testutils.GanetiTestCase): } 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"]: @@ -585,16 +1002,52 @@ class TestParseInstanceCreateRequestVersion1(testutils.GanetiTestCase): 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) -class TestParseExportInstanceRequest(testutils.GanetiTestCase): - def setUp(self): - testutils.GanetiTestCase.setUp(self) + # 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 - self.Parse = rlib2._ParseExportInstanceRequest + 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, @@ -604,43 +1057,72 @@ class TestParseExportInstanceRequest(testutils.GanetiTestCase): "x509_key_name": ["name", "hash"], "destination_x509_ca": "---cert---" } - op = self.Parse(name, data) - self.assert_(isinstance(op, opcodes.OpBackupExport)) + + 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.assertEqualValues(op.x509_key_name, ("name", "hash")) + 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, } - op = self.Parse(name, data) - self.assert_(isinstance(op, opcodes.OpBackupExport)) + + 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")) - def testErrors(self): - self.assertRaises(http.HttpBadRequest, self.Parse, "err1", - { "remove_instance": "True", }) - self.assertRaises(http.HttpBadRequest, self.Parse, "err1", - { "remove_instance": "False", }) + self.assertRaises(IndexError, cl.GetNextSubmittedJob) + def testErrors(self): + clfactory = _FakeClientFactory(_FakeClient) -class TestParseMigrateInstanceRequest(testutils.GanetiTestCase): - def setUp(self): - testutils.GanetiTestCase.setUp(self) + for value in ["True", "False"]: + handler = _CreateHandler(rlib2.R_2_instances_name_export, ["err1"], {}, { + "remove_instance": value, + }, clfactory) + self.assertRaises(http.HttpBadRequest, handler.PUT) - self.Parse = rlib2._ParseMigrateInstanceRequest +class TestInstanceMigrate(testutils.GanetiTestCase): def test(self): + clfactory = _FakeClientFactory(_FakeClient) + name = "instYooho6ek" for cleanup in [False, True]: @@ -649,29 +1131,53 @@ class TestParseMigrateInstanceRequest(testutils.GanetiTestCase): "cleanup": cleanup, "mode": mode, } - op = self.Parse(name, data) - self.assert_(isinstance(op, opcodes.OpInstanceMigrate)) + + 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" - op = self.Parse(name, {}) - self.assert_(isinstance(op, opcodes.OpInstanceMigrate)) + 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 setUp(self): - testutils.GanetiTestCase.setUp(self) - - self.Parse = rlib2._ParseRenameInstanceRequest +class TestParseRenameInstanceRequest(testutils.GanetiTestCase): def test(self): + clfactory = _FakeClientFactory(_FakeClient) + name = "instij0eeph7" for new_name in ["ua0aiyoo", "fai3ongi"]: @@ -683,14 +1189,28 @@ class TestParseRenameInstanceRequest(testutils.GanetiTestCase): "name_check": name_check, } - op = self.Parse(name, data) - self.assert_(isinstance(op, opcodes.OpInstanceRename)) + 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"]: @@ -698,21 +1218,30 @@ class TestParseRenameInstanceRequest(testutils.GanetiTestCase): "new_name": new_name, } - op = self.Parse(name, data) - self.assert_(isinstance(op, opcodes.OpInstanceRename)) + 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(testutils.GanetiTestCase): - def setUp(self): - testutils.GanetiTestCase.setUp(self) - - self.Parse = rlib2._ParseModifyInstanceRequest +class TestParseModifyInstanceRequest(unittest.TestCase): def test(self): + clfactory = _FakeClientFactory(_FakeClient) + name = "instush8gah" test_disks = [ @@ -722,7 +1251,7 @@ class TestParseModifyInstanceRequest(testutils.GanetiTestCase): for osparams in [{}, { "some": "value", "other": "Hello World", }]: for hvparams in [{}, { constants.HV_KERNEL_PATH: "/some/kernel", }]: - for beparams in [{}, { constants.BE_MEMORY: 128, }]: + 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: @@ -737,8 +1266,16 @@ class TestParseModifyInstanceRequest(testutils.GanetiTestCase): "disk_template": disk_template, } - op = self.Parse(name, data) - self.assert_(isinstance(op, opcodes.OpInstanceSetParams)) + 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) @@ -750,13 +1287,27 @@ class TestParseModifyInstanceRequest(testutils.GanetiTestCase): 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" - op = self.Parse(name, {}) - self.assert_(isinstance(op, opcodes.OpInstanceSetParams)) + 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)) @@ -812,6 +1363,10 @@ class TestParseInstanceReinstallRequest(testutils.GanetiTestCase): 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): @@ -864,11 +1419,10 @@ class TestGroupRename(unittest.TestCase): self.assertRaises(IndexError, cl.GetNextSubmittedJob) -class TestParseInstanceReplaceDisksRequest(unittest.TestCase): - def setUp(self): - self.Parse = rlib2._ParseInstanceReplaceDisksRequest - +class TestInstanceReplaceDisks(unittest.TestCase): def test(self): + clfactory = _FakeClientFactory(_FakeClient) + name = "inst22568" for disks in [range(1, 4), "1,2,3", "1, 2, 3"]: @@ -878,29 +1432,73 @@ class TestParseInstanceReplaceDisksRequest(unittest.TestCase): "iallocator": "myalloc", } - op = self.Parse(name, data) - self.assert_(isinstance(op, opcodes.OpInstanceReplaceDisks)) + 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, } - op = self.Parse(name, data) - self.assert_(isinstance(op, opcodes.OpInstanceReplaceDisks)) + 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): - self.assertRaises(http.HttpBadRequest, self.Parse, "inst", - { "mode": constants.REPLACE_DISK_AUTO, - "disks": "hello world", - }) + 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): @@ -1049,5 +1647,89 @@ class TestGroupAdd(unittest.TestCase): 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__': testutils.GanetiTestProgram()