Adding two snapshot related task states

The first, 'image_pending_upload', indicates that the snapshot of a given
instance has been taken and it is being prepared for uploading to the
image service.

The second, 'image_uploading', indicates that the compute manager has
initiated upload to the image service.

Implements blueprint snapshot-task-states

Change-Id: I256c5d21a1d23b87d2060cca99eb9839c5b89161
This commit is contained in:
Andrew Melton
2012-11-12 13:19:19 -05:00
parent 6fbc298428
commit 1ba2496c7c
5 changed files with 202 additions and 18 deletions

View File

@@ -26,6 +26,7 @@ import sys
import uuid import uuid
from nova.compute import power_state from nova.compute import power_state
from nova.compute import task_states
from nova import context from nova import context
from nova import db from nova import db
from nova.image import glance from nova.image import glance
@@ -36,6 +37,7 @@ from nova.tests.hyperv import db_fakes
from nova.tests.hyperv import hypervutils from nova.tests.hyperv import hypervutils
from nova.tests.hyperv import mockproxy from nova.tests.hyperv import mockproxy
import nova.tests.image.fake as fake_image import nova.tests.image.fake as fake_image
from nova.tests import matchers
from nova.virt.hyperv import constants from nova.virt.hyperv import constants
from nova.virt.hyperv import driver as driver_hyperv from nova.virt.hyperv import driver as driver_hyperv
from nova.virt.hyperv import vmutils from nova.virt.hyperv import vmutils
@@ -407,27 +409,55 @@ class HyperVAPITestCase(basetestcase.BaseTestCase):
self.assertTrue(self._fetched_image is None) self.assertTrue(self._fetched_image is None)
def test_snapshot_with_update_failure(self): def test_snapshot_with_update_failure(self):
expected_calls = [
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_PENDING_UPLOAD}},
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_UPLOADING,
'expected_state': task_states.IMAGE_PENDING_UPLOAD}}]
func_call_matcher = matchers.FunctionCallMatcher(expected_calls)
self._spawn_instance(True) self._spawn_instance(True)
self._update_image_raise_exception = True self._update_image_raise_exception = True
snapshot_name = 'test_snapshot_' + str(uuid.uuid4()) snapshot_name = 'test_snapshot_' + str(uuid.uuid4())
self.assertRaises(vmutils.HyperVException, self._conn.snapshot, self.assertRaises(vmutils.HyperVException, self._conn.snapshot,
self._context, self._instance_data, snapshot_name) self._context, self._instance_data, snapshot_name,
func_call_matcher.call)
# assert states changed in correct order
self.assertIsNone(func_call_matcher.match())
# assert VM snapshots have been removed # assert VM snapshots have been removed
self.assertEquals(self._hypervutils.get_vm_snapshots_count( self.assertEquals(self._hypervutils.get_vm_snapshots_count(
self._instance_data["name"]), 0) self._instance_data["name"]), 0)
def test_snapshot(self): def test_snapshot(self):
expected_calls = [
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_PENDING_UPLOAD}},
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_UPLOADING,
'expected_state': task_states.IMAGE_PENDING_UPLOAD}}]
func_call_matcher = matchers.FunctionCallMatcher(expected_calls)
self._spawn_instance(True) self._spawn_instance(True)
snapshot_name = 'test_snapshot_' + str(uuid.uuid4()) snapshot_name = 'test_snapshot_' + str(uuid.uuid4())
self._conn.snapshot(self._context, self._instance_data, snapshot_name) self._conn.snapshot(self._context, self._instance_data, snapshot_name,
func_call_matcher.call)
self.assertTrue(self._image_metadata and self.assertTrue(self._image_metadata and
"disk_format" in self._image_metadata and "disk_format" in self._image_metadata and
self._image_metadata["disk_format"] == "vhd") self._image_metadata["disk_format"] == "vhd")
# assert states changed in correct order
self.assertIsNone(func_call_matcher.match())
# assert VM snapshots have been removed # assert VM snapshots have been removed
self.assertEquals(self._hypervutils.get_vm_snapshots_count( self.assertEquals(self._hypervutils.get_vm_snapshots_count(
self._instance_data["name"]), 0) self._instance_data["name"]), 0)

View File

