Commit a47f574c authored by Oleksiy Mishchenko's avatar Oleksiy Mishchenko

Migrate RAPI QA to trunk.

Reviewed-by: imsnah
parent d128fdb6
......@@ -157,6 +157,7 @@ EXTRA_DIST = \
qa/ \
qa/ \
qa/ \
qa/ \
qa/ \
......@@ -39,6 +39,7 @@ import qa_instance
import qa_node
import qa_os
import qa_other
import qa_rapi
import qa_tags
import qa_utils
......@@ -111,6 +112,9 @@ def RunClusterTests():
if qa_config.TestEnabled('cluster-master-failover'):
if qa_rapi.Enabled():
def RunOsTests():
"""Runs all tests related to gnt-os.
......@@ -160,6 +164,8 @@ def RunCommonInstanceTests(instance):
if qa_config.TestEnabled('node-volumes'):
if qa_rapi.Enabled():
RunTest(qa_rapi.TestInstance, instance)
def RunExportImportTests(instance, pnode):
"""Tries to export and import the instance.
......@@ -282,6 +288,9 @@ def main():
if qa_config.TestEnabled('tags'):
RunTest(qa_tags.TestNodeTags, pnode)
if qa_rapi.Enabled():
RunTest(qa_rapi.TestNode, pnode)
if qa_config.TestEnabled('instance-add-plain-disk'):
instance = RunTest(qa_instance.TestInstanceAddWithPlainDisk, pnode)
......@@ -29,6 +29,7 @@ tests:
env: True
os: True
tags: True
rapi: True
cluster-verify: True
cluster-info: True
# Copyright (C) 2007, 2008 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
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
"""Remote API QA tests.
import urllib2
from ganeti import utils
from ganeti import constants
from ganeti import errors
from ganeti import serializer
import qa_config
import qa_utils
import qa_error
from qa_utils import AssertEqual, AssertNotEqual, AssertIn, StartSSH
# Create opener which doesn't try to look for proxies.
NoProxyOpener = urllib2.build_opener(urllib2.ProxyHandler({}))
INSTANCE_FIELDS = ("name", "os", "pnode", "snodes",
"admin_state", "admin_ram",
"disk_template", "ip", "mac", "bridge",
"sda_size", "sdb_size", "vcpus",
"oper_state", "status", "tags")
NODE_FIELDS = ("name", "dtotal", "dfree",
"mtotal", "mnode", "mfree",
"pinst_cnt", "sinst_cnt", "tags")
LIST_FIELDS = ("name", "uri")
def Enabled():
"""Return whether remote API tests should be run.
return constants.RAPI_ENABLE and qa_config.TestEnabled('rapi')
def PrintRemoteAPIWarning():
"""Print warning if remote API is not enabled.
if constants.RAPI_ENABLE or not qa_config.TestEnabled('rapi'):
msg = ("Remote API is not enabled in this Ganeti build. Please run"
" `configure [...] --enable-rapi'.")
print qa_utils.FormatWarning(msg)
def _DoTests(uris):
master = qa_config.GetMasterNode()
host = master["primary"]
port = qa_config.get("rapi-port", default=constants.RAPI_PORT)
for uri, verify in uris:
assert uri.startswith("/")
url = "http://%s:%s%s" % (host, port, uri)
print "Testing %s ..." % url
response =
AssertEqual(["Content-type"], "application/json")
data = serializer.LoadJson(
if verify is not None:
if callable(verify):
AssertEqual(data, verify)
def TestVersion():
"""Testing remote API version.
("/version", constants.RAPI_VERSION),
def TestEmptyCluster():
"""Testing remote API on an empty cluster.
master_name = qa_config.GetMasterNode()["primary"]
def _VerifyInfo(data):
AssertIn("name", data)
AssertIn("master", data)
AssertEqual(data["master"], master_name)
def _VerifyNodes(data):
master_entry = {
"name": master_name,
"uri": "/nodes/%s" % master_name,
AssertIn(master_entry, data)
def _VerifyNodesBulk(data):
for node in data:
for entry in NODE_FIELDS:
AssertIn(entry, node)
("/", None),
("/info", _VerifyInfo),
("/tags", None),
("/nodes", _VerifyNodes),
("/nodes?bulk=1", _VerifyNodesBulk),
("/instances", []),
("/instances?bulk=1", []),
("/os", None),
def TestInstance(instance):
"""Testing getting instance(s) info via remote API.
def _VerifyInstance(data):
for entry in INSTANCE_FIELDS:
AssertIn(entry, data)
def _VerifyInstancesList(data):
for instance in data:
for entry in LIST_FIELDS:
AssertIn(entry, instance)
def _VerifyInstancesBulk(data):
for instance_data in data:
("/instances/%s" % instance["name"], _VerifyInstance),
("/instances", _VerifyInstancesList),
("/instances?bulk=1", _VerifyInstancesBulk),
def TestNode(node):
"""Testing getting node(s) info via remote API.
def _VerifyNode(data):
for entry in NODE_FIELDS:
AssertIn(entry, data)
def _VerifyNodesList(data):
for node in data:
for entry in LIST_FIELDS:
AssertIn(entry, node)
def _VerifyNodesBulk(data):
for node_data in data:
("/nodes/%s" % node["primary"], _VerifyNode),
("/nodes", _VerifyNodesList),
("/nodes?bulk=1", _VerifyNodesBulk),
def TestTags(kind, name, tags):
"""Tests .../tags resources.
if kind == constants.TAG_CLUSTER:
uri = "/tags"
elif kind == constants.TAG_NODE:
uri = "/nodes/%s/tags" % name
elif kind == constants.TAG_INSTANCE:
uri = "/instances/%s/tags" % name
raise errors.ProgrammerError("Unknown tag kind")
def _VerifyTags(data):
# Create copies to modify
should = tags[:]
returned = data[:]
AssertEqual(should, returned)
(uri, _VerifyTags),
# Copyright (C) 2007 Google Inc.
# This program is free software; you can redistribute it and/or modify
......@@ -24,9 +21,11 @@
from ganeti import utils
from ganeti import constants
import qa_config
import qa_utils
import qa_rapi
from qa_utils import AssertEqual, StartSSH
......@@ -34,13 +33,27 @@ from qa_utils import AssertEqual, StartSSH
_TEMP_TAG_NAMES = ["TEMP-Ganeti-QA-Tag%d" % i for i in range(3)]
_TEMP_TAG_RE = r'^TEMP-Ganeti-QA-Tag\d+$'
constants.TAG_CLUSTER: "gnt-cluster",
constants.TAG_NODE: "gnt-node",
constants.TAG_INSTANCE: "gnt-instance",
def _TestTags(cmdfn):
def _TestTags(kind, name):
"""Generic function for add-tags.
master = qa_config.GetMasterNode()
def cmdfn(subcmd):
cmd = [_KIND_TO_COMMAND[kind], subcmd]
if kind != constants.TAG_CLUSTER:
return cmd
cmd = cmdfn('add-tags') + _TEMP_TAG_NAMES
utils.ShellQuoteArgs(cmd)).wait(), 0)
......@@ -53,6 +66,9 @@ def _TestTags(cmdfn):
utils.ShellQuoteArgs(cmd)).wait(), 0)
if qa_rapi.Enabled():
qa_rapi.TestTags(kind, name, _TEMP_TAG_NAMES)
cmd = cmdfn('remove-tags') + _TEMP_TAG_NAMES
utils.ShellQuoteArgs(cmd)).wait(), 0)
......@@ -61,16 +77,16 @@ def _TestTags(cmdfn):
def TestClusterTags():
"""gnt-cluster tags"""
_TestTags(lambda subcmd: ['gnt-cluster', subcmd])
_TestTags(constants.TAG_CLUSTER, "")
def TestNodeTags(node):
"""gnt-node tags"""
_TestTags(lambda subcmd: ['gnt-node', subcmd, node['primary']])
_TestTags(constants.TAG_NODE, node["primary"])
def TestInstanceTags(instance):
"""gnt-instance tags"""
_TestTags(lambda subcmd: ['gnt-instance', subcmd, instance['name']])
_TestTags(constants.TAG_INSTANCE, instance["name"])
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment