Пример #1
0
    def test_get_deployment_status_up_to_date(self, mock_create_new_deployment,
                                              mock_consul):
        """
        Test that the correct status is returned when instance is up-to-date.
        """
        self.client.force_login(self.user_with_instance)
        instance = self._setup_user_instance()
        instance.name = self.instance_config.instance_name
        instance.privacy_policy_url = self.instance_config.privacy_policy_url
        instance.email = self.instance_config.public_contact_email
        instance.theme_config = self.instance_config.draft_theme_config
        instance.save()

        make_test_deployment(instance,
                             appserver_states=[Status.Running],
                             active=True)

        url = reverse(
            'api:v2:openedx-instance-deployment-detail',
            args=(self.instance_config.pk, ),
        )
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assert_deployment_response(response.data,
                                        status='healthy',
                                        undeployed_changes=0)
Пример #2
0
 def test_multi_appserver_partial_activation(self, mock_consul,
                                             mock_make_active):
     """
     Test the start_deployment task, and that it can be used to spawn multiple AppServer(s)
     for a new instance.
     """
     instance = OpenEdXInstanceFactory()
     instance.openedx_appserver_count = 3
     instance.save()
     make_test_deployment(instance, active=True)
     self.mock_make_appserver_active.s = Mock()
     self.mock_make_appserver_active.s.side_effect = make_appserver_active.s
     self.assertEqual(instance.appserver_set.count(), 3)
     self.assertTrue(
         all(instance.appserver_set.values_list('_is_active', flat=True)))
     deployment = OpenEdXDeployment.objects.create(
         instance_id=instance.ref.id)
     statuses = [
         (AppServerStatus.Running, ServerStatus.Ready.state_id),
         (AppServerStatus.ConfigurationFailed,
          ServerStatus.BuildFailed.state_id),
         (AppServerStatus.Running, ServerStatus.Ready.state_id),
     ]
     self.mock_spawn_appserver.side_effect = gen_appserver_side_effect(
         deployment, instance, statuses)
     tasks.start_deployment(
         instance.ref.id,
         deployment.pk,
         mark_active_on_success=False,
     ).get()
     self.assertEqual(self.mock_make_appserver_active.s.call_count, 0)
     self.assertEqual(mock_make_active.call_count, 0)
Пример #3
0
 def test_commit_changes_fail_first_deployment(self, mock_create_deployment,
                                               mock_consul):
     """
     Test that committing changes fails when a user is new.
     """
     self.client.force_login(self.user_with_instance)
     instance = self._setup_user_instance()
     make_test_deployment(instance, appserver_states=[])
     response = self.client.post(
         reverse('api:v2:openedx-instance-deployment-list'),
         data={"id": self.instance_config.id})
     self.assertEqual(response.status_code, 400)
     self.assertIn(
         "You must wait for your initial instance to finish building.",
         response.content.decode('utf-8'))
Пример #4
0
    def test_commit_changes_fail_running_appserver(self,
                                                   mock_create_deployment,
                                                   mock_consul):
        """
        Test that committing changes fails when a user is new.
        """
        self.client.force_login(self.user_with_instance)
        instance = self._setup_user_instance()

        make_test_deployment(instance,
                             appserver_states=[Status.ConfiguringServer])
        response = self.client.post(
            reverse('api:v2:openedx-instance-deployment-list'),
            data={"id": self.instance_config.id})
        self.assertEqual(response.status_code, 400)
        self.assertIn("Instance launch already in progress",
                      response.content.decode('utf-8'))
Пример #5
0
 def test_status(self,
                 server_statuses,
                 appserver_count,
                 status,
                 additional_deployment=False):
     """
     Asserts that the .status() method returns the correct status based on the state of deployments and
     app servers.
     """
     instance = OpenEdXInstanceFactory()
     if additional_deployment:
         deployment = make_test_deployment(instance)
         make_test_appserver(deployment=deployment, instance=instance)
     deployment = make_test_deployment(instance,
                                       appserver_states=server_statuses)
     deployment.instance.instance.openedx_appserver_count = appserver_count
     deployment.instance.instance.save()
     self.assertEqual(deployment.status(), status)
Пример #6
0
    def test_get_deployment_notifications(self, mock_create_new_deployment,
                                          mock_consul):
        """
        Ensures that notification contain deployment's deployed changes and
        that status of last healthy deployment with undeployed changes
        is 'changes_pending'.
        """

        instance = self._setup_user_instance()
        first_deployment = make_test_deployment(
            instance, appserver_states=[Status.Running], active=True)
        second_deployment = make_test_deployment(
            instance, appserver_states=[Status.Running], active=True)

        changes = build_instance_config_diff(self.instance_config)
        first_deployment.changes = changes
        first_deployment.save()

        url = reverse("api:v2:notifications-list")
        response = self.client.get(url)

        self.assertEqual(response.status_code, 200)

        self.assertEqual(
            dict(response.data[0]), {
                "deployed_changes": [],
                "status":
                "changes_pending",
                "date":
                second_deployment.created.isoformat().replace("+00:00", "Z"),
            }, response.data)

        self.assertEqual(
            dict(response.data[1]),
            {
                # simulate postgres json field serialization and deserialization
                "deployed_changes":
                json.loads(json.dumps(changes)),
                "status":
                "healthy",
                "date":
                first_deployment.created.isoformat().replace("+00:00", "Z"),
            },
            response.data)
