~ubuntu-branches/ubuntu/quantal/nova/quantal-proposed

« back to all changes in this revision

Viewing changes to nova/tests/test_compute.py

  • Committer: Bazaar Package Importer
  • Author(s): Chuck Short
  • Date: 2011-10-21 14:37:26 UTC
  • mto: This revision was merged to the branch mainline in revision 47.
  • Revision ID: james.westby@ubuntu.com-20111021143726-dk1m1a0vwov3kyls
Tags: upstream-2012.1~e1~20111020.11229
ImportĀ upstreamĀ versionĀ 2012.1~e1~20111020.11229

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
Tests For Compute
21
21
"""
22
22
 
 
23
from copy import copy
 
24
import mox
 
25
 
23
26
from nova import compute
24
 
from nova.compute import instance_types
25
 
from nova.compute import manager as compute_manager
26
 
from nova.compute import power_state
27
 
from nova.compute import vm_states
28
27
from nova import context
29
28
from nova import db
30
 
from nova.db.sqlalchemy import models
31
 
from nova.db.sqlalchemy import api as sqlalchemy_api
32
29
from nova import exception
33
30
from nova import flags
34
 
import nova.image.fake
35
31
from nova import log as logging
 
32
from nova.scheduler import driver as scheduler_driver
36
33
from nova import rpc
37
34
from nova import test
38
35
from nova import utils
 
36
import nova
 
37
 
 
38
from nova.compute import instance_types
 
39
from nova.compute import manager as compute_manager
 
40
from nova.compute import power_state
 
41
from nova.compute import task_states
 
42
from nova.compute import vm_states
 
43
from nova.db.sqlalchemy import models
 
44
from nova.image import fake as fake_image
39
45
from nova.notifier import test_notifier
 
46
from nova.tests import fake_network
 
47
 
40
48
 
41
49
LOG = logging.getLogger('nova.tests.compute')
42
50
FLAGS = flags.FLAGS
52
60
        self.counter += t
53
61
 
54
62
 
 
63
orig_rpc_call = rpc.call
 
64
orig_rpc_cast = rpc.cast
 
65
 
 
66
 
 
67
def rpc_call_wrapper(context, topic, msg, do_cast=True):
 
68
    """Stub out the scheduler creating the instance entry"""
 
69
    if topic == FLAGS.scheduler_topic and \
 
70
            msg['method'] == 'run_instance':
 
71
        request_spec = msg['args']['request_spec']
 
72
        scheduler = scheduler_driver.Scheduler
 
73
        num_instances = request_spec.get('num_instances', 1)
 
74
        instances = []
 
75
        for x in xrange(num_instances):
 
76
            instance = scheduler().create_instance_db_entry(
 
77
                    context, request_spec)
 
78
            encoded = scheduler_driver.encode_instance(instance)
 
79
            instances.append(encoded)
 
80
        return instances
 
81
    else:
 
82
        if do_cast:
 
83
            orig_rpc_cast(context, topic, msg)
 
84
        else:
 
85
            return orig_rpc_call(context, topic, msg)
 
86
 
 
87
 
 
88
def rpc_cast_wrapper(context, topic, msg):
 
89
    """Stub out the scheduler creating the instance entry in
 
90
    the reservation_id case.
 
91
    """
 
92
    rpc_call_wrapper(context, topic, msg, do_cast=True)
 
93
 
 
94
 
55
95
def nop_report_driver_status(self):
56
96
    pass
57
97
 
72
112
        test_notifier.NOTIFICATIONS = []
73
113
 
74
114
        def fake_show(meh, context, id):
75
 
            return {'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1}}
 
115
            return {'id': 1, 'min_disk': None, 'min_ram': None,
 
116
                    'properties': {'kernel_id': 1, 'ramdisk_id': 1}}
76
117
 
77
 
        self.stubs.Set(nova.image.fake._FakeImageService, 'show', fake_show)
 
118
        self.stubs.Set(fake_image._FakeImageService, 'show', fake_show)
 
119
        self.stubs.Set(rpc, 'call', rpc_call_wrapper)
 
120
        self.stubs.Set(rpc, 'cast', rpc_cast_wrapper)
78
121
 
79
122
    def _create_instance(self, params=None):
80
123
        """Create a test instance"""
118
161
                  'project_id': self.project_id}
119
162
        return db.security_group_create(self.context, values)
120
163
 
121
 
    def _get_dummy_instance(self):
122
 
        """Get mock-return-value instance object
123
 
           Use this when any testcase executed later than test_run_terminate
124
 
        """
125
 
        vol1 = models.Volume()
126
 
        vol1['id'] = 1
127
 
        vol2 = models.Volume()
128
 
        vol2['id'] = 2
129
 
        instance_ref = models.Instance()
130
 
        instance_ref['id'] = 1
131
 
        instance_ref['volumes'] = [vol1, vol2]
132
 
        instance_ref['hostname'] = 'hostname-1'
133
 
        instance_ref['host'] = 'dummy'
134
 
        return instance_ref
135
 
 
136
164
    def test_create_instance_defaults_display_name(self):
137
165
        """Verify that an instance cannot be created without a display_name."""
138
166
        cases = [dict(), dict(display_name=None)]
139
167
        for instance in cases:
140
 
            ref = self.compute_api.create(self.context,
 
168
            (ref, resv_id) = self.compute_api.create(self.context,
141
169
                instance_types.get_default_instance_type(), None, **instance)
142
170
            try:
143
171
                self.assertNotEqual(ref[0]['display_name'], None)
147
175
    def test_create_instance_associates_security_groups(self):
148
176
        """Make sure create associates security groups"""
149
177
        group = self._create_group()
150
 
        ref = self.compute_api.create(
 
178
        (ref, resv_id) = self.compute_api.create(
151
179
                self.context,
152
180
                instance_type=instance_types.get_default_instance_type(),
153
181
                image_href=None,
207
235
                 ('<}\x1fh\x10e\x08l\x02l\x05o\x12!{>', 'hello'),
208
236
                 ('hello_server', 'hello-server')]
209
237
        for display_name, hostname in cases:
210
 
            ref = self.compute_api.create(self.context,
 
238
            (ref, resv_id) = self.compute_api.create(self.context,
211
239
                instance_types.get_default_instance_type(), None,
212
240
                display_name=display_name)
213
241
            try:
219
247
        """Make sure destroying disassociates security groups"""
220
248
        group = self._create_group()
221
249
 
222
 
        ref = self.compute_api.create(
 
250
        (ref, resv_id) = self.compute_api.create(
223
251
                self.context,
224
252
                instance_type=instance_types.get_default_instance_type(),
225
253
                image_href=None,
235
263
        """Make sure destroying security groups disassociates instances"""
236
264
        group = self._create_group()
237
265
 
238
 
        ref = self.compute_api.create(
 
266
        (ref, resv_id) = self.compute_api.create(
239
267
                self.context,
240
268
                instance_type=instance_types.get_default_instance_type(),
241
269
                image_href=None,
314
342
        self.compute.resume_instance(self.context, instance_id)
315
343
        self.compute.terminate_instance(self.context, instance_id)
316
344
 
317
 
    def test_reboot(self):
318
 
        """Ensure instance can be rebooted"""
319
 
        instance_id = self._create_instance()
320
 
        self.compute.run_instance(self.context, instance_id)
321
 
        self.compute.reboot_instance(self.context, instance_id)
 
345
    def test_soft_reboot(self):
 
346
        """Ensure instance can be soft rebooted"""
 
347
        instance_id = self._create_instance()
 
348
        reboot_type = "SOFT"
 
349
        self.compute.run_instance(self.context, instance_id)
 
350
        self.compute.reboot_instance(self.context, instance_id, reboot_type)
 
351
        self.compute.terminate_instance(self.context, instance_id)
 
352
 
 
353
    def test_hard_reboot(self):
 
354
        """Ensure instance can be hard rebooted"""
 
355
        instance_id = self._create_instance()
 
356
        reboot_type = "HARD"
 
357
        self.compute.run_instance(self.context, instance_id)
 
358
        self.compute.reboot_instance(self.context, instance_id, reboot_type)
322
359
        self.compute.terminate_instance(self.context, instance_id)
323
360
 
324
361
    def test_set_admin_password(self):
352
389
        self.compute.snapshot_instance(self.context, instance_id, name)
353
390
        self.compute.terminate_instance(self.context, instance_id)
354
391
 
 
392
    def test_snapshot_conflict_backup(self):
 
393
        """Can't backup an instance which is already being backed up."""
 
