tox ok, externalization from Ironic has been done

This commit is contained in:
Naohiro Tamura
2015-01-22 11:49:57 +09:00
parent 14dc6a0e1f
commit a91f89494b
9 changed files with 71 additions and 97 deletions

View File

@@ -4,3 +4,4 @@
pbr>=0.6,!=0.7,<1.0 pbr>=0.6,!=0.7,<1.0
Babel>=1.3 Babel>=1.3
requests>=2.2.0,!=2.4.0

View File

View File

@@ -1,3 +1,4 @@
# Copyright 2015 FUJITSU LIMITED
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # 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 # not use this file except in compliance with the License. You may obtain
@@ -20,8 +21,35 @@ import xml.etree.ElementTree as ET
import requests import requests
from ironic.common import exception
from ironic.common.i18n import _ class SCCIError(Exception):
"""SCCI Error
This exception is gerenral excetion.
"""
def __init__(self, message, errorcode=None):
super(SCCIError, self).__init__(message)
class SCCIInvalidInputError(SCCIError):
"""SCCIInvalidInputError
This exception is used when invalid inputs are passed to
the APIs exposed by this module.
"""
def __init__(self, message):
super(SCCIInvalidInputError, self).__init__(message)
class SCCIClientError(SCCIError):
"""SCCIClientError
This exception is used when a problem is encountered in
executing an operation on the iRMC
"""
def __init__(self, message):
super(SCCIClientError, self).__init__(message)
""" """
List of iRMC S4 supported SCCI commands List of iRMC S4 supported SCCI commands
@@ -183,9 +211,9 @@ def scci_cmd(host, userid, password, cmd,
:param auth_method: irmc_username :param auth_method: irmc_username
:param client_timeout: timeout for SCCI operations :param client_timeout: timeout for SCCI operations
:returns: requests.Response from SCCI server :returns: requests.Response from SCCI server
:raises: InvalidParameterValue if port and/or auth_method params :raises: SCCIInvalidInputError if port and/or auth_method params
are invalid are invalid
:raises: IRMCClientError if SCCI failed :raises: SCCIClientError if SCCI failed
""" """
auth_obj = None auth_obj = None
@@ -197,8 +225,8 @@ def scci_cmd(host, userid, password, cmd,
}[auth_method.lower()] }[auth_method.lower()]
except KeyError: except KeyError:
raise exception.InvalidParameterValue( raise SCCIInvalidInputError(
_("Invalid port %(port)d or " ("Invalid port %(port)d or " +
"auth_method for method %(auth_method)s") % "auth_method for method %(auth_method)s") %
{'port': port, 'auth_method': auth_method}) {'port': port, 'auth_method': auth_method})
@@ -211,27 +239,26 @@ def scci_cmd(host, userid, password, cmd,
auth=auth_obj) auth=auth_obj)
if r.status_code not in (200, 201): if r.status_code not in (200, 201):
raise exception.IRMCClientError( raise SCCIClientError(
operation=cmd, ('HTTP PROTOCOL ERROR, STATUS CODE = %s' %
error='http status = ' + str(r.status_code)) str(r.status_code)))
result_xml = ET.fromstring(r.text) result_xml = ET.fromstring(r.text)
status = result_xml.find("./Value") status = result_xml.find("./Value")
# severity = result_xml.find("./Severity") # severity = result_xml.find("./Severity")
# message = result_xml.find("./Message") # message = result_xml.find("./Message")
if not int(status.text) == 0: if not int(status.text) == 0:
raise exception.IRMCClientError(operation=cmd, raise SCCIClientError(
error=result_xml.text) ('SCCI PROTOCOL ERROR, STATUS CODE = %s' %
str(status.text)))
else: else:
return r return r
except ET.ParseError as parse_error: except ET.ParseError as parse_error:
raise exception.IRMCClientError(operation=cmd, raise SCCIClientError(parse_error)
error=parse_error)
except requests.exceptions.RequestException as requests_exception: except requests.exceptions.RequestException as requests_exception:
raise exception.IRMCClientError(operation=cmd, raise SCCIClientError(requests_exception)
error=requests_exception)
def get_client(host, userid, password, def get_client(host, userid, password,
@@ -328,9 +355,9 @@ def get_report(host, userid, password,
:param auth_method: irmc_username :param auth_method: irmc_username
:param client_timeout: timeout for SCCI operations :param client_timeout: timeout for SCCI operations
:returns: root element of SCCI report :returns: root element of SCCI report
:raises: InvalidParameterValue if port and/or auth_method params :raises: ISCCIInvalidInputError if port and/or auth_method params
are invalid are invalid
:raises: IRMCClientError if SCCI failed :raises: SCCIClientError if SCCI failed
""" """
auth_obj = None auth_obj = None
@@ -342,9 +369,9 @@ def get_report(host, userid, password,
}[auth_method.lower()] }[auth_method.lower()]
except KeyError: except KeyError:
raise exception.InvalidParameterValue( raise SCCIInvalidInputError(
_("Invalid port %(port)d or " ("Invalid port %(port)d or " +
"auth_method for method %(auth_method)s"), "auth_method for method %(auth_method)s") %
{'port': port, 'auth_method': auth_method}) {'port': port, 'auth_method': auth_method})
try: try:
@@ -355,17 +382,18 @@ def get_report(host, userid, password,
auth=auth_obj) auth=auth_obj)
if r.status_code not in (200, 201): if r.status_code not in (200, 201):
raise exception.IRMCClientError( raise SCCIClientError(
operation='get_report()', ('HTTP PROTOCOL ERROR, STATUS CODE = %s' %
error='http status = ' + str(r.status_code)) str(r.status_code)))
# pprint.pprint(r.text)
root = ET.fromstring(r.text) root = ET.fromstring(r.text)
return root return root
except ET.ParseError as parse_error:
raise SCCIClientError(parse_error)
except requests.exceptions.RequestException as requests_exception: except requests.exceptions.RequestException as requests_exception:
raise exception.IRMCClientError(operation='get_report()', raise SCCIClientError(requests_exception)
error=requests_exception)
def get_sensor_data_records(report): def get_sensor_data_records(report):

View File

@@ -1,23 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2010-2011 OpenStack Foundation
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
#
# 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 oslotest import base
class TestCase(base.BaseTestCase):
"""Test case base class for all unit tests."""

View File

View File

@@ -23,8 +23,7 @@ import mock
import requests import requests
import testtools import testtools
from ironic.common import exception from scciclient.irmc import scci
from ironic.drivers.modules.irmc import scci
class SCCITestCase(testtools.TestCase): class SCCITestCase(testtools.TestCase):
@@ -123,7 +122,7 @@ class SCCITestCase(testtools.TestCase):
'https://github.com', verify=False) 'https://github.com', verify=False)
self.assertEqual("'member_descriptor' object is not callable", str(e)) self.assertEqual("'member_descriptor' object is not callable", str(e))
@mock.patch('ironic.drivers.modules.irmc.scci.requests') @mock.patch('scciclient.irmc.scci.requests')
def test_scci_cmd_protocol_https_ok(self, mock_requests): def test_scci_cmd_protocol_https_ok(self, mock_requests):
https_port = 443 https_port = 443
mock_requests.post.return_value = mock.Mock( mock_requests.post.return_value = mock.Mock(
@@ -203,7 +202,7 @@ class SCCITestCase(testtools.TestCase):
body="401 Unauthorized", body="401 Unauthorized",
status=401) status=401)
e = self.assertRaises(exception.IRMCClientError, e = self.assertRaises(scci.SCCIClientError,
scci.scci_cmd, scci.scci_cmd,
self.irmc_address, self.irmc_address,
self.irmc_username, self.irmc_username,
@@ -214,13 +213,12 @@ class SCCITestCase(testtools.TestCase):
client_timeout=self.irmc_client_timeout) client_timeout=self.irmc_client_timeout)
self.assertEqual( self.assertEqual(
'iRMC SCCI %(operation)s failed. Reason: %(error)s' % 'HTTP PROTOCOL ERROR, STATUS CODE = 401',
{'operation': scci.POWER_ON, 'error': 'http status = 401'},
str(e)) str(e))
def test_scci_cmd_protocol_ng(self): def test_scci_cmd_protocol_ng(self):
ssh_port = 22 ssh_port = 22
e = self.assertRaises(exception.InvalidParameterValue, e = self.assertRaises(scci.SCCIInvalidInputError,
scci.scci_cmd, scci.scci_cmd,
self.irmc_address, self.irmc_address,
self.irmc_username, self.irmc_username,
@@ -236,7 +234,7 @@ class SCCITestCase(testtools.TestCase):
def test_scci_cmd_auth_method_ng(self): def test_scci_cmd_auth_method_ng(self):
unknown_auth_method = 'unknown' unknown_auth_method = 'unknown'
e = self.assertRaises(exception.InvalidParameterValue, e = self.assertRaises(scci.SCCIInvalidInputError,
scci.scci_cmd, scci.scci_cmd,
self.irmc_address, self.irmc_address,
self.irmc_username, self.irmc_username,
@@ -277,13 +275,11 @@ class SCCITestCase(testtools.TestCase):
auth_method=self.irmc_auth_method, auth_method=self.irmc_auth_method,
client_timeout=self.irmc_client_timeout) client_timeout=self.irmc_client_timeout)
e = self.assertRaises(exception.IRMCClientError, e = self.assertRaises(scci.SCCIClientError,
client, client,
scci.POWER_ON) scci.POWER_ON)
self.assertEqual( self.assertEqual(
'iRMC SCCI %(operation)s failed. Reason: %(error)s' % 'not well-formed (invalid token): line 10, column 41',
{'operation': scci.POWER_ON,
'error': "not well-formed (invalid token): line 10, column 41"},
str(e)) str(e))
@httpretty.activate @httpretty.activate
@@ -300,12 +296,11 @@ class SCCITestCase(testtools.TestCase):
auth_method=self.irmc_auth_method, auth_method=self.irmc_auth_method,
client_timeout=self.irmc_client_timeout) client_timeout=self.irmc_client_timeout)
e = self.assertRaises(exception.IRMCClientError, e = self.assertRaises(scci.SCCIClientError,
client, client,
scci.POWER_ON) scci.POWER_ON)
self.assertEqual( self.assertEqual(
'iRMC SCCI %(operation)s failed. Reason: %(error)s' % 'HTTP PROTOCOL ERROR, STATUS CODE = 302',
{'operation': scci.POWER_ON, 'error': 'http status = 302'},
str(e)) str(e))
@httpretty.activate @httpretty.activate
@@ -417,7 +412,7 @@ class SCCITestCase(testtools.TestCase):
content_type="application/x-www-form-urlencoded", content_type="application/x-www-form-urlencoded",
status=302) status=302)
e = self.assertRaises(exception.IRMCClientError, e = self.assertRaises(scci.SCCIClientError,
scci.get_report, scci.get_report,
self.irmc_address, self.irmc_address,
self.irmc_username, self.irmc_username,
@@ -426,8 +421,7 @@ class SCCITestCase(testtools.TestCase):
auth_method=self.irmc_auth_method, auth_method=self.irmc_auth_method,
client_timeout=self.irmc_client_timeout) client_timeout=self.irmc_client_timeout)
self.assertEqual( self.assertEqual(
'iRMC SCCI %(operation)s failed. Reason: %(error)s' % 'HTTP PROTOCOL ERROR, STATUS CODE = 302',
{'operation': 'get_report()', 'error': 'http status = 302'},
str(e)) str(e))
@httpretty.activate @httpretty.activate

View File

@@ -1,28 +0,0 @@
# -*- coding: utf-8 -*-
# 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.
"""
test_scciclient
----------------------------------
Tests for `scciclient` module.
"""
from scciclient.tests import base
class TestScciclient(base.TestCase):
def test_something(self):
pass

View File

@@ -13,3 +13,5 @@ oslotest>=1.1.0.0a1
testrepository>=0.0.18 testrepository>=0.0.18
testscenarios>=0.4 testscenarios>=0.4
testtools>=0.9.34 testtools>=0.9.34
httpretty!=0.8.1,!=0.8.2,!=0.8.3,>=0.8.0

View File

@@ -1,6 +1,6 @@
[tox] [tox]
minversion = 1.6 minversion = 1.6
envlist = py33,py34,py26,py27,pypy,pep8 envlist = py27,pep8
skipsdist = True skipsdist = True
[testenv] [testenv]