test.py 16 KB
Newer Older
1
# -*- coding: utf-8 -*-
2 3 4 5 6 7
"""
This config file runs the simplest dev environment using sqlite, and db-based
sessions. Assumes structure:

/envroot/
        /db   # This is where it'll write the database file
8
        /edx-platform  # The location of this repo
9 10
        /log  # Where we're going to write log files
"""
11 12 13

# We intentionally define lots of variables that aren't used, and
# want to import all variables from base settings files
14
# pylint: disable=wildcard-import, unused-wildcard-import
15

16 17 18 19 20
# Pylint gets confused by path.py instances, which report themselves as class
# objects. As a result, pylint applies the wrong regex in validating names,
# and throws spurious errors. Therefore, we disable invalid-name checking.
# pylint: disable=invalid-name

21
from .common import *
22
import os
23
from path import path
24
from tempfile import mkdtemp
25
from uuid import uuid4
26
from warnings import filterwarnings, simplefilter
27

28 29 30 31 32 33 34 35 36
# Silence noisy logs to make troubleshooting easier when tests fail.
import logging
LOG_OVERRIDES = [
    ('factory.generate', logging.ERROR),
    ('factory.containers', logging.ERROR),
]
for log_name, log_level in LOG_OVERRIDES:
    logging.getLogger(log_name).setLevel(log_level)

37 38 39 40
# mongo connection settings
MONGO_PORT_NUM = int(os.environ.get('EDXAPP_TEST_MONGO_PORT', '27017'))
MONGO_HOST = os.environ.get('EDXAPP_TEST_MONGO_HOST', 'localhost')

41 42
os.environ['DJANGO_LIVE_TEST_SERVER_ADDRESS'] = 'localhost:8000-9000'

43 44
THIS_UUID = uuid4().hex[:5]

45 46
# can't test start dates with this True, but on the other hand,
# can test everything else :)
47
FEATURES['DISABLE_START_DATES'] = True
48

49 50
# Most tests don't use the discussion service, so we turn it off to speed them up.
# Tests that do can enable this flag, but must use the UrlResetMixin class to force urls.py
51 52
# to reload. For consistency in user-experience, keep the value of this setting in sync with
# the one in cms/envs/test.py
53
FEATURES['ENABLE_DISCUSSION_SERVICE'] = False
54

55
FEATURES['ENABLE_SERVICE_STATUS'] = True
56

57
FEATURES['ENABLE_HINTER_INSTRUCTOR_VIEW'] = True
58

59
FEATURES['ENABLE_INSTRUCTOR_LEGACY_DASHBOARD'] = True
60

61
FEATURES['ENABLE_SHOPPING_CART'] = True
62

63 64
FEATURES['ENABLE_VERIFIED_CERTIFICATES'] = True

65 66 67 68
# Enable this feature for course staff grade downloads, to enable acceptance tests
FEATURES['ENABLE_S3_GRADE_DOWNLOADS'] = True
FEATURES['ALLOW_COURSE_STAFF_GRADE_DOWNLOADS'] = True

69 70 71
# Toggles embargo on for testing
FEATURES['EMBARGO'] = True

72 73
FEATURES['ENABLE_COMBINED_LOGIN_REGISTRATION'] = True

74 75 76
# Need wiki for courseware views to work. TODO (vshnayder): shouldn't need it.
WIKI_ENABLED = True

77 78 79
# Enable a parental consent age limit for testing
PARENTAL_CONSENT_AGE_LIMIT = 13

80
# Makes the tests run much faster...
81
SOUTH_TESTS_MIGRATE = False  # To disable migrations and use syncdb instead
82

83 84 85
# Nose Test Runner
TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'

86
_SYSTEM = 'lms'
87

88 89
_REPORT_DIR = REPO_ROOT / 'reports' / _SYSTEM
_REPORT_DIR.makedirs_p()
90 91

NOSE_ARGS = [
92 93
    '--id-file', REPO_ROOT / '.testids' / _SYSTEM / 'noseids',
    '--xunit-file', _REPORT_DIR / 'nosetests.xml',
94 95
]

96
# Local Directories
97
TEST_ROOT = path("test_root")
98
# Want static files in the same dir for running on jenkins.
99
STATIC_ROOT = TEST_ROOT / "staticfiles"
100