394
        instance_id = self._create_instance()
 
395
        instance_values = {'task_state': task_states.IMAGE_BACKUP}
 
396
        db.instance_update(self.context, instance_id, instance_values)
 
397
 
 
398
        self.assertRaises(exception.InstanceBackingUp,
 
399
                          self.compute_api.backup,
 
400
                          self.context,
 
401
                          instance_id,
 
402
                          None,
 
403
                          None,
 
404
                          None)
 
405
 
 
406
        db.instance_destroy(self.context, instance_id)
 
407
 
 
408
    def test_snapshot_conflict_snapshot(self):
 
409
        """Can't snapshot an instance which is already being snapshotted."""
 
410
        instance_id = self._create_instance()
 
411
        instance_values = {'task_state': task_states.IMAGE_SNAPSHOT}
 
412
        db.instance_update(self.context, instance_id, instance_values)
 
413
 
 
414
        self.assertRaises(exception.InstanceSnapshotting,
 
415
                          self.compute_api.snapshot,
 
416
                          self.context,
 
417
                          instance_id,
 
418
                          None)
 
419
 
 
420
        db.instance_destroy(self.context, instance_id)
 
421
 
355
422
    def test_console_output(self):
356
423
        """Make sure we can get console output from instance"""
357
424
        instance_id = self._create_instance()
382
449
        self.assert_(console)
383
450
        self.compute.terminate_instance(self.context, instance_id)
384
451
 
 
452
    def test_add_fixed_ip_usage_notification(self):
 
453
        def dummy(*args, **kwargs):
 
454
            pass
 
455
 
 
456
        self.stubs.Set(nova.network.API, 'add_fixed_ip_to_instance',
 
457
                       dummy)
 
458
        self.stubs.Set(nova.compute.manager.ComputeManager,
 
459
                       'inject_network_info', dummy)
 
460
        self.stubs.Set(nova.compute.manager.ComputeManager,
 
461
                       'reset_network', dummy)
 
462
 
 
463
        instance_id = self._create_instance()
 
464
 
 
465
        self.assertEquals(len(test_notifier.NOTIFICATIONS), 0)
 
466
        self.compute.add_fixed_ip_to_instance(self.context,
 
467
                                              instance_id,
 
468
                                              1)
 
469
 
 
470
        self.assertEquals(len(test_notifier.NOTIFICATIONS), 1)
 
471
        self.compute.terminate_instance(self.context, instance_id)
 
472
 
 
473
    def test_remove_fixed_ip_usage_notification(self):
 
474
        def dummy(*args, **kwargs):
 
475
            pass
 
476
 
 
477
        self.stubs.Set(nova.network.API, 'remove_fixed_ip_from_instance',
 
478
                       dummy)
 
479
        self.stubs.Set(nova.compute.manager.ComputeManager,
 
480
                       'inject_network_info', dummy)
 
481
        self.stubs.Set(nova.compute.manager.ComputeManager,
 
482
                       'reset_network', dummy)
 
483
 
 
484
        instance_id = self._create_instance()
 
485
 
 
486
        self.assertEquals(len(test_notifier.NOTIFICATIONS), 0)
 
487
        self.compute.remove_fixed_ip_from_instance(self.context,
 
488
                                              instance_id,
 
489
                                              1)
 
490
 
 
491
        self.assertEquals(len(test_notifier.NOTIFICATIONS), 1)
 
492
        self.compute.terminate_instance(self.context, instance_id)
 
493
 
385
494
    def test_run_instance_usage_notification(self):
386
495
        """Ensure run instance generates apropriate usage notification"""
387
496
        instance_id = self._create_instance()
391
500
        self.assertEquals(msg['priority'], 'INFO')
392
501
        self.assertEquals(msg['event_type'], 'compute.instance.create')
393
502
        payload = msg['payload']
394
 
        self.assertEquals(payload['project_id'], self.project_id)
 
503
        self.assertEquals(payload['tenant_id'], self.project_id)
395
504
        self.assertEquals(payload['user_id'], self.user_id)
396
505
        self.assertEquals(payload['instance_id'], instance_id)
397
506
        self.assertEquals(payload['instance_type'], 'm1.tiny')
410
519
        test_notifier.NOTIFICATIONS = []
411
520
        self.compute.terminate_instance(self.context, instance_id)
412
521
 
413
 
        self.assertEquals(len(test_notifier.NOTIFICATIONS), 1)
 
522
        self.assertEquals(len(test_notifier.NOTIFICATIONS), 2)
414
523
        msg = test_notifier.NOTIFICATIONS[0]
415
524
        self.assertEquals(msg['priority'], 'INFO')
 
525
        self.assertEquals(msg['event_type'], 'compute.instance.exists')
 
526
 
 
527
        msg = test_notifier.NOTIFICATIONS[1]
 
528
        self.assertEquals(msg['priority'], 'INFO')
416
529
        self.assertEquals(msg['event_type'], 'compute.instance.delete')
417
530
        payload = msg['payload']
418
 
        self.assertEquals(payload['project_id'], self.project_id)
 
531
        self.assertEquals(payload['tenant_id'], self.project_id)
419
532
        self.assertEquals(payload['user_id'], self.user_id)
420
533
        self.assertEquals(payload['instance_id'], instance_id)
421
534
        self.assertEquals(payload['instance_type'], 'm1.tiny')
498
611
        self.assertEquals(msg['priority'], 'INFO')
499
612
        self.assertEquals(msg['event_type'], 'compute.instance.resize.prep')
500
613
        payload = msg['payload']
501
 
        self.assertEquals(payload['project_id'], self.project_id)
 
614
        self.assertEquals(payload['tenant_id'], self.project_id)
502
615
        self.assertEquals(payload['user_id'], self.user_id)
503
616
        self.assertEquals(payload['instance_id'], instance_id)
504
617
        self.assertEquals(payload['instance_type'], 'm1.tiny')
573
686
            pass
574
687
 
575
688
        self.stubs.Set(self.compute.driver, 'finish_migration', fake)
576
 
        self.stubs.Set(self.compute.driver, 'revert_migration', fake)
 
689
        self.stubs.Set(self.compute.driver, 'finish_revert_migration', fake)
577
690
        self.stubs.Set(self.compute.network_api, 'get_instance_nw_info', fake)
