Commit 67d75634 by Matjaz Gregoric

Merge pull request #92 from open-craft/headandshoulders

Fix flaky tests
parents cc0c234e dea77481
language: python
python:
- "2.7"
before_install:
- "export DISPLAY=:99"
- "sh -e /etc/init.d/xvfb start"
install:
- "pip install -e git://github.com/edx/xblock-sdk.git@22c1b2f173919bef22f2d9d9295ec5396d02dffd#egg=xblock-sdk"
- "pip install -r requirements.txt"
- "pip install -r $VIRTUAL_ENV/src/xblock-sdk/requirements/base.txt"
- "pip install -r $VIRTUAL_ENV/src/xblock-sdk/requirements/test.txt"
- "pip uninstall -y xblock-problem-builder && python setup.py sdist && pip install dist/xblock-problem-builder-2.0.tar.gz"
- "pip install -r test_requirements.txt"
- "mkdir var"
script:
- pep8 problem_builder --max-line-length=120
- pylint problem_builder --disable=all --enable=function-redefined,undefined-variable,unused-variable
- python run_tests.py --with-coverage --cover-package=problem_builder
notifications:
email: false
addons:
firefox: "36.0"
Problem Builder and Step Builder Problem Builder and Step Builder
-------------------------------- --------------------------------
[![Build Status](https://travis-ci.org/open-craft/problem-builder.svg?branch=master)](https://travis-ci.org/open-craft/problem-builder) [![Circle CI](https://circleci.com/gh/open-craft/problem-builder.svg?style=svg)](https://circleci.com/gh/open-craft/problem-builder)
This repository provides two XBlocks: Problem Builder and Step Builder. This repository provides two XBlocks: Problem Builder and Step Builder.
......
machine:
python:
version: 2.7.10
dependencies:
override:
- "pip install -U pip wheel setuptools"
- "pip install -e git://github.com/edx/xblock-sdk.git@22c1b2f173919bef22f2d9d9295ec5396d02dffd#egg=xblock-sdk"
- "pip install -r requirements.txt"
- "pip install -r $VIRTUAL_ENV/src/xblock-sdk/requirements/base.txt"
- "pip install -r $VIRTUAL_ENV/src/xblock-sdk/requirements/test.txt"
- "pip uninstall -y xblock-problem-builder && python setup.py sdist && pip install dist/xblock-problem-builder-2.0.tar.gz"
- "pip install -r test_requirements.txt"
- "mkdir var"
test:
override:
- "if [ $CIRCLE_NODE_INDEX = '0' ]; then pep8 problem_builder --max-line-length=120; fi":
parallel: true
- "if [ $CIRCLE_NODE_INDEX = '1' ]; then pylint problem_builder --disable=all --enable=function-redefined,undefined-variable,unused-variable; fi":
parallel: true
- "python run_tests.py":
parallel: true
files:
- "problem_builder/v1/tests/**/*.py"
- "problem_builder/tests/**/*.py"
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
If an author makes changes to the block after students have started using it, will bad things If an author makes changes to the block after students have started using it, will bad things
happen? happen?
""" """
import time
from .base_test import ProblemBuilderBaseTest, MentoringAssessmentBaseTest from .base_test import ProblemBuilderBaseTest, MentoringAssessmentBaseTest
import re import re
...@@ -20,6 +21,12 @@ class AuthorChangesTest(ProblemBuilderBaseTest): ...@@ -20,6 +21,12 @@ class AuthorChangesTest(ProblemBuilderBaseTest):
[Re]load the page with our scenario [Re]load the page with our scenario
""" """
self.pb_block_dom = self.go_to_view("student_view") self.pb_block_dom = self.go_to_view("student_view")
# At this point the ajax request that initializes the Mentoring block
# might be still in progres. Race conditions resulting in duplicate field data
# can occur if we try to reload the block at the same time.
# Sleep 200ms to wait for the ajax request to finish, unfortunately I wasn't
# able to find a better way.
time.sleep(0.2)
self.reload_pb_block() self.reload_pb_block()
def reload_pb_block(self): def reload_pb_block(self):
......
import time
from mock import patch from mock import patch
from ddt import ddt, data from ddt import ddt, data
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support.ui import WebDriverWait
...@@ -1332,7 +1330,8 @@ class StepBuilderTest(MentoringAssessmentBaseTest, MultipleSliderBlocksTestMixin ...@@ -1332,7 +1330,8 @@ class StepBuilderTest(MentoringAssessmentBaseTest, MultipleSliderBlocksTestMixin
def is_scrolled_to_top(driver): def is_scrolled_to_top(driver):
scroll_top = int(driver.execute_script("return $(window).scrollTop()")) scroll_top = int(driver.execute_script("return $(window).scrollTop()"))
return abs(scroll_top - step_builder_offset) < 1 tolerance = 2
return abs(scroll_top - step_builder_offset) <= tolerance
wait = WebDriverWait(self.browser, 5) wait = WebDriverWait(self.browser, 5)
wait.until(is_scrolled_to_top) wait.until(is_scrolled_to_top)
...@@ -1342,7 +1341,7 @@ class StepBuilderTest(MentoringAssessmentBaseTest, MultipleSliderBlocksTestMixin ...@@ -1342,7 +1341,7 @@ class StepBuilderTest(MentoringAssessmentBaseTest, MultipleSliderBlocksTestMixin
def test_scroll_into_view(self): def test_scroll_into_view(self):
# Make window small, so that we have to scroll. # Make window small, so that we have to scroll.
self.browser.set_window_size(400, 400) self.browser.set_window_size(600, 400)
step_builder, controls = self.load_assessment_scenario("step_builder_long_steps.xml", {}) step_builder, controls = self.load_assessment_scenario("step_builder_long_steps.xml", {})
# First step # First step
self.check_viewport() self.check_viewport()
......
...@@ -9,7 +9,6 @@ because the workbench SDK's settings file is not inside any python module. ...@@ -9,7 +9,6 @@ because the workbench SDK's settings file is not inside any python module.
import os import os
import sys import sys
import logging import logging
logging_level_overrides = { logging_level_overrides = {
...@@ -18,7 +17,38 @@ logging_level_overrides = { ...@@ -18,7 +17,38 @@ logging_level_overrides = {
'workbench.runtime': logging.ERROR, 'workbench.runtime': logging.ERROR,
} }
def patch_broken_pipe_error():
"""Monkey Patch BaseServer.handle_error to not write a stacktrace to stderr on broken pipe.
This message is automatically suppressed in Django 1.8, so this monkey patch can be
removed once the workbench upgrades to Django >= 1.8.
http://stackoverflow.com/a/22618740/51397"""
import socket
from SocketServer import BaseServer
from wsgiref import handlers
handle_error = BaseServer.handle_error
log_exception = handlers.BaseHandler.log_exception
def is_broken_pipe_error():
exc_type, exc_value = sys.exc_info()[:2]
if issubclass(exc_type, socket.error) and exc_value.args[0] == 32:
return True
return False
def my_handle_error(self, request, client_address):
if not is_broken_pipe_error():
handle_error(self, request, client_address)
def my_log_exception(self, exc_info):
if not is_broken_pipe_error():
log_exception(self, exc_info)
BaseServer.handle_error = my_handle_error
handlers.BaseHandler.log_exception = my_log_exception
if __name__ == "__main__": if __name__ == "__main__":
patch_broken_pipe_error()
# Use the workbench settings file: # Use the workbench settings file:
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "workbench.settings") os.environ.setdefault("DJANGO_SETTINGS_MODULE", "workbench.settings")
# Configure a range of ports in case the default port of 8081 is in use # Configure a range of ports in case the default port of 8081 is in use
......
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