コード例 #1
0
ファイル: test_server.py プロジェクト: open-craft/opencraft
    def test_sleep_until_state_changes(self, condition, mock_sleep, mock_update_status):
        """
        Check if sleep_until behaves correctly if condition to wait for
        is unfulfilled initially.
        """
        server = OpenStackServerFactory()
        status_queue = [
            server._status_to_building,
            server._status_to_booting,
            server._status_to_ready,
        ]
        status_queue.reverse() # To be able to use pop()

        def update_status():
            """ Simulate status progression """
            status_queue.pop()()

        mock_update_status.side_effect = update_status

        # Sleep until condition is fulfilled.
        # Use a small value for "timeout" to ensure that we can fail quickly
        # if server can not reach desired status because transition logic is broken:
        server.sleep_until(lambda: getattr(server.status, condition['name']), timeout=5)
        self.assertEqual(server.status, condition['expected_status'])
        self.assertEqual(mock_sleep.call_count, condition['required_transitions'] - 1)
コード例 #2
0
ファイル: test_server.py プロジェクト: replaceafill/opencraft
    def test_sleep_until_state_changes(self, condition, mock_sleep,
                                       mock_update_status):
        """
        Check if sleep_until behaves correctly if condition to wait for
        is unfulfilled initially.
        """
        server = OpenStackServerFactory()
        status_queue = [
            server._status_to_building,
            server._status_to_booting,
            server._status_to_ready,
        ]
        status_queue.reverse()  # To be able to use pop()

        def update_status():
            """ Simulate status progression """
            status_queue.pop()()

        mock_update_status.side_effect = update_status

        # Sleep until condition is fulfilled.
        # Use a small value for "timeout" to ensure that we can fail quickly
        # if server can not reach desired status because transition logic is broken:
        server.sleep_until(lambda: getattr(server.status, condition['name']),
                           timeout=5)
        self.assertEqual(server.status, condition['expected_status'])
        self.assertEqual(mock_sleep.call_count,
                         condition['required_transitions'] - 1)
コード例 #3
0
ファイル: test_server.py プロジェクト: open-craft/opencraft
 def test_reboot_server_wrong_status(self, server_status):
     """
     Attempt to reboot a server while in a status that doesn't allow it
     """
     server = OpenStackServerFactory(status=server_status)
     with self.assertRaises(WrongStateException):
         server.reboot()
コード例 #4
0
ファイル: test_server.py プロジェクト: replaceafill/opencraft
 def test_reboot_server_wrong_status(self, server_status):
     """
     Attempt to reboot a server while in a status that doesn't allow it
     """
     server = OpenStackServerFactory(status=server_status)
     with self.assertRaises(WrongStateException):
         server.reboot()
コード例 #5
0
ファイル: test_server.py プロジェクト: singuliere/opencraft
 def test_terminate_server_vm_created(self, openstack_id, server_status):
     """
     Terminate a server with a VM
     """
     server = OpenStackServerFactory(openstack_id=openstack_id, status=server_status)
     server.terminate()
     self.assertEqual(server.status, ServerStatus.Terminated)
     server.os_server.delete.assert_called_once_with()
コード例 #6
0
ファイル: test_server.py プロジェクト: open-craft/opencraft
 def test_terminate_server_vm_created(self, openstack_id, server_status):
     """
     Terminate a server with a VM
     """
     server = OpenStackServerFactory(openstack_id=openstack_id, status=server_status)
     server.terminate()
     self.assertEqual(server.status, ServerStatus.Terminated)
     server.os_server.delete.assert_called_once_with()
コード例 #7
0
ファイル: test_server.py プロジェクト: open-craft/opencraft
 def test_update_status_pending(self, mock_create_server):
     """
     Update status while the server is pending
     """
     mock_create_server.return_value.id = 'pending-server-id'
     server = OpenStackServerFactory()
     self.assertEqual(server.status, ServerStatus.Pending)
     self.assertIsInstance(server.update_status(), ServerStatus.Building)
     self.assertEqual(server.status, ServerStatus.Building)
コード例 #8
0
ファイル: test_server.py プロジェクト: replaceafill/opencraft
 def test_update_status_pending(self, mock_create_server):
     """
     Update status while the server is pending
     """
     mock_create_server.return_value.id = 'pending-server-id'
     server = OpenStackServerFactory()
     self.assertEqual(server.status, ServerStatus.Pending)
     self.assertIsInstance(server.update_status(), ServerStatus.Pending)
     self.assertEqual(server.status, ServerStatus.Pending)
コード例 #9
0
ファイル: test_server.py プロジェクト: singuliere/opencraft
    def test_sleep_until_invalid_timeout(self):
        """
        Check if sleep_until behaves correctly when passed an invalid timeout value.
        """
        server = OpenStackServerFactory()

        for value in (-1, 0):
            with self.assertRaises(AssertionError):
                server.sleep_until(lambda: server.status.accepts_ssh_commands, timeout=value)
コード例 #10
0
ファイル: test_server.py プロジェクト: open-craft/opencraft
    def test_sleep_until_invalid_timeout(self):
        """
        Check if sleep_until behaves correctly when passed an invalid timeout value.
        """
        server = OpenStackServerFactory()

        for value in (-1, 0):
            with self.assertRaises(AssertionError):
                server.sleep_until(lambda: server.status.accepts_ssh_commands, timeout=value)
コード例 #11
0
 def test_update_status_new(self, mock_create_server):
     """
     Update status while the server is new
     """
     mock_create_server.return_value.id = 'new-server-id'
     server = OpenStackServerFactory(os_server_fixture='openstack/api_server_1_building.json')
     self.assertEqual(server.status, ServerStatus.New)
     self.assertEqual(server.progress, ServerProgress.Running)
     self.assertIsInstance(server.update_status(), ServerStatus.Active)
     self.assertEqual(server.progress, ServerProgress.Running)
