X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/2e5c33dbbcc0f235e251e83cefc51cb12d648e41..ef86bf28efce5c4002710dbbd5675e2057f21783:/test/ganeti.rapi.client_unittest.py diff --git a/test/ganeti.rapi.client_unittest.py b/test/ganeti.rapi.client_unittest.py index c84f72e..a09d4a2 100755 --- a/test/ganeti.rapi.client_unittest.py +++ b/test/ganeti.rapi.client_unittest.py @@ -22,7 +22,6 @@ """Script for unittesting the RAPI client module""" -import re import unittest import warnings import pycurl @@ -33,7 +32,9 @@ from ganeti import serializer from ganeti import utils from ganeti import query from ganeti import objects +from ganeti import rapi +import ganeti.rapi.testutils from ganeti.rapi import connector from ganeti.rapi import rlib2 from ganeti.rapi import client @@ -41,8 +42,6 @@ from ganeti.rapi import client import testutils -_URI_RE = re.compile(r"https://(?P.*):(?P\d+)(?P/.*)") - # List of resource handlers which aren't used by the RAPI client _KNOWN_UNUSED = set([ rlib2.R_root, @@ -53,49 +52,6 @@ _KNOWN_UNUSED = set([ _used_handlers = None -def _GetPathFromUri(uri): - """Gets the path and query from a URI. - - """ - match = _URI_RE.match(uri) - if match: - return match.groupdict()["path"] - else: - return None - - -class FakeCurl: - def __init__(self, rapi): - self._rapi = rapi - self._opts = {} - self._info = {} - - def setopt(self, opt, value): - self._opts[opt] = value - - def getopt(self, opt): - return self._opts.get(opt) - - def unsetopt(self, opt): - self._opts.pop(opt, None) - - def getinfo(self, info): - return self._info[info] - - def perform(self): - method = self._opts[pycurl.CUSTOMREQUEST] - url = self._opts[pycurl.URL] - request_body = self._opts[pycurl.POSTFIELDS] - writefn = self._opts[pycurl.WRITEFUNCTION] - - path = _GetPathFromUri(url) - (code, resp_body) = self._rapi.FetchResponse(path, method, request_body) - - self._info[pycurl.RESPONSE_CODE] = code - if resp_body is not None: - writefn(resp_body) - - class RapiMock(object): def __init__(self): self._mapper = connector.Mapper() @@ -118,7 +74,7 @@ class RapiMock(object): def GetLastRequestData(self): return self._last_req_data - def FetchResponse(self, path, method, request_body): + def FetchResponse(self, path, method, headers, request_body): self._last_req_data = request_body try: @@ -149,11 +105,6 @@ class TestConstants(unittest.TestCase): self.assertEqual(client.GANETI_RAPI_VERSION, constants.RAPI_VERSION) self.assertEqual(client.HTTP_APP_JSON, http.HTTP_APP_JSON) self.assertEqual(client._REQ_DATA_VERSION_FIELD, rlib2._REQ_DATA_VERSION) - self.assertEqual(client._INST_CREATE_REQV1, rlib2._INST_CREATE_REQV1) - self.assertEqual(client._INST_REINSTALL_REQV1, rlib2._INST_REINSTALL_REQV1) - self.assertEqual(client._NODE_MIGRATE_REQV1, rlib2._NODE_MIGRATE_REQV1) - self.assertEqual(client._NODE_EVAC_RES1, rlib2._NODE_EVAC_RES1) - self.assertEqual(client._INST_NIC_PARAMS, constants.INIC_PARAMS) self.assertEqual(client.JOB_STATUS_QUEUED, constants.JOB_STATUS_QUEUED) self.assertEqual(client.JOB_STATUS_WAITING, constants.JOB_STATUS_WAITING) self.assertEqual(client.JOB_STATUS_CANCELING, @@ -165,19 +116,34 @@ class TestConstants(unittest.TestCase): self.assertEqual(client.JOB_STATUS_FINALIZED, constants.JOBS_FINALIZED) self.assertEqual(client.JOB_STATUS_ALL, constants.JOB_STATUS_ALL) + # Node evacuation + self.assertEqual(client.NODE_EVAC_PRI, constants.NODE_EVAC_PRI) + self.assertEqual(client.NODE_EVAC_SEC, constants.NODE_EVAC_SEC) + self.assertEqual(client.NODE_EVAC_ALL, constants.NODE_EVAC_ALL) + # Legacy name self.assertEqual(client.JOB_STATUS_WAITLOCK, constants.JOB_STATUS_WAITING) + # RAPI feature strings + self.assertEqual(client._INST_CREATE_REQV1, rlib2._INST_CREATE_REQV1) + self.assertEqual(client.INST_CREATE_REQV1, rlib2._INST_CREATE_REQV1) + self.assertEqual(client._INST_REINSTALL_REQV1, rlib2._INST_REINSTALL_REQV1) + self.assertEqual(client.INST_REINSTALL_REQV1, rlib2._INST_REINSTALL_REQV1) + self.assertEqual(client._NODE_MIGRATE_REQV1, rlib2._NODE_MIGRATE_REQV1) + self.assertEqual(client.NODE_MIGRATE_REQV1, rlib2._NODE_MIGRATE_REQV1) + self.assertEqual(client._NODE_EVAC_RES1, rlib2._NODE_EVAC_RES1) + self.assertEqual(client.NODE_EVAC_RES1, rlib2._NODE_EVAC_RES1) + class RapiMockTest(unittest.TestCase): def test(self): rapi = RapiMock() path = "/version" - self.assertEqual((404, None), rapi.FetchResponse("/foo", "GET", None)) + self.assertEqual((404, None), rapi.FetchResponse("/foo", "GET", None, None)) self.assertEqual((501, "Method not implemented"), - rapi.FetchResponse("/version", "POST", None)) + rapi.FetchResponse("/version", "POST", None, None)) rapi.AddResponse("2") - code, response = rapi.FetchResponse("/version", "GET", None) + code, response = rapi.FetchResponse("/version", "GET", None, None) self.assertEqual(200, code) self.assertEqual("2", response) self.failUnless(isinstance(rapi.GetLastHandler(), rlib2.R_version)) @@ -206,8 +172,8 @@ def _FakeGnuTlsPycurlVersion(): class TestExtendedConfig(unittest.TestCase): def testAuth(self): cl = client.GanetiRapiClient("master.example.com", - username="user", password="pw", - curl_factory=lambda: FakeCurl(RapiMock())) + username="user", password="pw", + curl_factory=lambda: rapi.testutils.FakeCurl(RapiMock())) curl = cl._CreateCurl() self.assertEqual(curl.getopt(pycurl.HTTPAUTH), pycurl.HTTPAUTH_BASIC) @@ -244,7 +210,7 @@ class TestExtendedConfig(unittest.TestCase): verify_hostname=verify_hostname, _pycurl_version_fn=pcverfn) - curl_factory = lambda: FakeCurl(RapiMock()) + curl_factory = lambda: rapi.testutils.FakeCurl(RapiMock()) cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn, curl_factory=curl_factory) @@ -261,7 +227,7 @@ class TestExtendedConfig(unittest.TestCase): def testNoCertVerify(self): cfgfn = client.GenericCurlConfig() - curl_factory = lambda: FakeCurl(RapiMock()) + curl_factory = lambda: rapi.testutils.FakeCurl(RapiMock()) cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn, curl_factory=curl_factory) @@ -273,7 +239,7 @@ class TestExtendedConfig(unittest.TestCase): def testCertVerifyCurlBundle(self): cfgfn = client.GenericCurlConfig(use_curl_cabundle=True) - curl_factory = lambda: FakeCurl(RapiMock()) + curl_factory = lambda: rapi.testutils.FakeCurl(RapiMock()) cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn, curl_factory=curl_factory) @@ -286,7 +252,7 @@ class TestExtendedConfig(unittest.TestCase): mycert = "/tmp/some/UNUSED/cert/file.pem" cfgfn = client.GenericCurlConfig(cafile=mycert) - curl_factory = lambda: FakeCurl(RapiMock()) + curl_factory = lambda: rapi.testutils.FakeCurl(RapiMock()) cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn, curl_factory=curl_factory) @@ -301,7 +267,7 @@ class TestExtendedConfig(unittest.TestCase): cfgfn = client.GenericCurlConfig(capath=certdir, _pycurl_version_fn=pcverfn) - curl_factory = lambda: FakeCurl(RapiMock()) + curl_factory = lambda: rapi.testutils.FakeCurl(RapiMock()) cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn, curl_factory=curl_factory) @@ -316,7 +282,7 @@ class TestExtendedConfig(unittest.TestCase): cfgfn = client.GenericCurlConfig(capath=certdir, _pycurl_version_fn=pcverfn) - curl_factory = lambda: FakeCurl(RapiMock()) + curl_factory = lambda: rapi.testutils.FakeCurl(RapiMock()) cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn, curl_factory=curl_factory) @@ -328,7 +294,7 @@ class TestExtendedConfig(unittest.TestCase): cfgfn = client.GenericCurlConfig(capath=certdir, _pycurl_version_fn=pcverfn) - curl_factory = lambda: FakeCurl(RapiMock()) + curl_factory = lambda: rapi.testutils.FakeCurl(RapiMock()) cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn, curl_factory=curl_factory) @@ -340,7 +306,7 @@ class TestExtendedConfig(unittest.TestCase): cfgfn = client.GenericCurlConfig(capath=certdir, _pycurl_version_fn=pcverfn) - curl_factory = lambda: FakeCurl(RapiMock()) + curl_factory = lambda: rapi.testutils.FakeCurl(RapiMock()) cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn, curl_factory=curl_factory) @@ -352,7 +318,7 @@ class TestExtendedConfig(unittest.TestCase): cfgfn = client.GenericCurlConfig(connect_timeout=connect_timeout, timeout=timeout) - curl_factory = lambda: FakeCurl(RapiMock()) + curl_factory = lambda: rapi.testutils.FakeCurl(RapiMock()) cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn, curl_factory=curl_factory) @@ -366,7 +332,7 @@ class GanetiRapiClientTests(testutils.GanetiTestCase): testutils.GanetiTestCase.setUp(self) self.rapi = RapiMock() - self.curl = FakeCurl(self.rapi) + self.curl = rapi.testutils.FakeCurl(self.rapi) self.client = client.GanetiRapiClient("master.example.com", curl_factory=lambda: self.curl) @@ -669,24 +635,21 @@ class GanetiRapiClientTests(testutils.GanetiTestCase): def testReplaceInstanceDisks(self): self.rapi.AddResponse("999") job_id = self.client.ReplaceInstanceDisks("instance-name", - disks=[0, 1], dry_run=True, iallocator="hail") + disks=[0, 1], iallocator="hail") self.assertEqual(999, job_id) self.assertHandler(rlib2.R_2_instances_name_replace_disks) self.assertItems(["instance-name"]) self.assertQuery("disks", ["0,1"]) self.assertQuery("mode", ["replace_auto"]) self.assertQuery("iallocator", ["hail"]) - self.assertDryRun() self.rapi.AddResponse("1000") job_id = self.client.ReplaceInstanceDisks("instance-bar", - disks=[1], mode="replace_on_secondary", remote_node="foo-node", - dry_run=True) + disks=[1], mode="replace_on_secondary", remote_node="foo-node") self.assertEqual(1000, job_id) self.assertItems(["instance-bar"]) self.assertQuery("disks", ["1"]) self.assertQuery("remote_node", ["foo-node"]) - self.assertDryRun() self.rapi.AddResponse("5175") self.assertEqual(5175, self.client.ReplaceInstanceDisks("instance-moo")) @@ -863,11 +826,16 @@ class GanetiRapiClientTests(testutils.GanetiTestCase): self.rapi.AddResponse(serializer.DumpJson([rlib2._NODE_EVAC_RES1])) self.rapi.AddResponse("8888") - job_id = self.client.EvacuateNode("node-3", iallocator="hail", dry_run=True) + job_id = self.client.EvacuateNode("node-3", iallocator="hail", dry_run=True, + mode=constants.NODE_EVAC_ALL, + early_release=True) self.assertEqual(8888, job_id) self.assertItems(["node-3"]) - self.assertEqual(serializer.LoadJson(self.rapi.GetLastRequestData()), - { "iallocator": "hail", }) + self.assertEqual(serializer.LoadJson(self.rapi.GetLastRequestData()), { + "iallocator": "hail", + "mode": "all", + "early_release": True, + }) self.assertDryRun() self.assertRaises(client.GanetiApiError, @@ -881,34 +849,26 @@ class GanetiRapiClientTests(testutils.GanetiTestCase): "node-4", accept_old=False) self.assertEqual(self.rapi.CountPending(), 0) - self.rapi.AddResponse(serializer.DumpJson([])) - self.assertRaises(client.GanetiApiError, self.client.EvacuateNode, - "node-4", accept_old=True) - self.assertEqual(self.rapi.CountPending(), 0) - - self.rapi.AddResponse(serializer.DumpJson([])) - self.assertRaises(client.GanetiApiError, self.client.EvacuateNode, - "node-4", accept_old=True, primary=True) - self.assertEqual(self.rapi.CountPending(), 0) + for mode in [client.NODE_EVAC_PRI, client.NODE_EVAC_ALL]: + self.rapi.AddResponse(serializer.DumpJson([])) + self.assertRaises(client.GanetiApiError, self.client.EvacuateNode, + "node-4", accept_old=True, mode=mode) + self.assertEqual(self.rapi.CountPending(), 0) self.rapi.AddResponse(serializer.DumpJson([])) - self.assertRaises(client.GanetiApiError, self.client.EvacuateNode, - "node-4", accept_old=True, secondary=False) + self.rapi.AddResponse(serializer.DumpJson("21533")) + result = self.client.EvacuateNode("node-3", iallocator="hail", + dry_run=True, accept_old=True, + mode=client.NODE_EVAC_SEC, + early_release=True) + self.assertEqual(result, "21533") + self.assertItems(["node-3"]) + self.assertQuery("iallocator", ["hail"]) + self.assertQuery("early_release", ["1"]) + self.assertFalse(self.rapi.GetLastRequestData()) + self.assertDryRun() self.assertEqual(self.rapi.CountPending(), 0) - for sec in [True, None]: - self.rapi.AddResponse(serializer.DumpJson([])) - self.rapi.AddResponse(serializer.DumpJson([["res", "foo"]])) - result = self.client.EvacuateNode("node-3", iallocator="hail", - dry_run=True, accept_old=True, - primary=False, secondary=sec) - self.assertEqual(result, [["res", "foo"]]) - self.assertItems(["node-3"]) - self.assertQuery("iallocator", ["hail"]) - self.assertFalse(self.rapi.GetLastRequestData()) - self.assertDryRun() - self.assertEqual(self.rapi.CountPending(), 0) - def testMigrateNode(self): self.rapi.AddResponse(serializer.DumpJson([])) self.rapi.AddResponse("1111") @@ -983,6 +943,14 @@ class GanetiRapiClientTests(testutils.GanetiTestCase): self.assertFalse(self.rapi.GetLastRequestData()) self.assertEqual(self.rapi.CountPending(), 0) + def testModifyNode(self): + self.rapi.AddResponse("3783") + job_id = self.client.ModifyNode("node16979.example.com", drained=True) + self.assertEqual(job_id, 3783) + self.assertHandler(rlib2.R_2_nodes_name_modify) + self.assertItems(["node16979.example.com"]) + self.assertEqual(self.rapi.CountPending(), 0) + def testGetNodeStorageUnits(self): self.rapi.AddResponse("42") self.assertEqual(42,