def test_ansible_failignore(self, git_checkout, git_working_dir): """ Ensure failures that are ignored aren't reflected in the instance """ git_working_dir.return_value = os.path.join(os.path.dirname(__file__), "ansible") instance = OpenEdXInstanceFactory(name='Integration - test_ansible_failignore') with patch.object(OpenEdXAppServer, 'CONFIGURATION_PLAYBOOK', new="playbooks/failignore.yml"): spawn_appserver(instance.ref.pk, mark_active_on_success=True, num_attempts=1) instance.refresh_from_db() self.assertIsNotNone(instance.active_appserver) self.assertEqual(instance.active_appserver.status, AppServerStatus.Running) self.assertEqual(instance.active_appserver.server.status, ServerStatus.Ready)
def test_betatest_accepted(self): """ Provision an instance, spawn an AppServer and accepts the application. """ OpenEdXInstanceFactory( name='Integration - test_betatest_accepted', deploy_simpletheme=True, ) instance = OpenEdXInstance.objects.get() # Add an lms user, as happens with beta registration user, _ = get_user_model().objects.get_or_create( username='******', email='*****@*****.**') instance.lms_users.add(user) # Simulate that the application form was filled. This doesn't create another instance nor user BetaTestApplication.objects.create( user=user, subdomain='betatestdomain', instance_name=instance.name, public_contact_email='*****@*****.**', project_description='I want to beta test OpenCraft IM', status=BetaTestApplication.PENDING, instance=instance, ) appserver = MagicMock() appserver.status = AppServer.Status.Running instance.refresh_from_db() # Test accepting beta test application on_appserver_spawned(None, instance=instance, appserver=appserver) self.assertEqual(instance.betatestapplication_set.first().status, BetaTestApplication.ACCEPTED)
def test_ansible_failignore(self, heartbeat_active, get_playbooks, manage_instance_services): """ Ensure failures that are ignored aren't reflected in the instance """ heartbeat_active.return_value = True get_playbooks.return_value = [ Playbook( source_repo=os.path.join(os.path.dirname(__file__), 'ansible'), requirements_path='requirements.txt', playbook_path='playbooks/failignore.yml', version=None, variables='{}', ) ] # Mocking the manage_services.yml playbook because the services it tries to manage # will not be installed in the appserver provisioned by the dummy failignore.yml # playbook. manage_instance_services.return_value = True instance = OpenEdXInstanceFactory( name='Integration - test_ansible_failignore', configuration_playbook_name='playbooks/failignore.yml') create_new_deployment(instance, mark_active_on_success=True, num_attempts=1) self.assert_server_ready(instance)
def test_ansible_failure(self, git_checkout, git_working_dir): """ Ensure failures in the ansible flow are reflected in the instance """ git_working_dir.return_value = os.path.join(os.path.dirname(__file__), "ansible") instance = OpenEdXInstanceFactory( name='Integration - test_ansible_failure', configuration_playbook_name='playbooks/failure.yml' ) spawn_appserver(instance.ref.pk, mark_active_on_success=True, num_attempts=1) instance.refresh_from_db() self.assertFalse(instance.get_active_appservers().exists()) appserver = instance.appserver_set.last() self.assertFalse(appserver.is_active) self.assertEqual(appserver.status, AppServerStatus.ConfigurationFailed) self.assertEqual(appserver.server.status, ServerStatus.Ready)
def test_provision_instance(self): """ Provision an instance """ OpenEdXInstanceFactory(name='Integration - test_provision_instance') instance = OpenEdXInstance.objects.get() provision_instance(instance.pk) self.assert_instance_up(instance)
def test_ansible_failignore(self, git_checkout, git_working_dir): """ Ensure failures that are ignored doesn't reflect in the instance """ git_working_dir.return_value = os.path.join(os.path.dirname(__file__), "ansible") OpenEdXInstanceFactory(name='Integration - test_ansible_failignore', ansible_playbook_name='failignore') instance = OpenEdXInstance.objects.get() provision_instance(instance.pk) self.assertEqual(instance.status, Status.Ready) self.assertEqual(instance.progress, Progress.Success)
def test_ansible_failignore(self, heartbeat_active, git_checkout, git_working_dir): """ Ensure failures that are ignored aren't reflected in the instance """ git_working_dir.return_value = os.path.join(os.path.dirname(__file__), "ansible") heartbeat_active.return_value = True instance = OpenEdXInstanceFactory( name='Integration - test_ansible_failignore') with patch.object(OpenEdXAppServer, 'CONFIGURATION_PLAYBOOK', new="playbooks/failignore.yml"), \ self.settings(ANSIBLE_APPSERVER_PLAYBOOK='playbooks/failignore.yml'): spawn_appserver(instance.ref.pk, mark_active_on_success=True, num_attempts=1) instance.refresh_from_db() active_appservers = list(instance.get_active_appservers().all()) self.assertEqual(len(active_appservers), 1) self.assertTrue(active_appservers[0].is_active) self.assertEqual(active_appservers[0].status, AppServerStatus.Running) self.assertEqual(active_appservers[0].server.status, ServerStatus.Ready)
def test_ansible_failignore(self, heartbeat_active, git_checkout, git_working_dir): """ Ensure failures that are ignored aren't reflected in the instance """ git_working_dir.return_value = os.path.join(os.path.dirname(__file__), "ansible") heartbeat_active.return_value = True instance = OpenEdXInstanceFactory( name='Integration - test_ansible_failignore', configuration_playbook_name='playbooks/failignore.yml' ) with self.settings(ANSIBLE_APPSERVER_PLAYBOOK='playbooks/failignore.yml'): spawn_appserver(instance.ref.pk, mark_active_on_success=True, num_attempts=1) self.assert_server_ready(instance)
def test_external_databases(self): """ Ensure that the instance can connect to external databases """ if not settings.INSTANCE_MYSQL_URL or not settings.INSTANCE_MONGO_URL: print('External databases not configured, skipping integration test') return OpenEdXInstanceFactory(name='Integration - test_external_databases', use_ephemeral_databases=False) instance = OpenEdXInstance.objects.get() provision_instance(instance.pk) self.assert_swift_container_provisioned(instance) self.assert_instance_up(instance)
def test_spawn_appserver(self): """ Provision an instance and spawn an AppServer, complete with custom theme (colors) """ OpenEdXInstanceFactory( name='Integration - test_spawn_appserver', deploy_simpletheme=True, ) instance = OpenEdXInstance.objects.get() # Add an lms user, as happens with beta registration user, _ = get_user_model().objects.get_or_create( username='******', email='*****@*****.**') instance.lms_users.add(user) # Simulate that the application form was filled. This doesn't create another instance nor user application = BetaTestApplication.objects.create( user=user, subdomain='betatestdomain', instance_name=instance.name, public_contact_email='*****@*****.**', project_description='I want to beta test OpenCraft IM', status=BetaTestApplication.PENDING, # The presence of these colors will be checked later # Note: avoid string like #ffbb66 because it would be shortened to #fb6 and therefore # much harder to detect ("#ffbb66" wouldn't appear in CSS). Use e.g. #ffbb67 main_color='#13709b', link_color='#14719c', header_bg_color='#ffbb67', footer_bg_color='#ddff89', instance=instance, ) # We don't want to simulate e-mail verification of the user who submitted the application, # because that would start provisioning. Instead, we provision ourselves here. spawn_appserver(instance.ref.pk, mark_active_on_success=True, num_attempts=2) self.assert_instance_up(instance) self.assert_bucket_configured(instance) self.assert_appserver_firewalled(instance) self.assertTrue(instance.successfully_provisioned) for appserver in instance.appserver_set.all(): self.assert_secret_keys(instance, appserver) self.assert_lms_users_provisioned(user, appserver) self.assert_theme_provisioned(instance, appserver, application)
def test_activity_csv(self): """ Run the activity_csv management command against a live instance. """ OpenEdXInstanceFactory(name='Integration - test_activity_csv') instance = OpenEdXInstance.objects.get() spawn_appserver(instance.ref.pk, mark_active_on_success=True, num_attempts=2) self.assert_instance_up(instance) self.assertTrue(instance.successfully_provisioned) user = get_user_model().objects.create_user('betatestuser', '*****@*****.**') BetaTestApplication.objects.create( user=user, subdomain='betatestdomain', instance_name='betatestinstance', public_contact_email='*****@*****.**', project_description='I want to beta test OpenCraft IM', status=BetaTestApplication.ACCEPTED, instance=instance, ) # Run the management command and collect the CSV from stdout. out = StringIO() call_command('activity_csv', stdout=out) out_lines = out.getvalue().split('\r\n') # The output should look similar to this when one instance is launched: # # "Appserver IP","Internal LMS Domain","Name","Contact Email","Unique Hits","Total Users","Total Courses", # "Age (Days)" # "213.32.77.49","test.example.com","Instance","*****@*****.**","87","6","1",1 self.assertEqual( '"Appserver IP","Internal LMS Domain","Name","Contact Email","Unique Hits","Total Users","Total Courses",' '"Age (Days)"', out_lines[0]) self.assertIn('"Integration - test_activity_csv"', out_lines[1]) self.assertIn('"*****@*****.**"', out_lines[1]) self.assertNotIn('N/A', out_lines[1]) # stdout should contain 3 lines (as opposed to 2) to account for the last newline. self.assertEqual(len(out_lines), 3)
def test_ansible_failignore(self, heartbeat_active, get_playbooks): """ Ensure failures that are ignored aren't reflected in the instance """ heartbeat_active.return_value = True get_playbooks.return_value = [ Playbook( source_repo=os.path.join(os.path.dirname(__file__), 'ansible'), requirements_path='requirements.txt', playbook_path='playbooks/failignore.yml', version=None, variables='{}', ) ] instance = OpenEdXInstanceFactory( name='Integration - test_ansible_failignore', configuration_playbook_name='playbooks/failignore.yml' ) create_new_deployment(instance.ref.pk, mark_active_on_success=True, num_attempts=1) self.assert_server_ready(instance)
def test_external_databases(self): """ Ensure that the instance can connect to external databases """ if not settings.DEFAULT_INSTANCE_MYSQL_URL or not settings.DEFAULT_INSTANCE_MONGO_URL: print( 'External databases not configured, skipping integration test') return OpenEdXInstanceFactory(name='Integration - test_external_databases') instance = OpenEdXInstance.objects.get() spawn_appserver(instance.ref.pk, mark_active_on_success=True, num_attempts=2) self.assert_swift_container_provisioned(instance) self.assert_instance_up(instance) self.assert_appserver_firewalled(instance) self.assertTrue(instance.successfully_provisioned) self.assertFalse(instance.require_user_creation_success()) for appserver in instance.appserver_set.all(): self.assert_secret_keys(instance, appserver) self.assert_mysql_db_provisioned(instance) self.assert_mongo_db_provisioned(instance)
def test_spawn_appserver(self): """ Provision an instance and spawn an AppServer, complete with custom theme (colors) """ OpenEdXInstanceFactory( name='Integration - test_spawn_appserver', deploy_simpletheme=True, static_content_overrides={ 'version': 0, 'static_template_about_content': 'Hello world!', 'homepage_overlay_html': '<h1>Welcome to the LMS!</h1>', }, ) instance = OpenEdXInstance.objects.get() # Add an lms user, as happens with beta registration user, _ = get_user_model().objects.get_or_create(username='******', email='*****@*****.**') instance.lms_users.add(user) # Create user profile and update user model from db UserProfile.objects.create( user=user, full_name="Test user 1", accepted_privacy_policy=datetime.now(), accept_paid_support=True, subscribe_to_updates=True, ) user.refresh_from_db() # Simulate that the application form was filled. This doesn't create another instance nor user application = BetaTestApplication.objects.create( user=user, subdomain='betatestdomain', instance_name=instance.name, public_contact_email='*****@*****.**', project_description='I want to beta test OpenCraft IM', status=BetaTestApplication.PENDING, # The presence of these colors will be checked later # Note: avoid string like #ffbb66 because it would be shortened to #fb6 and therefore # much harder to detect ("#ffbb66" wouldn't appear in CSS). Use e.g. #ffbb67 main_color='#13709b', link_color='#14719c', header_bg_color='#ffbb67', footer_bg_color='#ddff89', instance=instance, ) # We don't want to simulate e-mail verification of the user who submitted the application, # because that would start provisioning. Instead, we provision ourselves here. spawn_appserver(instance.ref.pk, mark_active_on_success=True, num_attempts=2) self.assert_server_ready(instance) self.assert_instance_up(instance) self.assert_bucket_configured(instance) self.assert_appserver_firewalled(instance) self.assertTrue(instance.successfully_provisioned) for appserver in instance.appserver_set.all(): self.assert_secret_keys(instance, appserver) self.assert_lms_users_provisioned(user, appserver) self.assert_theme_provisioned(instance, appserver, application) self.assert_static_content_overrides_work(instance, appserver, page='about') self.assert_load_balanced_domains(instance) # Test external databases if settings.DEFAULT_INSTANCE_MYSQL_URL and settings.DEFAULT_INSTANCE_MONGO_URL: self.assertFalse(instance.require_user_creation_success()) self.assert_mysql_db_provisioned(instance) self.assert_mongo_db_provisioned(instance) # Test activity CSV # Run the management command and collect the CSV from stdout. out = StringIO() call_command('activity_csv', stdout=out) out_lines = out.getvalue().split('\r\n') # The output should look similar to this when one instance is launched: # # "Appserver IP","Internal LMS Domain","Name","Contact Email","Unique Hits","Total Users","Total Courses", # "Age (Days)" # "213.32.77.49","test.example.com","Instance","*****@*****.**","87","6","1",1 self.assertEqual( '"Appserver IP","Internal LMS Domain","Name","Contact Email","Unique Hits","Total Users","Total Courses",' '"Age (Days)"', out_lines[0] ) self.assertIn('"Integration - test_spawn_appserver"', out_lines[1]) self.assertIn('"*****@*****.**"', out_lines[1]) self.assertNotIn('N/A', out_lines[1]) # stdout should contain 3 lines (as opposed to 2) to account for the last newline. self.assertEqual(len(out_lines), 3)