コード例 #12
0
ファイル: test_server.py プロジェクト: omarkhan/opencraft
 def test_update_status_new(self, mock_create_server):
     """
     Update status while the server is new
     """
     mock_create_server.return_value.id = 'new-server-id'
     server = OpenStackServerFactory(os_server_fixture='openstack/api_server_1_building.json')
     self.assertEqual(server.status, server.NEW)
     self.assertEqual(server.progress, server.PROGRESS_RUNNING)
     self.assertEqual(server.update_status(), server.ACTIVE)
     self.assertEqual(server.progress, server.PROGRESS_RUNNING)
コード例 #13
0
ファイル: test_server.py プロジェクト: brousch/opencraft
 def test_update_status_new(self, mock_create_server):
     """
     Update status while the server is new
     """
     mock_create_server.return_value.id = 'new-server-id'
     server = OpenStackServerFactory(os_server_fixture='openstack/api_server_1_building.json')
     self.assertEqual(server.update_status(), server.STARTED)
     self.assertEqual(server.status, server.STARTED)
     self.assertEqual(server.update_status(), server.STARTED)
     self.assertEqual(server.status, server.STARTED)
コード例 #14
0
ファイル: test_server.py プロジェクト: brousch/opencraft
 def test_terminate_new_server(self):
     """
     Terminate a server with a 'new' status
     """
     server = OpenStackServerFactory()
     server.terminate()
     self.assertEqual(server.status, server.TERMINATED)
     server.terminate() # This shouldn't change anything
     self.assertEqual(server.status, server.TERMINATED)
     self.assertFalse(server.nova.mock_calls)
コード例 #15
0
ファイル: test_server.py プロジェクト: taivo/opencraft
    def test_status_transitions(self):
        """
        Test that status transitions work as expected for different server workflows
        """
        # Normal workflow
        server = OpenStackServerFactory()
        self.assertEqual(server.status, ServerStatus.Pending)
        self._assert_status_conditions(server)

        server._status_to_building()
        self.assertEqual(server.status, ServerStatus.Building)
        self._assert_status_conditions(server)

        server._status_to_booting()
        self.assertEqual(server.status, ServerStatus.Booting)
        self._assert_status_conditions(server, vm_available=True)

        server._status_to_ready()
        self.assertEqual(server.status, ServerStatus.Ready)
        self._assert_status_conditions(server, is_steady_state=True, accepts_ssh_commands=True, vm_available=True)

        server._status_to_terminated()
        self.assertEqual(server.status, ServerStatus.Terminated)
        self._assert_status_conditions(server, is_steady_state=True)

        # Server creation fails
        instance_bad_server = BuildingOpenStackServerFactory()
        instance_bad_server._status_to_build_failed()
        self.assertEqual(instance_bad_server.status, ServerStatus.BuildFailed)
        self._assert_status_conditions(server, is_steady_state=True)
コード例 #16
0
ファイル: test_log_entry.py プロジェクト: sshyran/opencraft
 def test_log_delete_num_queries(self, mock_consul):
     """
     Check that the LogEntry.on_post_delete handler doesn't do more queries than necessary.
     """
     server = OpenStackServerFactory()  # Can't use self.server since deletion of it cascades to self.app_server
     with self.assertNumQueries(3):
         # We expect one query to check for a related appserver, one to delete the server, one to delete the LogEntry
         server.delete()
     log_entry = LogEntry.objects.create(text='blah')
     with self.assertNumQueries(1):
         log_entry.delete()
コード例 #17
0
ファイル: test_server.py プロジェクト: replaceafill/opencraft
 def test_terminate_server_vm_unavailable(self, server_status):
     """
     Terminate a server without a VM
     """
     server = OpenStackServerFactory(status=server_status)
     try:
         server.terminate()
     except AssertionError:
         self.fail('Termination logic tried to operate on non-existent VM.')
     else:
         self.assertEqual(server.status, ServerStatus.Terminated)
コード例 #18
0
ファイル: test_server.py プロジェクト: open-craft/opencraft
 def test_terminate_server_vm_unavailable(self, server_status):
     """
     Terminate a server without a VM
     """
     server = OpenStackServerFactory(status=server_status)
     try:
         server.terminate()
     except AssertionError:
         self.fail('Termination logic tried to operate on non-existent VM.')
     else:
         self.assertEqual(server.status, ServerStatus.Terminated)
コード例 #19
0
 def test_log_delete_num_queries(self):
     """
     Check that the LogEntry.on_post_delete handler doesn't do more queries than necessary.
     """
     server = OpenStackServerFactory()  # Can't use self.server since deletion of it cascades to self.app_server
     with self.assertNumQueries(3):
         # We expect one query to check for a related appserver, one to delete the server, one to delete the LogEntry
         server.delete()
     log_entry = LogEntry.objects.create(text='blah')
     with self.assertNumQueries(1):
         log_entry.delete()
コード例 #20
0
ファイル: test_server.py プロジェクト: antoviaque/opencraft
 def test_terminate_new_server(self):
     """
     Terminate a server with a 'new' status
     """
     server = OpenStackServerFactory()
     server.terminate()
     self.assertEqual(server.status, ServerStatus.Terminated)
     self.assertEqual(server.progress, ServerProgress.Success)
     server.terminate() # This shouldn't change anything
     self.assertEqual(server.status, ServerStatus.Terminated)
     self.assertEqual(server.progress, ServerProgress.Success)
     self.assertFalse(server.nova.mock_calls)
コード例 #21
0
ファイル: test_server.py プロジェクト: open-craft/opencraft
    def test_start_server_fails(self, mock_create_server):
        """
        Check if 'start' behaves correctly when server creation fails
        """
        mock_create_server.side_effect = novaclient.exceptions.ClientException(400)
        server = OpenStackServerFactory()

        self.assertEqual(server.status, ServerStatus.Pending)
        server.start()

        server = OpenStackServer.objects.get(pk=server.pk)
        self.assertEqual(server.status, ServerStatus.BuildFailed)