@@ -32,6 +32,7 @@ from xml.dom import minidom
from nova.api.ec2 import cloud from nova.api.ec2 import cloud
from nova.compute import instance_types from nova.compute import instance_types
from nova.compute import power_state from nova.compute import power_state
from nova.compute import task_states
from nova.compute import vm_mode from nova.compute import vm_mode
from nova.compute import vm_states from nova.compute import vm_states
from nova import context from nova import context
@@ -1209,6 +1210,16 @@ class LibvirtConnTestCase(test.TestCase):
self.assertEqual(devices, ['vda', 'vdb']) self.assertEqual(devices, ['vda', 'vdb'])
def test_snapshot_in_ami_format(self): def test_snapshot_in_ami_format(self):
expected_calls = [
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_PENDING_UPLOAD}},
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_UPLOADING,
'expected_state': task_states.IMAGE_PENDING_UPLOAD}}]
func_call_matcher = matchers.FunctionCallMatcher(expected_calls)
self.flags(libvirt_snapshots_directory='./') self.flags(libvirt_snapshots_directory='./')
# Start test # Start test
@@ -1238,15 +1249,28 @@ class LibvirtConnTestCase(test.TestCase):
self.mox.ReplayAll() self.mox.ReplayAll()
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
conn.snapshot(self.context, instance_ref, recv_meta['id']) conn.snapshot(self.context, instance_ref, recv_meta['id'],
func_call_matcher.call)
snapshot = image_service.show(context, recv_meta['id']) snapshot = image_service.show(context, recv_meta['id'])
self.assertIsNone(func_call_matcher.match())
self.assertEquals(snapshot['properties']['image_state'], 'available')
self.assertEquals(snapshot['properties']['image_state'], 'available') self.assertEquals(snapshot['properties']['image_state'], 'available')
self.assertEquals(snapshot['status'], 'active') self.assertEquals(snapshot['status'], 'active')
self.assertEquals(snapshot['disk_format'], 'ami') self.assertEquals(snapshot['disk_format'], 'ami')
self.assertEquals(snapshot['name'], snapshot_name) self.assertEquals(snapshot['name'], snapshot_name)
def test_lxc_snapshot_in_ami_format(self): def test_lxc_snapshot_in_ami_format(self):
expected_calls = [
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_PENDING_UPLOAD}},
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_UPLOADING,
'expected_state': task_states.IMAGE_PENDING_UPLOAD}}]
func_call_matcher = matchers.FunctionCallMatcher(expected_calls)
self.flags(libvirt_snapshots_directory='./', self.flags(libvirt_snapshots_directory='./',
libvirt_type='lxc') libvirt_type='lxc')
@@ -1277,15 +1301,27 @@ class LibvirtConnTestCase(test.TestCase):
self.mox.ReplayAll() self.mox.ReplayAll()
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
conn.snapshot(self.context, instance_ref, recv_meta['id']) conn.snapshot(self.context, instance_ref, recv_meta['id'],
func_call_matcher.call)
snapshot = image_service.show(context, recv_meta['id']) snapshot = image_service.show(context, recv_meta['id'])
self.assertIsNone(func_call_matcher.match())
self.assertEquals(snapshot['properties']['image_state'], 'available') self.assertEquals(snapshot['properties']['image_state'], 'available')
self.assertEquals(snapshot['status'], 'active') self.assertEquals(snapshot['status'], 'active')
self.assertEquals(snapshot['disk_format'], 'ami') self.assertEquals(snapshot['disk_format'], 'ami')
self.assertEquals(snapshot['name'], snapshot_name) self.assertEquals(snapshot['name'], snapshot_name)
def test_snapshot_in_raw_format(self): def test_snapshot_in_raw_format(self):
expected_calls = [
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_PENDING_UPLOAD}},
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_UPLOADING,
'expected_state': task_states.IMAGE_PENDING_UPLOAD}}]
func_call_matcher = matchers.FunctionCallMatcher(expected_calls)
self.flags(libvirt_snapshots_directory='./') self.flags(libvirt_snapshots_directory='./')
# Start test # Start test
@@ -1316,15 +1352,27 @@ class LibvirtConnTestCase(test.TestCase):
self.mox.ReplayAll() self.mox.ReplayAll()
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
conn.snapshot(self.context, instance_ref, recv_meta['id']) conn.snapshot(self.context, instance_ref, recv_meta['id'],
func_call_matcher.call)
snapshot = image_service.show(context, recv_meta['id']) snapshot = image_service.show(context, recv_meta['id'])
self.assertIsNone(func_call_matcher.match())
self.assertEquals(snapshot['properties']['image_state'], 'available') self.assertEquals(snapshot['properties']['image_state'], 'available')
self.assertEquals(snapshot['status'], 'active') self.assertEquals(snapshot['status'], 'active')
self.assertEquals(snapshot['disk_format'], 'raw') self.assertEquals(snapshot['disk_format'], 'raw')
self.assertEquals(snapshot['name'], snapshot_name) self.assertEquals(snapshot['name'], snapshot_name)
def test_lxc_snapshot_in_raw_format(self): def test_lxc_snapshot_in_raw_format(self):
expected_calls = [
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_PENDING_UPLOAD}},
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_UPLOADING,
'expected_state': task_states.IMAGE_PENDING_UPLOAD}}]
func_call_matcher = matchers.FunctionCallMatcher(expected_calls)
self.flags(libvirt_snapshots_directory='./', self.flags(libvirt_snapshots_directory='./',
libvirt_type='lxc') libvirt_type='lxc')
@@ -1356,15 +1404,27 @@ class LibvirtConnTestCase(test.TestCase):
self.mox.ReplayAll() self.mox.ReplayAll()
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
conn.snapshot(self.context, instance_ref, recv_meta['id']) conn.snapshot(self.context, instance_ref, recv_meta['id'],
func_call_matcher.call)
snapshot = image_service.show(context, recv_meta['id']) snapshot = image_service.show(context, recv_meta['id'])
self.assertIsNone(func_call_matcher.match())
self.assertEquals(snapshot['properties']['image_state'], 'available') self.assertEquals(snapshot['properties']['image_state'], 'available')
self.assertEquals(snapshot['status'], 'active') self.assertEquals(snapshot['status'], 'active')
self.assertEquals(snapshot['disk_format'], 'raw') self.assertEquals(snapshot['disk_format'], 'raw')
self.assertEquals(snapshot['name'], snapshot_name) self.assertEquals(snapshot['name'], snapshot_name)
def test_snapshot_in_qcow2_format(self): def test_snapshot_in_qcow2_format(self):
expected_calls = [
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_PENDING_UPLOAD}},
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_UPLOADING,
'expected_state': task_states.IMAGE_PENDING_UPLOAD}}]
func_call_matcher = matchers.FunctionCallMatcher(expected_calls)
self.flags(snapshot_image_format='qcow2', self.flags(snapshot_image_format='qcow2',
libvirt_snapshots_directory='./') libvirt_snapshots_directory='./')
@@ -1391,15 +1451,27 @@ class LibvirtConnTestCase(test.TestCase):
self.mox.ReplayAll() self.mox.ReplayAll()
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
conn.snapshot(self.context, instance_ref, recv_meta['id']) conn.snapshot(self.context, instance_ref, recv_meta['id'],
func_call_matcher.call)
snapshot = image_service.show(context, recv_meta['id']) snapshot = image_service.show(context, recv_meta['id'])
self.assertIsNone(func_call_matcher.match())
self.assertEquals(snapshot['properties']['image_state'], 'available') self.assertEquals(snapshot['properties']['image_state'], 'available')
self.assertEquals(snapshot['status'], 'active') self.assertEquals(snapshot['status'], 'active')
self.assertEquals(snapshot['disk_format'], 'qcow2') self.assertEquals(snapshot['disk_format'], 'qcow2')
self.assertEquals(snapshot['name'], snapshot_name) self.assertEquals(snapshot['name'], snapshot_name)
def test_lxc_snapshot_in_qcow2_format(self): def test_lxc_snapshot_in_qcow2_format(self):
expected_calls = [
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_PENDING_UPLOAD}},
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_UPLOADING,
'expected_state': task_states.IMAGE_PENDING_UPLOAD}}]
func_call_matcher = matchers.FunctionCallMatcher(expected_calls)
self.flags(snapshot_image_format='qcow2', self.flags(snapshot_image_format='qcow2',
libvirt_snapshots_directory='./', libvirt_snapshots_directory='./',
libvirt_type='lxc') libvirt_type='lxc')
@@ -1427,15 +1499,27 @@ class LibvirtConnTestCase(test.TestCase):
self.mox.ReplayAll() self.mox.ReplayAll()
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
conn.snapshot(self.context, instance_ref, recv_meta['id']) conn.snapshot(self.context, instance_ref, recv_meta['id'],
func_call_matcher.call)
snapshot = image_service.show(context, recv_meta['id']) snapshot = image_service.show(context, recv_meta['id'])
self.assertIsNone(func_call_matcher.match())
self.assertEquals(snapshot['properties']['image_state'], 'available') self.assertEquals(snapshot['properties']['image_state'], 'available')
self.assertEquals(snapshot['status'], 'active') self.assertEquals(snapshot['status'], 'active')
self.assertEquals(snapshot['disk_format'], 'qcow2') self.assertEquals(snapshot['disk_format'], 'qcow2')
self.assertEquals(snapshot['name'], snapshot_name) self.assertEquals(snapshot['name'], snapshot_name)
def test_snapshot_no_image_architecture(self): def test_snapshot_no_image_architecture(self):
expected_calls = [
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_PENDING_UPLOAD}},
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_UPLOADING,
'expected_state': task_states.IMAGE_PENDING_UPLOAD}}]
func_call_matcher = matchers.FunctionCallMatcher(expected_calls)
self.flags(libvirt_snapshots_directory='./') self.flags(libvirt_snapshots_directory='./')
# Start test # Start test
@@ -1465,14 +1549,26 @@ class LibvirtConnTestCase(test.TestCase):
self.mox.ReplayAll() self.mox.ReplayAll()
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
conn.snapshot(self.context, instance_ref, recv_meta['id']) conn.snapshot(self.context, instance_ref, recv_meta['id'],
func_call_matcher.call)
snapshot = image_service.show(context, recv_meta['id']) snapshot = image_service.show(context, recv_meta['id'])
self.assertIsNone(func_call_matcher.match())
self.assertEquals(snapshot['properties']['image_state'], 'available') self.assertEquals(snapshot['properties']['image_state'], 'available')
self.assertEquals(snapshot['status'], 'active') self.assertEquals(snapshot['status'], 'active')
self.assertEquals(snapshot['name'], snapshot_name) self.assertEquals(snapshot['name'], snapshot_name)
def test_lxc_snapshot_no_image_architecture(self): def test_lxc_snapshot_no_image_architecture(self):
expected_calls = [
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_PENDING_UPLOAD}},
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_UPLOADING,
'expected_state': task_states.IMAGE_PENDING_UPLOAD}}]
func_call_matcher = matchers.FunctionCallMatcher(expected_calls)
self.flags(libvirt_snapshots_directory='./', self.flags(libvirt_snapshots_directory='./',
libvirt_type='lxc') libvirt_type='lxc')
@@ -1503,14 +1599,26 @@ class LibvirtConnTestCase(test.TestCase):
self.mox.ReplayAll() self.mox.ReplayAll()
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
conn.snapshot(self.context, instance_ref, recv_meta['id']) conn.snapshot(self.context, instance_ref, recv_meta['id'],
func_call_matcher.call)
snapshot = image_service.show(context, recv_meta['id']) snapshot = image_service.show(context, recv_meta['id'])
self.assertIsNone(func_call_matcher.match())
self.assertEquals(snapshot['properties']['image_state'], 'available') self.assertEquals(snapshot['properties']['image_state'], 'available')
self.assertEquals(snapshot['status'], 'active') self.assertEquals(snapshot['status'], 'active')
self.assertEquals(snapshot['name'], snapshot_name) self.assertEquals(snapshot['name'], snapshot_name)
def test_snapshot_no_original_image(self): def test_snapshot_no_original_image(self):
expected_calls = [
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_PENDING_UPLOAD}},
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_UPLOADING,
'expected_state': task_states.IMAGE_PENDING_UPLOAD}}]
func_call_matcher = matchers.FunctionCallMatcher(expected_calls)
self.flags(libvirt_snapshots_directory='./') self.flags(libvirt_snapshots_directory='./')
# Start test # Start test
@@ -1536,14 +1644,26 @@ class LibvirtConnTestCase(test.TestCase):
self.mox.ReplayAll() self.mox.ReplayAll()
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
conn.snapshot(self.context, instance_ref, recv_meta['id']) conn.snapshot(self.context, instance_ref, recv_meta['id'],
func_call_matcher.call)
snapshot = image_service.show(context, recv_meta['id']) snapshot = image_service.show(context, recv_meta['id'])
self.assertIsNone(func_call_matcher.match())
self.assertEquals(snapshot['properties']['image_state'], 'available') self.assertEquals(snapshot['properties']['image_state'], 'available')
self.assertEquals(snapshot['status'], 'active') self.assertEquals(snapshot['status'], 'active')
self.assertEquals(snapshot['name'], snapshot_name) self.assertEquals(snapshot['name'], snapshot_name)
def test_lxc_snapshot_no_original_image(self): def test_lxc_snapshot_no_original_image(self):
expected_calls = [
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_PENDING_UPLOAD}},
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_UPLOADING,
'expected_state': task_states.IMAGE_PENDING_UPLOAD}}]
func_call_matcher = matchers.FunctionCallMatcher(expected_calls)
self.flags(libvirt_snapshots_directory='./', self.flags(libvirt_snapshots_directory='./',
libvirt_type='lxc') libvirt_type='lxc')
@@ -1570,9 +1690,11 @@ class LibvirtConnTestCase(test.TestCase):
self.mox.ReplayAll() self.mox.ReplayAll()
conn = libvirt_driver.LibvirtDriver(False) conn = libvirt_driver.LibvirtDriver(False)
conn.snapshot(self.context, instance_ref, recv_meta['id']) conn.snapshot(self.context, instance_ref, recv_meta['id'],
func_call_matcher.call)
snapshot = image_service.show(context, recv_meta['id']) snapshot = image_service.show(context, recv_meta['id'])
self.assertIsNone(func_call_matcher.match())
self.assertEquals(snapshot['properties']['image_state'], 'available') self.assertEquals(snapshot['properties']['image_state'], 'available')
self.assertEquals(snapshot['status'], 'active') self.assertEquals(snapshot['status'], 'active')
self.assertEquals(snapshot['name'], snapshot_name) self.assertEquals(snapshot['name'], snapshot_name)

