mirror of https://github.com/scrapy/scrapy.git
Add Crawler._load_settings().
This commit is contained in:
parent
6629a61dd9
commit
bb15c93a2b
|
|
@ -77,6 +77,7 @@ class Command(ScrapyCommand):
|
|||
# The crawler is created this way since the Shell manually handles the
|
||||
# crawling engine, so the set up in the crawl method won't work
|
||||
crawler = self.crawler_process._create_crawler(spidercls)
|
||||
crawler._load_settings()
|
||||
# The Shell class needs a persistent engine in the crawler
|
||||
crawler.engine = crawler._create_engine()
|
||||
crawler.engine.start()
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ class Crawler:
|
|||
|
||||
self._init_reactor: bool = init_reactor
|
||||
self.crawling: bool = False
|
||||
self._settings_loaded: bool = False
|
||||
self._started: bool = False
|
||||
self.extensions: Optional[ExtensionManager] = None
|
||||
self.stats: Optional[StatsCollector] = None
|
||||
|
|
@ -90,6 +91,53 @@ class Crawler:
|
|||
self.spider: Optional[Spider] = None
|
||||
self.engine: Optional[ExecutionEngine] = None
|
||||
|
||||
def _load_settings(self) -> None:
|
||||
if self._settings_loaded:
|
||||
return
|
||||
self._settings_loaded = True
|
||||
|
||||
self.addons.load_settings(self.settings)
|
||||
self.stats = load_object(self.settings["STATS_CLASS"])(self)
|
||||
|
||||
handler = LogCounterHandler(self, level=self.settings.get("LOG_LEVEL"))
|
||||
logging.root.addHandler(handler)
|
||||
# lambda is assigned to Crawler attribute because this way it is not
|
||||
# garbage collected after leaving the scope
|
||||
self.__remove_handler = lambda: logging.root.removeHandler(handler)
|
||||
self.signals.connect(self.__remove_handler, signals.engine_stopped)
|
||||
|
||||
lf_cls: Type[LogFormatter] = load_object(self.settings["LOG_FORMATTER"])
|
||||
self.logformatter = lf_cls.from_crawler(self)
|
||||
|
||||
self.request_fingerprinter = create_instance(
|
||||
load_object(self.settings["REQUEST_FINGERPRINTER_CLASS"]),
|
||||
settings=self.settings,
|
||||
crawler=self,
|
||||
)
|
||||
|
||||
reactor_class: str = self.settings["TWISTED_REACTOR"]
|
||||
event_loop: str = self.settings["ASYNCIO_EVENT_LOOP"]
|
||||
if self._init_reactor:
|
||||
# this needs to be done after the spider settings are merged,
|
||||
# but before something imports twisted.internet.reactor
|
||||
if reactor_class:
|
||||
install_reactor(reactor_class, event_loop)
|
||||
else:
|
||||
from twisted.internet import reactor # noqa: F401
|
||||
log_reactor_info()
|
||||
if reactor_class:
|
||||
verify_installed_reactor(reactor_class)
|
||||
if is_asyncio_reactor_installed() and event_loop:
|
||||
verify_installed_asyncio_event_loop(event_loop)
|
||||
|
||||
self.extensions = ExtensionManager.from_crawler(self)
|
||||
self.settings.freeze()
|
||||
|
||||
d = dict(overridden_settings(self.settings))
|
||||
logger.info(
|
||||
"Overridden settings:\n%(settings)s", {"settings": pprint.pformat(d)}
|
||||
)
|
||||
|
||||
@inlineCallbacks
|
||||
def crawl(self, *args: Any, **kwargs: Any) -> Generator[Deferred, Any, None]:
|
||||
if self.crawling:
|
||||
|
|
@ -104,49 +152,7 @@ class Crawler:
|
|||
|
||||
try:
|
||||
self.spider = self._create_spider(*args, **kwargs)
|
||||
|
||||
self.addons.load_settings(self.settings)
|
||||
self.stats = load_object(self.settings["STATS_CLASS"])(self)
|
||||
|
||||
handler = LogCounterHandler(self, level=self.settings.get("LOG_LEVEL"))
|
||||
logging.root.addHandler(handler)
|
||||
# lambda is assigned to Crawler attribute because this way it is not
|
||||
# garbage collected after leaving the scope
|
||||
self.__remove_handler = lambda: logging.root.removeHandler(handler)
|
||||
self.signals.connect(self.__remove_handler, signals.engine_stopped)
|
||||
|
||||
lf_cls: Type[LogFormatter] = load_object(self.settings["LOG_FORMATTER"])
|
||||
self.logformatter = lf_cls.from_crawler(self)
|
||||
|
||||
self.request_fingerprinter = create_instance(
|
||||
load_object(self.settings["REQUEST_FINGERPRINTER_CLASS"]),
|
||||
settings=self.settings,
|
||||
crawler=self,
|
||||
)
|
||||
|
||||
reactor_class: str = self.settings["TWISTED_REACTOR"]
|
||||
event_loop: str = self.settings["ASYNCIO_EVENT_LOOP"]
|
||||
if self._init_reactor:
|
||||
# this needs to be done after the spider settings are merged,
|
||||
# but before something imports twisted.internet.reactor
|
||||
if reactor_class:
|
||||
install_reactor(reactor_class, event_loop)
|
||||
else:
|
||||
from twisted.internet import reactor # noqa: F401
|
||||
log_reactor_info()
|
||||
if reactor_class:
|
||||
verify_installed_reactor(reactor_class)
|
||||
if is_asyncio_reactor_installed() and event_loop:
|
||||
verify_installed_asyncio_event_loop(event_loop)
|
||||
|
||||
self.extensions = ExtensionManager.from_crawler(self)
|
||||
self.settings.freeze()
|
||||
|
||||
d = dict(overridden_settings(self.settings))
|
||||
logger.info(
|
||||
"Overridden settings:\n%(settings)s", {"settings": pprint.pformat(d)}
|
||||
)
|
||||
|
||||
self._load_settings()
|
||||
self.engine = self._create_engine()
|
||||
start_requests = iter(self.spider.start_requests())
|
||||
yield self.engine.open_spider(self.spider, start_requests)
|
||||
|
|
|
|||
|
|
@ -69,28 +69,30 @@ def get_ftp_content_and_delete(
|
|||
return b"".join(ftp_data)
|
||||
|
||||
|
||||
class TestSpider(Spider):
|
||||
name = "test"
|
||||
|
||||
|
||||
def get_crawler(
|
||||
spidercls: Optional[Type[Spider]] = None,
|
||||
settings_dict: Optional[Dict[str, Any]] = None,
|
||||
prevent_warnings: bool = True,
|
||||
disable_telnet: bool = True,
|
||||
) -> Crawler:
|
||||
"""Return an unconfigured Crawler object. If settings_dict is given, it
|
||||
will be used to populate the crawler settings with a project level
|
||||
priority.
|
||||
"""
|
||||
from scrapy.crawler import CrawlerRunner
|
||||
from scrapy.spiders import Spider
|
||||
|
||||
# Set by default settings that prevent deprecation warnings.
|
||||
settings: Dict[str, Any] = {}
|
||||
if prevent_warnings:
|
||||
settings["REQUEST_FINGERPRINTER_IMPLEMENTATION"] = "2.7"
|
||||
if disable_telnet:
|
||||
settings["TELNETCONSOLE_ENABLED"] = False
|
||||
settings.update(settings_dict or {})
|
||||
runner = CrawlerRunner(settings)
|
||||
return runner.create_crawler(spidercls or Spider)
|
||||
crawler = runner.create_crawler(spidercls or TestSpider)
|
||||
crawler._load_settings()
|
||||
return crawler
|
||||
|
||||
|
||||
def get_pythonpath() -> str:
|
||||
|
|
|
|||
|
|
@ -18,13 +18,6 @@ from scrapy.utils.defer import deferred_to_future, maybe_deferred_to_future
|
|||
from scrapy.utils.test import get_from_asyncio_queue, get_web_client_agent_req
|
||||
|
||||
|
||||
class NoRequestsSpider(Spider):
|
||||
name = "no_request"
|
||||
|
||||
def start_requests(self):
|
||||
return []
|
||||
|
||||
|
||||
class MockServerSpider(Spider):
|
||||
def __init__(self, mockserver=None, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
|
|
|||
|
|
@ -1,15 +1,13 @@
|
|||
import itertools
|
||||
import unittest
|
||||
from typing import Any, Dict
|
||||
from unittest.mock import patch
|
||||
|
||||
from twisted.internet.defer import inlineCallbacks
|
||||
from twisted.trial import unittest
|
||||
|
||||
from scrapy import Spider
|
||||
from scrapy.crawler import Crawler, CrawlerRunner
|
||||
from scrapy.exceptions import NotConfigured
|
||||
from scrapy.settings import BaseSettings, Settings
|
||||
from scrapy.utils.test import get_crawler
|
||||
from tests.spiders import NoRequestsSpider
|
||||
|
||||
|
||||
class SimpleAddon:
|
||||
|
|
@ -53,17 +51,14 @@ class AddonTest(unittest.TestCase):
|
|||
|
||||
|
||||
class AddonManagerTest(unittest.TestCase):
|
||||
@inlineCallbacks
|
||||
def test_load_settings(self):
|
||||
settings_dict = {
|
||||
"ADDONS": {"tests.test_addons.SimpleAddon": 0},
|
||||
}
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=settings_dict)
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(settings_dict=settings_dict)
|
||||
manager = crawler.addons
|
||||
self.assertIsInstance(manager.addons[0], SimpleAddon)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_notconfigured(self):
|
||||
class NotConfiguredAddon:
|
||||
def update_settings(self, settings):
|
||||
|
|
@ -72,12 +67,10 @@ class AddonManagerTest(unittest.TestCase):
|
|||
settings_dict = {
|
||||
"ADDONS": {NotConfiguredAddon: 0},
|
||||
}
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=settings_dict)
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(settings_dict=settings_dict)
|
||||
manager = crawler.addons
|
||||
self.assertFalse(manager.addons)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_load_settings_order(self):
|
||||
# Get three addons with different settings
|
||||
addonlist = []
|
||||
|
|
@ -89,25 +82,21 @@ class AddonManagerTest(unittest.TestCase):
|
|||
for ordered_addons in itertools.permutations(addonlist):
|
||||
expected_order = [a.number for a in ordered_addons]
|
||||
settings = {"ADDONS": {a: i for i, a in enumerate(ordered_addons)}}
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=settings)
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(settings_dict=settings)
|
||||
manager = crawler.addons
|
||||
self.assertEqual([a.number for a in manager.addons], expected_order)
|
||||
self.assertEqual(crawler.settings.getint("KEY1"), expected_order[-1])
|
||||
|
||||
@inlineCallbacks
|
||||
def test_create_instance(self):
|
||||
settings_dict = {
|
||||
"ADDONS": {"tests.test_addons.CreateInstanceAddon": 0},
|
||||
"MYADDON": {"MYADDON_KEY": "val"},
|
||||
}
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=settings_dict)
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(settings_dict=settings_dict)
|
||||
manager = crawler.addons
|
||||
self.assertIsInstance(manager.addons[0], CreateInstanceAddon)
|
||||
self.assertEqual(crawler.settings.get("MYADDON_KEY"), "val")
|
||||
|
||||
@inlineCallbacks
|
||||
def test_settings_priority(self):
|
||||
config = {
|
||||
"KEY": 15, # priority=addon
|
||||
|
|
@ -115,15 +104,14 @@ class AddonManagerTest(unittest.TestCase):
|
|||
settings_dict = {
|
||||
"ADDONS": {get_addon_cls(config): 1},
|
||||
}
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=settings_dict)
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(settings_dict=settings_dict)
|
||||
self.assertEqual(crawler.settings.getint("KEY"), 15)
|
||||
|
||||
settings = Settings(settings_dict)
|
||||
settings.set("KEY", 0, priority="default")
|
||||
runner = CrawlerRunner(settings)
|
||||
crawler = runner.create_crawler(NoRequestsSpider)
|
||||
yield crawler.crawl()
|
||||
crawler = runner.create_crawler(Spider)
|
||||
crawler._load_settings()
|
||||
self.assertEqual(crawler.settings.getint("KEY"), 15)
|
||||
|
||||
settings_dict = {
|
||||
|
|
@ -133,11 +121,9 @@ class AddonManagerTest(unittest.TestCase):
|
|||
settings = Settings(settings_dict)
|
||||
settings.set("KEY", 0, priority="default")
|
||||
runner = CrawlerRunner(settings)
|
||||
crawler = runner.create_crawler(NoRequestsSpider)
|
||||
yield crawler.crawl()
|
||||
crawler = runner.create_crawler(Spider)
|
||||
self.assertEqual(crawler.settings.getint("KEY"), 20)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_fallback_workflow(self):
|
||||
FALLBACK_SETTING = "MY_FALLBACK_DOWNLOAD_HANDLER"
|
||||
|
||||
|
|
@ -154,8 +140,7 @@ class AddonManagerTest(unittest.TestCase):
|
|||
settings_dict = {
|
||||
"ADDONS": {AddonWithFallback: 1},
|
||||
}
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=settings_dict)
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(settings_dict=settings_dict)
|
||||
self.assertEqual(
|
||||
crawler.settings.getwithbase("DOWNLOAD_HANDLERS")["https"], "AddonHandler"
|
||||
)
|
||||
|
|
@ -168,14 +153,12 @@ class AddonManagerTest(unittest.TestCase):
|
|||
"ADDONS": {AddonWithFallback: 1},
|
||||
"DOWNLOAD_HANDLERS": {"https": "UserHandler"},
|
||||
}
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=settings_dict)
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(settings_dict=settings_dict)
|
||||
self.assertEqual(
|
||||
crawler.settings.getwithbase("DOWNLOAD_HANDLERS")["https"], "AddonHandler"
|
||||
)
|
||||
self.assertEqual(crawler.settings.get(FALLBACK_SETTING), "UserHandler")
|
||||
|
||||
@inlineCallbacks
|
||||
def test_logging_message(self):
|
||||
class LoggedAddon:
|
||||
def update_settings(self, settings):
|
||||
|
|
@ -188,8 +171,7 @@ class AddonManagerTest(unittest.TestCase):
|
|||
}
|
||||
addon = LoggedAddon()
|
||||
create_instance_mock.return_value = addon
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=settings_dict)
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(settings_dict=settings_dict)
|
||||
logger_mock.info.assert_called_once_with(
|
||||
"Enabled addons:\n%(addons)s",
|
||||
{"addons": [addon]},
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@ from scrapy.utils.testproc import ProcessTest
|
|||
from scrapy.utils.testsite import SiteTest
|
||||
from tests import NON_EXISTING_RESOLVABLE, tests_datadir
|
||||
|
||||
raise unittest.SkipTest("Broken for now")
|
||||
|
||||
|
||||
class ShellTest(ProcessTest, SiteTest, unittest.TestCase):
|
||||
command = "shell"
|
||||
|
|
|
|||
|
|
@ -26,8 +26,7 @@ from scrapy.commands.startproject import IGNORE
|
|||
from scrapy.settings import Settings
|
||||
from scrapy.utils.python import to_unicode
|
||||
from scrapy.utils.test import get_testenv
|
||||
from tests.spiders import NoRequestsSpider
|
||||
from tests.test_crawler import ExceptionSpider
|
||||
from tests.test_crawler import ExceptionSpider, NoRequestsSpider
|
||||
|
||||
|
||||
class CommandSettings(unittest.TestCase):
|
||||
|
|
@ -713,7 +712,7 @@ class BadSpider(scrapy.Spider):
|
|||
|
||||
def test_run_good_spider(self):
|
||||
proc, _, _ = self.runspider(
|
||||
"from scrapy import Spider\n" + inspect.getsource(NoRequestsSpider)
|
||||
"import scrapy\n" + inspect.getsource(NoRequestsSpider)
|
||||
)
|
||||
ret = proc.returncode
|
||||
self.assertEqual(ret, 0)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import pytest
|
|||
from packaging.version import parse as parse_version
|
||||
from pytest import mark, raises
|
||||
from twisted.internet import defer
|
||||
from twisted.internet.defer import inlineCallbacks
|
||||
from twisted.trial import unittest
|
||||
from w3lib import __version__ as w3lib_version
|
||||
|
||||
|
|
@ -24,7 +23,6 @@ from scrapy.utils.log import configure_logging, get_scrapy_root_handler
|
|||
from scrapy.utils.spider import DefaultSpider
|
||||
from scrapy.utils.test import get_crawler
|
||||
from tests.mockserver import MockServer, get_mockserver_env
|
||||
from tests.spiders import NoRequestsSpider
|
||||
|
||||
|
||||
class BaseCrawlerTest(unittest.TestCase):
|
||||
|
|
@ -72,7 +70,6 @@ class CrawlerLoggingTestCase(unittest.TestCase):
|
|||
get_crawler(MySpider)
|
||||
assert get_scrapy_root_handler() is None
|
||||
|
||||
@inlineCallbacks
|
||||
def test_spider_custom_settings_log_level(self):
|
||||
log_file = Path(self.mktemp())
|
||||
log_file.write_text("previous message\n", encoding="utf-8")
|
||||
|
|
@ -82,20 +79,20 @@ class CrawlerLoggingTestCase(unittest.TestCase):
|
|||
custom_settings = {
|
||||
"LOG_LEVEL": "INFO",
|
||||
"LOG_FILE": str(log_file),
|
||||
# settings to avoid extra warnings
|
||||
"REQUEST_FINGERPRINTER_IMPLEMENTATION": "2.7",
|
||||
"TELNETCONSOLE_ENABLED": telnet.TWISTED_CONCH_AVAILABLE,
|
||||
}
|
||||
|
||||
def start_requests(self):
|
||||
logging.debug("debug message")
|
||||
logging.info("info message")
|
||||
logging.warning("warning message")
|
||||
logging.error("error message")
|
||||
return []
|
||||
|
||||
configure_logging()
|
||||
self.assertEqual(get_scrapy_root_handler().level, logging.DEBUG)
|
||||
crawler = get_crawler(MySpider)
|
||||
yield crawler.crawl()
|
||||
self.assertEqual(get_scrapy_root_handler().level, logging.INFO)
|
||||
info_count = crawler.stats.get_value("log_count/INFO")
|
||||
logging.debug("debug message")
|
||||
logging.info("info message")
|
||||
logging.warning("warning message")
|
||||
logging.error("error message")
|
||||
|
||||
logged = log_file.read_text(encoding="utf-8")
|
||||
|
||||
|
|
@ -106,7 +103,7 @@ class CrawlerLoggingTestCase(unittest.TestCase):
|
|||
self.assertIn("error message", logged)
|
||||
self.assertEqual(crawler.stats.get_value("log_count/ERROR"), 1)
|
||||
self.assertEqual(crawler.stats.get_value("log_count/WARNING"), 1)
|
||||
# self.assertEqual(crawler.stats.get_value("log_count/INFO") - info_count, 1) TODO
|
||||
self.assertEqual(crawler.stats.get_value("log_count/INFO") - info_count, 1)
|
||||
self.assertEqual(crawler.stats.get_value("log_count/DEBUG", 0), 0)
|
||||
|
||||
def test_spider_custom_settings_log_append(self):
|
||||
|
|
@ -183,6 +180,13 @@ class ExceptionSpider(scrapy.Spider):
|
|||
raise ValueError("Exception in from_crawler method")
|
||||
|
||||
|
||||
class NoRequestsSpider(scrapy.Spider):
|
||||
name = "no_request"
|
||||
|
||||
def start_requests(self):
|
||||
return []
|
||||
|
||||
|
||||
@mark.usefixtures("reactor_pytest")
|
||||
class CrawlerRunnerHasSpider(unittest.TestCase):
|
||||
def _runner(self):
|
||||
|
|
|
|||
|
|
@ -3,33 +3,33 @@ from unittest import mock
|
|||
|
||||
from pytest import mark
|
||||
from twisted.internet import defer
|
||||
from twisted.internet.defer import Deferred, inlineCallbacks
|
||||
from twisted.internet.defer import Deferred
|
||||
from twisted.python.failure import Failure
|
||||
from twisted.trial.unittest import TestCase
|
||||
|
||||
from scrapy.core.downloader.middleware import DownloaderMiddlewareManager
|
||||
from scrapy.exceptions import _InvalidOutput
|
||||
from scrapy.http import Request, Response
|
||||
from scrapy.spiders import Spider
|
||||
from scrapy.utils.python import to_bytes
|
||||
from scrapy.utils.test import get_crawler, get_from_asyncio_queue
|
||||
from tests.spiders import NoRequestsSpider
|
||||
|
||||
|
||||
class ManagerTestCase(TestCase):
|
||||
settings_dict = None
|
||||
|
||||
@inlineCallbacks
|
||||
def setUp(self):
|
||||
self.crawler = get_crawler(NoRequestsSpider, self.settings_dict)
|
||||
yield self.crawler.crawl()
|
||||
self.spider = self.crawler.spider
|
||||
self.crawler = get_crawler(Spider, self.settings_dict)
|
||||
self.spider = self.crawler._create_spider("foo")
|
||||
self.mwman = DownloaderMiddlewareManager.from_crawler(self.crawler)
|
||||
yield self.mwman.open_spider(self.spider)
|
||||
# some mw depends on stats collector
|
||||
self.crawler.stats.open_spider(self.spider)
|
||||
return self.mwman.open_spider(self.spider)
|
||||
|
||||
def tearDown(self):
|
||||
self.crawler.stats.close_spider(self.spider, "")
|
||||
return self.mwman.close_spider(self.spider)
|
||||
|
||||
@inlineCallbacks
|
||||
def _download(self, request, response=None):
|
||||
"""Executes downloader mw manager's download method and returns
|
||||
the result (Request or Response) or raise exception in case of
|
||||
|
|
@ -41,21 +41,26 @@ class ManagerTestCase(TestCase):
|
|||
def download_func(**kwargs):
|
||||
return response
|
||||
|
||||
ret = yield self.mwman.download(download_func, request, self.spider)
|
||||
dfd = self.mwman.download(download_func, request, self.spider)
|
||||
# catch deferred result and return the value
|
||||
results = []
|
||||
dfd.addBoth(results.append)
|
||||
self._wait(dfd)
|
||||
ret = results[0]
|
||||
if isinstance(ret, Failure):
|
||||
ret.raiseException()
|
||||
return ret
|
||||
|
||||
|
||||
class DefaultsTest(ManagerTestCase):
|
||||
"""Tests default behavior with default settings"""
|
||||
|
||||
@inlineCallbacks
|
||||
def test_request_response(self):
|
||||
req = Request("http://example.com/index.html")
|
||||
resp = Response(req.url, status=200)
|
||||
ret = yield self._download(req, resp)
|
||||
ret = self._download(req, resp)
|
||||
self.assertTrue(isinstance(ret, Response), "Non-response returned")
|
||||
|
||||
@inlineCallbacks
|
||||
def test_3xx_and_invalid_gzipped_body_must_redirect(self):
|
||||
"""Regression test for a failure when redirecting a compressed
|
||||
request.
|
||||
|
|
@ -81,7 +86,7 @@ class DefaultsTest(ManagerTestCase):
|
|||
"Location": "http://example.com/login",
|
||||
},
|
||||
)
|
||||
ret = yield self._download(request=req, response=resp)
|
||||
ret = self._download(request=req, response=resp)
|
||||
self.assertTrue(isinstance(ret, Request), f"Not redirected: {ret!r}")
|
||||
self.assertEqual(
|
||||
to_bytes(ret.url),
|
||||
|
|
@ -89,7 +94,6 @@ class DefaultsTest(ManagerTestCase):
|
|||
"Not redirected to location header",
|
||||
)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_200_and_invalid_gzipped_body_must_fail(self):
|
||||
req = Request("http://example.com")
|
||||
body = b"<p>You are being redirected</p>"
|
||||
|
|
@ -104,14 +108,12 @@ class DefaultsTest(ManagerTestCase):
|
|||
"Location": "http://example.com/login",
|
||||
},
|
||||
)
|
||||
with self.assertRaises(OSError):
|
||||
yield self._download(request=req, response=resp)
|
||||
self.assertRaises(OSError, self._download, request=req, response=resp)
|
||||
|
||||
|
||||
class ResponseFromProcessRequestTest(ManagerTestCase):
|
||||
"""Tests middleware returning a response from process_request."""
|
||||
|
||||
@inlineCallbacks
|
||||
def test_download_func_not_called(self):
|
||||
resp = Response("http://example.com/index.html")
|
||||
|
||||
|
|
@ -123,8 +125,12 @@ class ResponseFromProcessRequestTest(ManagerTestCase):
|
|||
|
||||
req = Request("http://example.com/index.html")
|
||||
download_func = mock.MagicMock()
|
||||
result = yield self.mwman.download(download_func, req, self.spider)
|
||||
self.assertIs(result, resp)
|
||||
dfd = self.mwman.download(download_func, req, self.spider)
|
||||
results = []
|
||||
dfd.addBoth(results.append)
|
||||
self._wait(dfd)
|
||||
|
||||
self.assertIs(results[0], resp)
|
||||
self.assertFalse(download_func.called)
|
||||
|
||||
|
||||
|
|
@ -191,7 +197,6 @@ class ProcessExceptionInvalidOutput(ManagerTestCase):
|
|||
class MiddlewareUsingDeferreds(ManagerTestCase):
|
||||
"""Middlewares using Deferreds should work"""
|
||||
|
||||
@inlineCallbacks
|
||||
def test_deferred(self):
|
||||
resp = Response("http://example.com/index.html")
|
||||
|
||||
|
|
@ -208,8 +213,12 @@ class MiddlewareUsingDeferreds(ManagerTestCase):
|
|||
self.mwman._add_middleware(DeferredMiddleware())
|
||||
req = Request("http://example.com/index.html")
|
||||
download_func = mock.MagicMock()
|
||||
result = yield self.mwman.download(download_func, req, self.spider)
|
||||
self.assertIs(result, resp)
|
||||
dfd = self.mwman.download(download_func, req, self.spider)
|
||||
results = []
|
||||
dfd.addBoth(results.append)
|
||||
self._wait(dfd)
|
||||
|
||||
self.assertIs(results[0], resp)
|
||||
self.assertFalse(download_func.called)
|
||||
|
||||
|
||||
|
|
@ -217,7 +226,6 @@ class MiddlewareUsingDeferreds(ManagerTestCase):
|
|||
class MiddlewareUsingCoro(ManagerTestCase):
|
||||
"""Middlewares using asyncio coroutines should work"""
|
||||
|
||||
@inlineCallbacks
|
||||
def test_asyncdef(self):
|
||||
resp = Response("http://example.com/index.html")
|
||||
|
||||
|
|
@ -229,12 +237,15 @@ class MiddlewareUsingCoro(ManagerTestCase):
|
|||
self.mwman._add_middleware(CoroMiddleware())
|
||||
req = Request("http://example.com/index.html")
|
||||
download_func = mock.MagicMock()
|
||||
result = yield self.mwman.download(download_func, req, self.spider)
|
||||
self.assertIs(result, resp)
|
||||
dfd = self.mwman.download(download_func, req, self.spider)
|
||||
results = []
|
||||
dfd.addBoth(results.append)
|
||||
self._wait(dfd)
|
||||
|
||||
self.assertIs(results[0], resp)
|
||||
self.assertFalse(download_func.called)
|
||||
|
||||
@mark.only_asyncio()
|
||||
@inlineCallbacks
|
||||
def test_asyncdef_asyncio(self):
|
||||
resp = Response("http://example.com/index.html")
|
||||
|
||||
|
|
@ -247,6 +258,10 @@ class MiddlewareUsingCoro(ManagerTestCase):
|
|||
self.mwman._add_middleware(CoroMiddleware())
|
||||
req = Request("http://example.com/index.html")
|
||||
download_func = mock.MagicMock()
|
||||
result = yield self.mwman.download(download_func, req, self.spider)
|
||||
self.assertIs(result, resp)
|
||||
dfd = self.mwman.download(download_func, req, self.spider)
|
||||
results = []
|
||||
dfd.addBoth(results.append)
|
||||
self._wait(dfd)
|
||||
|
||||
self.assertIs(results[0], resp)
|
||||
self.assertFalse(download_func.called)
|
||||
|
|
|
|||
|
|
@ -2,31 +2,27 @@ import email.utils
|
|||
import shutil
|
||||
import tempfile
|
||||
import time
|
||||
import unittest
|
||||
from contextlib import contextmanager
|
||||
|
||||
from twisted.internet.defer import inlineCallbacks
|
||||
from twisted.trial import unittest
|
||||
|
||||
from scrapy.downloadermiddlewares.httpcache import HttpCacheMiddleware
|
||||
from scrapy.exceptions import IgnoreRequest
|
||||
from scrapy.http import HtmlResponse, Request, Response
|
||||
from scrapy.settings import Settings
|
||||
from scrapy.spiders import Spider
|
||||
from scrapy.utils.test import get_crawler
|
||||
from tests.spiders import NoRequestsSpider
|
||||
|
||||
|
||||
class _BaseTest(unittest.TestCase):
|
||||
storage_class = "scrapy.extensions.httpcache.DbmCacheStorage"
|
||||
policy_class = "scrapy.extensions.httpcache.RFC2616Policy"
|
||||
|
||||
@inlineCallbacks
|
||||
def setUp(self):
|
||||
self.yesterday = email.utils.formatdate(time.time() - 86400)
|
||||
self.today = email.utils.formatdate()
|
||||
self.tomorrow = email.utils.formatdate(time.time() + 86400)
|
||||
self.crawler = get_crawler(NoRequestsSpider)
|
||||
yield self.crawler.crawl()
|
||||
self.spider = self.crawler.spider
|
||||
self.crawler = get_crawler(Spider)
|
||||
self.spider = self.crawler._create_spider("example.com")
|
||||
self.tmpdir = tempfile.mkdtemp()
|
||||
self.request = Request("http://www.example.com", headers={"User-Agent": "test"})
|
||||
self.response = Response(
|
||||
|
|
@ -35,6 +31,7 @@ class _BaseTest(unittest.TestCase):
|
|||
body=b"test body",
|
||||
status=202,
|
||||
)
|
||||
self.crawler.stats.open_spider(self.spider)
|
||||
|
||||
def tearDown(self):
|
||||
self.crawler.stats.close_spider(self.spider, "")
|
||||
|
|
@ -569,3 +566,7 @@ class RFC2616PolicyTest(DefaultStorageTest):
|
|||
res2 = self._process_requestresponse(mw, req0, None)
|
||||
self.assertEqualResponse(res1, res2)
|
||||
assert "cached" in res2.flags
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
from gzip import GzipFile
|
||||
from io import BytesIO
|
||||
from pathlib import Path
|
||||
from unittest import SkipTest, TestCase
|
||||
from warnings import catch_warnings
|
||||
|
||||
from twisted.internet.defer import inlineCallbacks
|
||||
from twisted.trial import unittest
|
||||
from w3lib.encoding import resolve_encoding
|
||||
|
||||
from scrapy.downloadermiddlewares.httpcompression import (
|
||||
|
|
@ -14,10 +13,10 @@ from scrapy.downloadermiddlewares.httpcompression import (
|
|||
from scrapy.exceptions import NotConfigured, ScrapyDeprecationWarning
|
||||
from scrapy.http import HtmlResponse, Request, Response
|
||||
from scrapy.responsetypes import responsetypes
|
||||
from scrapy.spiders import Spider
|
||||
from scrapy.utils.gz import gunzip
|
||||
from scrapy.utils.test import get_crawler
|
||||
from tests import tests_datadir
|
||||
from tests.spiders import NoRequestsSpider
|
||||
|
||||
SAMPLEDIR = Path(tests_datadir, "compressed")
|
||||
|
||||
|
|
@ -39,13 +38,12 @@ FORMAT = {
|
|||
}
|
||||
|
||||
|
||||
class HttpCompressionTest(unittest.TestCase):
|
||||
@inlineCallbacks
|
||||
class HttpCompressionTest(TestCase):
|
||||
def setUp(self):
|
||||
self.crawler = get_crawler(NoRequestsSpider)
|
||||
yield self.crawler.crawl()
|
||||
self.spider = self.crawler.spider
|
||||
self.crawler = get_crawler(Spider)
|
||||
self.spider = self.crawler._create_spider("scrapytest.org")
|
||||
self.mw = HttpCompressionMiddleware.from_crawler(self.crawler)
|
||||
self.crawler.stats.open_spider(self.spider)
|
||||
|
||||
def _getresponse(self, coding):
|
||||
if coding not in FORMAT:
|
||||
|
|
@ -133,7 +131,7 @@ class HttpCompressionTest(unittest.TestCase):
|
|||
try:
|
||||
import brotli # noqa: F401
|
||||
except ImportError:
|
||||
raise unittest.SkipTest("no brotli")
|
||||
raise SkipTest("no brotli")
|
||||
response = self._getresponse("br")
|
||||
request = response.request
|
||||
self.assertEqual(response.headers["Content-Encoding"], b"br")
|
||||
|
|
@ -148,7 +146,7 @@ class HttpCompressionTest(unittest.TestCase):
|
|||
try:
|
||||
import zstandard # noqa: F401
|
||||
except ImportError:
|
||||
raise unittest.SkipTest("no zstd support (zstandard)")
|
||||
raise SkipTest("no zstd support (zstandard)")
|
||||
raw_content = None
|
||||
for check_key in FORMAT:
|
||||
if not check_key.startswith("zstd-"):
|
||||
|
|
@ -376,15 +374,13 @@ class HttpCompressionTest(unittest.TestCase):
|
|||
self.assertStatsEqual("httpcompression/response_bytes", None)
|
||||
|
||||
|
||||
class HttpCompressionSubclassTest(unittest.TestCase):
|
||||
@inlineCallbacks
|
||||
class HttpCompressionSubclassTest(TestCase):
|
||||
def test_init_missing_stats(self):
|
||||
class HttpCompressionMiddlewareSubclass(HttpCompressionMiddleware):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
crawler = get_crawler(NoRequestsSpider)
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(Spider)
|
||||
with catch_warnings(record=True) as caught_warnings:
|
||||
HttpCompressionMiddlewareSubclass.from_crawler(crawler)
|
||||
messages = tuple(
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import logging
|
||||
import unittest
|
||||
import warnings
|
||||
|
||||
from testfixtures import LogCapture
|
||||
from twisted.internet import defer
|
||||
from twisted.internet.defer import inlineCallbacks
|
||||
from twisted.internet.error import (
|
||||
ConnectError,
|
||||
ConnectionDone,
|
||||
|
|
@ -11,7 +11,6 @@ from twisted.internet.error import (
|
|||
DNSLookupError,
|
||||
TCPTimedOutError,
|
||||
)
|
||||
from twisted.trial import unittest
|
||||
from twisted.web.client import ResponseFailed
|
||||
|
||||
from scrapy.downloadermiddlewares.retry import RetryMiddleware, get_retry_request
|
||||
|
|
@ -20,15 +19,12 @@ from scrapy.http import Request, Response
|
|||
from scrapy.settings.default_settings import RETRY_EXCEPTIONS
|
||||
from scrapy.spiders import Spider
|
||||
from scrapy.utils.test import get_crawler
|
||||
from tests.spiders import NoRequestsSpider
|
||||
|
||||
|
||||
class RetryTest(unittest.TestCase):
|
||||
@inlineCallbacks
|
||||
def setUp(self):
|
||||
self.crawler = get_crawler(NoRequestsSpider)
|
||||
yield self.crawler.crawl()
|
||||
self.spider = self.crawler.spider
|
||||
self.crawler = get_crawler(Spider)
|
||||
self.spider = self.crawler._create_spider("foo")
|
||||
self.mw = RetryMiddleware.from_crawler(self.crawler)
|
||||
self.mw.max_retry_times = 2
|
||||
|
||||
|
|
@ -164,19 +160,16 @@ class RetryTest(unittest.TestCase):
|
|||
class MaxRetryTimesTest(unittest.TestCase):
|
||||
invalid_url = "http://www.scrapytest.org/invalid_url"
|
||||
|
||||
@inlineCallbacks
|
||||
def get_spider_and_middleware(self, settings=None):
|
||||
crawler = get_crawler(NoRequestsSpider, settings or {})
|
||||
yield crawler.crawl()
|
||||
spider = crawler.spider
|
||||
crawler = get_crawler(Spider, settings or {})
|
||||
spider = crawler._create_spider("foo")
|
||||
middleware = RetryMiddleware.from_crawler(crawler)
|
||||
return spider, middleware
|
||||
|
||||
@inlineCallbacks
|
||||
def test_with_settings_zero(self):
|
||||
max_retry_times = 0
|
||||
settings = {"RETRY_TIMES": max_retry_times}
|
||||
spider, middleware = yield self.get_spider_and_middleware(settings)
|
||||
spider, middleware = self.get_spider_and_middleware(settings)
|
||||
req = Request(self.invalid_url)
|
||||
self._test_retry(
|
||||
req,
|
||||
|
|
@ -186,10 +179,9 @@ class MaxRetryTimesTest(unittest.TestCase):
|
|||
middleware=middleware,
|
||||
)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_with_metakey_zero(self):
|
||||
max_retry_times = 0
|
||||
spider, middleware = yield self.get_spider_and_middleware()
|
||||
spider, middleware = self.get_spider_and_middleware()
|
||||
meta = {"max_retry_times": max_retry_times}
|
||||
req = Request(self.invalid_url, meta=meta)
|
||||
self._test_retry(
|
||||
|
|
@ -200,11 +192,10 @@ class MaxRetryTimesTest(unittest.TestCase):
|
|||
middleware=middleware,
|
||||
)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_without_metakey(self):
|
||||
max_retry_times = 5
|
||||
settings = {"RETRY_TIMES": max_retry_times}
|
||||
spider, middleware = yield self.get_spider_and_middleware(settings)
|
||||
spider, middleware = self.get_spider_and_middleware(settings)
|
||||
req = Request(self.invalid_url)
|
||||
self._test_retry(
|
||||
req,
|
||||
|
|
@ -214,7 +205,6 @@ class MaxRetryTimesTest(unittest.TestCase):
|
|||
middleware=middleware,
|
||||
)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_with_metakey_greater(self):
|
||||
meta_max_retry_times = 3
|
||||
middleware_max_retry_times = 2
|
||||
|
|
@ -223,7 +213,7 @@ class MaxRetryTimesTest(unittest.TestCase):
|
|||
req2 = Request(self.invalid_url)
|
||||
|
||||
settings = {"RETRY_TIMES": middleware_max_retry_times}
|
||||
spider, middleware = yield self.get_spider_and_middleware(settings)
|
||||
spider, middleware = self.get_spider_and_middleware(settings)
|
||||
|
||||
self._test_retry(
|
||||
req1,
|
||||
|
|
@ -240,7 +230,6 @@ class MaxRetryTimesTest(unittest.TestCase):
|
|||
middleware=middleware,
|
||||
)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_with_metakey_lesser(self):
|
||||
meta_max_retry_times = 4
|
||||
middleware_max_retry_times = 5
|
||||
|
|
@ -249,7 +238,7 @@ class MaxRetryTimesTest(unittest.TestCase):
|
|||
req2 = Request(self.invalid_url)
|
||||
|
||||
settings = {"RETRY_TIMES": middleware_max_retry_times}
|
||||
spider, middleware = yield self.get_spider_and_middleware(settings)
|
||||
spider, middleware = self.get_spider_and_middleware(settings)
|
||||
|
||||
self._test_retry(
|
||||
req1,
|
||||
|
|
@ -266,10 +255,9 @@ class MaxRetryTimesTest(unittest.TestCase):
|
|||
middleware=middleware,
|
||||
)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_with_dont_retry(self):
|
||||
max_retry_times = 4
|
||||
spider, middleware = yield self.get_spider_and_middleware()
|
||||
spider, middleware = self.get_spider_and_middleware()
|
||||
meta = {
|
||||
"max_retry_times": max_retry_times,
|
||||
"dont_retry": True,
|
||||
|
|
@ -304,16 +292,13 @@ class MaxRetryTimesTest(unittest.TestCase):
|
|||
|
||||
|
||||
class GetRetryRequestTest(unittest.TestCase):
|
||||
@inlineCallbacks
|
||||
def get_spider(self, settings=None):
|
||||
crawler = get_crawler(NoRequestsSpider, settings or {})
|
||||
yield crawler.crawl()
|
||||
return crawler.spider
|
||||
crawler = get_crawler(Spider, settings or {})
|
||||
return crawler._create_spider("foo")
|
||||
|
||||
@inlineCallbacks
|
||||
def test_basic_usage(self):
|
||||
request = Request("https://example.com")
|
||||
spider = yield self.get_spider()
|
||||
spider = self.get_spider()
|
||||
with LogCapture() as log:
|
||||
new_request = get_retry_request(
|
||||
request,
|
||||
|
|
@ -337,10 +322,9 @@ class GetRetryRequestTest(unittest.TestCase):
|
|||
)
|
||||
)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_max_retries_reached(self):
|
||||
request = Request("https://example.com")
|
||||
spider = yield self.get_spider()
|
||||
spider = self.get_spider()
|
||||
max_retry_times = 0
|
||||
with LogCapture() as log:
|
||||
new_request = get_retry_request(
|
||||
|
|
@ -361,10 +345,9 @@ class GetRetryRequestTest(unittest.TestCase):
|
|||
)
|
||||
)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_one_retry(self):
|
||||
request = Request("https://example.com")
|
||||
spider = yield self.get_spider()
|
||||
spider = self.get_spider()
|
||||
with LogCapture() as log:
|
||||
new_request = get_retry_request(
|
||||
request,
|
||||
|
|
@ -389,9 +372,8 @@ class GetRetryRequestTest(unittest.TestCase):
|
|||
)
|
||||
)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_two_retries(self):
|
||||
spider = yield self.get_spider()
|
||||
spider = self.get_spider()
|
||||
request = Request("https://example.com")
|
||||
new_request = request
|
||||
max_retry_times = 2
|
||||
|
|
@ -445,10 +427,9 @@ class GetRetryRequestTest(unittest.TestCase):
|
|||
with self.assertRaises(TypeError):
|
||||
get_retry_request(request) # pylint: disable=missing-kwoa
|
||||
|
||||
@inlineCallbacks
|
||||
def test_max_retry_times_setting(self):
|
||||
max_retry_times = 0
|
||||
spider = yield self.get_spider({"RETRY_TIMES": max_retry_times})
|
||||
spider = self.get_spider({"RETRY_TIMES": max_retry_times})
|
||||
request = Request("https://example.com")
|
||||
new_request = get_retry_request(
|
||||
request,
|
||||
|
|
@ -456,10 +437,9 @@ class GetRetryRequestTest(unittest.TestCase):
|
|||
)
|
||||
self.assertEqual(new_request, None)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_max_retry_times_meta(self):
|
||||
max_retry_times = 0
|
||||
spider = yield self.get_spider({"RETRY_TIMES": max_retry_times + 1})
|
||||
spider = self.get_spider({"RETRY_TIMES": max_retry_times + 1})
|
||||
meta = {"max_retry_times": max_retry_times}
|
||||
request = Request("https://example.com", meta=meta)
|
||||
new_request = get_retry_request(
|
||||
|
|
@ -468,10 +448,9 @@ class GetRetryRequestTest(unittest.TestCase):
|
|||
)
|
||||
self.assertEqual(new_request, None)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_max_retry_times_argument(self):
|
||||
max_retry_times = 0
|
||||
spider = yield self.get_spider({"RETRY_TIMES": max_retry_times + 1})
|
||||
spider = self.get_spider({"RETRY_TIMES": max_retry_times + 1})
|
||||
meta = {"max_retry_times": max_retry_times + 1}
|
||||
request = Request("https://example.com", meta=meta)
|
||||
new_request = get_retry_request(
|
||||
|
|
@ -481,10 +460,9 @@ class GetRetryRequestTest(unittest.TestCase):
|
|||
)
|
||||
self.assertEqual(new_request, None)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_priority_adjust_setting(self):
|
||||
priority_adjust = 1
|
||||
spider = yield self.get_spider({"RETRY_PRIORITY_ADJUST": priority_adjust})
|
||||
spider = self.get_spider({"RETRY_PRIORITY_ADJUST": priority_adjust})
|
||||
request = Request("https://example.com")
|
||||
new_request = get_retry_request(
|
||||
request,
|
||||
|
|
@ -492,10 +470,9 @@ class GetRetryRequestTest(unittest.TestCase):
|
|||
)
|
||||
self.assertEqual(new_request.priority, priority_adjust)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_priority_adjust_argument(self):
|
||||
priority_adjust = 1
|
||||
spider = yield self.get_spider({"RETRY_PRIORITY_ADJUST": priority_adjust + 1})
|
||||
spider = self.get_spider({"RETRY_PRIORITY_ADJUST": priority_adjust + 1})
|
||||
request = Request("https://example.com")
|
||||
new_request = get_retry_request(
|
||||
request,
|
||||
|
|
@ -504,10 +481,9 @@ class GetRetryRequestTest(unittest.TestCase):
|
|||
)
|
||||
self.assertEqual(new_request.priority, priority_adjust)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_log_extra_retry_success(self):
|
||||
request = Request("https://example.com")
|
||||
spider = yield self.get_spider()
|
||||
spider = self.get_spider()
|
||||
with LogCapture(attributes=("spider",)) as log:
|
||||
get_retry_request(
|
||||
request,
|
||||
|
|
@ -515,10 +491,9 @@ class GetRetryRequestTest(unittest.TestCase):
|
|||
)
|
||||
log.check_present(spider)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_log_extra_retries_exceeded(self):
|
||||
request = Request("https://example.com")
|
||||
spider = yield self.get_spider()
|
||||
spider = self.get_spider()
|
||||
with LogCapture(attributes=("spider",)) as log:
|
||||
get_retry_request(
|
||||
request,
|
||||
|
|
@ -527,10 +502,9 @@ class GetRetryRequestTest(unittest.TestCase):
|
|||
)
|
||||
log.check_present(spider)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_reason_string(self):
|
||||
request = Request("https://example.com")
|
||||
spider = yield self.get_spider()
|
||||
spider = self.get_spider()
|
||||
expected_reason = "because"
|
||||
with LogCapture() as log:
|
||||
get_retry_request(
|
||||
|
|
@ -550,10 +524,9 @@ class GetRetryRequestTest(unittest.TestCase):
|
|||
)
|
||||
)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_reason_builtin_exception(self):
|
||||
request = Request("https://example.com")
|
||||
spider = yield self.get_spider()
|
||||
spider = self.get_spider()
|
||||
expected_reason = NotImplementedError()
|
||||
expected_reason_string = "builtins.NotImplementedError"
|
||||
with LogCapture() as log:
|
||||
|
|
@ -576,10 +549,9 @@ class GetRetryRequestTest(unittest.TestCase):
|
|||
)
|
||||
)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_reason_builtin_exception_class(self):
|
||||
request = Request("https://example.com")
|
||||
spider = yield self.get_spider()
|
||||
spider = self.get_spider()
|
||||
expected_reason = NotImplementedError
|
||||
expected_reason_string = "builtins.NotImplementedError"
|
||||
with LogCapture() as log:
|
||||
|
|
@ -602,10 +574,9 @@ class GetRetryRequestTest(unittest.TestCase):
|
|||
)
|
||||
)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_reason_custom_exception(self):
|
||||
request = Request("https://example.com")
|
||||
spider = yield self.get_spider()
|
||||
spider = self.get_spider()
|
||||
expected_reason = IgnoreRequest()
|
||||
expected_reason_string = "scrapy.exceptions.IgnoreRequest"
|
||||
with LogCapture() as log:
|
||||
|
|
@ -628,10 +599,9 @@ class GetRetryRequestTest(unittest.TestCase):
|
|||
)
|
||||
)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_reason_custom_exception_class(self):
|
||||
request = Request("https://example.com")
|
||||
spider = yield self.get_spider()
|
||||
spider = self.get_spider()
|
||||
expected_reason = IgnoreRequest
|
||||
expected_reason_string = "scrapy.exceptions.IgnoreRequest"
|
||||
with LogCapture() as log:
|
||||
|
|
@ -654,11 +624,10 @@ class GetRetryRequestTest(unittest.TestCase):
|
|||
)
|
||||
)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_custom_logger(self):
|
||||
logger = logging.getLogger("custom-logger")
|
||||
request = Request("https://example.com")
|
||||
spider = yield self.get_spider()
|
||||
spider = self.get_spider()
|
||||
expected_reason = "because"
|
||||
with LogCapture() as log:
|
||||
get_retry_request(
|
||||
|
|
@ -675,10 +644,9 @@ class GetRetryRequestTest(unittest.TestCase):
|
|||
)
|
||||
)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_custom_stats_key(self):
|
||||
request = Request("https://example.com")
|
||||
spider = yield self.get_spider()
|
||||
spider = self.get_spider()
|
||||
expected_reason = "because"
|
||||
stats_key = "custom_retry"
|
||||
get_retry_request(
|
||||
|
|
@ -692,3 +660,7 @@ class GetRetryRequestTest(unittest.TestCase):
|
|||
f"{stats_key}/reason_count/{expected_reason}",
|
||||
):
|
||||
self.assertEqual(spider.crawler.stats.get_value(stat), 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
|||
|
|
@ -1,29 +1,27 @@
|
|||
import warnings
|
||||
from itertools import product
|
||||
|
||||
from twisted.internet.defer import inlineCallbacks
|
||||
from twisted.trial import unittest
|
||||
from unittest import TestCase
|
||||
|
||||
from scrapy.downloadermiddlewares.stats import DownloaderStats
|
||||
from scrapy.exceptions import ScrapyDeprecationWarning
|
||||
from scrapy.http import Request, Response
|
||||
from scrapy.spiders import Spider
|
||||
from scrapy.utils.response import response_httprepr
|
||||
from scrapy.utils.test import get_crawler
|
||||
from tests.spiders import NoRequestsSpider
|
||||
|
||||
|
||||
class MyException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class TestDownloaderStats(unittest.TestCase):
|
||||
@inlineCallbacks
|
||||
class TestDownloaderStats(TestCase):
|
||||
def setUp(self):
|
||||
self.crawler = get_crawler(NoRequestsSpider)
|
||||
yield self.crawler.crawl()
|
||||
self.spider = self.crawler.spider
|
||||
self.crawler = get_crawler(Spider)
|
||||
self.spider = self.crawler._create_spider("scrapytest.org")
|
||||
self.mw = DownloaderStats(self.crawler.stats)
|
||||
|
||||
self.crawler.stats.open_spider(self.spider)
|
||||
|
||||
self.req = Request("http://scrapytest.org")
|
||||
self.res = Response("scrapytest.org", status=400)
|
||||
|
||||
|
|
|
|||
|
|
@ -2,25 +2,22 @@ import hashlib
|
|||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from testfixtures import LogCapture
|
||||
from twisted.internet.defer import inlineCallbacks
|
||||
from twisted.trial import unittest
|
||||
|
||||
from scrapy.core.scheduler import Scheduler
|
||||
from scrapy.dupefilters import RFPDupeFilter
|
||||
from scrapy.http import Request
|
||||
from scrapy.utils.python import to_bytes
|
||||
from scrapy.utils.test import get_crawler
|
||||
from tests.spiders import NoRequestsSpider
|
||||
from tests.spiders import SimpleSpider
|
||||
|
||||
|
||||
@inlineCallbacks
|
||||
def _get_dupefilter(*, crawler=None, settings=None, open=True):
|
||||
if crawler is None:
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=settings)
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(settings_dict=settings)
|
||||
scheduler = Scheduler.from_crawler(crawler)
|
||||
dupefilter = scheduler.df
|
||||
if open:
|
||||
|
|
@ -47,51 +44,41 @@ class FromSettingsRFPDupeFilter(RFPDupeFilter):
|
|||
class DirectDupeFilter:
|
||||
method = "n/a"
|
||||
|
||||
def open(self):
|
||||
pass
|
||||
|
||||
|
||||
class RFPDupeFilterTest(unittest.TestCase):
|
||||
@inlineCallbacks
|
||||
def test_df_from_crawler_scheduler(self):
|
||||
settings = {
|
||||
"DUPEFILTER_DEBUG": True,
|
||||
"DUPEFILTER_CLASS": FromCrawlerRFPDupeFilter,
|
||||
"REQUEST_FINGERPRINTER_IMPLEMENTATION": "2.7",
|
||||
}
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=settings)
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(settings_dict=settings)
|
||||
scheduler = Scheduler.from_crawler(crawler)
|
||||
self.assertTrue(scheduler.df.debug)
|
||||
self.assertEqual(scheduler.df.method, "from_crawler")
|
||||
|
||||
@inlineCallbacks
|
||||
def test_df_from_settings_scheduler(self):
|
||||
settings = {
|
||||
"DUPEFILTER_DEBUG": True,
|
||||
"DUPEFILTER_CLASS": FromSettingsRFPDupeFilter,
|
||||
"REQUEST_FINGERPRINTER_IMPLEMENTATION": "2.7",
|
||||
}
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=settings)
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(settings_dict=settings)
|
||||
scheduler = Scheduler.from_crawler(crawler)
|
||||
self.assertTrue(scheduler.df.debug)
|
||||
self.assertEqual(scheduler.df.method, "from_settings")
|
||||
|
||||
@inlineCallbacks
|
||||
def test_df_direct_scheduler(self):
|
||||
settings = {
|
||||
"DUPEFILTER_CLASS": DirectDupeFilter,
|
||||
"REQUEST_FINGERPRINTER_IMPLEMENTATION": "2.7",
|
||||
}
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=settings)
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(settings_dict=settings)
|
||||
scheduler = Scheduler.from_crawler(crawler)
|
||||
self.assertEqual(scheduler.df.method, "n/a")
|
||||
|
||||
@inlineCallbacks
|
||||
def test_filter(self):
|
||||
dupefilter = yield _get_dupefilter()
|
||||
dupefilter = _get_dupefilter()
|
||||
r1 = Request("http://scrapytest.org/1")
|
||||
r2 = Request("http://scrapytest.org/2")
|
||||
r3 = Request("http://scrapytest.org/2")
|
||||
|
|
@ -104,14 +91,13 @@ class RFPDupeFilterTest(unittest.TestCase):
|
|||
|
||||
dupefilter.close("finished")
|
||||
|
||||
@inlineCallbacks
|
||||
def test_dupefilter_path(self):
|
||||
r1 = Request("http://scrapytest.org/1")
|
||||
r2 = Request("http://scrapytest.org/2")
|
||||
|
||||
path = tempfile.mkdtemp()
|
||||
try:
|
||||
df = yield _get_dupefilter(settings={"JOBDIR": path}, open=False)
|
||||
df = _get_dupefilter(settings={"JOBDIR": path}, open=False)
|
||||
try:
|
||||
df.open()
|
||||
assert not df.request_seen(r1)
|
||||
|
|
@ -119,7 +105,7 @@ class RFPDupeFilterTest(unittest.TestCase):
|
|||
finally:
|
||||
df.close("finished")
|
||||
|
||||
df2 = yield _get_dupefilter(settings={"JOBDIR": path}, open=False)
|
||||
df2 = _get_dupefilter(settings={"JOBDIR": path}, open=False)
|
||||
assert df != df2
|
||||
try:
|
||||
df2.open()
|
||||
|
|
@ -131,13 +117,12 @@ class RFPDupeFilterTest(unittest.TestCase):
|
|||
finally:
|
||||
shutil.rmtree(path)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_request_fingerprint(self):
|
||||
"""Test if customization of request_fingerprint method will change
|
||||
output of request_seen.
|
||||
|
||||
"""
|
||||
dupefilter = yield _get_dupefilter()
|
||||
dupefilter = _get_dupefilter()
|
||||
r1 = Request("http://scrapytest.org/index.html")
|
||||
r2 = Request("http://scrapytest.org/INDEX.html")
|
||||
|
||||
|
|
@ -153,14 +138,13 @@ class RFPDupeFilterTest(unittest.TestCase):
|
|||
return fp.digest()
|
||||
|
||||
settings = {"REQUEST_FINGERPRINTER_CLASS": RequestFingerprinter}
|
||||
case_insensitive_dupefilter = yield _get_dupefilter(settings=settings)
|
||||
case_insensitive_dupefilter = _get_dupefilter(settings=settings)
|
||||
|
||||
assert not case_insensitive_dupefilter.request_seen(r1)
|
||||
assert case_insensitive_dupefilter.request_seen(r2)
|
||||
|
||||
case_insensitive_dupefilter.close("finished")
|
||||
|
||||
@inlineCallbacks
|
||||
def test_seenreq_newlines(self):
|
||||
"""Checks against adding duplicate \r to
|
||||
line endings on Windows platforms."""
|
||||
|
|
@ -168,8 +152,7 @@ class RFPDupeFilterTest(unittest.TestCase):
|
|||
r1 = Request("http://scrapytest.org/1")
|
||||
|
||||
path = tempfile.mkdtemp()
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict={"JOBDIR": path})
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(settings_dict={"JOBDIR": path})
|
||||
try:
|
||||
scheduler = Scheduler.from_crawler(crawler)
|
||||
df = scheduler.df
|
||||
|
|
@ -178,10 +161,7 @@ class RFPDupeFilterTest(unittest.TestCase):
|
|||
df.close("finished")
|
||||
|
||||
with Path(path, "requests.seen").open("rb") as seen_file:
|
||||
try:
|
||||
line = next(seen_file).decode()
|
||||
except StopIteration:
|
||||
return
|
||||
line = next(seen_file).decode()
|
||||
assert not line.endswith("\r\r\n")
|
||||
if sys.platform == "win32":
|
||||
assert line.endswith("\r\n")
|
||||
|
|
@ -191,7 +171,6 @@ class RFPDupeFilterTest(unittest.TestCase):
|
|||
finally:
|
||||
shutil.rmtree(path)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_log(self):
|
||||
with LogCapture() as log:
|
||||
settings = {
|
||||
|
|
@ -199,10 +178,9 @@ class RFPDupeFilterTest(unittest.TestCase):
|
|||
"DUPEFILTER_CLASS": FromCrawlerRFPDupeFilter,
|
||||
"REQUEST_FINGERPRINTER_IMPLEMENTATION": "2.7",
|
||||
}
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=settings)
|
||||
yield crawler.crawl()
|
||||
spider = crawler.spider
|
||||
dupefilter = yield _get_dupefilter(crawler=crawler)
|
||||
crawler = get_crawler(SimpleSpider, settings_dict=settings)
|
||||
spider = SimpleSpider.from_crawler(crawler)
|
||||
dupefilter = _get_dupefilter(crawler=crawler)
|
||||
|
||||
r1 = Request("http://scrapytest.org/index.html")
|
||||
r2 = Request("http://scrapytest.org/index.html")
|
||||
|
|
@ -222,7 +200,6 @@ class RFPDupeFilterTest(unittest.TestCase):
|
|||
|
||||
dupefilter.close("finished")
|
||||
|
||||
@inlineCallbacks
|
||||
def test_log_debug(self):
|
||||
with LogCapture() as log:
|
||||
settings = {
|
||||
|
|
@ -230,10 +207,9 @@ class RFPDupeFilterTest(unittest.TestCase):
|
|||
"DUPEFILTER_CLASS": FromCrawlerRFPDupeFilter,
|
||||
"REQUEST_FINGERPRINTER_IMPLEMENTATION": "2.7",
|
||||
}
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=settings)
|
||||
yield crawler.crawl()
|
||||
spider = crawler.spider
|
||||
dupefilter = yield _get_dupefilter(crawler=crawler)
|
||||
crawler = get_crawler(SimpleSpider, settings_dict=settings)
|
||||
spider = SimpleSpider.from_crawler(crawler)
|
||||
dupefilter = _get_dupefilter(crawler=crawler)
|
||||
|
||||
r1 = Request("http://scrapytest.org/index.html")
|
||||
r2 = Request(
|
||||
|
|
@ -263,17 +239,15 @@ class RFPDupeFilterTest(unittest.TestCase):
|
|||
|
||||
dupefilter.close("finished")
|
||||
|
||||
@inlineCallbacks
|
||||
def test_log_debug_default_dupefilter(self):
|
||||
with LogCapture() as log:
|
||||
settings = {
|
||||
"DUPEFILTER_DEBUG": True,
|
||||
"REQUEST_FINGERPRINTER_IMPLEMENTATION": "2.7",
|
||||
}
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=settings)
|
||||
yield crawler.crawl()
|
||||
spider = crawler.spider
|
||||
dupefilter = yield _get_dupefilter(crawler=crawler)
|
||||
crawler = get_crawler(SimpleSpider, settings_dict=settings)
|
||||
spider = SimpleSpider.from_crawler(crawler)
|
||||
dupefilter = _get_dupefilter(crawler=crawler)
|
||||
|
||||
r1 = Request("http://scrapytest.org/index.html")
|
||||
r2 = Request(
|
||||
|
|
|
|||
|
|
@ -420,16 +420,12 @@ class EngineTest(unittest.TestCase):
|
|||
|
||||
@defer.inlineCallbacks
|
||||
def test_close_downloader(self):
|
||||
crawler = get_crawler(TestSpider)
|
||||
yield crawler.crawl()
|
||||
e = ExecutionEngine(crawler, lambda _: None)
|
||||
e = ExecutionEngine(get_crawler(TestSpider), lambda _: None)
|
||||
yield e.close()
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_start_already_running_exception(self):
|
||||
crawler = get_crawler(TestSpider)
|
||||
yield crawler.crawl()
|
||||
e = ExecutionEngine(crawler, lambda _: None)
|
||||
e = ExecutionEngine(get_crawler(TestSpider), lambda _: None)
|
||||
yield e.open_spider(TestSpider(), [])
|
||||
e.start()
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
import datetime
|
||||
import typing
|
||||
|
||||
from twisted.internet.defer import inlineCallbacks
|
||||
from twisted.trial import unittest
|
||||
import unittest
|
||||
|
||||
from scrapy.crawler import Crawler
|
||||
from scrapy.extensions.periodic_log import PeriodicLog
|
||||
|
|
@ -61,44 +59,33 @@ class TestExtPeriodicLog(PeriodicLog):
|
|||
self.stats._stats = stats_dump_2
|
||||
|
||||
|
||||
@inlineCallbacks
|
||||
def extension(settings=None):
|
||||
crawler = Crawler(
|
||||
MetaSpider,
|
||||
settings=settings,
|
||||
)
|
||||
yield crawler.crawl()
|
||||
crawler = Crawler(MetaSpider, settings=settings)
|
||||
crawler._load_settings()
|
||||
return TestExtPeriodicLog.from_crawler(crawler)
|
||||
|
||||
|
||||
class TestPeriodicLog(unittest.TestCase):
|
||||
@inlineCallbacks
|
||||
def test_extension_enabled(self):
|
||||
# Expected that settings for this extension loaded succesfully
|
||||
# And on certain conditions - extension raising NotConfigured
|
||||
|
||||
# "PERIODIC_LOG_STATS": True -> set to {"enabled": True}
|
||||
# due to TypeError exception from settings.getdict
|
||||
assert (yield extension({"PERIODIC_LOG_STATS": True, "LOGSTATS_INTERVAL": 60}))
|
||||
assert extension({"PERIODIC_LOG_STATS": True, "LOGSTATS_INTERVAL": 60})
|
||||
|
||||
# "PERIODIC_LOG_STATS": "True" -> set to {"enabled": True}
|
||||
# due to JSONDecodeError(ValueError) exception from settings.getdict
|
||||
assert (
|
||||
yield extension({"PERIODIC_LOG_STATS": "True", "LOGSTATS_INTERVAL": 60})
|
||||
)
|
||||
assert extension({"PERIODIC_LOG_STATS": "True", "LOGSTATS_INTERVAL": 60})
|
||||
|
||||
# The ame for PERIODIC_LOG_DELTA:
|
||||
assert (yield extension({"PERIODIC_LOG_DELTA": True, "LOGSTATS_INTERVAL": 60}))
|
||||
assert (
|
||||
yield extension({"PERIODIC_LOG_DELTA": "True", "LOGSTATS_INTERVAL": 60})
|
||||
)
|
||||
assert extension({"PERIODIC_LOG_DELTA": True, "LOGSTATS_INTERVAL": 60})
|
||||
assert extension({"PERIODIC_LOG_DELTA": "True", "LOGSTATS_INTERVAL": 60})
|
||||
|
||||
@inlineCallbacks
|
||||
def test_log_delta(self):
|
||||
@inlineCallbacks
|
||||
def emulate(settings=None):
|
||||
spider = MetaSpider()
|
||||
ext = yield extension(settings)
|
||||
ext = extension(settings)
|
||||
ext.spider_opened(spider)
|
||||
ext.set_a()
|
||||
a = ext.log_delta()
|
||||
|
|
@ -107,9 +94,8 @@ class TestPeriodicLog(unittest.TestCase):
|
|||
ext.spider_closed(spider, reason="finished")
|
||||
return ext, a, b
|
||||
|
||||
@inlineCallbacks
|
||||
def check(settings: dict, condition: typing.Callable):
|
||||
ext, a, b = yield emulate(settings)
|
||||
ext, a, b = emulate(settings)
|
||||
assert list(a["delta"].keys()) == [
|
||||
k for k, v in ext.stats._stats.items() if condition(k, v)
|
||||
]
|
||||
|
|
@ -118,49 +104,45 @@ class TestPeriodicLog(unittest.TestCase):
|
|||
]
|
||||
|
||||
# Including all
|
||||
yield check(
|
||||
{"PERIODIC_LOG_DELTA": True}, lambda k, v: isinstance(v, (int, float))
|
||||
)
|
||||
check({"PERIODIC_LOG_DELTA": True}, lambda k, v: isinstance(v, (int, float)))
|
||||
|
||||
# include:
|
||||
yield check(
|
||||
check(
|
||||
{"PERIODIC_LOG_DELTA": {"include": ["downloader/"]}},
|
||||
lambda k, v: isinstance(v, (int, float)) and "downloader/" in k,
|
||||
)
|
||||
|
||||
# include multiple
|
||||
yield check(
|
||||
check(
|
||||
{"PERIODIC_LOG_DELTA": {"include": ["downloader/", "scheduler/"]}},
|
||||
lambda k, v: isinstance(v, (int, float))
|
||||
and ("downloader/" in k or "scheduler/" in k),
|
||||
)
|
||||
|
||||
# exclude
|
||||
yield check(
|
||||
check(
|
||||
{"PERIODIC_LOG_DELTA": {"exclude": ["downloader/"]}},
|
||||
lambda k, v: isinstance(v, (int, float)) and "downloader/" not in k,
|
||||
)
|
||||
|
||||
# exclude multiple
|
||||
yield check(
|
||||
check(
|
||||
{"PERIODIC_LOG_DELTA": {"exclude": ["downloader/", "scheduler/"]}},
|
||||
lambda k, v: isinstance(v, (int, float))
|
||||
and ("downloader/" not in k and "scheduler/" not in k),
|
||||
)
|
||||
|
||||
# include exclude combined
|
||||
yield check(
|
||||
check(
|
||||
{"PERIODIC_LOG_DELTA": {"include": ["downloader/"], "exclude": ["bytes"]}},
|
||||
lambda k, v: isinstance(v, (int, float))
|
||||
and ("downloader/" in k and "bytes" not in k),
|
||||
)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_log_stats(self):
|
||||
@inlineCallbacks
|
||||
def emulate(settings=None):
|
||||
spider = MetaSpider()
|
||||
ext = yield extension(settings)
|
||||
ext = extension(settings)
|
||||
ext.spider_opened(spider)
|
||||
ext.set_a()
|
||||
a = ext.log_crawler_stats()
|
||||
|
|
@ -169,9 +151,8 @@ class TestPeriodicLog(unittest.TestCase):
|
|||
ext.spider_closed(spider, reason="finished")
|
||||
return ext, a, b
|
||||
|
||||
@inlineCallbacks
|
||||
def check(settings: dict, condition: typing.Callable):
|
||||
ext, a, b = yield emulate(settings)
|
||||
ext, a, b = emulate(settings)
|
||||
assert list(a["stats"].keys()) == [
|
||||
k for k, v in ext.stats._stats.items() if condition(k, v)
|
||||
]
|
||||
|
|
@ -180,34 +161,35 @@ class TestPeriodicLog(unittest.TestCase):
|
|||
]
|
||||
|
||||
# Including all
|
||||
yield check({"PERIODIC_LOG_STATS": True}, lambda k, v: True)
|
||||
check({"PERIODIC_LOG_STATS": True}, lambda k, v: True)
|
||||
|
||||
# include:
|
||||
yield check(
|
||||
check(
|
||||
{"PERIODIC_LOG_STATS": {"include": ["downloader/"]}},
|
||||
lambda k, v: "downloader/" in k,
|
||||
)
|
||||
|
||||
# include multiple
|
||||
yield check(
|
||||
check(
|
||||
{"PERIODIC_LOG_STATS": {"include": ["downloader/", "scheduler/"]}},
|
||||
lambda k, v: "downloader/" in k or "scheduler/" in k,
|
||||
)
|
||||
|
||||
# exclude
|
||||
yield check(
|
||||
check(
|
||||
{"PERIODIC_LOG_STATS": {"exclude": ["downloader/"]}},
|
||||
lambda k, v: "downloader/" not in k,
|
||||
)
|
||||
|
||||
# exclude multiple
|
||||
yield check(
|
||||
check(
|
||||
{"PERIODIC_LOG_STATS": {"exclude": ["downloader/", "scheduler/"]}},
|
||||
lambda k, v: "downloader/" not in k and "scheduler/" not in k,
|
||||
)
|
||||
|
||||
# include exclude combined
|
||||
yield check(
|
||||
check(
|
||||
{"PERIODIC_LOG_STATS": {"include": ["downloader/"], "exclude": ["bytes"]}},
|
||||
lambda k, v: "downloader/" in k and "bytes" not in k,
|
||||
)
|
||||
#
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from scrapy.utils.test import get_crawler
|
|||
|
||||
class TelnetExtensionTest(unittest.TestCase):
|
||||
def _get_console_and_portal(self, settings=None):
|
||||
crawler = get_crawler(settings_dict=settings, disable_telnet=False)
|
||||
crawler = get_crawler(settings_dict=settings)
|
||||
console = TelnetConsole(crawler)
|
||||
|
||||
# This function has some side effects we don't need for this test
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ import lxml.etree
|
|||
import pytest
|
||||
from testfixtures import LogCapture
|
||||
from twisted.internet import defer
|
||||
from twisted.internet.defer import inlineCallbacks
|
||||
from twisted.trial import unittest
|
||||
from w3lib.url import file_uri_to_path, path_to_file_uri
|
||||
from zope.interface import implementer
|
||||
|
|
@ -52,7 +51,7 @@ from scrapy.settings import Settings
|
|||
from scrapy.utils.python import to_unicode
|
||||
from scrapy.utils.test import get_crawler, mock_google_cloud_storage, skip_if_no_boto
|
||||
from tests.mockserver import MockFTPServer, MockServer
|
||||
from tests.spiders import ItemSpider, NoRequestsSpider
|
||||
from tests.spiders import ItemSpider
|
||||
|
||||
|
||||
def path_to_url(path):
|
||||
|
|
@ -2748,14 +2747,13 @@ class FeedExporterSignalsTest(unittest.TestCase):
|
|||
d.callback(None)
|
||||
return d
|
||||
|
||||
@inlineCallbacks
|
||||
def run_signaled_feed_exporter(
|
||||
self, feed_exporter_signal_handler, feed_slot_signal_handler
|
||||
):
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=self.settings)
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(settings_dict=self.settings)
|
||||
feed_exporter = FeedExporter.from_crawler(crawler)
|
||||
spider = crawler.spider
|
||||
spider = scrapy.Spider("default")
|
||||
spider.crawler = crawler
|
||||
crawler.signals.connect(
|
||||
feed_exporter_signal_handler,
|
||||
signal=signals.feed_exporter_closed,
|
||||
|
|
@ -2766,26 +2764,24 @@ class FeedExporterSignalsTest(unittest.TestCase):
|
|||
feed_exporter.open_spider(spider)
|
||||
for item in self.items:
|
||||
feed_exporter.item_scraped(item, spider)
|
||||
yield defer.ensureDeferred(feed_exporter.close_spider(spider))
|
||||
defer.ensureDeferred(feed_exporter.close_spider(spider))
|
||||
|
||||
@inlineCallbacks
|
||||
def test_feed_exporter_signals_sent(self):
|
||||
self.feed_exporter_closed_received = False
|
||||
self.feed_slot_closed_received = False
|
||||
|
||||
yield self.run_signaled_feed_exporter(
|
||||
self.run_signaled_feed_exporter(
|
||||
self.feed_exporter_closed_signal_handler,
|
||||
self.feed_slot_closed_signal_handler,
|
||||
)
|
||||
self.assertTrue(self.feed_slot_closed_received)
|
||||
self.assertTrue(self.feed_exporter_closed_received)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_feed_exporter_signals_sent_deferred(self):
|
||||
self.feed_exporter_closed_received = False
|
||||
self.feed_slot_closed_received = False
|
||||
|
||||
yield self.run_signaled_feed_exporter(
|
||||
self.run_signaled_feed_exporter(
|
||||
self.feed_exporter_closed_signal_handler_deferred,
|
||||
self.feed_slot_closed_signal_handler_deferred,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import attr
|
|||
import pytest
|
||||
from itemadapter import ItemAdapter
|
||||
from twisted.internet import defer
|
||||
from twisted.internet.defer import inlineCallbacks
|
||||
from twisted.trial import unittest
|
||||
|
||||
from scrapy.http import Request, Response
|
||||
|
|
@ -36,18 +35,15 @@ from scrapy.utils.test import (
|
|||
skip_if_no_boto,
|
||||
)
|
||||
from tests.mockserver import MockFTPServer
|
||||
from tests.spiders import NoRequestsSpider
|
||||
|
||||
from .test_pipeline_media import _mocked_download_func
|
||||
|
||||
|
||||
class FilesPipelineTestCase(unittest.TestCase):
|
||||
@inlineCallbacks
|
||||
def setUp(self):
|
||||
self.tempdir = mkdtemp()
|
||||
settings_dict = {"FILES_STORE": self.tempdir}
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=settings_dict)
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(spidercls=None, settings_dict=settings_dict)
|
||||
self.pipeline = FilesPipeline.from_crawler(crawler)
|
||||
self.pipeline.download_func = _mocked_download_func
|
||||
self.pipeline.open_spider(None)
|
||||
|
|
|
|||
|
|
@ -14,11 +14,11 @@ from scrapy.pipelines.files import FileException
|
|||
from scrapy.pipelines.images import ImagesPipeline
|
||||
from scrapy.pipelines.media import MediaPipeline
|
||||
from scrapy.settings import Settings
|
||||
from scrapy.spiders import Spider
|
||||
from scrapy.utils.deprecate import ScrapyDeprecationWarning
|
||||
from scrapy.utils.log import failure_to_exc_info
|
||||
from scrapy.utils.signal import disconnect_all
|
||||
from scrapy.utils.test import get_crawler
|
||||
from tests.spiders import NoRequestsSpider
|
||||
|
||||
try:
|
||||
from PIL import Image # noqa: imported just to check for the import error
|
||||
|
|
@ -40,11 +40,10 @@ class BaseMediaPipelineTestCase(unittest.TestCase):
|
|||
pipeline_class = MediaPipeline
|
||||
settings = None
|
||||
|
||||
@inlineCallbacks
|
||||
def setUp(self):
|
||||
crawler = get_crawler(NoRequestsSpider, self.settings)
|
||||
yield crawler.crawl()
|
||||
self.spider = crawler.spider
|
||||
spider_cls = Spider
|
||||
self.spider = spider_cls("media.com")
|
||||
crawler = get_crawler(spider_cls, self.settings)
|
||||
self.pipe = self.pipeline_class.from_crawler(crawler)
|
||||
self.pipe.download_func = _mocked_download_func
|
||||
self.pipe.open_spider(self.spider)
|
||||
|
|
@ -431,14 +430,12 @@ class MockedMediaPipelineDeprecatedMethods(ImagesPipeline):
|
|||
class MediaPipelineDeprecatedMethodsTestCase(unittest.TestCase):
|
||||
skip = skip_pillow
|
||||
|
||||
@inlineCallbacks
|
||||
def setUp(self):
|
||||
settings_dict = {
|
||||
"IMAGES_STORE": "store-uri",
|
||||
"IMAGES_THUMBS": {"small": (50, 50)},
|
||||
}
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=settings_dict)
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(spidercls=None, settings_dict=settings_dict)
|
||||
self.pipe = MockedMediaPipelineDeprecatedMethods.from_crawler(crawler)
|
||||
self.pipe.download_func = _mocked_download_func
|
||||
self.pipe.open_spider(None)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import collections
|
||||
import shutil
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
from twisted.internet import defer
|
||||
from twisted.internet.defer import inlineCallbacks
|
||||
from twisted.trial import unittest
|
||||
from twisted.trial.unittest import TestCase
|
||||
|
||||
from scrapy.core.downloader import Downloader
|
||||
from scrapy.core.scheduler import Scheduler
|
||||
|
|
@ -15,7 +15,6 @@ from scrapy.utils.httpobj import urlparse_cached
|
|||
from scrapy.utils.misc import load_object
|
||||
from scrapy.utils.test import get_crawler
|
||||
from tests.mockserver import MockServer
|
||||
from tests.spiders import NoRequestsSpider
|
||||
|
||||
MockEngine = collections.namedtuple("MockEngine", ["downloader"])
|
||||
MockSlot = collections.namedtuple("MockSlot", ["active"])
|
||||
|
|
@ -310,7 +309,7 @@ class StartUrlsSpider(Spider):
|
|||
pass
|
||||
|
||||
|
||||
class TestIntegrationWithDownloaderAwareInMemory(unittest.TestCase):
|
||||
class TestIntegrationWithDownloaderAwareInMemory(TestCase):
|
||||
def setUp(self):
|
||||
self.crawler = get_crawler(
|
||||
spidercls=StartUrlsSpider,
|
||||
|
|
@ -337,19 +336,16 @@ class TestIntegrationWithDownloaderAwareInMemory(unittest.TestCase):
|
|||
|
||||
|
||||
class TestIncompatibility(unittest.TestCase):
|
||||
@inlineCallbacks
|
||||
def _incompatible(self):
|
||||
settings = dict(
|
||||
SCHEDULER_PRIORITY_QUEUE="scrapy.pqueues.DownloaderAwarePriorityQueue",
|
||||
CONCURRENT_REQUESTS_PER_IP=1,
|
||||
)
|
||||
crawler = get_crawler(NoRequestsSpider, settings)
|
||||
yield crawler.crawl()
|
||||
spider = crawler.spider
|
||||
crawler = get_crawler(Spider, settings)
|
||||
scheduler = Scheduler.from_crawler(crawler)
|
||||
spider = Spider(name="spider")
|
||||
scheduler.open(spider)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_incompatibility(self):
|
||||
with self.assertRaises(ValueError):
|
||||
yield self._incompatible()
|
||||
self._incompatible()
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ class SpiderTest(unittest.TestCase):
|
|||
spider.settings.set("TEST1", "spider_instance", priority="spider")
|
||||
return spider
|
||||
|
||||
crawler = get_crawler(TestSpider, settings_dict=project_settings)
|
||||
crawler = Crawler(TestSpider, project_settings)
|
||||
self.assertEqual(crawler.settings.get("TEST1"), "spider")
|
||||
self.assertEqual(crawler.settings.get("TEST2"), "spider")
|
||||
self.assertEqual(crawler.settings.get("TEST3"), "project")
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import logging
|
||||
from unittest import TestCase
|
||||
|
||||
from testfixtures import LogCapture
|
||||
from twisted.internet import defer
|
||||
from twisted.internet.defer import inlineCallbacks
|
||||
from twisted.trial.unittest import TestCase
|
||||
from twisted.trial.unittest import TestCase as TrialTestCase
|
||||
|
||||
from scrapy.http import Request, Response
|
||||
from scrapy.settings import Settings
|
||||
|
|
@ -11,7 +11,7 @@ from scrapy.spidermiddlewares.httperror import HttpError, HttpErrorMiddleware
|
|||
from scrapy.spiders import Spider
|
||||
from scrapy.utils.test import get_crawler
|
||||
from tests.mockserver import MockServer
|
||||
from tests.spiders import MockServerSpider, NoRequestsSpider
|
||||
from tests.spiders import MockServerSpider
|
||||
|
||||
|
||||
class _HttpErrorSpider(MockServerSpider):
|
||||
|
|
@ -59,11 +59,9 @@ def _responses(request, status_codes):
|
|||
|
||||
|
||||
class TestHttpErrorMiddleware(TestCase):
|
||||
@inlineCallbacks
|
||||
def setUp(self):
|
||||
crawler = get_crawler(NoRequestsSpider)
|
||||
yield crawler.crawl()
|
||||
self.spider = crawler.spider
|
||||
crawler = get_crawler(Spider)
|
||||
self.spider = Spider.from_crawler(crawler, name="foo")
|
||||
self.mw = HttpErrorMiddleware(Settings({}))
|
||||
self.req = Request("http://scrapytest.org")
|
||||
self.res200, self.res404 = _responses(self.req, [200, 404])
|
||||
|
|
@ -173,7 +171,7 @@ class TestHttpErrorMiddlewareHandleAll(TestCase):
|
|||
self.assertIsNone(mw.process_spider_input(res402, self.spider))
|
||||
|
||||
|
||||
class TestHttpErrorMiddlewareIntegrational(TestCase):
|
||||
class TestHttpErrorMiddlewareIntegrational(TrialTestCase):
|
||||
def setUp(self):
|
||||
self.mockserver = MockServer()
|
||||
self.mockserver.__enter__()
|
||||
|
|
|
|||
|
|
@ -1,21 +1,17 @@
|
|||
import warnings
|
||||
from unittest import TestCase
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from twisted.internet.defer import inlineCallbacks
|
||||
from twisted.trial import unittest
|
||||
|
||||
from scrapy.http import Request, Response
|
||||
from scrapy.spidermiddlewares.offsite import OffsiteMiddleware, PortWarning, URLWarning
|
||||
from scrapy.spiders import Spider
|
||||
from scrapy.utils.test import get_crawler
|
||||
|
||||
|
||||
class TestOffsiteMiddleware(unittest.TestCase):
|
||||
@inlineCallbacks
|
||||
class TestOffsiteMiddleware(TestCase):
|
||||
def setUp(self):
|
||||
crawler = get_crawler(Spider)
|
||||
yield crawler.crawl(**self._get_spiderargs())
|
||||
self.spider = crawler.spider
|
||||
self.spider = crawler._create_spider(**self._get_spiderargs())
|
||||
self.mw = OffsiteMiddleware.from_crawler(crawler)
|
||||
self.mw.spider_opened(self.spider)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +1,21 @@
|
|||
from unittest import TestCase
|
||||
|
||||
from testfixtures import LogCapture
|
||||
from twisted.internet.defer import inlineCallbacks
|
||||
from twisted.trial import unittest
|
||||
|
||||
from scrapy.http import Request, Response
|
||||
from scrapy.settings import Settings
|
||||
from scrapy.spidermiddlewares.urllength import UrlLengthMiddleware
|
||||
from scrapy.spiders import Spider
|
||||
from scrapy.utils.test import get_crawler
|
||||
from tests.spiders import NoRequestsSpider
|
||||
|
||||
|
||||
class TestUrlLengthMiddleware(unittest.TestCase):
|
||||
@inlineCallbacks
|
||||
class TestUrlLengthMiddleware(TestCase):
|
||||
def setUp(self):
|
||||
self.maxlength = 25
|
||||
settings = Settings({"URLLENGTH_LIMIT": self.maxlength})
|
||||
|
||||
crawler = get_crawler(NoRequestsSpider)
|
||||
yield crawler.crawl()
|
||||
self.spider = crawler.spider
|
||||
crawler = get_crawler(Spider)
|
||||
self.spider = crawler._create_spider("foo")
|
||||
self.stats = crawler.stats
|
||||
self.mw = UrlLengthMiddleware.from_settings(settings)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
import logging
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from testfixtures import LogCapture
|
||||
from twisted.internet.defer import inlineCallbacks
|
||||
from twisted.python.failure import Failure
|
||||
from twisted.trial import unittest
|
||||
|
||||
from scrapy.extensions import telnet
|
||||
from scrapy.utils.log import (
|
||||
|
|
@ -14,7 +13,6 @@ from scrapy.utils.log import (
|
|||
failure_to_exc_info,
|
||||
)
|
||||
from scrapy.utils.test import get_crawler
|
||||
from tests.spiders import NoRequestsSpider
|
||||
|
||||
|
||||
class FailureToExcInfoTest(unittest.TestCase):
|
||||
|
|
@ -62,7 +60,6 @@ class TopLevelFormatterTest(unittest.TestCase):
|
|||
|
||||
|
||||
class LogCounterHandlerTest(unittest.TestCase):
|
||||
@inlineCallbacks
|
||||
def setUp(self):
|
||||
settings = {"LOG_LEVEL": "WARNING"}
|
||||
if not telnet.TWISTED_CONCH_AVAILABLE:
|
||||
|
|
@ -71,8 +68,7 @@ class LogCounterHandlerTest(unittest.TestCase):
|
|||
self.logger = logging.getLogger("test")
|
||||
self.logger.setLevel(logging.NOTSET)
|
||||
self.logger.propagate = False
|
||||
self.crawler = get_crawler(NoRequestsSpider, settings_dict=settings)
|
||||
yield self.crawler.crawl()
|
||||
self.crawler = get_crawler(settings_dict=settings)
|
||||
self.handler = LogCounterHandler(self.crawler)
|
||||
self.logger.addHandler(self.handler)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
import json
|
||||
import unittest
|
||||
import warnings
|
||||
from hashlib import sha1
|
||||
from typing import Dict, Mapping, Optional, Tuple, Union
|
||||
from weakref import WeakKeyDictionary
|
||||
|
||||
import pytest
|
||||
from twisted.internet.defer import inlineCallbacks
|
||||
from twisted.trial import unittest
|
||||
from w3lib.url import canonicalize_url
|
||||
|
||||
from scrapy.http import Request
|
||||
|
|
@ -23,7 +22,6 @@ from scrapy.utils.request import (
|
|||
request_to_curl,
|
||||
)
|
||||
from scrapy.utils.test import get_crawler
|
||||
from tests.spiders import NoRequestsSpider
|
||||
|
||||
|
||||
class UtilsRequestTest(unittest.TestCase):
|
||||
|
|
@ -451,18 +449,15 @@ class BackwardCompatibilityTestCase(unittest.TestCase):
|
|||
)
|
||||
self.assertEqual(fp, old_fp)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_component_backward_compatibility(self):
|
||||
for request_object in REQUEST_OBJECTS_TO_TEST:
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore")
|
||||
crawler = get_crawler(NoRequestsSpider, prevent_warnings=False)
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(prevent_warnings=False)
|
||||
fp = crawler.request_fingerprinter.fingerprint(request_object)
|
||||
old_fp = request_fingerprint_2_6(request_object)
|
||||
self.assertEqual(fp.hex(), old_fp)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_custom_component_backward_compatibility(self):
|
||||
"""Tests that the backward-compatible request fingerprinting class featured
|
||||
in the documentation is indeed backward compatible and does not cause a
|
||||
|
|
@ -485,8 +480,7 @@ class BackwardCompatibilityTestCase(unittest.TestCase):
|
|||
settings = {
|
||||
"REQUEST_FINGERPRINTER_CLASS": RequestFingerprinter,
|
||||
}
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=settings)
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(settings_dict=settings)
|
||||
fp = crawler.request_fingerprinter.fingerprint(request_object)
|
||||
old_fp = request_fingerprint_2_6(request_object)
|
||||
self.assertEqual(fp.hex(), old_fp)
|
||||
|
|
@ -494,11 +488,9 @@ class BackwardCompatibilityTestCase(unittest.TestCase):
|
|||
|
||||
|
||||
class RequestFingerprinterTestCase(unittest.TestCase):
|
||||
@inlineCallbacks
|
||||
def test_default_implementation(self):
|
||||
with warnings.catch_warnings(record=True) as logged_warnings:
|
||||
crawler = get_crawler(NoRequestsSpider, prevent_warnings=False)
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(prevent_warnings=False)
|
||||
request = Request("https://example.com")
|
||||
self.assertEqual(
|
||||
crawler.request_fingerprinter.fingerprint(request),
|
||||
|
|
@ -506,14 +498,12 @@ class RequestFingerprinterTestCase(unittest.TestCase):
|
|||
)
|
||||
self.assertTrue(logged_warnings)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_deprecated_implementation(self):
|
||||
settings = {
|
||||
"REQUEST_FINGERPRINTER_IMPLEMENTATION": "2.6",
|
||||
}
|
||||
with warnings.catch_warnings(record=True) as logged_warnings:
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=settings)
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(settings_dict=settings)
|
||||
request = Request("https://example.com")
|
||||
self.assertEqual(
|
||||
crawler.request_fingerprinter.fingerprint(request),
|
||||
|
|
@ -521,14 +511,12 @@ class RequestFingerprinterTestCase(unittest.TestCase):
|
|||
)
|
||||
self.assertTrue(logged_warnings)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_recommended_implementation(self):
|
||||
settings = {
|
||||
"REQUEST_FINGERPRINTER_IMPLEMENTATION": "2.7",
|
||||
}
|
||||
with warnings.catch_warnings(record=True) as logged_warnings:
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=settings)
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(settings_dict=settings)
|
||||
request = Request("https://example.com")
|
||||
self.assertEqual(
|
||||
crawler.request_fingerprinter.fingerprint(request),
|
||||
|
|
@ -536,18 +524,15 @@ class RequestFingerprinterTestCase(unittest.TestCase):
|
|||
)
|
||||
self.assertFalse(logged_warnings)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_unknown_implementation(self):
|
||||
settings = {
|
||||
"REQUEST_FINGERPRINTER_IMPLEMENTATION": "2.5",
|
||||
}
|
||||
with self.assertRaises(ValueError):
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=settings)
|
||||
yield crawler.crawl()
|
||||
get_crawler(settings_dict=settings)
|
||||
|
||||
|
||||
class CustomRequestFingerprinterTestCase(unittest.TestCase):
|
||||
@inlineCallbacks
|
||||
def test_include_headers(self):
|
||||
class RequestFingerprinter:
|
||||
def fingerprint(self, request):
|
||||
|
|
@ -556,8 +541,7 @@ class CustomRequestFingerprinterTestCase(unittest.TestCase):
|
|||
settings = {
|
||||
"REQUEST_FINGERPRINTER_CLASS": RequestFingerprinter,
|
||||
}
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=settings)
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(settings_dict=settings)
|
||||
|
||||
r1 = Request("http://www.example.com", headers={"X-ID": "1"})
|
||||
fp1 = crawler.request_fingerprinter.fingerprint(r1)
|
||||
|
|
@ -565,7 +549,6 @@ class CustomRequestFingerprinterTestCase(unittest.TestCase):
|
|||
fp2 = crawler.request_fingerprinter.fingerprint(r2)
|
||||
self.assertNotEqual(fp1, fp2)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_dont_canonicalize(self):
|
||||
class RequestFingerprinter:
|
||||
cache = WeakKeyDictionary()
|
||||
|
|
@ -580,8 +563,7 @@ class CustomRequestFingerprinterTestCase(unittest.TestCase):
|
|||
settings = {
|
||||
"REQUEST_FINGERPRINTER_CLASS": RequestFingerprinter,
|
||||
}
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=settings)
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(settings_dict=settings)
|
||||
|
||||
r1 = Request("http://www.example.com?a=1&a=2")
|
||||
fp1 = crawler.request_fingerprinter.fingerprint(r1)
|
||||
|
|
@ -589,7 +571,6 @@ class CustomRequestFingerprinterTestCase(unittest.TestCase):
|
|||
fp2 = crawler.request_fingerprinter.fingerprint(r2)
|
||||
self.assertNotEqual(fp1, fp2)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_meta(self):
|
||||
class RequestFingerprinter:
|
||||
def fingerprint(self, request):
|
||||
|
|
@ -600,8 +581,7 @@ class CustomRequestFingerprinterTestCase(unittest.TestCase):
|
|||
settings = {
|
||||
"REQUEST_FINGERPRINTER_CLASS": RequestFingerprinter,
|
||||
}
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=settings)
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(settings_dict=settings)
|
||||
|
||||
r1 = Request("http://www.example.com")
|
||||
fp1 = crawler.request_fingerprinter.fingerprint(r1)
|
||||
|
|
@ -616,7 +596,6 @@ class CustomRequestFingerprinterTestCase(unittest.TestCase):
|
|||
self.assertNotEqual(fp2, fp4)
|
||||
self.assertEqual(fp2, fp3)
|
||||
|
||||
@inlineCallbacks
|
||||
def test_from_crawler(self):
|
||||
class RequestFingerprinter:
|
||||
@classmethod
|
||||
|
|
@ -633,14 +612,12 @@ class CustomRequestFingerprinterTestCase(unittest.TestCase):
|
|||
"REQUEST_FINGERPRINTER_CLASS": RequestFingerprinter,
|
||||
"FINGERPRINT": b"fingerprint",
|
||||
}
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=settings)
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(settings_dict=settings)
|
||||
|
||||
request = Request("http://www.example.com")
|
||||
fingerprint = crawler.request_fingerprinter.fingerprint(request)
|
||||
self.assertEqual(fingerprint, settings["FINGERPRINT"])
|
||||
|
||||
@inlineCallbacks
|
||||
def test_from_settings(self):
|
||||
class RequestFingerprinter:
|
||||
@classmethod
|
||||
|
|
@ -657,14 +634,12 @@ class CustomRequestFingerprinterTestCase(unittest.TestCase):
|
|||
"REQUEST_FINGERPRINTER_CLASS": RequestFingerprinter,
|
||||
"FINGERPRINT": b"fingerprint",
|
||||
}
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=settings)
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(settings_dict=settings)
|
||||
|
||||
request = Request("http://www.example.com")
|
||||
fingerprint = crawler.request_fingerprinter.fingerprint(request)
|
||||
self.assertEqual(fingerprint, settings["FINGERPRINT"])
|
||||
|
||||
@inlineCallbacks
|
||||
def test_from_crawler_and_settings(self):
|
||||
class RequestFingerprinter:
|
||||
# This method is ignored due to the presence of from_crawler
|
||||
|
|
@ -686,8 +661,7 @@ class CustomRequestFingerprinterTestCase(unittest.TestCase):
|
|||
"REQUEST_FINGERPRINTER_CLASS": RequestFingerprinter,
|
||||
"FINGERPRINT": b"fingerprint",
|
||||
}
|
||||
crawler = get_crawler(NoRequestsSpider, settings_dict=settings)
|
||||
yield crawler.crawl()
|
||||
crawler = get_crawler(settings_dict=settings)
|
||||
|
||||
request = Request("http://www.example.com")
|
||||
fingerprint = crawler.request_fingerprinter.fingerprint(request)
|
||||
|
|
@ -754,3 +728,7 @@ class RequestToCurlTest(unittest.TestCase):
|
|||
" --data-raw '{\"foo\": \"bar\"}' --cookie 'foo=bar'"
|
||||
)
|
||||
self._test_request(request_object, expected_curl_command)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
|||
Loading…
Reference in New Issue