~ubuntu-branches/ubuntu/vivid/ironic/vivid-updates

« back to all changes in this revision

Viewing changes to ironic/tests/drivers/test_iscsi_deploy.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2015-04-17 09:28:31 UTC
  • mfrom: (1.2.7)
  • Revision ID: package-import@ubuntu.com-20150417092831-wu2awfbqomnzpeim
Tags: 2015.1~rc1-0ubuntu1
* New upstream milestone release:
  - d/control: Align with upstream dependencies
  - d/p/fix-requirements.patch: Dropped no longer needed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
429
429
                         'ironic_api_url': api_url,
430
430
                         'boot_option': expected_boot_option,
431
431
                         'boot_mode': expected_boot_mode,
 
432
                         'coreos.configdrive': 0,
432
433
                        }
433
434
 
434
435
        if expected_root_device:
486
487
        self._test_build_deploy_ramdisk_options(mock_alnum, fake_api_url,
487
488
                                                expected_boot_option=expected)
488
489
 
 
490
    @mock.patch.object(keystone, 'get_service_url', autospec=True)
 
491
    @mock.patch.object(utils, 'random_alnum', autospec=True)
 
492
    def test_build_deploy_ramdisk_options_whole_disk_image(self, mock_alnum,
 
493
                                                           mock_get_url):
 
494
        """Tests a hack to boot_option for whole disk images.
 
495
 
 
496
        This hack is in place to fix bug #1441556.
 
497
        """
 
498
        self.node.instance_info = {'capabilities': '{"boot_option": "local"}'}
 
499
        dii = self.node.driver_internal_info
 
500
        dii['is_whole_disk_image'] = True
 
501
        self.node.driver_internal_info = dii
 
502
        self.node.save()
 
503
        expected = 'netboot'
 
504
        fake_api_url = 'http://127.0.0.1:6385'
 
505
        self.config(api_url=fake_api_url, group='conductor')
 
506
        self._test_build_deploy_ramdisk_options(mock_alnum, fake_api_url,
 
507
                                                expected_boot_option=expected)
 
508
 
489
509
    def test_get_boot_option(self):
490
510
        self.node.instance_info = {'capabilities': '{"boot_option": "local"}'}
491
511
        result = iscsi_deploy.get_boot_option(self.node)
511
531
        with task_manager.acquire(self.context, self.node.uuid,
512
532
                                  shared=False) as task:
513
533
            params = iscsi_deploy.get_deploy_info(task.node, **kwargs)
514
 
            iscsi_deploy.continue_deploy(task, **kwargs)
 
534
            self.assertRaises(exception.InstanceDeployFailure,
 
535
                              iscsi_deploy.continue_deploy,
 
536
                              task, **kwargs)
515
537
            self.assertEqual(states.DEPLOYFAIL, task.node.provision_state)
516
538
            self.assertEqual(states.ACTIVE, task.node.target_provision_state)
517
539
            self.assertIsNotNone(task.node.last_error)
533
555
 
534
556
        with task_manager.acquire(self.context, self.node.uuid,
535
557
                                  shared=False) as task:
536
 
            retval = iscsi_deploy.continue_deploy(task, **kwargs)
 
558
            self.assertRaises(exception.InstanceDeployFailure,
 
559
                              iscsi_deploy.continue_deploy,
 
560
                              task, **kwargs)
537
561
            self.assertIsNotNone(task.node.last_error)
538
562
            self.assertEqual(states.DEPLOYFAIL, task.node.provision_state)
539
563
            self.assertEqual(states.ACTIVE, task.node.target_provision_state)
541
565
            mock_image_cache.assert_called_once_with()
542
566
            mock_image_cache.return_value.clean_up.assert_called_once_with()
543
567
            self.assertFalse(deploy_mock.called)
544
 
            self.assertEqual({}, retval)
 
568
 
 
569
    @mock.patch.object(iscsi_deploy, 'InstanceImageCache')
 
570
    @mock.patch.object(manager_utils, 'node_power_action')
 
