+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, address=None):
+ 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, address=None):
+ cl = self._client_cls(address=address)
+ 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(address=None):
+ 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:
+ def __init__(self, address=None):
+ pass
+
+ @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.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)
+