304 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			304 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # vim: tabstop=4 shiftwidth=4 softtabstop=4
 | |
| 
 | |
| # Copyright 2010 United States Government as represented by the
 | |
| # Administrator of the National Aeronautics and Space Administration.
 | |
| # All Rights Reserved.
 | |
| #
 | |
| #    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.
 | |
| """
 | |
| Tests For Compute
 | |
| """
 | |
| 
 | |
| import datetime
 | |
| 
 | |
| from nova import compute
 | |
| from nova import context
 | |
| from nova import db
 | |
| from nova import exception
 | |
| from nova import flags
 | |
| from nova import log as logging
 | |
| from nova import test
 | |
| from nova import utils
 | |
| from nova.auth import manager
 | |
| from nova.compute import instance_types
 | |
| from nova.image import local
 | |
| 
 | |
| LOG = logging.getLogger('nova.tests.compute')
 | |
| FLAGS = flags.FLAGS
 | |
| flags.DECLARE('stub_network', 'nova.compute.manager')
 | |
| 
 | |
| 
 | |
| class ComputeTestCase(test.TestCase):
 | |
|     """Test case for compute"""
 | |
|     def setUp(self):
 | |
|         super(ComputeTestCase, self).setUp()
 | |
|         self.flags(connection_type='fake',
 | |
|                    stub_network=True,
 | |
|                    network_manager='nova.network.manager.FlatManager')
 | |
|         self.compute = utils.import_object(FLAGS.compute_manager)
 | |
|         self.compute_api = compute.API()
 | |
|         self.manager = manager.AuthManager()
 | |
|         self.user = self.manager.create_user('fake', 'fake', 'fake')
 | |
|         self.project = self.manager.create_project('fake', 'fake', 'fake')
 | |
|         self.context = context.RequestContext('fake', 'fake', False)
 | |
| 
 | |
|         def fake_show(meh, context, id):
 | |
