Ejemplo n.º 1
0
class InstanceTests(TestCase):
    api_client = None
    expected_output = {
        "alias": "",
        "alias_hash": "",
        "created_by": "",
        "has_shell": "",
        "has_vnc": "",
        "ip_address": "",
        "machine_alias": "",
        "machine_alias_hash": "",
        "machine_name": "",
        "name": "",
        "size_alias": "",
        "start_date": "",
        "status": "",
        "tags": "",
        "token": "",
    }

    def setUp_API(self):
        # Initialize API
        self.api_client = TokenAPIClient()
        self.api_client.login(username=settings.TEST_RUNNER_USER, password=settings.TEST_RUNNER_PASS)

    def setUp(self):
        self.setUp_API()

    def tearDown(self):
        self.api_client.logout()

    def test_openstack_launch(self):
        print "Testing launch. ETA:10min"
        self.os_instance_id, self.os_instance_ip = self.launch_openstack_instance()

    # def test_openstack_stop_start(self):
    #    print "Testing stop/start ETA:10min"
    #    self.os_instance_id, self.os_instance_ip = self.launch_openstack_instance()
    #    self.instance_action_step(self.os_instance_id, 'stop')
    #    time.sleep(5*60)
    #    self.instance_action_step(self.os_instance_id, 'start')
    #    time.sleep(5*60)

    # def test_openstack_suspend_resume(self):
    #    print "Testing suspend/resume ETA:10min"
    #    self.os_instance_id, self.os_instance_ip = self.launch_openstack_instance()
    #    self.instance_action_step(self.os_instance_id, 'suspend')
    #    time.sleep(5*60)
    #    self.instance_action_step(self.os_instance_id, 'resume')
    #    time.sleep(5*60)

    # def test_openstack_resize_and_revert(self):
    #    print "Testing resize/revert. ETA:20min"
    #    self.os_instance_id, self.os_instance_ip = self.launch_openstack_instance()
    #    self.instance_action_step(self.os_instance_id, 'resize', {'size':'3'})
    #    time.sleep(7*60)
    #    self.instance_action_step(self.os_instance_id, 'revert_resize')
    #    time.sleep(7*60)

    # def test_openstack_resize_up_and_down(self):
    #    print "Testing resize up/down. ETA:40min"
    #    self.os_instance_id, self.os_instance_ip = self.launch_openstack_instance()
    #    self.instance_action_step(self.os_instance_id, 'resize', {'size':'3'})
    #    time.sleep(7*60)
    #    self.instance_action_step(self.os_instance_id, 'confirm_resize')
    #    time.sleep(7*60)
    #    self.instance_action_step(self.os_instance_id, 'resize', {'size':'1'})
    #    time.sleep(7*60)
    #    self.instance_action_step(self.os_instance_id, 'confirm_resize')
    #    time.sleep(7*60)

    def launch_openstack_instance(self):
        """
        Testing instances must be done in order
        * Create the instance
        * Detail the instance
        * Delete the instance
        """
        global delete_instances
        os_instance_id, os_instance_ip = standup_instance(
            self,
            os_base_instance_url,
            "0f539197-3718-40bc-8a29-c22e0841684f",
            "1",
            "Ubuntu 12.04 - Automated OpenStack Testing",
            delete_before=delete_instances,
        )
        if delete_instances:
            delete_instances = False
        return (os_instance_id, os_instance_ip)

    def instance_action_step(self, instance_id, action, action_params={}):
        instance_action_url = urljoin(urljoin(os_base_instance_url, "%s/" % instance_id), "action/")
        # Attach volume parameters
        action_params.update({"action": action})

        action_resp = self.api_client.post(instance_action_url, action_params, format="json")
        self.assertEqual(action_resp.status_code, status.HTTP_200_OK)
        self.assertEqual("success", action_resp.data.get("result", "No Result In Data"))
        return action_resp

    def detail_step_os(self, instance_id):
        # Detail the instance
        os_instance_url = urljoin(os_base_instance_url, "%s/" % instance_id)
        instance_get_resp = self.api_client.get(os_instance_url)
        # Validate the output
        self.assertEqual(instance_get_resp.status_code, status.HTTP_200_OK)
        verify_expected_output(self, instance_get_resp.data, self.expected_output)

    def predelete_step_os(self):
        list_instance_resp = self.api_client.get(os_base_instance_url)
        self.assertEqual(list_instance_resp.status_code, status.HTTP_200_OK)
        if not list_instance_resp.data:
            return False
        for instance in list_instance_resp.data:
            self.delete_step_os(instance["alias"])
        return True

    def delete_step_os(self, instance_id):
        os_instance_url = os.path.join(os_base_instance_url, "%s/" % instance_id)
        # Delete the instance
        delete_resp = self.api_client.delete(os_instance_url)
        # Validate the output
        self.assertEqual(delete_resp.status_code, status.HTTP_200_OK)
