Skip to content

Commit

Permalink
Adding test to try to repro the timeout+lock issue
Browse files Browse the repository at this point in the history
  • Loading branch information
andresriancho committed Jan 5, 2015
1 parent b0b544e commit 4662304
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 21 deletions.
2 changes: 0 additions & 2 deletions w3af/core/data/parsers/parser_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@ def __init__(self):
self._total = 0.0

def get_document_parser_for(self, http_response):
res = None

# Before I used md5, but I realized that it was unnecessary. I
# experimented a little bit with python's hash functions and this is
# what I got:
Expand Down
38 changes: 19 additions & 19 deletions w3af/core/data/parsers/tests/test_document_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,24 +118,6 @@ def test_parser_timeout(self):
Test to verify fix for https://github.com/andresriancho/w3af/issues/6723
"w3af running long time more than 24h"
"""
class DelayedParser(object):
def __init__(self, http_response):
"""
According to the stopit docs it can't kill a thread running an
atomic python function such as time.sleep() , so I have to
create a function like this. I don't mind, since it's realistic
with what we do in w3af anyways.
"""
total_delay = 3.0

for _ in xrange(100):
time.sleep(total_delay/100)

@staticmethod
def can_parse(*args):
return True


mod = 'w3af.core.data.parsers.document_parser.%s'

with patch(mod % 'om.out') as om_mock,\
Expand All @@ -160,4 +142,22 @@ def can_parse(*args):

self.assertIn(call.debug(error), om_mock.mock_calls)
else:
self.assertTrue(False)
self.assertTrue(False)


class DelayedParser(object):
def __init__(self, http_response):
"""
According to the stopit docs it can't kill a thread running an
atomic python function such as time.sleep() , so I have to
create a function like this. I don't mind, since it's realistic
with what we do in w3af anyways.
"""
total_delay = 3.0

for _ in xrange(100):
time.sleep(total_delay/100)

@staticmethod
def can_parse(*args):
return True
38 changes: 38 additions & 0 deletions w3af/core/data/parsers/tests/test_parser_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,16 @@
"""
import unittest

from mock import patch, call, PropertyMock

from w3af.core.data.parsers.document_parser import DocumentParser
from w3af.core.controllers.exceptions import BaseFrameworkException
from w3af.core.data.parsers.parser_cache import ParserCache
from w3af.core.data.parsers.url import URL
from w3af.core.data.url.HTTPResponse import HTTPResponse
from w3af.core.data.dc.headers import Headers
from w3af.core.data.parsers.tests.test_document_parser import (DelayedParser,
_build_http_response)


class TestParserCache(unittest.TestCase):
Expand Down Expand Up @@ -65,3 +71,35 @@ def test_issue_188_invalid_url(self):
all_chars = ''.join([chr(i) for i in xrange(0,255)])
response = HTTPResponse(200, all_chars, self.headers, self.url, self.url)
parser = self.dpc.get_document_parser_for(response)

def test_parser_timeout_releases_lock(self):
"""
Test to verify fix for https://github.com/andresriancho/w3af/issues/6723
"w3af running long time more than 24h"
"""
mod = 'w3af.core.data.parsers.document_parser.%s'

with patch(mod % 'om.out') as om_mock,\
patch(mod % 'DocumentParser.PARSER_TIMEOUT', new_callable=PropertyMock) as timeout_mock,\
patch(mod % 'DocumentParser.PARSERS', new_callable=PropertyMock) as parsers_mock:

timeout_mock.return_value = 1
parsers_mock.return_value = [DelayedParser]

html = '<html>foo!</html>'
http_resp = _build_http_response(html, u'text/html')

try:
self.dpc.get_document_parser_for(http_resp)
except BaseFrameworkException:
msg = '[timeout] The "%s" parser took more than %s seconds'\
' to complete parsing of "%s", killing it!'

error = msg % ('DelayedParser',
DocumentParser.PARSER_TIMEOUT,
http_resp.get_url())

self.assertIn(call.debug(error), om_mock.mock_calls)
self.assertEqual(self.dpc._LRULock._RLock__count, 0)
else:
self.assertTrue(False)

0 comments on commit 4662304

Please sign in to comment.