101 102
STATUS_MESSAGE_PATH = TEST_ROOT / "status_message.json"

103
COURSES_ROOT = TEST_ROOT / "data"
104 105
DATA_DIR = COURSES_ROOT

106
COMMON_TEST_DATA_ROOT = COMMON_ROOT / "test" / "data"
107 108 109
# Where the content data is checked out.  This may not exist on jenkins.
GITHUB_REPO_ROOT = ENV_ROOT / "data"

110
USE_I18N = True
111
LANGUAGE_CODE = 'en'  # tests assume they will get English.
112

113
XQUEUE_INTERFACE = {
114
    "url": "http://sandbox-xqueue.edx.org",
115
    "django_auth": {
116 117
        "username": "lms",
        "password": "***REMOVED***"
118 119
    },
    "basic_auth": ('anant', 'agarwal'),
120
}
121
XQUEUE_WAITTIME_BETWEEN_REQUESTS = 5  # seconds
122

Victor Shnayder committed
123 124
# Don't rely on a real staff grading backend
MOCK_STAFF_GRADING = True
125
MOCK_PEER_GRADING = True
126

127 128
# 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
129 130 131 132 133 134 135 136 137 138
STATICFILES_DIRS = [
    COMMON_ROOT / "static",
    PROJECT_ROOT / "static",
]
STATICFILES_DIRS += [
    (course_dir, COMMON_TEST_DATA_ROOT / course_dir)
    for course_dir in os.listdir(COMMON_TEST_DATA_ROOT)
    if os.path.isdir(COMMON_TEST_DATA_ROOT / course_dir)
]

139 140 141 142
# Avoid having to run collectstatic before the unit test suite
# If we don't add these settings, then Django templates that can't
# find pipelined assets will raise a ValueError.
# http://stackoverflow.com/questions/12816941/unit-testing-with-django-pipeline
143 144
STATICFILES_STORAGE = 'pipeline.storage.NonPackagingPipelineStorage'
PIPELINE_ENABLED = False
145

146 147 148 149 150 151
update_module_store_settings(
    MODULESTORE,
    module_store_options={
        'fs_root': TEST_ROOT / "data",
    },
    xml_store_options={
152
        'data_dir': mkdtemp(dir=TEST_ROOT),  # never inadvertently load all the XML courses
153 154
    },
    doc_store_settings={
155 156
        'host': MONGO_HOST,
        'port': MONGO_PORT_NUM,
157
        'db': 'test_xmodule',
158
        'collection': 'test_modulestore{0}'.format(THIS_UUID),
159 160
    },
)
161

162 163
CONTENTSTORE = {
    'ENGINE': 'xmodule.contentstore.mongo.MongoContentStore',
164
    'DOC_STORE_CONFIG': {
165
        'host': MONGO_HOST,
166
        'db': 'xcontent',
167
        'port': MONGO_PORT_NUM,
168 169
    }
}
170

171 172
DATABASES = {
    'default': {
173
        'ENGINE': 'django.db.backends.sqlite3',
174
        'NAME': TEST_ROOT / 'db' / 'edx.db'
175 176
    },

177 178 179
}

CACHES = {
Victor Shnayder committed
180
    # This is the cache used for most things.
181 182 183
    # In staging/prod envs, the sessions also live here.
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
184
        'LOCATION': 'edx_loc_mem_cache',
185
        'KEY_FUNCTION': 'util.memcache.safe_key',
186 187 188 189 190 191 192 193 194 195 196
    },

    # 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,
197
        'KEY_FUNCTION': 'util.memcache.safe_key',
198 199 200 201
    },

    'mongo_metadata_inheritance': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
202
        'LOCATION': os.path.join(tempfile.gettempdir(), 'mongo_metadata_inheritance'),
203 204
        'TIMEOUT': 300,
        'KEY_FUNCTION': 'util.memcache.safe_key',
205 206 207 208 209 210
    },
    'loc_cache': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': 'edx_location_mem_cache',
    },

211 212 213 214 215
}

# Dummy secret key for dev
SECRET_KEY = '85920908f28904ed733fe576320db18cabd7b6cd'

Diana Huang committed
216 217 218
# hide ratelimit warnings while running tests
filterwarnings('ignore', message='No request passed to the backend, unable to rate-limit')