View File

@@ -215,13 +215,15 @@ class _VirtDriverTestCase(_FakeDriverBackendTestCase):
img_ref = self.image_service.create(self.ctxt, {'name': 'snap-1'}) img_ref = self.image_service.create(self.ctxt, {'name': 'snap-1'})
self.assertRaises(exception.InstanceNotRunning, self.assertRaises(exception.InstanceNotRunning,
self.connection.snapshot, self.connection.snapshot,
self.ctxt, instance_ref, img_ref['id']) self.ctxt, instance_ref, img_ref['id'],
lambda *args, **kwargs: None)
@catch_notimplementederror @catch_notimplementederror
def test_snapshot_running(self): def test_snapshot_running(self):
img_ref = self.image_service.create(self.ctxt, {'name': 'snap-1'}) img_ref = self.image_service.create(self.ctxt, {'name': 'snap-1'})
instance_ref, network_info = self._get_running_instance() instance_ref, network_info = self._get_running_instance()
self.connection.snapshot(self.ctxt, instance_ref, img_ref['id']) self.connection.snapshot(self.ctxt, instance_ref, img_ref['id'],
lambda *args, **kwargs: None)
@catch_notimplementederror @catch_notimplementederror
def test_reboot(self): def test_reboot(self):

View File

@@ -20,11 +20,13 @@ Test suite for VMWareAPI.
""" """
from nova.compute import power_state from nova.compute import power_state
from nova.compute import task_states
from nova import context from nova import context
from nova import db from nova import db
from nova import exception from nova import exception
from nova import test from nova import test
import nova.tests.image.fake import nova.tests.image.fake
from nova.tests import matchers
from nova.tests.vmwareapi import db_fakes from nova.tests.vmwareapi import db_fakes
from nova.tests.vmwareapi import stubs from nova.tests.vmwareapi import stubs
from nova.virt.vmwareapi import driver from nova.virt.vmwareapi import driver
@@ -159,17 +161,29 @@ class VMWareAPIVMTestCase(test.TestCase):
self._check_vm_info(info, power_state.RUNNING) self._check_vm_info(info, power_state.RUNNING)
def test_snapshot(self): def test_snapshot(self):
expected_calls = [
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_PENDING_UPLOAD}},
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_UPLOADING,
'expected_state': task_states.IMAGE_PENDING_UPLOAD}}]
func_call_matcher = matchers.FunctionCallMatcher(expected_calls)
self._create_vm() self._create_vm()
info = self.conn.get_info({'name': 1}) info = self.conn.get_info({'name': 1})
self._check_vm_info(info, power_state.RUNNING) self._check_vm_info(info, power_state.RUNNING)
self.conn.snapshot(self.context, self.instance, "Test-Snapshot") self.conn.snapshot(self.context, self.instance, "Test-Snapshot",
func_call_matcher.call)
info = self.conn.get_info({'name': 1}) info = self.conn.get_info({'name': 1})
self._check_vm_info(info, power_state.RUNNING) self._check_vm_info(info, power_state.RUNNING)
self.assertIsNone(func_call_matcher.match())
def test_snapshot_non_existent(self): def test_snapshot_non_existent(self):
self._create_instance_in_the_db() self._create_instance_in_the_db()
self.assertRaises(exception.InstanceNotFound, self.conn.snapshot, self.assertRaises(exception.InstanceNotFound, self.conn.snapshot,
self.context, self.instance, "Test-Snapshot") self.context, self.instance, "Test-Snapshot",
lambda *args, **kwargs: None)
def test_reboot(self): def test_reboot(self):
self._create_vm() self._create_vm()