Пример #7
0
    def test_get_deployment_status_pending_changes(self,
                                                   mock_create_new_deployment,
                                                   mock_consul):
        """
        Test that the correct status is returned when there's changes to be deployed.
        """
        self.client.force_login(self.user_with_instance)
        instance = self._setup_user_instance()
        make_test_deployment(instance, active=True)

        url = reverse(
            'api:v2:openedx-instance-deployment-detail',
            args=(self.instance_config.pk, ),
        )
        response = self.client.get(url)

        self.assertEqual(response.status_code, 200)
        self.assert_deployment_response(response.data,
                                        status='changes_pending',
                                        undeployed_changes=3)
Пример #8
0
    def test_cancel_deployment(self, deploy_type, status_code,
                               mock_create_new_deployment, mock_consul):
        """
        Test that trying to stop a provisioning succeeds.
        """
        self.client.force_login(self.user_with_instance)
        instance = self._setup_user_instance()
        make_test_deployment(instance,
                             appserver_states=[Status.Running],
                             active=True)
        make_test_deployment(instance,
                             appserver_states=[Status.ConfiguringServer],
                             deployment_type=deploy_type)

        url = reverse(
            'api:v2:openedx-instance-deployment-detail',
            args=(self.instance_config.pk, ),
        )
        response = self.client.delete(url)

        self.assertEqual(response.status_code, status_code)
Пример #9
0
 def test_spawn_when_cancelled(self, mocks, mock_provision, mock_consul):
     """
     Spawn appserver with a cancelled deployment
     """
     mock_provision.return_value = False
     instance = OpenEdXInstanceFactory(internal_lms_domain='test.activate.opencraft.co.uk')
     deployment = make_test_deployment(instance)
     deployment.cancelled = True
     deployment.save()
     appserver_id = instance.spawn_appserver(deployment_id=deployment.id)
     self.assertEqual(mock_provision.call_count, 1)
     self.assertIs(appserver_id, None)
Пример #10
0
 def test_multi_appserver_activation(self, mock_consul, mock_make_active):
     """
     Test the start_deployment task, and that it can be used to spawn multiple AppServer(s)
     for a new instance.
     """
     instance = OpenEdXInstanceFactory()
     instance.openedx_appserver_count = 3
     instance.save()
     make_test_deployment(instance, active=True)
     self.mock_make_appserver_active.s = Mock()
     self.mock_make_appserver_active.s.side_effect = make_appserver_active.s
     self.assertEqual(instance.appserver_set.count(), 3)
     appservers = list(instance.appserver_set.all())
     self.assertTrue(
         all(instance.appserver_set.values_list('_is_active', flat=True)))
     deployment = OpenEdXDeployment.objects.create(
         instance_id=instance.ref.id)
     statuses = [(AppServerStatus.Running, ServerStatus.Ready.state_id)] * 3
     self.mock_spawn_appserver.side_effect = gen_appserver_side_effect(
         deployment, instance, statuses)
     with self.assertLogs() as ctx:
         tasks.start_deployment(
             instance.ref.id,
             deployment.pk,
             mark_active_on_success=True,
         ).get()
     self.assertEqual(self.mock_make_appserver_active.s.call_count, 3)
     self.assertEqual(mock_make_active.call_count, 6)
     mock_make_active.assert_has_calls([
         call(active=True),
         call(active=True),
         call(active=True),
         call(active=False),
         call(active=False),
         call(active=False),
     ])
     for appserver in appservers:
         self.assertIn(
             f'INFO:instance.tasks:Deactivating {appserver} [{appserver.id}]',
             ctx.output)
Пример #11
0
    def test_notifications_limit(self, mock_create_new_deployment,
                                 mock_consul):
        """
        Tests that limit query param works as intended and doesn't allow malformed
        data.
        """

        instance = self._setup_user_instance()

        for _ in range(5):
            make_test_deployment(instance,
                                 appserver_states=[Status.Running],
                                 active=True)

        url = reverse("api:v2:notifications-list")

        response = self.client.get(url, data={'limit': -1})

        self.assertEqual(response.status_code, 400)

        response = self.client.get(url, data={'limit': 3})

        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.data), 3)
Пример #12
0
 def test_multi_appserver_activation(self, mock_consul, mock_make_active):
     """
     Test the create_new_deployment task, and that it can be used to spawn multiple AppServer(s)
     for a new instance.
     """
     instance = OpenEdXInstanceFactory()
     instance.openedx_appserver_count = 3
     instance.save()
     make_test_deployment(instance, active=True)
     self.assertEqual(instance.appserver_set.count(), 3)
     appservers = list(instance.appserver_set.all())
     self.assertTrue(
         all(instance.appserver_set.values_list('_is_active', flat=True)))
     with self.assertLogs() as ctx:
         tasks.create_new_deployment(
             instance.ref.pk,
             mark_active_on_success=True,
         ).get()
     self.assertEqual(self.mock_make_appserver_active.call_count, 3)
     self.assertEqual(mock_make_active.call_count, 3)
     for appserver in appservers:
         self.assertIn(
             f'INFO:instance.tasks:Deactivating {appserver} [{appserver.id}]',
             ctx.output)
Пример #13
0
    def test_provision_when_cancelled(self, mocks, mock_consul):
        """
        Provision appserver with a cancelled deployment
        """
        mocks.mock_run_ansible_playbooks.return_value = (['log'], 0)

        instance = OpenEdXInstanceFactory(internal_lms_domain='test.activate.opencraft.co.uk')
        deployment = make_test_deployment(instance)
        deployment.cancelled = True
        deployment.save()
        appserver = make_test_appserver(deployment=deployment)
        self.assertEqual(appserver.status, AppServerStatus.New)
        self.assertEqual(appserver.server.status, Server.Status.Pending)
        result = appserver.provision()
        self.assertFalse(result)
        self.assertEqual(mocks.mock_run_ansible_playbooks.call_count, 0)
        self.assertEqual(appserver.status, AppServerStatus.ConfiguringServer)