219 220
# Ignore deprecation warnings (so we don't clutter Jenkins builds/production)
# https://docs.python.org/2/library/warnings.html#the-warnings-filter
David Baumgold committed
221 222
# Change to "default" to see the first instance of each hit
# or "error" to convert all into errors
223
simplefilter('ignore')
224

225 226 227 228 229 230 231 232 233 234 235
############################# SECURITY SETTINGS ################################
# Default to advanced security in common.py, so tests can reset here to use
# a simpler security model
FEATURES['ENFORCE_PASSWORD_POLICY'] = False
FEATURES['ENABLE_MAX_FAILED_LOGIN_ATTEMPTS'] = False
FEATURES['SQUELCH_PII_IN_LOGS'] = False
FEATURES['PREVENT_CONCURRENT_LOGINS'] = False
FEATURES['ADVANCED_SECURITY'] = False
PASSWORD_MIN_LENGTH = None
PASSWORD_COMPLEXITY = {}

236 237 238
######### Third-party auth ##########
FEATURES['ENABLE_THIRD_PARTY_AUTH'] = True

239 240 241 242 243 244 245 246 247 248 249
THIRD_PARTY_AUTH = {
    "Google": {
        "SOCIAL_AUTH_GOOGLE_OAUTH2_KEY": "test",
        "SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET": "test",
    },
    "Facebook": {
        "SOCIAL_AUTH_GOOGLE_OAUTH2_KEY": "test",
        "SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET": "test",
    },
}

250
################################## OPENID #####################################
251 252
FEATURES['AUTH_USE_OPENID'] = True
FEATURES['AUTH_USE_OPENID_PROVIDER'] = True
253

254
################################## SHIB #######################################
255 256 257
FEATURES['AUTH_USE_SHIB'] = True
FEATURES['SHIB_DISABLE_TOS'] = True
FEATURES['RESTRICT_ENROLL_BY_REG_METHOD'] = True
258

259 260 261
OPENID_CREATE_USERS = False
OPENID_UPDATE_DETAILS_FROM_SREG = True
OPENID_USE_AS_ADMIN_LOGIN = False
262 263
OPENID_PROVIDER_TRUSTED_ROOTS = ['*']

264 265 266
############################## OAUTH2 Provider ################################
FEATURES['ENABLE_OAUTH2_PROVIDER'] = True

267 268
########################### External REST APIs #################################
FEATURES['ENABLE_MOBILE_REST_API'] = True
269
FEATURES['ENABLE_MOBILE_SOCIAL_FACEBOOK_FEATURES'] = True
270 271
FEATURES['ENABLE_VIDEO_ABSTRACTION_LAYER_API'] = True

272 273
###################### Payment ##############################3
# Enable fake payment processing page
274
FEATURES['ENABLE_PAYMENT_FAKE'] = True
275

276 277 278 279 280
# Configure the payment processor to use the fake processing page
# Since both the fake payment page and the shoppingcart app are using
# the same settings, we can generate this randomly and guarantee
# that they are using the same secret.
from random import choice
281
from string import letters, digits, punctuation  # pylint: disable=deprecated-module
282
RANDOM_SHARED_SECRET = ''.join(
283
    choice(letters + digits + punctuation)
284 285 286
    for x in range(250)
)

287 288 289 290 291 292 293
CC_PROCESSOR_NAME = 'CyberSource2'
CC_PROCESSOR['CyberSource2']['SECRET_KEY'] = RANDOM_SHARED_SECRET
CC_PROCESSOR['CyberSource2']['ACCESS_KEY'] = "0123456789012345678901"
CC_PROCESSOR['CyberSource2']['PROFILE_ID'] = "edx"
CC_PROCESSOR['CyberSource2']['PURCHASE_ENDPOINT'] = "/shoppingcart/payment_fake"

FEATURES['STORE_BILLING_INFO'] = True
294

Carson Gee committed
295 296 297 298
########################### SYSADMIN DASHBOARD ################################
FEATURES['ENABLE_SYSADMIN_DASHBOARD'] = True
GIT_REPO_DIR = TEST_ROOT / "course_repos"

299 300 301
################################# CELERY ######################################