578
691
 
579
692
        self.compute.run_instance(self.context, instance_id)
646
759
 
647
760
    def test_pre_live_migration_instance_has_no_fixed_ip(self):
648
761
        """Confirm raising exception if instance doesn't have fixed_ip."""
649
 
        instance_ref = self._get_dummy_instance()
 
762
        # creating instance testdata
 
763
        instance_id = self._create_instance({'host': 'dummy'})
650
764
        c = context.get_admin_context()
651
 
        i_id = instance_ref['id']
652
 
 
653
 
        dbmock = self.mox.CreateMock(db)
654
 
        dbmock.instance_get(c, i_id).AndReturn(instance_ref)
655
 
        dbmock.instance_get_fixed_addresses(c, i_id).AndReturn(None)
656
 
 
657
 
        self.compute.db = dbmock
658
 
        self.mox.ReplayAll()
659
 
        self.assertRaises(exception.NotFound,
 
765
        inst_ref = db.instance_get(c, instance_id)
 
766
        topic = db.queue_get_for(c, FLAGS.compute_topic, inst_ref['host'])
 
767
 
 
768
        # start test
 
769
        self.assertRaises(exception.FixedIpNotFoundForInstance,
660
770
                          self.compute.pre_live_migration,
661
 
                          c, instance_ref['id'], time=FakeTime())
 
771
                          c, inst_ref['id'], time=FakeTime())
 
772
        # cleanup
 
773
        db.instance_destroy(c, instance_id)
662
774
 
663
 
    def test_pre_live_migration_instance_has_volume(self):
 
775
    def test_pre_live_migration_works_correctly(self):
664
776
        """Confirm setup_compute_volume is called when volume is mounted."""
665
 
        i_ref = self._get_dummy_instance()
666
 
        c = context.get_admin_context()
667
 
 
668
 
        self._setup_other_managers()
669
 
        dbmock = self.mox.CreateMock(db)
670
 
        volmock = self.mox.CreateMock(self.volume_manager)
671
 
        drivermock = self.mox.CreateMock(self.compute_driver)
672
 
 
673
 
        dbmock.instance_get(c, i_ref['id']).AndReturn(i_ref)
674
 
        dbmock.instance_get_fixed_addresses(c, i_ref['id']).AndReturn('dummy')
675
 
        for i in range(len(i_ref['volumes'])):
676
 
            vid = i_ref['volumes'][i]['id']
677
 
            volmock.setup_compute_volume(c, vid).InAnyOrder('g1')
678
 
        drivermock.plug_vifs(i_ref, [])
679
 
        drivermock.ensure_filtering_rules_for_instance(i_ref, [])
680
 
 
681
 
        self.compute.db = dbmock
682
 
        self.compute.volume_manager = volmock
683
 
        self.compute.driver = drivermock
684
 
 
685
 
        self.mox.ReplayAll()
686
 
        ret = self.compute.pre_live_migration(c, i_ref['id'])
687
 
        self.assertEqual(ret, None)
688
 
 
689
 
    def test_pre_live_migration_instance_has_no_volume(self):
690
 
        """Confirm log meg when instance doesn't mount any volumes."""
691
 
        i_ref = self._get_dummy_instance()
692
 
        i_ref['volumes'] = []
693
 
        c = context.get_admin_context()
694
 
 
695
 
        self._setup_other_managers()
696
 
        dbmock = self.mox.CreateMock(db)
697
 
        drivermock = self.mox.CreateMock(self.compute_driver)
698
 
 
699
 
        dbmock.instance_get(c, i_ref['id']).AndReturn(i_ref)
700
 
        dbmock.instance_get_fixed_addresses(c, i_ref['id']).AndReturn('dummy')
701
 
        self.mox.StubOutWithMock(compute_manager.LOG, 'info')
702
 
        compute_manager.LOG.info(_("%s has no volume."), i_ref['hostname'])
703
 
        drivermock.plug_vifs(i_ref, [])
704
 
        drivermock.ensure_filtering_rules_for_instance(i_ref, [])
705
 
 
706
 
        self.compute.db = dbmock
707
 
        self.compute.driver = drivermock
708
 
 
709
 
        self.mox.ReplayAll()
710
 
        ret = self.compute.pre_live_migration(c, i_ref['id'], time=FakeTime())
711
 
        self.assertEqual(ret, None)
712
 
 
713
 
    def test_pre_live_migration_setup_compute_node_fail(self):
714
 
        """Confirm operation setup_compute_network() fails.
715
 
 
716
 
        It retries and raise exception when timeout exceeded.
717
 
 
718
 
        """
719
 
 
720
 
        i_ref = self._get_dummy_instance()
721
 
        c = context.get_admin_context()
722
 
 
723
 
        self._setup_other_managers()
724
 
        dbmock = self.mox.CreateMock(db)
725
 
        netmock = self.mox.CreateMock(self.network_manager)
726
 
        volmock = self.mox.CreateMock(self.volume_manager)
727
 
        drivermock = self.mox.CreateMock(self.compute_driver)
728
 
 
729
 
        dbmock.instance_get(c, i_ref['id']).AndReturn(i_ref)
730
 
        dbmock.instance_get_fixed_addresses(c, i_ref['id']).AndReturn('dummy')
731
 
        for i in range(len(i_ref['volumes'])):
732
 
            volmock.setup_compute_volume(c, i_ref['volumes'][i]['id'])
733
 
        for i in range(FLAGS.live_migration_retry_count):
734
 
            drivermock.plug_vifs(i_ref, []).\
735
 
                AndRaise(exception.ProcessExecutionError())
736
 
 
737
 
        self.compute.db = dbmock
738
 
        self.compute.network_manager = netmock
739
 
        self.compute.volume_manager = volmock
740
 
        self.compute.driver = drivermock
741
 
 
742
 
        self.mox.ReplayAll()
743
 
        self.assertRaises(exception.ProcessExecutionError,
744
 
                          self.compute.pre_live_migration,
745
 
                          c, i_ref['id'], time=FakeTime())
746
 
 
747
 
    def test_live_migration_works_correctly_with_volume(self):
748
 
        """Confirm check_for_export to confirm volume health check."""
749
 
        i_ref = self._get_dummy_instance()
750
 
        c = context.get_admin_context()
751
 
        topic = db.queue_get_for(c, FLAGS.compute_topic, i_ref['host'])
752
 
 
753
 
        dbmock = self.mox.CreateMock(db)
754
 
        dbmock.instance_get(c, i_ref['id']).AndReturn(i_ref)
755
 
        self.mox.StubOutWithMock(rpc, 'call')
756
 
        rpc.call(c, FLAGS.volume_topic, {"method": "check_for_export",
757
 
                                         "args": {'instance_id': i_ref['id']}})
758
 
        dbmock.queue_get_for(c, FLAGS.compute_topic, i_ref['host']).\
759
 
                             AndReturn(topic)
760
 
        rpc.call(c, topic, {"method": "pre_live_migration",
761
 
                            "args": {'instance_id': i_ref['id'],
762
 
                                     'block_migration': False,
763
 
                                     'disk': None}})
764
 
 
765
 
        self.mox.StubOutWithMock(self.compute.driver, 'live_migration')
766
 
        self.compute.driver.live_migration(c, i_ref, i_ref['host'],
767
 
                                  self.compute.post_live_migration,
768
 
                                  self.compute.rollback_live_migration,
769
 
                                  False)
