Page MenuHomeSoftware Heritage

swh-search tests are hanging since elasticsearch 7.16 release
Closed, MigratedEdits Locked

Description

The swh-environement/tests Jenkins job timeouts since a couple of days due to swh-search tests hanging.

This seems related to the new elasticsearch 7.16 release.

Below is the stack trace obtained locally using elasticsearch 7.16.1:

(swh) ✘-INT ~/swh/swh-environment/swh-search [master|⚑ 4] 
14:32 $ pytest -sv --full-trace
============================================================================================== test session starts ===============================================================================================
platform linux -- Python 3.9.2, pytest-6.2.5, py-1.10.0, pluggy-1.0.0 -- /home/anlambert/.virtualenvs/swh/bin/python
cachedir: .pytest_cache
hypothesis profile 'default' -> database=DirectoryBasedExampleDatabase('/home/anlambert/swh/swh-environment/swh-search/.hypothesis/examples')
rootdir: /home/anlambert/swh/swh-environment/swh-search, configfile: pytest.ini
plugins: mock-3.6.1, flask-1.2.0, django-4.5.0, cov-3.0.0, requests-mock-1.9.3, xdist-2.4.0, redis-2.1.1, dash-2.0.0, forked-1.3.0, asyncio-0.15.1, postgresql-2.6.1, django-test-migrations-1.1.0, hypothesis-6.27.1, swh.core-0.15.2.dev0+g8edcb95.d20211125, swh.journal-0.9.2.dev1+gbac6b47
collected 173 items                                                                                                                                                                                              

swh/search/tests/test_api_client.py::TestRemoteSearch::test_filter_keyword_in_filter 14:32:42.689 [main] ERROR org.elasticsearch.bootstrap.ElasticsearchUncaughtExceptionHandler - uncaught exception in thread [main]
org.elasticsearch.bootstrap.StartupException: java.lang.NullPointerException: LIBFFI_TMPDIR environment variable was not specified
        at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:170) ~[elasticsearch-7.16.1.jar:7.16.1]
        at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:157) ~[elasticsearch-7.16.1.jar:7.16.1]
        at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:77) ~[elasticsearch-7.16.1.jar:7.16.1]
        at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:112) ~[elasticsearch-cli-7.16.1.jar:7.16.1]
        at org.elasticsearch.cli.Command.main(Command.java:77) ~[elasticsearch-cli-7.16.1.jar:7.16.1]
        at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:122) ~[elasticsearch-7.16.1.jar:7.16.1]
        at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:80) ~[elasticsearch-7.16.1.jar:7.16.1]
Caused by: java.lang.NullPointerException: LIBFFI_TMPDIR environment variable was not specified
        at org.elasticsearch.env.Environment.validateTemporaryDirectory(Environment.java:340) ~[elasticsearch-7.16.1.jar:7.16.1]
        at org.elasticsearch.env.Environment.validateNativesConfig(Environment.java:334) ~[elasticsearch-7.16.1.jar:7.16.1]
        at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:179) ~[elasticsearch-7.16.1.jar:7.16.1]
        at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:434) ~[elasticsearch-7.16.1.jar:7.16.1]
        at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:166) ~[elasticsearch-7.16.1.jar:7.16.1]
        ... 6 more
uncaught exception in thread [main]
java.lang.NullPointerException: LIBFFI_TMPDIR environment variable was not specified
        at org.elasticsearch.env.Environment.validateTemporaryDirectory(Environment.java:340)
        at org.elasticsearch.env.Environment.validateNativesConfig(Environment.java:334)
        at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:179)
        at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:434)
        at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:166)
        at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:157)
        at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:77)
        at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:112)
        at org.elasticsearch.cli.Command.main(Command.java:77)
        at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:122)
        at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:80)
For complete error details, refer to the log at /tmp/pytest-of-anlambert/pytest-2/elasticsearch0/logs/elasticsearch.log
2021-12-13 13:32:43,011472 UTC [1659887] INFO  Main.cc@111 Parent process died - ML controller exiting
^C

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! KeyboardInterrupt !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

