Commit 4ff1c8b3 by Andy Armstrong

Merge pull request #8529 from edx/andya/bokchoy-asset-pipeline

Update Bok Choy to run against optimized static files
parents 95091794 923edee1
""" """
Settings for bok choy tests Settings for Bok Choy tests that are used for running CMS and LMS.
Bok Choy uses two different settings files:
1. test_static_optimized is used when invoking collectstatic
2. bok_choy is used when running CMS and LMS
Note: it isn't possible to have a single settings file, because Django doesn't
support both generating static assets to a directory and also serving static
from the same directory.
""" """
import os import os
...@@ -44,8 +52,20 @@ update_module_store_settings( ...@@ -44,8 +52,20 @@ update_module_store_settings(
default_store=os.environ.get('DEFAULT_STORE', 'draft'), default_store=os.environ.get('DEFAULT_STORE', 'draft'),
) )
# Enable django-pipeline and staticfiles ############################ STATIC FILES #############################
STATIC_ROOT = (TEST_ROOT / "staticfiles").abspath()
# Enable debug so that static assets are served by Django
DEBUG = True
# Serve static files at /static directly from the staticfiles directory under test root
# Note: optimized files for testing are generated with settings from test_static_optimized
STATIC_URL = "/static/"
STATICFILES_FINDERS = (
'staticfiles.finders.FileSystemFinder',
)
STATICFILES_DIRS = (
(TEST_ROOT / "staticfiles").abspath(),
)
# Silence noisy logs # Silence noisy logs
import logging import logging
...@@ -80,9 +100,6 @@ FEATURES['ENABLE_VIDEO_BUMPER'] = True # Enable video bumper in Studio settings ...@@ -80,9 +100,6 @@ FEATURES['ENABLE_VIDEO_BUMPER'] = True # Enable video bumper in Studio settings
########################### Entrance Exams ################################# ########################### Entrance Exams #################################
FEATURES['ENTRANCE_EXAMS'] = True FEATURES['ENTRANCE_EXAMS'] = True
# Unfortunately, we need to use debug mode to serve staticfiles
DEBUG = True
# Point the URL used to test YouTube availability to our stub YouTube server # Point the URL used to test YouTube availability to our stub YouTube server
YOUTUBE_PORT = 9080 YOUTUBE_PORT = 9080
YOUTUBE['API'] = "127.0.0.1:{0}/get_youtube_api/".format(YOUTUBE_PORT) YOUTUBE['API'] = "127.0.0.1:{0}/get_youtube_api/".format(YOUTUBE_PORT)
......
"""
Settings used when generating static assets for use in tests.
For example, Bok Choy uses two different settings files:
1. test_static_optimized is used when invoking collectstatic
2. bok_choy is used when running CMS and LMS
Note: it isn't possible to have a single settings file, because Django doesn't
support both generating static assets to a directory and also serving static
from the same directory.
"""
import os
from path import path # pylint: disable=no-name-in-module
# 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
########################## Prod-like settings ###################################
# These should be as close as possible to the settings we use in production.
# As in prod, we read in environment and auth variables from JSON files.
# Unlike in prod, we use the JSON files stored in this repo.
# This is a convenience for ensuring (a) that we can consistently find the files
# and (b) that the files are the same in Jenkins as in local dev.
os.environ['SERVICE_VARIANT'] = 'bok_choy'
os.environ['CONFIG_ROOT'] = path(__file__).abspath().dirname() # pylint: disable=no-value-for-parameter
from .aws import * # pylint: disable=wildcard-import, unused-wildcard-import
######################### Testing overrides ####################################
# Redirects to the test_root folder within the repo
TEST_ROOT = CONFIG_ROOT.dirname().dirname() / "test_root" # pylint: disable=no-value-for-parameter
LOG_DIR = (TEST_ROOT / "log").abspath()
# Stores the static files under test root so that they don't overwrite existing static assets
STATIC_ROOT = (TEST_ROOT / "staticfiles").abspath()
# Disables uglify when tests are running (used by build.js).
# 1. Uglify is by far the slowest part of the build process
# 2. Having full source code makes debugging tests easier for developers
os.environ['REQUIRE_BUILD_PROFILE_OPTIMIZE'] = 'none'
...@@ -19,6 +19,10 @@ ...@@ -19,6 +19,10 @@
})); }));
}; };
var jsOptimize = process.env.REQUIRE_BUILD_PROFILE_OPTIMIZE !== undefined ?
process.env.REQUIRE_BUILD_PROFILE_OPTIMIZE : 'uglify2';
return { return {
/** /**
* List the modules that will be optimized. All their immediate and deep * List the modules that will be optimized. All their immediate and deep
...@@ -143,7 +147,7 @@ ...@@ -143,7 +147,7 @@
* mode to minify the code. Only available if REQUIRE_ENVIRONMENT is "rhino" (the default). * mode to minify the code. Only available if REQUIRE_ENVIRONMENT is "rhino" (the default).
* - "none": No minification will be done. * - "none": No minification will be done.
*/ */
optimize: 'uglify2', optimize: jsOptimize,
/** /**
* Sets the logging level. It is a number: * Sets the logging level. It is a number:
* TRACE: 0, * TRACE: 0,
......
...@@ -239,10 +239,16 @@ class ImportMixin(object): ...@@ -239,10 +239,16 @@ class ImportMixin(object):
def is_timestamp_visible(self): def is_timestamp_visible(self):
""" """
Checks if the UTC timestamp of the last successfull import is visible Checks if the UTC timestamp of the last successful import is visible
""" """
return self.q(css='.item-progresspoint-success-date').visible return self.q(css='.item-progresspoint-success-date').visible
def wait_for_timestamp_visible(self):
"""
Wait for the timestamp of the last successful import to be visible.
"""
EmptyPromise(self.is_timestamp_visible, 'Timestamp Visible', timeout=30).fulfill()
def wait_for_filename_error(self): def wait_for_filename_error(self):
""" """
Wait for the upload field to display an error. Wait for the upload field to display an error.
......
...@@ -4,7 +4,6 @@ Acceptance tests for the Import and Export pages ...@@ -4,7 +4,6 @@ Acceptance tests for the Import and Export pages
from abc import abstractmethod from abc import abstractmethod
from bok_choy.promise import EmptyPromise from bok_choy.promise import EmptyPromise
from datetime import datetime from datetime import datetime
from flaky import flaky
from .base_studio_test import StudioLibraryTest, StudioCourseTest from .base_studio_test import StudioLibraryTest, StudioCourseTest
from ...fixtures.course import XBlockFixtureDesc from ...fixtures.course import XBlockFixtureDesc
...@@ -186,7 +185,6 @@ class ImportTestMixin(object): ...@@ -186,7 +185,6 @@ class ImportTestMixin(object):
self.import_page.upload_tarball(self.tarball_name) self.import_page.upload_tarball(self.tarball_name)
self.import_page.wait_for_upload() self.import_page.wait_for_upload()
@flaky # TODO: fix this. See TNL-2386
def test_import_timestamp(self): def test_import_timestamp(self):
""" """
Scenario: I perform a course / library import Scenario: I perform a course / library import
...@@ -200,13 +198,13 @@ class ImportTestMixin(object): ...@@ -200,13 +198,13 @@ class ImportTestMixin(object):
utc_now = datetime.utcnow() utc_now = datetime.utcnow()
import_date, import_time = self.import_page.timestamp import_date, import_time = self.import_page.timestamp
self.assertTrue(self.import_page.is_timestamp_visible()) self.import_page.wait_for_timestamp_visible()
self.assertEqual(utc_now.strftime('%m/%d/%Y'), import_date) self.assertEqual(utc_now.strftime('%m/%d/%Y'), import_date)
self.assertEqual(utc_now.strftime('%H:%M'), import_time) self.assertEqual(utc_now.strftime('%H:%M'), import_time)
self.import_page.visit() self.import_page.visit()
self.import_page.wait_for_tasks(completed=True) self.import_page.wait_for_tasks(completed=True)
self.assertTrue(self.import_page.is_timestamp_visible()) self.import_page.wait_for_timestamp_visible()
def test_landing_url(self): def test_landing_url(self):
""" """
......
...@@ -1965,7 +1965,7 @@ class TestEmailMessageWithCustomICRVBlock(ModuleStoreTestCase): ...@@ -1965,7 +1965,7 @@ class TestEmailMessageWithCustomICRVBlock(ModuleStoreTestCase):
"We could not verify your identity for the {assessment} assessment " "We could not verify your identity for the {assessment} assessment "
"in the {course_name} course. You have used " "in the {course_name} course. You have used "
"{used_attempts} out of {allowed_attempts} attempts to " "{used_attempts} out of {allowed_attempts} attempts to "
"verify your identity.".format( "verify your identity".format(
course_name=self.course.display_name_with_default, course_name=self.course.display_name_with_default,
assessment=self.assessment, assessment=self.assessment,
used_attempts=1, used_attempts=1,
......
"""
Settings used when generating static assets for use in tests.
Bok Choy uses two different settings files:
1. test_static_optimized is used when invoking collectstatic
2. bok_choy is used when running CMS and LMS
Note: it isn't possible to have a single settings file, because Django doesn't
support both generating static assets to a directory and also serving static
from the same directory.
"""
# TODO: update the Bok Choy tests to run with optimized static assets (as is done in Studio)
from .bok_choy import * # pylint: disable=wildcard-import, unused-wildcard-import
...@@ -91,7 +91,7 @@ class AcceptanceTestSuite(TestSuite): ...@@ -91,7 +91,7 @@ class AcceptanceTestSuite(TestSuite):
def __enter__(self): def __enter__(self):
super(AcceptanceTestSuite, self).__enter__() super(AcceptanceTestSuite, self).__enter__()
if not self.skip_clean: if not (self.fasttest or self.skip_clean):
test_utils.clean_test_files() test_utils.clean_test_files()
if not self.fasttest: if not self.fasttest:
......
...@@ -57,7 +57,7 @@ class BokChoyTestSuite(TestSuite): ...@@ -57,7 +57,7 @@ class BokChoyTestSuite(TestSuite):
self.report_dir.makedirs_p() self.report_dir.makedirs_p()
test_utils.clean_reports_dir() test_utils.clean_reports_dir()
if not self.skip_clean: if not (self.fasttest or self.skip_clean):
test_utils.clean_test_files() test_utils.clean_test_files()
msg = colorize('green', "Checking for mongo, memchache, and mysql...") msg = colorize('green', "Checking for mongo, memchache, and mysql...")
...@@ -85,16 +85,13 @@ class BokChoyTestSuite(TestSuite): ...@@ -85,16 +85,13 @@ class BokChoyTestSuite(TestSuite):
def prepare_bokchoy_run(self): def prepare_bokchoy_run(self):
""" """
Sets up and starts servers for bok-choy run. This includes any stubbed servers. Sets up and starts servers for a Bok Choy run. If --fasttest is not
specified then static assets are collected
""" """
sh("{}/scripts/reset-test-db.sh".format(Env.REPO_ROOT)) sh("{}/scripts/reset-test-db.sh".format(Env.REPO_ROOT))
if not self.fasttest: if not self.fasttest:
# Process assets and set up database for bok-choy tests self.generate_optimized_static_assets()
# Reset the database
# Collect static assets
sh("paver update_assets --settings=bok_choy")
# Clear any test data already in Mongo or MySQLand invalidate # Clear any test data already in Mongo or MySQLand invalidate
# the cache # the cache
......
...@@ -3,6 +3,8 @@ A class used for defining and running test suites ...@@ -3,6 +3,8 @@ A class used for defining and running test suites
""" """
import sys import sys
import subprocess import subprocess
from paver.easy import sh
from pavelib.utils.process import kill_process from pavelib.utils.process import kill_process
try: try:
...@@ -57,6 +59,14 @@ class TestSuite(object): ...@@ -57,6 +59,14 @@ class TestSuite(object):
""" """
return None return None
def generate_optimized_static_assets(self):
"""
Collect static assets using test_static_optimized.py which generates
optimized files to a dedicated test static root.
"""
print colorize('green', "Generating optimized static assets...")
sh("paver update_assets --settings=test_static_optimized")
def run_test(self): def run_test(self):
""" """
Runs a self.cmd in a subprocess and waits for it to finish. Runs a self.cmd in a subprocess and waits for it to finish.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment