-
Notifications
You must be signed in to change notification settings - Fork 874
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* tweak comments * reduce default timeout as 10 minutes is unrealistic * remove mysql test in test * finish rewrite * use tighter timeout in test * capture timeout errors in ci * make the timeout skip a wrapper * use a conditional timeout * better deprecation handle without breaking * use a formula with only one match
- Loading branch information
1 parent
a28e1da
commit aa9bdbf
Showing
2 changed files
with
106 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,58 @@ | ||
from __future__ import annotations | ||
|
||
import os | ||
from shutil import which | ||
from unittest import TestCase | ||
from functools import wraps | ||
|
||
import pytest | ||
import requests | ||
import urllib3 | ||
|
||
from pymatgen.ext.cod import COD | ||
|
||
if "CI" in os.environ: # test is slow and flaky, skip in CI. see | ||
# https://github.com/materialsproject/pymatgen/pull/3777#issuecomment-2071217785 | ||
pytest.skip(allow_module_level=True, reason="Skip COD test in CI") | ||
# Set a tighter timeout in CI | ||
TIMEOUT = 10 if os.getenv("CI") else 60 | ||
|
||
|
||
try: | ||
WEBSITE_DOWN = requests.get("https://www.crystallography.net", timeout=60).status_code != 200 | ||
except (requests.exceptions.ConnectionError, urllib3.exceptions.ConnectTimeoutError): | ||
WEBSITE_DOWN = requests.get("https://www.crystallography.net", timeout=TIMEOUT).status_code != 200 | ||
except (requests.exceptions.ConnectionError, requests.exceptions.Timeout, requests.exceptions.ReadTimeout): | ||
WEBSITE_DOWN = True | ||
|
||
if WEBSITE_DOWN: | ||
pytest.skip(reason="www.crystallography.net is down", allow_module_level=True) | ||
|
||
|
||
def skip_on_timeout(func): | ||
"""Skip test in CI when time out.""" | ||
|
||
@wraps(func) | ||
def wrapper(*args, **kwargs): | ||
try: | ||
return func(*args, **kwargs) | ||
except (requests.exceptions.ConnectionError, requests.exceptions.Timeout, requests.exceptions.ReadTimeout): | ||
if os.getenv("CI"): | ||
pytest.skip("Request timeout in CI environment") | ||
else: | ||
raise | ||
|
||
return wrapper | ||
|
||
|
||
@pytest.mark.skipif(WEBSITE_DOWN, reason="www.crystallography.net is down") | ||
class TestCOD(TestCase): | ||
@pytest.mark.skipif(not which("mysql"), reason="No mysql") | ||
class TestCOD: | ||
@skip_on_timeout | ||
def test_get_cod_ids(self): | ||
ids = COD().get_cod_ids("Li2O") | ||
ids = COD(timeout=TIMEOUT).get_cod_ids("Li2O") | ||
assert len(ids) > 15 | ||
assert set(ids).issuperset({1010064, 1011372}) | ||
|
||
@pytest.mark.skipif(not which("mysql"), reason="No mysql") | ||
@skip_on_timeout | ||
def test_get_structure_by_formula(self): | ||
data = COD().get_structure_by_formula("Li2O") | ||
assert len(data) > 15 | ||
assert data[0]["structure"].reduced_formula == "Li2O" | ||
# This formula has only one match (as of 2024-10-17) therefore | ||
# the runtime is shorter (~ 2s for each match) | ||
data = COD(timeout=TIMEOUT).get_structure_by_formula("C3 H18 F6 Fe N9") | ||
assert len(data) >= 1 | ||
assert data[0]["structure"].reduced_formula == "FeH18C3(N3F2)3" | ||
|
||
@skip_on_timeout | ||
def test_get_structure_by_id(self): | ||
struct = COD().get_structure_by_id(2_002_926) | ||
struct = COD(timeout=TIMEOUT).get_structure_by_id(2_002_926) | ||
assert struct.formula == "Be8 H64 N16 F32" |