switch to use the zvm cloud connector backend
Utilize the new zvm cloud connector utilities for the implement of ceilometer-zvm driver APIs. Change-Id: Ia24c4ca0c1e34f4a225ab1ddc58220e1d3e92774
This commit is contained in:
parent
ef127c85b2
commit
e6e9b9efb0
28
ceilometer_zvm/compute/virt/zvm/conf.py
Normal file
28
ceilometer_zvm/compute/virt/zvm/conf.py
Normal file
@ -0,0 +1,28 @@
|
||||
# Copyright 2017 IBM Corp.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
|
||||
zvm_opts = [
|
||||
cfg.URIOpt('zvm_cloud_connector_url',
|
||||
help="""
|
||||
URL to be used to communicate with z/VM Cloud Connector.
|
||||
Example: https://10.10.10.1:8080.
|
||||
"""),
|
||||
]
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(zvm_opts)
|
22
ceilometer_zvm/compute/virt/zvm/exception.py
Normal file
22
ceilometer_zvm/compute/virt/zvm/exception.py
Normal file
@ -0,0 +1,22 @@
|
||||
# Copyright 2017 IBM Corp.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from ceilometer.compute.virt import inspector as virt_inspector
|
||||
|
||||
|
||||
class ZVMConnectorRequestFailed(virt_inspector.InspectorException):
|
||||
|
||||
def __init__(self, msg, results):
|
||||
self.results = results
|
||||
super(ZVMConnectorRequestFailed, self).__init__(message=msg)
|
@ -13,184 +13,94 @@
|
||||
# under the License.
|
||||
|
||||
|
||||
import six
|
||||
|
||||
from ceilometer.compute.virt import inspector as virt_inspector
|
||||
from ceilometer.i18n import _
|
||||
from oslo_config import cfg
|
||||
from oslo_utils import timeutils
|
||||
from oslo_utils import units
|
||||
|
||||
from ceilometer_zvm.compute.virt.zvm import exception
|
||||
from ceilometer_zvm.compute.virt.zvm import utils as zvmutils
|
||||
|
||||
|
||||
zvm_ops = [
|
||||
cfg.StrOpt('zvm_xcat_server',
|
||||
default=None,
|
||||
help='Host name or IP address of xCAT management_node'),
|
||||
cfg.StrOpt('zvm_xcat_username',
|
||||
default=None,
|
||||
help='xCAT username'),
|
||||
cfg.StrOpt('zvm_xcat_password',
|
||||
default=None,
|
||||
secret=True,
|
||||
help='Password of the xCAT user'),
|
||||
cfg.IntOpt('zvm_xcat_connection_timeout',
|
||||
default=600,
|
||||
help="The number of seconds wait for xCAT MN response"),
|
||||
cfg.StrOpt('xcat_zhcp_nodename',
|
||||
default='zhcp',
|
||||
help='xCat zHCP nodename in xCAT '),
|
||||
cfg.StrOpt('zvm_host',
|
||||
default=None,
|
||||
help='z/VM host that managed by xCAT MN.'),
|
||||
cfg.StrOpt('zvm_xcat_master',
|
||||
default='xcat',
|
||||
help='The xCAT MM node name'),
|
||||
cfg.IntOpt('cache_update_interval',
|
||||
default=600,
|
||||
help="Cached data update interval"),
|
||||
cfg.StrOpt('zvm_xcat_ca_file',
|
||||
default=None,
|
||||
help="CA file for https connection to xcat"),
|
||||
]
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(zvm_ops, group='zvm')
|
||||
from oslo_utils import units
|
||||
|
||||
|
||||
class ZVMInspector(virt_inspector.Inspector):
|
||||
|
||||
def __init__(self):
|
||||
self.cache = zvmutils.CacheData()
|
||||
self.cache_expiration = timeutils.utcnow_ts()
|
||||
|
||||
self.instances = {}
|
||||
self.zhcp_info = {
|
||||
'nodename': CONF.zvm.xcat_zhcp_nodename,
|
||||
'hostname': zvmutils.get_node_hostname(
|
||||
CONF.zvm.xcat_zhcp_nodename),
|
||||
'userid': zvmutils.get_userid(CONF.zvm.xcat_zhcp_nodename)
|
||||
}
|
||||
|
||||
def _update_inst_cpu_mem_stat(self, instances):
|
||||
inst_pis = zvmutils.image_performance_query(
|
||||
self.zhcp_info['nodename'], instances.values())
|
||||
|
||||
for inst_name, userid in instances.items():
|
||||
if userid not in inst_pis.keys():
|
||||
# Not performance data returned for this virtual machine
|
||||
continue
|
||||
|
||||
with zvmutils.expect_invalid_xcat_resp_data():
|
||||
guest_cpus = int(inst_pis[userid]['guest_cpus'])
|
||||
used_cpu_time = inst_pis[userid]['used_cpu_time']
|
||||
used_cpu_time = int(used_cpu_time.partition(' ')[0]) * units.k
|
||||
used_memory = inst_pis[userid]['used_memory']
|
||||
used_memory = int(used_memory.partition(' ')[0]) / units.Ki
|
||||
|
||||
inst_stat = {'nodename': inst_name,
|
||||
'userid': userid,
|
||||
'guest_cpus': guest_cpus,
|
||||
'used_cpu_time': used_cpu_time,
|
||||
'used_memory': used_memory}
|
||||
|
||||
self.cache.set('cpumem', inst_stat)
|
||||
|
||||
def _update_inst_nic_stat(self, instances):
|
||||
vsw_dict = zvmutils.virutal_network_vswitch_query_iuo_stats(
|
||||
self.zhcp_info['nodename'])
|
||||
with zvmutils.expect_invalid_xcat_resp_data():
|
||||
for vsw in vsw_dict['vswitches']:
|
||||
for nic in vsw['nics']:
|
||||
for inst_name, userid in instances.items():
|
||||
if nic['userid'].upper() == userid.upper():
|
||||
nic_entry = {
|
||||
'vswitch_name': vsw['vswitch_name'],
|
||||
'nic_vdev': nic['vdev'],
|
||||
'nic_fr_rx': int(nic['nic_fr_rx']),
|
||||
'nic_fr_tx': int(nic['nic_fr_tx']),
|
||||
'nic_fr_rx_dsc': int(nic['nic_fr_rx_dsc']),
|
||||
'nic_fr_tx_dsc': int(nic['nic_fr_tx_dsc']),
|
||||
'nic_fr_rx_err': int(nic['nic_fr_rx_err']),
|
||||
'nic_fr_tx_err': int(nic['nic_fr_tx_err']),
|
||||
'nic_rx': int(nic['nic_rx']),
|
||||
'nic_tx': int(nic['nic_tx'])}
|
||||
inst_stat = self.cache.get('vnics', inst_name)
|
||||
if inst_stat is None:
|
||||
inst_stat = {
|
||||
'nodename': inst_name,
|
||||
'userid': userid,
|
||||
'nics': [nic_entry]
|
||||
}
|
||||
else:
|
||||
inst_stat['nics'].append(nic_entry)
|
||||
self.cache.set('vnics', inst_stat)
|
||||
|
||||
def _update_cache(self, meter, instances={}):
|
||||
if instances == {}:
|
||||
self.cache.clear()
|
||||
self.cache_expiration = (timeutils.utcnow_ts() +
|
||||
CONF.zvm.cache_update_interval)
|
||||
instances = self.instances = zvmutils.list_instances(
|
||||
self.zhcp_info)
|
||||
if meter == 'cpumem':
|
||||
self._update_inst_cpu_mem_stat(instances)
|
||||
if meter == 'vnics':
|
||||
self._update_inst_nic_stat(instances)
|
||||
|
||||
def _check_expiration_and_update_cache(self, meter):
|
||||
now = timeutils.utcnow_ts()
|
||||
if now >= self.cache_expiration:
|
||||
self._update_cache(meter)
|
||||
|
||||
def _get_inst_stat(self, meter, instance):
|
||||
inst_name = zvmutils.get_inst_name(instance)
|
||||
# zvm inspector can not get instance info in shutdown stat
|
||||
if zvmutils.get_inst_power_state(instance) == 0x04:
|
||||
msg = _("Can not get vm info in shutdown state "
|
||||
"for %s") % inst_name
|
||||
raise virt_inspector.InstanceShutOffException(msg)
|
||||
|
||||
self._check_expiration_and_update_cache(meter)
|
||||
|
||||
inst_stat = self.cache.get(meter, inst_name)
|
||||
|
||||
if inst_stat is None:
|
||||
userid = (self.instances.get(inst_name) or
|
||||
zvmutils.get_userid(inst_name))
|
||||
self._update_cache(meter, {inst_name: userid})
|
||||
inst_stat = self.cache.get(meter, inst_name)
|
||||
|
||||
if inst_stat is None:
|
||||
msg = _("Can not get vm info for %s") % inst_name
|
||||
raise virt_inspector.InstanceNotFoundException(msg)
|
||||
else:
|
||||
return inst_stat
|
||||
|
||||
def inspect_cpus(self, instance):
|
||||
inst_stat = self._get_inst_stat('cpumem', instance)
|
||||
return virt_inspector.CPUStats(number=inst_stat['guest_cpus'],
|
||||
time=inst_stat['used_cpu_time'])
|
||||
|
||||
def inspect_memory_usage(self, instance, duration=None):
|
||||
inst_stat = self._get_inst_stat('cpumem', instance)
|
||||
return virt_inspector.MemoryUsageStats(usage=inst_stat['used_memory'])
|
||||
self._reqh = zvmutils.zVMConnectorRequestHandler()
|
||||
|
||||
def inspect_vnics(self, instance):
|
||||
inst_stat = self._get_inst_stat('vnics', instance)
|
||||
for nic in inst_stat['nics']:
|
||||
interface = virt_inspector.Interface(
|
||||
name=nic['nic_vdev'],
|
||||
mac=None,
|
||||
fref=None,
|
||||
parameters=None)
|
||||
stats = virt_inspector.InterfaceStats(
|
||||
rx_bytes=nic['nic_rx'],
|
||||
rx_packets=nic['nic_fr_rx'],
|
||||
tx_bytes=nic['nic_tx'],
|
||||
tx_packets=nic['nic_fr_tx'],
|
||||
rx_drop=nic['nic_fr_rx_dsc'],
|
||||
tx_drop=nic['nic_fr_tx_dsc'],
|
||||
rx_errors=nic['nic_fr_rx_err'],
|
||||
tx_errors=nic['nic_fr_tx_err'])
|
||||
yield (interface, stats)
|
||||
nics_data = self._inspect_inst_data(instance, 'vnics')
|
||||
# Construct the final result
|
||||
for nic in nics_data:
|
||||
yield virt_inspector.InterfaceStats(name=nic['nic_vdev'],
|
||||
mac=None,
|
||||
fref=None,
|
||||
parameters=None,
|
||||
rx_bytes=nic['nic_rx'],
|
||||
rx_packets=nic['nic_fr_rx'],
|
||||
rx_errors=None,
|
||||
rx_drop=None,
|
||||
tx_bytes=nic['nic_tx'],
|
||||
tx_packets=nic['nic_fr_tx'],
|
||||
tx_errors=None,
|
||||
tx_drop=None
|
||||
)
|
||||
|
||||
def inspect_instance(self, instance, duration):
|
||||
inst_stats = self._inspect_inst_data(instance, 'stats')
|
||||
cpu_number = inst_stats['guest_cpus']
|
||||
used_cpu_time = (inst_stats['used_cpu_time_us'] * units.k)
|
||||
used_mem_mb = inst_stats['used_mem_kb'] / units.Ki
|
||||
# Construct the final result
|
||||
return virt_inspector.InstanceStats(cpu_number=cpu_number,
|
||||
cpu_time=used_cpu_time,
|
||||
memory_usage=used_mem_mb
|
||||
)
|
||||
|
||||
def _inspect_inst_data(self, instance, inspect_type):
|
||||
inspect_data = {}
|
||||
inst_name = zvmutils.get_inst_name(instance)
|
||||
msg_shutdown = _("Can not get vm info in shutdown state "
|
||||
"for %s") % inst_name
|
||||
msg_notexist = _("Can not get vm info for %s, vm not exist"
|
||||
) % inst_name
|
||||
msg_nodata = _("Failed to get vm info for %s") % inst_name
|
||||
# zvm inspector can not get instance info in shutdown stat
|
||||
if zvmutils.get_inst_power_state(instance) == 0x04:
|
||||
raise virt_inspector.InstanceShutOffException(msg_shutdown)
|
||||
try:
|
||||
if inspect_type == 'stats':
|
||||
inspect_data = self._reqh.call('guest_inspect_stats',
|
||||
inst_name)
|
||||
elif inspect_type == 'vnics':
|
||||
inspect_data = self._reqh.call('guest_inspect_vnics',
|
||||
inst_name)
|
||||
except Exception as err:
|
||||
msg_nodata += (". Error: %s" % six.text_type(err))
|
||||
raise virt_inspector.NoDataException(msg_nodata)
|
||||
|
||||
# Check the inst data is in the returned result
|
||||
index_key = inst_name.upper()
|
||||
if index_key not in inspect_data:
|
||||
# Check the reason: shutdown or not exist or other error
|
||||
power_stat = ''
|
||||
try:
|
||||
power_stat = self._reqh.call('guest_get_power_state',
|
||||
inst_name)
|
||||
except exception.ZVMConnectorRequestFailed as err:
|
||||
if err.results['overallRC'] == 404:
|
||||
# instance not exists
|
||||
raise virt_inspector.InstanceNotFoundException(msg_notexist
|
||||
)
|
||||
else:
|
||||
msg_nodata += (". Error: %s" % six.text_type(err))
|
||||
raise virt_inspector.NoDataException(msg_nodata)
|
||||
except Exception as err:
|
||||
msg_nodata += (". Error: %s" % six.text_type(err))
|
||||
raise virt_inspector.NoDataException(msg_nodata)
|
||||
|
||||
if power_stat == 'off':
|
||||
raise virt_inspector.InstanceShutOffException(msg_shutdown)
|
||||
else:
|
||||
raise virt_inspector.NoDataException(msg_nodata)
|
||||
else:
|
||||
return inspect_data[index_key]
|
||||
|
@ -13,416 +13,17 @@
|
||||
# under the License.
|
||||
|
||||
|
||||
import contextlib
|
||||
import functools
|
||||
import os
|
||||
from six.moves import http_client as httplib
|
||||
import socket
|
||||
import ssl
|
||||
import six.moves.urllib.parse as urlparse
|
||||
|
||||
from ceilometer.compute.virt import inspector
|
||||
from ceilometer.i18n import _
|
||||
from ceilometer.i18n import _LW
|
||||
from oslo_config import cfg
|
||||
from ceilometer_zvm.compute.virt.zvm import conf
|
||||
from ceilometer_zvm.compute.virt.zvm import exception
|
||||
from oslo_log import log as logging
|
||||
from oslo_serialization import jsonutils
|
||||
from zvmconnector import connector
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF = conf.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ZVMException(inspector.InspectorException):
|
||||
pass
|
||||
|
||||
|
||||
class CacheData(object):
|
||||
"""Virtual machine stat cache."""
|
||||
_CTYPES = ('cpumem', 'vnics')
|
||||
|
||||
def __init__(self):
|
||||
self._reset()
|
||||
|
||||
def _reset(self):
|
||||
self.cache = dict((tp, {}) for tp in self._CTYPES)
|
||||
|
||||
def set(self, ctype, inst_stat):
|
||||
"""Set or update cache content.
|
||||
|
||||
@ctype: cache type.
|
||||
@inst_stat: cache data.
|
||||
"""
|
||||
self.cache[ctype][inst_stat['nodename']] = inst_stat
|
||||
|
||||
def get(self, ctype, inst_name):
|
||||
return self.cache[ctype].get(inst_name, None)
|
||||
|
||||
def delete(self, ctype, inst_name):
|
||||
if inst_name in self.cache[ctype]:
|
||||
del self.cache[ctype][inst_name]
|
||||
|
||||
def clear(self, ctype='all'):
|
||||
if ctype == 'all':
|
||||
self._reset()
|
||||
else:
|
||||
self.cache[ctype] = {}
|
||||
|
||||
|
||||
class XCATUrl(object):
|
||||
"""To return xCAT url for invoking xCAT REST API."""
|
||||
def __init__(self):
|
||||
self.PREFIX = '/xcatws'
|
||||
self.SUFFIX = ''.join(('?userName=', CONF.zvm.zvm_xcat_username,
|
||||
'&password=', CONF.zvm.zvm_xcat_password,
|
||||
'&format=json'))
|
||||
|
||||
# xcat objects
|
||||
self.NODES = '/nodes'
|
||||
self.TABLES = '/tables'
|
||||
|
||||
# xcat actions
|
||||
self.XDSH = '/dsh'
|
||||
|
||||
def _append_addp(self, rurl, addp=None):
|
||||
if addp is not None:
|
||||
return ''.join((rurl, addp))
|
||||
else:
|
||||
return rurl
|
||||
|
||||
def xdsh(self, arg=''):
|
||||
"""Run shell command."""
|
||||
return ''.join((self.PREFIX, self.NODES, arg, self.XDSH, self.SUFFIX))
|
||||
|
||||
def gettab(self, arg='', addp=None):
|
||||
rurl = ''.join((self.PREFIX, self.TABLES, arg, self.SUFFIX))
|
||||
return self._append_addp(rurl, addp)
|
||||
|
||||
def tabdump(self, arg='', addp=None):
|
||||
return self.gettab(arg, addp)
|
||||
|
||||
def lsdef_node(self, arg='', addp=None):
|
||||
rurl = ''.join((self.PREFIX, self.NODES, arg, self.SUFFIX))
|
||||
return self._append_addp(rurl, addp)
|
||||
|
||||
|
||||
class HTTPSClientAuthConnection(httplib.HTTPSConnection):
|
||||
"""For https://wiki.openstack.org/wiki/OSSN/OSSN-0033."""
|
||||
|
||||
def __init__(self, host, port, ca_file, timeout=None, key_file=None,
|
||||
cert_file=None):
|
||||
httplib.HTTPSConnection.__init__(self, host, port,
|
||||
key_file=key_file,
|
||||
cert_file=cert_file)
|
||||
self.key_file = key_file
|
||||
self.cert_file = cert_file
|
||||
self.ca_file = ca_file
|
||||
self.timeout = timeout
|
||||
self.use_ca = True
|
||||
|
||||
if self.ca_file is None:
|
||||
LOG.debug("no xCAT CA file specified, this is considered "
|
||||
"not secure")
|
||||
self.use_ca = False
|
||||
|
||||
def connect(self):
|
||||
sock = socket.create_connection((self.host, self.port), self.timeout)
|
||||
if self._tunnel_host:
|
||||
self.sock = sock
|
||||
self._tunnel()
|
||||
|
||||
if (self.ca_file is not None and
|
||||
not os.path.exists(self.ca_file)):
|
||||
LOG.warning(_LW("the CA file %(ca_file) does not exist!"),
|
||||
{'ca_file': self.ca_file})
|
||||
self.use_ca = False
|
||||
|
||||
if not self.use_ca:
|
||||
self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file,
|
||||
cert_reqs=ssl.CERT_NONE)
|
||||
else:
|
||||
self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file,
|
||||
ca_certs=self.ca_file,
|
||||
cert_reqs=ssl.CERT_REQUIRED)
|
||||
|
||||
|
||||
class XCATConnection(object):
|
||||
"""Https requests to xCAT web service."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize https connection to xCAT service."""
|
||||
self.host = CONF.zvm.zvm_xcat_server
|
||||
self.port = 443
|
||||
self.conn = HTTPSClientAuthConnection(self.host, self.port,
|
||||
CONF.zvm.zvm_xcat_ca_file,
|
||||
timeout=CONF.zvm.zvm_xcat_connection_timeout)
|
||||
|
||||
def request(self, method, url, body=None, headers={}):
|
||||
"""Send https request to xCAT server.
|
||||
|
||||
Will return a python dictionary including:
|
||||
{'status': http return code,
|
||||
'reason': http reason,
|
||||
'message': response message}
|
||||
|
||||
"""
|
||||
if body is not None:
|
||||
body = jsonutils.dumps(body)
|
||||
headers = {'content-type': 'text/plain',
|
||||
'content-length': len(body)}
|
||||
|
||||
_rep_ptn = ''.join(('&password=', CONF.zvm.zvm_xcat_password))
|
||||
LOG.debug("Sending request to xCAT. xCAT-Server:%(xcat_server)s "
|
||||
"Request-method:%(method)s "
|
||||
"URL:%(url)s "
|
||||
"Headers:%(headers)s "
|
||||
"Body:%(body)s" %
|
||||
{'xcat_server': CONF.zvm.zvm_xcat_server,
|
||||
'method': method,
|
||||
'url': url.replace(_rep_ptn, ''), # hide password in log
|
||||
'headers': str(headers),
|
||||
'body': body})
|
||||
|
||||
try:
|
||||
self.conn.request(method, url, body, headers)
|
||||
except socket.gaierror as err:
|
||||
msg = (_("Failed to connect xCAT server %(srv)s: %(err)s") %
|
||||
{'srv': self.host, 'err': err})
|
||||
raise ZVMException(msg)
|
||||
except (socket.error, socket.timeout) as err:
|
||||
msg = (_("Communicate with xCAT server %(srv)s error: %(err)s") %
|
||||
{'srv': self.host, 'err': err})
|
||||
raise ZVMException(msg)
|
||||
|
||||
try:
|
||||
res = self.conn.getresponse()
|
||||
except Exception as err:
|
||||
msg = (_("Failed to get response from xCAT server %(srv)s: "
|
||||
"%(err)s") % {'srv': self.host, 'err': err})
|
||||
raise ZVMException(msg)
|
||||
|
||||
msg = res.read()
|
||||
resp = {
|
||||
'status': res.status,
|
||||
'reason': res.reason,
|
||||
'message': msg}
|
||||
|
||||
LOG.debug("xCAT response: %s" % str(resp))
|
||||
|
||||
# Only "200" or "201" returned from xCAT can be considered
|
||||
# as good status
|
||||
err = None
|
||||
if method == "POST":
|
||||
if res.status != 201:
|
||||
err = str(resp)
|
||||
else:
|
||||
if res.status != 200:
|
||||
err = str(resp)
|
||||
|
||||
if err is not None:
|
||||
msg = (_('Request to xCAT server %(srv)s failed: %(err)s') %
|
||||
{'srv': self.host, 'err': err})
|
||||
raise ZVMException(msg)
|
||||
|
||||
return resp
|
||||
|
||||
|
||||
def xcat_request(method, url, body=None, headers={}):
|
||||
conn = XCATConnection()
|
||||
resp = conn.request(method, url, body, headers)
|
||||
return load_xcat_resp(resp['message'])
|
||||
|
||||
|
||||
def jsonloads(jsonstr):
|
||||
try:
|
||||
return jsonutils.loads(jsonstr)
|
||||
except ValueError:
|
||||
errmsg = _("xCAT response data is not in JSON format")
|
||||
LOG.error(errmsg)
|
||||
raise ZVMException(errmsg)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def expect_invalid_xcat_resp_data():
|
||||
"""Catch exceptions when using xCAT response data."""
|
||||
try:
|
||||
yield
|
||||
except (ValueError, TypeError, IndexError, AttributeError,
|
||||
KeyError) as err:
|
||||
msg = _("Invalid xCAT response data: %s") % str(err)
|
||||
raise ZVMException(msg)
|
||||
|
||||
|
||||
def wrap_invalid_xcat_resp_data_error(function):
|
||||
"""Catch exceptions when using xCAT response data."""
|
||||
|
||||
@functools.wraps(function)
|
||||
def decorated_function(*arg, **kwargs):
|
||||
try:
|
||||
return function(*arg, **kwargs)
|
||||
except (ValueError, TypeError, IndexError, AttributeError,
|
||||
KeyError) as err:
|
||||
msg = _("Invalid xCAT response data: %s") % str(err)
|
||||
raise ZVMException(msg)
|
||||
|
||||
return decorated_function
|
||||
|
||||
|
||||
@wrap_invalid_xcat_resp_data_error
|
||||
def translate_xcat_resp(rawdata, dirt):
|
||||
"""Translate xCAT response JSON stream to a python dictionary."""
|
||||
data_list = rawdata.split("\n")
|
||||
|
||||
data = {}
|
||||
|
||||
for ls in data_list:
|
||||
for k in dirt.keys():
|
||||
if ls.__contains__(dirt[k]):
|
||||
data[k] = ls[(ls.find(dirt[k]) + len(dirt[k])):].strip(' "')
|
||||
break
|
||||
|
||||
return data
|
||||
|
||||
|
||||
@wrap_invalid_xcat_resp_data_error
|
||||
def load_xcat_resp(message):
|
||||
"""Abstract information from xCAT REST response body."""
|
||||
resp_list = jsonloads(message)['data']
|
||||
keys = ('info', 'data', 'node', 'errorcode', 'error')
|
||||
|
||||
resp = {}
|
||||
|
||||
for k in keys:
|
||||
resp[k] = []
|
||||
|
||||
for d in resp_list:
|
||||
for k in keys:
|
||||
if d.get(k) is not None:
|
||||
resp[k].append(d.get(k))
|
||||
|
||||
err = resp.get('error')
|
||||
if err != []:
|
||||
for e in err:
|
||||
if _is_warning(str(e)):
|
||||
# ignore known warnings or errors:
|
||||
continue
|
||||
else:
|
||||
raise ZVMException(message)
|
||||
|
||||
_log_warnings(resp)
|
||||
|
||||
return resp
|
||||
|
||||
|
||||
def _log_warnings(resp):
|
||||
for msg in (resp['info'], resp['node'], resp['data']):
|
||||
msgstr = str(msg)
|
||||
if 'warn' in msgstr.lower():
|
||||
LOG.warning(_("Warning from xCAT: %s") % msgstr)
|
||||
|
||||
|
||||
def _is_warning(err_str):
|
||||
ignore_list = (
|
||||
'Warning: the RSA host key for',
|
||||
'Warning: Permanently added',
|
||||
'WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED',
|
||||
)
|
||||
|
||||
for im in ignore_list:
|
||||
if im in err_str:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def get_userid(node_name):
|
||||
"""Returns z/VM userid for the xCAT node."""
|
||||
url = XCATUrl().lsdef_node(''.join(['/', node_name]))
|
||||
info = xcat_request('GET', url)['info']
|
||||
|
||||
with expect_invalid_xcat_resp_data():
|
||||
for s in info[0]:
|
||||
if s.__contains__('userid='):
|
||||
return s.strip().rpartition('=')[2]
|
||||
|
||||
|
||||
def xdsh(node, commands):
|
||||
""""Run command on xCAT node."""
|
||||
LOG.debug('Run command %(cmd)s on xCAT node %(node)s' %
|
||||
{'cmd': commands, 'node': node})
|
||||
|
||||
def xdsh_execute(node, commands):
|
||||
"""Invoke xCAT REST API to execute command on node."""
|
||||
xdsh_commands = 'command=%s' % commands
|
||||
# Add -q (quiet) option to ignore ssh warnings and banner msg
|
||||
opt = 'options=-q'
|
||||
body = [xdsh_commands, opt]
|
||||
url = XCATUrl().xdsh('/' + node)
|
||||
return xcat_request("PUT", url, body)
|
||||
|
||||
res_dict = xdsh_execute(node, commands)
|
||||
|
||||
return res_dict
|
||||
|
||||
|
||||
def get_node_hostname(node_name):
|
||||
addp = '&col=node&value=%s&attribute=hostnames' % node_name
|
||||
url = XCATUrl().gettab("/hosts", addp)
|
||||
with expect_invalid_xcat_resp_data():
|
||||
return xcat_request("GET", url)['data'][0][0]
|
||||
|
||||
|
||||
def list_instances(hcp_info):
|
||||
zvm_host = CONF.zvm.zvm_host
|
||||
|
||||
url = XCATUrl().tabdump("/zvm")
|
||||
res_dict = xcat_request("GET", url)
|
||||
|
||||
instances = {}
|
||||
|
||||
with expect_invalid_xcat_resp_data():
|
||||
data_entries = res_dict['data'][0][1:]
|
||||
for data in data_entries:
|
||||
l = data.split(",")
|
||||
node = l[0].strip("\"")
|
||||
hcp = l[1].strip("\"")
|
||||
userid = l[2].strip("\"")
|
||||
|
||||
# zvm host and zhcp are not included in the list
|
||||
if (hcp.upper() == hcp_info['hostname'].upper() and
|
||||
node.upper() not in (zvm_host.upper(),
|
||||
hcp_info['nodename'].upper(),
|
||||
CONF.zvm.zvm_xcat_master.upper())):
|
||||
instances[node] = userid.upper()
|
||||
|
||||
return instances
|
||||
|
||||
|
||||
def image_performance_query(zhcp_node, inst_list):
|
||||
cmd = ('smcli Image_Performance_Query -T "%(inst_list)s" -c %(num)s' %
|
||||
{'inst_list': " ".join(inst_list), 'num': len(inst_list)})
|
||||
|
||||
with expect_invalid_xcat_resp_data():
|
||||
resp = xdsh(zhcp_node, cmd)
|
||||
raw_data = resp["data"][0][0]
|
||||
|
||||
ipq_kws = {
|
||||
'userid': "Guest name:",
|
||||
'guest_cpus': "Guest CPUs:",
|
||||
'used_cpu_time': "Used CPU time:",
|
||||
'used_memory': "Used memory:",
|
||||
}
|
||||
|
||||
pi_dict = {}
|
||||
with expect_invalid_xcat_resp_data():
|
||||
rpi_list = raw_data.split("".join((zhcp_node, ": \n")))
|
||||
for rpi in rpi_list:
|
||||
pi = translate_xcat_resp(rpi, ipq_kws)
|
||||
if pi.get('userid') is not None:
|
||||
pi_dict[pi['userid']] = pi
|
||||
|
||||
return pi_dict
|
||||
|
||||
|
||||
def get_inst_name(instance):
|
||||
return getattr(instance, 'OS-EXT-SRV-ATTR:instance_name', None)
|
||||
|
||||
@ -431,79 +32,20 @@ def get_inst_power_state(instance):
|
||||
return getattr(instance, 'OS-EXT-STS:power_state', None)
|
||||
|
||||
|
||||
def virutal_network_vswitch_query_iuo_stats(zhcp_node):
|
||||
cmd = ('smcli Virtual_Network_Vswitch_Query_IUO_Stats -T "%s" '
|
||||
'-k "switch_name=*"' % zhcp_node)
|
||||
class zVMConnectorRequestHandler(object):
|
||||
|
||||
with expect_invalid_xcat_resp_data():
|
||||
resp = xdsh(zhcp_node, cmd)
|
||||
raw_data_list = resp["data"][0]
|
||||
def __init__(self):
|
||||
_url = urlparse.urlparse(CONF.zvm_cloud_connector_url)
|
||||
self._conn = connector.ZVMConnector(_url.hostname, _url.port)
|
||||
|
||||
while raw_data_list.__contains__(None):
|
||||
raw_data_list.remove(None)
|
||||
|
||||
raw_data = '\n'.join(raw_data_list)
|
||||
rd_list = raw_data.split('\n')
|
||||
|
||||
def _parse_value(data_list, idx, keyword, offset):
|
||||
return idx + offset, data_list[idx].rpartition(keyword)[2].strip()
|
||||
|
||||
vsw_dict = {}
|
||||
with expect_invalid_xcat_resp_data():
|
||||
# vswitch count
|
||||
idx = 0
|
||||
idx, vsw_count = _parse_value(rd_list, idx, 'vswitch count:', 2)
|
||||
vsw_dict['vswitch_count'] = int(vsw_count)
|
||||
|
||||
# deal with each vswitch data
|
||||
vsw_dict['vswitches'] = []
|
||||
for i in range(vsw_dict['vswitch_count']):
|
||||
vsw_data = {}
|
||||
# skip vswitch number
|
||||
idx += 1
|
||||
# vswitch name
|
||||
idx, vsw_name = _parse_value(rd_list, idx, 'vswitch name:', 1)
|
||||
vsw_data['vswitch_name'] = vsw_name
|
||||
# uplink count
|
||||
idx, up_count = _parse_value(rd_list, idx, 'uplink count:', 1)
|
||||
# skip uplink data
|
||||
idx += int(up_count) * 9
|
||||
# skip bridge data
|
||||
idx += 8
|
||||
# nic count
|
||||
vsw_data['nics'] = []
|
||||
idx, nic_count = _parse_value(rd_list, idx, 'nic count:', 1)
|
||||
nic_count = int(nic_count)
|
||||
for j in range(nic_count):
|
||||
nic_data = {}
|
||||
idx, nic_id = _parse_value(rd_list, idx, 'nic_id:', 1)
|
||||
userid, toss, vdev = nic_id.partition(' ')
|
||||
nic_data['userid'] = userid
|
||||
nic_data['vdev'] = vdev
|
||||
idx, nic_data['nic_fr_rx'] = _parse_value(rd_list, idx,
|
||||
'nic_fr_rx:', 1)
|
||||
idx, nic_data['nic_fr_rx_dsc'] = _parse_value(rd_list, idx,
|
||||
'nic_fr_rx_dsc:', 1)
|
||||
idx, nic_data['nic_fr_rx_err'] = _parse_value(rd_list, idx,
|
||||
'nic_fr_rx_err:', 1)
|
||||
idx, nic_data['nic_fr_tx'] = _parse_value(rd_list, idx,
|
||||
'nic_fr_tx:', 1)
|
||||
idx, nic_data['nic_fr_tx_dsc'] = _parse_value(rd_list, idx,
|
||||
'nic_fr_tx_dsc:', 1)
|
||||
idx, nic_data['nic_fr_tx_err'] = _parse_value(rd_list, idx,
|
||||
'nic_fr_tx_err:', 1)
|
||||
idx, nic_data['nic_rx'] = _parse_value(rd_list, idx,
|
||||
'nic_rx:', 1)
|
||||
idx, nic_data['nic_tx'] = _parse_value(rd_list, idx,
|
||||
'nic_tx:', 1)
|
||||
vsw_data['nics'].append(nic_data)
|
||||
# vlan count
|
||||
idx, vlan_count = _parse_value(rd_list, idx, 'vlan count:', 1)
|
||||
# skip vlan data
|
||||
idx += int(vlan_count) * 3
|
||||
# skip the blank line
|
||||
idx += 1
|
||||
|
||||
vsw_dict['vswitches'].append(vsw_data)
|
||||
|
||||
return vsw_dict
|
||||
def call(self, func_name, *args, **kwargs):
|
||||
results = self._conn.send_request(func_name, *args, **kwargs)
|
||||
if results['overallRC'] == 0:
|
||||
return results['output']
|
||||
else:
|
||||
msg = ("z/VM Cloud Connector request %(api)s failed with "
|
||||
"parameters: %(args)s %(kwargs)s . Results: %(results)s" %
|
||||
{'api': func_name, 'args': str(args), 'kwargs': str(kwargs),
|
||||
'results': str(results)})
|
||||
LOG.debug(msg)
|
||||
raise exception.ZVMConnectorRequestFailed(msg=msg, results=results)
|
||||
|
@ -14,304 +14,202 @@
|
||||
|
||||
|
||||
import mock
|
||||
import unittest
|
||||
|
||||
from ceilometer.compute.virt import inspector as virt_inspertor
|
||||
from oslo_config import fixture as fixture_config
|
||||
from oslo_utils import timeutils
|
||||
from oslotest import base
|
||||
|
||||
from ceilometer_zvm.compute.virt.zvm import inspector as zvm_inspector
|
||||
from ceilometer.compute.virt import inspector as virt_inspector
|
||||
from ceilometer_zvm.compute.virt.zvm import conf
|
||||
from ceilometer_zvm.compute.virt.zvm import exception as zvmexception
|
||||
from ceilometer_zvm.compute.virt.zvm import inspector as zvminspector
|
||||
from ceilometer_zvm.compute.virt.zvm import utils as zvmutils
|
||||
|
||||
|
||||
class TestZVMInspector(base.BaseTestCase):
|
||||
CONF = conf.CONF
|
||||
|
||||
|
||||
class TestZVMInspector(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.CONF = self.useFixture(
|
||||
fixture_config.Config(zvm_inspector.CONF)).conf
|
||||
self.CONF.set_override('xcat_zhcp_nodename', 'zhcp', 'zvm')
|
||||
super(TestZVMInspector, self).setUp()
|
||||
unittest.TestCase.setUp(self)
|
||||
CONF.zvm_cloud_connector_url = 'https://1.1.1.1:1111'
|
||||
self._inspector = zvminspector.ZVMInspector()
|
||||
self._inst = mock.MagicMock()
|
||||
self._stats_dict = {'guest_cpus': 1,
|
||||
'used_cpu_time_us': 7185838,
|
||||
'elapsed_cpu_time_us': 35232895,
|
||||
'min_cpu_count': 2,
|
||||
'max_cpu_limit': 10000,
|
||||
'samples_cpu_in_use': 0,
|
||||
'samples_cpu_delay': 0,
|
||||
'used_mem_kb': 390232,
|
||||
'max_mem_kb': 3097152,
|
||||
'min_mem_kb': 0,
|
||||
'shared_mem_kb': 5222192
|
||||
}
|
||||
self._vnics_list = [{'vswitch_name': 'vsw1',
|
||||
'nic_vdev': '0600',
|
||||
'nic_fr_rx': 99999,
|
||||
'nic_fr_tx': 99999,
|
||||
'nic_rx': 9999999,
|
||||
'nic_tx': 9999999,
|
||||
'nic_fr_rx_dsc': 0,
|
||||
'nic_fr_tx_dsc': 0,
|
||||
'nic_fr_rx_err': 0,
|
||||
'nic_fr_tx_err': 0},
|
||||
{'vswitch_name': 'vsw2',
|
||||
'nic_vdev': '0700',
|
||||
'nic_fr_rx': 88888,
|
||||
'nic_fr_tx': 88888,
|
||||
'nic_rx': 8888888,
|
||||
'nic_tx': 8888888,
|
||||
'nic_fr_rx_dsc': 0,
|
||||
'nic_fr_tx_dsc': 0,
|
||||
'nic_fr_rx_err': 0,
|
||||
'nic_fr_tx_err': 0}]
|
||||
|
||||
get_nhn = mock.MagicMock(return_value='zhcp.com')
|
||||
get_uid = mock.MagicMock(return_value='zhcp')
|
||||
with mock.patch.multiple(zvmutils, get_node_hostname=get_nhn,
|
||||
get_userid=get_uid):
|
||||
self.inspector = zvm_inspector.ZVMInspector()
|
||||
|
||||
def test_init(self):
|
||||
self.assertEqual('zhcp', self.inspector.zhcp_info['nodename'])
|
||||
self.assertEqual('zhcp.com', self.inspector.zhcp_info['hostname'])
|
||||
self.assertEqual('zhcp', self.inspector.zhcp_info['userid'])
|
||||
|
||||
@mock.patch.object(zvmutils, 'image_performance_query')
|
||||
def test_update_inst_cpu_mem_stat(self, ipq):
|
||||
ipq.return_value = {'INST1': {'userid': 'INST1',
|
||||
'guest_cpus': '2',
|
||||
'used_cpu_time': '1710205201 uS',
|
||||
'used_memory': '4189268 KB'},
|
||||
'INST2': {'userid': 'INST2',
|
||||
'guest_cpus': '4',
|
||||
'used_cpu_time': '1710205201 uS',
|
||||
'used_memory': '4189268 KB'}}
|
||||
inst_list = {'inst1': 'INST1', 'inst2': 'INST2'}
|
||||
self.inspector._update_inst_cpu_mem_stat(inst_list)
|
||||
|
||||
exp1 = {'guest_cpus': 2,
|
||||
'nodename': 'inst1',
|
||||
'used_cpu_time': 1710205201000,
|
||||
'used_memory': 4091,
|
||||
'userid': 'INST1'}
|
||||
self.assertEqual(exp1, self.inspector.cache.get('cpumem', 'inst1'))
|
||||
self.assertEqual(4,
|
||||
self.inspector.cache.get('cpumem', 'inst2')['guest_cpus'])
|
||||
|
||||
@mock.patch.object(zvmutils, 'image_performance_query')
|
||||
def test_update_inst_cpu_mem_stat_invalid_data(self, ipq):
|
||||
ipq.return_value = {'INST1': {'userid': 'INST1', 'guest_cpus': 's'}}
|
||||
self.assertRaises(zvmutils.ZVMException,
|
||||
self.inspector._update_inst_cpu_mem_stat,
|
||||
{'inst1': 'INST1'})
|
||||
@mock.patch.object(zvminspector.ZVMInspector, "_inspect_inst_data")
|
||||
def test_inspect_instance(self, inspect_inst):
|
||||
inspect_inst.return_value = self._stats_dict
|
||||
rdata = self._inspector.inspect_instance(self._inst, 0)
|
||||
inspect_inst.assert_called_once_with(self._inst, 'stats')
|
||||
self.assertIsInstance(rdata, virt_inspector.InstanceStats)
|
||||
self.assertEqual(rdata.cpu_number, 1)
|
||||
self.assertEqual(rdata.cpu_time, 7185838000)
|
||||
self.assertEqual(rdata.memory_usage, 381)
|
||||
|
||||
@mock.patch("ceilometer_zvm.compute.virt.zvm.inspector.ZVMInspector."
|
||||
"_update_inst_cpu_mem_stat")
|
||||
@mock.patch.object(zvmutils, 'list_instances')
|
||||
def test_update_cache_all(self, list_inst, upd):
|
||||
inst_list = {'inst1': 'INST1', 'inst2': 'INST2'}
|
||||
list_inst.return_value = inst_list
|
||||
self.inspector._update_cache("cpumem", {})
|
||||
list_inst.assert_called_with(self.inspector.zhcp_info)
|
||||
upd.assert_called_with(inst_list)
|
||||
|
||||
@mock.patch("ceilometer_zvm.compute.virt.zvm.inspector.ZVMInspector."
|
||||
"_update_inst_cpu_mem_stat")
|
||||
def test_update_cache_one_inst(self, upd):
|
||||
inst = {'inst1': 'INST1'}
|
||||
self.inspector._update_cache('cpumem', inst)
|
||||
upd.assert_called_with(inst)
|
||||
|
||||
@mock.patch("ceilometer_zvm.compute.virt.zvm.inspector.ZVMInspector."
|
||||
"_update_cache")
|
||||
def test_check_expiration_and_update_cache(self, udc):
|
||||
self.inspector._check_expiration_and_update_cache('cpus')
|
||||
udc.assert_called_once_with('cpus')
|
||||
|
||||
@mock.patch("ceilometer_zvm.compute.virt.zvm.inspector.ZVMInspector."
|
||||
"_update_cache")
|
||||
def test_check_expiration_and_update_cache_no_update(self, udc):
|
||||
self.inspector.cache_expiration = timeutils.utcnow_ts() + 100
|
||||
self.inspector._check_expiration_and_update_cache('cpus')
|
||||
udc.assert_not_called()
|
||||
|
||||
"_inspect_inst_data")
|
||||
@mock.patch.object(zvmutils, 'get_inst_name')
|
||||
@mock.patch("ceilometer_zvm.compute.virt.zvm.inspector.ZVMInspector."
|
||||
"_check_expiration_and_update_cache")
|
||||
def test_get_inst_stat(self, check_update, get_name):
|
||||
get_name.return_value = 'inst1'
|
||||
self.inspector.cache.set('cpumem',
|
||||
{'guest_cpus': 2, 'nodename': 'inst1'})
|
||||
|
||||
inst_stat = self.inspector._get_inst_stat('cpumem', {'inst1': 'INST1'})
|
||||
self.assertEqual(2, inst_stat['guest_cpus'])
|
||||
check_update.assert_called_once_with('cpumem')
|
||||
|
||||
@mock.patch("ceilometer_zvm.compute.virt.zvm.inspector.ZVMInspector."
|
||||
"_update_cache")
|
||||
@mock.patch.object(zvmutils, 'get_userid')
|
||||
@mock.patch.object(zvmutils, 'get_inst_name')
|
||||
@mock.patch("ceilometer_zvm.compute.virt.zvm.inspector.ZVMInspector."
|
||||
"_check_expiration_and_update_cache")
|
||||
def test_get_inst_stat_not_found(self, check_update, get_name,
|
||||
get_uid, update):
|
||||
get_name.return_value = 'inst1'
|
||||
get_uid.return_value = 'INST1'
|
||||
|
||||
self.assertRaises(virt_inspertor.InstanceNotFoundException,
|
||||
self.inspector._get_inst_stat, 'cpumem',
|
||||
{'inst1': 'INST1'})
|
||||
check_update.assert_called_once_with('cpumem')
|
||||
update.assert_called_once_with('cpumem', {'inst1': 'INST1'})
|
||||
def test_inspect_vnics(self, get_inst_name, inspect_data):
|
||||
get_inst_name.return_value = 'INST1'
|
||||
inspect_data.return_value = self._vnics_list
|
||||
interface = list(self._inspector.inspect_vnics({'inst1': 'INST1'}))[0]
|
||||
if interface.name == '0600':
|
||||
self.assertEqual(99999, interface.rx_packets)
|
||||
else:
|
||||
self.assertEqual(8888888, interface.rx_bytes)
|
||||
inspect_data.assert_called_once_with({'inst1': 'INST1'}, 'vnics')
|
||||
|
||||
@mock.patch.object(zvmutils.zVMConnectorRequestHandler, 'call')
|
||||
@mock.patch.object(zvmutils, 'get_inst_power_state')
|
||||
@mock.patch.object(zvmutils, 'get_inst_name')
|
||||
def test_get_inst_stat_shutoff(self, get_name, get_power_stat):
|
||||
get_name.return_value = 'inst1'
|
||||
get_power_stat.return_value = 0x04
|
||||
self.inspector.instances = {'inst1': 'INST1'}
|
||||
def test_private_inspect_inst_type_stats(self, inst_name, inst_power_state,
|
||||
sdkclient_call):
|
||||
inst_name.return_value = 'FAKEINST'
|
||||
inst_power_state.return_value = 0x01
|
||||
sdkclient_call.return_value = {'FAKEINST': self._stats_dict}
|
||||
rdata = self._inspector._inspect_inst_data(self._inst, 'stats')
|
||||
inst_name.assert_called_once_with(self._inst)
|
||||
inst_power_state.assert_called_once_with(self._inst)
|
||||
sdkclient_call.assert_called_once_with('guest_inspect_stats',
|
||||
'FAKEINST')
|
||||
self.assertDictEqual(rdata, self._stats_dict)
|
||||
|
||||
self.assertRaises(virt_inspertor.InstanceShutOffException,
|
||||
self.inspector._get_inst_stat, 'cpumem',
|
||||
{'inst1': 'INST1'})
|
||||
get_name.assert_called_once_with({'inst1': 'INST1'})
|
||||
get_power_stat.assert_called_once_with({'inst1': 'INST1'})
|
||||
|
||||
@mock.patch("ceilometer_zvm.compute.virt.zvm.inspector.ZVMInspector."
|
||||
"_update_cache")
|
||||
@mock.patch.object(zvmutils, 'get_userid')
|
||||
@mock.patch("ceilometer_zvm.compute.virt.zvm.utils.CacheData.get")
|
||||
@mock.patch.object(zvmutils.zVMConnectorRequestHandler, 'call')
|
||||
@mock.patch.object(zvmutils, 'get_inst_power_state')
|
||||
@mock.patch.object(zvmutils, 'get_inst_name')
|
||||
@mock.patch("ceilometer_zvm.compute.virt.zvm.inspector.ZVMInspector."
|
||||
"_check_expiration_and_update_cache")
|
||||
def test_get_inst_stat_update_cache(self, check_update, get_name,
|
||||
cache_get, get_uid, update):
|
||||
get_name.return_value = 'inst1'
|
||||
cache_get.side_effect = [None, {'guest_cpus': 2, 'nodename': 'inst1'}]
|
||||
get_uid.return_value = 'INST1'
|
||||
|
||||
inst_stat = self.inspector._get_inst_stat('cpus', {'inst1': 'INST1'})
|
||||
self.assertEqual(2, inst_stat['guest_cpus'])
|
||||
check_update.assert_called_once_with('cpus')
|
||||
update.assert_called_once_with('cpus', {'inst1': 'INST1'})
|
||||
def test_private_inspect_inst_type_vnics(self, inst_name, inst_power_state,
|
||||
sdkclient_call):
|
||||
inst_name.return_value = 'FAKEINST'
|
||||
inst_power_state.return_value = 0x01
|
||||
sdkclient_call.return_value = {'FAKEINST': self._vnics_list}
|
||||
rdata = self._inspector._inspect_inst_data(self._inst, 'vnics')
|
||||
inst_name.assert_called_once_with(self._inst)
|
||||
inst_power_state.assert_called_once_with(self._inst)
|
||||
sdkclient_call.assert_called_once_with('guest_inspect_vnics',
|
||||
'FAKEINST')
|
||||
self.assertListEqual(rdata, self._vnics_list)
|
||||
|
||||
@mock.patch.object(zvmutils.zVMConnectorRequestHandler, 'call')
|
||||
@mock.patch.object(zvmutils, 'get_inst_power_state')
|
||||
@mock.patch.object(zvmutils, 'get_inst_name')
|
||||
@mock.patch("ceilometer_zvm.compute.virt.zvm.inspector.ZVMInspector."
|
||||
"_check_expiration_and_update_cache")
|
||||
def test_get_inst_stat_nics(self, check_update, get_name):
|
||||
get_name.return_value = 'inst1'
|
||||
self.inspector.cache.set(
|
||||
'vnics',
|
||||
{'nodename': 'inst1',
|
||||
'userid': 'INST1',
|
||||
'nics': [{'vswitch_name': 'vsw1',
|
||||
'nic_vdev': '0600',
|
||||
'nic_fr_rx': 99999,
|
||||
'nic_fr_tx': 99999,
|
||||
'nic_rx': 9999999,
|
||||
'nic_tx': 9999999},
|
||||
{'vswitch_name': 'vsw2',
|
||||
'nic_vdev': '0700',
|
||||
'nic_fr_rx': 88888,
|
||||
'nic_fr_tx': 88888,
|
||||
'nic_rx': 8888888,
|
||||
'nic_tx': 8888888}]}
|
||||
)
|
||||
inst_stat = self.inspector._get_inst_stat('vnics', {'inst1': 'INST1'})
|
||||
self.assertEqual(2, len(inst_stat['nics']))
|
||||
check_update.assert_called_once_with('vnics')
|
||||
def test_private_inspect_inst_power_off(self, inst_name,
|
||||
inst_power_state,
|
||||
sdkclient_call):
|
||||
inst_name.return_value = 'FAKEINST'
|
||||
inst_power_state.return_value = 0x04
|
||||
self.assertRaises(virt_inspector.InstanceShutOffException,
|
||||
self._inspector._inspect_inst_data,
|
||||
self._inst, 'stats')
|
||||
inst_name.assert_called_once_with(self._inst)
|
||||
inst_power_state.assert_called_once_with(self._inst)
|
||||
sdkclient_call.assert_not_called()
|
||||
|
||||
@mock.patch("ceilometer_zvm.compute.virt.zvm.inspector.ZVMInspector."
|
||||
"_get_inst_stat")
|
||||
def test_inspect_cpus(self, get_stat):
|
||||
get_stat.return_value = {'guest_cpus': 2, 'used_cpu_time': 99999999}
|
||||
cpu_stat = self.inspector.inspect_cpus(None)
|
||||
self.assertEqual(2, cpu_stat.number)
|
||||
self.assertEqual(99999999, cpu_stat.time)
|
||||
get_stat.assert_called_once_with('cpumem', None)
|
||||
@mock.patch.object(zvmutils.zVMConnectorRequestHandler, 'call')
|
||||
@mock.patch.object(zvmutils, 'get_inst_power_state')
|
||||
@mock.patch.object(zvmutils, 'get_inst_name')
|
||||
def test_private_inspect_inst_not_exist(self, inst_name,
|
||||
inst_power_state,
|
||||
sdkclient_call):
|
||||
inst_name.return_value = 'FAKEINST'
|
||||
inst_power_state.return_value = 0x01
|
||||
sdkclient_call.side_effect = [{},
|
||||
zvmexception.ZVMConnectorRequestFailed(
|
||||
msg='SDK Request Failed',
|
||||
results={'overallRC': 404,
|
||||
'output': ''})
|
||||
]
|
||||
self.assertRaises(virt_inspector.InstanceNotFoundException,
|
||||
self._inspector._inspect_inst_data,
|
||||
self._inst, 'stats')
|
||||
inst_name.assert_called_once_with(self._inst)
|
||||
inst_power_state.assert_called_once_with(self._inst)
|
||||
|
||||
@mock.patch("ceilometer_zvm.compute.virt.zvm.inspector.ZVMInspector."
|
||||
"_get_inst_stat")
|
||||
def test_inspect_memory_usage(self, get_stat):
|
||||
get_stat.return_value = {'used_memory': 1998}
|
||||
mem_usage = self.inspector.inspect_memory_usage(None)
|
||||
self.assertEqual(1998, mem_usage.usage)
|
||||
get_stat.assert_called_once_with('cpumem', None)
|
||||
@mock.patch.object(zvmutils.zVMConnectorRequestHandler, 'call')
|
||||
@mock.patch.object(zvmutils, 'get_inst_power_state')
|
||||
@mock.patch.object(zvmutils, 'get_inst_name')
|
||||
def test_private_inspect_inst_other_exception(self, inst_name,
|
||||
inst_power_state,
|
||||
sdkclient_call):
|
||||
inst_name.return_value = 'FAKEINST'
|
||||
inst_power_state.return_value = 0x01
|
||||
sdkclient_call.side_effect = Exception()
|
||||
self.assertRaises(virt_inspector.NoDataException,
|
||||
self._inspector._inspect_inst_data,
|
||||
self._inst, 'stats')
|
||||
inst_name.assert_called_once_with(self._inst)
|
||||
inst_power_state.assert_called_once_with(self._inst)
|
||||
sdkclient_call.assert_called_with('guest_inspect_stats', 'FAKEINST')
|
||||
|
||||
@mock.patch.object(zvmutils, 'virutal_network_vswitch_query_iuo_stats')
|
||||
def test_update_inst_nic_stat(self, vswq):
|
||||
vsw_dist = {'vswitches': [
|
||||
{'vswitch_name': 'XCATVSW1',
|
||||
'nics': [
|
||||
{'nic_fr_rx_dsc': '0',
|
||||
'nic_fr_rx_err': '0',
|
||||
'nic_fr_tx_err': '4',
|
||||
'userid': 'INST1',
|
||||
'nic_rx': '103024058',
|
||||
'nic_fr_rx': '573952',
|
||||
'nic_fr_tx': '548780',
|
||||
'vdev': '0600',
|
||||
'nic_fr_tx_dsc': '0',
|
||||
'nic_tx': '102030890'},
|
||||
{'nic_fr_rx_dsc': '0',
|
||||
'nic_fr_rx_err': '0',
|
||||
'nic_fr_tx_err': '4',
|
||||
'userid': 'INST2',
|
||||
'nic_rx': '3111714',
|
||||
'nic_fr_rx': '17493',
|
||||
'nic_fr_tx': '16886',
|
||||
'vdev': '0600',
|
||||
'nic_fr_tx_dsc': '0',
|
||||
'nic_tx': '3172646'}]},
|
||||
{'vswitch_name': 'XCATVSW2',
|
||||
'nics': [
|
||||
{'nic_fr_rx_dsc': '0',
|
||||
'nic_fr_rx_err': '0',
|
||||
'nic_fr_tx_err': '0',
|
||||
'userid': 'INST1',
|
||||
'nic_rx': '4684435',
|
||||
'nic_fr_rx': '34958',
|
||||
'nic_fr_tx': '16211',
|
||||
'vdev': '1000',
|
||||
'nic_fr_tx_dsc': '0',
|
||||
'nic_tx': '3316601'},
|
||||
{'nic_fr_rx_dsc': '0',
|
||||
'nic_fr_rx_err': '0',
|
||||
'nic_fr_tx_err': '0',
|
||||
'userid': 'INST2',
|
||||
'nic_rx': '3577163',
|
||||
'nic_fr_rx': '27211',
|
||||
'nic_fr_tx': '12344',
|
||||
'vdev': '1000',
|
||||
'nic_fr_tx_dsc': '0',
|
||||
'nic_tx': '2515045'}]}],
|
||||
'vswitch_count': 2}
|
||||
vswq.return_value = vsw_dist
|
||||
instances = {'inst1': 'INST1', 'inst2': 'INST2'}
|
||||
self.inspector._update_inst_nic_stat(instances)
|
||||
@mock.patch.object(zvmutils.zVMConnectorRequestHandler, 'call')
|
||||
@mock.patch.object(zvmutils, 'get_inst_power_state')
|
||||
@mock.patch.object(zvmutils, 'get_inst_name')
|
||||
def test_private_inspect_inst_null_data_shutdown(self, inst_name,
|
||||
inst_power_state,
|
||||
sdkclient_call):
|
||||
inst_name.return_value = 'FAKEINST'
|
||||
inst_power_state.return_value = 0x01
|
||||
sdkclient_call.side_effect = [{}, 'off']
|
||||
self.assertRaises(virt_inspector.InstanceShutOffException,
|
||||
self._inspector._inspect_inst_data,
|
||||
self._inst, 'stats')
|
||||
inst_name.assert_called_once_with(self._inst)
|
||||
inst_power_state.assert_called_once_with(self._inst)
|
||||
|
||||
exp_inst1_nics_data = [
|
||||
{'nic_fr_rx': 573952,
|
||||
'nic_fr_rx_dsc': 0,
|
||||
'nic_fr_rx_err': 0,
|
||||
'nic_fr_tx': 548780,
|
||||
'nic_fr_tx_dsc': 0,
|
||||
'nic_fr_tx_err': 4,
|
||||
'nic_rx': 103024058,
|
||||
'nic_tx': 102030890,
|
||||
'nic_vdev': '0600',
|
||||
'vswitch_name': 'XCATVSW1'},
|
||||
{'nic_fr_rx': 34958,
|
||||
'nic_fr_rx_dsc': 0,
|
||||
'nic_fr_rx_err': 0,
|
||||
'nic_fr_tx': 16211,
|
||||
'nic_fr_tx_dsc': 0,
|
||||
'nic_fr_tx_err': 0,
|
||||
'nic_rx': 4684435,
|
||||
'nic_tx': 3316601,
|
||||
'nic_vdev': '1000',
|
||||
'vswitch_name': 'XCATVSW2'}
|
||||
]
|
||||
self.assertEqual(exp_inst1_nics_data,
|
||||
self.inspector.cache.get('vnics', 'inst1')['nics'])
|
||||
vswq.assert_called_once_with('zhcp')
|
||||
@mock.patch.object(zvmutils.zVMConnectorRequestHandler, 'call')
|
||||
@mock.patch.object(zvmutils, 'get_inst_power_state')
|
||||
@mock.patch.object(zvmutils, 'get_inst_name')
|
||||
def test_private_inspect_inst_null_data_active(self, inst_name,
|
||||
inst_power_state,
|
||||
sdkclient_call):
|
||||
inst_name.return_value = 'FAKEINST'
|
||||
inst_power_state.return_value = 0x01
|
||||
sdkclient_call.side_effect = [{}, 'on']
|
||||
self.assertRaises(virt_inspector.NoDataException,
|
||||
self._inspector._inspect_inst_data,
|
||||
self._inst, 'stats')
|
||||
inst_name.assert_called_once_with(self._inst)
|
||||
inst_power_state.assert_called_once_with(self._inst)
|
||||
|
||||
@mock.patch("ceilometer_zvm.compute.virt.zvm.inspector.ZVMInspector."
|
||||
"_get_inst_stat")
|
||||
def test_inspect_nics(self, get_stat):
|
||||
get_stat.return_value = {'nodename': 'inst1',
|
||||
'userid': 'INST1',
|
||||
'nics': [
|
||||
{'vswitch_name': 'vsw1',
|
||||
'nic_vdev': '0600',
|
||||
'nic_fr_rx': 99999,
|
||||
'nic_fr_tx': 99999,
|
||||
'nic_rx': 9999999,
|
||||
'nic_tx': 9999999,
|
||||
'nic_fr_rx_dsc': 0,
|
||||
'nic_fr_tx_dsc': 0,
|
||||
'nic_fr_rx_err': 0,
|
||||
'nic_fr_tx_err': 0},
|
||||
{'vswitch_name': 'vsw2',
|
||||
'nic_vdev': '0700',
|
||||
'nic_fr_rx': 88888,
|
||||
'nic_fr_tx': 88888,
|
||||
'nic_rx': 8888888,
|
||||
'nic_tx': 8888888,
|
||||
'nic_fr_rx_dsc': 0,
|
||||
'nic_fr_tx_dsc': 0,
|
||||
'nic_fr_rx_err': 0,
|
||||
'nic_fr_tx_err': 0}]}
|
||||
nic, stat = list(self.inspector.inspect_vnics({'inst1': 'INST1'}))[0]
|
||||
if nic.name == '0600':
|
||||
self.assertEqual(99999, stat.rx_packets)
|
||||
else:
|
||||
self.assertEqual(8888888, stat.rx_bytes)
|
||||
get_stat.assert_called_once_with('vnics', {'inst1': 'INST1'})
|
||||
@mock.patch.object(zvmutils.zVMConnectorRequestHandler, 'call')
|
||||
@mock.patch.object(zvmutils, 'get_inst_power_state')
|
||||
@mock.patch.object(zvmutils, 'get_inst_name')
|
||||
def test_private_inspect_inst_null_data_unknown_exception(self,
|
||||
inst_name, inst_power_state, sdkclient_call):
|
||||
inst_name.return_value = 'FAKEINST'
|
||||
inst_power_state.return_value = 0x01
|
||||
sdkclient_call.side_effect = [{}, Exception()]
|
||||
self.assertRaises(virt_inspector.NoDataException,
|
||||
self._inspector._inspect_inst_data,
|
||||
self._inst, 'stats')
|
||||
inst_name.assert_called_once_with(self._inst)
|
||||
inst_power_state.assert_called_once_with(self._inst)
|
||||
|
@ -14,309 +14,25 @@
|
||||
|
||||
|
||||
import mock
|
||||
import unittest
|
||||
|
||||
from oslo_config import fixture as fixture_config
|
||||
from oslo_serialization import jsonutils
|
||||
from oslotest import base
|
||||
|
||||
from ceilometer_zvm.compute.virt.zvm import inspector as zvm_inspector
|
||||
from ceilometer_zvm.compute.virt.zvm import utils as zvmutils
|
||||
|
||||
|
||||
class TestXCATUrl(base.BaseTestCase):
|
||||
class TestZVMUtils(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.CONF = self.useFixture(
|
||||
fixture_config.Config(zvm_inspector.CONF)).conf
|
||||
self.CONF.set_override('zvm_xcat_username', 'user', 'zvm')
|
||||
self.CONF.set_override('zvm_xcat_password', 'pwd', 'zvm')
|
||||
super(TestXCATUrl, self).setUp()
|
||||
self.xcaturl = zvmutils.XCATUrl()
|
||||
|
||||
def test_xdsh(self):
|
||||
url = ("/xcatws/nodes/fakenode/dsh"
|
||||
"?userName=user&password=pwd&format=json")
|
||||
self.assertEqual(self.xcaturl.xdsh("/fakenode"), url)
|
||||
|
||||
def test_gettab(self):
|
||||
url = ("/xcatws/tables/table"
|
||||
"?userName=user&password=pwd&format=json&addp")
|
||||
self.assertEqual(self.xcaturl.gettab('/table', '&addp'), url)
|
||||
|
||||
def test_lsdef_node(self):
|
||||
url = ("/xcatws/nodes/fakenode"
|
||||
"?userName=user&password=pwd&format=json")
|
||||
self.assertEqual(self.xcaturl.lsdef_node("/fakenode"), url)
|
||||
|
||||
def test_tabdump(self):
|
||||
url = ("/xcatws/tables/table"
|
||||
"?userName=user&password=pwd&format=json&addp")
|
||||
self.assertEqual(self.xcaturl.tabdump('/table', '&addp'), url)
|
||||
|
||||
|
||||
class TestXCATConnection(base.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.CONF = self.useFixture(
|
||||
fixture_config.Config(zvm_inspector.CONF)).conf
|
||||
self.CONF.set_override('zvm_xcat_server', '1.1.1.1', 'zvm')
|
||||
self.CONF.set_override('zvm_xcat_username', 'user', 'zvm')
|
||||
self.CONF.set_override('zvm_xcat_password', 'pwd', 'zvm')
|
||||
super(TestXCATConnection, self).setUp()
|
||||
self.conn = zvmutils.XCATConnection()
|
||||
|
||||
def test_request(self):
|
||||
with mock.patch.object(self.conn, 'conn') as fake_conn:
|
||||
fake_res = mock.Mock()
|
||||
fake_res.status = 200
|
||||
fake_res.reason = 'OK'
|
||||
fake_res.read.return_value = 'data'
|
||||
fake_conn.getresponse.return_value = fake_res
|
||||
|
||||
exp_data = {'status': 200,
|
||||
'reason': 'OK',
|
||||
'message': 'data'}
|
||||
res_data = self.conn.request("GET", 'url')
|
||||
self.assertEqual(exp_data, res_data)
|
||||
|
||||
def test_request_failed(self):
|
||||
with mock.patch.object(self.conn, 'conn') as fake_conn:
|
||||
fake_res = mock.Mock()
|
||||
fake_res.status = 500
|
||||
fake_res.reason = 'INVALID'
|
||||
fake_res.read.return_value = 'err data'
|
||||
fake_conn.getresponse.return_value = fake_res
|
||||
|
||||
self.assertRaises(zvmutils.ZVMException,
|
||||
self.conn.request, 'GET', 'url')
|
||||
|
||||
|
||||
class TestZVMUtils(base.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.CONF = self.useFixture(
|
||||
fixture_config.Config(zvm_inspector.CONF)).conf
|
||||
self.CONF.set_override('zvm_xcat_server', '1.1.1.1', 'zvm')
|
||||
self.CONF.set_override('zvm_xcat_username', 'user', 'zvm')
|
||||
self.CONF.set_override('zvm_xcat_password', 'pwd', 'zvm')
|
||||
self.CONF.set_override('zvm_host', 'zvmhost1', 'zvm')
|
||||
super(TestZVMUtils, self).setUp()
|
||||
self._inst = mock.MagicMock()
|
||||
setattr(self._inst, 'OS-EXT-SRV-ATTR:instance_name',
|
||||
'fakeinst')
|
||||
setattr(self._inst, 'OS-EXT-STS:power_state',
|
||||
0x01)
|
||||
|
||||
@mock.patch('ceilometer_zvm.compute.virt.zvm.utils.XCATConnection.request')
|
||||
def test_xcat_request(self, xcat_req):
|
||||
xcat_req.return_value = {'message': jsonutils.dumps(
|
||||
{'data': [{'data': ['data']}]})}
|
||||
self.assertEqual([['data']],
|
||||
zvmutils.xcat_request("GET", 'url')['data'])
|
||||
def test_get_instance_name(self):
|
||||
inst = zvmutils.get_inst_name(self._inst)
|
||||
self.assertEqual('fakeinst', inst)
|
||||
|
||||
@mock.patch('ceilometer_zvm.compute.virt.zvm.utils.xcat_request')
|
||||
def test_get_userid(self, xcat_req):
|
||||
xcat_req.return_value = {'info': [['userid=fakeuser']]}
|
||||
self.assertEqual('fakeuser', zvmutils.get_userid('fakenode'))
|
||||
|
||||
@mock.patch('ceilometer_zvm.compute.virt.zvm.utils.xcat_request')
|
||||
def test_xdsh(self, xcat_req):
|
||||
zvmutils.xdsh('node', 'cmds')
|
||||
xcat_req.assert_any_call('PUT',
|
||||
'/xcatws/nodes/node/dsh?userName=user&password=pwd&format=json',
|
||||
['command=cmds', 'options=-q'])
|
||||
|
||||
@mock.patch('ceilometer_zvm.compute.virt.zvm.utils.xcat_request')
|
||||
def test_get_node_hostname(self, xcat_req):
|
||||
xcat_req.return_value = {'data': [['hostname']]}
|
||||
self.assertEqual('hostname', zvmutils.get_node_hostname('nodename'))
|
||||
|
||||
@mock.patch.object(zvmutils, 'xcat_request')
|
||||
def test_list_instances(self, xcat_req):
|
||||
resp_list = [
|
||||
'toss',
|
||||
'"xcat","zhcp.com","xcat"',
|
||||
'"zhcp","zhcp.com","zhcp"',
|
||||
'"zvmhost1","zhcp.com",""',
|
||||
'"node1","zhcp.com","node1"',
|
||||
'"node2","zhcp.com","node2"',
|
||||
'"node3","zhcp2.com","node3"',
|
||||
]
|
||||
xcat_req.return_value = {'data': [resp_list]}
|
||||
|
||||
exp_list = {'node1': 'NODE1', 'node2': 'NODE2'}
|
||||
hcp_info = {'nodename': 'zhcp',
|
||||
'hostname': 'zhcp.com',
|
||||
'userid': 'zhcp'}
|
||||
self.assertEqual(exp_list, zvmutils.list_instances(hcp_info))
|
||||
|
||||
@mock.patch.object(zvmutils, 'xcat_request')
|
||||
def test_list_instances_invalid_data(self, xcat_req):
|
||||
resp_list = [
|
||||
'toss',
|
||||
'"xcat","zhcp.com","xcat"',
|
||||
'"zhcp","zhcp.com","zhcp"',
|
||||
'"zvmhost1","zhcp.com",""',
|
||||
'"node1","zhcp.com"',
|
||||
]
|
||||
hcp_info = {'nodename': 'zhcp',
|
||||
'hostname': 'zhcp.com',
|
||||
'userid': 'zhcp'}
|
||||
xcat_req.return_value = {'data': [resp_list]}
|
||||
self.assertRaises(zvmutils.ZVMException, zvmutils.list_instances,
|
||||
hcp_info)
|
||||
|
||||
@mock.patch.object(zvmutils, 'xdsh')
|
||||
def test_image_performance_query(self, dsh):
|
||||
res_data = ["zhcp: Number of virtual server IDs: 2 \n"
|
||||
"zhcp: Guest name: INST1\n"
|
||||
"zhcp: Used CPU time: \"1710205201 uS\"\n"
|
||||
"zhcp: Elapsed time: \"6659572798 uS\"\n"
|
||||
"zhcp: Used memory: \"4189268 KB\"\n"
|
||||
"zhcp: Guest CPUs: \"2\"\n"
|
||||
"zhcp: \n"
|
||||
"zhcp: Guest name: INST2\n"
|
||||
"zhcp: Used CPU time: \"1710205201 uS\"\n"
|
||||
"zhcp: Elapsed time: \"6659572798 uS\"\n"
|
||||
"zhcp: Used memory: \"4189268 KB\"\n"
|
||||
"zhcp: Guest CPUs: \"4\"\n"]
|
||||
dsh.return_value = {'data': [res_data]}
|
||||
inst_list = {'inst1': 'INST1', 'inst2': 'INST2'}
|
||||
|
||||
exp_data = {'INST1': {'userid': 'INST1',
|
||||
'guest_cpus': '2',
|
||||
'used_cpu_time': '1710205201 uS',
|
||||
'used_memory': '4189268 KB'},
|
||||
'INST2': {'userid': 'INST2',
|
||||
'guest_cpus': '4',
|
||||
'used_cpu_time': '1710205201 uS',
|
||||
'used_memory': '4189268 KB'}}
|
||||
self.assertEqual(exp_data,
|
||||
zvmutils.image_performance_query('zhcp', inst_list))
|
||||
|
||||
@mock.patch.object(zvmutils, 'xdsh')
|
||||
def test_virutal_network_vswitch_query_iuo_stats(self, dsh):
|
||||
vsw_data = ['zhcp11: vswitch count: 2\n'
|
||||
'zhcp11: \n'
|
||||
'zhcp11: vswitch number: 1\n'
|
||||
'zhcp11: vswitch name: XCATVSW1\n'
|
||||
'zhcp11: uplink count: 1\n'
|
||||
'zhcp11: uplink_conn: 6240\n'
|
||||
'zhcp11: uplink_fr_rx: 3658251\n'
|
||||
'zhcp11: uplink_fr_rx_dsc: 0\n'
|
||||
'zhcp11: uplink_fr_rx_err: 0\n'
|
||||
'zhcp11: uplink_fr_tx: 4209828\n'
|
||||
'zhcp11: uplink_fr_tx_dsc: 0\n'
|
||||
'zhcp11: uplink_fr_tx_err: 0\n'
|
||||
'zhcp11: uplink_rx: 498914052\n'
|
||||
'zhcp11: uplink_tx: 2615220898\n'
|
||||
'zhcp11: bridge_fr_rx: 0\n'
|
||||
'zhcp11: bridge_fr_rx_dsc: 0\n'
|
||||
'zhcp11: bridge_fr_rx_err: 0\n'
|
||||
'zhcp11: bridge_fr_tx: 0\n'
|
||||
'zhcp11: bridge_fr_tx_dsc: 0\n'
|
||||
'zhcp11: bridge_fr_tx_err: 0\n'
|
||||
'zhcp11: bridge_rx: 0\n'
|
||||
'zhcp11: bridge_tx: 0\n'
|
||||
'zhcp11: nic count: 2\n'
|
||||
'zhcp11: nic_id: INST1 0600\n'
|
||||
'zhcp11: nic_fr_rx: 573952\n'
|
||||
'zhcp11: nic_fr_rx_dsc: 0\n'
|
||||
'zhcp11: nic_fr_rx_err: 0\n'
|
||||
'zhcp11: nic_fr_tx: 548780\n'
|
||||
'zhcp11: nic_fr_tx_dsc: 0\n'
|
||||
'zhcp11: nic_fr_tx_err: 4\n'
|
||||
'zhcp11: nic_rx: 103024058\n'
|
||||
'zhcp11: nic_tx: 102030890\n'
|
||||
'zhcp11: nic_id: INST2 0600\n'
|
||||
'zhcp11: nic_fr_rx: 17493\n'
|
||||
'zhcp11: nic_fr_rx_dsc: 0\n'
|
||||
'zhcp11: nic_fr_rx_err: 0\n'
|
||||
'zhcp11: nic_fr_tx: 16886\n'
|
||||
'zhcp11: nic_fr_tx_dsc: 0\n'
|
||||
'zhcp11: nic_fr_tx_err: 4\n'
|
||||
'zhcp11: nic_rx: 3111714\n'
|
||||
'zhcp11: nic_tx: 3172646\n'
|
||||
'zhcp11: vlan count: 0\n'
|
||||
'zhcp11: \n'
|
||||
'zhcp11: vswitch number: 2\n'
|
||||
'zhcp11: vswitch name: XCATVSW2\n'
|
||||
'zhcp11: uplink count: 1\n'
|
||||
'zhcp11: uplink_conn: 6200\n'
|
||||
'zhcp11: uplink_fr_rx: 1608681\n'
|
||||
'zhcp11: uplink_fr_rx_dsc: 0\n'
|
||||
'zhcp11: uplink_fr_rx_err: 0\n'
|
||||
'zhcp11: uplink_fr_tx: 2120075\n'
|
||||
'zhcp11: uplink_fr_tx_dsc: 0\n'
|
||||
'zhcp11: uplink_fr_tx_err: 0\n'
|
||||
'zhcp11: uplink_rx: 314326223',
|
||||
'zhcp11: uplink_tx: 1503721533\n'
|
||||
'zhcp11: bridge_fr_rx: 0\n'
|
||||
'zhcp11: bridge_fr_rx_dsc: 0\n'
|
||||
'zhcp11: bridge_fr_rx_err: 0\n'
|
||||
'zhcp11: bridge_fr_tx: 0\n'
|
||||
'zhcp11: bridge_fr_tx_dsc: 0\n'
|
||||
'zhcp11: bridge_fr_tx_err: 0\n'
|
||||
'zhcp11: bridge_rx: 0\n'
|
||||
'zhcp11: bridge_tx: 0\n'
|
||||
'zhcp11: nic count: 2\n'
|
||||
'zhcp11: nic_id: INST1 1000\n'
|
||||
'zhcp11: nic_fr_rx: 34958\n'
|
||||
'zhcp11: nic_fr_rx_dsc: 0\n'
|
||||
'zhcp11: nic_fr_rx_err: 0\n'
|
||||
'zhcp11: nic_fr_tx: 16211\n'
|
||||
'zhcp11: nic_fr_tx_dsc: 0\n'
|
||||
'zhcp11: nic_fr_tx_err: 0\n'
|
||||
'zhcp11: nic_rx: 4684435\n'
|
||||
'zhcp11: nic_tx: 3316601\n'
|
||||
'zhcp11: nic_id: INST2 1000\n'
|
||||
'zhcp11: nic_fr_rx: 27211\n'
|
||||
'zhcp11: nic_fr_rx_dsc: 0\n'
|
||||
'zhcp11: nic_fr_rx_err: 0\n'
|
||||
'zhcp11: nic_fr_tx: 12344\n'
|
||||
'zhcp11: nic_fr_tx_dsc: 0\n'
|
||||
'zhcp11: nic_fr_tx_err: 0\n'
|
||||
'zhcp11: nic_rx: 3577163\n'
|
||||
'zhcp11: nic_tx: 2515045\n'
|
||||
'zhcp11: vlan count: 0',
|
||||
None]
|
||||
dsh.return_value = {'data': [vsw_data]}
|
||||
vsw_dict = zvmutils.virutal_network_vswitch_query_iuo_stats('zhcp11')
|
||||
self.assertEqual(2, len(vsw_dict['vswitches']))
|
||||
self.assertEqual('INST1',
|
||||
vsw_dict['vswitches'][0]['nics'][0]['userid'])
|
||||
|
||||
@mock.patch.object(zvmutils, 'xdsh')
|
||||
def test_virutal_network_vswitch_query_iuo_stats_invalid_data(self, dsh):
|
||||
dsh.return_value = ['invalid', 'data']
|
||||
self.assertRaises(zvmutils.ZVMException,
|
||||
zvmutils.virutal_network_vswitch_query_iuo_stats,
|
||||
'zhcp')
|
||||
|
||||
|
||||
class TestCacheData(base.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestCacheData, self).setUp()
|
||||
self.cache_data = zvmutils.CacheData()
|
||||
|
||||
def tearDown(self):
|
||||
self.cache_data.clear()
|
||||
super(TestCacheData, self).tearDown()
|
||||
|
||||
def test_set(self):
|
||||
self.cache_data.set('cpumem', {'nodename': 'node'})
|
||||
self.assertEqual({'nodename': 'node'},
|
||||
self.cache_data.cache['cpumem']['node'])
|
||||
|
||||
def test_get(self):
|
||||
self.cache_data.set('vnics', {'nodename': 'node'})
|
||||
self.assertEqual({'nodename': 'node'},
|
||||
self.cache_data.get('vnics', 'node'))
|
||||
|
||||
def test_delete(self):
|
||||
self.cache_data.set('cpumem', {'nodename': 'node'})
|
||||
self.cache_data.delete('cpumem', 'node')
|
||||
self.assertIsNone(self.cache_data.get('cpumem', 'node'))
|
||||
|
||||
def test_clear(self):
|
||||
self.cache_data.set('cpumem', {'nodename': 'node1'})
|
||||
self.cache_data.set('vnics', {'nodename': 'node2'})
|
||||
self.cache_data.clear()
|
||||
self.assertEqual({'cpumem': {}, 'vnics': {}},
|
||||
self.cache_data.cache)
|
||||
def test_get_inst_power_state(self):
|
||||
pst = zvmutils.get_inst_power_state(self._inst)
|
||||
self.assertEqual(0x01, pst)
|
||||
|
@ -5,3 +5,5 @@ oslo.i18n>=1.5.0 # Apache-2.0
|
||||
oslo.log>=1.8.0 # Apache-2.0
|
||||
oslo.service>=0.6.0 # Apache-2.0
|
||||
pbr<2.0,>=1.4
|
||||
six>=1.9.0
|
||||
zVMCloudConnector>=0.3.2 # Apache 2.0 License
|
||||
|
5
tox.ini
5
tox.ini
@ -10,15 +10,18 @@ setenv =
|
||||
VIRTUAL_ENV={envdir}
|
||||
deps = -r{toxinidir}/requirements.txt
|
||||
-r{toxinidir}/test-requirements.txt
|
||||
-egit+https://github.com/openstack/ceilometer#egg=ceilometer
|
||||
-egit+https://github.com/openstack/ceilometer@master#egg=ceilometer
|
||||
-egit+https://github.com/mfcloud/python-zvm-sdk@master#egg=zvmsdk
|
||||
commands = python setup.py testr --slowest --testr-args='{posargs}'
|
||||
|
||||
[testenv:pep8]
|
||||
commands = flake8
|
||||
|
||||
[testenv:py27]
|
||||
whitelist_externals = git
|
||||
commands = /bin/cp -r {toxinidir}/ceilometer_zvm/compute/virt/zvm \
|
||||
{toxinidir}/.tox/py27/src/ceilometer/ceilometer/compute/virt/
|
||||
git --git-dir={toxinidir}/.tox/py27/src/zvmsdk/.git --work-tree={toxinidir}/.tox/py27/src/zvmsdk pull
|
||||
python setup.py testr --slowest --testr-args='{posargs}'
|
||||
|
||||
[testenv:venv]
|
||||
|
Loading…
x
Reference in New Issue
Block a user