|
18 | 18 | from pymysqlreplication.event import * |
19 | 19 | from pymysqlreplication.constants.BINLOG import * |
20 | 20 | from pymysqlreplication.row_event import * |
| 21 | +from pymysqlreplication.packet import BinLogPacketWrapper |
| 22 | +from pymysql.protocol import MysqlPacket |
21 | 23 |
|
22 | | -__all__ = ["TestBasicBinLogStreamReader", "TestMultipleRowBinLogStreamReader", "TestCTLConnectionSettings", "TestGtidBinLogStreamReader", "TestMariadbBinlogStreamReader", "TestStatementConnectionSetting", "TestRowsQueryLogEvents"] |
| 24 | +__all__ = ["TestBasicBinLogStreamReader", "TestMultipleRowBinLogStreamReader", "TestCTLConnectionSettings", |
| 25 | + "TestGtidBinLogStreamReader", "TestMariadbBinlogStreamReader", "TestStatementConnectionSetting", |
| 26 | + "TestRowsQueryLogEvents"] |
23 | 27 |
|
24 | 28 |
|
25 | 29 | class TestBasicBinLogStreamReader(base.PyMySQLReplicationTestCase): |
@@ -522,6 +526,55 @@ def test_end_log_pos(self): |
522 | 526 | self.assertEqual(last_log_pos, 888) |
523 | 527 | self.assertEqual(last_event_type, TABLE_MAP_EVENT) |
524 | 528 |
|
| 529 | + def test_event_validation(self): |
| 530 | + def create_binlog_packet_wrapper(pkt): |
| 531 | + return BinLogPacketWrapper(pkt, self.stream.table_map, |
| 532 | + self.stream._ctl_connection, self.stream.mysql_version, |
| 533 | + self.stream._BinLogStreamReader__use_checksum, |
| 534 | + self.stream._BinLogStreamReader__allowed_events_in_packet, |
| 535 | + self.stream._BinLogStreamReader__only_tables, |
| 536 | + self.stream._BinLogStreamReader__ignored_tables, |
| 537 | + self.stream._BinLogStreamReader__only_schemas, |
| 538 | + self.stream._BinLogStreamReader__ignored_schemas, |
| 539 | + self.stream._BinLogStreamReader__freeze_schema, |
| 540 | + self.stream._BinLogStreamReader__fail_on_table_metadata_unavailable, |
| 541 | + self.stream._BinLogStreamReader__ignore_decode_errors, |
| 542 | + self.stream._BinLogStreamReader__verify_crc32) |
| 543 | + |
| 544 | + self.stream.close() |
| 545 | + self.stream = BinLogStreamReader( |
| 546 | + self.database, |
| 547 | + server_id=1024, |
| 548 | + blocking=False, |
| 549 | + use_crc32=True |
| 550 | + ) |
| 551 | + # For event data, refer to the official document example data of mariaDB. |
| 552 | + # https://mariadb.com/kb/en/query_event/#example-with-crc32 |
| 553 | + correct_event_data = ( |
| 554 | + # OK value |
| 555 | + b"\x00" |
| 556 | + # Header |
| 557 | + b"q\x17(Z\x02\x8c'\x00\x00U\x00\x00\x00\x01\t\x00\x00\x00\x00" |
| 558 | + # Content |
| 559 | + b"f\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a\x00" |
| 560 | + b"\x00\x00\x00\x00\x00\x01\x00\x00\x00P\x00\x00" |
| 561 | + b"\x00\x00\x06\x03std\x04\x08\x00\x08\x00\x08\x00\x00" |
| 562 | + b"TRUNCATE TABLE test.t4" |
| 563 | + # CRC 32, 4 Bytes |
| 564 | + b"Ji\x9e\xed" |
| 565 | + ) |
| 566 | + # Assume a bit flip occurred while data was being transmitted q(1001000) -> U(0110111) |
| 567 | + modified_byte = b"U" |
| 568 | + wrong_event_data = correct_event_data[:1] + modified_byte + correct_event_data[2:] |
| 569 | + |
| 570 | + packet = MysqlPacket(correct_event_data, 0) |
| 571 | + wrong_packet = MysqlPacket(wrong_event_data, 0) |
| 572 | + self.stream.fetchone() # for '_ctl_connection' parameter |
| 573 | + binlog_event = create_binlog_packet_wrapper(packet) |
| 574 | + wrong_event = create_binlog_packet_wrapper(wrong_packet) |
| 575 | + self.assertEqual(binlog_event.event._is_event_valid, True) |
| 576 | + self.assertNotEqual(wrong_event.event._is_event_valid, True) |
| 577 | + |
525 | 578 |
|
526 | 579 | class TestMultipleRowBinLogStreamReader(base.PyMySQLReplicationTestCase): |
527 | 580 | def ignoredEvents(self): |
|
0 commit comments