Skip to content

Commit d7b5060

Browse files
committed
Adds test
1 parent 16441c7 commit d7b5060

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

async_substrate_interface/utils/cache.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ async def close(self):
4343
async with self._lock:
4444
if self._db:
4545
await self._db.close()
46+
self._db = None
4647

4748
async def _create_if_not_exists(self, chain: str, table_name: str):
4849
if not (local_chain := _check_if_local(chain)) or not USE_CACHE:

tests/unit_tests/test_types.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
from async_substrate_interface.types import ScaleObj, Runtime, RuntimeCache
2+
from async_substrate_interface.async_substrate import DiskCachedAsyncSubstrateInterface
3+
from async_substrate_interface.utils import cache
4+
5+
import sqlite3
6+
import os
7+
import pickle
8+
import pytest
9+
from unittest.mock import patch
210

311

412
def test_scale_object():
@@ -84,3 +92,71 @@ def test_runtime_cache():
8492
assert runtime_cache.retrieve(newer_fake_block) is not None
8593
assert runtime_cache.retrieve(fake_block, block_hash=new_fake_hash) is not None
8694
assert runtime_cache.retrieve(block_hash=new_fake_hash) is not None
95+
96+
97+
@pytest.mark.asyncio
98+
async def test_runtime_cache_from_disk():
99+
test_db_location = "/tmp/async-substrate-interface-test-cache"
100+
fake_chain = "ws://fake.com"
101+
fake_block = 1
102+
fake_hash = "0xignore"
103+
new_fake_block = 2
104+
new_fake_hash = "0xnewfakehash"
105+
106+
if os.path.exists(test_db_location):
107+
os.remove(test_db_location)
108+
with patch.object(cache, "CACHE_LOCATION", test_db_location):
109+
substrate = DiskCachedAsyncSubstrateInterface(fake_chain, _mock=True)
110+
# Needed to avoid trying to initialize on the network during `substrate.initialize()`
111+
substrate.initialized = True
112+
113+
# runtime cache should be completely empty
114+
assert substrate.runtime_cache.block_hashes == {}
115+
assert substrate.runtime_cache.blocks == {}
116+
assert substrate.runtime_cache.versions == {}
117+
await substrate.initialize()
118+
119+
# after initialization, runtime cache should still be completely empty
120+
assert substrate.runtime_cache.block_hashes == {}
121+
assert substrate.runtime_cache.blocks == {}
122+
assert substrate.runtime_cache.versions == {}
123+
await substrate.close()
124+
125+
# ensure we have created the SQLite DB during initialize()
126+
assert os.path.exists(test_db_location)
127+
128+
# insert some fake data into our DB
129+
conn = sqlite3.connect(test_db_location)
130+
conn.execute(
131+
"INSERT INTO RuntimeCache_blocks (key, value, chain) VALUES (?, ?, ?)",
132+
(fake_block, pickle.dumps(fake_hash), fake_chain),
133+
)
134+
conn.commit()
135+
conn.close()
136+
137+
substrate.initialized = True
138+
await substrate.initialize()
139+
assert substrate.runtime_cache.blocks == {fake_block: fake_hash}
140+
# add an item to the cache
141+
substrate.runtime_cache.add_item(
142+
runtime=None, block_hash=new_fake_hash, block=new_fake_block
143+
)
144+
await substrate.close()
145+
146+
# verify that our added item is now in the DB
147+
conn = sqlite3.connect(test_db_location)
148+
cursor = conn.cursor()
149+
cursor.execute("SELECT key, value, chain FROM RuntimeCache_blocks")
150+
query = cursor.fetchall()
151+
cursor.close()
152+
conn.close()
153+
154+
first_row = query[0]
155+
assert first_row[0] == fake_block
156+
assert pickle.loads(first_row[1]) == fake_hash
157+
assert first_row[2] == fake_chain
158+
159+
second_row = query[1]
160+
assert second_row[0] == new_fake_block
161+
assert pickle.loads(second_row[1]) == new_fake_hash
162+
assert second_row[2] == fake_chain

0 commit comments

Comments
 (0)