CELERY_ALWAYS_EAGER = True
Feanil Patel committed
302
CELERY_RESULT_BACKEND = 'djcelery.backends.cache:CacheBackend'
303

304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
######################### MARKETING SITE ###############################

MKTG_URL_LINK_MAP = {
    'ABOUT': 'about',
    'CONTACT': 'contact',
    'FAQ': 'help',
    'COURSES': 'courses',
    'ROOT': 'root',
    'TOS': 'tos',
    'HONOR': 'honor',
    'PRIVACY': 'privacy',
    'JOBS': 'jobs',
    'NEWS': 'news',
    'PRESS': 'press',
    'BLOG': 'blog',
    'DONATE': 'donate',

    # Verified Certificates
    'WHAT_IS_VERIFIED_CERT': 'verified-certificate',
}


326
############################ STATIC FILES #############################
327
DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'
328
MEDIA_ROOT = TEST_ROOT / "uploads"
329 330
MEDIA_URL = "/static/uploads/"
STATICFILES_DIRS.append(("uploads", MEDIA_ROOT))
331

332
_NEW_STATICFILES_DIRS = []
333
# Strip out any static files that aren't in the repository root
334
# so that the tests can run with only the edx-platform directory checked out
335 336 337 338 339 340 341
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

342
    if data_dir.startswith(REPO_ROOT):
343 344
        _NEW_STATICFILES_DIRS.append(static_dir)
STATICFILES_DIRS = _NEW_STATICFILES_DIRS
345

346
FILE_UPLOAD_TEMP_DIR = TEST_ROOT / "uploads"
347 348 349 350
FILE_UPLOAD_HANDLERS = (
    'django.core.files.uploadhandler.MemoryFileUploadHandler',
    'django.core.files.uploadhandler.TemporaryFileUploadHandler',
)
351

352 353 354 355 356 357 358 359
########################### Server Ports ###################################

# These ports are carefully chosen so that if the browser needs to
# access them, they will be available through the SauceLabs SSH tunnel
LETTUCE_SERVER_PORT = 8003
XQUEUE_PORT = 8040
YOUTUBE_PORT = 8031
LTI_PORT = 8765
360
VIDEO_SOURCE_PORT = 8777
361

362 363 364 365 366 367 368 369 370 371 372
################### Make tests faster

#http://slacy.com/blog/2012/04/make-your-tests-faster-in-django-1-4/
PASSWORD_HASHERS = (
    # 'django.contrib.auth.hashers.PBKDF2PasswordHasher',
    # 'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
    # 'django.contrib.auth.hashers.BCryptPasswordHasher',
    'django.contrib.auth.hashers.SHA1PasswordHasher',
    'django.contrib.auth.hashers.MD5PasswordHasher',
    # 'django.contrib.auth.hashers.CryptPasswordHasher',
)
373

374 375 376
### This enables the Metrics tab for the Instructor dashboard ###########
FEATURES['CLASS_DASHBOARD'] = True

377 378 379 380 381 382
################### Make tests quieter

# OpenID spews messages like this to stderr, we don't need to see them:
#   Generated checkid_setup request to http://testserver/openid/provider/login/ with assocication {HMAC-SHA1}{51d49995}{s/kRmA==}

import openid.oidutil
stv committed
383
openid.oidutil.log = lambda message, level=0: None
384

385 386 387
PLATFORM_NAME = "edX"
SITE_NAME = "edx.org"

