diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..c3c0e95c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.pyc +.cache/ +.coverage \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..ad025dbe --- /dev/null +++ b/.travis.yml @@ -0,0 +1,8 @@ +language: python +python: + - "2.7" +install: + - "pip install -Ur requirements-test.txt" +script: "py.test tests/ -v --cov mgmtsystem" +after_success: + - coveralls \ No newline at end of file diff --git a/README.md b/README.md index f2c97541..1b865701 100644 --- a/README.md +++ b/README.md @@ -1 +1,6 @@ -MGMT_SYSTEM +mgmtsystem - A simple virtualization client +=========================================== + +[![Coverage Status](https://coveralls.io/repos/RedHatQE/mgmtsystem/badge.svg?branch=master&service=github)](https://coveralls.io/github/RedHatQE/mgmtsystem?branch=master) +[![Build Status](https://travis-ci.org/RedHatQE/mgmtsystem.svg)](https://travis-ci.org/RedHatQE/mgmtsystem) + diff --git a/mgmtsystem/exceptions.py b/mgmtsystem/exceptions.py index 06deb4e0..e438e7a6 100644 --- a/mgmtsystem/exceptions.py +++ b/mgmtsystem/exceptions.py @@ -71,3 +71,7 @@ class VMNotFoundViaIP(Exception): class HostNotRemoved(Exception): """Raised when :py:mod:`utils.mgmt_system` fails to remove host from cluster""" + + +class VMError(Exception): + """Raised when a VM goes to the ERROR state.""" diff --git a/mgmtsystem/openstack.py b/mgmtsystem/openstack.py index 9b0cfa32..74e5f174 100644 --- a/mgmtsystem/openstack.py +++ b/mgmtsystem/openstack.py @@ -20,7 +20,8 @@ from base import MgmtSystemAPIBase, VMInfo from exceptions import ( - NoMoreFloatingIPs, NetworkNameNotFound, VMInstanceNotFound, VMNotFoundViaIP, ActionTimedOutError + NoMoreFloatingIPs, NetworkNameNotFound, VMInstanceNotFound, VMNotFoundViaIP, ActionTimedOutError, + VMError ) @@ -248,7 +249,18 @@ def disconnect(self): pass def vm_status(self, vm_name): - return self._find_instance_by_name(vm_name).status + """Retrieve Instance status. + + Raises: + :py:class:`mgmtsystem.exceptions.VMError + """ + inst = self._find_instance_by_name(vm_name) + if inst.status != "ERROR": + return inst.status + if not hasattr(inst, "fault"): + raise VMError("Instance {} in error state!".format(vm_name)) + raise VMError("Instance {} error {}: {} | {}".format( + vm_name, inst.fault["code"], inst.fault["message"], inst.fault["created"])) def create_volume(self, size_gb, **kwargs): volume = self.capi.volumes.create(size_gb, **kwargs).id diff --git a/requirements-test.txt b/requirements-test.txt new file mode 100644 index 00000000..ce55fa23 --- /dev/null +++ b/requirements-test.txt @@ -0,0 +1,5 @@ +-r ./requirements.txt + +pytest +pytest-cov +coveralls diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..40a96afc --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1 @@ +# -*- coding: utf-8 -*- diff --git a/tests/test_openstack.py b/tests/test_openstack.py new file mode 100644 index 00000000..84c0498c --- /dev/null +++ b/tests/test_openstack.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +"""Unit tests for Openstack client.""" +import pytest + +from mgmtsystem import exceptions, openstack + + +@pytest.fixture(scope="function") +def provider(): + os = openstack.OpenstackSystem(tenant=None, username=None, password=None, auth_url=None) + return os + + +class mkobj(object): + def __init__(self, **d): + self.__dict__ = d + + +def test_vm_status_error_raises_with_fault(provider, monkeypatch): + """Check that if the Instance gets to the ERROR state, vm_status will let us know.""" + def _find_instance_by_name(vm_name): + return mkobj( + status="ERROR", + fault={"code": 500, "created": "2015-11-02T10:54:18Z", "details": "x", "message": "y"}) + + monkeypatch.setattr(provider, '_find_instance_by_name', _find_instance_by_name) + + with pytest.raises(exceptions.VMError): + provider.vm_status("xyz") + + +def test_vm_status_error_raises_without_fault(provider, monkeypatch): + """Check that if the Instance gets to the ERROR state, vm_status will let us know. + + With no fault field. + """ + def _find_instance_by_name(vm_name): + return mkobj(status="ERROR") + + monkeypatch.setattr(provider, '_find_instance_by_name', _find_instance_by_name) + + with pytest.raises(exceptions.VMError): + provider.vm_status("xyz") + + +def test_vm_status_no_error(provider, monkeypatch): + """Check that if the Instance is not in error state, it works as usual.""" + def _find_instance_by_name(vm_name): + return mkobj(status="UP") + + monkeypatch.setattr(provider, '_find_instance_by_name', _find_instance_by_name) + + assert provider.vm_status("xyz") == "UP"