test_firmware_server.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import json
  2. import lzma
  3. from pathlib import Path
  4. from unittest.mock import Mock, patch
  5. from metadata_manager import ManifestClient, ManifestIndex
  6. from metadata_manager.firmware_server.client import _CacheMeta
  7. FIXTURES_DIR = Path(__file__).parent / "fixtures"
  8. SAMPLE_MANIFEST = json.loads((FIXTURES_DIR / "manifest_sample.json").read_text())
  9. SAMPLE_JSON_BYTES = json.dumps(SAMPLE_MANIFEST).encode("utf-8")
  10. MANIFEST_XZ_URL = "https://firmware.ardupilot.org/manifest.json.xz"
  11. class TestManifestIndex:
  12. def test_builds_releases_for_copter_heli_and_tracker(self):
  13. index = ManifestIndex.build(SAMPLE_MANIFEST)
  14. copter = index.get_releases("copter")
  15. stable = [r for r in copter if r.release_type == "stable" and r.version_number == "4.6.3"]
  16. assert len(stable) == 1
  17. assert stable[0].commit_reference.startswith("aaaa")
  18. heli = index.get_releases("heli")
  19. heli_stable = [r for r in heli if r.release_type == "stable" and r.version_number == "4.6.3"]
  20. assert len(heli_stable) == 1
  21. assert heli_stable[0].commit_reference.startswith("bbbb")
  22. tracker = index.get_releases("tracker")
  23. assert any(r.version_number == "4.6.3" for r in tracker)
  24. latest = [r for r in copter if r.release_type == "latest"]
  25. assert len(latest) == 1
  26. assert latest[0].commit_reference.startswith("eeee")
  27. assert latest[0].version_number == "NA"
  28. assert latest[0].ap_build_artifacts_url == (
  29. "https://firmware.ardupilot.org/Copter/latest"
  30. )
  31. class TestManifestClientCache:
  32. def test_uses_cache_on_304(self, tmp_path):
  33. client = ManifestClient(
  34. url=MANIFEST_XZ_URL,
  35. cache_dir=str(tmp_path),
  36. )
  37. client._write_cache(
  38. b'{"format-version":"1.0.0","firmware":[]}',
  39. _CacheMeta(etag='"abc"', last_modified="Mon, 01 Jan 2024 00:00:00 GMT"),
  40. )
  41. response = Mock(status_code=304, headers={}, content=b"")
  42. with patch(
  43. "metadata_manager.firmware_server.client.requests.get",
  44. return_value=response,
  45. ) as mock_get:
  46. raw = client.fetch_raw()
  47. assert raw == b'{"format-version":"1.0.0","firmware":[]}'
  48. mock_get.assert_called_once_with(
  49. MANIFEST_XZ_URL,
  50. headers={
  51. "User-Agent": "CustomBuild/1.0",
  52. "If-None-Match": '"abc"',
  53. "If-Modified-Since": "Mon, 01 Jan 2024 00:00:00 GMT",
  54. },
  55. timeout=120,
  56. )
  57. def test_download_decompresses_xz_manifest(self, tmp_path):
  58. client = ManifestClient(
  59. url=MANIFEST_XZ_URL,
  60. cache_dir=str(tmp_path),
  61. )
  62. compressed = lzma.compress(SAMPLE_JSON_BYTES)
  63. response = Mock(
  64. status_code=200,
  65. content=compressed,
  66. headers={
  67. "ETag": '"etag123"',
  68. "Last-Modified": "Mon, 01 Jan 2024 00:00:00 GMT",
  69. },
  70. )
  71. response.raise_for_status = Mock()
  72. with patch(
  73. "metadata_manager.firmware_server.client.requests.get",
  74. return_value=response,
  75. ):
  76. result = client.fetch()
  77. assert result == SAMPLE_MANIFEST
  78. assert client.cache_path.read_bytes() == SAMPLE_JSON_BYTES
  79. meta = _CacheMeta.from_dict(
  80. json.loads(client.meta_path.read_text(encoding="utf-8"))
  81. )
  82. assert meta.etag == '"etag123"'
  83. assert meta.last_modified == "Mon, 01 Jan 2024 00:00:00 GMT"