Skip to content

Commit

Permalink
Check YouTube Availabitlity for Video Tests
Browse files Browse the repository at this point in the history
  • Loading branch information
muhammad-ammar committed May 29, 2014
1 parent 721732b commit 7afcb93
Show file tree
Hide file tree
Showing 12 changed files with 143 additions and 75 deletions.
2 changes: 1 addition & 1 deletion cms/djangoapps/contentstore/features/transcripts.feature
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@shard_3
@shard_3 @requires_stub_youtube
Feature: CMS Transcripts
As a course author, I want to be able to create video components

Expand Down
2 changes: 1 addition & 1 deletion cms/djangoapps/contentstore/features/video.feature
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@shard_3
@shard_3 @requires_stub_youtube
Feature: CMS Video Component
As a course author, I want to be able to view my created videos in Studio

Expand Down
4 changes: 0 additions & 4 deletions cms/djangoapps/contentstore/features/video.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# pylint: disable=C0111

from lettuce import world, step
from nose.tools import assert_less
from xmodule.modulestore import Location
from contentstore.utils import get_modulestore
from selenium.webdriver.common.keys import Keys

Expand All @@ -22,7 +20,6 @@
# We should wait 300 ms for event handler invocation + 200ms for safety.
DELAY = 0.5


@step('youtube stub server (.*) YouTube API')
def configure_youtube_api(_step, action):
action=action.strip()
Expand All @@ -33,7 +30,6 @@ def configure_youtube_api(_step, action):
else:
raise ValueError('Parameter `action` should be one of "proxies" or "blocks".')


@step('I have created a Video component$')
def i_created_a_video_component(_step):

Expand Down
2 changes: 1 addition & 1 deletion cms/djangoapps/contentstore/features/video_editor.feature
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@shard_1
@shard_1 @requires_stub_youtube
Feature: CMS Video Component Editor
As a course author, I want to be able to create video components

Expand Down
2 changes: 1 addition & 1 deletion cms/djangoapps/contentstore/features/video_handout.feature
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@shard_3
@shard_3 @requires_stub_youtube
Feature: CMS Video Component Handout
As a course author, I want to be able to create video handout

Expand Down
9 changes: 5 additions & 4 deletions common/djangoapps/terrain/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Use this as your lettuce terrain file so that the common steps
# across all lms apps can be put in terrain/common
# See https://groups.google.com/forum/?fromgroups=#!msg/lettuce-users/5VyU9B4HcX8/USgbGIJdS5QJ
from terrain.browser import *
from terrain.steps import *
from terrain.factories import *
from terrain.start_stubs import *

from terrain.browser import * # pylint: disable=W0401
from terrain.steps import * # pylint: disable=W0401
from terrain.factories import * # pylint: disable=W0401
from terrain.setup_prereqs import * # pylint: disable=W0401
129 changes: 129 additions & 0 deletions common/djangoapps/terrain/setup_prereqs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
"""
Set up the prequisites for acceptance tests.
This includes initialization and teardown for stub and video HTTP services
and checking for external URLs that need to be accessible and responding.
"""
from lettuce import before, after, world
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

import re
import requests


SERVICES = {
"youtube": {"port": settings.YOUTUBE_PORT, "class": StubYouTubeService},
"xqueue": {"port": settings.XQUEUE_PORT, "class": StubXQueueService},
"lti": {"port": settings.LTI_PORT, "class": StubLtiService},
}

YOUTUBE_API_URLS = {
'main': 'https://www.youtube.com/',
'player': 'http://www.youtube.com/iframe_api',
'metadata': 'http://gdata.youtube.com/feeds/api/videos/',
# For transcripts, you need to check an actual video, so we will
# just specify our default video and see if that one is available.
'transcript': 'http://video.google.com/timedtext?lang=en&v=OEoXaMPEzfM',
}


@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 process_requires_tags(scenario):
"""
Process the scenario tags to make sure that any
requirements are met prior to that scenario
being executed.
Scenario tags must be named with this convention:
@requires_stub_bar, where 'bar' is the name of the stub service to start
if 'bar' is 'youtube'
if 'youtube' is not available Then
DON'T start youtube stub server
ALSO DON'T start any other stub server BECAUSE we will SKIP this Scenario so no need to start any stub
else
start the stub server
"""
tag_re = re.compile('requires_stub_(?P<server>[^_]+)')
for tag in scenario.tags:
requires = tag_re.match(tag)

if requires:
if requires.group('server') == 'youtube':
if not is_youtube_available(scenario, YOUTUBE_API_URLS):
return

start_stub(requires.group('server'))


def start_stub(name):
"""
Start the required stub service running on a local port.
Since these services can be reconfigured on the fly,
we start them on a scenario basis when needed and
stop them at the end of the scenario.
"""
service = SERVICES.get(name, None)
if service:
fake_server = service['class'](port_num=service['port'])
setattr(world, name, fake_server)


def is_youtube_available(scenario, urls):
"""
Check if the required youtube urls are available.
If they are not, then skip the scenario.
"""
for name, url in urls.iteritems():
response = requests.get(url, allow_redirects=False)
status = response.status_code
if status != 200:
print "ERROR: YouTube {0} service not available. Status code: {1}".format(
name, status)

# This is a hackish way to skip a test in lettuce as there is
# no proper way to skip a test conditionally
scenario.steps = []

# No need to check all the URLs
return False

return True


@after.each_scenario
def stop_stubs(_scenario):
"""
Shut down any stub services that were started up for the scenario.
"""
for name in SERVICES.keys():
stub_server = getattr(world, name, None)
if stub_server is not None:
stub_server.shutdown()
60 changes: 0 additions & 60 deletions common/djangoapps/terrain/start_stubs.py

This file was deleted.

2 changes: 1 addition & 1 deletion lms/djangoapps/courseware/features/lti.feature
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@shard_1
@shard_1 @requires_stub_lti
Feature: LMS.LTI component
As a student, I want to view LTI component in LMS.

Expand Down
2 changes: 1 addition & 1 deletion lms/djangoapps/courseware/features/problems.feature
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@shard_1
@shard_1 @requires_stub_xqueue
Feature: LMS.Answer problems
As a student in an edX course
In order to test my understanding of the material
Expand Down
2 changes: 1 addition & 1 deletion lms/djangoapps/courseware/features/video.feature
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@shard_2
@shard_2 @requires_stub_youtube
Feature: LMS.Video component
As a student, I want to view course videos in LMS

Expand Down
2 changes: 2 additions & 0 deletions lms/djangoapps/courseware/features/video.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from xmodule.contentstore.content import StaticContent
from xmodule.contentstore.django import contentstore


TEST_ROOT = settings.COMMON_TEST_DATA_ROOT
LANGUAGES = settings.ALL_LANGUAGES
VIDEO_SOURCE_PORT = settings.VIDEO_SOURCE_PORT
Expand Down Expand Up @@ -55,6 +56,7 @@

coursenum = 'test_course'


@before.each_scenario
def setUp(scenario):
world.video_sequences = {}
Expand Down

0 comments on commit 7afcb93

Please sign in to comment.