コード例 #22
0
ファイル: test_server.py プロジェクト: singuliere/opencraft
    def test_start_server_fails(self, mock_create_server):
        """
        Check if 'start' behaves correctly when server creation fails
        """
        mock_create_server.side_effect = novaclient.exceptions.ClientException(400)
        server = OpenStackServerFactory()

        self.assertEqual(server.status, ServerStatus.Pending)
        server.start()

        server = OpenStackServer.objects.get(pk=server.pk)
        self.assertEqual(server.status, ServerStatus.BuildFailed)
コード例 #23
0
ファイル: test_server.py プロジェクト: open-craft/opencraft
    def test_sleep_until_timeout(self, mock_sleep, mock_update_status):
        """
        Check if sleep_until behaves correctly if condition to wait for
        is unfulfilled when timeout is reached.
        """
        server = OpenStackServerFactory()

        def update_status():
            """ Simulate status progression """
            server._status_to_building()
        mock_update_status.side_effect = update_status

        with self.assertRaises(TimeoutError):
            server.sleep_until(lambda: server.status.accepts_ssh_commands, timeout=1)
            self.assertEqual(mock_sleep.call_count, 1)
コード例 #24
0
ファイル: test_server.py プロジェクト: brousch/opencraft
    def test_sleep_until_status_list(self, mock_sleep, mock_update_status):
        """
        Sleep until the server gets to one of the status in a list
        """
        server = OpenStackServerFactory()
        status_queue = [server.STARTED, server.BOOTED]
        status_queue.reverse() # To be able to use pop()

        def update_status():
            """ Simulate status progression successive runs """
            server.status = status_queue.pop()
        mock_update_status.side_effect = update_status

        self.assertEqual(server.sleep_until_status([server.TERMINATED, server.BOOTED]), server.BOOTED)
        self.assertEqual(server.status, server.BOOTED)
コード例 #25
0
    def test_sleep_until_timeout(self, mock_sleep, mock_update_status):
        """
        Check if sleep_until behaves correctly if condition to wait for
        is unfulfilled when timeout is reached.
        """
        server = OpenStackServerFactory()

        def update_status():
            """ Simulate status progression """
            server._transition(server._status_to_started, progress=ServerProgress.Success)
        mock_update_status.side_effect = update_status

        with self.assertRaises(TimeoutError):
            server.sleep_until(lambda: server.status.accepts_ssh_commands, timeout=1)
            self.assertEqual(mock_sleep.call_count, 1)
コード例 #26
0
 def setUp(self):
     """
     Set up an instance and server to use for testing.
     """
     super().setUp()
     self.instance = OpenEdXInstanceFactory(sub_domain='my.instance')
     self.server = OpenStackServerFactory(instance=self.instance, openstack_id='vm1_id')
コード例 #27
0
    def test_get_log_entries(self):
        """
        GET - Log entries
        """
        self.api_client.login(username='******', password='******')
        instance = OpenEdXInstanceFactory(sub_domain='instance0')
        server = OpenStackServerFactory(openstack_id="vm0", instance=instance)
        instance.logger.info("info")
        instance.logger.error("error")
        server.logger.info("info")
        server.logger.error("error")

        response = self.api_client.get('/api/v1/openedxinstance/{pk}/'.format(pk=instance.pk))
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        expected_list = [
            {'level': 'INFO', 'text': 'instance.models.instance  | instance=instance0 | info'},
            {'level': 'ERROR', 'text': 'instance.models.instance  | instance=instance0 | error'},
            {'level': 'INFO', 'text': 'instance.models.server    | instance=instance0,server=vm0 | info'},
            {'level': 'ERROR', 'text': 'instance.models.server    | instance=instance0,server=vm0 | error'},
        ]
        self.assertEqual(len(expected_list), len(response.data['log_entries']))

        for expected_entry, log_entry in zip(expected_list, response.data['log_entries']):
            self.assertEqual(expected_entry['level'], log_entry['level'])
            self.assertEqual(expected_entry['text'], log_entry['text'])
コード例 #28
0
ファイル: test_server.py プロジェクト: singuliere/opencraft
    def test_sleep_until_timeout(self, mock_sleep, mock_update_status):
        """
        Check if sleep_until behaves correctly if condition to wait for
        is unfulfilled when timeout is reached.
        """
        server = OpenStackServerFactory()

        def update_status():
            """ Simulate status progression """
            server._status_to_building()
        mock_update_status.side_effect = update_status

        with self.assertRaises(TimeoutError) as timeout_error:
            server.sleep_until(lambda: server.status.accepts_ssh_commands, timeout=1)
            self.assertEqual(mock_sleep.call_count, 1)
            self.assertIn("Waited 0.01", timeout_error.exception)
コード例 #29
0
ファイル: test_server.py プロジェクト: replaceafill/opencraft
 def test_vm_created(self, openstack_id, server_status):
     """
     Test that server correctly reports that a VM has been created for it
     """
     server = OpenStackServerFactory(openstack_id=openstack_id,
                                     status=server_status)
     self.assertTrue(server.vm_created)
コード例 #30
0
ファイル: test_server.py プロジェクト: singuliere/opencraft
    def test_terminate_server_not_found(self, openstack_id, server_status):
        """
        Terminate a server for which the corresponding VM doesn't exist anymore
        """
        server = OpenStackServerFactory(openstack_id=openstack_id, status=server_status)

        def raise_not_found(): #pylint: disable=missing-docstring
            raise novaclient.exceptions.NotFound('not-found')
        server.os_server.delete.side_effect = raise_not_found
        server.logger = Mock()
        mock_logger = server.logger

        server.terminate()
        self.assertEqual(server.status, ServerStatus.Terminated)
        server.os_server.delete.assert_called_once_with()
        mock_logger.error.assert_called_once_with(AnyStringMatching('Error while attempting to terminate server'))
コード例 #31
0
ファイル: test_server.py プロジェクト: open-craft/opencraft
    def test_terminate_server_not_found(self, openstack_id, server_status):
        """
        Terminate a server for which the corresponding VM doesn't exist anymore
        """
        server = OpenStackServerFactory(openstack_id=openstack_id, status=server_status)

        def raise_not_found(): #pylint: disable=missing-docstring
            raise novaclient.exceptions.NotFound('not-found')
        server.os_server.delete.side_effect = raise_not_found
        server.logger = Mock()
        mock_logger = server.logger

        server.terminate()
        self.assertEqual(server.status, ServerStatus.Terminated)
        server.os_server.delete.assert_called_once_with()
        mock_logger.error.assert_called_once_with(AnyStringMatching('Error while attempting to terminate server'))
コード例 #32
0
ファイル: test_log_entry.py プロジェクト: taivo/opencraft
 def setUp(self):
     """
     Set up an instance and server to use for testing.
     """
     super().setUp()
     self.instance = SingleVMOpenEdXInstanceFactory(sub_domain='my.instance')
     self.server = OpenStackServerFactory(instance=self.instance, openstack_id='vm1_id')
コード例 #33
0
ファイル: test_log_entry.py プロジェクト: sshyran/opencraft
    def test_log_delete(self, mock_consul):
        """
        Check `log_entries` output for combination of instance & server logs
        """
        # Clear out existing log entries to make sure we're starting with a clean slate:
        for log_entry in LogEntry.objects.all():
            log_entry.delete()

        server1 = self.server
        server2 = OpenStackServerFactory(openstack_id='vm2_id')

        self.instance.logger.info('Line #1, on instance')
        server1.logger.info('Line #2, on server 1')
        server2.logger.info('Line #3, on server 2')

        self.assertEqual(LogEntry.objects.count(), 3)
        # Delete server 1:
        server1_id = server1.pk
        server1.delete()
        # Now its log entry should be deleted:
        entries = LogEntry.objects.order_by('pk').all().values_list('text', flat=True)
        for entry_text in entries:
            self.assertNotIn('Line #2', entry_text)
        self.assertIn('Line #1, on instance', entries[0])
        self.assertIn('Line #3, on server 2', entries[1])
        self.assertIn(
            'Deleted 1 log entries for deleted OpenStack VM instance with ID {}'.format(server1_id),
            entries[2]
        )
コード例 #34
0
ファイル: test_server.py プロジェクト: brousch/opencraft
    def test_sleep_until_status(self, mock_sleep, mock_update_status):
        """
        Sleep until the server gets to 'booted' status (single status string argument)
        """
        server = OpenStackServerFactory()
        status_queue = [server.STARTED, server.STARTED, server.ACTIVE, server.BOOTED, server.TERMINATED]
        status_queue.reverse() # To be able to use pop()

        def update_status():
            """ Simulate status progression successive runs """
            server.status = status_queue.pop()
        mock_update_status.side_effect = update_status

        self.assertEqual(server.sleep_until_status(server.BOOTED), server.BOOTED)
        self.assertEqual(server.status, server.BOOTED)
        self.assertEqual(mock_sleep.call_count, 3)
        self.assertEqual(status_queue, [server.TERMINATED])
コード例 #35
0
ファイル: test_logging.py プロジェクト: brousch/opencraft
    def test_log_text(self):
        """
        Check `log_text` output for combination of instance & server logs
        """
        instance = OpenEdXInstanceFactory()
        server = OpenStackServerFactory(instance=instance)

        with freeze_time("2015-08-05 18:07:00"):
            instance.log('info', 'Line #1, on instance')

        with freeze_time("2015-08-05 18:07:01"):
            server.log('info', 'Line #2, on server')

        with freeze_time("2015-08-05 18:07:02"):
            instance.log('debug', 'Line #3, on instance (debug, not published by default)')

        with freeze_time("2015-08-05 18:07:03"):
            instance.log('info', 'Line #4, on instance')

        with freeze_time("2015-08-05 18:07:04"):
            instance.log('warn', 'Line #5, on instance (warn)')

        with freeze_time("2015-08-05 18:07:05"):
            server.log('info', 'Line #6, on server')

        with freeze_time("2015-08-05 18:07:06"):
            server.log('exception', 'Line #7, on server (exception)')

        self.assertEqual(instance.log_text, (
            "2015-08-05 18:07:00 [info] Line #1, on instance\n"
            "2015-08-05 18:07:01 [info] Line #2, on server\n"
            "2015-08-05 18:07:03 [info] Line #4, on instance\n"
            "2015-08-05 18:07:04 [warn] Line #5, on instance (warn)\n"
            "2015-08-05 18:07:05 [info] Line #6, on server\n"
            "2015-08-05 18:07:06 [exception] Line #7, on server (exception)\n"))
コード例 #36
0
ファイル: test_server.py プロジェクト: singuliere/opencraft
 def test_os_server(self, mock_create_server):
     """
     Get the os_server attribute of a new server
     This should ensure the server is started to be able to return a value
     """
     mock_create_server.return_value.id = 'pending-server-id'
     server = OpenStackServerFactory()
     self.assertEqual(server.os_server, server.nova.servers.get.return_value)
     self.assertEqual(server.nova.mock_calls, [call.servers.get('pending-server-id')])
コード例 #37
0
 def test_provision_not_ready(self):
     """
     POST /:id/provision - Status not ready
     """
     self.api_client.login(username='******', password='******')
     instance = OpenEdXInstanceFactory()
     OpenStackServerFactory(instance=instance, progress=OpenStackServer.Progress.Running)
     self.assertEqual(instance.progress, OpenStackServer.Progress.Running)
     response = self.api_client.post('/api/v1/openedxinstance/{pk}/provision/'.format(pk=instance.pk))
     self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