571
    @mock.patch.object(deploy_utils, 'deploy_partition_image')
 
572
    def test_continue_deploy_fail_no_root_uuid_or_disk_id(
 
573
            self, deploy_mock, power_mock, mock_image_cache):
 
574
        kwargs = {'address': '123456', 'iqn': 'aaa-bbb', 'key': 'fake-56789'}
 
575
        deploy_mock.return_value = {}
 
576
        self.node.provision_state = states.DEPLOYWAIT
 
577
        self.node.target_provision_state = states.ACTIVE
 
578
        self.node.save()
 
579
 
 
580
        with task_manager.acquire(self.context, self.node.uuid,
 
581
                                  shared=False) as task:
 
582
            params = iscsi_deploy.get_deploy_info(task.node, **kwargs)
 
583
            self.assertRaises(exception.InstanceDeployFailure,
 
584
                              iscsi_deploy.continue_deploy,
 
585
                              task, **kwargs)
 
586
            self.assertEqual(states.DEPLOYFAIL, task.node.provision_state)
 
587
            self.assertEqual(states.ACTIVE, task.node.target_provision_state)
 
588
            self.assertIsNotNone(task.node.last_error)
 
589
            deploy_mock.assert_called_once_with(**params)
 
590
            power_mock.assert_called_once_with(task, states.POWER_OFF)
 
591
            mock_image_cache.assert_called_once_with()
 
592
            mock_image_cache.return_value.clean_up.assert_called_once_with()
 
593
 
 
594
    @mock.patch.object(iscsi_deploy, 'InstanceImageCache')
 
595
    @mock.patch.object(manager_utils, 'node_power_action')
 
596
    @mock.patch.object(deploy_utils, 'deploy_partition_image')
 
597
    def test_continue_deploy_fail_empty_root_uuid(
 
598
            self, deploy_mock, power_mock, mock_image_cache):
 
599
        kwargs = {'address': '123456', 'iqn': 'aaa-bbb', 'key': 'fake-56789'}
 
600
        deploy_mock.return_value = {'root uuid': ''}
 
601
        self.node.provision_state = states.DEPLOYWAIT
 
602
        self.node.target_provision_state = states.ACTIVE
 
603
        self.node.save()
 
604
 
 
605
        with task_manager.acquire(self.context, self.node.uuid,
 
606
                                  shared=False) as task:
 
607
            params = iscsi_deploy.get_deploy_info(task.node, **kwargs)
 
608
            self.assertRaises(exception.InstanceDeployFailure,
 
609
                              iscsi_deploy.continue_deploy,
 
610
                              task, **kwargs)
 
611
            self.assertEqual(states.DEPLOYFAIL, task.node.provision_state)
 
612
            self.assertEqual(states.ACTIVE, task.node.target_provision_state)
 
613
            self.assertIsNotNone(task.node.last_error)
 
614
            deploy_mock.assert_called_once_with(**params)
 
615
            power_mock.assert_called_once_with(task, states.POWER_OFF)
 
616
            mock_image_cache.assert_called_once_with()
 
617
            mock_image_cache.return_value.clean_up.assert_called_once_with()
545
618
 
546
619
    @mock.patch.object(iscsi_deploy, 'LOG')
547
620
    @mock.patch.object(iscsi_deploy, 'get_deploy_info')
725
798
            self.assertEqual(states.ACTIVE, self.node.target_provision_state)
726
799
            self.assertIsNotNone(self.node.last_error)
727
800
 
728
 
    @mock.patch.object(iscsi_deploy, 'continue_deploy')
729
 
    @mock.patch.object(iscsi_deploy, 'build_deploy_ramdisk_options')
730
 
    def test_do_agent_iscsi_deploy_no_root_uuid(self, build_options_mock,
731
 
                                                continue_deploy_mock):
732
 
        build_options_mock.return_value = {'deployment_key': 'abcdef',
733
 
                                           'iscsi_target_iqn': 'iqn-qweqwe'}
734
 
        agent_client_mock = mock.MagicMock()