addr = '127.0.0.1', port = 42351

    def wait_for_peer(addr, port):
        while True:
            try:
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>               sock.connect((addr, port))
E               ConnectionRefusedError: [Errno 111] Connection refused

swh/search/tests/conftest.py:31: ConnectionRefusedError

During handling of the above exception, another exception occurred:

config = <_pytest.config.Config object at 0x7fc66e861ee0>, doit = <function _main at 0x7fc66eaa1040>

    def wrap_session(
        config: Config, doit: Callable[[Config, "Session"], Optional[Union[int, ExitCode]]]
    ) -> Union[int, ExitCode]:
        """Skeleton command line program."""
        session = Session.from_config(config)
        session.exitstatus = ExitCode.OK
        initstate = 0
        try:
            try:
                config._do_configure()
                initstate = 1
                config.hook.pytest_sessionstart(session=session)
                initstate = 2
>               session.exitstatus = doit(config, session) or 0

../../../.virtualenvs/swh/lib/python3.9/site-packages/_pytest/main.py:269: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

config = <_pytest.config.Config object at 0x7fc66e861ee0>, session = <Session swh-search exitstatus=<ExitCode.OK: 0> testsfailed=0 testscollected=173>

    def _main(config: Config, session: "Session") -> Optional[Union[int, ExitCode]]:
        """Default command line protocol for initialization, session,
        running tests and reporting."""
        config.hook.pytest_collection(session=session)
>       config.hook.pytest_runtestloop(session=session)

../../../.virtualenvs/swh/lib/python3.9/site-packages/_pytest/main.py:323: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <_HookCaller 'pytest_runtestloop'>, args = (), kwargs = {'session': <Session swh-search exitstatus=<ExitCode.OK: 0> testsfailed=0 testscollected=173>}, argname = 'session', firstresult = True

    def __call__(self, *args, **kwargs):
        if args:
            raise TypeError("hook calling supports only keyword arguments")
        assert not self.is_historic()
    
        # This is written to avoid expensive operations when not needed.
        if self.spec:
            for argname in self.spec.argnames:
                if argname not in kwargs:
                    notincall = tuple(set(self.spec.argnames) - kwargs.keys())
                    warnings.warn(
                        "Argument(s) {} which are declared in the hookspec "
                        "can not be found in this hook call".format(notincall),
                        stacklevel=2,
                    )
                    break
    
            firstresult = self.spec.opts.get("firstresult")
        else:
            firstresult = False
    
>       return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)

../../../.virtualenvs/swh/lib/python3.9/site-packages/pluggy/_hooks.py:265: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <_pytest.config.PytestPluginManager object at 0x7fc66e928940>, hook_name = 'pytest_runtestloop'
methods = [<HookImpl plugin_name='main', plugin=<module '_pytest.main' from '/home/anlambert/.virtualenvs/swh/lib/python3.9/site...t/main.py'>>, <HookImpl plugin_name='logging-plugin', plugin=<_pytest.logging.LoggingPlugin object at 0x7fc66e7557f0>>]
kwargs = {'session': <Session swh-search exitstatus=<ExitCode.OK: 0> testsfailed=0 testscollected=173>}, firstresult = True

    def _hookexec(self, hook_name, methods, kwargs, firstresult):
        # called from all hookcaller instances.
        # enable_tracing will set its own wrapping function at self._inner_hookexec
>       return self._inner_hookexec(hook_name, methods, kwargs, firstresult)

../../../.virtualenvs/swh/lib/python3.9/site-packages/pluggy/_manager.py:80: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