388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
# set up some testing for microsites
MICROSITE_CONFIGURATION = {
    "test_microsite": {
        "domain_prefix": "testmicrosite",
        "university": "test_microsite",
        "platform_name": "Test Microsite",
        "logo_image_url": "test_microsite/images/header-logo.png",
        "email_from_address": "test_microsite@edx.org",
        "payment_support_email": "test_microsite@edx.org",
        "ENABLE_MKTG_SITE": False,
        "SITE_NAME": "test_microsite.localhost",
        "course_org_filter": "TestMicrositeX",
        "course_about_show_social_links": False,
        "css_overrides_file": "test_microsite/css/test_microsite.css",
        "show_partners": False,
        "show_homepage_promo_video": False,
        "course_index_overlay_text": "This is a Test Microsite Overlay Text.",
        "course_index_overlay_logo_file": "test_microsite/images/header-logo.png",
406 407
        "homepage_overlay_html": "<h1>This is a Test Microsite Overlay HTML</h1>",
        "ALWAYS_REDIRECT_HOMEPAGE_TO_DASHBOARD_FOR_AUTHENTICATED_USER": False,
408 409
        "COURSE_CATALOG_VISIBILITY_PERMISSION": "see_in_catalog",
        "COURSE_ABOUT_VISIBILITY_PERMISSION": "see_about_page",
410 411
        "ENABLE_SHOPPING_CART": True,
        "ENABLE_PAID_COURSE_REGISTRATION": True,
412
        "SESSION_COOKIE_DOMAIN": "test_microsite.localhost",
413 414 415 416
    },
    "default": {
        "university": "default_university",
        "domain_prefix": "www",
417 418
    }
}
419
MICROSITE_ROOT_DIR = COMMON_ROOT / 'test' / 'test_microsites'
420 421
MICROSITE_TEST_HOSTNAME = 'testmicrosite.testserver'

422
FEATURES['USE_MICROSITES'] = True
423

424 425 426 427 428 429
# add extra template directory for test-only templates
MAKO_TEMPLATES['main'].extend([
    COMMON_ROOT / 'test' / 'templates'
])


430 431
# Setting for the testing of Software Secure Result Callback
VERIFY_STUDENT["SOFTWARE_SECURE"] = {
432 433
    "API_ACCESS_KEY": "BBBBBBBBBBBBBBBBBBBB",
    "API_SECRET_KEY": "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC",
434
}
435 436 437 438

VIDEO_CDN_URL = {
    'CN': 'http://api.xuetangx.com/edx/video?s3_url='
}
439 440 441 442 443 444 445 446 447

######### dashboard git log settings #########
MONGODB_LOG = {
    'host': MONGO_HOST,
    'port': MONGO_PORT_NUM,
    'user': '',
    'password': '',
    'db': 'xlog',
}
448 449 450

# Enable EdxNotes for tests.
FEATURES['ENABLE_EDXNOTES'] = True
451 452 453

# Add milestones to Installed apps for testing
INSTALLED_APPS += ('milestones', )
454 455 456 457 458 459

# MILESTONES
FEATURES['MILESTONES_APP'] = True

# ENTRANCE EXAMS
FEATURES['ENTRANCE_EXAMS'] = True
460 461 462

# Enable courseware search for tests
FEATURES['ENABLE_COURSEWARE_SEARCH'] = True
463 464 465 466

# Enable dashboard search for tests
FEATURES['ENABLE_DASHBOARD_SEARCH'] = True

467 468
# Use MockSearchEngine as the search engine for test scenario
SEARCH_ENGINE = "search.tests.mock_search_engine.MockSearchEngine"
469 470 471 472

FACEBOOK_APP_SECRET = "Test"
FACEBOOK_APP_ID = "Test"
FACEBOOK_API_VERSION = "v2.2"
473 474 475

# Certificates Views
FEATURES['CERTIFICATES_HTML_VIEW'] = True
476

cewing committed
477 478 479
######### custom courses #########
INSTALLED_APPS += ('ccx',)
MIDDLEWARE_CLASSES += ('ccx.overrides.CcxMiddleware',)
480
FEATURES['CUSTOM_COURSES_EDX'] = True
481 482

# Set dummy values for profile image settings.
483 484 485 486 487 488 489
PROFILE_IMAGE_BACKEND = {
    'class': 'storages.backends.overwrite.OverwriteStorage',
    'options': {
        'location': MEDIA_ROOT,
        'base_url': 'http://example-storage.com/profile-images/',
    },
}
490
PROFILE_IMAGE_DEFAULT_FILENAME = 'default'
491
PROFILE_IMAGE_DEFAULT_FILE_EXTENSION = 'png'
492
PROFILE_IMAGE_SECRET_KEY = 'secret'
493 494
PROFILE_IMAGE_MAX_BYTES = 1024 * 1024
PROFILE_IMAGE_MIN_BYTES = 100
495 496 497 498

# Enable the LTI provider feature for testing
FEATURES['ENABLE_LTI_PROVIDER'] = True
INSTALLED_APPS += ('lti_provider',)