test_filter.py (12543B)
1 # standard imports 2 import unittest 3 import tempfile 4 import shutil 5 import logging 6 import stat 7 import os 8 9 # local imports 10 from chainsyncer.store.fs import SyncFsStore 11 from chainsyncer.session import SyncSession 12 from chainsyncer.error import ( 13 LockError, 14 FilterDone, 15 IncompleteFilterError, 16 ) 17 from chainsyncer.unittest import ( 18 MockFilter, 19 MockConn, 20 MockTx, 21 MockBlock, 22 MockFilterError, 23 state_event_handler, 24 filter_state_event_handler, 25 ) 26 27 28 logging.basicConfig(level=logging.STATETRACE) 29 logg = logging.getLogger() 30 31 32 33 class TestFilter(unittest.TestCase): 34 35 def setUp(self): 36 self.path = tempfile.mkdtemp() 37 self.store = SyncFsStore(self.path, state_event_callback=state_event_handler, filter_state_event_callback=filter_state_event_handler) 38 self.session = SyncSession(self.store) 39 self.conn = MockConn() 40 41 42 def tearDown(self): 43 shutil.rmtree(self.path) 44 45 46 def test_filter_basic(self): 47 fltr_one = MockFilter('foo') 48 self.store.register(fltr_one) 49 fltr_two = MockFilter('bar') 50 self.store.register(fltr_two) 51 52 self.session.start() 53 54 tx_hash = os.urandom(32).hex() 55 tx = MockTx(42, tx_hash) 56 block = MockBlock(13, [tx_hash]) 57 self.session.filter(self.conn, block, tx) 58 59 self.assertEqual(len(fltr_one.contents), 1) 60 self.assertEqual(len(fltr_two.contents), 1) 61 62 63 64 def test_filter_interrupt(self): 65 fltr_one = MockFilter('foo', brk=True) 66 self.store.register(fltr_one) 67 fltr_two = MockFilter('bar') 68 self.store.register(fltr_two) 69 70 self.session.start() 71 72 tx_hash = os.urandom(32).hex() 73 tx = MockTx(42, tx_hash) 74 block = MockBlock(13, [tx_hash]) 75 self.session.filter(self.conn, block, tx) 76 77 self.assertEqual(len(fltr_one.contents), 1) 78 self.assertEqual(len(fltr_two.contents), 0) 79 80 81 def test_filter_resume_single_revert(self): 82 fltr_one = MockFilter('foo', brk_hard=True) 83 self.store.register(fltr_one) 84 85 self.session.start() 86 87 item = self.store.get('0') 88 item.next() 89 90 tx_hash = os.urandom(32).hex() 91 tx = MockTx(42, tx_hash) 92 block = MockBlock(13, [tx_hash]) 93 94 with self.assertRaises(MockFilterError): 95 self.session.filter(self.conn, block, tx) 96 97 # Unlock the state, reverting to previous filter 98 store = SyncFsStore(self.path, state_event_callback=state_event_handler, filter_state_event_callback=filter_state_event_handler) 99 self.conn = MockConn() 100 fltr_one = MockFilter('foo') 101 store.register(fltr_one) 102 store.connect() 103 store.start(ignore_lock=True) 104 store.unlock_filter(revert=True) 105 106 store = SyncFsStore(self.path, state_event_callback=state_event_handler, filter_state_event_callback=filter_state_event_handler) 107 session = SyncSession(store) 108 self.conn = MockConn() 109 110 fltr_one = MockFilter('foo') 111 store.register(fltr_one) 112 113 session.start() 114 115 session.filter(self.conn, block, tx) 116 117 118 119 def test_filter_resume_single_continue(self): 120 fltr_one = MockFilter('foo', brk_hard=True) 121 self.store.register(fltr_one) 122 123 self.session.start() 124 125 item = self.store.get('0') 126 item.next() 127 128 tx_hash = os.urandom(32).hex() 129 tx = MockTx(42, tx_hash) 130 block = MockBlock(13, [tx_hash]) 131 132 with self.assertRaises(MockFilterError): 133 self.session.filter(self.conn, block, tx) 134 135 # Unlock the state, reverting to previous filter 136 store = SyncFsStore(self.path, state_event_callback=state_event_handler, filter_state_event_callback=filter_state_event_handler) 137 self.conn = MockConn() 138 fltr_one = MockFilter('foo') 139 store.register(fltr_one) 140 store.connect() 141 store.start(ignore_lock=True) 142 store.unlock_filter(revert=False) 143 144 store = SyncFsStore(self.path, state_event_callback=state_event_handler, filter_state_event_callback=filter_state_event_handler) 145 session = SyncSession(store) 146 self.conn = MockConn() 147 148 fltr_one = MockFilter('foo') 149 store.register(fltr_one) 150 store.connect() 151 152 session.start() 153 154 session.filter(self.conn, block, tx) 155 156 157 158 def test_filter_resume_multi_revert_last(self): 159 fltr_one = MockFilter('foo') 160 self.store.register(fltr_one) 161 162 fltr_two = MockFilter('bar', brk_hard=True) 163 self.store.register(fltr_two) 164 165 self.session.start() 166 167 item = self.store.get('0') 168 item.next() 169 170 tx_hash = os.urandom(32).hex() 171 tx = MockTx(42, tx_hash) 172 block = MockBlock(13, [tx_hash]) 173 174 with self.assertRaises(MockFilterError): 175 self.session.filter(self.conn, block, tx) 176 177 # Unlock the state, reverting to previous filter 178 store = SyncFsStore(self.path, state_event_callback=state_event_handler, filter_state_event_callback=filter_state_event_handler) 179 self.conn = MockConn() 180 fltr_one = MockFilter('foo') 181 store.register(fltr_one) 182 fltr_bar = MockFilter('bar') 183 store.register(fltr_bar) 184 store.connect() 185 store.start(ignore_lock=True) 186 store.unlock_filter(revert=True) 187 188 store = SyncFsStore(self.path, state_event_callback=state_event_handler, filter_state_event_callback=filter_state_event_handler) 189 session = SyncSession(store) 190 self.conn = MockConn() 191 192 fltr_one = MockFilter('foo') 193 store.register(fltr_one) 194 fltr_two = MockFilter('bar') 195 store.register(fltr_two) 196 197 store.connect() 198 199 session.start() 200 201 session.filter(self.conn, block, tx) 202 203 204 def test_filter_resume_multi_continue_last(self): 205 fltr_one = MockFilter('foo') 206 self.store.register(fltr_one) 207 208 fltr_two = MockFilter('bar', brk_hard=True) 209 self.store.register(fltr_two) 210 211 self.session.start() 212 213 item = self.store.get('0') 214 item.next() 215 216 tx_hash = os.urandom(32).hex() 217 tx = MockTx(42, tx_hash) 218 block = MockBlock(13, [tx_hash]) 219 220 with self.assertRaises(MockFilterError): 221 self.session.filter(self.conn, block, tx) 222 223 # Unlock the state, reverting to previous filter 224 store = SyncFsStore(self.path, state_event_callback=state_event_handler, filter_state_event_callback=filter_state_event_handler) 225 self.conn = MockConn() 226 fltr_one = MockFilter('foo') 227 store.register(fltr_one) 228 fltr_bar = MockFilter('bar') 229 store.register(fltr_bar) 230 store.connect() 231 store.start(ignore_lock=True) 232 store.unlock_filter(revert=False) 233 234 store = SyncFsStore(self.path, state_event_callback=state_event_handler, filter_state_event_callback=filter_state_event_handler) 235 session = SyncSession(store) 236 self.conn = MockConn() 237 238 fltr_one = MockFilter('foo') 239 store.register(fltr_one) 240 fltr_two = MockFilter('bar') 241 store.register(fltr_two) 242 243 session.start() 244 245 session.filter(self.conn, block, tx) 246 247 248 def test_filter_resume_multi_revert_middle(self): 249 fltr_one = MockFilter('foo') 250 self.store.register(fltr_one) 251 252 fltr_two = MockFilter('bar', brk_hard=True) 253 self.store.register(fltr_two) 254 255 fltr_three = MockFilter('baz') 256 self.store.register(fltr_three) 257 258 self.session.start() 259 260 item = self.store.get('0') 261 item.next() 262 263 tx_hash = os.urandom(32).hex() 264 tx = MockTx(42, tx_hash) 265 block = MockBlock(13, [tx_hash]) 266 267 with self.assertRaises(MockFilterError): 268 self.session.filter(self.conn, block, tx) 269 270 # Unlock the state, reverting to previous filter 271 store = SyncFsStore(self.path, state_event_callback=state_event_handler, filter_state_event_callback=filter_state_event_handler) 272 self.conn = MockConn() 273 fltr_one = MockFilter('foo') 274 store.register(fltr_one) 275 fltr_two = MockFilter('bar') 276 store.register(fltr_two) 277 fltr_three = MockFilter('baz') 278 store.register(fltr_three) 279 280 store.connect() 281 store.start(ignore_lock=True) 282 store.unlock_filter(revert=True) 283 284 store = SyncFsStore(self.path, state_event_callback=state_event_handler, filter_state_event_callback=filter_state_event_handler) 285 session = SyncSession(store) 286 self.conn = MockConn() 287 288 fltr_one = MockFilter('foo') 289 store.register(fltr_one) 290 fltr_two = MockFilter('bar') 291 store.register(fltr_two) 292 fltr_three = MockFilter('baz') 293 store.register(fltr_three) 294 295 store.connect() 296 297 session.start() 298 299 session.filter(self.conn, block, tx) 300 301 302 def test_filter_resume_multi_continue_middle(self): 303 fltr_one = MockFilter('foo') 304 self.store.register(fltr_one) 305 306 fltr_two = MockFilter('bar', brk_hard=True) 307 self.store.register(fltr_two) 308 309 fltr_three = MockFilter('baz') 310 self.store.register(fltr_three) 311 312 self.session.start() 313 314 item = self.store.get('0') 315 item.next() 316 317 tx_hash = os.urandom(32).hex() 318 tx = MockTx(42, tx_hash) 319 block = MockBlock(13, [tx_hash]) 320 321 with self.assertRaises(MockFilterError): 322 self.session.filter(self.conn, block, tx) 323 324 # Unlock the state, reverting to previous filter 325 store = SyncFsStore(self.path, state_event_callback=state_event_handler, filter_state_event_callback=filter_state_event_handler) 326 self.conn = MockConn() 327 fltr_one = MockFilter('foo') 328 store.register(fltr_one) 329 fltr_two = MockFilter('bar') 330 store.register(fltr_two) 331 fltr_three = MockFilter('baz') 332 store.register(fltr_three) 333 334 store.connect() 335 store.start(ignore_lock=True) 336 store.unlock_filter(revert=False) 337 338 store = SyncFsStore(self.path, state_event_callback=state_event_handler, filter_state_event_callback=filter_state_event_handler) 339 session = SyncSession(store) 340 self.conn = MockConn() 341 342 fltr_one = MockFilter('foo') 343 store.register(fltr_one) 344 fltr_two = MockFilter('bar') 345 store.register(fltr_two) 346 fltr_three = MockFilter('baz') 347 store.register(fltr_three) 348 349 session.start() 350 351 session.filter(self.conn, block, tx) 352 353 354 # harness testing 355 def test_filter_breakpoint(self): 356 fltr_one = MockFilter('foo', brk=3, brk_points=[(2, 3,), (3, 0,)]) 357 self.store.register(fltr_one) 358 fltr_two = MockFilter('bar') 359 self.store.register(fltr_two) 360 361 self.session.start() 362 363 tx_hash = os.urandom(32).hex() 364 tx = MockTx(2, tx_hash) 365 block = MockBlock(1, [tx_hash]) 366 self.session.filter(self.conn, block, tx) 367 368 self.assertEqual(len(fltr_one.contents), 1) 369 self.assertEqual(len(fltr_two.contents), 1) 370 371 tx_hash = os.urandom(32).hex() 372 tx = MockTx(2, tx_hash) 373 block = MockBlock(2, [tx_hash]) 374 self.session.filter(self.conn, block, tx) 375 376 self.assertEqual(len(fltr_one.contents), 2) 377 self.assertEqual(len(fltr_two.contents), 2) 378 379 tx_hash = os.urandom(32).hex() 380 tx = MockTx(3, tx_hash) 381 block = MockBlock(2, [tx_hash]) 382 self.session.filter(self.conn, block, tx) 383 self.assertEqual(len(fltr_one.contents), 3) 384 self.assertEqual(len(fltr_two.contents), 2) 385 386 tx_hash = os.urandom(32).hex() 387 tx = MockTx(0, tx_hash) 388 block = MockBlock(3, [tx_hash]) 389 self.session.filter(self.conn, block, tx) 390 self.assertEqual(len(fltr_one.contents), 4) 391 self.assertEqual(len(fltr_two.contents), 2) 392 393 tx_hash = os.urandom(32).hex() 394 tx = MockTx(2, tx_hash) 395 block = MockBlock(4, [tx_hash]) 396 self.session.filter(self.conn, block, tx) 397 self.assertEqual(len(fltr_one.contents), 5) 398 self.assertEqual(len(fltr_two.contents), 2) 399 400 tx_hash = os.urandom(32).hex() 401 tx = MockTx(3, tx_hash) 402 block = MockBlock(4, [tx_hash]) 403 self.session.filter(self.conn, block, tx) 404 self.assertEqual(len(fltr_one.contents), 6) 405 self.assertEqual(len(fltr_two.contents), 3) 406 407 408 if __name__ == '__main__': 409 unittest.main() 410