session = <Session swh-search exitstatus=<ExitCode.OK: 0> testsfailed=0 testscollected=173>

    def pytest_runtestloop(session: "Session") -> bool:
        if session.testsfailed and not session.config.option.continue_on_collection_errors:
            raise session.Interrupted(
                "%d error%s during collection"
                % (session.testsfailed, "s" if session.testsfailed != 1 else "")
            )
    
        if session.config.option.collectonly:
            return True
    
        for i, item in enumerate(session.items):
            nextitem = session.items[i + 1] if i + 1 < len(session.items) else None
>           item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem)

../../../.virtualenvs/swh/lib/python3.9/site-packages/_pytest/main.py:348: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <_HookCaller 'pytest_runtest_protocol'>, args = (), kwargs = {'item': <TestCaseFunction test_filter_keyword_in_filter>, 'nextitem': <TestCaseFunction test_journal_client_origin_visit_status_permutation>}
argname = 'nextitem', firstresult = True

    def __call__(self, *args, **kwargs):
        if args:
            raise TypeError("hook calling supports only keyword arguments")
        assert not self.is_historic()
    
        # This is written to avoid expensive operations when not needed.
        if self.spec:
            for argname in self.spec.argnames:
                if argname not in kwargs:
                    notincall = tuple(set(self.spec.argnames) - kwargs.keys())
                    warnings.warn(
                        "Argument(s) {} which are declared in the hookspec "
                        "can not be found in this hook call".format(notincall),
                        stacklevel=2,
                    )
                    break
    
            firstresult = self.spec.opts.get("firstresult")
        else:
            firstresult = False
    
>       return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)

../../../.virtualenvs/swh/lib/python3.9/site-packages/pluggy/_hooks.py:265: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <_pytest.config.PytestPluginManager object at 0x7fc66e928940>, hook_name = 'pytest_runtest_protocol'
methods = [<HookImpl plugin_name='runner', plugin=<module '_pytest.runner' from '/home/anlambert/.virtualenvs/swh/lib/python3.9/...n=<module '_pytest.warnings' from '/home/anlambert/.virtualenvs/swh/lib/python3.9/site-packages/_pytest/warnings.py'>>]
kwargs = {'item': <TestCaseFunction test_filter_keyword_in_filter>, 'nextitem': <TestCaseFunction test_journal_client_origin_visit_status_permutation>}, firstresult = True

    def _hookexec(self, hook_name, methods, kwargs, firstresult):
        # called from all hookcaller instances.
        # enable_tracing will set its own wrapping function at self._inner_hookexec
>       return self._inner_hookexec(hook_name, methods, kwargs, firstresult)

../../../.virtualenvs/swh/lib/python3.9/site-packages/pluggy/_manager.py:80: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

item = <TestCaseFunction test_filter_keyword_in_filter>, nextitem = <TestCaseFunction test_journal_client_origin_visit_status_permutation>

    def pytest_runtest_protocol(item: Item, nextitem: Optional[Item]) -> bool:
        ihook = item.ihook
        ihook.pytest_runtest_logstart(nodeid=item.nodeid, location=item.location)
>       runtestprotocol(item, nextitem=nextitem)

../../../.virtualenvs/swh/lib/python3.9/site-packages/_pytest/runner.py:109: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

item = <TestCaseFunction test_filter_keyword_in_filter>, log = True, nextitem = <TestCaseFunction test_journal_client_origin_visit_status_permutation>

    def runtestprotocol(
        item: Item, log: bool = True, nextitem: Optional[Item] = None
    ) -> List[TestReport]:
        hasrequest = hasattr(item, "_request")
        if hasrequest and not item._request:  # type: ignore[attr-defined]
            item._initrequest()  # type: ignore[attr-defined]
>       rep = call_and_report(item, "setup", log)

../../../.virtualenvs/swh/lib/python3.9/site-packages/_pytest/runner.py:120: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

item = <TestCaseFunction test_filter_keyword_in_filter>, when = 'setup', log = True, kwds = {}

    def call_and_report(
        item: Item, when: "Literal['setup', 'call', 'teardown']", log: bool = True, **kwds
    ) -> TestReport:
>       call = call_runtest_hook(item, when, **kwds)

../../../.virtualenvs/swh/lib/python3.9/site-packages/_pytest/runner.py:215: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

item = <TestCaseFunction test_filter_keyword_in_filter>, when = 'setup', kwds = {}, reraise = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>)

    def call_runtest_hook(
        item: Item, when: "Literal['setup', 'call', 'teardown']", **kwds
    ) -> "CallInfo[None]":
        if when == "setup":
            ihook: Callable[..., None] = item.ihook.pytest_runtest_setup
        elif when == "call":
            ihook = item.ihook.pytest_runtest_call
        elif when == "teardown":
            ihook = item.ihook.pytest_runtest_teardown
        else:
            assert False, f"Unhandled runtest hook case: {when}"
        reraise: Tuple[Type[BaseException], ...] = (Exit,)
        if not item.config.getoption("usepdb", False):
            reraise += (KeyboardInterrupt,)
