Merge pull request #3882 from edx/ammar/test-youtube-availibility
Check YouTube Availability for Video Tests
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -22,7 +20,6 @@ SELECTORS = {
|
||||
# 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()
|
||||
@@ -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):
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
common/djangoapps/terrain/setup_prereqs.py
Normal file
129
common/djangoapps/terrain/setup_prereqs.py
Normal file
@@ -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()
|
||||
@@ -1,60 +0,0 @@
|
||||
"""
|
||||
Initialize and teardown stub and video HTTP services for use in acceptance tests.
|
||||
"""
|
||||
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
|
||||
|
||||
|
||||
SERVICES = {
|
||||
"youtube": {"port": settings.YOUTUBE_PORT, "class": StubYouTubeService},
|
||||
"xqueue": {"port": settings.XQUEUE_PORT, "class": StubXQueueService},
|
||||
"lti": {"port": settings.LTI_PORT, "class": StubLtiService},
|
||||
}
|
||||
|
||||
|
||||
@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(_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'])
|
||||
setattr(world, name, fake_server)
|
||||
|
||||
|
||||
@after.each_scenario
|
||||
def stop_stubs(_scenario):
|
||||
"""
|
||||
Shut down each stub service.
|
||||
"""
|
||||
for name in SERVICES.keys():
|
||||
stub_server = getattr(world, name, None)
|
||||
if stub_server is not None:
|
||||
stub_server.shutdown()
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ from cache_toolbox.core import del_cached_content
|
||||
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
|
||||
@@ -55,6 +56,7 @@ VIDEO_MENUS = {
|
||||
|
||||
coursenum = 'test_course'
|
||||
|
||||
|
||||
@before.each_scenario
|
||||
def setUp(scenario):
|
||||
world.video_sequences = {}
|
||||
|
||||
Reference in New Issue
Block a user