Config for integration tests

* move askbot repo into mitx as a submodule
* set settings as in 85865f7221
* remove test_mongo env.
* Refactor tests to use new config structure.
* Add real integration tests--not working due to bugs in course xml. Turned off.
This commit is contained in:
Victor Shnayder
2012-07-27 16:04:02 -04:00
parent a8afe5ed17
commit cb30850759
6 changed files with 100 additions and 145 deletions

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "askbot"]
path = askbot
url = git@github.com:MITx/askbot-devel.git

1
askbot Submodule

Submodule askbot added at 1c3381046c

View File

@@ -1,4 +1,9 @@
import copy
import json
import os
from pprint import pprint
from django.test import TestCase
from django.test.client import Client
from mock import patch, Mock
@@ -14,7 +19,6 @@ from xmodule.modulestore.django import modulestore
import xmodule.modulestore.django
from xmodule.modulestore import Location
from xmodule.modulestore.xml_importer import import_from_xml
import copy
def parse_json(response):
@@ -32,14 +36,32 @@ def registration(email):
return Registration.objects.get(user__email=email)
TEST_DATA_MODULESTORE = copy.deepcopy(settings.MODULESTORE)
# TODO (vshnayder): test the real courses
TEST_DATA_DIR = 'common/test/data'
TEST_DATA_MODULESTORE['default']['OPTIONS']['fs_root'] = path(TEST_DATA_DIR)
# A bit of a hack--want mongo modulestore for these tests, until
# jump_to works with the xmlmodulestore or we have an even better solution
# NOTE: this means this test requires mongo to be running.
@override_settings(MODULESTORE=TEST_DATA_MODULESTORE)
class IntegrationTestCase(TestCase):
'''Check that all objects in all accessible courses will load properly'''
def mongo_store_config(data_dir):
return {
'default': {
'ENGINE': 'xmodule.modulestore.mongo.MongoModuleStore',
'OPTIONS': {
'default_class': 'xmodule.raw_module.RawDescriptor',
'host': 'localhost',
'db': 'xmodule',
'collection': 'modulestore',
'fs_root': data_dir,
}
}
}
TEST_DATA_DIR = settings.COMMON_TEST_DATA_ROOT
TEST_DATA_MODULESTORE = mongo_store_config(TEST_DATA_DIR)
REAL_DATA_DIR = settings.GITHUB_REPO_ROOT
REAL_DATA_MODULESTORE = mongo_store_config(REAL_DATA_DIR)
class ActivateLoginTestCase(TestCase):
'''Check that we can activate and log in'''
def setUp(self):
email = 'view@test.com'
@@ -47,9 +69,6 @@ class IntegrationTestCase(TestCase):
self.create_account('viewtest', email, password)
self.activate_user(email)
self.login(email, password)
xmodule.modulestore.django._MODULESTORES = {}
xmodule.modulestore.django.modulestore().collection.drop()
# ============ User creation and login ==============
@@ -107,15 +126,22 @@ class IntegrationTestCase(TestCase):
# Now make sure that the user is now actually activated
self.assertTrue(user(email).is_active)
# ============ Page loading ==============
def test_activate_login(self):
'''The setup function does all the work'''
pass
def check_pages_load(self, test_course_name):
import_from_xml(modulestore(), TEST_DATA_DIR, [test_course_name])
class PageLoader(ActivateLoginTestCase):
''' Base class that adds a function to load all pages in a modulestore '''
def check_pages_load(self, course_name, data_dir, modstore):
print "Checking course {0} in {1}".format(course_name, data_dir)
import_from_xml(modstore, data_dir, [course_name])
n = 0
num_bad = 0
all_ok = True
for descriptor in modulestore().get_items(
for descriptor in modstore.get_items(
Location(None, None, None, None, None)):
n += 1
print "Checking ", descriptor.location.url()
@@ -129,16 +155,54 @@ class IntegrationTestCase(TestCase):
all_ok = False
num_bad += 1
print msg
self.assertTrue(all_ok)
self.assertTrue(all_ok) # fail fast
print "{0}/{1} good".format(n - num_bad, n)
self.assertTrue(all_ok)
@override_settings(MODULESTORE=TEST_DATA_MODULESTORE)
class TestCoursesLoadTestCase(PageLoader):
'''Check that all pages in test courses load properly'''
def setUp(self):
ActivateLoginTestCase.setUp(self)
xmodule.modulestore.django._MODULESTORES = {}
xmodule.modulestore.django.modulestore().collection.drop()
def test_toy_course_loads(self):
self.check_pages_load('toy')
self.check_pages_load('toy', TEST_DATA_DIR, modulestore())
def test_full_course_loads(self):
self.check_pages_load('full')
self.check_pages_load('full', TEST_DATA_DIR, modulestore())
# ========= TODO: check ajax interaction here too?
@override_settings(MODULESTORE=REAL_DATA_MODULESTORE)
class RealCoursesLoadTestCase(PageLoader):
'''Check that all pages in real courses load properly'''
def setUp(self):
ActivateLoginTestCase.setUp(self)
xmodule.modulestore.django._MODULESTORES = {}
xmodule.modulestore.django.modulestore().collection.drop()
# TODO: Disabled test for now.. Fix once things are cleaned up.
def Xtest_real_courses_loads(self):
'''See if any real courses are available at the REAL_DATA_DIR.
If they are, check them.'''
# TODO: adjust staticfiles_dirs
if not os.path.isdir(REAL_DATA_DIR):
# No data present. Just pass.
return
courses = [course_dir for course_dir in os.listdir(REAL_DATA_DIR)
if os.path.isdir(REAL_DATA_DIR / course_dir)]
for course in courses:
self.check_pages_load(course, REAL_DATA_DIR, modulestore())
# ========= TODO: check ajax interaction here too?

View File

@@ -61,7 +61,7 @@ PROJECT_ROOT = path(__file__).abspath().dirname().dirname() # /mitx/lms
REPO_ROOT = PROJECT_ROOT.dirname()
COMMON_ROOT = REPO_ROOT / "common"
ENV_ROOT = REPO_ROOT.dirname() # virtualenv dir /mitx is in
ASKBOT_ROOT = ENV_ROOT / "askbot-devel"
ASKBOT_ROOT = REPO_ROOT / "askbot"
COURSES_ROOT = ENV_ROOT / "data"
# FIXME: To support multiple courses, we should walk the courses dir at startup

View File

@@ -12,15 +12,18 @@ from .logsettings import get_logger_config
import os
from path import path
INSTALLED_APPS = [
app
for app
in INSTALLED_APPS
if not app.startswith('askbot')
]
# can't test start dates with this True, but on the other hand,
# can test everything else :)
MITX_FEATURES['DISABLE_START_DATES'] = True
# Need wiki for courseware views to work. TODO (vshnayder): shouldn't need it.
WIKI_ENABLED = True
# Makes the tests run much faster...
SOUTH_TESTS_MIGRATE = False # To disable migrations and use syncdb instead
# Nose Test Runner
INSTALLED_APPS += ['django_nose']
INSTALLED_APPS += ('django_nose',)
NOSE_ARGS = ['--cover-erase', '--with-xunit', '--with-xcoverage', '--cover-html',
'--cover-inclusive', '--cover-html-dir',
os.environ.get('NOSE_COVER_HTML_DIR', 'cover_html')]
@@ -35,12 +38,6 @@ STATIC_ROOT = TEST_ROOT / "staticfiles"
COURSES_ROOT = TEST_ROOT / "data"
DATA_DIR = COURSES_ROOT
MAKO_TEMPLATES['course'] = [DATA_DIR]
MAKO_TEMPLATES['sections'] = [DATA_DIR / 'sections']
MAKO_TEMPLATES['custom_tags'] = [DATA_DIR / 'custom_tags']
MAKO_TEMPLATES['main'] = [PROJECT_ROOT / 'templates',
DATA_DIR / 'info',
DATA_DIR / 'problems']
LOGGING = get_logger_config(TEST_ROOT / "log",
logging_env="dev",
@@ -48,6 +45,9 @@ LOGGING = get_logger_config(TEST_ROOT / "log",
debug=True)
COMMON_TEST_DATA_ROOT = COMMON_ROOT / "test" / "data"
# Where the content data is checked out. This may not exist on jenkins.
GITHUB_REPO_ROOT = ENV_ROOT / "data"
# TODO (cpennington): We need to figure out how envs/test.py can inject things
# into common.py so that we don't have to repeat this sort of thing

View File

@@ -1,113 +0,0 @@
"""
This config file runs the test environment, but with mongo as the datastore
"""
from .common import *
from .logsettings import get_logger_config
import os
from path import path
# can't testing start dates with this True, but on the other hand,
# can test everything else :)
MITX_FEATURES['DISABLE_START_DATES'] = True
WIKI_ENABLED = True
GITHUB_REPO_ROOT = ENV_ROOT / "data"
MODULESTORE = {
'default': {
'ENGINE': 'xmodule.modulestore.mongo.MongoModuleStore',
'OPTIONS': {
'default_class': 'xmodule.raw_module.RawDescriptor',
'host': 'localhost',
'db': 'xmodule',
'collection': 'modulestore',
'fs_root': GITHUB_REPO_ROOT,
}
}
}
# Nose Test Runner
INSTALLED_APPS += ('django_nose',)
NOSE_ARGS = ['--cover-erase', '--with-xunit', '--with-xcoverage', '--cover-html',
'--cover-inclusive', '--cover-html-dir',
os.environ.get('NOSE_COVER_HTML_DIR', 'cover_html')]
for app in os.listdir(PROJECT_ROOT / 'djangoapps'):
NOSE_ARGS += ['--cover-package', app]
TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
TEST_ROOT = path("test_root")
# Want static files in the same dir for running on jenkins.
STATIC_ROOT = TEST_ROOT / "staticfiles"
LOGGING = get_logger_config(TEST_ROOT / "log",
logging_env="dev",
tracking_filename="tracking.log",
debug=True)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': PROJECT_ROOT / "db" / "mitx.db",
}
}
CACHES = {
# This is the cache used for most things. Askbot will not work without a
# functioning cache -- it relies on caching to load its settings in places.
# In staging/prod envs, the sessions also live here.
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'mitx_loc_mem_cache',
'KEY_FUNCTION': 'util.memcache.safe_key',
},
# The general cache is what you get if you use our util.cache. It's used for
# things like caching the course.xml file for different A/B test groups.
# We set it to be a DummyCache to force reloading of course.xml in dev.
# In staging environments, we would grab VERSION from data uploaded by the
# push process.
'general': {
'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
'KEY_PREFIX': 'general',
'VERSION': 4,
'KEY_FUNCTION': 'util.memcache.safe_key',
}
}
# Dummy secret key for dev
SECRET_KEY = '85920908f28904ed733fe576320db18cabd7b6cd'
# Makes the tests run much faster...
SOUTH_TESTS_MIGRATE = False # To disable migrations and use syncdb instead
############################ FILE UPLOADS (ASKBOT) #############################
DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'
MEDIA_ROOT = TEST_ROOT / "uploads"
MEDIA_URL = "/static/uploads/"
STATICFILES_DIRS.append(("uploads", MEDIA_ROOT))
new_staticfiles_dirs = []
# Strip out any static files that aren't in the repository root
# so that the tests can run with only the mitx directory checked out
for static_dir in STATICFILES_DIRS:
# Handle both tuples and non-tuple directory definitions
try:
_, data_dir = static_dir
except ValueError:
data_dir = static_dir
if data_dir.startswith(REPO_ROOT):
new_staticfiles_dirs.append(static_dir)
STATICFILES_DIRS = new_staticfiles_dirs
FILE_UPLOAD_TEMP_DIR = PROJECT_ROOT / "uploads"
FILE_UPLOAD_HANDLERS = (
'django.core.files.uploadhandler.MemoryFileUploadHandler',
'django.core.files.uploadhandler.TemporaryFileUploadHandler',
)