コード例 #38
0
 def test_new_server(self):
     """
     New OpenStackServer object
     """
     self.assertFalse(OpenStackServer.objects.all())
     server = OpenStackServerFactory()
     self.assertEqual(OpenStackServer.objects.get().pk, server.pk)
     self.assertEqual(str(server), 'New OpenStack Server')
     self.assertEqual(server.status, ServerStatus.New)
     self.assertEqual(server.progress, ServerProgress.Running)
コード例 #39
0
ファイル: test_server.py プロジェクト: SaptakS/opencraft
    def test_terminate_server_openstack_api_error(self, exception):
        """
        Terminate a server when there are errors connecting to the OpenStack API
        """
        server = OpenStackServerFactory()

        def raise_openstack_api_error():  #pylint: disable=missing-docstring
            raise exception

        server.os_server.delete.side_effect = raise_openstack_api_error

        server.logger = Mock()
        mock_logger = server.logger

        server.terminate()
        self.assertEqual(server.status, ServerStatus.Unknown)
        server.os_server.delete.assert_called_once_with()
        mock_logger.error.assert_called_once_with(
            AnyStringMatching('Unable to reach the OpenStack API due to'),
            exception)
コード例 #40
0
ファイル: test_server.py プロジェクト: replaceafill/opencraft
 def test_new_server(self):
     """
     New OpenStackServer object
     """
     self.assertFalse(OpenStackServer.objects.all())
     server = OpenStackServerFactory()
     created_server = OpenStackServer.objects.get()
     self.assertEqual(created_server.pk, server.pk)
     self.assertIsInstance(created_server.status, ServerStatus.Pending)
     self.assertEqual(str(server), 'Pending OpenStack Server')
     self.assertEqual(server.status, ServerStatus.Pending)
コード例 #41
0
ファイル: test_server.py プロジェクト: open-craft/opencraft
    def test_sleep_until_condition_already_fulfilled(self, condition, mock_sleep, mock_update_status):
        """
        Check if sleep_until behaves correctly if condition to wait for
        is already fulfilled.
        """
        server = OpenStackServerFactory()
        status_queue = [
            server._status_to_building,
            server._status_to_booting,
            server._status_to_ready,
        ]
        # Transition to state fulfilling condition
        for state_transition in status_queue:
            state_transition()

        # Sleep until condition is fulfilled.
        # Use a small value for "timeout" to ensure that we can fail quickly
        # if server can not reach desired status because transition logic is broken:
        server.sleep_until(lambda: getattr(server.status, condition), timeout=5)
        self.assertEqual(server.status, ServerStatus.Ready)
        self.assertEqual(mock_sleep.call_count, 0)
コード例 #42
0
ファイル: test_server.py プロジェクト: open-craft/opencraft
    def test_sleep_until_steady_state(self, mock_building_is_steady_state, mock_update_status):
        """
        Check if sleep_until behaves correctly if condition to wait for
        can not be fulfilled because server is in a steady state
        (that doesn't fulfill the condition).
        """
        server = OpenStackServerFactory()

        def update_status():
            """ Simulate status progression """
            server._status_to_building()
        mock_update_status.side_effect = update_status

        # Pretend that Status.Building (which doesn't accept SSH commands) is a steady state
        mock_building_is_steady_state.return_value = True

        with self.assertRaises(SteadyStateException):
            # Try to sleep until condition is fulfilled.
            # Use a small value for "timeout" to ensure that we can fail quickly
            # if server can not reach desired status because transition logic is broken:
            server.sleep_until(lambda: server.status.accepts_ssh_commands, timeout=5)
コード例 #43
0
ファイル: test_server.py プロジェクト: replaceafill/opencraft
    def test_start_server(self, mock_create_server):
        """
        Start a new server
        """
        mock_create_server.return_value.id = 'pending-server-id'
        server = OpenStackServerFactory()

        self.assertEqual(server.status, ServerStatus.Pending)
        server.start()
        mock_create_server.assert_called_once_with(
            server.nova,
            AnyStringMatching(r'test-inst-\d+'),
            flavor_selector=settings.OPENSTACK_SANDBOX_FLAVOR,
            image_selector=settings.OPENSTACK_SANDBOX_BASE_IMAGE,
            key_name=settings.OPENSTACK_SANDBOX_SSH_KEYNAME,
        )

        server = OpenStackServer.objects.get(pk=server.pk)
        self.assertEqual(server.status, ServerStatus.Building)
        self.assertEqual(server.openstack_id, 'pending-server-id')
        self.assertEqual(str(server), 'pending-server-id')
コード例 #44
0
ファイル: test_server.py プロジェクト: open-craft/opencraft
    def test_start_server(self, mock_create_server):
        """
        Start a new server
        """
        mock_create_server.return_value.id = 'pending-server-id'
        server = OpenStackServerFactory()

        self.assertEqual(server.status, ServerStatus.Pending)
        server.start()
        mock_create_server.assert_called_once_with(
            server.nova,
            AnyStringMatching(r'test-inst-\d+'),
            settings.OPENSTACK_SANDBOX_FLAVOR,
            settings.OPENSTACK_SANDBOX_BASE_IMAGE,
            key_name=settings.OPENSTACK_SANDBOX_SSH_KEYNAME,
        )

        server = OpenStackServer.objects.get(pk=server.pk)
        self.assertEqual(server.status, ServerStatus.Building)
        self.assertEqual(server.openstack_id, 'pending-server-id')
        self.assertEqual(str(server), 'pending-server-id')
コード例 #45
0
ファイル: test_server.py プロジェクト: singuliere/opencraft
    def test_sleep_until_steady_state(self, mock_building_is_steady_state, mock_update_status):
        """
        Check if sleep_until behaves correctly if condition to wait for
        can not be fulfilled because server is in a steady state
        (that doesn't fulfill the condition).
        """
        server = OpenStackServerFactory()

        def update_status():
            """ Simulate status progression """
            server._status_to_building()
        mock_update_status.side_effect = update_status

        # Pretend that Status.Building (which doesn't accept SSH commands) is a steady state
        mock_building_is_steady_state.return_value = True

        with self.assertRaises(SteadyStateException):
            # Try to sleep until condition is fulfilled.
            # Use a small value for "timeout" to ensure that we can fail quickly
            # if server can not reach desired status because transition logic is broken:
            server.sleep_until(lambda: server.status.accepts_ssh_commands, timeout=5)