>       return CallInfo.from_call(
            lambda: ihook(item=item, **kwds), when=when, reraise=reraise
        )

../../../.virtualenvs/swh/lib/python3.9/site-packages/_pytest/runner.py:254: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

cls = <class '_pytest.runner.CallInfo'>, func = <function call_runtest_hook.<locals>.<lambda> at 0x7fc668fbcf70>, when = 'setup', reraise = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>)

    @classmethod
    def from_call(
        cls,
        func: "Callable[[], TResult]",
        when: "Literal['collect', 'setup', 'call', 'teardown']",
        reraise: Optional[
            Union[Type[BaseException], Tuple[Type[BaseException], ...]]
        ] = None,
    ) -> "CallInfo[TResult]":
        excinfo = None
        start = timing.time()
        precise_start = timing.perf_counter()
        try:
>           result: Optional[TResult] = func()

../../../.virtualenvs/swh/lib/python3.9/site-packages/_pytest/runner.py:311: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

>       lambda: ihook(item=item, **kwds), when=when, reraise=reraise
    )

../../../.virtualenvs/swh/lib/python3.9/site-packages/_pytest/runner.py:255: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <_HookCaller 'pytest_runtest_setup'>, args = (), kwargs = {'item': <TestCaseFunction test_filter_keyword_in_filter>}, argname = 'item', firstresult = False

    def __call__(self, *args, **kwargs):
        if args:
            raise TypeError("hook calling supports only keyword arguments")
        assert not self.is_historic()
    
        # This is written to avoid expensive operations when not needed.
        if self.spec:
            for argname in self.spec.argnames:
                if argname not in kwargs:
                    notincall = tuple(set(self.spec.argnames) - kwargs.keys())
                    warnings.warn(
                        "Argument(s) {} which are declared in the hookspec "
                        "can not be found in this hook call".format(notincall),
                        stacklevel=2,
                    )
                    break
    
            firstresult = self.spec.opts.get("firstresult")
        else:
            firstresult = False
    
>       return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)