|             return {'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1}}
 | |
| 
 | |
|         self.stubs.Set(local.LocalImageService, 'show', fake_show)
 | |
| 
 | |
|     def tearDown(self):
 | |
|         self.manager.delete_user(self.user)
 | |
|         self.manager.delete_project(self.project)
 | |
|         super(ComputeTestCase, self).tearDown()
 | |
| 
 | |
|     def _create_instance(self, params={}):
 | |
|         """Create a test instance"""
 | |
|         inst = {}
 | |
|         inst['image_id'] = 1
 | |
|         inst['reservation_id'] = 'r-fakeres'
 | |
|         inst['launch_time'] = '10'
 | |
|         inst['user_id'] = self.user.id
 | |
|         inst['project_id'] = self.project.id
 | |
|         inst['instance_type'] = 'm1.tiny'
 | |
|         inst['mac_address'] = utils.generate_mac()
 | |
|         inst['ami_launch_index'] = 0
 | |
|         inst.update(params)
 | |
|         return db.instance_create(self.context, inst)['id']
 | |
| 
 | |
|     def _create_group(self):
 | |
|         values = {'name': 'testgroup',
 | |
|                   'description': 'testgroup',
 | |
|                   'user_id': self.user.id,
 | |
|                   'project_id': self.project.id}
 | |
|         return db.security_group_create(self.context, values)
 | |
| 
 | |
|     def test_create_instance_defaults_display_name(self):
 | |
|         """Verify that an instance cannot be created without a display_name."""
 | |
|         cases = [dict(), dict(display_name=None)]
 | |
|         for instance in cases:
 | |
|             ref = self.compute_api.create(self.context,
 | |
|                 FLAGS.default_instance_type, None, **instance)
 | |
|             try:
 | |
|                 self.assertNotEqual(ref[0]['display_name'], None)
 | |
|             finally:
 | |
|                 db.instance_destroy(self.context, ref[0]['id'])
 | |
| 
 | |
|     def test_create_instance_associates_security_groups(self):
 | |
|         """Make sure create associates security groups"""
 | |
|         group = self._create_group()
 | |
|         ref = self.compute_api.create(
 | |
|                 self.context,
 | |
|                 instance_type=FLAGS.default_instance_type,
 | |
|                 image_id=None,
 | |
|                 security_group=['testgroup'])
 | |
|         try:
 | |
|             self.assertEqual(len(db.security_group_get_by_instance(
 | |
|                              self.context, ref[0]['id'])), 1)
 | |
|             group = db.security_group_get(self.context, group['id'])
 | |
|             self.assert_(len(group.instances) == 1)
 | |
|         finally:
 | |
|             db.security_group_destroy(self.context, group['id'])
 | |
|             db.instance_destroy(self.context, ref[0]['id'])
 | |
| 
 | |
|     def test_destroy_instance_disassociates_security_groups(self):
 | |
|         """Make sure destroying disassociates security groups"""
 | |
|         group = self._create_group()
 | |
| 
 | |
|         ref = self.compute_api.create(
 | |
|                 self.context,
 | |
|                 instance_type=FLAGS.default_instance_type,
 | |
|                 image_id=None,
 | |
|                 security_group=['testgroup'])
 | |
|         try:
 | |
|             db.instance_destroy(self.context, ref[0]['id'])
 | |
|             group = db.security_group_get(self.context, group['id'])
 | |
|             self.assert_(len(group.instances) == 0)
 | |
|         finally:
 | |
|             db.security_group_destroy(self.context, group['id'])
 | |
| 
 | |
|     def test_destroy_security_group_disassociates_instances(self):
 | |
|         """Make sure destroying security groups disassociates instances"""
 | |
|         group = self._create_group()
 | |
| 
 | |
|         ref = self.compute_api.create(
 | |
|                 self.context,
 | |
|                 instance_type=FLAGS.default_instance_type,
 | |
|                 image_id=None,
 | |
|                 security_group=['testgroup'])
 | |
| 
 | |
|         try:
 | |
|             db.security_group_destroy(self.context, group['id'])
 | |
|             group = db.security_group_get(context.get_admin_context(
 | |
|                                           read_deleted=True), group['id'])
 | |
|             self.assert_(len(group.instances) == 0)
 | |
|         finally:
 | |
|             db.instance_destroy(self.context, ref[0]['id'])
 | |
| 
 | |
|     def test_run_terminate(self):
 | |
|         """Make sure it is possible to  run and terminate instance"""
 | |
|         instance_id = self._create_instance()
 | |
| 
 | |
|         self.compute.run_instance(self.context, instance_id)
 | |
| 
 | |
|         instances = db.instance_get_all(context.get_admin_context())
 | |
|         LOG.info(_("Running instances: %s"), instances)
 | |
|         self.assertEqual(len(instances), 1)
 | |
| 
 | |
|         self.compute.terminate_instance(self.context, instance_id)
 | |
| 
 | |
|         instances = db.instance_get_all(context.get_admin_context())
 | |
|         LOG.info(_("After terminating instances: %s"), instances)
 | |
|         self.assertEqual(len(instances), 0)
 | |
| 
 | |
|     def test_run_terminate_timestamps(self):
 | |
|         """Make sure timestamps are set for launched and destroyed"""
 | |
|         instance_id = self._create_instance()
 | |
|         instance_ref = db.instance_get(self.context, instance_id)
 | |
|         self.assertEqual(instance_ref['launched_at'], None)
 | |
|         self.assertEqual(instance_ref['deleted_at'], None)
 | |
|         launch = datetime.datetime.utcnow()
 | |
|         self.compute.run_instance(self.context, instance_id)
 | |
|         instance_ref = db.instance_get(self.context, instance_id)
 | |
|         self.assert_(instance_ref['launched_at'] > launch)
 | |
|         self.assertEqual(instance_ref['deleted_at'], None)
 | |
|         terminate = datetime.datetime.utcnow()
 | |
|         self.compute.terminate_instance(self.context, instance_id)
 | |
|         self.context = self.context.elevated(True)
 | |
|         instance_ref = db.instance_get(self.context, instance_id)
 | |
|         self.assert_(instance_ref['launched_at'] < terminate)
 | |
|         self.assert_(instance_ref['deleted_at'] > terminate)
 | |
| 
 | |
|     def test_pause(self):
 | |
|         """Ensure instance can be paused"""
 | |
|         instance_id = self._create_instance()
 | |
|         self.compute.run_instance(self.context, instance_id)
 | |
|         self.compute.pause_instance(self.context, instance_id)
 | |
|         self.compute.unpause_instance(self.context, instance_id)
 | |
|         self.compute.terminate_instance(self.context, instance_id)
 | |
| 
 | |
|     def test_suspend(self):
 | |
|         """ensure instance can be suspended"""
 | |
|         instance_id = self._create_instance()
 | |
|         self.compute.run_instance(self.context, instance_id)
 | |
|         self.compute.suspend_instance(self.context, instance_id)
 | |
|         self.compute.resume_instance(self.context, instance_id)
 | |
|         self.compute.terminate_instance(self.context, instance_id)
 | |
| 
 | |
|     def test_reboot(self):
 | |
|         """Ensure instance can be rebooted"""
 | |
|         instance_id = self._create_instance()
 | |
|         self.compute.run_instance(self.context, instance_id)
 | |
|         self.compute.reboot_instance(self.context, instance_id)
 | |
|         self.compute.terminate_instance(self.context, instance_id)
 | |
| 
 | |
|     def test_set_admin_password(self):
 | |
|         """Ensure instance can have its admin password set"""
 | |
|         instance_id = self._create_instance()
 | |
|         self.compute.run_instance(self.context, instance_id)
 | |
|         self.compute.set_admin_password(self.context, instance_id)
 | |
|         self.compute.terminate_instance(self.context, instance_id)
 | |
| 
 | |
|     def test_inject_file(self):
 | |
|         """Ensure we can write a file to an instance"""
 | |
|         instance_id = self._create_instance()
 | |
|         self.compute.run_instance(self.context, instance_id)
 | |
|         self.compute.inject_file(self.context, instance_id, "/tmp/test",
 | |
|                 "File Contents")
 | |
|         self.compute.terminate_instance(self.context, instance_id)
 | |
| 
 | |
|     def test_snapshot(self):
 | |
|         """Ensure instance can be snapshotted"""
 | |
|         instance_id = self._create_instance()
 | |
|         name = "myfakesnapshot"
 | |
|         self.compute.run_instance(self.context, instance_id)
 | |
|         self.compute.snapshot_instance(self.context, instance_id, name)
 | |
|         self.compute.terminate_instance(self.context, instance_id)
 | |
| 
 | |
|     def test_console_output(self):
 | |
|         """Make sure we can get console output from instance"""
 | |
|         instance_id = self._create_instance()
 | |
|         self.compute.run_instance(self.context, instance_id)
 | |
| 
 | |
|         console = self.compute.get_console_output(self.context,
 | |
|                                                         instance_id)
 | |
|         self.assert_(console)
 | |
|         self.compute.terminate_instance(self.context, instance_id)
 | |
| 
 | |
|     def test_ajax_console(self):
 | |
|         """Make sure we can get console output from instance"""
 | |
|         instance_id = self._create_instance()
 | |
|         self.compute.run_instance(self.context, instance_id)
 | |
| 
 | |
|         console = self.compute.get_ajax_console(self.context,
 | |
|                                                 instance_id)
 | |
|         self.assert_(console)
 | |
|         self.compute.terminate_instance(self.context, instance_id)
 | |
| 
 | |
|     def test_run_instance_existing(self):
 | |
|         """Ensure failure when running an instance that already exists"""
 | |
|         instance_id = self._create_instance()
 | |
|         self.compute.run_instance(self.context, instance_id)
 | |
|         self.assertRaises(exception.Error,
 | |
|                           self.compute.run_instance,
 | |
|                           self.context,
 | |
|                           instance_id)
 | |
|         self.compute.terminate_instance(self.context, instance_id)
 | |
| 
 | |
|     def test_lock(self):
 | |
|         """ensure locked instance cannot be changed"""
 | |
|         instance_id = self._create_instance()
 | |
|         self.compute.run_instance(self.context, instance_id)
 | |
| 
 | |
|         non_admin_context = context.RequestContext(None, None, False, False)
 | |
| 
 | |
|         # decorator should return False (fail) with locked nonadmin context
 | |
|         self.compute.lock_instance(self.context, instance_id)
 | |
|         ret_val = self.compute.reboot_instance(non_admin_context, instance_id)
 | |
|         self.assertEqual(ret_val, False)
 | |
| 
 | |
|         # decorator should return None (success) with unlocked nonadmin context
 | |
|         self.compute.unlock_instance(self.context, instance_id)
 | |
|         ret_val = self.compute.reboot_instance(non_admin_context, instance_id)
 | |
|         self.assertEqual(ret_val, None)
 | |
| 
 | |
|         self.compute.terminate_instance(self.context, instance_id)
 | |
| 
 | |
|     def test_resize_instance(self):
 | |
|         """Ensure instance can be migrated/resized"""
 | |
|         instance_id = self._create_instance()
 | |
|         context = self.context.elevated()
 | |
|         self.compute.run_instance(self.context, instance_id)
 | |
|         db.instance_update(self.context, instance_id, {'host': 'foo'})
 | |
|         self.compute.prep_resize(context, instance_id)
 | |
|         migration_ref = db.migration_get_by_instance_and_status(context,
 | |
|                 instance_id, 'pre-migrating')
 | |
|         self.compute.resize_instance(context, instance_id,
 | |
|                 migration_ref['id'])
 | |
|         self.compute.terminate_instance(context, instance_id)
 | |
| 
 | |
|     def test_get_by_flavor_id(self):
 | |
|         type = instance_types.get_by_flavor_id(1)
 | |
|         self.assertEqual(type, 'm1.tiny')
 | |
| 
 | |
|     def test_resize_same_source_fails(self):
 | |
|         """Ensure instance fails to migrate when source and destination are
 | |
|         the same host"""
 | |
|         instance_id = self._create_instance()
 | |
|         self.compute.run_instance(self.context, instance_id)
 | |
|         self.assertRaises(exception.Error, self.compute.prep_resize,
 | |
|                 self.context, instance_id)
 | |
|         self.compute.terminate_instance(self.context, instance_id)
 | |
|         type = instance_types.get_by_flavor_id("1")
 | |
|         self.assertEqual(type, 'm1.tiny')
 | 