コード例 #46
0
ファイル: test_server.py プロジェクト: singuliere/opencraft
    def test_sleep_until_condition_already_fulfilled(self, condition, mock_sleep, mock_update_status):
        """
        Check if sleep_until behaves correctly if condition to wait for
        is already fulfilled.
        """
        server = OpenStackServerFactory()
        status_queue = [
            server._status_to_building,
            server._status_to_booting,
            server._status_to_ready,
        ]
        # Transition to state fulfilling condition
        for state_transition in status_queue:
            state_transition()

        # Sleep until condition is fulfilled.
        # Use a small value for "timeout" to ensure that we can fail quickly
        # if server can not reach desired status because transition logic is broken:
        server.sleep_until(lambda: getattr(server.status, condition), timeout=5)
        self.assertEqual(server.status, ServerStatus.Ready)
        self.assertEqual(mock_sleep.call_count, 0)
コード例 #47
0
    def test_get_details(self):
        """
        GET - Detailed attributes
        """
        self.api_client.login(username='******', password='******')

        test_openstack_id = 'test-openstack-id'
        server = OpenStackServerFactory(openstack_id=test_openstack_id)
        response = self.api_client.get('/api/v1/openstackserver/{pk}/'.format(pk=server.id))
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.check_serialized_server(response.data, server)
        self.assertEqual(response.data['openstack_id'], test_openstack_id)
コード例 #48
0
ファイル: test_server.py プロジェクト: brousch/opencraft
    def test_start_server(self, mock_create_server):
        """
        Start a new server
        """
        mock_create_server.return_value.id = 'new-server-id'
        server = OpenStackServerFactory()

        self.assertEqual(server.status, server.NEW)
        server.start()
        mock_create_server.assert_called_once_with(
            server.nova,
            AnyStringMatching(r'instance\d+\.test'),
            {"ram": 4096, "disk": 40},
            {"name": "Ubuntu 12.04"},
            key_name='opencraft',
        )

        server = OpenStackServer.objects.get(pk=server.pk)
        self.assertEqual(server.status, server.STARTED)
        self.assertEqual(server.openstack_id, 'new-server-id')
        self.assertEqual(str(server), 'new-server-id')
コード例 #49
0
ファイル: test_server.py プロジェクト: singuliere/opencraft
 def test_invalid_status_transitions(self, transition):
     """
     Test that invalid status transitions raise exception
     """
     # TODO: Get pylint to see state as an iterable
     invalid_from_states = (state for state in ServerStatus.states #pylint: disable=not-an-iterable
                            if state not in transition['from_states'])
     for invalid_from_state in invalid_from_states:
         instance = OpenStackServerFactory(status=invalid_from_state)
         self.assertEqual(instance.status, invalid_from_state)
         with self.assertRaises(WrongStateException):
             getattr(instance, transition['name'])()
コード例 #50
0
    def test_sleep_until_condition_already_fulfilled(self, mock_sleep, mock_update_status):
        """
        Check if sleep_until behaves correctly if condition to wait for
        is already fulfilled.
        """
        conditions = [
            lambda: server.status.is_steady_state,
            lambda: server.status.accepts_ssh_commands,
        ]
        for condition in conditions:
            server = OpenStackServerFactory()
            status_queue = [
                server._status_to_started,
                server._status_to_active,
                server._status_to_booted,
            ]
            # Transition to state fulfilling condition
            for state_transition in status_queue:
                server._transition(state_transition, progress=ServerProgress.Success)

            # Sleep until condition is fulfilled.
            # Use a small value for "timeout" to ensure that we can fail quickly
            # if server can not reach desired status because transition logic is broken:
            server.sleep_until(condition, timeout=5)
            self.assertEqual(server.status, ServerStatus.Booted)
            self.assertEqual(server.progress, ServerProgress.Success)
            self.assertEqual(mock_sleep.call_count, 0)
コード例 #51
0
    def test_get_superuser(self):
        """
        GET - Authenticated access through a superuser account.
        """
        self.api_client.login(username='******', password='******')
        response = self.api_client.get('/api/v1/openstackserver/')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data, [])

        server = OpenStackServerFactory()
        response = self.api_client.get('/api/v1/openstackserver/')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.check_serialized_server(response.data[0], server)
コード例 #52
0
    def test_start_server(self, mock_create_server):
        """
        Start a new server
        """
        mock_create_server.return_value.id = 'new-server-id'
        server = OpenStackServerFactory()

        self.assertEqual(server.status, ServerStatus.New)
        self.assertEqual(server.progress, ServerProgress.Running)
        server.start()
        mock_create_server.assert_called_once_with(
            server.nova,
            AnyStringMatching(r'instance\d+\.test'),
            {"ram": 4096, "disk": 40},
            {"name": "Ubuntu 12.04"},
            key_name='opencraft',
        )

        server = OpenStackServer.objects.get(pk=server.pk)
        self.assertEqual(server.status, ServerStatus.Started)
        self.assertEqual(server.progress, ServerProgress.Success)
        self.assertEqual(server.openstack_id, 'new-server-id')
        self.assertEqual(str(server), 'new-server-id')
