Skip to content

Commit 0fcf369

Browse files
committed
test: fix test_util_archive.py to avoid cross-environment non-determinism
Different implementations of zlib can yield different hashes. So instead, generate the archive twice and make sure the hash is the same.
1 parent 38ed8ed commit 0fcf369

File tree

1 file changed

+52
-25
lines changed

1 file changed

+52
-25
lines changed

test/test_util_archive.py

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,8 @@
44

55
import hashlib
66
import io
7-
import os
8-
import shutil
97
import stat
108
import tarfile
11-
import tempfile
12-
import unittest
139

1410
import pytest
1511

@@ -36,7 +32,6 @@ def file_hash(path):
3632

3733
@pytest.fixture
3834
def create_files(tmp_path):
39-
4035
def inner():
4136
files = {}
4237
for i in range(10):
@@ -69,9 +64,7 @@ def verify_basic_tarfile(tf):
6964
assert ti.mtime == DEFAULT_MTIME
7065

7166

72-
@pytest.mark.xfail(
73-
reason="ValueError is not thrown despite being provided directory."
74-
)
67+
@pytest.mark.xfail(reason="ValueError is not thrown despite being provided directory.")
7568
def test_dirs_refused(tmp_path):
7669
tp = tmp_path / "test.tar"
7770
with open(tp, "wb") as fh:
@@ -110,45 +103,79 @@ def test_create_tar_basic(tmp_path, create_files):
110103
verify_basic_tarfile(tf)
111104

112105

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)
106+
def test_executable_preserved(tmp_path):
107+
p = tmp_path / "exec"
108+
p.write_bytes(b"#!/bin/bash\n")
109+
p.chmod(MODE_STANDARD | stat.S_IXUSR)
119110

120-
tp = os.path.join(d, "test.tar")
111+
tp = tmp_path / "test.tar"
121112
with open(tp, "wb") as fh:
122-
create_tar_from_files(fh, {"exec": p})
113+
create_tar_from_files(fh, {"exec": str(p)})
123114

124-
assert file_hash(tp) == "357e1b81c0b6cfdfa5d2d118d420025c3c76ee93"
115+
# Test determinism by creating the same file again
116+
tp2 = tmp_path / "test2.tar"
117+
with open(tp2, "wb") as fh:
118+
create_tar_from_files(fh, {"exec": str(p)})
125119

120+
assert file_hash(str(tp)) == file_hash(str(tp2))
121+
122+
# Verify executable permissions are preserved in tar
126123
with tarfile.open(tp, "r") as tf:
127124
m = tf.getmember("exec")
128125
assert m.mode == MODE_STANDARD | stat.S_IXUSR
129126

127+
# Verify file content is correct
128+
extracted_content = tf.extractfile(m).read()
129+
assert extracted_content == b"#!/bin/bash\n"
130130

131-
def test_create_tar_gz_basic(tmp_path, create_files):
132-
files = create_files()
133131

132+
def test_create_tar_gz_basic(tmp_path, create_files):
134133
gp = tmp_path / "test.tar.gz"
135134
with open(gp, "wb") as fh:
136-
create_tar_gz_from_files(fh, files)
135+
create_tar_gz_from_files(fh, create_files())
137136

138-
assert file_hash(gp) == "7c4da5adc5088cdf00911d5daf9a67b15de714b7"
137+
# Test determinism by creating the same file again with fresh BytesIO objects
138+
gp2 = tmp_path / "test2.tar.gz"
139+
with open(gp2, "wb") as fh:
140+
create_tar_gz_from_files(fh, create_files())
139141

142+
assert file_hash(str(gp)) == file_hash(str(gp2))
143+
144+
# Create uncompressed version for size comparison
145+
tp = tmp_path / "test.tar"
146+
with open(tp, "wb") as fh:
147+
create_tar_from_files(fh, create_files())
148+
uncompressed_size = tp.stat().st_size
149+
compressed_size = gp.stat().st_size
150+
151+
# Compressed should be smaller than uncompressed
152+
assert compressed_size < uncompressed_size
153+
154+
# Verify the contents are correct
140155
with tarfile.open(gp, "r:gz") as tf:
141156
verify_basic_tarfile(tf)
142157

143158

144159
def test_tar_gz_name(tmp_path, create_files):
145-
files = create_files()
146-
147160
gp = tmp_path / "test.tar.gz"
148161
with open(gp, "wb") as fh:
149-
create_tar_gz_from_files(fh, files, filename="foobar")
162+
create_tar_gz_from_files(fh, create_files(), filename="foobar")
163+
164+
# Test determinism by creating the same file again with fresh BytesIO objects
165+
gp2 = tmp_path / "test2.tar.gz"
166+
with open(gp2, "wb") as fh:
167+
create_tar_gz_from_files(fh, create_files(), filename="foobar")
168+
169+
assert file_hash(str(gp)) == file_hash(str(gp2))
170+
171+
# Create version without filename for comparison
172+
gp_no_name = tmp_path / "test_no_name.tar.gz"
173+
with open(gp_no_name, "wb") as fh:
174+
create_tar_gz_from_files(fh, create_files())
150175

151-
assert file_hash(gp) == "721e00083c17d16df2edbddf40136298c06d0c49"
176+
# Files should be different (different filename in gzip header)
177+
assert file_hash(str(gp)) != file_hash(str(gp_no_name))
152178

179+
# Verify the contents are correct
153180
with tarfile.open(gp, "r:gz") as tf:
154181
verify_basic_tarfile(tf)

0 commit comments

Comments
 (0)