../../../.virtualenvs/swh/lib/python3.9/site-packages/pluggy/_hooks.py:265: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <_pytest.config.PytestPluginManager object at 0x7fc66e928940>, hook_name = 'pytest_runtest_setup'
methods = [<HookImpl plugin_name='nose', plugin=<module '_pytest.nose' from '/home/anlambert/.virtualenvs/swh/lib/python3.9/site... plugin_name='capturemanager', plugin=<CaptureManager _method='no' _global_capturing=None _capture_fixture=None>>, ...]
kwargs = {'item': <TestCaseFunction test_filter_keyword_in_filter>}, firstresult = False

    def _hookexec(self, hook_name, methods, kwargs, firstresult):
        # called from all hookcaller instances.
        # enable_tracing will set its own wrapping function at self._inner_hookexec
>       return self._inner_hookexec(hook_name, methods, kwargs, firstresult)

../../../.virtualenvs/swh/lib/python3.9/site-packages/pluggy/_manager.py:80: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

item = <TestCaseFunction test_filter_keyword_in_filter>

    def pytest_runtest_setup(item: Item) -> None:
        _update_current_test_var(item, "setup")
>       item.session._setupstate.prepare(item)

../../../.virtualenvs/swh/lib/python3.9/site-packages/_pytest/runner.py:150: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <_pytest.runner.SetupState object at 0x7fc66aa53040>, colitem = <TestCaseFunction test_filter_keyword_in_filter>

    def prepare(self, colitem) -> None:
        """Setup objects along the collector chain to the test-method."""
    
        # Check if the last collection node has raised an error.
        for col in self.stack:
            if hasattr(col, "_prepare_exc"):
                exc = col._prepare_exc  # type: ignore[attr-defined]
                raise exc
    
        needed_collectors = colitem.listchain()
        for col in needed_collectors[len(self.stack) :]:
            self.stack.append(col)
            try:
>               col.setup()

../../../.virtualenvs/swh/lib/python3.9/site-packages/_pytest/runner.py:449: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <TestCaseFunction test_filter_keyword_in_filter>

    def setup(self) -> None:
        # A bound method to be called during teardown() if set (see 'runtest()').
        self._explicit_tearDown: Optional[Callable[[], None]] = None
        assert self.parent is not None
        self._testcase = self.parent.obj(self.name)  # type: ignore[attr-defined]
        self._obj = getattr(self._testcase, self.name)
        if hasattr(self, "_request"):
>           self._request._fillfixtures()

../../../.virtualenvs/swh/lib/python3.9/site-packages/_pytest/unittest.py:197: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <FixtureRequest for <TestCaseFunction test_filter_keyword_in_filter>>

    def _fillfixtures(self) -> None:
        item = self._pyfuncitem
        fixturenames = getattr(item, "fixturenames", self.fixturenames)
        for argname in fixturenames:
            if argname not in item.funcargs:
>               item.funcargs[argname] = self.getfixturevalue(argname)

../../../.virtualenvs/swh/lib/python3.9/site-packages/_pytest/fixtures.py:568: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <FixtureRequest for <TestCaseFunction test_filter_keyword_in_filter>>, argname = 'elasticsearch_session'

    def getfixturevalue(self, argname: str) -> Any:
        """Dynamically run a named fixture function.
    
        Declaring fixtures via function argument is recommended where possible.
        But if you can only decide whether to use another fixture at test
        setup time, you may use this function to retrieve it inside a fixture
        or test function body.
    
        :raises pytest.FixtureLookupError:
            If the given fixture could not be found.
        """
>       fixturedef = self._get_active_fixturedef(argname)

../../../.virtualenvs/swh/lib/python3.9/site-packages/_pytest/fixtures.py:581: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <FixtureRequest for <TestCaseFunction test_filter_keyword_in_filter>>, argname = 'elasticsearch_session'

    def _get_active_fixturedef(
        self, argname: str
    ) -> Union["FixtureDef[object]", PseudoFixtureDef[object]]:
        try:
            return self._fixture_defs[argname]
        except KeyError:
            try:
                fixturedef = self._getnextfixturedef(argname)
            except FixtureLookupError:
                if argname == "request":
                    cached_result = (self, [0], None)
                    scope: _Scope = "function"
                    return PseudoFixtureDef(cached_result, scope)
                raise
        # Remove indent to prevent the python3 exception
        # from leaking into the call.
>       self._compute_fixture_value(fixturedef)

../../../.virtualenvs/swh/lib/python3.9/site-packages/_pytest/fixtures.py:601: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <FixtureRequest for <TestCaseFunction test_filter_keyword_in_filter>>, fixturedef = <FixtureDef argname='elasticsearch_session' scope='session' baseid='swh/search/tests'>

    def _compute_fixture_value(self, fixturedef: "FixtureDef[object]") -> None:
        """Create a SubRequest based on "self" and call the execute method
        of the given FixtureDef object.
    
        This will force the FixtureDef object to throw away any previous
        results and compute a new fixture value, which will be stored into
        the FixtureDef object itself.
        """
        # prepare a subrequest object before calling fixture function
        # (latter managed by fixturedef)
        argname = fixturedef.argname
        funcitem = self._pyfuncitem
        scope = fixturedef.scope
        try:
            param = funcitem.callspec.getparam(argname)
        except (AttributeError, ValueError):
            param = NOTSET
            param_index = 0
            has_params = fixturedef.params is not None
            fixtures_not_supported = getattr(funcitem, "nofuncargs", False)
            if has_params and fixtures_not_supported:
                msg = (
                    "{name} does not support fixtures, maybe unittest.TestCase subclass?\n"
                    "Node id: {nodeid}\n"
                    "Function type: {typename}"
                ).format(
                    name=funcitem.name,
                    nodeid=funcitem.nodeid,
                    typename=type(funcitem).__name__,
                )
                fail(msg, pytrace=False)
            if has_params:
                frame = inspect.stack()[3]
                frameinfo = inspect.getframeinfo(frame[0])
                source_path = py.path.local(frameinfo.filename)
                source_lineno = frameinfo.lineno
                rel_source_path = source_path.relto(funcitem.config.rootdir)
                if rel_source_path:
                    source_path_str = rel_source_path
                else:
                    source_path_str = str(source_path)
                msg = (
                    "The requested fixture has no parameter defined for test:\n"
                    "    {}\n\n"
                    "Requested fixture '{}' defined in:\n{}"
                    "\n\nRequested here:\n{}:{}".format(
                        funcitem.nodeid,
                        fixturedef.argname,
                        getlocation(fixturedef.func, funcitem.config.rootdir),
                        source_path_str,
                        source_lineno,
                    )
                )
                fail(msg, pytrace=False)
        else:
            param_index = funcitem.callspec.indices[argname]
            # If a parametrize invocation set a scope it will override
            # the static scope defined with the fixture function.
            paramscopenum = funcitem.callspec._arg2scopenum.get(argname)
            if paramscopenum is not None:
                scope = scopes[paramscopenum]
    
        subrequest = SubRequest(
            self, scope, param, param_index, fixturedef, _ispytest=True
        )
    
        # Check if a higher-level scoped fixture accesses a lower level one.
        subrequest._check_scope(argname, self.scope, scope)
        try:
            # Call the fixture function.
>           fixturedef.execute(request=subrequest)

../../../.virtualenvs/swh/lib/python3.9/site-packages/_pytest/fixtures.py:687: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <FixtureDef argname='elasticsearch_session' scope='session' baseid='swh/search/tests'>, request = <SubRequest 'elasticsearch_session' for <TestCaseFunction test_filter_keyword_in_filter>>

    def execute(self, request: SubRequest) -> _FixtureValue:
        # Get required arguments and register our own finish()
        # with their finalization.
        for argname in self.argnames:
            fixturedef = request._get_active_fixturedef(argname)
            if argname != "request":
                # PseudoFixtureDef is only for "request".
                assert isinstance(fixturedef, FixtureDef)
                fixturedef.addfinalizer(functools.partial(self.finish, request=request))
    
        my_cache_key = self.cache_key(request)
        if self.cached_result is not None:
            # note: comparison with `==` can fail (or be expensive) for e.g.
            # numpy arrays (#6497).
            cache_key = self.cached_result[1]
            if my_cache_key is cache_key:
                if self.cached_result[2] is not None:
                    _, val, tb = self.cached_result[2]
                    raise val.with_traceback(tb)
                else:
                    result = self.cached_result[0]
                    return result
            # We have a previous but differently parametrized fixture instance
            # so we need to tear it down before creating a new one.
            self.finish(request)
            assert self.cached_result is None
    
        hook = self._fixturemanager.session.gethookproxy(request.node.fspath)
>       result = hook.pytest_fixture_setup(fixturedef=self, request=request)

../../../.virtualenvs/swh/lib/python3.9/site-packages/_pytest/fixtures.py:1072: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <_HookCaller 'pytest_fixture_setup'>, args = ()
kwargs = {'fixturedef': <FixtureDef argname='elasticsearch_session' scope='session' baseid='swh/search/tests'>, 'request': <SubRequest 'elasticsearch_session' for <TestCaseFunction test_filter_keyword_in_filter>>}
argname = 'request', firstresult = True

    def __call__(self, *args, **kwargs):
        if args:
            raise TypeError("hook calling supports only keyword arguments")
        assert not self.is_historic()
    
        # This is written to avoid expensive operations when not needed.
        if self.spec:
            for argname in self.spec.argnames:
                if argname not in kwargs:
                    notincall = tuple(set(self.spec.argnames) - kwargs.keys())
                    warnings.warn(
                        "Argument(s) {} which are declared in the hookspec "
                        "can not be found in this hook call".format(notincall),
                        stacklevel=2,
                    )
                    break
    
            firstresult = self.spec.opts.get("firstresult")
        else:
            firstresult = False
    
>       return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)

