|
1 | 1 | """Tests for bundled compatibility manifests and data release manifests.""" |
2 | 2 |
|
3 | 3 | import json |
| 4 | +import os |
4 | 5 | import re |
| 6 | +import subprocess |
| 7 | +import sys |
5 | 8 | from pathlib import Path |
6 | 9 | from unittest.mock import MagicMock, patch |
7 | 10 |
|
@@ -316,6 +319,22 @@ def test__given_private_manifest_unavailable__then_bundled_certification_is_used |
316 | 319 |
|
317 | 320 | assert certification == get_release_manifest("us").certification |
318 | 321 |
|
| 322 | + def test__given_manifest_request_timeout__then_bundled_certification_is_used( |
| 323 | + self, |
| 324 | + ): |
| 325 | + get_data_release_manifest.cache_clear() |
| 326 | + |
| 327 | + with patch( |
| 328 | + "policyengine.provenance.manifest.requests.get", |
| 329 | + side_effect=Timeout("network timeout"), |
| 330 | + ): |
| 331 | + certification = certify_data_release_compatibility( |
| 332 | + "us", |
| 333 | + runtime_model_version="1.687.0", |
| 334 | + ) |
| 335 | + |
| 336 | + assert certification == get_release_manifest("us").certification |
| 337 | + |
319 | 338 | def test__given_private_manifest_unavailable_and_fingerprint_mismatch__then_fails( |
320 | 339 | self, |
321 | 340 | ): |
@@ -348,24 +367,68 @@ def test__given_private_manifest_unavailable_and_fingerprint_mismatch__then_fail |
348 | 367 | else: |
349 | 368 | raise AssertionError("Expected fingerprint mismatch to fail") |
350 | 369 |
|
351 | | - def test__given_manifest_fetch_failure__then_certification_does_not_fallback( |
| 370 | + def test__given_manifest_fetch_failure_and_version_mismatch__then_fallback_fails( |
352 | 371 | self, |
353 | 372 | ): |
354 | 373 | get_data_release_manifest.cache_clear() |
355 | 374 |
|
356 | 375 | with patch( |
357 | | - "policyengine.provenance.manifest.get_data_release_manifest", |
| 376 | + "policyengine.provenance.manifest.requests.get", |
358 | 377 | side_effect=Timeout("network timeout"), |
359 | 378 | ): |
360 | 379 | try: |
361 | 380 | certify_data_release_compatibility( |
362 | 381 | "us", |
363 | 382 | runtime_model_version="1.602.0", |
364 | 383 | ) |
365 | | - except Timeout as error: |
366 | | - assert "network timeout" in str(error) |
| 384 | + except DataReleaseManifestUnavailableError as error: |
| 385 | + assert "Could not fetch" in str(error) |
367 | 386 | else: |
368 | | - raise AssertionError("Expected timeout to propagate") |
| 387 | + raise AssertionError("Expected offline mismatched version to fail") |
| 388 | + |
| 389 | + def test__given_offline_hf__then_us_import_uses_bundled_certification( |
| 390 | + self, |
| 391 | + tmp_path, |
| 392 | + ): |
| 393 | + sitecustomize = tmp_path / "sitecustomize.py" |
| 394 | + sitecustomize.write_text( |
| 395 | + "\n".join( |
| 396 | + [ |
| 397 | + "import requests", |
| 398 | + "from requests import Timeout", |
| 399 | + "", |
| 400 | + "def offline_get(*args, **kwargs):", |
| 401 | + " raise Timeout('offline')", |
| 402 | + "", |
| 403 | + "requests.get = offline_get", |
| 404 | + ] |
| 405 | + ) |
| 406 | + ) |
| 407 | + env = os.environ.copy() |
| 408 | + existing_pythonpath = env.get("PYTHONPATH") |
| 409 | + env["PYTHONPATH"] = ( |
| 410 | + f"{tmp_path}{os.pathsep}{existing_pythonpath}" |
| 411 | + if existing_pythonpath |
| 412 | + else str(tmp_path) |
| 413 | + ) |
| 414 | + |
| 415 | + result = subprocess.run( |
| 416 | + [ |
| 417 | + sys.executable, |
| 418 | + "-c", |
| 419 | + ( |
| 420 | + "import policyengine.tax_benefit_models.us as us; " |
| 421 | + "print(us.model.data_certification.certified_by)" |
| 422 | + ), |
| 423 | + ], |
| 424 | + capture_output=True, |
| 425 | + text=True, |
| 426 | + check=False, |
| 427 | + env=env, |
| 428 | + ) |
| 429 | + |
| 430 | + assert result.returncode == 0, result.stderr |
| 431 | + assert "policyengine.py bundled manifest" in result.stdout |
369 | 432 |
|
370 | 433 | def test__given_mismatched_version_and_fingerprint__then_certification_fails(self): |
371 | 434 | get_data_release_manifest.cache_clear() |
|
0 commit comments