View File

@@ -397,6 +397,7 @@ class XenAPIVMTestCase(stubs.XenAPITestBase):
self.assertThat(fake_diagnostics, matchers.DictMatches(expected)) self.assertThat(fake_diagnostics, matchers.DictMatches(expected))
def test_instance_snapshot_fails_with_no_primary_vdi(self): def test_instance_snapshot_fails_with_no_primary_vdi(self):
def create_bad_vbd(session, vm_ref, vdi_ref, userdevice, def create_bad_vbd(session, vm_ref, vdi_ref, userdevice,
vbd_type='disk', read_only=False, bootable=False, vbd_type='disk', read_only=False, bootable=False,
osvol=False): osvol=False):
@@ -417,9 +418,20 @@ class XenAPIVMTestCase(stubs.XenAPITestBase):
image_id = "my_snapshot_id" image_id = "my_snapshot_id"
self.assertRaises(exception.NovaException, self.conn.snapshot, self.assertRaises(exception.NovaException, self.conn.snapshot,
self.context, instance, image_id) self.context, instance, image_id,
lambda *args, **kwargs: None)
def test_instance_snapshot(self): def test_instance_snapshot(self):
expected_calls = [
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_PENDING_UPLOAD}},
{'args': (),
'kwargs':
{'task_state': task_states.IMAGE_UPLOADING,
'expected_state': task_states.IMAGE_PENDING_UPLOAD}}]
func_call_matcher = matchers.FunctionCallMatcher(expected_calls)
stubs.stubout_instance_snapshot(self.stubs) stubs.stubout_instance_snapshot(self.stubs)
stubs.stubout_is_snapshot(self.stubs) stubs.stubout_is_snapshot(self.stubs)
# Stubbing out firewall driver as previous stub sets alters # Stubbing out firewall driver as previous stub sets alters
@@ -428,7 +440,8 @@ class XenAPIVMTestCase(stubs.XenAPITestBase):
instance = self._create_instance() instance = self._create_instance()
image_id = "my_snapshot_id" image_id = "my_snapshot_id"
self.conn.snapshot(self.context, instance, image_id) self.conn.snapshot(self.context, instance, image_id,
func_call_matcher.call)
# Ensure VM was torn down # Ensure VM was torn down
vm_labels = [] vm_labels = []
@@ -447,6 +460,9 @@ class XenAPIVMTestCase(stubs.XenAPITestBase):
self.assertEquals(vbd_labels, [instance['name']]) self.assertEquals(vbd_labels, [instance['name']])
# Ensure task states changed in correct order
self.assertIsNone(func_call_matcher.match())
# Ensure VDIs were torn down # Ensure VDIs were torn down
for vdi_ref in xenapi_fake.get_all('VDI'): for vdi_ref in xenapi_fake.get_all('VDI'):
vdi_rec = xenapi_fake.get_record('VDI', vdi_ref) vdi_rec = xenapi_fake.get_record('VDI', vdi_ref)