770
 
 
771
 
        self.compute.db = dbmock
772
 
        self.mox.ReplayAll()
773
 
        ret = self.compute.live_migration(c, i_ref['id'], i_ref['host'])
774
 
        self.assertEqual(ret, None)
 
777
        # creating instance testdata
 
778
        instance_id = self._create_instance({'host': 'dummy'})
 
779
        c = context.get_admin_context()
 
780
        inst_ref = db.instance_get(c, instance_id)
 
781
        topic = db.queue_get_for(c, FLAGS.compute_topic, inst_ref['host'])
 
782
 
 
783
        # creating mocks
 
784
        self.mox.StubOutWithMock(self.compute.driver, 'pre_live_migration')
 
785
        self.compute.driver.pre_live_migration({'block_device_mapping': []})
 
786
        dummy_nw_info = [[None, {'ips':'1.1.1.1'}]]
 
787
        self.mox.StubOutWithMock(self.compute, '_get_instance_nw_info')
 
788
        self.compute._get_instance_nw_info(c, mox.IsA(inst_ref)
 
789
            ).AndReturn(dummy_nw_info)
 
790
        self.mox.StubOutWithMock(self.compute.driver, 'plug_vifs')
 
791
        self.compute.driver.plug_vifs(mox.IsA(inst_ref), dummy_nw_info)
 
792
        self.mox.StubOutWithMock(self.compute.driver,
 
793
                                 'ensure_filtering_rules_for_instance')
 
794
        self.compute.driver.ensure_filtering_rules_for_instance(
 
795
            mox.IsA(inst_ref), dummy_nw_info)
 
796
 
 
797
        # start test
 
798
        self.mox.ReplayAll()
 
799
        ret = self.compute.pre_live_migration(c, inst_ref['id'])
 
800
        self.assertEqual(ret, None)
 
801
 
 
802
        # cleanup
 
803
        db.instance_destroy(c, instance_id)
775
804
 
776
805
    def test_live_migration_dest_raises_exception(self):
777
806
        """Confirm exception when pre_live_migration fails."""
778
 
        i_ref = self._get_dummy_instance()
 
807
        # creating instance testdata
 
808
        instance_id = self._create_instance({'host': 'dummy'})
779
809
        c = context.get_admin_context()
780
 
        topic = db.queue_get_for(c, FLAGS.compute_topic, i_ref['host'])
 
810
        inst_ref = db.instance_get(c, instance_id)
 
811
        topic = db.queue_get_for(c, FLAGS.compute_topic, inst_ref['host'])
 
812
        # creating volume testdata
 
813
        volume_id = 1
 
814
        db.volume_create(c, {'id': volume_id})
 
815
        values = {'instance_id': instance_id, 'device_name': '/dev/vdc',
 
816
            'delete_on_termination': False, 'volume_id': volume_id}
 
817
        db.block_device_mapping_create(c, values)
781
818
 
782
 
        dbmock = self.mox.CreateMock(db)
783
 
        dbmock.instance_get(c, i_ref['id']).AndReturn(i_ref)
 
819
        # creating mocks
784
820
        self.mox.StubOutWithMock(rpc, 'call')
785
821
        rpc.call(c, FLAGS.volume_topic, {"method": "check_for_export",
786
 
                                         "args": {'instance_id': i_ref['id']}})
787
 
        dbmock.queue_get_for(c, FLAGS.compute_topic, i_ref['host']).\
788
 
                             AndReturn(topic)
789
 
        rpc.call(c, topic, {"method": "pre_live_migration",
790
 
                            "args": {'instance_id': i_ref['id'],
791
 
                                     'block_migration': False,
792
 
                                     'disk': None}}).\
793
 
                            AndRaise(rpc.RemoteError('', '', ''))
794
 
        dbmock.instance_update(c, i_ref['id'], {'vm_state': vm_states.ACTIVE,
795
 
                                                'task_state': None,
796
 
                                                'host': i_ref['host']})
797
 
        for v in i_ref['volumes']:
798
 
            dbmock.volume_update(c, v['id'], {'status': 'in-use'})
799
 
            # mock for volume_api.remove_from_compute
800
 
            rpc.call(c, topic, {"method": "remove_volume",
801
 
                                "args": {'volume_id': v['id']}})
802
 
 
803
 
        self.compute.db = dbmock
804
 
        self.mox.ReplayAll()
805
 
        self.assertRaises(rpc.RemoteError,
806
 
                          self.compute.live_migration,
807
 
                          c, i_ref['id'], i_ref['host'])
808
 
 
809
 
    def test_live_migration_dest_raises_exception_no_volume(self):
810
 
        """Same as above test(input pattern is different) """
811
 
        i_ref = self._get_dummy_instance()
812
 
        i_ref['volumes'] = []
813
 
        c = context.get_admin_context()
814
 
        topic = db.queue_get_for(c, FLAGS.compute_topic, i_ref['host'])
815
 
 
816
 
        dbmock = self.mox.CreateMock(db)
817
 
        dbmock.instance_get(c, i_ref['id']).AndReturn(i_ref)
818
 
        dbmock.queue_get_for(c, FLAGS.compute_topic, i_ref['host']).\
819
 
                             AndReturn(topic)
820
 
        self.mox.StubOutWithMock(rpc, 'call')
821
 
        rpc.call(c, topic, {"method": "pre_live_migration",
822
 
                            "args": {'instance_id': i_ref['id'],
823
 
                                     'block_migration': False,
824
 
                                     'disk': None}}).\
825
 
                            AndRaise(rpc.RemoteError('', '', ''))
826
 
        dbmock.instance_update(c, i_ref['id'], {'vm_state': vm_states.ACTIVE,
827
 
                                                'task_state': None,
828
 
                                                'host': i_ref['host']})
829
 
 
830
 
        self.compute.db = dbmock
831
 
        self.mox.ReplayAll()
832
 
        self.assertRaises(rpc.RemoteError,
833
 
                          self.compute.live_migration,
834
 
                          c, i_ref['id'], i_ref['host'])
835
 
 
836
 
    def test_live_migration_works_correctly_no_volume(self):
 
822
                                         "args": {'instance_id': instance_id}})
 
823
        rpc.call(c, topic, {"method": "pre_live_migration",
 
824
                            "args": {'instance_id': instance_id,
 
825
                                     'block_migration': True,
 
826
                                     'disk': None}}).\
 
827
                            AndRaise(rpc.common.RemoteError('', '', ''))
 
828
        # mocks for rollback
 
829
        rpc.call(c, topic, {"method": "remove_volume_connection",
 
830
                            "args": {'instance_id': instance_id,
 
831
                                     'volume_id': volume_id}})
 
832
        rpc.cast(c, topic, {"method": "rollback_live_migration_at_destination",
 
833
                            "args": {'instance_id': inst_ref['id']}})
 
834
 
 
835
        # start test
 
836
        self.mox.ReplayAll()
 
837
        self.assertRaises(rpc.RemoteError,
 
838
                          self.compute.live_migration,
 
839
                          c, instance_id, inst_ref['host'], True)
 
840
 
 
841
        # cleanup
 
842
        for bdms in db.block_device_mapping_get_all_by_instance(c,
 
843
                                                                instance_id):
 
844
            db.block_device_mapping_destroy(c, bdms['id'])
 
845
        db.volume_destroy(c, volume_id)
 
