Exemple #1
0
    def test_production_instance_factory(self):
        """
        Test that factory function for creating production instances produces expected results
        """
        # Create instance without changing defaults
        sub_domain = "production-instance-with-defaults"
        instance = production_instance_factory(sub_domain=sub_domain)
        instance = OpenEdXInstance.objects.get(pk=instance.pk)
        self._assert_field_values(instance, sub_domain, **self.PRODUCTION_DEFAULTS)

        # Create instance with custom field values
        sub_domain = "production-instance-customized"
        custom_instance = production_instance_factory(sub_domain=sub_domain, **self.SANDBOX_DEFAULTS)
        custom_instance = OpenEdXInstance.objects.get(pk=custom_instance.pk)
        expected_settings = self.SANDBOX_DEFAULTS.copy()
        expected_settings["configuration_extra_settings"] = self.PRODUCTION_DEFAULTS["configuration_extra_settings"]
        self._assert_field_values(custom_instance, sub_domain, **expected_settings)

        # Create instance that overrides defaults for extra settings
        sub_domain = "production-instance-extra-settings"
        configuration_extra_settings = """
        DEMO_CREATE_STAFF_USER: false
        demo_test_users: []
        SANDBOX_ENABLE_CERTIFICATES: false
        EXTRA_SETTINGS: false
        ADDITIONAL_SETTINGS: true
        """
        expected_settings["configuration_extra_settings"] = configuration_extra_settings
        extra_settings_instance = production_instance_factory(sub_domain=sub_domain, **expected_settings)
        extra_settings_instance = OpenEdXInstance.objects.get(pk=extra_settings_instance.pk)
        self._assert_field_values(extra_settings_instance, sub_domain, **expected_settings)

        # Calling factory without specifying "sub_domain" should result in an error
        with self.assertRaises(AssertionError):
            production_instance_factory()
Exemple #2
0
    def test_production_instance_factory_no_databases(self):
        """
        Test that calling `production_instance_factory` with settings that are problematic
        for production instances produces warnings and does not create production instance.
        """
        # Delete database server objects created during the migrations.
        MySQLServer.objects.all().delete()
        MongoDBServer.objects.all().delete()

        for custom_settings, warning in (
                (
                    {
                        'INSTANCE_STORAGE_TYPE': StorageContainer.S3_STORAGE,
                        'AWS_ACCESS_KEY': None,
                        'AWS_SECRET_ACCESS_KEY': None
                    },
                    (
                        "AWS support is currently enabled. Add AWS_ACCESS_KEY_ID and "
                        "AWS_SECRET_ACCESS_KEY settings or adjust INSTANCE_STORAGE_TYPE setting."
                    ),
                ),
                (
                    {'DEFAULT_INSTANCE_MYSQL_URL': None},
                    (
                        "No MySQL servers configured, and default URL for external MySQL database is missing."
                        "Create at least one MySQLServer, or set DEFAULT_INSTANCE_MYSQL_URL in your .env."
                    ),
                ),
                (
                    {'DEFAULT_INSTANCE_MONGO_URL': None},
                    (
                        "No MongoDB servers configured, and default URL for external MongoDB database is missing."
                        "Create at least one MongoDBServer, or set DEFAULT_INSTANCE_MONGO_URL in your .env."
                    ),
                ),
        ):
            with override_settings(**custom_settings):
                sub_domain = "production-instance-doomed"
                production_instance_factory(sub_domain=sub_domain)
                log_entries = LogEntry.objects.filter(level="WARNING")
                general_entry = log_entries[0]
                setting_entry = log_entries[1]
                self.assertIn(
                    "Environment not ready. Please fix the problems above, then try again. Aborting.",
                    general_entry.text
                )
                self.assertIn(warning, setting_entry.text)
                self.assertFalse(
                    OpenEdXInstance.objects.filter(internal_lms_domain__startswith=sub_domain).exists()
                )
    def test_production_instance_factory(self, patched_loader):
        """
        Test that factory function for creating production instances produces expected results
        """
        mock_template = Mock()
        mock_template.render.return_value = self.CONFIGURATION_EXTRA_SETTINGS
        patched_loader.get_template.return_value = mock_template

        # Create instance without changing defaults
        sub_domain = "production-instance-with-defaults"
        instance = production_instance_factory(sub_domain=sub_domain)
        instance = OpenEdXInstance.objects.get(pk=instance.pk)
        self._assert_field_values(instance, sub_domain,
                                  **self.PRODUCTION_DEFAULTS)
        patched_loader.get_template.assert_called_once_with(
            "instance/ansible/prod-vars.yml")
        mock_template.render.assert_called_once_with({})

        # Create instance with custom field values
        sub_domain = "production-instance-customized"
        custom_instance = production_instance_factory(sub_domain=sub_domain,
                                                      **self.SANDBOX_DEFAULTS)
        custom_instance = OpenEdXInstance.objects.get(pk=custom_instance.pk)
        expected_settings = self.SANDBOX_DEFAULTS.copy()
        expected_settings[
            "configuration_extra_settings"] = self.PRODUCTION_DEFAULTS[
                "configuration_extra_settings"]
        self._assert_field_values(custom_instance, sub_domain,
                                  **expected_settings)

        # Create instance that overrides defaults for extra settings
        sub_domain = "production-instance-extra-settings"
        configuration_extra_settings = """
        EXTRA_SETTINGS: false
        ADDITIONAL_SETTINGS: true
        """
        expected_settings[
            "configuration_extra_settings"] = configuration_extra_settings
        extra_settings_instance = production_instance_factory(
            sub_domain=sub_domain, **expected_settings)
        extra_settings_instance = OpenEdXInstance.objects.get(
            pk=extra_settings_instance.pk)
        self._assert_field_values(extra_settings_instance, sub_domain,
                                  **expected_settings)

        # Calling factory without specifying "sub_domain" should result in an error
        with self.assertRaises(AssertionError):
            production_instance_factory()
