From 3fc19a35b0c8718e3d25d76c458aa5343c924b7b Mon Sep 17 00:00:00 2001 From: Jay Zoldak <zoldak@edx.org> Date: Thu, 10 Apr 2014 14:42:26 -0400 Subject: [PATCH] Serve video HTML5 sources locally for acceptance tests --- cms/envs/test.py | 1 + common/djangoapps/terrain/start_stubs.py | 31 ++++++++++-- common/djangoapps/terrain/stubs/start.py | 2 + .../djangoapps/terrain/stubs/video_source.py | 48 +++++++++++++++++++ .../acceptance/tests/test_video_module.py | 9 ++-- lms/djangoapps/courseware/features/video.py | 10 ++-- lms/envs/test.py | 1 + rakelib/bok_choy.rake | 8 ++++ test_root/data/video/gizmo.mp99 | 2 + 9 files changed, 100 insertions(+), 12 deletions(-) create mode 100644 common/djangoapps/terrain/stubs/video_source.py create mode 100644 test_root/data/video/gizmo.mp99 diff --git a/cms/envs/test.py b/cms/envs/test.py index 4171dc303f9..74b0525388d 100644 --- a/cms/envs/test.py +++ b/cms/envs/test.py @@ -175,6 +175,7 @@ LETTUCE_SERVER_PORT = 8003 XQUEUE_PORT = 8040 YOUTUBE_PORT = 8031 LTI_PORT = 8765 +VIDEO_SOURCE_PORT = 8777 ################### Make tests faster diff --git a/common/djangoapps/terrain/start_stubs.py b/common/djangoapps/terrain/start_stubs.py index b859e95df44..a4dd93ad4c0 100644 --- a/common/djangoapps/terrain/start_stubs.py +++ b/common/djangoapps/terrain/start_stubs.py @@ -1,5 +1,5 @@ """ -Initialize and teardown fake HTTP services for use in acceptance tests. +Initialize and teardown stub and video HTTP services for use in acceptance tests. """ import requests from lettuce import before, after, world @@ -7,6 +7,8 @@ from django.conf import settings from terrain.stubs.youtube import StubYouTubeService from terrain.stubs.xqueue import StubXQueueService from terrain.stubs.lti import StubLtiService +from terrain.stubs.video_source import VideoSourceHttpService + SERVICES = { "youtube": {"port": settings.YOUTUBE_PORT, "class": StubYouTubeService}, @@ -17,10 +19,33 @@ SERVICES = { YOUTUBE_API_RESPONSE = requests.get('http://www.youtube.com/iframe_api') +@before.all # pylint: disable=E1101 +def start_video_server(): + """ + Serve the HTML5 Video Sources from a local port + """ + video_source_dir = '{}/data/video'.format(settings.TEST_ROOT) + video_server = VideoSourceHttpService(port_num=settings.VIDEO_SOURCE_PORT) + video_server.config['root_dir'] = video_source_dir + setattr(world, 'video_source', video_server) + + +@after.all # pylint: disable=E1101 +def stop_video_server(_total): + """ + Stop the HTML5 Video Source server after all tests have executed + """ + video_server = getattr(world, 'video_source', None) + if video_server: + video_server.shutdown() + + @before.each_scenario -def start_stubs(_): +def start_stubs(_scenario): """ Start each stub service running on a local port. + Since these services can be reconfigured on the fly, + stop and restart them on a scenario basis. """ for name, service in SERVICES.iteritems(): fake_server = service['class'](port_num=service['port']) @@ -30,7 +55,7 @@ def start_stubs(_): @after.each_scenario -def stop_stubs(_): +def stop_stubs(_scenario): """ Shut down each stub service. """ diff --git a/common/djangoapps/terrain/stubs/start.py b/common/djangoapps/terrain/stubs/start.py index f9fdf4a388e..0a60d425395 100644 --- a/common/djangoapps/terrain/stubs/start.py +++ b/common/djangoapps/terrain/stubs/start.py @@ -9,6 +9,7 @@ from .xqueue import StubXQueueService from .youtube import StubYouTubeService from .ora import StubOraService from .lti import StubLtiService +from .video_source import VideoSourceHttpService USAGE = "USAGE: python -m stubs.start SERVICE_NAME PORT_NUM [CONFIG_KEY=CONFIG_VAL, ...]" @@ -19,6 +20,7 @@ SERVICES = { 'ora': StubOraService, 'comments': StubCommentsService, 'lti': StubLtiService, + 'video': VideoSourceHttpService, } # Log to stdout, including debug messages diff --git a/common/djangoapps/terrain/stubs/video_source.py b/common/djangoapps/terrain/stubs/video_source.py new file mode 100644 index 00000000000..460b2f7560d --- /dev/null +++ b/common/djangoapps/terrain/stubs/video_source.py @@ -0,0 +1,48 @@ +""" +Serve HTML5 video sources for acceptance tests +""" +from SimpleHTTPServer import SimpleHTTPRequestHandler +from .http import StubHttpService +from contextlib import contextmanager +import os + +from logging import getLogger +LOGGER = getLogger(__name__) + +class VideoSourceRequestHandler(SimpleHTTPRequestHandler): + """ + Request handler for serving video sources locally. + """ + def translate_path(self, path): + """ + Remove any extra parameters from the path. + For example /gizmo.mp4?1397160769634 + becomes /gizmo.mp4 + """ + root_dir = self.server.config.get('root_dir') + path = '{}{}'.format(root_dir, path) + return path.split('?')[0] + + +class VideoSourceHttpService(StubHttpService): + """ + Simple HTTP server for serving HTML5 Video sources locally for tests + """ + HANDLER_CLASS = VideoSourceRequestHandler + + def __init__(self, port_num=0): + + @contextmanager + def _remember_cwd(): + """ + Files are automatically served from the current directory + so we need to change it, start the server, then set it back. + """ + curdir = os.getcwd() + try: + yield + finally: + os.chdir(curdir) + + with _remember_cwd(): + StubHttpService.__init__(self, port_num=port_num) diff --git a/common/test/acceptance/tests/test_video_module.py b/common/test/acceptance/tests/test_video_module.py index 4fe9f321a6e..b2e67f550d5 100644 --- a/common/test/acceptance/tests/test_video_module.py +++ b/common/test/acceptance/tests/test_video_module.py @@ -11,15 +11,16 @@ from ..pages.studio.auto_auth import AutoAuthPage from ..pages.lms.course_info import CourseInfoPage from ..fixtures.course import CourseFixture, XBlockFixtureDesc +VIDEO_SOURCE_PORT = 8777 HTML5_SOURCES = [ - 'https://s3.amazonaws.com/edx-course-videos/edx-intro/edX-FA12-cware-1_100.mp4', - 'https://s3.amazonaws.com/edx-course-videos/edx-intro/edX-FA12-cware-1_100.webm', - 'https://s3.amazonaws.com/edx-course-videos/edx-intro/edX-FA12-cware-1_100.ogv', + 'http://localhost:{0}/gizmo.mp4'.format(VIDEO_SOURCE_PORT), + 'http://localhost:{0}/gizmo.webm'.format(VIDEO_SOURCE_PORT), + 'http://localhost:{0}/gizmo.ogv'.format(VIDEO_SOURCE_PORT), ] HTML5_SOURCES_INCORRECT = [ - 'https://s3.amazonaws.com/edx-course-videos/edx-intro/edX-FA12-cware-1_100.mp99', + 'http://localhost:{0}/gizmo.mp99'.format(VIDEO_SOURCE_PORT), ] HTML5_METADATA = { diff --git a/lms/djangoapps/courseware/features/video.py b/lms/djangoapps/courseware/features/video.py index 0cc89514ccb..fb81325099a 100644 --- a/lms/djangoapps/courseware/features/video.py +++ b/lms/djangoapps/courseware/features/video.py @@ -16,14 +16,14 @@ from xmodule.contentstore.django import contentstore TEST_ROOT = settings.COMMON_TEST_DATA_ROOT LANGUAGES = settings.ALL_LANGUAGES - +VIDEO_SOURCE_PORT = settings.VIDEO_SOURCE_PORT ############### ACTIONS #################### HTML5_SOURCES = [ - 'https://s3.amazonaws.com/edx-course-videos/edx-intro/edX-FA12-cware-1_100.mp4', - 'https://s3.amazonaws.com/edx-course-videos/edx-intro/edX-FA12-cware-1_100.webm', - 'https://s3.amazonaws.com/edx-course-videos/edx-intro/edX-FA12-cware-1_100.ogv', + 'http://localhost:{0}/gizmo.mp4'.format(VIDEO_SOURCE_PORT), + 'http://localhost:{0}/gizmo.webm'.format(VIDEO_SOURCE_PORT), + 'http://localhost:{0}/gizmo.ogv'.format(VIDEO_SOURCE_PORT), ] FLASH_SOURCES = { @@ -34,7 +34,7 @@ FLASH_SOURCES = { } HTML5_SOURCES_INCORRECT = [ - 'https://s3.amazonaws.com/edx-course-videos/edx-intro/edX-FA12-cware-1_100.mp99', + 'http://localhost:{0}/gizmo.mp99'.format(VIDEO_SOURCE_PORT), ] VIDEO_BUTTONS = { diff --git a/lms/envs/test.py b/lms/envs/test.py index 5b9e6a5f4af..52288774712 100644 --- a/lms/envs/test.py +++ b/lms/envs/test.py @@ -257,6 +257,7 @@ LETTUCE_SERVER_PORT = 8003 XQUEUE_PORT = 8040 YOUTUBE_PORT = 8031 LTI_PORT = 8765 +VIDEO_SOURCE_PORT = 8777 ################### Make tests faster diff --git a/rakelib/bok_choy.rake b/rakelib/bok_choy.rake index 679303ff6c0..06bf342693a 100644 --- a/rakelib/bok_choy.rake +++ b/rakelib/bok_choy.rake @@ -23,6 +23,8 @@ BOK_CHOY_XUNIT_REPORT = File.join(BOK_CHOY_REPORT_DIR, "xunit.xml") BOK_CHOY_COVERAGE_RC = File.join(BOK_CHOY_DIR, ".coveragerc") directory BOK_CHOY_REPORT_DIR +# Directory that videos are served from +VIDEO_SOURCE_DIR = File.join(REPO_ROOT, "test_root", "data", "video") BOK_CHOY_SERVERS = { :lms => { :port => 8003, :log => File.join(BOK_CHOY_LOG_DIR, "bok_choy_lms.log") }, @@ -46,6 +48,12 @@ BOK_CHOY_STUBS = { :comments => { :port => 4567, :log => File.join(BOK_CHOY_LOG_DIR, "bok_choy_comments.log") + }, + + :video => { + :port => 8777, + :log => File.join(BOK_CHOY_LOG_DIR, "bok_choy_video_sources.log"), + :config => "root_dir=#{VIDEO_SOURCE_DIR}" } } diff --git a/test_root/data/video/gizmo.mp99 b/test_root/data/video/gizmo.mp99 new file mode 100644 index 00000000000..df23f62c2fc --- /dev/null +++ b/test_root/data/video/gizmo.mp99 @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>1205EB22685DC2E7</RequestId><HostId>/a61gfYpYdzvEXubtCRZCM8u3hsEBjRxcZ+aCP0VXVcL2oQmWo2bZ1aAocxXiZ+S</HostId></Error> -- GitLab