Source code for tools.lib.tests.test_caching

#!/usr/bin/env python3
from functools import partial
import http.server
import os
import shutil
import socket
import unittest

from parameterized import parameterized
from openpilot.selfdrive.test.helpers import with_http_server
from openpilot.system.hardware.hw import Paths
from openpilot.tools.lib.url_file import URLFile


[docs] class CachingTestRequestHandler(http.server.BaseHTTPRequestHandler): FILE_EXISTS = True
[docs] def do_GET(self): if self.FILE_EXISTS: self.send_response(206 if "Range" in self.headers else 200, b'1234') else: self.send_response(404) self.end_headers()
[docs] def do_HEAD(self): if self.FILE_EXISTS: self.send_response(200) self.send_header("Content-Length", "4") else: self.send_response(404) self.end_headers()
with_caching_server = partial(with_http_server, handler=CachingTestRequestHandler)
[docs] class TestFileDownload(unittest.TestCase):
[docs] @with_caching_server def test_pipeline_defaults(self, host): # TODO: parameterize the defaults so we don't rely on hard-coded values in xx self.assertEqual(URLFile.pool_manager().pools._maxsize, 10) # PoolManager num_pools param pool_manager_defaults = { "maxsize": 100, "socket_options": [(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),], } for k, v in pool_manager_defaults.items(): self.assertEqual(URLFile.pool_manager().connection_pool_kw.get(k), v) retry_defaults = { "total": 5, "backoff_factor": 0.5, "status_forcelist": [409, 429, 503, 504], } for k, v in retry_defaults.items(): self.assertEqual(getattr(URLFile.pool_manager().connection_pool_kw["retries"], k), v) # ensure caching off by default and cache dir doesn't get created os.environ.pop("FILEREADER_CACHE", None) if os.path.exists(Paths.download_cache_root()): shutil.rmtree(Paths.download_cache_root()) URLFile(f"{host}/test.txt").get_length() URLFile(f"{host}/test.txt").read() self.assertEqual(os.path.exists(Paths.download_cache_root()), False)
[docs] def compare_loads(self, url, start=0, length=None): """Compares range between cached and non cached version""" file_cached = URLFile(url, cache=True) file_downloaded = URLFile(url, cache=False) file_cached.seek(start) file_downloaded.seek(start) self.assertEqual(file_cached.get_length(), file_downloaded.get_length()) self.assertLessEqual(length + start if length is not None else 0, file_downloaded.get_length()) response_cached = file_cached.read(ll=length) response_downloaded = file_downloaded.read(ll=length) self.assertEqual(response_cached, response_downloaded) # Now test with cache in place file_cached = URLFile(url, cache=True) file_cached.seek(start) response_cached = file_cached.read(ll=length) self.assertEqual(file_cached.get_length(), file_downloaded.get_length()) self.assertEqual(response_cached, response_downloaded)
[docs] def test_small_file(self): # Make sure we don't force cache os.environ["FILEREADER_CACHE"] = "0" small_file_url = "https://raw.githubusercontent.com/commaai/openpilot/master/docs/SAFETY.md" # If you want large file to be larger than a chunk # large_file_url = "https://commadataci.blob.core.windows.net/openpilotci/0375fdf7b1ce594d/2019-06-13--08-32-25/3/fcamera.hevc" # Load full small file self.compare_loads(small_file_url) file_small = URLFile(small_file_url) length = file_small.get_length() self.compare_loads(small_file_url, length - 100, 100) self.compare_loads(small_file_url, 50, 100) # Load small file 100 bytes at a time for i in range(length // 100): self.compare_loads(small_file_url, 100 * i, 100)
[docs] def test_large_file(self): large_file_url = "https://commadataci.blob.core.windows.net/openpilotci/0375fdf7b1ce594d/2019-06-13--08-32-25/3/qlog.bz2" # Load the end 100 bytes of both files file_large = URLFile(large_file_url) length = file_large.get_length() self.compare_loads(large_file_url, length - 100, 100) self.compare_loads(large_file_url)
@parameterized.expand([(True, ), (False, )]) @with_caching_server def test_recover_from_missing_file(self, cache_enabled, host): os.environ["FILEREADER_CACHE"] = "1" if cache_enabled else "0" file_url = f"{host}/test.png" CachingTestRequestHandler.FILE_EXISTS = False length = URLFile(file_url).get_length() self.assertEqual(length, -1) CachingTestRequestHandler.FILE_EXISTS = True length = URLFile(file_url).get_length() self.assertEqual(length, 4)
if __name__ == "__main__": unittest.main()