| 
5 | 5 | import hashlib  | 
6 | 6 | import io  | 
7 | 7 | import os  | 
8 |  | -import shutil  | 
9 | 8 | import stat  | 
10 | 9 | import tarfile  | 
11 |  | -import tempfile  | 
12 |  | -import unittest  | 
13 | 10 | 
 
  | 
14 | 11 | import pytest  | 
15 | 12 | 
 
  | 
@@ -110,45 +107,78 @@ def test_create_tar_basic(tmp_path, create_files):  | 
110 | 107 |         verify_basic_tarfile(tf)  | 
111 | 108 | 
 
  | 
112 | 109 | 
 
  | 
113 |  | -@pytest.mark.xfail(reason="hash mismatch")  | 
114 |  | -def test_executable_preserved():  | 
115 |  | -    p = os.path.join(d, "exec")  | 
116 |  | -    with open(p, "wb") as fh:  | 
117 |  | -        fh.write(b"#!/bin/bash\n")  | 
118 |  | -    os.chmod(p, MODE_STANDARD | stat.S_IXUSR)  | 
 | 110 | +def test_executable_preserved(tmp_path):  | 
 | 111 | +    p = tmp_path / "exec"  | 
 | 112 | +    p.write_bytes(b"#!/bin/bash\n")  | 
 | 113 | +    p.chmod(MODE_STANDARD | stat.S_IXUSR)  | 
119 | 114 | 
 
  | 
120 |  | -    tp = os.path.join(d, "test.tar")  | 
 | 115 | +    tp = tmp_path / "test.tar"  | 
121 | 116 |     with open(tp, "wb") as fh:  | 
122 |  | -        create_tar_from_files(fh, {"exec": p})  | 
 | 117 | +        create_tar_from_files(fh, {"exec": str(p)})  | 
 | 118 | + | 
 | 119 | +    # Test determinism by creating the same file again  | 
 | 120 | +    tp2 = tmp_path / "test2.tar"  | 
 | 121 | +    with open(tp2, "wb") as fh:  | 
 | 122 | +        create_tar_from_files(fh, {"exec": str(p)})  | 
123 | 123 | 
 
  | 
124 |  | -    assert file_hash(tp) == "357e1b81c0b6cfdfa5d2d118d420025c3c76ee93"  | 
 | 124 | +    assert file_hash(str(tp)) == file_hash(str(tp2))  | 
125 | 125 | 
 
  | 
 | 126 | +    # Verify executable permissions are preserved in tar  | 
126 | 127 |     with tarfile.open(tp, "r") as tf:  | 
127 | 128 |         m = tf.getmember("exec")  | 
128 | 129 |         assert m.mode == MODE_STANDARD | stat.S_IXUSR  | 
129 | 130 | 
 
  | 
 | 131 | +        # Verify file content is correct  | 
 | 132 | +        extracted_content = tf.extractfile(m).read()  | 
 | 133 | +        assert extracted_content == b"#!/bin/bash\n"  | 
130 | 134 | 
 
  | 
131 | 135 | def test_create_tar_gz_basic(tmp_path, create_files):  | 
132 |  | -    files = create_files()  | 
133 |  | - | 
134 | 136 |     gp = tmp_path / "test.tar.gz"  | 
135 | 137 |     with open(gp, "wb") as fh:  | 
136 |  | -        create_tar_gz_from_files(fh, files)  | 
 | 138 | +        create_tar_gz_from_files(fh, create_files())  | 
 | 139 | + | 
 | 140 | +    # Test determinism by creating the same file again with fresh BytesIO objects  | 
 | 141 | +    gp2 = tmp_path / "test2.tar.gz"  | 
 | 142 | +    with open(gp2, "wb") as fh:  | 
 | 143 | +        create_tar_gz_from_files(fh, create_files())  | 
 | 144 | + | 
 | 145 | +    assert file_hash(str(gp)) == file_hash(str(gp2))  | 
 | 146 | + | 
 | 147 | +    # Create uncompressed version for size comparison  | 
 | 148 | +    tp = tmp_path / "test.tar"  | 
 | 149 | +    with open(tp, "wb") as fh:  | 
 | 150 | +        create_tar_from_files(fh, create_files())  | 
 | 151 | +    uncompressed_size = tp.stat().st_size  | 
 | 152 | +    compressed_size = gp.stat().st_size  | 
137 | 153 | 
 
  | 
138 |  | -    assert file_hash(gp) == "7c4da5adc5088cdf00911d5daf9a67b15de714b7"  | 
 | 154 | +    # Compressed should be smaller than uncompressed  | 
 | 155 | +    assert compressed_size < uncompressed_size  | 
139 | 156 | 
 
  | 
 | 157 | +    # Verify the contents are correct  | 
140 | 158 |     with tarfile.open(gp, "r:gz") as tf:  | 
141 | 159 |         verify_basic_tarfile(tf)  | 
142 | 160 | 
 
  | 
143 | 161 | 
 
  | 
144 | 162 | def test_tar_gz_name(tmp_path, create_files):  | 
145 |  | -    files = create_files()  | 
146 |  | - | 
147 | 163 |     gp = tmp_path / "test.tar.gz"  | 
148 | 164 |     with open(gp, "wb") as fh:  | 
149 |  | -        create_tar_gz_from_files(fh, files, filename="foobar")  | 
 | 165 | +        create_tar_gz_from_files(fh, create_files(), filename="foobar")  | 
 | 166 | + | 
 | 167 | +    # Test determinism by creating the same file again with fresh BytesIO objects  | 
 | 168 | +    gp2 = tmp_path / "test2.tar.gz"  | 
 | 169 | +    with open(gp2, "wb") as fh:  | 
 | 170 | +        create_tar_gz_from_files(fh, create_files(), filename="foobar")  | 
 | 171 | + | 
 | 172 | +    assert file_hash(str(gp)) == file_hash(str(gp2))  | 
 | 173 | + | 
 | 174 | +    # Create version without filename for comparison  | 
 | 175 | +    gp_no_name = tmp_path / "test_no_name.tar.gz"  | 
 | 176 | +    with open(gp_no_name, "wb") as fh:  | 
 | 177 | +        create_tar_gz_from_files(fh, create_files())  | 
150 | 178 | 
 
  | 
151 |  | -    assert file_hash(gp) == "721e00083c17d16df2edbddf40136298c06d0c49"  | 
 | 179 | +    # Files should be different (different filename in gzip header)  | 
 | 180 | +    assert file_hash(str(gp)) != file_hash(str(gp_no_name))  | 
152 | 181 | 
 
  | 
 | 182 | +    # Verify the contents are correct  | 
153 | 183 |     with tarfile.open(gp, "r:gz") as tf:  | 
154 | 184 |         verify_basic_tarfile(tf)  | 
0 commit comments