846
        db.instance_destroy(c, instance_id)
 
847
 
 
848
    def test_live_migration_works_correctly(self):
837
849
        """Confirm live_migration() works as expected correctly."""
838
 
        i_ref = self._get_dummy_instance()
839
 
        i_ref['volumes'] = []
 
850
        # creating instance testdata
 
851
        instance_id = self._create_instance({'host': 'dummy'})
840
852
        c = context.get_admin_context()
841
 
        topic = db.queue_get_for(c, FLAGS.compute_topic, i_ref['host'])
 
853
        inst_ref = db.instance_get(c, instance_id)
 
854
        topic = db.queue_get_for(c, FLAGS.compute_topic, inst_ref['host'])
842
855
 
843
 
        dbmock = self.mox.CreateMock(db)
844
 
        dbmock.instance_get(c, i_ref['id']).AndReturn(i_ref)
 
856
        # create
845
857
        self.mox.StubOutWithMock(rpc, 'call')
846
 
        dbmock.queue_get_for(c, FLAGS.compute_topic, i_ref['host']).\
847
 
                             AndReturn(topic)
848
858
        rpc.call(c, topic, {"method": "pre_live_migration",
849
 
                            "args": {'instance_id': i_ref['id'],
 
859
                            "args": {'instance_id': instance_id,
850
860
                                     'block_migration': False,
851
861
                                     'disk': None}})
852
 
        self.mox.StubOutWithMock(self.compute.driver, 'live_migration')
853
 
        self.compute.driver.live_migration(c, i_ref, i_ref['host'],
854
 
                                  self.compute.post_live_migration,
855
 
                                  self.compute.rollback_live_migration,
856
 
                                  False)
857
862
 
858
 
        self.compute.db = dbmock
 
863
        # start test
859
864
        self.mox.ReplayAll()
860
 
        ret = self.compute.live_migration(c, i_ref['id'], i_ref['host'])
 
865
        ret = self.compute.live_migration(c, inst_ref['id'], inst_ref['host'])
861
866
        self.assertEqual(ret, None)
862
867
 
 
868
        # cleanup
 
869
        db.instance_destroy(c, instance_id)
 
870
 
863
871
    def test_post_live_migration_working_correctly(self):
864
872
        """Confirm post_live_migration() works as expected correctly."""
865
873
        dest = 'desthost'
866
874
        flo_addr = '1.2.1.2'
867
875
 
868
 
        # Preparing datas
 
876
        # creating testdata
869
877
        c = context.get_admin_context()
870
 
        instance_id = self._create_instance()
 
878
        instance_id = self._create_instance({'state_description': 'migrating',
 
879
                                             'state': power_state.PAUSED})
871
880
        i_ref = db.instance_get(c, instance_id)
872
881
        db.instance_update(c, i_ref['id'], {'vm_state': vm_states.MIGRATING,
873
882
                                            'power_state': power_state.PAUSED})
877
886
        fix_ref = db.fixed_ip_get_by_address(c, fix_addr)
878
887
        flo_ref = db.floating_ip_create(c, {'address': flo_addr,
879
888
                                        'fixed_ip_id': fix_ref['id']})
880
 
        # reload is necessary before setting mocks
881
 
        i_ref = db.instance_get(c, instance_id)
882
889
 
883
 
        # Preparing mocks
884
 
        self.mox.StubOutWithMock(self.compute.volume_manager,
885
 
                                 'remove_compute_volume')
886
 
        for v in i_ref['volumes']:
887
 
            self.compute.volume_manager.remove_compute_volume(c, v['id'])
 
890
        # creating mocks
888
891
        self.mox.StubOutWithMock(self.compute.driver, 'unfilter_instance')
889
892
        self.compute.driver.unfilter_instance(i_ref, [])
890
893
        self.mox.StubOutWithMock(rpc, 'call')
892
895
            {"method": "post_live_migration_at_destination",
893
896
             "args": {'instance_id': i_ref['id'], 'block_migration': False}})
894
897
 
895
 
        # executing
 
898
        # start test
896
899
        self.mox.ReplayAll()
897
900
        ret = self.compute.post_live_migration(c, i_ref, dest)
898
901
 
899
 
        # make sure every data is rewritten to dest
 
902
        # make sure every data is rewritten to destinatioin hostname.
900
903
        i_ref = db.instance_get(c, i_ref['id'])
901
904
        c1 = (i_ref['host'] == dest)
902
905
        flo_refs = db.floating_ip_get_all_by_host(c, dest)
903
906
        c2 = (len(flo_refs) != 0 and flo_refs[0]['address'] == flo_addr)
904
 
 
905
 
        # post operaton
906
907
        self.assertTrue(c1 and c2)
 
908
 
 
909
        # cleanup
907
910
        db.instance_destroy(c, instance_id)
908
911
        db.volume_destroy(c, v_ref['id'])
909
912
        db.floating_ip_destroy(c, flo_addr)
1007
1010
        db.instance_destroy(c, instance_id2)
1008
1011
        db.instance_destroy(c, instance_id3)
1009
1012
 
1010
 
    def test_get_by_fixed_ip(self):
1011
 
        """Test getting 1 instance by Fixed IP"""
1012
 
        c = context.get_admin_context()
1013
 
        instance_id1 = self._create_instance()
1014
 
        instance_id2 = self._create_instance({'id': 20})
1015
 
        instance_id3 = self._create_instance({'id': 30})
1016
 
 
1017
 
        vif_ref1 = db.virtual_interface_create(c,
1018
 
                {'address': '12:34:56:78:90:12',
1019
 
                 'instance_id': instance_id1,
1020
 
                 'network_id': 1})
1021
 
        vif_ref2 = db.virtual_interface_create(c,
1022
 
                {'address': '90:12:34:56:78:90',
1023
 
                 'instance_id': instance_id2,
1024
 
                 'network_id': 1})
1025
 
 
1026
 
        db.fixed_ip_create(c,
1027
 
                {'address': '1.1.1.1',
1028
 
                 'instance_id': instance_id1,
1029
 
                 'virtual_interface_id': vif_ref1['id']})
1030
 
        db.fixed_ip_create(c,
1031
 
                {'address': '1.1.2.1',
1032
 
                 'instance_id': instance_id2,
1033
 
                 'virtual_interface_id': vif_ref2['id']})
1034
 
 
1035
 
        # regex not allowed
1036
 
        instances = self.compute_api.get_all(c,
1037
 
                search_opts={'fixed_ip': '.*'})
1038
 
        self.assertEqual(len(instances), 0)
1039
 
 
1040
 
        instances = self.compute_api.get_all(c,
1041
 
                search_opts={'fixed_ip': '1.1.3.1'})
1042
 
        self.assertEqual(len(instances), 0)
1043
 
 
1044
 
        instances = self.compute_api.get_all(c,
1045
 
                search_opts={'fixed_ip': '1.1.1.1'})
1046
 
        self.assertEqual(len(instances), 1)
1047
 
        self.assertEqual(instances[0].id, instance_id1)
1048
 
 
1049
 
        instances = self.compute_api.get_all(c,
1050
 
                search_opts={'fixed_ip': '1.1.2.1'})
1051
 
        self.assertEqual(len(instances), 1)
1052
 
        self.assertEqual(instances[0].id, instance_id2)
1053
 
 
1054
 
        db.virtual_interface_delete(c, vif_ref1['id'])