../../../.virtualenvs/swh/lib/python3.9/site-packages/pluggy/_hooks.py:265: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <_pytest.config.PytestPluginManager object at 0x7fc66e928940>, hook_name = 'pytest_fixture_setup'
methods = [<HookImpl plugin_name='fixtures', plugin=<module '_pytest.fixtures' from '/home/anlambert/.virtualenvs/swh/lib/python...'pytest_asyncio.plugin' from '/home/anlambert/.virtualenvs/swh/lib/python3.9/site-packages/pytest_asyncio/plugin.py'>>]
kwargs = {'fixturedef': <FixtureDef argname='elasticsearch_session' scope='session' baseid='swh/search/tests'>, 'request': <SubRequest 'elasticsearch_session' for <TestCaseFunction test_filter_keyword_in_filter>>}
firstresult = True

    def _hookexec(self, hook_name, methods, kwargs, firstresult):
        # called from all hookcaller instances.
        # enable_tracing will set its own wrapping function at self._inner_hookexec
>       return self._inner_hookexec(hook_name, methods, kwargs, firstresult)

../../../.virtualenvs/swh/lib/python3.9/site-packages/pluggy/_manager.py:80: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

fixturedef = <FixtureDef argname='elasticsearch_session' scope='session' baseid='swh/search/tests'>, request = <SubRequest 'elasticsearch_session' for <TestCaseFunction test_filter_keyword_in_filter>>

    def pytest_fixture_setup(
        fixturedef: FixtureDef[_FixtureValue], request: SubRequest
    ) -> _FixtureValue:
        """Execution of fixture setup."""
        kwargs = {}
        for argname in fixturedef.argnames:
            fixdef = request._get_active_fixturedef(argname)
            assert fixdef.cached_result is not None
            result, arg_cache_key, exc = fixdef.cached_result
            request._check_scope(argname, request.scope, fixdef.scope)
            kwargs[argname] = result
    
        fixturefunc = resolve_fixture_function(fixturedef, request)
        my_cache_key = fixturedef.cache_key(request)
        try:
>           result = call_fixture_func(fixturefunc, request, kwargs)

../../../.virtualenvs/swh/lib/python3.9/site-packages/_pytest/fixtures.py:1126: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

fixturefunc = <function elasticsearch_session at 0x7fc66a8a8280>, request = <SubRequest 'elasticsearch_session' for <TestCaseFunction test_filter_keyword_in_filter>>
kwargs = {'tmpdir_factory': TempdirFactory(_tmppath_factory=TempPathFactory(_given_basetemp=None, _trace=<pluggy._tracing.TagTracerSub object at 0x7fc66e7780d0>, _basetemp=PosixPath('/tmp/pytest-of-anlambert/pytest-2')))}

    def call_fixture_func(
        fixturefunc: "_FixtureFunc[_FixtureValue]", request: FixtureRequest, kwargs
    ) -> _FixtureValue:
        if is_generator(fixturefunc):
            fixturefunc = cast(
                Callable[..., Generator[_FixtureValue, None, None]], fixturefunc
            )
            generator = fixturefunc(**kwargs)
            try:
>               fixture_result = next(generator)

../../../.virtualenvs/swh/lib/python3.9/site-packages/_pytest/fixtures.py:925: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

tmpdir_factory = TempdirFactory(_tmppath_factory=TempPathFactory(_given_basetemp=None, _trace=<pluggy._tracing.TagTracerSub object at 0x7fc66e7780d0>, _basetemp=PosixPath('/tmp/pytest-of-anlambert/pytest-2')))

    @pytest.fixture(scope="session")
    def elasticsearch_session(tmpdir_factory):
        tmpdir = tmpdir_factory.mktemp("elasticsearch")
        es_conf = tmpdir.mkdir("conf")
    
        http_port = free_port()
        transport_port = free_port()
    
>       p = _run_elasticsearch(
            conf_dir=str(es_conf),
            data_dir=str(tmpdir.mkdir("data")),
            logs_dir=str(tmpdir.mkdir("logs")),
            http_port=http_port,
            transport_port=transport_port,
        )

swh/search/tests/conftest.py:97: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

conf_dir = '/tmp/pytest-of-anlambert/pytest-2/elasticsearch0/conf', data_dir = '/tmp/pytest-of-anlambert/pytest-2/elasticsearch0/data', logs_dir = '/tmp/pytest-of-anlambert/pytest-2/elasticsearch0/logs'
http_port = 42351, transport_port = 45249

    def _run_elasticsearch(conf_dir, data_dir, logs_dir, http_port, transport_port):
        es_home = "/usr/share/elasticsearch"
    
        with open(conf_dir + "/elasticsearch.yml", "w") as fd:
            fd.write(
                CONFIG_TEMPLATE.format(
                    data=data_dir,
                    logs=logs_dir,
                    http_port=http_port,
                    transport_port=transport_port,
                )
            )
    
        with open(conf_dir + "/log4j2.properties", "w") as fd:
            pass
    
        cmd = [
            "/usr/share/elasticsearch/jdk/bin/java",
            "-Des.path.home={}".format(es_home),
            "-Des.path.conf={}".format(conf_dir),
            "-Des.bundled_jdk=true",
            "-Dlog4j2.disable.jmx=true",
            "-cp",
            "{}/lib/*".format(es_home),
            "org.elasticsearch.bootstrap.Elasticsearch",
        ]
    
        host = "127.0.0.1:{}".format(http_port)
    
        with open(logs_dir + "/output.txt", "w") as fd:
            p = subprocess.Popen(cmd)
    
>       wait_for_peer("127.0.0.1", http_port)

swh/search/tests/conftest.py:81: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

addr = '127.0.0.1', port = 42351

    def wait_for_peer(addr, port):
        while True:
            try:
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.connect((addr, port))
            except ConnectionRefusedError:
>               time.sleep(0.1)
E               KeyboardInterrupt

swh/search/tests/conftest.py:33: KeyboardInterrupt

Event Timeline

anlambert triaged this task as Normal priority.Dec 13 2021, 2:42 PM
anlambert created this task.

If not defined, this variable is set by the elasticsearch launch script https://github.com/elastic/elasticsearch/pull/80699/files#diff-ddfc3a6ea1404997e56f2e771adede06b173f0fea37b4779d827c85d6cc52897R35
I guess as the fixture is not starting elasticsearch[1] throught the startup script, the variable is not defined

[1] https://forge.softwareheritage.org/source/swh-search/browse/master/swh/search/tests/conftest.py$65

Explicitly setting the LIBFFI_TMPDIR environment variable indeed fixes the hang: D6828.