import os
import shutil
import tempfile
import time
import unittest
from pathlib import Path
from tilecap import TileCap, tile_key
class TileCapTest(unittest.TestCase):
def setUp(self):
self.root = Path(tempfile.mkdtemp())
def tearDown(self):
shutil.rmtree(self.root)
def put(self, rel, size, age):
f = self.root / "v5.4-abc" / rel
f.parent.mkdir(parents=True, exist_ok=True)
f.write_bytes(b"x" * size)
t = time.time() - age
os.utime(f, (t, t))
return f
def test_tile_key(self):
self.assertEqual(tile_key("t/v5/relief/9/12/34.jpg"), ("relief", 9))
self.assertEqual(tile_key("t/v5/mesh/12/1/2.bin"), ("mesh", 12))
self.assertIsNone(tile_key("t/v5/manifest.npz"))
self.assertIsNone(tile_key("t/v5/relief/9/12/tmpab.part"))
self.assertIsNone(tile_key("t/v5/relief/9/x/3.jpg"))
def test_sweep_deletes_least_recently_used_down_to_slack(self):
# 10 deep tiles of 100 B, the oldest first; cap 700 → goal 630: the 4 oldest go (1000 → 600)
fs = [self.put(f"relief/12/{i}/0.jpg", 100, age=100 - i) for i in range(10)]
keep = self.put("relief/5/0/0.jpg", 5000, age=1000) # prerendered: kept and not counted
other = self.put("biomes/5/0/0.jpg", 100, age=1) # another layer at a kept zoom: counted
man = self.put("manifest.npz", 100, age=1000) # not a tile
cap = TileCap(700, keep_z=9)
cap.add_root(self.root)
freed = cap.sweep()
self.assertEqual(freed, 500) # 1100 → 600: the 5 oldest of 11 counted
self.assertEqual([f.exists() for f in fs], [False] * 5 + [True] * 5)
self.assertTrue(keep.exists() and other.exists() and man.exists())
self.assertEqual(cap.total, 600)
self.assertFalse((self.root / "v5.4-abc" / "relief" / "12" / "0").exists(), "empty folders go")
def test_used_tile_survives(self):
fs = [self.put(f"relief/12/{i}/0.jpg", 100, age=100 - i) for i in range(4)]
cap = TileCap(300, keep_z=-1)
cap.add_root(self.root)
cap.used(fs[0]) # the oldest is read again
cap.sweep() # 400 → goal 270: two go
self.assertEqual([f.exists() for f in fs], [True, False, False, True])
def test_under_cap_deletes_nothing_and_saves_count(self):
fs = [self.put(f"relief/12/{i}/0.jpg", 100, age=10) for i in range(3)]
cap = TileCap(1000)
cap.add_root(self.root)
self.assertEqual(cap.sweep(), 0)
self.assertEqual(cap.total, 300)
cap.saved(self.root / "v5.4-abc" / "relief" / "5" / "0" / "0.jpg", 50)
self.assertEqual(cap.total, 350)
self.assertTrue(all(f.exists() for f in fs))
def test_save_past_cap_sweeps(self):
cap = TileCap(250)
cap.add_root(self.root)
cap.sweep()
fs = [self.put(f"mesh/13/{i}/0.bin", 100, age=10 - i) for i in range(3)]
started = []
cap.start = lambda: started.append(1)
cap.saved(fs[0], 100)
cap.saved(fs[1], 100)
self.assertEqual(started, [])
cap.saved(fs[2], 100)
self.assertEqual(started, [1])
if __name__ == "__main__":
unittest.main()