Ejemplo n.º 2
0
class MachineRequestTests(TestCase):
    api_client = None
    expected_output = {
        "description": "",
        "id": "",
        "instance": "",
        "name": "",
        "new_machine": "",
        "owner": "",
        "provider": "",
        "shared_with": "",
        "software": "",
        "status": "",
        "sys": "",
        "tags": "",
        "vis": ""
    }

    def setUp(self):
        #Initialize core DB
        self.euca_admin_id = create_euca_provider()
        self.euca_provider = self.euca_admin_id.provider
        self.os_admin_id = create_os_provider()
        self.os_provider = self.os_admin_id.provider
        #Ensure there is an account created/ready to go
        euca_accounts = EucaAccounts(self.euca_provider)
        euca_user = euca_accounts.get_user(settings.TEST_RUNNER_USER)
        self.euca_id = euca_accounts.create_account(euca_user, max_quota=True)
        os_accounts = OSAccounts(self.os_provider)
        self.os_id = os_accounts.create_account(settings.TEST_RUNNER_USER,
                                                os_accounts.hashpass(
                                                    settings.TEST_RUNNER_USER),
                                                max_quota=True)
        user = AtmosphereUser.objects.get(username=settings.TEST_RUNNER_USER)
        user.is_staff = True
        user.is_superuser = True
        user.save()
        #Initialize API
        self.api_client = TokenAPIClient()
        self.api_client.login(username=settings.TEST_RUNNER_USER,
                              password=settings.TEST_RUNNER_PASS)
        reverse_link = reverse('api:public_apis:instance-list',
                               args=[self.os_id.provider.id, self.os_id.id])
        self.os_instance_url = urljoin(settings.SERVER_URL, reverse_link)
        reverse_link = reverse(
            'api:public_apis:instance-list',
            args=[self.euca_id.provider.id, self.euca_id.id])
        self.euca_instance_url = urljoin(settings.SERVER_URL, reverse_link)
        reverse_link = reverse('api:public_apis:machine-request-list',
                               args=[self.os_id.provider.id, self.os_id.id])
        self.os_request_url = urljoin(settings.SERVER_URL, reverse_link)
        reverse_link = reverse(
            'api:public_apis:machine-request-list',
            args=[self.euca_id.provider.id, self.euca_id.id])
        self.euca_request_url = urljoin(settings.SERVER_URL, reverse_link)

    def openstack_mach_and_size(self):
        reverse_link = reverse('api:public_apis:machine-list',
                               args=[self.os_id.provider.id, self.os_id.id])
        self.os_machine_url = urljoin(settings.SERVER_URL, reverse_link)
        self.api_client.get(self.os_machine_url)
        reverse_link = reverse('api:public_apis:size-list',
                               args=[self.os_id.provider.id, self.os_id.id])
        self.os_size_url = urljoin(settings.SERVER_URL, reverse_link)
        self.api_client.get(self.os_size_url)

    def euca_mach_and_size(self):
        reverse_link = reverse(
            'api:public_apis:machine-list',
            args=[self.euca_id.provider.id, self.euca_id.id])
        self.euca_machine_url = urljoin(settings.SERVER_URL, reverse_link)
        self.api_client.get(self.euca_machine_url)

        reverse_link = reverse(
            'size-list', args=[self.euca_id.provider.id, self.euca_id.id])
        self.euca_size_url = urljoin(settings.SERVER_URL, reverse_link)

        self.api_client.get(self.euca_size_url)

    def tearDown(self):
        self.api_client.logout()

    ##TEST CASES:
    #NOTE: Eucalyptus machine requests will not complete fully until node controller info added..
    # This is on a TODO at a later date..

    #def test_euca_machine_request(self):
    #    """
    #    Testing machine requests require specific order:
    #      * "Stand-up" an instance
    #      * Create a machine request
    #      * Approve a machine request
    #      * Verify machine request has gone to 'completed'
    #      * "Stand-up" the new machine
    #      * Delete an existing machine request
    #    """
    #    machine_alias = "emi-E7F8300F"
    #    size_alias = "m1.small"
    #    self.euca_mach_and_size()
    #    instance_id, instance_ip = standup_instance(
    #            self, self.euca_instance_url,
    #            machine_alias, size_alias, "test imaging")
    #    request_id = self.create_machine_request(
    #            self.euca_request_url,
    #            instance_id, instance_ip, self.euca_id.provider.id)
    #    approval_link = reverse('api:private_apis:direct-machine-request-action',
    #                          args=[request_id, 'approve'])
    #    euca_approval_url = urljoin(settings.SERVER_URL, approval_link)
    #    self.approve_machine_request(euca_approval_url)
    #    machine_request_url = reverse('api:private_apis:direct-machine-request-detail',
    #            args=[request_id,])
    #    new_machine_id = self.wait_for_machine_request(machine_request_url)
    #    machine_alias = new_machine_id
    #    instance_id, instance_ip = standup_instance(
    #            self, self.euca_instance_url,
    #            machine_alias, size_alias, "test imaging was successful",
    #            delete_after=True)

    #def test_euca_os_migration(self):
    #    euca_accounts = EucaAccounts(
    #            Provider.objects.get(location='EUCALYPTUS'))
    #    euca_img_class = euca_accounts.image_manager.__class__
    #    euca_img_creds = euca_accounts.image_creds
    #    os_accounts = OSAccounts(
    #            Provider.objects.get(location='OPENSTACK'))
    #    os_img_class = os_accounts.image_manager.__class__
    #    os_img_creds = os_accounts.image_creds
    #    migrate_args = {
    #            'download_dir':"/Storage/test",
    #            'image_id':"emi-E7F8300F",
    #            'image_name': "ATMO Migration Test %s"\
    #                    % datetime.now().strftime('%m%d_%H%M'),
    #            'xen_to_kvm':True,
    #            }
    #    migrate_image(euca_img_class, euca_img_creds,
    #                  os_img_class, os_img_creds,
    #                  **migrate_args)

    #def test_openstack_machine_request(self):
    #    """
    #    Testing machines must be done in order
    #      * Create a machine request
    #      * Approve a machine request
    #      * Verify a completed machine request
    #      * Delete a machine request
    #    # to verify a completed image:
    #    # Launch and Ensure: SSH, VNC, Shellinabox, Deploy access
    #    """
    #    machine_alias = "75fdfca4-d49d-4b2d-b919-a3297bc6d7ae"
    #    size_alias = "2"
    #    self.openstack_mach_and_size()
    #    instance_id, instance_ip = standup_instance(
    #            self, self.os_instance_url,
    #            machine_alias, size_alias, "test imaging")
    #    request_id = self.create_machine_request(
    #            self.os_request_url,
    #            instance_id, instance_ip, self.os_id.provider.id)
    #    #E-mail for approval sent to ADMINS here..
    #    #Image ready for approval after this line returns
    #    approval_link = reverse('api:private_apis:direct-machine-request-action',
    #                          args=[request_id, 'approve'])
    #    os_approval_url = urljoin(settings.SERVER_URL, approval_link)
    #    self.approve_machine_request(os_approval_url)
    #    #Machine will be imaged HERE.. Image EXISTS after this line returns!
    #    machine_request_url = reverse('api:private_apis:direct-machine-request-detail',
    #            args=[request_id,])
    #    new_machine_id = self.wait_for_machine_request(machine_request_url)
    #    machine_alias = new_machine_id
    #    instance_id, instance_ip = standup_instance(
    #            self, self.os_instance_url,
    #            machine_alias, size_alias, "test imaging successful",
    #            delete_after=True, first_launch=True)

    #TEST STEPS: Called indirectly by TEST CASES...

    def create_machine_request(self, machine_request_url, instance_id,
                               instance_ip, new_provider_id):
        post_data = {
            "name":"Testing Machine Request",
            "description":"This is only a test, "\
                          "as such it is not meant to be launched.",
            "instance": instance_id,
            "provider": new_provider_id,
            "vis":"public",
            "ip_address":instance_ip,
            "software":"",
            "sys":"",
            "exclude":"",
            "tags":"",
        }
        post_machine_resp = self.api_client.post(machine_request_url,
                                                 post_data,
                                                 format='json')
        #Validate the output
        self.assertEqual(post_machine_resp.status_code,
                         status.HTTP_201_CREATED)
        self.assertIsNotNone(post_machine_resp.data)
        #TODO:
        # Create 'expected output'
        # verify_expected_output(self, instance_launch_resp.data, self.expected_output)
        request_id = post_machine_resp.data['id']
        return request_id

    def approve_machine_request(self, machine_request_approval_url):
        mach_request_put = self.api_client.get(machine_request_approval_url)
        self.assertEqual(mach_request_put.status_code, status.HTTP_200_OK)

    def wait_for_machine_request(self, machine_request_url):
        finished = False
        minutes = 1
        attempts = 1
        while not finished:
            mach_request_get = self.api_client.get(machine_request_url)
            self.assertEqual(mach_request_get.status_code, status.HTTP_200_OK)
            mach_status = mach_request_get.data['status']
            new_machine = mach_request_get.data['new_machine']
            if 'error' in mach_status:
                raise Exception("Error occurred during imaging. "
                                "Will not wait for machine request to finish.")
                break
            if mach_status != 'completed':
                #5m, 5m, 5m, 5m, 5m, ...
                attempts += 1
                minutes = 5
                test_client.assertNotEqual(
                    attempts, 10,
                    "Made 10 attempts to wait for an active instance. "
                    "Giving up..")
                continue
            finished = True
        complete_time = datetime.now()
        logger.info("Machine Request marked as completed. complete time:%s" %
                    (complete_time))
        return new_machine
