Skip to content

Commit 921701f

Browse files
committed
Add failing tests for legacy-db support
These reproduce opendatacube#169 on my system. This also adds functions that will allow us to experiment more with tests of Explorer in unusual Index situations
1 parent 159bef1 commit 921701f

File tree

1 file changed

+130
-0
lines changed

1 file changed

+130
-0
lines changed
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
"""
2+
Test functions that iterate all pages to check that no error was
3+
thrown during rendering.
4+
5+
These can be used to test that the application works when
6+
the DB/Index is put in an unusual state -- the most common
7+
situation by far is a hard rendering error.
8+
9+
*caution*
10+
11+
Please don't rely on this for increasing test coverage of
12+
normal functionality.
13+
14+
Other test modules, such as `test_page_loads.py`, are more
15+
useful to imitate for normal testing as they test the
16+
actual values on the page.
17+
18+
This does catch a lot of bugs though, at low effort.
19+
20+
"""
21+
from textwrap import indent
22+
from typing import List
23+
24+
import pytest
25+
from flask import Response
26+
from flask.testing import FlaskClient
27+
28+
from cubedash._utils import alchemy_engine
29+
from cubedash.summary import SummaryStore
30+
from cubedash.summary._schema import CUBEDASH_SCHEMA
31+
from datacube.index import Index
32+
33+
34+
def test_all_pages_render(all_urls, client: FlaskClient):
35+
"""Do all expected URLS render with HTTP OK response/"""
36+
assert_all_urls_render(all_urls, client)
37+
38+
39+
def test_allows_null_product_fixed_fields(
40+
all_urls, client: FlaskClient, module_index: Index, summary_store: SummaryStore,
41+
):
42+
"""
43+
Pages should not fallover when fixed_metadata is null.
44+
45+
Older versions of cubedash-gen don't write the fixed_metadata column, so
46+
it can be null in legacy and migrated deployments.
47+
48+
(and null is desired behaviour here: null indicates "not known",
49+
while "empty dict" indicates there are zero fields of metadata)
50+
"""
51+
52+
# WHEN we have some products summarised
53+
assert (
54+
summary_store.list_complete_products()
55+
), "There's no summarised products to test"
56+
57+
# AND there's some with null fixed_metadata (ie. pre-Explorer0-EO3-update)
58+
update_count = (
59+
alchemy_engine(module_index)
60+
.execute(f"update {CUBEDASH_SCHEMA}.product set fixed_metadata = null")
61+
.rowcount
62+
)
63+
assert update_count > 0, "There were no test products to update?"
64+
65+
# THEN All pages should still render fine.
66+
assert_all_urls_render(all_urls, client)
67+
68+
69+
def assert_all_urls_render(all_urls: List[str], client: FlaskClient):
70+
"""Assert all given URLs return an OK HTTP response"""
71+
72+
__tracebackhide__ = True
73+
for url in all_urls:
74+
response: Response = client.get(url, follow_redirects=True)
75+
76+
assert response.status_code == 200, (
77+
f"Response {response.status_code} from url f{url}. "
78+
f"Content:\n{indent(response.data.decode('utf-8'), ' ' * 4)}"
79+
)
80+
81+
82+
@pytest.fixture()
83+
def all_urls(summary_store: SummaryStore):
84+
return list(_find_all_public_urls(summary_store.index))
85+
86+
87+
def _find_all_public_urls(index: Index):
88+
yield "/"
89+
yield "/about"
90+
yield "/products.txt"
91+
yield "/product-audit"
92+
yield "/product-audit/day-times.txt"
93+
94+
for mdt in index.metadata_types.get_all():
95+
name = mdt.name
96+
yield f"/metadata-type/{name}"
97+
# yield f"/metadata-type/{name}.odc-type.yaml"
98+
99+
for dt in index.products.get_all():
100+
name = dt.name
101+
yield f"/{name}"
102+
yield f"/datasets/{name}"
103+
yield f"/product/{name}"
104+
# yield f"/product/{name}.odc-product.yaml"
105+
106+
has_datasets = index.datasets.search_eager(product=name, limit=1)
107+
if has_datasets:
108+
dataset = has_datasets[0]
109+
time = dataset.center_time
110+
yield f"/{name}/{time:%Y}"
111+
yield f"/{name}/{time:%Y%/m}"
112+
yield f"/{name}/{time::%Y/%m/%d}"
113+
yield f"/datasets/{name}/{time:%Y}"
114+
yield f"/datasets/{name}/{time:%Y%/m}"
115+
yield f"/datasets/{name}/{time::%Y/%m/%d}"
116+
117+
yield f"/api/datasets/{name}"
118+
yield f"/api/regions/{name}/{time::%Y/%m/%d}"
119+
yield f"/api/footprint/{name}/{time::%Y/%m/%d}"
120+
121+
# TODO: Do non-region_code regions too (such as ingested data)
122+
# TODO: Actually we have no EO3 in this test data, so it does nothing.
123+
# Maybe add test data from test_eo3_support.py?
124+
if "region_code" in dataset.metadata.fields:
125+
yield f"/region/{dataset.metadata.region_code}"
126+
yield f"/region/{dataset.metadata.region_code}/{time::%Y/%m/%d}"
127+
128+
for [dataset_id] in index.datasets.search_returning(("id",), limit=10):
129+
yield f"/dataset/{dataset_id}"
130+
# yield f"/dataset/{dataset_id}.odc-metadata.yaml"

0 commit comments

Comments
 (0)