コード例 #53
0
ファイル: test_instance.py プロジェクト: taivo/opencraft
 def test_server_status(self):
     """
     Server status of an instance with one active server
     """
     instance = SingleVMOpenEdXInstanceFactory()
     self.assertIsNone(instance.server_status)
     server = OpenStackServerFactory(instance=instance)
     self.assertEqual(instance.server_status, Server.Status.Pending)
     server._status_to_building()
     self.assertEqual(instance.server_status, Server.Status.Building)
     server._status_to_booting()
     self.assertEqual(instance.server_status, Server.Status.Booting)
     server._status_to_ready()
     self.assertEqual(instance.server_status, Server.Status.Ready)
     server._status_to_terminated()
     self.assertIsNone(instance.server_status)
     bad_instance = SingleVMOpenEdXInstanceFactory()
     bad_server = BuildingOpenStackServerFactory(instance=bad_instance)
     bad_server._status_to_build_failed()
     self.assertEqual(bad_instance.server_status, Server.Status.BuildFailed)
コード例 #54
0
    def test_sleep_until_state_changes(self, mock_sleep, mock_update_status):
        """
        Check if sleep_until behaves correctly if condition to wait for
        is unfulfilled initially.
        """
        conditions = [
            lambda: server.status.is_steady_state,
            lambda: server.status.accepts_ssh_commands,
        ]

        def scoped_update_status(server=None, status_queue=None):
            """ Return mock update_status scoped to a specific server and status_queue """
            def update_status():
                """ Simulate status progression """
                server._transition(status_queue.pop(), progress=ServerProgress.Success)
            return update_status

        for condition in conditions:
            server = OpenStackServerFactory()
            status_queue = [
                server._status_to_started,
                server._status_to_active,
                server._status_to_booted,
            ]
            status_queue.reverse() # To be able to use pop()

            mock_update_status.side_effect = scoped_update_status(server, status_queue)
            mock_sleep.call_count = 0

            # Sleep until condition is fulfilled.
            # Use a small value for "timeout" to ensure that we can fail quickly
            # if server can not reach desired status because transition logic is broken:
            server.sleep_until(condition, timeout=5)
            self.assertEqual(server.status, ServerStatus.Booted)
            self.assertEqual(server.progress, ServerProgress.Success)
            self.assertEqual(mock_sleep.call_count, 2)