Exemple #4
0
def _provision_instance(sender, **kwargs):
    """Provision a new instance once all email addresses of a user are confirmed."""
    user = sender
    if not all(email.is_confirmed for email in user.email_address_set.iterator()):
        return
    try:
        application = user.betatestapplication
    except BetaTestApplication.DoesNotExist:
        logger.info('Email confirmed for user %s, who is not a beta tester.', user.username)
        return
    if application.status == BetaTestApplication.REJECTED:
        logger.info('Email confirmed for user %s, but application was rejected.', user.username)
        return
    if application.instance is not None:
        logger.info('Email confirmed for user %s, but instance already provisioned.', user.username)
        return

    with transaction.atomic():
        application.instance = production_instance_factory(
            sub_domain=application.subdomain,
            name=application.instance_name,
            email=application.public_contact_email,
            deploy_simpletheme=True,
        )
        application.instance.lms_users.add(user)
        application.save()
    spawn_appserver(application.instance.ref.pk, mark_active_on_success=True, num_attempts=2)
Exemple #5
0
def _provision_instance(sender, **kwargs):
    """Provision a new instance once all email addresses of a user are confirmed."""
    user = sender
    if not all(email.is_confirmed for email in user.email_address_set.iterator()):
        return
    try:
        application = user.betatestapplication
    except BetaTestApplication.DoesNotExist:
        logger.info('Email confirmed for user %s, who is not a beta tester.', user.username)
        return
    if application.status == BetaTestApplication.REJECTED:
        logger.info('Email confirmed for user %s, but application was rejected.', user.username)
        return
    if application.instance is not None:
        logger.info('Email confirmed for user %s, but instance already provisioned.', user.username)
        return
    with transaction.atomic():
        application.instance = production_instance_factory(
            sub_domain=application.subdomain,
            name=application.instance_name,
            email=application.public_contact_email,
        )
        application.instance.lms_users.add(user)
        application.save()
    spawn_appserver(application.instance.ref.pk, mark_active_on_success=True, num_attempts=2)