Ejemplo n.º 3
0
class VolumeTests(TestCase):
    api_client = None
    expected_output = {
        "status": "",
        "attach_data": "",
        "alias": "",
        "provider": "",
        "size": "",
        "name": "",
        "description": "",
        "created_by": "",
        "created_by_identity": "",
        "start_date": ""
    }

    def setUp(self):
        #Initialize core DB
        #self.euca_admin_id = create_euca_provider()
        #self.euca_provider = self.euca_admin_id.provider
        self.os_admin_id = create_os_provider()
        self.os_provider = self.os_admin_id.provider
        #Ensure there is an account created/ready to go
        #euca_accounts = EucaAccounts(self.euca_provider)
        #euca_user = euca_accounts.get_user(settings.TEST_RUNNER_USER)
        #self.euca_id = euca_accounts.create_account(euca_user, max_quota=True)
        os_accounts = OSAccounts(self.os_provider)
        self.os_id = os_accounts.create_account(settings.TEST_RUNNER_USER,
                                                os_accounts.hashpass(
                                                    settings.TEST_RUNNER_USER),
                                                max_quota=True)
        #user = AtmosphereUser.objects.get(username=settings.TEST_RUNNER_USER)
        #user.is_staff = True
        #user.is_superuser = True
        #user.save()
        #Initialize API
        self.api_client = TokenAPIClient()
        self.api_client.login(username=settings.TEST_RUNNER_USER,
                              password=settings.TEST_RUNNER_PASS)
        reverse_link = reverse('api:public_apis:instance-list',
                               args=[self.os_id.provider.id, self.os_id.id])
        self.os_instance_url = urljoin(settings.SERVER_URL, reverse_link)
        reverse_link = reverse('api:public_apis:volume-list',
                               args=[self.os_id.provider.id, self.os_id.id])
        #Prepare Openstack
        self.os_volume_url = urljoin(settings.SERVER_URL, reverse_link)
        instance_data = {
            "size_alias": "2",
            "machine_alias": "0f539197-3718-40bc-8a29-c22e0841684f",
            "name": "test volume attachment",
            "delete_before": False
        }
        (self.os_instance_id,
         self.os_instance_ip) = standup_instance(self, self.os_instance_url,
                                                 **instance_data)

        #Prepare Eucalyptus
        #reverse_link = reverse('api:public_apis:volume-list',
        #                      args=[self.euca_id.provider.id,
        #                            self.euca_id.id])
        #self.euca_volume_url = urljoin(settings.SERVER_URL, reverse_link)
        #reverse_link = reverse('api:public_apis:instance-list',
        #                      args=[self.euca_id.provider.id,
        #                            self.euca_id.id])
        #self.euca_instance_url = urljoin(settings.SERVER_URL, reverse_link)
        #instance_data = {
        #        "size_alias":"m1.small",
        #        "machine_alias":"emi-E7F8300F",
        #        "name":"test volume attachment",
        #        "delete_before":False
        #    }
        #(self.euca_instance_id, self.euca_instance_ip) = standup_instance(
        #        self, self.euca_instance_url, **instance_data)

    def tearDown(self):
        self.api_client.logout()

    #def test_openstack_volume(self):
    #    """
    #    Testing volumes must be done in order
    #    * Create the volume
    #    * Detail the volume
    #    * Delete the volume
    #    """
    #    volume_post_data = {
    #        "name":"openstack_vol_test1",
    #        "size":1,
    #    }
    #    self.expected_output['name'] = volume_post_data['name']
    #    self.expected_output['size'] = volume_post_data['size']
    #    volume_id = self.create_volume(self.os_volume_url, volume_post_data)
    #    self.detail_volume(self.os_volume_url, volume_id)
    #    # Wait time associated between 'create' and 'attachment'
    #    time.sleep(30)
    #    self.attach_volume(self.os_instance_url, self.os_instance_id, volume_id)
    #    time.sleep(30)
    #    self.detach_volume(self.os_instance_url, self.os_instance_id, volume_id)
    #    # Wait time associated between 'detach' and 'delete'
    #    time.sleep(30) # Sorry, its euca.
    #    #Delete all volumes
    #    deleted = self.delete_all_volumes(self.os_volume_url)

    #def test_euca_volume(self):
    #    """
    #    Testing volumes must be done in order
    #    * Create the volume
    #    * wait a second
    #    * Attach the volume
    #    * Verify success
    #    * If failed, Try again(?)
    #    * Detach the volume
    #    * Verify success
    #    * wait a second
    #    * Delete the volume
    #    # Wait for volume to deploy and
    #    # Ensure: SSH, VNC, Shellinabox, Deploy access
    #    """

    #    volume_post_data = {
    #        "name":"euca_vol_test1",
    #        "size":1,
    #    }
    #    self.expected_output['name'] = volume_post_data['name']
    #    self.expected_output['size'] = volume_post_data['size']

    #    volume_id = self.create_volume(self.euca_volume_url, volume_post_data)
    #    self.detail_volume(self.euca_volume_url, volume_id)
    #    # Wait time associated between 'create' and 'attachment'
    #    time.sleep(30)
    #    self.attach_volume(self.euca_instance_url, self.euca_instance_id, volume_id)
    #    time.sleep(30)
    #    self.detach_volume(self.euca_instance_url, self.euca_instance_id, volume_id)
    #    #Delete all volumes
    #    deleted = self.delete_all_volumes(self.euca_volume_url)
    #    if deleted:
    #        # Wait time associated between 'detach' and 'delete'
    #        time.sleep(30) # Sorry, its euca.

    def attach_volume(self, instance_base_url, instance_id, volume_id):
        #Make action url
        instance_action_url = urljoin(
            urljoin(instance_base_url, '%s/' % instance_id), 'action/')
        #Attach volume parameters
        action_params = {
            'action': 'attach_volume',
            'volume_id': volume_id,
            #'device':'/dev/xvdb',
        }
        volume_attach_resp = self.api_client.post(instance_action_url,
                                                  action_params,
                                                  format='json')
        #Wait and see..

    def detach_volume(self, instance_base_url, instance_id, volume_id):
        #Make action url
        instance_action_url = urljoin(
            urljoin(instance_base_url, '%s/' % instance_id), 'action/')
        #Attach volume parameters
        action_params = {
            'action': 'detach_volume',
            'volume_id': volume_id,
            #'device': '/dev/xvdb',
        }
        volume_detach_resp = self.api_client.post(instance_action_url,
                                                  action_params,
                                                  format='json')
        #Wait and see..

    def create_volume(self, volume_base_url, post_data):
        #Create the volume
        volume_launch_resp = self.api_client.post(volume_base_url,
                                                  post_data,
                                                  format='json')
        #Validate the output
        if volume_launch_resp.status_code != status.HTTP_201_CREATED:
            logger.info(volume_launch_resp)
        self.assertEqual(volume_launch_resp.status_code,
                         status.HTTP_201_CREATED)
        self.assertIsNotNone(volume_launch_resp.data)
        verify_expected_output(self, volume_launch_resp.data,
                               self.expected_output)
        volume_id = volume_launch_resp.data['alias']
        return volume_id

    def delete_all_volumes(self, volume_list_url):
        list_volume_resp = self.api_client.get(volume_list_url)
        self.assertEqual(list_volume_resp.status_code, status.HTTP_200_OK)
        if not list_volume_resp.data:
            return False
        for volume in list_volume_resp.data:
            self.delete_volume(volume_list_url, volume['alias'])
        return True

    def delete_volume(self, volume_base_url, volume_alias):
        specific_volume_url = urljoin(volume_base_url, '%s/' % volume_alias)
        #Delete the volume
        delete_resp = self.api_client.delete(specific_volume_url)
        #Validate the output
        self.assertEqual(delete_resp.status_code, status.HTTP_200_OK)

    def detail_volume(self, volume_base_url, volume_id):
        #Detail the volume
        specific_volume_url = urljoin(volume_base_url, '%s/' % volume_id)
        volume_get_resp = self.api_client.get(specific_volume_url)
        #Validate the output
        self.assertEqual(volume_get_resp.status_code, status.HTTP_200_OK)
        verify_expected_output(self, volume_get_resp.data,
                               self.expected_output)
