332 lines
12 KiB
Python
332 lines
12 KiB
Python
# coding=utf-8
|
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
|
|
# 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.
|
|
|
|
"""
|
|
Unittest for the Compute Backend.
|
|
"""
|
|
|
|
#pylint: disable=W0102,C0103,R0904
|
|
|
|
import unittest
|
|
|
|
# depenency from nova :-)
|
|
import mox
|
|
from nova.compute import vm_states
|
|
|
|
from occi import core_model
|
|
from occi.extensions import infrastructure
|
|
|
|
from occi_os_api import nova_glue
|
|
from occi_os_api.backends import compute
|
|
from occi_os_api.extensions import os_mixins
|
|
|
|
|
|
class TestComputeBackend(unittest.TestCase):
|
|
"""
|
|
Tests the compute backend.
|
|
"""
|
|
|
|
os_template = os_mixins.OsTemplate('http://example.com', 'unix')
|
|
os_template2 = os_mixins.OsTemplate('http://example.com', 'windows')
|
|
|
|
res_template = os_mixins.ResourceTemplate('http://example.com', 'itsy')
|
|
res_template2 = os_mixins.ResourceTemplate('http://example.com', 'bitsy')
|
|
|
|
def setUp(self):
|
|
"""
|
|
Setup tests.
|
|
"""
|
|
self.backend = compute.ComputeBackend()
|
|
self.sec_obj = {'nova_ctx': None}
|
|
self.mox = mox.Mox()
|
|
|
|
def tearDown(self):
|
|
"""
|
|
Cleanup mocks.
|
|
"""
|
|
self.mox.UnsetStubs()
|
|
|
|
# Test for failure
|
|
|
|
def test_create_for_failure(self):
|
|
"""
|
|
Test for proper error handling.
|
|
"""
|
|
# msg OS template
|
|
res = core_model.Resource('/foo/bar', infrastructure.COMPUTE, [])
|
|
|
|
self.assertRaises(AttributeError, self.backend.create, res,
|
|
self.sec_obj)
|
|
|
|
# provide immutable attr
|
|
res = core_model.Resource('/foo/bar', infrastructure.COMPUTE,
|
|
[self.os_template])
|
|
res.attributes = {'occi.compute.cores': 2}
|
|
|
|
self.assertRaises(AttributeError, self.backend.create, res,
|
|
self.sec_obj)
|
|
|
|
def test_update_for_failure(self):
|
|
"""
|
|
Test if correct errors are thrown.
|
|
"""
|
|
# msg mixin
|
|
res1 = core_model.Resource('/foo/bar', infrastructure.COMPUTE, [])
|
|
res1.attributes = {'occi.core.id': 'bar'}
|
|
res2 = core_model.Resource('/foo/bar', infrastructure.COMPUTE, [])
|
|
|
|
self.assertRaises(AttributeError, self.backend.update, res1, res2,
|
|
self.sec_obj)
|
|
|
|
res2 = core_model.Resource('/foo/bar', infrastructure.COMPUTE,
|
|
[core_model.Category('http://foo.com',
|
|
'bar', '', '', '')])
|
|
|
|
self.assertRaises(AttributeError, self.backend.update, res1, res2,
|
|
self.sec_obj)
|
|
|
|
def test_action_for_failure(self):
|
|
"""
|
|
Test if correct errors are thrown.
|
|
"""
|
|
# wrong action
|
|
res1 = core_model.Resource('/foo/bar', infrastructure.COMPUTE, [])
|
|
res1.attributes = {'occi.core.id': 'bar'}
|
|
self.mox.StubOutWithMock(nova_glue.vm, 'get_vm')
|
|
nova_glue.vm.get_vm(mox.IsA(object), mox.IsA(object)).AndReturn(
|
|
{
|
|
'vm_state': vm_states.STOPPED
|
|
})
|
|
self.mox.ReplayAll()
|
|
self.assertRaises(AttributeError, self.backend.action, res1,
|
|
infrastructure.STOP, {}, self.sec_obj)
|
|
self.mox.VerifyAll()
|
|
|
|
# missing method!
|
|
self.mox.UnsetStubs()
|
|
self.mox.StubOutWithMock(nova_glue.vm, 'get_vm')
|
|
nova_glue.vm.get_vm(mox.IsA(object), mox.IsA(object)).AndReturn(
|
|
{
|
|
'vm_state': vm_states.ACTIVE
|
|
})
|
|
self.mox.ReplayAll()
|
|
self.assertRaises(AttributeError, self.backend.action, res1,
|
|
infrastructure.RESTART, {}, self.sec_obj)
|
|
self.mox.VerifyAll()
|
|
|
|
# Test for Sanity
|
|
|
|
def test_create_for_sanity(self):
|
|
"""
|
|
Simulate a create call!
|
|
"""
|
|
res = core_model.Resource('/foo/bar', infrastructure.COMPUTE,
|
|
[self.os_template])
|
|
|
|
self.mox.StubOutWithMock(nova_glue.vm, 'create_vm')
|
|
nova_glue.vm.create_vm(mox.IsA(object), mox.IsA(object)).AndReturn(
|
|
{
|
|
'uuid': 'foo',
|
|
'hostname': 'Server foo',
|
|
'vcpus': 1,
|
|
'memory_mb': 256
|
|
})
|
|
self.mox.StubOutWithMock(nova_glue.storage, 'get_image_architecture')
|
|
nova_glue.storage.get_image_architecture(mox.IsA(object),
|
|
mox.IsA(object)).\
|
|
AndReturn('foo')
|
|
|
|
self.mox.ReplayAll()
|
|
|
|
self.backend.create(res, self.sec_obj)
|
|
|
|
# check if all attrs are there!
|
|
self.assertIn('occi.compute.hostname', res.attributes)
|
|
self.assertIn('occi.compute.architecture', res.attributes)
|
|
self.assertIn('occi.compute.cores', res.attributes)
|
|
self.assertIn('occi.compute.speed', res.attributes)
|
|
self.assertIn('occi.compute.memory', res.attributes)
|
|
self.assertIn('occi.compute.state', res.attributes)
|
|
|
|
self.assertEqual('inactive', res.attributes['occi.compute.state'])
|
|
|
|
self.assertListEqual([infrastructure.STOP, infrastructure.SUSPEND,
|
|
infrastructure.RESTART], res.actions)
|
|
|
|
self.mox.VerifyAll()
|
|
|
|
def test_retrieve_for_sanity(self):
|
|
"""
|
|
Simulate a retrieve call!
|
|
"""
|
|
res = core_model.Resource('/foo/bar', infrastructure.COMPUTE,
|
|
[self.os_template])
|
|
res.attributes = {'occi.core.id': 'bar'}
|
|
|
|
self.mox.StubOutWithMock(nova_glue.vm, 'get_occi_state')
|
|
nova_glue.vm.get_occi_state(mox.IsA(object),
|
|
mox.IsA(object)).\
|
|
AndReturn(('active', [infrastructure.STOP,
|
|
infrastructure.SUSPEND,
|
|
infrastructure.RESTART]))
|
|
self.mox.StubOutWithMock(nova_glue.vm, 'get_vm')
|
|
nova_glue.vm.get_vm(mox.IsA(object), mox.IsA(object)).AndReturn(
|
|
{
|
|
'hostname': 'bar',
|
|
'vcpus': 1,
|
|
'memory_mb': 256
|
|
})
|
|
self.mox.StubOutWithMock(nova_glue.storage, 'get_image_architecture')
|
|
nova_glue.storage.get_image_architecture(mox.IsA(object),
|
|
mox.IsA(object)).\
|
|
AndReturn('foo')
|
|
self.mox.ReplayAll()
|
|
|
|
self.backend.retrieve(res, self.sec_obj)
|
|
|
|
# check if all attrs are there!
|
|
self.assertIn('occi.compute.hostname', res.attributes)
|
|
self.assertIn('occi.compute.architecture', res.attributes)
|
|
self.assertIn('occi.compute.cores', res.attributes)
|
|
self.assertIn('occi.compute.speed', res.attributes)
|
|
self.assertIn('occi.compute.memory', res.attributes)
|
|
self.assertIn('occi.compute.state', res.attributes)
|
|
|
|
self.assertIn('occi.core.id', res.attributes)
|
|
|
|
self.assertEqual('active', res.attributes['occi.compute.state'])
|
|
|
|
self.assertListEqual([infrastructure.STOP, infrastructure.SUSPEND,
|
|
infrastructure.RESTART], res.actions)
|
|
|
|
self.mox.VerifyAll()
|
|
|
|
def test_update_for_sanity(self):
|
|
"""
|
|
Simulate a update call!
|
|
"""
|
|
res1 = core_model.Resource('/foo/bar', infrastructure.COMPUTE,
|
|
[self.os_template])
|
|
res1.attributes = {'occi.core.id': 'bar'}
|
|
|
|
# case 1 - rebuild VM with different OS
|
|
res2 = core_model.Resource('/foo/bar', infrastructure.COMPUTE,
|
|
[self.os_template2])
|
|
|
|
self.mox.StubOutWithMock(nova_glue.vm, 'rebuild_vm')
|
|
nova_glue.vm.rebuild_vm(mox.IsA(object), mox.IsA(object),
|
|
mox.IsA(object))
|
|
self.mox.ReplayAll()
|
|
self.backend.update(res1, res2, self.sec_obj)
|
|
|
|
self.assertIn(self.os_template2, res1.mixins)
|
|
|
|
self.mox.VerifyAll()
|
|
|
|
# case 2 - resize the VM
|
|
res2 = core_model.Resource('/foo/bar', infrastructure.COMPUTE,
|
|
[self.res_template2])
|
|
|
|
self.mox.StubOutWithMock(nova_glue.vm, 'resize_vm')
|
|
nova_glue.vm.resize_vm(mox.IsA(object), mox.IsA(object),
|
|
mox.IsA(object))
|
|
self.mox.ReplayAll()
|
|
self.backend.update(res1, res2, self.sec_obj)
|
|
|
|
self.assertIn(self.res_template2, res1.mixins)
|
|
|
|
self.mox.VerifyAll()
|
|
|
|
def test_replace_for_sanity(self):
|
|
"""
|
|
Simulate a replace call - does nothing atm.
|
|
"""
|
|
self.backend.replace(None, None, self.sec_obj)
|
|
|
|
def test_delete_for_sanity(self):
|
|
"""
|
|
Simulate a delete call.
|
|
"""
|
|
res = core_model.Resource('/foo/bar', infrastructure.COMPUTE,
|
|
[self.os_template])
|
|
res.attributes = {'occi.core.id': 'bar'}
|
|
|
|
self.mox.StubOutWithMock(nova_glue.vm, 'delete_vm')
|
|
nova_glue.vm.delete_vm(mox.IsA(object), mox.IsA(object))
|
|
self.mox.ReplayAll()
|
|
self.backend.delete(res, self.sec_obj)
|
|
|
|
self.mox.VerifyAll()
|
|
|
|
def test_action_for_sanity(self):
|
|
"""
|
|
Test actions
|
|
"""
|
|
res1 = core_model.Resource('/foo/bar', infrastructure.COMPUTE, [])
|
|
res1.attributes = {'occi.core.id': 'bar'}
|
|
|
|
# start
|
|
self.mox.StubOutWithMock(nova_glue.vm, 'start_vm')
|
|
nova_glue.vm.start_vm(mox.IsA(object), mox.IsA(object))
|
|
self.mox.StubOutWithMock(nova_glue.vm, 'get_vm')
|
|
nova_glue.vm.get_vm(mox.IsA(object), mox.IsA(object)).AndReturn(
|
|
{
|
|
'vm_state': vm_states.STOPPED
|
|
})
|
|
self.mox.ReplayAll()
|
|
self.backend.action(res1, infrastructure.START, {}, self.sec_obj)
|
|
self.mox.VerifyAll()
|
|
|
|
# stop
|
|
self.mox.UnsetStubs()
|
|
self.mox.StubOutWithMock(nova_glue.vm, 'stop_vm')
|
|
nova_glue.vm.stop_vm(mox.IsA(object), mox.IsA(object))
|
|
self.mox.StubOutWithMock(nova_glue.vm, 'get_vm')
|
|
nova_glue.vm.get_vm(mox.IsA(object), mox.IsA(object)).AndReturn(
|
|
{
|
|
'vm_state': vm_states.ACTIVE
|
|
})
|
|
self.mox.ReplayAll()
|
|
self.backend.action(res1, infrastructure.STOP, {}, self.sec_obj)
|
|
self.mox.VerifyAll()
|
|
|
|
# reboot
|
|
self.mox.UnsetStubs()
|
|
self.mox.StubOutWithMock(nova_glue.vm, 'restart_vm')
|
|
nova_glue.vm.restart_vm(mox.IsA(object), mox.IsA(str),
|
|
mox.IsA(object))
|
|
self.mox.StubOutWithMock(nova_glue.vm, 'get_vm')
|
|
nova_glue.vm.get_vm(mox.IsA(object), mox.IsA(object)).AndReturn(
|
|
{
|
|
'vm_state': vm_states.ACTIVE
|
|
})
|
|
self.mox.ReplayAll()
|
|
self.backend.action(res1, infrastructure.RESTART,
|
|
{'method': 'graceful'}, self.sec_obj)
|
|
self.mox.VerifyAll()
|
|
|
|
# suspend
|
|
self.mox.UnsetStubs()
|
|
self.mox.StubOutWithMock(nova_glue.vm, 'suspend_vm')
|
|
nova_glue.vm.suspend_vm(mox.IsA(object), mox.IsA(object))
|
|
self.mox.StubOutWithMock(nova_glue.vm, 'get_vm')
|
|
nova_glue.vm.get_vm(mox.IsA(object), mox.IsA(object)).AndReturn(
|
|
{
|
|
'vm_state': vm_states.ACTIVE
|
|
})
|
|
self.mox.ReplayAll()
|
|
self.backend.action(res1, infrastructure.SUSPEND, {}, self.sec_obj)
|
|
self.mox.VerifyAll()
|