#
-# Copyright (C) 2007, 2008 Google Inc.
+# Copyright (C) 2007, 2008, 2009, 2010 Google Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
import qa_error
from qa_utils import (AssertEqual, AssertNotEqual, AssertIn, AssertMatch,
- StartSSH)
+ StartLocalCommand)
_rapi_ca = None
_rapi_client = None
+_rapi_username = None
+_rapi_password = None
def Setup(username, password):
"""
global _rapi_ca
global _rapi_client
+ global _rapi_username
+ global _rapi_password
+
+ _rapi_username = username
+ _rapi_password = password
master = qa_config.GetMasterNode()
_rapi_ca.flush()
port = qa_config.get("rapi-port", default=constants.DEFAULT_RAPI_PORT)
- cfg_ssl = rapi.client.CertAuthorityVerify(cafile=_rapi_ca.name)
+ cfg_curl = rapi.client.GenericCurlConfig(cafile=_rapi_ca.name,
+ proxy="")
_rapi_client = rapi.client.GanetiRapiClient(master["primary"], port=port,
username=username,
password=password,
- config_ssl_verification=cfg_ssl,
- ignore_proxy=True)
+ curl_config_fn=cfg_curl)
print "RAPI protocol version: %s" % _rapi_client.GetVersion()
"disk_template", "disk.sizes",
"nic.ips", "nic.macs", "nic.modes", "nic.links",
"beparams", "hvparams",
- "oper_state", "oper_ram", "status", "tags")
+ "oper_state", "oper_ram", "oper_vcpus", "status", "tags")
NODE_FIELDS = ("name", "dtotal", "dfree",
"mtotal", "mnode", "mfree",
for uri, verify, method, body in uris:
assert uri.startswith("/")
+ print "%s %s" % (method, uri)
data = _rapi_client._SendRequest(method, uri, None, body)
if verify is not None:
else:
AssertEqual(data, verify)
- results.append(data)
+ results.append(data)
return results
("/2/os", None, 'GET', None),
])
+ # Test HTTP Not Found
+ for method in ["GET", "PUT", "POST", "DELETE"]:
+ try:
+ _DoTests([("/99/resource/not/here/99", None, method, None)])
+ except rapi.client.GanetiApiError, err:
+ AssertEqual(err.code, 404)
+ else:
+ raise qa_error.Error("Non-existent resource didn't return HTTP 404")
+
+ # Test HTTP Not Implemented
+ for method in ["PUT", "POST", "DELETE"]:
+ try:
+ _DoTests([("/version", None, method, None)])
+ except rapi.client.GanetiApiError, err:
+ AssertEqual(err.code, 501)
+ else:
+ raise qa_error.Error("Non-implemented method didn't fail")
+
def TestInstance(instance):
"""Testing getting instance(s) info via remote API.
_VerifyReturnsJob, 'PUT', None),
])
+ # Test OpPrepareExport
+ (job_id, ) = _DoTests([
+ ("/2/instances/%s/prepare-export?mode=%s" %
+ (instance["name"], constants.EXPORT_MODE_REMOTE),
+ _VerifyReturnsJob, "PUT", None),
+ ])
+
+ result = _WaitForRapiJob(job_id)[0]
+ AssertEqual(len(result["handshake"]), 3)
+ AssertEqual(result["handshake"][0], constants.RIE_VERSION)
+ AssertEqual(len(result["x509_key_name"]), 3)
+ AssertIn("-----BEGIN CERTIFICATE-----", result["x509_ca"])
+
def TestNode(node):
"""Testing getting node(s) info via remote API.
def _VerifyTags(data):
AssertEqual(sorted(tags), sorted(data))
+ query = "&".join("tag=%s" % i for i in tags)
+
+ # Add tags
+ (job_id, ) = _DoTests([
+ ("%s?%s" % (uri, query), _VerifyReturnsJob, "PUT", None),
+ ])
+ _WaitForRapiJob(job_id)
+
+ # Retrieve tags
_DoTests([
(uri, _VerifyTags, 'GET', None),
])
+ # Remove tags
+ (job_id, ) = _DoTests([
+ ("%s?%s" % (uri, query), _VerifyReturnsJob, "DELETE", None),
+ ])
+ _WaitForRapiJob(job_id)
+
def _WaitForRapiJob(job_id):
"""Waits for a job to finish.
("/2/jobs/%s" % job_id, _VerifyJob, "GET", None),
])
- rapi.client_utils.PollJob(_rapi_client, job_id, cli.StdioJobPollReportCb())
+ return rapi.client_utils.PollJob(_rapi_client, job_id,
+ cli.StdioJobPollReportCb())
-def TestRapiInstanceAdd(node):
+def TestRapiInstanceAdd(node, use_client):
"""Test adding a new instance via RAPI"""
instance = qa_config.AcquireInstance()
try:
- body = {
- "name": instance["name"],
- "os": qa_config.get("os"),
- "disk_template": constants.DT_PLAIN,
- "pnode": node["primary"],
- "memory": utils.ParseUnit(qa_config.get("mem")),
- "disks": [utils.ParseUnit(size) for size in qa_config.get("disk")],
- }
-
- (job_id, ) = _DoTests([
- ("/2/instances", _VerifyReturnsJob, "POST", body),
- ])
+ memory = utils.ParseUnit(qa_config.get("mem"))
+ disk_sizes = [utils.ParseUnit(size) for size in qa_config.get("disk")]
+
+ if use_client:
+ disks = [{"size": size} for size in disk_sizes]
+ nics = [{}]
+
+ beparams = {
+ constants.BE_MEMORY: memory,
+ }
+
+ job_id = _rapi_client.CreateInstance(constants.INSTANCE_CREATE,
+ instance["name"],
+ constants.DT_PLAIN,
+ disks, nics,
+ os=qa_config.get("os"),
+ pnode=node["primary"],
+ beparams=beparams)
+ else:
+ body = {
+ "name": instance["name"],
+ "os": qa_config.get("os"),
+ "disk_template": constants.DT_PLAIN,
+ "pnode": node["primary"],
+ "memory": memory,
+ "disks": disk_sizes,
+ }
+
+ (job_id, ) = _DoTests([
+ ("/2/instances", _VerifyReturnsJob, "POST", body),
+ ])
_WaitForRapiJob(job_id)
raise
-def TestRapiInstanceRemove(instance):
+def TestRapiInstanceRemove(instance, use_client):
"""Test removing instance via RAPI"""
- (job_id, ) = _DoTests([
- ("/2/instances/%s" % instance["name"], _VerifyReturnsJob, "DELETE", None),
- ])
+ if use_client:
+ job_id = _rapi_client.DeleteInstance(instance["name"])
+ else:
+ (job_id, ) = _DoTests([
+ ("/2/instances/%s" % instance["name"], _VerifyReturnsJob, "DELETE", None),
+ ])
_WaitForRapiJob(job_id)
qa_config.ReleaseInstance(instance)
+
+
+def TestRapiInstanceMigrate(instance):
+ """Test migrating instance via RAPI"""
+ # Move to secondary node
+ _WaitForRapiJob(_rapi_client.MigrateInstance(instance["name"]))
+ # And back to previous primary
+ _WaitForRapiJob(_rapi_client.MigrateInstance(instance["name"]))
+
+
+def TestRapiInstanceRename(instance, rename_target):
+ """Test renaming instance via RAPI"""
+ rename_source = instance["name"]
+
+ for name1, name2 in [(rename_source, rename_target),
+ (rename_target, rename_source)]:
+ _WaitForRapiJob(_rapi_client.RenameInstance(name1, name2))
+
+
+def TestRapiInstanceModify(instance):
+ """Test modifying instance via RAPI"""
+ def _ModifyInstance(**kwargs):
+ _WaitForRapiJob(_rapi_client.ModifyInstance(instance["name"], **kwargs))
+
+ _ModifyInstance(hvparams={
+ constants.HV_KERNEL_ARGS: "single",
+ })
+
+ _ModifyInstance(beparams={
+ constants.BE_VCPUS: 3,
+ })
+
+ _ModifyInstance(beparams={
+ constants.BE_VCPUS: constants.VALUE_DEFAULT,
+ })
+
+ _ModifyInstance(hvparams={
+ constants.HV_KERNEL_ARGS: constants.VALUE_DEFAULT,
+ })
+
+
+def TestInterClusterInstanceMove(src_instance, dest_instance,
+ pnode, snode, tnode):
+ """Test tools/move-instance"""
+ master = qa_config.GetMasterNode()
+
+ rapi_pw_file = tempfile.NamedTemporaryFile()
+ rapi_pw_file.write(_rapi_password)
+ rapi_pw_file.flush()
+
+ # TODO: Run some instance tests before moving back
+
+ if snode is None:
+ # instance is not redundant, but we still need to pass a node
+ # (which will be ignored)
+ fsec = tnode
+ else:
+ fsec = snode
+ # note: pnode:snode are the *current* nodes, so we move it first to
+ # tnode:pnode, then back to pnode:snode
+ for si, di, pn, sn in [(src_instance["name"], dest_instance["name"],
+ tnode["primary"], pnode["primary"]),
+ (dest_instance["name"], src_instance["name"],
+ pnode["primary"], fsec["primary"])]:
+ cmd = [
+ "../tools/move-instance",
+ "--verbose",
+ "--src-ca-file=%s" % _rapi_ca.name,
+ "--src-username=%s" % _rapi_username,
+ "--src-password-file=%s" % rapi_pw_file.name,
+ "--dest-instance-name=%s" % di,
+ "--dest-primary-node=%s" % pn,
+ "--dest-secondary-node=%s" % sn,
+ "--net=0:mac=%s" % constants.VALUE_GENERATE,
+ master["primary"],
+ master["primary"],
+ si,
+ ]
+
+ AssertEqual(StartLocalCommand(cmd).wait(), 0)