Ejemplo n.º 4
0
class MachineTests(TestCase):
    api_client = None
    expected_output = {
        "alias": "", 
        "alias_hash": "", 
        "created_by": "", 
        "icon": "",
        "private": "",
        "architecture": "", 
        "ownerid": "", 
        "state": "", 
        "name": "", 
        "tags": "", 
        "description": "", 
        "start_date": "", 
        "end_date": "", 
        "featured": "", 
        "identifier": "", 
        "created_by_identity": ""
    }
    def setUp(self):
        #Initialize core DB
        #self.euca_admin_id = create_euca_provider()
        #self.euca_provider = self.euca_admin_id.provider
        self.os_admin_id = create_os_provider()
        self.os_provider = self.os_admin_id.provider
        #Ensure there is an account created/ready to go
        #euca_accounts = EucaAccounts(self.euca_provider)
        #euca_user = euca_accounts.get_user(settings.TEST_RUNNER_USER)
        #self.euca_id = euca_accounts.create_account(euca_user)
        os_accounts = OSAccounts(self.os_provider)
        self.os_id = os_accounts.create_account(
                settings.TEST_RUNNER_USER, 
                os_accounts.hashpass(settings.TEST_RUNNER_USER))
        #Initialize API
        self.api_client = TokenAPIClient()
        self.api_client.login(
                username=settings.TEST_RUNNER_USER,
                password=settings.TEST_RUNNER_PASS)
        reverse_link = reverse('api:public_apis:machine-list',
                               args=[self.os_id.provider.uuid,
                                     self.os_id.uuid])
        self.os_machine_url = urljoin(settings.SERVER_URL, reverse_link)
        #reverse_link = reverse('api:public_apis:machine-list',
        #                      args=[self.euca_id.provider.id,
        #                            self.euca_id.id])
        #self.euca_machine_url = urljoin(settings.SERVER_URL, reverse_link)
        

    def tearDown(self):
        self.api_client.logout()

    #def test_euca_machine(self):
    #    """
    #    Testing machines must be done in order
    #    * Create the machine
    #    * Detail the machine
    #    * Delete the machine
    #    # Wait for machine to deploy and
    #    # Ensure: SSH, VNC, Shellinabox, Deploy access
    #    """
    #    list_machine_resp = self.api_client.get(self.euca_machine_url)
    #    self.assertEqual(list_machine_resp.status_code, status.HTTP_200_OK)
    #    if not list_machine_resp.data:
    #        return
    #    for machine in list_machine_resp.data:
    #        verify_expected_output(self, machine, self.expected_output)

    def test_openstack_machine(self):
        """
        Testing machines must be done in order
        * Create the machine
        * Detail the machine
        * Delete the machine
        """
        list_machine_resp = self.api_client.get(self.os_machine_url)
        self.assertEqual(list_machine_resp.status_code, status.HTTP_200_OK)
        if not list_machine_resp.data:
            return
        for machine in list_machine_resp.data:
            verify_expected_output(self, machine, self.expected_output)