735
 
        agent_client_mock.start_iscsi_target.return_value = {
736
 
            'command_status': 'SUCCESS', 'command_error': None}
737
 
        driver_internal_info = {'agent_url': 'http://1.2.3.4:1234'}
738
 
        self.node.driver_internal_info = driver_internal_info
 
801
    def test_validate_pass_bootloader_info_input(self):
 
802
        params = {'key': 'some-random-key', 'address': '1.2.3.4',
 
803
                  'error': '', 'status': 'SUCCEEDED'}
 
804
        with task_manager.acquire(self.context, self.node.uuid,
 
805
                                  shared=False) as task:
 
806
            task.node.instance_info['deploy_key'] = 'some-random-key'
 
807
            # Assert that the method doesn't raise
 
808
            iscsi_deploy.validate_pass_bootloader_info_input(task, params)
 
809
 
 
810
    def test_validate_pass_bootloader_info_missing_status(self):
 
811
        params = {'key': 'some-random-key', 'address': '1.2.3.4'}
 
812
        with task_manager.acquire(self.context, self.node.uuid,
 
813
                                  shared=False) as task:
 
814
            self.assertRaises(exception.MissingParameterValue,
 
815
                              iscsi_deploy.validate_pass_bootloader_info_input,
 
816
                              task, params)
 
817
 
 
818
    def test_validate_pass_bootloader_info_missing_key(self):
 
819
        params = {'status': 'SUCCEEDED', 'address': '1.2.3.4'}
 
820
        with task_manager.acquire(self.context, self.node.uuid,
 
821
                                  shared=False) as task:
 
822
            self.assertRaises(exception.MissingParameterValue,
 
823
                              iscsi_deploy.validate_pass_bootloader_info_input,
 
824
                              task, params)
 
825
 
 
826
    def test_validate_pass_bootloader_info_missing_address(self):
 
827
        params = {'status': 'SUCCEEDED', 'key': 'some-random-key'}
 
828
        with task_manager.acquire(self.context, self.node.uuid,
 
829
                                  shared=False) as task:
 
830
            self.assertRaises(exception.MissingParameterValue,
 
831
                              iscsi_deploy.validate_pass_bootloader_info_input,
 
832
                              task, params)
 
833
 
 
834
    def test_validate_pass_bootloader_info_input_invalid_key(self):
 
835
        params = {'key': 'some-other-key', 'address': '1.2.3.4',
 
836
                  'status': 'SUCCEEDED'}
 
837
        with task_manager.acquire(self.context, self.node.uuid,
 
838
                                  shared=False) as task:
 
839
            task.node.instance_info['deploy_key'] = 'some-random-key'
 
840
            self.assertRaises(exception.InvalidParameterValue,
 
841
                              iscsi_deploy.validate_pass_bootloader_info_input,
 
842
                              task, params)
 
843
 
 
844
    def test_validate_bootloader_install_status(self):
 
845
        kwargs = {'key': 'abcdef', 'status': 'SUCCEEDED', 'error': ''}
 
846
        with task_manager.acquire(self.context, self.node.uuid,
 
847
                                  shared=False) as task:
 
848
            task.node.instance_info['deploy_key'] = 'abcdef'
 
849
            # Nothing much to assert except that it shouldn't raise.
 
850
            iscsi_deploy.validate_bootloader_install_status(task, kwargs)
 
851
 
 
852
    @mock.patch.object(deploy_utils, 'set_failed_state', autospec=True)
 
853
    def test_validate_bootloader_install_status_install_failed(
 
854
            self, set_fail_state_mock):
 
855
        kwargs = {'key': 'abcdef', 'status': 'FAILED', 'error': 'some-error'}
 
856
        with task_manager.acquire(self.context, self.node.uuid,
 
857
                                  shared=False) as task:
 
858
            task.node.provision_state = states.DEPLOYING
 
859
            task.node.target_provision_state = states.ACTIVE
 
860
            task.node.instance_info['deploy_key'] = 'abcdef'
 
861
            self.assertRaises(exception.InstanceDeployFailure,
 
862
                              iscsi_deploy.validate_bootloader_install_status,
 
863
                              task, kwargs)
 
