|
27 | 27 | from tzlocal import get_localzone_name # type: ignore |
28 | 28 |
|
29 | 29 | import trino |
| 30 | +from tests.development_server import get_trino_container |
30 | 31 | from tests.integration.conftest import trino_version |
31 | 32 | from trino import constants |
32 | 33 | from trino.client import InlineSegment |
@@ -1896,7 +1897,7 @@ def test_segments_cursor(trino_connection): |
1896 | 1897 | assert isinstance(segment.segment.ack_uri, str), ( |
1897 | 1898 | f"Expected string for ack_uri, got {type(segment.segment.ack_uri)}" |
1898 | 1899 | ) |
1899 | | - total += len(list(SegmentIterator(segment, row_mapper))) |
| 1900 | + total += len(list(SegmentIterator(segment, row_mapper, cur._query._request))) |
1900 | 1901 | assert total == 300875, f"Expected total rows 300875, got {total}" |
1901 | 1902 |
|
1902 | 1903 |
|
@@ -2000,6 +2001,61 @@ def test_spooled_segments_lazy_description(trino_connection): |
2000 | 2001 | assert len(cur.fetchall()) == 60175 |
2001 | 2002 |
|
2002 | 2003 |
|
| 2004 | +@pytest.mark.skipif( |
| 2005 | + trino_version() <= 466, |
| 2006 | + reason="spooling protocol was introduced in version 466" |
| 2007 | +) |
| 2008 | +def test_heartbeat_head_requests_during_spooled_download(run_trino): |
| 2009 | + """Verify that heartbeat HEAD requests are sent to the coordinator while |
| 2010 | + downloading spooled segments from external storage.""" |
| 2011 | + trino_container = get_trino_container() |
| 2012 | + if trino_container is None: |
| 2013 | + pytest.skip("cannot read Trino HTTP request log (Trino not started by this test session)") |
| 2014 | + |
| 2015 | + host, port = run_trino |
| 2016 | + conn = trino.dbapi.Connection( |
| 2017 | + host=host, port=port, user="test", source="test", |
| 2018 | + max_attempts=1, encoding="json", heartbeat_interval=0.1, |
| 2019 | + ) |
| 2020 | + |
| 2021 | + container = trino_container.get_wrapped_container() |
| 2022 | + log_path = "/data/trino/var/log/http-request.log" |
| 2023 | + |
| 2024 | + # Capture the current size of the HTTP request log |
| 2025 | + exit_code, output = container.exec_run(["wc", "-l", log_path]) |
| 2026 | + if exit_code != 0: |
| 2027 | + pytest.skip("cannot read Trino HTTP request log (log disabled or path changed)") |
| 2028 | + logfile_lines = int(output.decode().split()[0]) |
| 2029 | + |
| 2030 | + cur = conn.cursor() |
| 2031 | + cur.execute("""SELECT l.* |
| 2032 | + FROM tpch.tiny.lineitem l, TABLE(sequence( |
| 2033 | + start => 1, |
| 2034 | + stop => 5, |
| 2035 | + step => 1)) n""") |
| 2036 | + cur.fetchall() |
| 2037 | + cur.close() |
| 2038 | + |
| 2039 | + for try_ in range(10): |
| 2040 | + if try_: |
| 2041 | + # Sometimes trino needs time to flush the logs |
| 2042 | + t.sleep(1.0) |
| 2043 | + |
| 2044 | + _, output = container.exec_run(["tail", "-n", f"+{logfile_lines}", log_path]) |
| 2045 | + loglines = output.decode().splitlines() |
| 2046 | + head_requests = [ |
| 2047 | + line for line in loglines |
| 2048 | + if "HEAD" in line and "/v1/statement/executing/" in line |
| 2049 | + ] |
| 2050 | + if head_requests: |
| 2051 | + break |
| 2052 | + |
| 2053 | + assert head_requests, ( |
| 2054 | + "Expected heartbeat HEAD requests in http-request.log but found none.\n" |
| 2055 | + f"Log tail:\n{''.join(loglines)}" |
| 2056 | + ) |
| 2057 | + |
| 2058 | + |
2003 | 2059 | def get_cursor(legacy_prepared_statements, run_trino): |
2004 | 2060 | host, port = run_trino |
2005 | 2061 |
|
|
0 commit comments