1055
 
        db.virtual_interface_delete(c, vif_ref2['id'])
1056
 
        db.instance_destroy(c, instance_id1)
1057
 
        db.instance_destroy(c, instance_id2)
1058
 
 
1059
 
    def test_get_all_by_ip_regexp(self):
1060
 
        """Test searching by Floating and Fixed IP"""
1061
 
        c = context.get_admin_context()
1062
 
        instance_id1 = self._create_instance({'display_name': 'woot'})
1063
 
        instance_id2 = self._create_instance({
1064
 
                'display_name': 'woo',
1065
 
                'id': 20})
1066
 
        instance_id3 = self._create_instance({
1067
 
                'display_name': 'not-woot',
1068
 
                'id': 30})
1069
 
 
1070
 
        vif_ref1 = db.virtual_interface_create(c,
1071
 
                {'address': '12:34:56:78:90:12',
1072
 
                 'instance_id': instance_id1,
1073
 
                 'network_id': 1})
1074
 
        vif_ref2 = db.virtual_interface_create(c,
1075
 
                {'address': '90:12:34:56:78:90',
1076
 
                 'instance_id': instance_id2,
1077
 
                 'network_id': 1})
1078
 
        vif_ref3 = db.virtual_interface_create(c,
1079
 
                {'address': '34:56:78:90:12:34',
1080
 
                 'instance_id': instance_id3,
1081
 
                 'network_id': 1})
1082
 
 
1083
 
        db.fixed_ip_create(c,
1084
 
                {'address': '1.1.1.1',
1085
 
                 'instance_id': instance_id1,
1086
 
                 'virtual_interface_id': vif_ref1['id']})
1087
 
        db.fixed_ip_create(c,
1088
 
                {'address': '1.1.2.1',
1089
 
                 'instance_id': instance_id2,
1090
 
                 'virtual_interface_id': vif_ref2['id']})
1091
 
        fix_addr = db.fixed_ip_create(c,
1092
 
                {'address': '1.1.3.1',
1093
 
                 'instance_id': instance_id3,
1094
 
                 'virtual_interface_id': vif_ref3['id']})
1095
 
        fix_ref = db.fixed_ip_get_by_address(c, fix_addr)
1096
 
        flo_ref = db.floating_ip_create(c,
1097
 
                {'address': '10.0.0.2',
1098
 
                'fixed_ip_id': fix_ref['id']})
1099
 
 
1100
 
        # ends up matching 2nd octet here.. so all 3 match
1101
 
        instances = self.compute_api.get_all(c,
1102
 
                search_opts={'ip': '.*\.1'})
1103
 
        self.assertEqual(len(instances), 3)
1104
 
 
1105
 
        instances = self.compute_api.get_all(c,
1106
 
                search_opts={'ip': '1.*'})
1107
 
        self.assertEqual(len(instances), 3)
1108
 
 
1109
 
        instances = self.compute_api.get_all(c,
1110
 
                search_opts={'ip': '.*\.1.\d+$'})
1111
 
        self.assertEqual(len(instances), 1)
1112
 
        instance_ids = [instance.id for instance in instances]
1113
 
        self.assertTrue(instance_id1 in instance_ids)
1114
 
 
1115
 
        instances = self.compute_api.get_all(c,
1116
 
                search_opts={'ip': '.*\.2.+'})
1117
 
        self.assertEqual(len(instances), 1)
1118
 
        self.assertEqual(instances[0].id, instance_id2)
1119
 
 
1120
 
        instances = self.compute_api.get_all(c,
1121
 
                search_opts={'ip': '10.*'})
1122
 
        self.assertEqual(len(instances), 1)
1123
 
        self.assertEqual(instances[0].id, instance_id3)
1124
 
 
1125
 
        db.virtual_interface_delete(c, vif_ref1['id'])
1126
 
        db.virtual_interface_delete(c, vif_ref2['id'])
1127
 
        db.virtual_interface_delete(c, vif_ref3['id'])
1128
 
        db.floating_ip_destroy(c, '10.0.0.2')
1129
 
        db.instance_destroy(c, instance_id1)
1130
 
        db.instance_destroy(c, instance_id2)
1131
 
        db.instance_destroy(c, instance_id3)
1132
 
 
1133
 
    def test_get_all_by_ipv6_regexp(self):
1134
 
        """Test searching by IPv6 address"""
1135
 
 
1136
 
        c = context.get_admin_context()
1137
 
        instance_id1 = self._create_instance({'display_name': 'woot'})
1138
 
        instance_id2 = self._create_instance({
1139
 
                'display_name': 'woo',
1140
 
                'id': 20})
1141
 
        instance_id3 = self._create_instance({
1142
 
                'display_name': 'not-woot',
1143
 
                'id': 30})
1144
 
 
1145
 
        vif_ref1 = db.virtual_interface_create(c,
1146
 
                {'address': '12:34:56:78:90:12',
1147
 
                 'instance_id': instance_id1,
1148
 
                 'network_id': 1})
1149
 
        vif_ref2 = db.virtual_interface_create(c,
1150
 
                {'address': '90:12:34:56:78:90',
1151
 
                 'instance_id': instance_id2,
1152
 
                 'network_id': 1})
1153
 
        vif_ref3 = db.virtual_interface_create(c,
1154
 
                {'address': '34:56:78:90:12:34',
1155
 
                 'instance_id': instance_id3,
1156
 
                 'network_id': 1})
1157
 
 
1158
 
        # This will create IPv6 addresses of:
1159
 
        # 1: fd00::1034:56ff:fe78:9012
1160
 
        # 20: fd00::9212:34ff:fe56:7890
1161
 
        # 30: fd00::3656:78ff:fe90:1234
1162
 
 
1163
 
        instances = self.compute_api.get_all(c,
1164
 
                search_opts={'ip6': '.*1034.*'})
1165
 
        self.assertEqual(len(instances), 1)
1166
 
        self.assertEqual(instances[0].id, instance_id1)
1167
 
 
1168
 
        instances = self.compute_api.get_all(c,
1169
 
                search_opts={'ip6': '^fd00.*'})
1170
 
        self.assertEqual(len(instances), 3)
1171
 
        instance_ids = [instance.id for instance in instances]
1172
 
        self.assertTrue(instance_id1 in instance_ids)
1173
 
        self.assertTrue(instance_id2 in instance_ids)
1174
 
        self.assertTrue(instance_id3 in instance_ids)
1175
 
 
1176
 
        instances = self.compute_api.get_all(c,
1177
 
                search_opts={'ip6': '^.*12.*34.*'})
1178
 
        self.assertEqual(len(instances), 2)
1179
 
        instance_ids = [instance.id for instance in instances]
1180
 
        self.assertTrue(instance_id2 in instance_ids)
1181
 
        self.assertTrue(instance_id3 in instance_ids)
1182
 
 
1183
 
        db.virtual_interface_delete(c, vif_ref1['id'])
1184
 
        db.virtual_interface_delete(c, vif_ref2['id'])
1185
 
        db.virtual_interface_delete(c, vif_ref3['id'])
1186
 
        db.instance_destroy(c, instance_id1)
1187
 
        db.instance_destroy(c, instance_id2)
1188
 
        db.instance_destroy(c, instance_id3)
1189
 
 
1190
1013
    def test_get_all_by_multiple_options_at_once(self):
1191
1014
        """Test searching by multiple options at once"""
1192
1015
        c = context.get_admin_context()