Ejemplo n.º 5
0
class MachineTests(TestCase):
    api_client = None
    expected_output = {
        "alias": "",
        "alias_hash": "",
        "created_by": "",
        "icon": "",
        "private": "",
        "architecture": "",
        "ownerid": "",
        "state": "",
        "name": "",
        "tags": "",
        "description": "",
        "start_date": "",
        "end_date": "",
        "featured": "",
        "identifier": "",
        "created_by_identity": ""
    }

    def setUp(self):
        #Initialize core DB
        self.euca_admin_id = create_euca_provider()
        self.euca_provider = self.euca_admin_id.provider
        self.os_admin_id = create_os_provider()
        self.os_provider = self.os_admin_id.provider
        #Ensure there is an account created/ready to go
        euca_accounts = EucaAccounts(self.euca_provider)
        euca_user = euca_accounts.get_user(settings.TEST_RUNNER_USER)
        self.euca_id = euca_accounts.create_account(euca_user)
        os_accounts = OSAccounts(self.os_provider)
        self.os_id = os_accounts.create_account(
            settings.TEST_RUNNER_USER,
            os_accounts.hashpass(settings.TEST_RUNNER_USER))
        #Initialize API
        self.api_client = TokenAPIClient()
        self.api_client.login(username=settings.TEST_RUNNER_USER,
                              password=settings.TEST_RUNNER_PASS)
        reverse_link = reverse('api:public_apis:machine-list',
                               args=[self.os_id.provider.id, self.os_id.id])
        self.os_machine_url = urljoin(settings.SERVER_URL, reverse_link)
        reverse_link = reverse(
            'api:public_apis:machine-list',
            args=[self.euca_id.provider.id, self.euca_id.id])
        self.euca_machine_url = urljoin(settings.SERVER_URL, reverse_link)

    def tearDown(self):
        self.api_client.logout()

    def test_euca_machine(self):
        """
        Testing machines must be done in order
        * Create the machine
        * Detail the machine
        * Delete the machine
        # Wait for machine to deploy and
        # Ensure: SSH, VNC, Shellinabox, Deploy access
        """
        list_machine_resp = self.api_client.get(self.euca_machine_url)
        self.assertEqual(list_machine_resp.status_code, status.HTTP_200_OK)
        if not list_machine_resp.data:
            return
        for machine in list_machine_resp.data:
            verify_expected_output(self, machine, self.expected_output)

    def test_openstack_machine(self):
        """
        Testing machines must be done in order
        * Create the machine
        * Detail the machine
        * Delete the machine
        """
        list_machine_resp = self.api_client.get(self.os_machine_url)
        self.assertEqual(list_machine_resp.status_code, status.HTTP_200_OK)
        if not list_machine_resp.data:
            return
        for machine in list_machine_resp.data:
            verify_expected_output(self, machine, self.expected_output)
Ejemplo n.º 6
0
class InstanceTests(TestCase):
    api_client = None
    expected_output = {
        "alias": "",
        "alias_hash": "",
        "created_by": "",
        "has_shell": "",
        "has_vnc": "",
        "ip_address": "",
        "machine_alias": "",
        "machine_alias_hash": "",
        "machine_name": "",
        "name": "",
        "size_alias": "",
        "start_date": "",
        "status": "",
        "tags": "",
        "token": "",
    }

    def setUp_API(self):
        #Initialize API
        self.api_client = TokenAPIClient()
        self.api_client.login(username=settings.TEST_RUNNER_USER,
                              password=settings.TEST_RUNNER_PASS)

    def setUp(self):
        self.setUp_API()

    def tearDown(self):
        self.api_client.logout()

    #def test_openstack_launch(self):
    #    self.os_instance_id, self.os_instance_ip = self.launch_openstack_instance()

    #def test_openstack_stop_start(self):
    #    self.os_instance_id, self.os_instance_ip = self.launch_openstack_instance()
    #    self.instance_action_step(self.os_instance_id, 'stop')
    #    time.sleep(5*60)
    #    self.instance_action_step(self.os_instance_id, 'start')
    #    time.sleep(5*60)

    #def test_openstack_suspend_resume(self):
    #    self.os_instance_id, self.os_instance_ip = self.launch_openstack_instance()
    #    self.instance_action_step(self.os_instance_id, 'suspend')
    #    time.sleep(5*60)
    #    self.instance_action_step(self.os_instance_id, 'resume')
    #    time.sleep(5*60)

    #def test_openstack_resize_and_revert(self):
    #    self.os_instance_id, self.os_instance_ip = self.launch_openstack_instance()
    #    self.instance_action_step(self.os_instance_id, 'resize', {'size':'3'})
    #    time.sleep(7*60)
    #    self.instance_action_step(self.os_instance_id, 'revert_resize')
    #    time.sleep(7*60)

    #def test_openstack_resize_up_and_down(self):
    #    self.os_instance_id, self.os_instance_ip = self.launch_openstack_instance()
    #    self.instance_action_step(self.os_instance_id, 'resize', {'size':'3'})
    #    time.sleep(7*60)
    #    self.instance_action_step(self.os_instance_id, 'confirm_resize')
    #    time.sleep(7*60)
    #    self.instance_action_step(self.os_instance_id, 'resize', {'size':'1'})
    #    time.sleep(7*60)
    #    self.instance_action_step(self.os_instance_id, 'confirm_resize')
    #    time.sleep(7*60)

    def launch_openstack_instance(self):
        """
        Testing instances must be done in order
        * Create the instance
        * Detail the instance
        * Delete the instance
        """
        global delete_instances
        os_instance_id, os_instance_ip = standup_instance(
            self,
            os_base_instance_url,
            "0f539197-3718-40bc-8a29-c22e0841684f",
            "1",
            "Ubuntu 12.04 - Automated OpenStack Testing",
            delete_before=delete_instances)
        if delete_instances:
            delete_instances = False
        return (os_instance_id, os_instance_ip)

    def instance_action_step(self, instance_id, action, action_params={}):
        instance_action_url = urljoin(
            urljoin(os_base_instance_url, '%s/' % instance_id), 'action/')
        #Attach volume parameters
        action_params.update({
            'action': action,
        })

        action_resp = self.api_client.post(instance_action_url,
                                           action_params,
                                           format='json')
        self.assertEqual(action_resp.status_code, status.HTTP_200_OK)
        self.assertEqual('success',
                         action_resp.data.get('result', 'No Result In Data'))
        return action_resp

    def detail_step_os(self, instance_id):
        #Detail the instance
        os_instance_url = urljoin(os_base_instance_url, '%s/' % instance_id)
        instance_get_resp = self.api_client.get(os_instance_url)
        #Validate the output
        self.assertEqual(instance_get_resp.status_code, status.HTTP_200_OK)
        verify_expected_output(self, instance_get_resp.data,
                               self.expected_output)

    def predelete_step_os(self):
        list_instance_resp = self.api_client.get(os_base_instance_url)
        self.assertEqual(list_instance_resp.status_code, status.HTTP_200_OK)
        if not list_instance_resp.data:
            return False
        for instance in list_instance_resp.data:
            self.delete_step_os(instance['alias'])
        return True

    def delete_step_os(self, instance_id):
        os_instance_url = os.path.join(os_base_instance_url,
                                       '%s/' % instance_id)
        #Delete the instance
        delete_resp = self.api_client.delete(os_instance_url)
        #Validate the output
        self.assertEqual(delete_resp.status_code, status.HTTP_200_OK)
