Skip to content

Commit c8e5e50

Browse files
committed
ran first pytest --- passed
1 parent 9093022 commit c8e5e50

File tree

2 files changed

+97
-6
lines changed

2 files changed

+97
-6
lines changed

python/grass/temporal/abstract_map_dataset.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -537,15 +537,14 @@ def update_absolute_time(self, start_time, end_time=None, dbif=None) -> None:
537537
dbif.close()
538538

539539
# write to timestamp only if its the same mapset, otherwise show a warning and skip the write to avoid inconsistencies between the temporal database and the grass file system --> supposed to fix issue 3394
540-
if (
541-
get_enable_timestamp_write()
542-
and self.get_mapset() == get_current_mapset()
543-
):
544-
self.write_timestamp_to_grass()
545-
else:
540+
if self.get_mapset() != get_current_mapset():
546541
self.msgr.warning(
547542
f"Skipping timestamp write for {self.get_map_id()} (different mapset)"
548543
)
544+
return
545+
546+
if get_enable_timestamp_write():
547+
self.write_timestamp_to_grass()
549548

550549
def set_relative_time(self, start_time, end_time, unit) -> bool:
551550
"""Set the relative time interval
@@ -665,6 +664,12 @@ def update_relative_time(self, start_time, end_time, unit, dbif=None) -> None:
665664
if connection_state_changed:
666665
dbif.close()
667666

667+
if self.get_mapset() != get_current_mapset():
668+
self.msgr.warning(
669+
f"Skipping timestamp write for {self.get_map_id()} (different mapset)"
670+
)
671+
return
672+
668673
if get_enable_timestamp_write():
669674
self.write_timestamp_to_grass()
670675

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
"""
2+
Check when timestamps are written -- especially when write_timestamp_to_grass() is called.
3+
4+
:authors: Anirban Das
5+
"""
6+
7+
import grass.script as gs
8+
import grass.temporal as tgis
9+
from grass_session import Session
10+
import pytest
11+
from unittest.mock import patch
12+
13+
import tempfile
14+
15+
16+
# setting up a fixture to create a temporary GRASS environment
17+
@pytest.fixture(scope="module")
18+
def grass_env():
19+
# just ensuring that the test runs on a new GRASS environment every time and does not interfere with any existing GRASS session. This also ensures that the test is self-contained and does not rely on any external state.
20+
with (
21+
tempfile.TemporaryDirectory() as temp_dir,
22+
Session(
23+
gisdb=temp_dir,
24+
location="testloc",
25+
mapset="PERMANENT",
26+
create_opts="EPSG:4326",
27+
),
28+
):
29+
# initialize temporal GRASS
30+
tgis.init()
31+
32+
gs.run_command("g.mapset", flags="c", mapset="NEW")
33+
gs.run_command("g.region", n=50, s=0, e=50, w=0, res=1)
34+
gs.run_command("r.mapcalc", expression="new_map = 1")
35+
36+
# come back to PERMANENT mapset
37+
gs.run_command("g.mapset", mapset="PERMANENT")
38+
# make the NEW mapset visible
39+
gs.run_command("g.mapsets", mapset="NEW", operation="add")
40+
41+
gs.run_command(
42+
"t.create",
43+
type="strds",
44+
output="test_dataset",
45+
temporaltype="absolute",
46+
title="test_dataset",
47+
description="testing outputs",
48+
)
49+
50+
# next we have to register this map with timestamp
51+
gs.run_command(
52+
"t.register", input="test_dataset", maps="new_map", start="2020-01-01"
53+
)
54+
yield
55+
56+
57+
def test_update_absolute_time(grass_env):
58+
ds = tgis.open_old_stds("test_dataset", "strds")
59+
maps = ds.get_registered_maps_as_objects()
60+
m = maps[0]
61+
with patch.object(type(m), "write_timestamp_to_grass") as mock_func:
62+
with pytest.raises(SystemExit):
63+
m.update_absolute_time("2020-01-01")
64+
65+
mock_func.assert_not_called()
66+
67+
68+
def test_update_relative_time(grass_env):
69+
ds = tgis.open_old_stds("test_dataset", "strds")
70+
maps = ds.get_registered_maps_as_objects()
71+
m = maps[0]
72+
with patch.object(type(m), "write_timestamp_to_grass") as mock_func:
73+
with pytest.raises(SystemExit):
74+
m.update_relative_time(0, None, "days")
75+
76+
mock_func.assert_not_called()
77+
78+
79+
# short explanation of the tests:
80+
# 1. write_timestamp_to_grass() is defined in abstract_map_dataset.py as an @abstractmethod. but the real implementation is in space_time_datasets.py. so who is actually calling it when you run m.update_absolute_time() or m.update_relative_time() ? is it the abstract_map_dataset.py or space_time_datasets.py ? we want to check that. so we patch the method in the abstract_map_dataset.py and check if it is called when we run the update time methods. if it is called, then we know that the update time methods are calling the write_timestamp_to_grass() method as expected.
81+
#
82+
# 2. the solution is to patch where the method is looked up, not where it is defined.
83+
#
84+
# 3. python resolves it via the instance (m), so it calls the method from the actual class of 'm', not the abstract base.
85+
#
86+
# 4. patching it via (m) allows this test to run even when GRASS changes internals.

0 commit comments

Comments
 (0)