Check that checksum verification works for datasets created with pq.write_to_dataset
(tempdir)
| 1020 | |
| 1021 | @pytest.mark.dataset |
| 1022 | def test_checksum_write_to_dataset(tempdir): |
| 1023 | """Check that checksum verification works for datasets created with |
| 1024 | pq.write_to_dataset""" |
| 1025 | |
| 1026 | table_orig = pa.table({'a': [1, 2, 3, 4]}) |
| 1027 | |
| 1028 | # Write a sample dataset with page checksum enabled |
| 1029 | original_dir_path = tempdir / 'correct_dir' |
| 1030 | pq.write_to_dataset(table_orig, |
| 1031 | original_dir_path, |
| 1032 | write_page_checksum=True) |
| 1033 | |
| 1034 | # Read file and verify that the data is correct |
| 1035 | original_file_path_list = list(original_dir_path.iterdir()) |
| 1036 | assert len(original_file_path_list) == 1 |
| 1037 | original_path = original_file_path_list[0] |
| 1038 | table_check = pq.read_table(original_path, page_checksum_verification=True) |
| 1039 | assert table_orig == table_check |
| 1040 | |
| 1041 | # Read the original file as binary and swap the 31-th and 36-th bytes. This |
| 1042 | # should be equivalent to storing the following data: |
| 1043 | # pa.table({'a': [1, 3, 2, 4]}) |
| 1044 | bin_data = bytearray(original_path.read_bytes()) |
| 1045 | |
| 1046 | # Swap two bytes to emulate corruption. Also, check that the two bytes are |
| 1047 | # different, otherwise no corruption occurs |
| 1048 | assert bin_data[31] != bin_data[36] |
| 1049 | bin_data[31], bin_data[36] = bin_data[36], bin_data[31] |
| 1050 | |
| 1051 | # Write the corrupted data to another parquet dataset |
| 1052 | # Copy dataset dir (which should be just one file) |
| 1053 | corrupted_dir_path = tempdir / 'corrupted_dir' |
| 1054 | copytree(original_dir_path, corrupted_dir_path) |
| 1055 | # Corrupt just the one file with the dataset |
| 1056 | corrupted_file_path = corrupted_dir_path / original_path.name |
| 1057 | corrupted_file_path.write_bytes(bin_data) |
| 1058 | |
| 1059 | # Case 1: Reading the corrupted file with read_table() and without page |
| 1060 | # checksum verification succeeds but yields corrupted data |
| 1061 | table_corrupt = pq.read_table(corrupted_file_path, |
| 1062 | page_checksum_verification=False) |
| 1063 | # The read should complete without error, but the table has different |
| 1064 | # content than the original file! |
| 1065 | assert table_corrupt != table_orig |
| 1066 | assert table_corrupt == pa.table({'a': [1, 3, 2, 4]}) |
| 1067 | |
| 1068 | # Case 2: Reading the corrupted file with read_table() and with page |
| 1069 | # checksum verification enabled raises an exception |
| 1070 | with pytest.raises(OSError, match="CRC checksum verification"): |
| 1071 | _ = pq.read_table(corrupted_file_path, page_checksum_verification=True) |
| 1072 | |
| 1073 | |
| 1074 | @pytest.mark.parametrize( |
nothing calls this directly
no test coverage detected