Ejemplo n.º 7
0
class VolumeTests(TestCase):
    api_client = None
    expected_output = {
            "status": "", 
            "attach_data": "", 
            "alias": "", 
            "provider": "",
            "size": "",
            "name": "",
            "description": "", 
            "created_by": "",
            "created_by_identity": "",
            "start_date": ""
            }

    def setUp(self):
        #Initialize core DB
        #self.euca_admin_id = create_euca_provider()
        #self.euca_provider = self.euca_admin_id.provider
        self.os_admin_id = create_os_provider()
        self.os_provider = self.os_admin_id.provider
        #Ensure there is an account created/ready to go
        #euca_accounts = EucaAccounts(self.euca_provider)
        #euca_user = euca_accounts.get_user(settings.TEST_RUNNER_USER)
        #self.euca_id = euca_accounts.create_account(euca_user, max_quota=True)
        os_accounts = OSAccounts(self.os_provider)
        self.os_id = os_accounts.create_account(
                settings.TEST_RUNNER_USER, 
                os_accounts.hashpass(settings.TEST_RUNNER_USER), max_quota=True)
        #user = AtmosphereUser.objects.get(username=settings.TEST_RUNNER_USER)
        #user.is_staff = True
        #user.is_superuser = True
        #user.save()
        #Initialize API
        self.api_client = TokenAPIClient()
        self.api_client.login(
                username=settings.TEST_RUNNER_USER,
                password=settings.TEST_RUNNER_PASS)
        reverse_link = reverse('api:public_apis:instance-list',
                              args=[self.os_id.provider.id,
                                    self.os_id.id])
        self.os_instance_url = urljoin(settings.SERVER_URL, reverse_link)
        reverse_link = reverse('api:public_apis:volume-list',
                               args=[self.os_id.provider.id,
                                     self.os_id.id])
        #Prepare Openstack
        self.os_volume_url = urljoin(settings.SERVER_URL, reverse_link)
        instance_data = {
                "size_alias":"2",
                "machine_alias":"0f539197-3718-40bc-8a29-c22e0841684f",
                "name":"test volume attachment",
                "delete_before":False
            }
        (self.os_instance_id, self.os_instance_ip) = standup_instance(
                self, self.os_instance_url, **instance_data)

        #Prepare Eucalyptus
        #reverse_link = reverse('api:public_apis:volume-list',
        #                      args=[self.euca_id.provider.id,
        #                            self.euca_id.id])
        #self.euca_volume_url = urljoin(settings.SERVER_URL, reverse_link)
        #reverse_link = reverse('api:public_apis:instance-list',
        #                      args=[self.euca_id.provider.id,
        #                            self.euca_id.id])
        #self.euca_instance_url = urljoin(settings.SERVER_URL, reverse_link)
        #instance_data = {
        #        "size_alias":"m1.small",
        #        "machine_alias":"emi-E7F8300F",
        #        "name":"test volume attachment",
        #        "delete_before":False
        #    }
        #(self.euca_instance_id, self.euca_instance_ip) = standup_instance(
        #        self, self.euca_instance_url, **instance_data)
        

    def tearDown(self):
        self.api_client.logout()

    #def test_openstack_volume(self):
    #    """
    #    Testing volumes must be done in order
    #    * Create the volume
    #    * Detail the volume
    #    * Delete the volume
    #    """
    #    volume_post_data = {
    #        "name":"openstack_vol_test1",
    #        "size":1,
    #    }
    #    self.expected_output['name'] = volume_post_data['name']
    #    self.expected_output['size'] = volume_post_data['size']
    #    volume_id = self.create_volume(self.os_volume_url, volume_post_data)
    #    self.detail_volume(self.os_volume_url, volume_id)
    #    # Wait time associated between 'create' and 'attachment'
    #    time.sleep(30)
    #    self.attach_volume(self.os_instance_url, self.os_instance_id, volume_id)
    #    time.sleep(30)
    #    self.detach_volume(self.os_instance_url, self.os_instance_id, volume_id)
    #    # Wait time associated between 'detach' and 'delete'
    #    time.sleep(30) # Sorry, its euca.
    #    #Delete all volumes
    #    deleted = self.delete_all_volumes(self.os_volume_url)


    #def test_euca_volume(self):
    #    """
    #    Testing volumes must be done in order
    #    * Create the volume
    #    * wait a second
    #    * Attach the volume
    #    * Verify success
    #    * If failed, Try again(?)
    #    * Detach the volume
    #    * Verify success
    #    * wait a second
    #    * Delete the volume
    #    # Wait for volume to deploy and
    #    # Ensure: SSH, VNC, Shellinabox, Deploy access
    #    """

    #    volume_post_data = {
    #        "name":"euca_vol_test1",
    #        "size":1,
    #    }
    #    self.expected_output['name'] = volume_post_data['name']
    #    self.expected_output['size'] = volume_post_data['size']

    #    volume_id = self.create_volume(self.euca_volume_url, volume_post_data)
    #    self.detail_volume(self.euca_volume_url, volume_id)
    #    # Wait time associated between 'create' and 'attachment'
    #    time.sleep(30)
    #    self.attach_volume(self.euca_instance_url, self.euca_instance_id, volume_id)
    #    time.sleep(30)
    #    self.detach_volume(self.euca_instance_url, self.euca_instance_id, volume_id)
    #    #Delete all volumes
    #    deleted = self.delete_all_volumes(self.euca_volume_url)
    #    if deleted:
    #        # Wait time associated between 'detach' and 'delete'
    #        time.sleep(30) # Sorry, its euca.

    def attach_volume(self, instance_base_url, instance_id, volume_id):
        #Make action url
        instance_action_url = urljoin(
            urljoin(instance_base_url, '%s/' % instance_id),
            'action/')
        #Attach volume parameters
        action_params = {
            'action':'attach_volume',
            'volume_id':volume_id,
            #'device':'/dev/xvdb',
        }
        volume_attach_resp = self.api_client.post(instance_action_url,
                                                  action_params, format='json')
        #Wait and see..

    def detach_volume(self, instance_base_url, instance_id, volume_id):
        #Make action url
        instance_action_url = urljoin(
            urljoin(instance_base_url, '%s/' % instance_id), 'action/')
        #Attach volume parameters
        action_params = {
            'action': 'detach_volume',
            'volume_id': volume_id,
            #'device': '/dev/xvdb',
        }
        volume_detach_resp = self.api_client.post(instance_action_url,
                                                  action_params, format='json')
        #Wait and see..

    def create_volume(self, volume_base_url, post_data):
        #Create the volume
        volume_launch_resp = self.api_client.post(volume_base_url, post_data,
                                                  format='json')
        #Validate the output
        if volume_launch_resp.status_code != status.HTTP_201_CREATED:
            logger.info(volume_launch_resp)
        self.assertEqual(volume_launch_resp.status_code, status.HTTP_201_CREATED)
        self.assertIsNotNone(volume_launch_resp.data)
        verify_expected_output(self, volume_launch_resp.data,
                               self.expected_output)
        volume_id = volume_launch_resp.data['alias']
        return volume_id

    def delete_all_volumes(self, volume_list_url):
        list_volume_resp = self.api_client.get(volume_list_url)
        self.assertEqual(list_volume_resp.status_code, status.HTTP_200_OK)
        if not list_volume_resp.data:
            return False
        for volume in list_volume_resp.data:
            self.delete_volume(volume_list_url, volume['alias'])
        return True

    def delete_volume(self, volume_base_url, volume_alias):
        specific_volume_url = urljoin(
            volume_base_url,
            '%s/' % volume_alias)
        #Delete the volume
        delete_resp = self.api_client.delete(specific_volume_url)
        #Validate the output
        self.assertEqual(delete_resp.status_code, status.HTTP_200_OK)


    def detail_volume(self, volume_base_url, volume_id):
        #Detail the volume
        specific_volume_url = urljoin(
            volume_base_url,
            '%s/' % volume_id)
        volume_get_resp = self.api_client.get(specific_volume_url)
        #Validate the output
        self.assertEqual(volume_get_resp.status_code, status.HTTP_200_OK)
        verify_expected_output(self, volume_get_resp.data,
                               self.expected_output)
