Merge "Tests for PXE bare-metal provisioning helper server."
This commit is contained in:
commit
794b0ffc75
@ -18,7 +18,10 @@
|
||||
"""Starter script for Bare-Metal Deployment Service."""
|
||||
|
||||
import eventlet
|
||||
eventlet.monkey_patch()
|
||||
|
||||
# Do not monkey_patch in unittest
|
||||
if __name__ == '__main__':
|
||||
eventlet.monkey_patch()
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
256
nova/tests/baremetal/test_nova_baremetal_deploy_helper.py
Normal file
256
nova/tests/baremetal/test_nova_baremetal_deploy_helper.py
Normal file
@ -0,0 +1,256 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright (c) 2012 NTT DOCOMO, INC.
|
||||
# Copyright 2011 OpenStack LLC
|
||||
# Copyright 2011 Ilya Alekseyev
|
||||
#
|
||||
# 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.
|
||||
|
||||
import imp
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import time
|
||||
|
||||
from nova import test
|
||||
|
||||
from nova.tests.baremetal.db import base as bm_db_base
|
||||
|
||||
|
||||
TOPDIR = os.path.normpath(os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
os.pardir,
|
||||
os.pardir,
|
||||
os.pardir))
|
||||
BMDH_PATH = os.path.join(TOPDIR, 'bin', 'nova-baremetal-deploy-helper')
|
||||
|
||||
sys.dont_write_bytecode = True
|
||||
bmdh = imp.load_source('bmdh', BMDH_PATH)
|
||||
sys.dont_write_bytecode = False
|
||||
|
||||
_PXECONF_DEPLOY = """
|
||||
default deploy
|
||||
|
||||
label deploy
|
||||
kernel deploy_kernel
|
||||
append initrd=deploy_ramdisk
|
||||
ipappend 3
|
||||
|
||||
label boot
|
||||
kernel kernel
|
||||
append initrd=ramdisk root=${ROOT}
|
||||
"""
|
||||
|
||||
_PXECONF_BOOT = """
|
||||
default boot
|
||||
|
||||
label deploy
|
||||
kernel deploy_kernel
|
||||
append initrd=deploy_ramdisk
|
||||
ipappend 3
|
||||
|
||||
label boot
|
||||
kernel kernel
|
||||
append initrd=ramdisk root=UUID=12345678-1234-1234-1234-1234567890abcdef
|
||||
"""
|
||||
|
||||
|
||||
class WorkerTestCase(bm_db_base.BMDBTestCase):
|
||||
def setUp(self):
|
||||
super(WorkerTestCase, self).setUp()
|
||||
self.worker = bmdh.Worker()
|
||||
# Make tearDown() fast
|
||||
self.worker.queue_timeout = 0.1
|
||||
self.worker.start()
|
||||
|
||||
def tearDown(self):
|
||||
if self.worker.isAlive():
|
||||
self.worker.stop = True
|
||||
self.worker.join(timeout=1)
|
||||
super(WorkerTestCase, self).tearDown()
|
||||
|
||||
def wait_queue_empty(self, timeout):
|
||||
for _ in xrange(int(timeout / 0.1)):
|
||||
if bmdh.QUEUE.empty():
|
||||
break
|
||||
time.sleep(0.1)
|
||||
|
||||
def test_run_calls_deploy(self):
|
||||
"""Check all queued requests are passed to deploy()."""
|
||||
history = []
|
||||
|
||||
def fake_deploy(**params):
|
||||
history.append(params)
|
||||
|
||||
self.stubs.Set(bmdh, 'deploy', fake_deploy)
|
||||
params_list = [{'fake1': ''}, {'fake2': ''}, {'fake3': ''}]
|
||||
for (dep_id, params) in enumerate(params_list):
|
||||
bmdh.QUEUE.put((dep_id, params))
|
||||
self.wait_queue_empty(1)
|
||||
self.assertEqual(params_list, history)
|
||||
|
||||
def test_run_with_failing_deploy(self):
|
||||
"""Check a worker keeps on running even if deploy() raises
|
||||
an exception.
|
||||
"""
|
||||
history = []
|
||||
|
||||
def fake_deploy(**params):
|
||||
history.append(params)
|
||||
# always fail
|
||||
raise Exception('test')
|
||||
|
||||
self.stubs.Set(bmdh, 'deploy', fake_deploy)
|
||||
params_list = [{'fake1': ''}, {'fake2': ''}, {'fake3': ''}]
|
||||
for (dep_id, params) in enumerate(params_list):
|
||||
bmdh.QUEUE.put((dep_id, params))
|
||||
self.wait_queue_empty(1)
|
||||
self.assertEqual(params_list, history)
|
||||
|
||||
|
||||
class PhysicalWorkTestCase(test.TestCase):
|
||||
def setUp(self):
|
||||
super(PhysicalWorkTestCase, self).setUp()
|
||||
|
||||
def noop(*args, **kwargs):
|
||||
pass
|
||||
|
||||
self.stubs.Set(time, 'sleep', noop)
|
||||
|
||||
def test_deploy(self):
|
||||
"""Check loosely all functions are called with right args."""
|
||||
address = '127.0.0.1'
|
||||
port = 3306
|
||||
iqn = 'iqn.xyz'
|
||||
lun = 1
|
||||
image_path = '/tmp/xyz/image'
|
||||
pxe_config_path = '/tmp/abc/pxeconfig'
|
||||
root_mb = 128
|
||||
swap_mb = 64
|
||||
|
||||
dev = '/dev/fake'
|
||||
root_part = '/dev/fake-part1'
|
||||
swap_part = '/dev/fake-part2'
|
||||
root_uuid = '12345678-1234-1234-12345678-12345678abcdef'
|
||||
|
||||
self.mox.StubOutWithMock(bmdh, 'get_dev')
|
||||
self.mox.StubOutWithMock(bmdh, 'get_image_mb')
|
||||
self.mox.StubOutWithMock(bmdh, 'discovery')
|
||||
self.mox.StubOutWithMock(bmdh, 'login_iscsi')
|
||||
self.mox.StubOutWithMock(bmdh, 'logout_iscsi')
|
||||
self.mox.StubOutWithMock(bmdh, 'make_partitions')
|
||||
self.mox.StubOutWithMock(bmdh, 'is_block_device')
|
||||
self.mox.StubOutWithMock(bmdh, 'dd')
|
||||
self.mox.StubOutWithMock(bmdh, 'mkswap')
|
||||
self.mox.StubOutWithMock(bmdh, 'block_uuid')
|
||||
self.mox.StubOutWithMock(bmdh, 'switch_pxe_config')
|
||||
self.mox.StubOutWithMock(bmdh, 'notify')
|
||||
|
||||
bmdh.get_dev(address, port, iqn, lun).AndReturn(dev)
|
||||
bmdh.get_image_mb(image_path).AndReturn(1) # < root_mb
|
||||
bmdh.discovery(address, port)
|
||||
bmdh.login_iscsi(address, port, iqn)
|
||||
bmdh.is_block_device(dev).AndReturn(True)
|
||||
bmdh.make_partitions(dev, root_mb, swap_mb)
|
||||
bmdh.is_block_device(root_part).AndReturn(True)
|
||||
bmdh.is_block_device(swap_part).AndReturn(True)
|
||||
bmdh.dd(image_path, root_part)
|
||||
bmdh.mkswap(swap_part)
|
||||
bmdh.block_uuid(root_part).AndReturn(root_uuid)
|
||||
bmdh.logout_iscsi(address, port, iqn)
|
||||
bmdh.switch_pxe_config(pxe_config_path, root_uuid)
|
||||
bmdh.notify(address, 10000)
|
||||
self.mox.ReplayAll()
|
||||
|
||||
bmdh.deploy(address, port, iqn, lun, image_path, pxe_config_path,
|
||||
root_mb, swap_mb)
|
||||
|
||||
def test_always_logout_iscsi(self):
|
||||
"""logout_iscsi() must be called once login_iscsi() is called."""
|
||||
address = '127.0.0.1'
|
||||
port = 3306
|
||||
iqn = 'iqn.xyz'
|
||||
lun = 1
|
||||
image_path = '/tmp/xyz/image'
|
||||
pxe_config_path = '/tmp/abc/pxeconfig'
|
||||
root_mb = 128
|
||||
swap_mb = 64
|
||||
|
||||
dev = '/dev/fake'
|
||||
|
||||
self.mox.StubOutWithMock(bmdh, 'get_dev')
|
||||
self.mox.StubOutWithMock(bmdh, 'get_image_mb')
|
||||
self.mox.StubOutWithMock(bmdh, 'discovery')
|
||||
self.mox.StubOutWithMock(bmdh, 'login_iscsi')
|
||||
self.mox.StubOutWithMock(bmdh, 'logout_iscsi')
|
||||
self.mox.StubOutWithMock(bmdh, 'work_on_disk')
|
||||
|
||||
class TestException(Exception):
|
||||
pass
|
||||
|
||||
bmdh.get_dev(address, port, iqn, lun).AndReturn(dev)
|
||||
bmdh.get_image_mb(image_path).AndReturn(1) # < root_mb
|
||||
bmdh.discovery(address, port)
|
||||
bmdh.login_iscsi(address, port, iqn)
|
||||
bmdh.work_on_disk(dev, root_mb, swap_mb, image_path).\
|
||||
AndRaise(TestException)
|
||||
bmdh.logout_iscsi(address, port, iqn)
|
||||
self.mox.ReplayAll()
|
||||
|
||||
self.assertRaises(TestException,
|
||||
bmdh.deploy,
|
||||
address, port, iqn, lun, image_path,
|
||||
pxe_config_path, root_mb, swap_mb)
|
||||
|
||||
|
||||
class SwitchPxeConfigTestCase(test.TestCase):
|
||||
def setUp(self):
|
||||
super(SwitchPxeConfigTestCase, self).setUp()
|
||||
(fd, self.fname) = tempfile.mkstemp()
|
||||
os.write(fd, _PXECONF_DEPLOY)
|
||||
os.close(fd)
|
||||
|
||||
def tearDown(self):
|
||||
os.unlink(self.fname)
|
||||
super(SwitchPxeConfigTestCase, self).tearDown()
|
||||
|
||||
def test_switch_pxe_config(self):
|
||||
bmdh.switch_pxe_config(self.fname,
|
||||
'12345678-1234-1234-1234-1234567890abcdef')
|
||||
with open(self.fname, 'r') as f:
|
||||
pxeconf = f.read()
|
||||
self.assertEqual(pxeconf, _PXECONF_BOOT)
|
||||
|
||||
|
||||
class OtherFunctionTestCase(test.TestCase):
|
||||
def test_get_dev(self):
|
||||
expected = '/dev/disk/by-path/ip-1.2.3.4:5678-iscsi-iqn.fake-lun-9'
|
||||
actual = bmdh.get_dev('1.2.3.4', 5678, 'iqn.fake', 9)
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_get_image_mb(self):
|
||||
mb = 1024 * 1024
|
||||
size = None
|
||||
|
||||
def fake_getsize(path):
|
||||
return size
|
||||
|
||||
self.stubs.Set(os.path, 'getsize', fake_getsize)
|
||||
size = 0
|
||||
self.assertEqual(bmdh.get_image_mb('x'), 0)
|
||||
size = 1
|
||||
self.assertEqual(bmdh.get_image_mb('x'), 1)
|
||||
size = mb
|
||||
self.assertEqual(bmdh.get_image_mb('x'), 1)
|
||||
size = mb + 1
|
||||
self.assertEqual(bmdh.get_image_mb('x'), 2)
|
Loading…
x
Reference in New Issue
Block a user