Пример #1
0
    def test_dont_suspend_unexistent_stack(self):
        mock_heat_client = Mock()
        mock_heat_client.stacks.get.side_effect = [HTTPNotFound]

        job = SuspenderJob(self.configuration)
        with patch.multiple(
                job, get_heat_client=Mock(return_value=mock_heat_client)):
            job.run()

        mock_heat_client.actions.suspend.assert_not_called()
Пример #2
0
    def test_dont_suspend_unexistent_stack(self):
        # Setup
        mock_suspend_task = self.get_suspend_task_mock()

        # Run
        job = SuspenderJob(self.settings)
        job.run()

        # Assert
        mock_suspend_task.apply_async.assert_not_called()
Пример #3
0
    def test_suspend_concurrency(self):
        self.configuration["suspend_concurrency"] = 2
        suspend_timeout = self.configuration.get("suspend_timeout")
        timedelta = timezone.timedelta(seconds=(suspend_timeout + 1))
        suspend_timestamp = timezone.now() - timedelta
        state = 'CREATE_COMPLETE'
        stack1_name = 'bogus_stack_1'
        stack1 = Stack(student_id=self.student_id,
                       course_id=self.course_id,
                       name=stack1_name,
                       suspend_timestamp=suspend_timestamp,
                       status=state)
        stack1.save()
        stack2_name = 'bogus_stack_2'
        stack2 = Stack(student_id=self.student_id,
                       course_id=self.course_id,
                       name=stack2_name,
                       suspend_timestamp=suspend_timestamp,
                       status=state)
        stack2.save()
        stack3_name = 'bogus_stack_3'
        stack3 = Stack(student_id=self.student_id,
                       course_id=self.course_id,
                       name=stack3_name,
                       suspend_timestamp=suspend_timestamp,
                       status=state)
        stack3.save()
        mock_heat_client = Mock()
        mock_heat_client.stacks.get.side_effect = [
            self.stacks[state], self.stacks[state]
        ]

        job = SuspenderJob(self.configuration)
        with patch.multiple(
                job, get_heat_client=Mock(return_value=mock_heat_client)):
            job.run()

        mock_heat_client.actions.suspend.assert_has_calls(
            [call(stack_id=stack1_name),
             call(stack_id=stack2_name)])
        self.assertNotIn(call(stack_id=stack3_name),
                         mock_heat_client.actions.suspend.mock_calls)
        stack1 = Stack.objects.get(name=stack1_name)
        self.assertEqual(stack1.status, SUSPEND_ISSUED_STATE)
        stack2 = Stack.objects.get(name=stack2_name)
        self.assertEqual(stack2.status, SUSPEND_ISSUED_STATE)
        stack3 = Stack.objects.get(name=stack3_name)
        self.assertEqual(stack3.status, state)
Пример #4
0
    def test_suspend_concurrency(self):
        # Setup
        self.settings["suspend_concurrency"] = 2
        suspend_timeout = self.settings.get("suspend_timeout")
        timedelta = timezone.timedelta(seconds=(suspend_timeout + 1))
        suspend_timestamp = timezone.now() - timedelta
        state = "CREATE_COMPLETE"
        stack1_name = "bogus_stack_1"
        stack1 = Stack(student_id=self.student_id,
                       course_id=self.course_id,
                       name=stack1_name,
                       suspend_timestamp=suspend_timestamp,
                       provider="provider1",
                       status=state)
        stack1.save()
        stack2_name = "bogus_stack_2"
        stack2 = Stack(student_id=self.student_id,
                       course_id=self.course_id,
                       name=stack2_name,
                       suspend_timestamp=suspend_timestamp,
                       provider="provider2",
                       status=state)
        stack2.save()
        stack3_name = "bogus_stack_3"
        stack3 = Stack(student_id=self.student_id,
                       course_id=self.course_id,
                       name=stack3_name,
                       suspend_timestamp=suspend_timestamp,
                       provider="provider3",
                       status=state)
        stack3.save()
        mock_suspend_task = self.get_suspend_task_mock()

        # Run
        job = SuspenderJob(self.settings)
        job.run()

        # Assert
        self.assertEqual(2, len(mock_suspend_task.apply_async.mock_calls))
        stack1 = Stack.objects.get(name=stack1_name)
        self.assertEqual(stack1.status, SUSPEND_PENDING)
        stack2 = Stack.objects.get(name=stack2_name)
        self.assertEqual(stack2.status, SUSPEND_PENDING)
        stack3 = Stack.objects.get(name=stack3_name)
        self.assertEqual(stack3.status, state)
Пример #5
0
    def handle(self, *args, **options):
        # Get configuration
        settings = get_xblock_settings()

        # Schedule
        scheduler = BlockingScheduler()
        suspender = SuspenderJob(settings)
        interval = settings.get("suspend_interval", 60)
        scheduler.add_job(suspender.run, 'interval', seconds=interval)
        scheduler.start()