Ejemplo n.º 8
0
class MachineRequestTests(TestCase):
    api_client = None
    expected_output = {
        "description": "",
        "id": "",
        "instance": "",
        "name": "",
        "new_machine": "",
        "owner": "",
        "provider": "",
        "shared_with": "",
        "software": "",
        "status": "",
        "sys": "",
        "tags": "",
        "vis": ""
    }

    def setUp(self):
        #Initialize core DB
        #Ensure there is an account created/ready to go

        #self.euca_admin_id = create_euca_provider()
        #self.euca_provider = self.euca_admin_id.provider
        #euca_accounts = EucaAccounts(self.euca_provider)
        #euca_user = euca_accounts.get_user(settings.TEST_RUNNER_USER)
        #self.euca_id = euca_accounts.create_account(euca_user, max_quota=True)

        self.os_admin_id = create_os_provider()
        self.os_provider = self.os_admin_id.provider
        os_accounts = OSAccounts(self.os_provider)
        self.os_id = os_accounts.create_account(
                settings.TEST_RUNNER_USER,
                os_accounts.hashpass(settings.TEST_RUNNER_USER), max_quota=True)
        user = AtmosphereUser.objects.get(username=settings.TEST_RUNNER_USER)
        user.is_staff = True
        user.is_superuser = True
        user.save()
        #Initialize API
        self.api_client = TokenAPIClient()
        self.api_client.login(
                username=settings.TEST_RUNNER_USER,
                password=settings.TEST_RUNNER_PASS)
        reverse_link = reverse('api:v1:instance-list',
                               args=[self.os_id.provider.id,
                                     self.os_id.id])
        self.os_instance_url = urljoin(settings.SERVER_URL, reverse_link)
        reverse_link = reverse('api:v1:machine-request-list',
                               args=[self.os_id.provider.id,
                                     self.os_id.id])
        self.os_request_url = urljoin(settings.SERVER_URL, reverse_link)
        #reverse_link = reverse('api:v1:instance-list',
        #                      args=[self.euca_id.provider.id,
        #                            self.euca_id.id])
        #self.euca_instance_url = urljoin(settings.SERVER_URL, reverse_link)
        #reverse_link = reverse('api:v1:machine-request-list',
        #                      args=[self.euca_id.provider.id,
        #                            self.euca_id.id])
        #self.euca_request_url = urljoin(settings.SERVER_URL, reverse_link)

    def openstack_mach_and_size(self):
        reverse_link = reverse('api:v1:machine-list',
                               args=[self.os_id.provider.id,
                                     self.os_id.id])
        self.os_machine_url = urljoin(settings.SERVER_URL, reverse_link)
        self.api_client.get(self.os_machine_url)
        reverse_link = reverse('api:v1:size-list',
                               args=[self.os_id.provider.id,
                                     self.os_id.id])
        self.os_size_url = urljoin(settings.SERVER_URL, reverse_link)
        self.api_client.get(self.os_size_url)

    def euca_mach_and_size(self):
        reverse_link = reverse('api:v1:machine-list',
                              args=[self.euca_id.provider.id,
                                    self.euca_id.id])
        self.euca_machine_url = urljoin(settings.SERVER_URL, reverse_link)
        self.api_client.get(self.euca_machine_url)

        reverse_link = reverse('size-list',
                              args=[self.euca_id.provider.id,
                                    self.euca_id.id])
        self.euca_size_url = urljoin(settings.SERVER_URL, reverse_link)

        self.api_client.get(self.euca_size_url)

    def tearDown(self):
        self.api_client.logout()

    ##TEST CASES:
    #NOTE: Eucalyptus machine requests will not complete fully until node controller info added..
    # This is on a TODO at a later date..

    #def test_euca_machine_request(self):
    #    """
    #    Testing machine requests require specific order:
    #      * "Stand-up" an instance
    #      * Create a machine request
    #      * Approve a machine request
    #      * Verify machine request has gone to 'completed'
    #      * "Stand-up" the new machine
    #      * Delete an existing machine request
    #    """
    #    machine_alias = "emi-E7F8300F"
    #    size_alias = "m1.small"
    #    self.euca_mach_and_size()
    #    instance_id, instance_ip = standup_instance(
    #            self, self.euca_instance_url,
    #            machine_alias, size_alias, "test imaging")
    #    request_id = self.create_machine_request(
    #            self.euca_request_url,
    #            instance_id, instance_ip, self.euca_id.provider.id)
    #    approval_link = reverse('api:v1:direct-machine-request-action',
    #                          args=[request_id, 'approve'])
    #    euca_approval_url = urljoin(settings.SERVER_URL, approval_link)
    #    self.approve_machine_request(euca_approval_url)
    #    machine_request_url = reverse('api:v1:direct-machine-request-detail',
    #            args=[request_id,])
    #    new_machine_id = self.wait_for_machine_request(machine_request_url)
    #    machine_alias = new_machine_id
    #    instance_id, instance_ip = standup_instance(
    #            self, self.euca_instance_url,
    #            machine_alias, size_alias, "test imaging was successful",
    #            delete_after=True)

    #def test_euca_os_migration(self):
    #    euca_accounts = EucaAccounts(
    #            Provider.objects.get(location='EUCALYPTUS'))
    #    euca_img_class = euca_accounts.image_manager.__class__
    #    euca_img_creds = euca_accounts.image_creds
    #    os_accounts = OSAccounts(
    #            Provider.objects.get(location='OPENSTACK'))
    #    os_img_class = os_accounts.image_manager.__class__
    #    os_img_creds = os_accounts.image_creds
    #    migrate_args = {
    #            'download_dir':"/Storage/test",
    #            'image_id':"emi-E7F8300F",
    #            'image_name': "ATMO Migration Test %s"\
    #                    % datetime.now().strftime('%m%d_%H%M'),
    #            'xen_to_kvm':True,
    #            }
    #    migrate_image(euca_img_class, euca_img_creds,
    #                  os_img_class, os_img_creds,
    #                  **migrate_args)

    #def test_openstack_machine_request(self):
    #    """
    #    Testing machines must be done in order
    #      * Create a machine request
    #      * Approve a machine request
    #      * Verify a completed machine request
    #      * Delete a machine request
    #    # to verify a completed image:
    #    # Launch and Ensure: SSH, VNC, Shellinabox, Deploy access
    #    """
    #    machine_alias = "75fdfca4-d49d-4b2d-b919-a3297bc6d7ae"
    #    size_alias = "2"
    #    self.openstack_mach_and_size()
    #    instance_id, instance_ip = standup_instance(
    #            self, self.os_instance_url,
    #            machine_alias, size_alias, "test imaging")
    #    request_id = self.create_machine_request(
    #            self.os_request_url,
    #            instance_id, instance_ip, self.os_id.provider.id)
    #    #E-mail for approval sent to ADMINS here..
    #    #Image ready for approval after this line returns
    #    approval_link = reverse('api:v1:direct-machine-request-action',
    #                          args=[request_id, 'approve'])
    #    os_approval_url = urljoin(settings.SERVER_URL, approval_link)
    #    self.approve_machine_request(os_approval_url)
    #    #Machine will be imaged HERE.. Image EXISTS after this line returns!
    #    machine_request_url = reverse('api:v1:direct-machine-request-detail',
    #            args=[request_id,])
    #    new_machine_id = self.wait_for_machine_request(machine_request_url)
    #    machine_alias = new_machine_id
    #    instance_id, instance_ip = standup_instance(
    #            self, self.os_instance_url,
    #            machine_alias, size_alias, "test imaging successful",
    #            delete_after=True, first_launch=True)


    #TEST STEPS: Called indirectly by TEST CASES...


    def create_machine_request(self, machine_request_url,
                               instance_id, instance_ip, new_provider_id):
        post_data = {
            "name":"Testing Machine Request",
            "description":"This is only a test, "\
                          "as such it is not meant to be launched.",
            "instance": instance_id,
            "provider": new_provider_id,
            "vis":"public",
            "ip_address":instance_ip,
            "software":"",
            "sys":"",
            "exclude":"",
            "tags":"",
        }
        post_machine_resp = self.api_client.post(machine_request_url,
                                                 post_data, format='json')
        #Validate the output
        self.assertEqual(post_machine_resp.status_code, status.HTTP_201_CREATED)
        self.assertIsNotNone(post_machine_resp.data)
        #TODO:
        # Create 'expected output'
        # verify_expected_output(self, instance_launch_resp.data, self.expected_output)
        request_id = post_machine_resp.data['id']
        return request_id

    def approve_machine_request(self, machine_request_approval_url):
        mach_request_put = self.api_client.get(machine_request_approval_url)
        self.assertEqual(mach_request_put.status_code, status.HTTP_200_OK)

    def wait_for_machine_request(self, machine_request_url):
        finished = False
        minutes = 1
        attempts = 1
        while not finished:
            mach_request_get = self.api_client.get(machine_request_url)
            self.assertEqual(mach_request_get.status_code, status.HTTP_200_OK)
            mach_status = mach_request_get.data['status']
            new_machine = mach_request_get.data['new_machine']
            if 'error' in mach_status:
                raise Exception("Error occurred during imaging. "
                                "Will not wait for machine request to finish.")
                break
            if mach_status != 'completed':
                #5m, 5m, 5m, 5m, 5m, ...
                attempts += 1
                minutes = 5
                test_client.assertNotEqual(attempts, 10,
                    "Made 10 attempts to wait for an active instance. "
                    "Giving up..")
                continue
            finished = True
        complete_time = datetime.now()
        logger.info("Machine Request marked as completed. complete time:%s"
                    % (complete_time))
        return new_machine