1193
 
        instance_id1 = self._create_instance({'display_name': 'woot'})
 
1016
        network_manager = fake_network.FakeNetworkManager()
 
1017
        self.stubs.Set(self.compute_api.network_api,
 
1018
                       'get_instance_uuids_by_ip_filter',
 
1019
                       network_manager.get_instance_uuids_by_ip_filter)
 
1020
        self.stubs.Set(network_manager.db,
 
1021
                       'instance_get_id_to_uuid_mapping',
 
1022
                       db.instance_get_id_to_uuid_mapping)
 
1023
 
 
1024
        instance_id1 = self._create_instance({'display_name': 'woot',
 
1025
                                              'id': 0})
1194
1026
        instance_id2 = self._create_instance({
1195
1027
                'display_name': 'woo',
1196
1028
                'id': 20})
1198
1030
                'display_name': 'not-woot',
1199
1031
                'id': 30})
1200
1032
 
1201
 
        vif_ref1 = db.virtual_interface_create(c,
1202
 
                {'address': '12:34:56:78:90:12',
1203
 
                 'instance_id': instance_id1,
1204
 
                 'network_id': 1})
1205
 
        vif_ref2 = db.virtual_interface_create(c,
1206
 
                {'address': '90:12:34:56:78:90',
1207
 
                 'instance_id': instance_id2,
1208
 
                 'network_id': 1})
1209
 
        vif_ref3 = db.virtual_interface_create(c,
1210
 
                {'address': '34:56:78:90:12:34',
1211
 
                 'instance_id': instance_id3,
1212
 
                 'network_id': 1})
1213
 
 
1214
 
        db.fixed_ip_create(c,
1215
 
                {'address': '1.1.1.1',
1216
 
                 'instance_id': instance_id1,
1217
 
                 'virtual_interface_id': vif_ref1['id']})
1218
 
        db.fixed_ip_create(c,
1219
 
                {'address': '1.1.2.1',
1220
 
                 'instance_id': instance_id2,
1221
 
                 'virtual_interface_id': vif_ref2['id']})
1222
 
        fix_addr = db.fixed_ip_create(c,
1223
 
                {'address': '1.1.3.1',
1224
 
                 'instance_id': instance_id3,
1225
 
                 'virtual_interface_id': vif_ref3['id']})
1226
 
        fix_ref = db.fixed_ip_get_by_address(c, fix_addr)
1227
 
        flo_ref = db.floating_ip_create(c,
1228
 
                {'address': '10.0.0.2',
1229
 
                'fixed_ip_id': fix_ref['id']})
1230
 
 
1231
1033
        # ip ends up matching 2nd octet here.. so all 3 match ip
1232
1034
        # but 'name' only matches one
1233
1035
        instances = self.compute_api.get_all(c,
1235
1037
        self.assertEqual(len(instances), 1)
1236
1038
        self.assertEqual(instances[0].id, instance_id3)
1237
1039
 
1238
 
        # ip ends up matching any ip with a '2' in it.. so instance
1239
 
        # 2 and 3.. but name should only match #2
 
1040
        # ip ends up matching any ip with a '1' in the last octet..
 
1041
        # so instance 1 and 3.. but name should only match #1
1240
1042
        # but 'name' only matches one
1241
1043
        instances = self.compute_api.get_all(c,
1242
 
                search_opts={'ip': '.*2', 'name': '^woo.*'})
 
1044
                search_opts={'ip': '.*\.1$', 'name': '^woo.*'})
1243
1045
        self.assertEqual(len(instances), 1)
1244
 
        self.assertEqual(instances[0].id, instance_id2)
 
1046
        self.assertEqual(instances[0].id, instance_id1)
1245
1047
 
1246
1048
        # same as above but no match on name (name matches instance_id1
1247
1049
        # but the ip query doesn't
1248
1050
        instances = self.compute_api.get_all(c,
1249
 
                search_opts={'ip': '.*2.*', 'name': '^woot.*'})
 
1051
                search_opts={'ip': '.*\.2$', 'name': '^woot.*'})
1250
1052
        self.assertEqual(len(instances), 0)
1251
1053
 
1252
1054
        # ip matches all 3... ipv6 matches #2+#3...name matches #3
1257
1059
        self.assertEqual(len(instances), 1)
1258
1060
        self.assertEqual(instances[0].id, instance_id3)
1259
1061
 
1260
 
        db.virtual_interface_delete(c, vif_ref1['id'])
1261
 
        db.virtual_interface_delete(c, vif_ref2['id'])
1262
 
        db.virtual_interface_delete(c, vif_ref3['id'])
1263
 
        db.floating_ip_destroy(c, '10.0.0.2')
1264
1062
        db.instance_destroy(c, instance_id1)
1265
1063
        db.instance_destroy(c, instance_id2)
1266
1064
        db.instance_destroy(c, instance_id3)
1581
1379
        self.assertEqual(self.compute_api._volume_size(inst_type,
1582
1380
                                                       'swap'),
1583
1381
                         swap_size)
 
1382
 
 
1383
    def test_reservation_id_one_instance(self):
 
1384
        """Verify building an instance has a reservation_id that
 
1385
        matches return value from create"""
 
1386
        (refs, resv_id) = self.compute_api.create(self.context,
 
1387
                instance_types.get_default_instance_type(), None)
 
1388
        try:
 
1389
            self.assertEqual(len(refs), 1)
 
1390
            self.assertEqual(refs[0]['reservation_id'], resv_id)
 
1391
        finally:
 
1392
            db.instance_destroy(self.context, refs[0]['id'])
 
1393
 
 
1394
    def test_reservation_ids_two_instances(self):
 
1395
        """Verify building 2 instances at once results in a
 
1396
        reservation_id being returned equal to reservation id set
 
1397
        in both instances
 
1398
        """
 
1399
        (refs, resv_id) = self.compute_api.create(self.context,
 
1400
                instance_types.get_default_instance_type(), None,
 
1401
                min_count=2, max_count=2)
 
1402
        try:
 
1403
            self.assertEqual(len(refs), 2)
 
1404
            self.assertNotEqual(resv_id, None)
 
1405
        finally:
 
1406
            for instance in refs:
 
1407
                self.assertEqual(instance['reservation_id'], resv_id)
 
1408
                db.instance_destroy(self.context, instance['id'])
 
1409
 
 
1410
    def test_reservation_ids_two_instances_no_wait(self):
 
1411
        """Verify building 2 instances at once without waiting for
 
1412
        instance IDs results in a reservation_id being returned equal
 
1413
        to reservation id set in both instances
 
1414
        """
 
1415
        (refs, resv_id) = self.compute_api.create(self.context,
 
1416
                instance_types.get_default_instance_type(), None,
 
1417
                min_count=2, max_count=2, wait_for_instances=False)
 
1418
        try:
 
1419
            self.assertEqual(refs, None)
 
1420
            self.assertNotEqual(resv_id, None)
 
1421
        finally:
 
1422
            instances = self.compute_api.get_all(self.context,
 
1423
                    search_opts={'reservation_id': resv_id})
 
1424
            self.assertEqual(len(instances), 2)
 
1425
            for instance in instances:
 
1426
                self.assertEqual(instance['reservation_id'], resv_id)
 
1427
                db.instance_destroy(self.context, instance['id'])
 
1428
 
 
1429
    def test_create_with_specified_reservation_id(self):
 