Пример #6
0
    def test_dont_suspend_deleted_stack(self):
        suspend_timeout = self.configuration.get("suspend_timeout")
        timedelta = timezone.timedelta(seconds=(suspend_timeout + 1))
        suspend_timestamp = timezone.now() - timedelta
        state = 'RESUME_COMPLETE'
        stack = Stack(student_id=self.student_id,
                      course_id=self.course_id,
                      suspend_timestamp=suspend_timestamp,
                      name=self.stack_name,
                      status=state)
        stack.save()
        mock_heat_client = Mock()
        mock_heat_client.stacks.get.side_effect = [HTTPNotFound]

        job = SuspenderJob(self.configuration)
        with patch.multiple(
                job, get_heat_client=Mock(return_value=mock_heat_client)):
            job.run()

        mock_heat_client.actions.suspend.assert_not_called()
        stack = Stack.objects.get(name=self.stack_name)
        self.assertEqual(stack.status, DELETED_STATE)
Пример #7
0
    def test_dont_suspend_stack_with_no_provider(self):
        # Setup
        suspend_timeout = self.settings.get("suspend_timeout")
        timedelta = timezone.timedelta(seconds=(suspend_timeout + 1))
        suspend_timestamp = timezone.now() - timedelta
        state = "RESUME_COMPLETE"
        stack = Stack(student_id=self.student_id,
                      course_id=self.course_id,
                      suspend_timestamp=suspend_timestamp,
                      name=self.stack_name,
                      status=state)
        stack.save()
        mock_suspend_task = self.get_suspend_task_mock()

        # Run
        job = SuspenderJob(self.settings)
        job.run()

        # Assert
        mock_suspend_task.apply_async.assert_not_called()
        stack = Stack.objects.get(name=self.stack_name)
        self.assertEqual(stack.status, state)
Пример #8
0
    def test_stack_log(self):
        suspend_timeout = self.configuration.get("suspend_timeout")
        timedelta = timezone.timedelta(seconds=(suspend_timeout + 1))
        suspend_timestamp = timezone.now() - timedelta
        state = 'CREATE_COMPLETE'
        stack = Stack(student_id=self.student_id,
                      course_id=self.course_id,
                      suspend_timestamp=suspend_timestamp,
                      name=self.stack_name)
        stack.status = state
        stack.save()
        mock_heat_client = Mock()
        mock_heat_client.stacks.get.side_effect = [self.stacks[state]]

        job = SuspenderJob(self.configuration)
        with patch.multiple(
                job, get_heat_client=Mock(return_value=mock_heat_client)):
            job.run()

        stacklog = StackLog.objects.filter(stack_id=stack.id)
        states = [l.status for l in stacklog]
        expected_states = [state, 'SUSPEND_PENDING', 'SUSPEND_ISSUED']
        self.assertEqual(states, expected_states)
Пример #9
0
    def test_suspend_stack_for_the_first_time(self):
        # Setup
        suspend_timeout = self.settings.get("suspend_timeout")
        timedelta = timezone.timedelta(seconds=(suspend_timeout + 1))
        suspend_timestamp = timezone.now() - timedelta
        state = "CREATE_COMPLETE"
        stack = Stack(student_id=self.student_id,
                      course_id=self.course_id,
                      suspend_timestamp=suspend_timestamp,
                      name=self.stack_name,
                      provider="provider1",
                      status=state)
        stack.save()
        mock_suspend_task = self.get_suspend_task_mock()

        # Run
        job = SuspenderJob(self.settings)
        job.run()

        # Assert
        mock_suspend_task.apply_async.assert_called()
        stack = Stack.objects.get(name=self.stack_name)
        self.assertEqual(stack.status, SUSPEND_PENDING)
Пример #10
0
    def test_stack_log(self):
        # Setup
        suspend_timeout = self.settings.get("suspend_timeout")
        timedelta = timezone.timedelta(seconds=(suspend_timeout + 1))
        suspend_timestamp = timezone.now() - timedelta
        state = 'CREATE_COMPLETE'
        stack = Stack(student_id=self.student_id,
                      course_id=self.course_id,
                      suspend_timestamp=suspend_timestamp,
                      provider='provider1',
                      name=self.stack_name)
        stack.status = state
        stack.save()

        # Run
        job = SuspenderJob(self.settings)
        job.run()

        # Assert
        stacklog = StackLog.objects.filter(stack_id=stack.id)
        states = [l.status for l in stacklog]
        expected_states = [state, SUSPEND_PENDING]
        self.assertEqual(states, expected_states)
Пример #11
0
    def handle(self, *args, **options):
        # Get configuration
        xblock_settings = django_settings.XBLOCK_SETTINGS
        if xblock_settings:
            settings = xblock_settings.get(SETTINGS_KEY, DEFAULT_SETTINGS)
        else:
            settings = DEFAULT_SETTINGS

        # Schedule
        scheduler = BlockingScheduler()
        suspender = SuspenderJob(settings)
        interval = settings.get("suspend_interval", 60)
        scheduler.add_job(suspender.run, 'interval', seconds=interval)
        scheduler.start()