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