Exemple #6
0
def _provision_instance(sender, **kwargs):
    """Provision a new instance once all email addresses of a user are confirmed."""
    user = sender
    if not all(email.is_confirmed for email in user.email_address_set.iterator()):
        return
    try:
        application = user.betatestapplication
    except BetaTestApplication.DoesNotExist:
        logger.info('Email confirmed for user %s, who is not a beta tester.', user.username)
        return
    if application.status == BetaTestApplication.REJECTED:
        logger.info('Email confirmed for user %s, but application was rejected.', user.username)
        return
    if application.instance is not None:
        logger.info('Email confirmed for user %s, but instance already provisioned.', user.username)
        return

    with transaction.atomic():
        application.instance = production_instance_factory(
            sub_domain=application.subdomain,
            name=application.instance_name,
            email=application.public_contact_email,
            privacy_policy_url=application.privacy_policy_url,
            deploy_simpletheme=True,
        )
        application.instance.lms_users.add(user)
        if settings.PROD_APPSERVER_FAIL_EMAILS:
            application.instance.provisioning_failure_notification_emails = settings.PROD_APPSERVER_FAIL_EMAILS
            application.instance.save()
        application.save()
        # At this point we know the user has confirmed their email and set up an instance.
        # So we can go ahead and send the account info email.
        transaction.on_commit(lambda: send_account_info_email(application))
    spawn_appserver(application.instance.ref.pk, mark_active_on_success=True, num_attempts=2)
    def test_production_instance_factory_no_databases(self):
        """
        Test that calling `production_instance_factory` with settings that are problematic
        for production instances produces warnings and does not create production instance.
        """
        # Delete database server objects created during the migrations.
        MySQLServer.objects.all().delete()
        MongoDBServer.objects.all().delete()

        for setting, value, warning in (
            (
                'SWIFT_ENABLE',
                False,
                'Swift support is currently disabled. Adjust SWIFT_ENABLE setting.',
            ),
            (
                'DEFAULT_INSTANCE_MYSQL_URL',
                None,
                ("No MySQL servers configured, and default URL for external MySQL database is missing."
                 "Create at least one MySQLServer, or set DEFAULT_INSTANCE_MYSQL_URL in your .env."
                 ),
            ),
            (
                'DEFAULT_INSTANCE_MONGO_URL',
                None,
                ("No MongoDB servers configured, and default URL for external MongoDB database is missing."
                 "Create at least one MongoDBServer, or set DEFAULT_INSTANCE_MONGO_URL in your .env."
                 ),
            ),
        ):
            with override_settings(**{setting: value}):
                sub_domain = "production-instance-doomed"
                production_instance_factory(sub_domain=sub_domain)
                log_entries = LogEntry.objects.filter(level="WARNING")
                general_entry = log_entries[0]
                setting_entry = log_entries[1]
                self.assertIn(
                    "Environment not ready. Please fix the problems above, then try again. Aborting.",
                    general_entry.text)
                self.assertIn(warning, setting_entry.text)
                self.assertFalse(
                    OpenEdXInstance.objects.filter(
                        internal_lms_domain__startswith=sub_domain).exists())
 def test_production_instance_factory_no_databases(self):
     """
     Test that calling `production_instance_factory` with settings that are problematic
     for production instances produces warnings and does not create production instance.
     """
     for setting, value, warning in (
         ("SWIFT_ENABLE", False, "Swift support is currently disabled. Adjust SWIFT_ENABLE setting."),
         (
             "DEFAULT_INSTANCE_MYSQL_URL",
             None,
             (
                 "No MySQL servers configured, and default URL for external MySQL database is missing."
                 "Create at least one MySQLServer, or set DEFAULT_INSTANCE_MYSQL_URL in your .env."
             ),
         ),
         (
             "DEFAULT_INSTANCE_MONGO_URL",
             None,
             (
                 "No MongoDB servers configured, and default URL for external MongoDB database is missing."
                 "Create at least one MongoDBServer, or set DEFAULT_INSTANCE_MONGO_URL in your .env."
             ),
         ),
     ):
         with patch("instance.factories.settings") as patched_settings:
             setattr(patched_settings, setting, value)
             sub_domain = "production-instance-doomed"
             production_instance_factory(sub_domain=sub_domain)
             log_entries = LogEntry.objects.all()
             general_entry = log_entries[0]
             setting_entry = log_entries[1]
             for log_entry in (general_entry, setting_entry):
                 self.assertEqual(log_entry.level, "WARNING")
             self.assertIn(
                 "Environment not ready. Please fix the problems above, then try again. Aborting.",
                 general_entry.text,
             )
             self.assertIn(warning, setting_entry.text)
             self.assertFalse(OpenEdXInstance.objects.filter(internal_lms_domain__startswith=sub_domain).exists())
    def test_production_instance_factory(self, patched_loader):
        """
        Test that factory function for creating production instances produces expected results
        """
        mock_template = Mock()
        mock_template.render.return_value = self.CONFIGURATION_EXTRA_SETTINGS
        patched_loader.get_template.return_value = mock_template

        # Create instance without changing defaults
        sub_domain = "production-instance-with-defaults"
        instance = production_instance_factory(sub_domain=sub_domain)
        instance = OpenEdXInstance.objects.get(pk=instance.pk)
        self._assert_field_values(instance, sub_domain, **self.PRODUCTION_DEFAULTS)
        patched_loader.get_template.assert_called_once_with("instance/ansible/prod-vars.yml")
        mock_template.render.assert_called_once_with({})

        # Create instance with custom field values
        sub_domain = "production-instance-customized"
        custom_instance = production_instance_factory(sub_domain=sub_domain, **self.SANDBOX_DEFAULTS)
        custom_instance = OpenEdXInstance.objects.get(pk=custom_instance.pk)
        expected_settings = self.SANDBOX_DEFAULTS.copy()
        expected_settings["configuration_extra_settings"] = self.PRODUCTION_DEFAULTS["configuration_extra_settings"]
        self._assert_field_values(custom_instance, sub_domain, **expected_settings)

        # Create instance that overrides defaults for extra settings
        sub_domain = "production-instance-extra-settings"
        configuration_extra_settings = """
        EXTRA_SETTINGS: false
        ADDITIONAL_SETTINGS: true
        """
        expected_settings["configuration_extra_settings"] = configuration_extra_settings
        extra_settings_instance = production_instance_factory(sub_domain=sub_domain, **expected_settings)
        extra_settings_instance = OpenEdXInstance.objects.get(pk=extra_settings_instance.pk)
        self._assert_field_values(extra_settings_instance, sub_domain, **expected_settings)

        # Calling factory without specifying "sub_domain" should result in an error
        with self.assertRaises(AssertionError):
            production_instance_factory()