From d117222f7c8252648ce02dab8e0cc3f66a742ee3 Mon Sep 17 00:00:00 2001 From: uzairr Date: Thu, 9 Mar 2017 07:25:47 +0000 Subject: [PATCH] Add timeout in request to xqueue --- common/lib/capa/capa/xqueue_interface.py | 16 ++++++++++++---- .../xmodule/xmodule/tests/test_capa_module.py | 17 +++++++++++++++++ .../tests/test_submitting_problems.py | 2 +- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/common/lib/capa/capa/xqueue_interface.py b/common/lib/capa/capa/xqueue_interface.py index aa327dc285..fe47e9b597 100644 --- a/common/lib/capa/capa/xqueue_interface.py +++ b/common/lib/capa/capa/xqueue_interface.py @@ -15,6 +15,8 @@ XQUEUE_METRIC_NAME = 'edxapp.xqueue' # Wait time for response from Xqueue. XQUEUE_TIMEOUT = 35 # seconds +CONNECT_TIMEOUT = 3.05 # seconds +READ_TIMEOUT = 10 # seconds def make_hashkey(seed): @@ -134,12 +136,18 @@ class XQueueInterface(object): def _http_post(self, url, data, files=None): try: - r = self.session.post(url, data=data, files=files) + response = self.session.post( + url, data=data, files=files, timeout=(CONNECT_TIMEOUT, READ_TIMEOUT) + ) except requests.exceptions.ConnectionError, err: log.error(err) return (1, 'cannot connect to server') - if r.status_code not in [200]: - return (1, 'unexpected HTTP status code [%d]' % r.status_code) + except requests.exceptions.ReadTimeout, err: + log.error(err) + return (1, 'failed to read from the server') - return parse_xreply(r.text) + if response.status_code not in [200]: + return (1, 'unexpected HTTP status code [%d]' % response.status_code) + + return parse_xreply(response.text) diff --git a/common/lib/xmodule/xmodule/tests/test_capa_module.py b/common/lib/xmodule/xmodule/tests/test_capa_module.py index e7653ef81c..3af41a46fc 100644 --- a/common/lib/xmodule/xmodule/tests/test_capa_module.py +++ b/common/lib/xmodule/xmodule/tests/test_capa_module.py @@ -8,6 +8,7 @@ Tests of the Capa XModule import datetime import json import random +import requests import os import textwrap import unittest @@ -242,6 +243,22 @@ class CapaModuleTest(unittest.TestCase): problem = CapaFactory.create() self.assertFalse(problem.answer_available()) + @ddt.data( + (requests.exceptions.ReadTimeout, (1, 'failed to read from the server')), + (requests.exceptions.ConnectionError, (1, 'cannot connect to server')), + ) + @ddt.unpack + def test_xqueue_request_exception(self, exception, result): + """ + Makes sure that platform will raise appropriate exception in case of + connect/read timeout(s) to request to xqueue + """ + xqueue_interface = XQueueInterface("http://example.com/xqueue", Mock()) + with patch.object(xqueue_interface.session, 'post', side_effect=exception): + # pylint: disable = protected-access + response = xqueue_interface._http_post('http://some/fake/url', {}) + self.assertEqual(response, result) + def test_showanswer_attempted(self): problem = CapaFactory.create(showanswer='attempted') self.assertFalse(problem.answer_available()) diff --git a/lms/djangoapps/courseware/tests/test_submitting_problems.py b/lms/djangoapps/courseware/tests/test_submitting_problems.py index 9c7ffc3a6b..c0e2602ed8 100644 --- a/lms/djangoapps/courseware/tests/test_submitting_problems.py +++ b/lms/djangoapps/courseware/tests/test_submitting_problems.py @@ -818,7 +818,7 @@ class ProblemWithUploadedFilesTest(TestSubmittingProblems): self.assertEqual(name, "post") self.assertEqual(len(args), 1) self.assertTrue(args[0].endswith("/submit/")) - self.assertItemsEqual(kwargs.keys(), ["files", "data"]) + self.assertItemsEqual(kwargs.keys(), ["files", "data", "timeout"]) self.assertItemsEqual(kwargs['files'].keys(), filenames.split())