864
            set_fail_state_mock.assert_called_once_with(task, mock.ANY)
 
865
 
 
866
    @mock.patch.object(deploy_utils, 'notify_ramdisk_to_proceed',
 
867
                       autospec=True)
 
868
    def test_finish_deploy(self, notify_mock):
739
869
        self.node.provision_state = states.DEPLOYING
740
870
        self.node.target_provision_state = states.ACTIVE
741
871
        self.node.save()
742
 
        continue_deploy_mock.return_value = {}
 
872
        with task_manager.acquire(self.context, self.node.uuid,
 
873
                                  shared=False) as task:
 
874
            iscsi_deploy.finish_deploy(task, '1.2.3.4')
 
875
            notify_mock.assert_called_once_with('1.2.3.4')
 
876
            self.assertEqual(states.ACTIVE, task.node.provision_state)
 
877
            self.assertEqual(states.NOSTATE, task.node.target_provision_state)
743
878
 
 
879
    @mock.patch.object(deploy_utils, 'set_failed_state', autospec=True)
 
880
    @mock.patch.object(deploy_utils, 'notify_ramdisk_to_proceed',
 
881
                       autospec=True)
 
882
    def test_finish_deploy_notify_fails(self, notify_mock,
 
883
                                        set_fail_state_mock):
744
884
        with task_manager.acquire(self.context, self.node.uuid,
745
885
                                  shared=False) as task:
 
886
            notify_mock.side_effect = RuntimeError()
746
887
            self.assertRaises(exception.InstanceDeployFailure,
747
 
                              iscsi_deploy.do_agent_iscsi_deploy,
748
 
                              task, agent_client_mock)
749
 
            self.node.refresh()
750
 
            build_options_mock.assert_called_once_with(task.node)
751
 
            agent_client_mock.start_iscsi_target.assert_called_once_with(
752
 
                task.node, 'iqn-qweqwe')
753
 
            continue_deploy_mock.assert_called_once_with(
754
 
                task, error=None, iqn='iqn-qweqwe', key='abcdef',
755
 
                address='1.2.3.4')
756
 
            self.assertEqual(states.DEPLOYFAIL, self.node.provision_state)
757
 
            self.assertEqual(states.ACTIVE, self.node.target_provision_state)
758
 
            self.assertIsNotNone(self.node.last_error)
 
888
                              iscsi_deploy.finish_deploy, task, '1.2.3.4')
 
889
            set_fail_state_mock.assert_called_once_with(task, mock.ANY)
 
890
 
 
891
    @mock.patch.object(manager_utils, 'node_power_action')
 
892
    @mock.patch.object(deploy_utils, 'notify_ramdisk_to_proceed',
 
893
                       autospec=True)
 
894
    def test_finish_deploy_ssh_with_local_boot(self, notify_mock,
 
895
                                               node_power_mock):
 
896
        instance_info = dict(INST_INFO_DICT)
 
897
        instance_info['capabilities'] = {'boot_option': 'local'}
 
898
        n = {
 
899
              'uuid': uuidutils.generate_uuid(),
 
900
              'driver': 'fake_ssh',
 
901
              'instance_info': instance_info,
 
902
              'provision_state': states.DEPLOYING,
 
903
              'target_provision_state': states.ACTIVE,
 
904
        }
 
905
        mgr_utils.mock_the_extension_manager(driver="fake_ssh")
 
906
        node = obj_utils.create_test_node(self.context, **n)
 
907
 
 
908
        with task_manager.acquire(self.context, node.uuid,
 
909
                                  shared=False) as task:
 
910
            iscsi_deploy.finish_deploy(task, '1.2.3.4')
 
911
            notify_mock.assert_called_once_with('1.2.3.4')
 
912
            self.assertEqual(states.ACTIVE, task.node.provision_state)
 
913
            self.assertEqual(states.NOSTATE, task.node.target_provision_state)
 
914
            node_power_mock.assert_called_once_with(task, states.REBOOT)