1430
        """Verify building instances with a specified
 
1431
        reservation_id results in the correct reservation_id
 
1432
        being set
 
1433
        """
 
1434
 
 
1435
        # We need admin context to be able to specify our own
 
1436
        # reservation_ids.
 
1437
        context = self.context.elevated()
 
1438
        # 1 instance
 
1439
        (refs, resv_id) = self.compute_api.create(context,
 
1440
                instance_types.get_default_instance_type(), None,
 
1441
                min_count=1, max_count=1, reservation_id='meow')
 
1442
        try:
 
1443
            self.assertEqual(len(refs), 1)
 
1444
            self.assertEqual(resv_id, 'meow')
 
1445
        finally:
 
1446
            self.assertEqual(refs[0]['reservation_id'], resv_id)
 
1447
            db.instance_destroy(self.context, refs[0]['id'])
 
1448
 
 
1449
        # 2 instances
 
1450
        (refs, resv_id) = self.compute_api.create(context,
 
1451
                instance_types.get_default_instance_type(), None,
 
1452
                min_count=2, max_count=2, reservation_id='woof')
 
1453
        try:
 
1454
            self.assertEqual(len(refs), 2)
 
1455
            self.assertEqual(resv_id, 'woof')
 
1456
        finally:
 
1457
            for instance in refs:
 
1458
                self.assertEqual(instance['reservation_id'], resv_id)
 
1459
                db.instance_destroy(self.context, instance['id'])
 
1460
 
 
1461
    def test_instance_name_template(self):
 
1462
        """Test the instance_name template"""
 
1463
        self.flags(instance_name_template='instance-%d')
 
1464
        instance_id = self._create_instance()
 
1465
        i_ref = db.instance_get(self.context, instance_id)
 
1466
        self.assertEqual(i_ref['name'], 'instance-%d' % i_ref['id'])
 
1467
        db.instance_destroy(self.context, i_ref['id'])
 
1468
 
 
1469
        self.flags(instance_name_template='instance-%(uuid)s')
 
1470
        instance_id = self._create_instance()
 
1471
        i_ref = db.instance_get(self.context, instance_id)
 
1472
        self.assertEqual(i_ref['name'], 'instance-%s' % i_ref['uuid'])
 
1473
        db.instance_destroy(self.context, i_ref['id'])
 
1474
 
 
1475
        self.flags(instance_name_template='%(id)d-%(uuid)s')
 
1476
        instance_id = self._create_instance()
 
1477
        i_ref = db.instance_get(self.context, instance_id)
 
1478
        self.assertEqual(i_ref['name'], '%d-%s' %
 
1479
                (i_ref['id'], i_ref['uuid']))
 
1480
        db.instance_destroy(self.context, i_ref['id'])
 
1481
 
 
1482
        # not allowed.. default is uuid
 
1483
        self.flags(instance_name_template='%(name)s')
 
1484
        instance_id = self._create_instance()
 
1485
        i_ref = db.instance_get(self.context, instance_id)
 
1486
        self.assertEqual(i_ref['name'], i_ref['uuid'])
 
1487
        db.instance_destroy(self.context, i_ref['id'])
 
1488
 
 
1489
 
 
1490
class ComputeTestMinRamMinDisk(test.TestCase):
 
1491
    def setUp(self):
 
1492
        super(ComputeTestMinRamMinDisk, self).setUp()
 
1493
        self.compute = utils.import_object(FLAGS.compute_manager)
 
1494
        self.compute_api = compute.API()
 
1495
        self.context = context.RequestContext('fake', 'fake')
 
1496
        self.stubs.Set(rpc, 'call', rpc_call_wrapper)
 
1497
        self.stubs.Set(rpc, 'cast', rpc_cast_wrapper)
 
1498
        self.fake_image = {
 
1499
            'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1}}
 
1500
 
 
1501
    def test_create_with_too_little_ram(self):
 
1502
        """Test an instance type with too little memory"""
 
1503
 
 
1504
        inst_type = instance_types.get_default_instance_type()
 
1505
        inst_type['memory_mb'] = 1
 
1506
 
 
1507
        def fake_show(*args):
 
1508
            img = copy(self.fake_image)
 
1509
            img['min_ram'] = 2
 
1510
            return img
 
1511
        self.stubs.Set(fake_image._FakeImageService, 'show', fake_show)
 
1512
 
 
1513
        self.assertRaises(exception.InstanceTypeMemoryTooSmall,
 
1514
            self.compute_api.create, self.context, inst_type, None)
 
1515
 
 
1516
        # Now increase the inst_type memory and make sure all is fine.
 
1517
        inst_type['memory_mb'] = 2
 
1518
        (refs, resv_id) = self.compute_api.create(self.context,
 
1519
                inst_type, None)
 
1520
        db.instance_destroy(self.context, refs[0]['id'])
 
1521
 
 
1522
    def test_create_with_too_little_disk(self):
 
1523
        """Test an instance type with too little disk space"""
 
1524
 
 
1525
        inst_type = instance_types.get_default_instance_type()
 
1526
        inst_type['local_gb'] = 1
 
1527
 
 
1528
        def fake_show(*args):
 
1529
            img = copy(self.fake_image)
 
1530
            img['min_disk'] = 2
 
1531
            return img
 
1532
        self.stubs.Set(fake_image._FakeImageService, 'show', fake_show)
 
1533
 
 
1534
        self.assertRaises(exception.InstanceTypeDiskTooSmall,
 
1535
            self.compute_api.create, self.context, inst_type, None)
 
1536
 
 
1537
        # Now increase the inst_type disk space and make sure all is fine.
 
1538
        inst_type['local_gb'] = 2
 
1539
        (refs, resv_id) = self.compute_api.create(self.context,
 
1540
                inst_type, None)
 
1541
        db.instance_destroy(self.context, refs[0]['id'])
 
1542
 
 
1543
    def test_create_just_enough_ram_and_disk(self):
 
1544
        """Test an instance type with just enough ram and disk space"""
 
1545
 
 
1546
        inst_type = instance_types.get_default_instance_type()
 
1547
        inst_type['local_gb'] = 2
 
1548
        inst_type['memory_mb'] = 2
 
1549
 
 
1550
        def fake_show(*args):
 
1551
            img = copy(self.fake_image)
 
1552
            img['min_ram'] = 2
 
1553
            img['min_disk'] = 2
 
1554
            return img
 
1555
        self.stubs.Set(fake_image._FakeImageService, 'show', fake_show)
 
1556
 
 
1557
        (refs, resv_id) = self.compute_api.create(self.context,
 
1558
                inst_type, None)
 
1559
        db.instance_destroy(self.context, refs[0]['id'])
 
1560
 
 
1561
    def test_create_with_no_ram_and_disk_reqs(self):
 
1562
        """Test an instance type with no min_ram or min_disk"""
 
1563
 
 
1564
        inst_type = instance_types.get_default_instance_type()
 
1565
        inst_type['local_gb'] = 1
 
1566
        inst_type['memory_mb'] = 1
 
1567
 
 
1568
        def fake_show(*args):
 
1569
            return copy(self.fake_image)
 
1570
        self.stubs.Set(fake_image._FakeImageService, 'show', fake_show)
 
1571
 
 
1572
        (refs, resv_id) = self.compute_api.create(self.context,
 
1573
                inst_type, None)
 
1574
        db.instance_destroy(self.context, refs[0]['id'])