コード例 #55
0
ファイル: test_log_entry.py プロジェクト: taivo/opencraft
class LoggingTestCase(TestCase):
    """
    Test cases for logging
    """
    def setUp(self):
        """
        Set up an instance and server to use for testing.
        """
        super().setUp()
        self.instance = SingleVMOpenEdXInstanceFactory(sub_domain='my.instance')
        self.server = OpenStackServerFactory(instance=self.instance, openstack_id='vm1_id')

    def check_log_entries(self, entries, expected):
        """
        Check that the given entries match the expected log output.
        """
        for entry, (date, level, text) in zip(entries, expected):
            self.assertEqual(entry.created.strftime("%Y-%m-%d %H:%M:%S"), date)
            self.assertEqual(entry.level, level)
            self.assertEqual(entry.text, text)

    def test_default_log_level(self):
        """
        Check that the default log level is INFO
        """
        log_entry = LogEntry(text='OHAI')
        self.assertEqual(log_entry.level, 'INFO')

    def test_log_entries(self):
        """
        Check `log_entries` output for combination of instance & server logs
        """
        lines = [
            ("2015-08-05 18:07:00", self.instance.logger.info, 'Line #1, on instance'),
            ("2015-08-05 18:07:01", self.server.logger.info, 'Line #2, on server'),
            ("2015-08-05 18:07:02", self.instance.logger.debug,
             'Line #3, on instance (debug, not published by default)'),
            ("2015-08-05 18:07:03", self.instance.logger.info, 'Line #4, on instance'),
            ("2015-08-05 18:07:04", self.instance.logger.warn, 'Line #5, on instance (warn)'),
            ("2015-08-05 18:07:05", self.server.logger.info, 'Line #6, on server'),
            ("2015-08-05 18:07:06", self.server.logger.critical, 'Line #7, exception'),
        ]

        for date, log, text in lines:
            with freeze_time(date):
                log(text)

        instance_prefix = 'instance.models.instance  | instance=my.instance | '
        server_prefix = 'instance.models.server    | instance=my.instance,server=vm1_id | '
        expected = [
            ("2015-08-05 18:07:00", 'INFO', instance_prefix + 'Line #1, on instance'),
            ("2015-08-05 18:07:01", 'INFO', server_prefix + 'Line #2, on server'),
            ("2015-08-05 18:07:03", 'INFO', instance_prefix + 'Line #4, on instance'),
            ("2015-08-05 18:07:04", 'WARNING', instance_prefix + 'Line #5, on instance (warn)'),
            ("2015-08-05 18:07:05", 'INFO', server_prefix + 'Line #6, on server'),
            ("2015-08-05 18:07:06", 'CRITICAL', server_prefix + 'Line #7, exception'),
        ]
        self.check_log_entries(self.instance.log_entries, expected)

        # Check that the `LOG_LIMIT` setting is respected
        with override_settings(LOG_LIMIT=3):
            self.check_log_entries(self.instance.log_entries, expected[-3:])

    @patch('instance.logging.publish_data')
    def test_log_publish(self, mock_publish_data):
        """
        Logger sends an event to the client on each new log entry added
        """
        with freeze_time("2015-09-21 21:07:00"):
            self.instance.logger.info('Text the client should see')

        mock_publish_data.assert_called_with('log', {
            'log_entry': {
                'created': '2015-09-21T21:07:00Z',
                'level': 'INFO',
                'text': 'instance.models.instance  | instance=my.instance | Text the client should see',
            },
            'type': 'instance_log',
            'instance_id': self.instance.pk,
        })

        with freeze_time("2015-09-21 21:07:01"):
            self.server.logger.info('Text the client should also see, with unicode «ταБЬℓσ»')

        mock_publish_data.assert_called_with('log', {
            'log_entry': {
                'created': '2015-09-21T21:07:01Z',
                'level': 'INFO',
                'text': ('instance.models.server    | instance=my.instance,server=vm1_id | Text the client '
                         'should also see, with unicode «ταБЬℓσ»'),
            },
            'type': 'instance_log',
            'instance_id': self.instance.pk,
            'server_id': self.server.pk,
        })

    def test_log_delete(self):
        """
        Check `log_entries` output for combination of instance & server logs
        """
        server1 = self.server
        server2 = OpenStackServerFactory(instance=self.instance, openstack_id='vm2_id')

        self.instance.logger.info('Line #1, on instance')
        server1.logger.info('Line #2, on server 1')
        server2.logger.info('Line #3, on server 2')

        self.assertEqual(LogEntry.objects.count(), 3)
        # Delete server 1:
        server1_id = server1.pk
        server1.delete()
        # Now its log entry should be deleted:
        entries = LogEntry.objects.order_by('pk').all().values_list('text', flat=True)
        for entry_text in entries:
            self.assertNotIn('Line #2', entry_text)
        self.assertIn('Line #1, on instance', entries[0])
        self.assertIn('Line #3, on server 2', entries[1])
        self.assertIn(
            'Deleted 1 log entries for deleted open stack server instance with ID {}'.format(server1_id),
            entries[2]
        )

    def test_log_num_queries(self):
        """
        Check that logging to the LogEntry table doesn't do more queries than necessary.

        The expected queries upon inserting a log entry are:
        1. SELECT (1) AS "a" FROM "django_content_type" WHERE "django_content_type"."id" = {content_type_id} LIMIT 1
        2. SELECT (1) AS "a" FROM "instance_openstackserver" WHERE "instance_openstackserver"."id" = {object_id} LIMIT 1
        3. INSERT INTO "instance_logentry" (...)

        The first two are used to validate the foreign keys. 1. is added by django, and 2. is
        added by us since the object_id foreign key constraint is not enforced by the database.
        """
        with self.assertNumQueries(3):
            self.server.logger.info('some log message')

    def test_log_delete_num_queries(self):
        """
        Check that the LogEntry.on_post_delete handler doesn't do more queries than necessary.
        """
        with self.assertNumQueries(2):  # one query to delete the server; one to delete the LogEntry
            self.server.delete()
        log_entry = LogEntry.objects.create(text='blah')
        with self.assertNumQueries(1):
            log_entry.delete()

    def test_str_repr(self):
        """
        Test the string representation of a LogEntry object
        """
        msg = 'We have entered a spectacular binary star system in the Kavis Alpha sector'
        with freeze_time("2015-10-20 20:10:15"):
            self.server.logger.info(msg)
        log_entry = LogEntry.objects.order_by('-pk')[0]
        self.assertEqual(
            str(log_entry),
            '2015-10-20 20:10:15 |     INFO | instance.models.server    | instance=my.instance,server=vm1_id | ' + msg,
        )

    def test_invalid_content_type_object_id_combo(self):
        """
        Test that content_type and object_id cannot be set on their own
        """
        text = 'We are en route to Mintaka III.'

        def check_exception(exc):
            """ Check that the given exception contains the expected message """
            self.assertEqual(
                exc.messages,
                ['LogEntry content_type and object_id must both be set or both be None.'],
            )

        with self.assertRaises(ValidationError) as context:
            LogEntry.objects.create(text=text, content_type_id=None, object_id=self.server.pk)
        check_exception(context.exception)

        content_type = ContentType.objects.get_for_model(self.server)
        with self.assertRaises(ValidationError) as context:
            LogEntry.objects.create(text=text, content_type_id=content_type.pk, object_id=None)
        check_exception(context.exception)

    def test_invalid_object_id(self):
        """
        Test that object_id validity is enforced at the application level.
        """
        content_type = ContentType.objects.get_for_model(self.server)
        with self.assertRaises(ValidationError) as context:
            LogEntry.objects.create(
                text='We are departing the Rana system for Starbase 133.',
                content_type=content_type,
                object_id=987654321,  # An invalid ID
            )
        self.assertEqual(
            context.exception.messages,
            ['Object attached to LogEntry has bad content_type or primary key'],
        )

    def test_log_error_entries(self):
        """
        Check `log_error_entries` output for combination of instance & server logs
        """
        with freeze_time("2015-08-05 18:07:00"):
            self.instance.logger.info('Line #1, on instance')

        with freeze_time("2015-08-05 18:07:01"):
            self.instance.logger.error('Line #2, on server')

        with freeze_time("2015-08-05 18:07:02"):
            self.instance.logger.debug('Line #3, on instance (debug, not published by default)')

        with freeze_time("2015-08-05 18:07:03"):
            self.server.logger.critical('Line #4, on instance')

        with freeze_time("2015-08-05 18:07:04"):
            self.instance.logger.warn('Line #5, on instance (warn)')

        with freeze_time("2015-08-05 18:07:05"):
            self.server.logger.info('Line #6, on server')

        with freeze_time("2015-08-05 18:07:06"):
            self.instance.logger.critical('Line #7, exception')

        entries = self.instance.log_error_entries
        self.assertEqual(entries[0].level, "ERROR")
        self.assertEqual(entries[0].created.strftime("%Y-%m-%d %H:%M:%S"), "2015-08-05 18:07:01")
        self.assertEqual(entries[0].text,
                         "instance.models.instance  | instance=my.instance | Line #2, on server")

        self.assertEqual(entries[1].level, "CRITICAL")
        self.assertEqual(entries[1].created.strftime("%Y-%m-%d %H:%M:%S"), "2015-08-05 18:07:03")
        self.assertEqual(entries[1].text,
                         "instance.models.server    | instance=my.instance,server=vm1_id | Line #4, on instance")

        self.assertEqual(entries[2].level, "CRITICAL")
        self.assertEqual(entries[2].created.strftime("%Y-%m-%d %H:%M:%S"), "2015-08-05 18:07:06")
        self.assertEqual(entries[2].text,
                         "instance.models.instance  | instance=my.instance | Line #7, exception")