44import contextlib
55import errno
66import os
7+ import stat
78
89import pytest
910
1011from pex .common import (
1112 Chroot ,
1213 ZipFileEx ,
14+ ZipFileType ,
1315 deterministic_walk ,
1416 open_zip ,
17+ safe_mkdir ,
1518 safe_open ,
1619 temporary_dir ,
1720 touch ,
1821)
1922from pex .executables import chmod_plus_x
2023from pex .typing import TYPE_CHECKING
2124from testing import NonDeterministicWalk
25+ from testing .pytest_utils .tmp import Tempdir
2226
2327try :
2428 from unittest import mock
2933 from typing import Iterator , Tuple
3034
3135
36+ def test_zip_file_type_mode (tmpdir ):
37+ # type: (Tempdir) -> None
38+
39+ directory = safe_mkdir (tmpdir .join ("dir" ))
40+ zip_dir = ZipFileType .from_path (directory )
41+ assert stat .S_ISDIR (zip_dir .deterministic_mode )
42+ assert 0o755 == 0o755 & zip_dir .deterministic_mode
43+
44+ regular_file = touch (tmpdir .join ("file" ))
45+ zip_reg_file = ZipFileType .from_path (regular_file )
46+ assert stat .S_ISREG (zip_reg_file .deterministic_mode )
47+ assert 0o644 == 0o644 & zip_reg_file .deterministic_mode
48+
49+ executable_file = touch (tmpdir .join ("exe" ))
50+ chmod_plus_x (executable_file )
51+ zip_exe_file = ZipFileType .from_path (executable_file )
52+ assert stat .S_ISREG (zip_exe_file .deterministic_mode )
53+ assert 0o755 == 0o755 & zip_exe_file .deterministic_mode
54+
55+
3256def extract_perms (path ):
3357 # type: (str) -> str
3458 return oct (os .stat (path ).st_mode )
3559
3660
3761@contextlib .contextmanager
3862def zip_fixture ():
39- # type: () -> Iterator[Tuple[str, str, str, str ]]
63+ # type: () -> Iterator[Tuple[str, str]]
4064 with temporary_dir () as target_dir :
41- one = os .path .join (target_dir , "one " )
42- touch (one )
65+ no_x = os .path .join (target_dir , "no-x " )
66+ touch (no_x )
4367
44- two = os .path .join (target_dir , "two" )
45- touch (two )
46- chmod_plus_x (two )
68+ no_w = os .path .join (target_dir , "no-w" )
69+ touch (no_w )
70+ os .chmod (no_w , 0o444 )
71+
72+ with_x = os .path .join (target_dir , "with-x" )
73+ touch (with_x )
74+ chmod_plus_x (with_x )
4775
48- assert extract_perms (one ) != extract_perms (two )
76+ assert extract_perms (no_x ) != extract_perms (no_w ) != extract_perms ( with_x )
4977
5078 zip_file = os .path .join (target_dir , "test.zip" )
5179 with contextlib .closing (ZipFileEx (zip_file , "w" )) as zf :
52- zf .write (one , "one" )
53- zf .write (two , "two" )
80+ zf .write (no_x , "no-x" )
81+ zf .write (no_w , "no-w" )
82+ zf .write (with_x , "with-x" )
5483
55- yield zip_file , os .path .join (target_dir , "extract" ), one , two
84+ yield zip_file , os .path .join (target_dir , "extract" )
85+
86+
87+ def is_writeable (path ):
88+ # type: (str) -> bool
89+ return bool (os .stat (path ).st_mode & 0o222 )
90+
91+
92+ def is_executable (path ):
93+ # type: (str) -> bool
94+ return bool (os .stat (path ).st_mode & 0o111 )
5695
5796
5897def test_perm_preserving_zipfile_extractall ():
5998 # type: () -> None
60- with zip_fixture () as (zip_file , extract_dir , one , two ):
99+ with zip_fixture () as (zip_file , extract_dir ):
61100 with contextlib .closing (ZipFileEx (zip_file )) as zf :
62101 zf .extractall (extract_dir )
63102
64- assert extract_perms (one ) == extract_perms (os .path .join (extract_dir , "one" ))
65- assert extract_perms (two ) == extract_perms (os .path .join (extract_dir , "two" ))
103+ no_x = os .path .join (extract_dir , "no-x" )
104+ no_w = os .path .join (extract_dir , "no-w" )
105+ with_x = os .path .join (extract_dir , "with-x" )
106+
107+ assert not is_executable (no_x )
108+ assert not is_executable (no_w )
109+ assert is_executable (with_x )
110+
111+ files = [no_x , no_w , with_x ]
112+ assert all (is_writeable (f ) for f in files )
66113
67114
68115def test_perm_preserving_zipfile_extract ():
69116 # type: () -> None
70- with zip_fixture () as (zip_file , extract_dir , one , two ):
117+ with zip_fixture () as (zip_file , extract_dir ):
71118 with contextlib .closing (ZipFileEx (zip_file )) as zf :
72- zf .extract ("one" , path = extract_dir )
73- zf .extract ("two" , path = extract_dir )
119+ zf .extract ("no-x" , path = extract_dir )
120+ zf .extract ("no-w" , path = extract_dir )
121+ zf .extract ("with-x" , path = extract_dir )
122+
123+ no_x = os .path .join (extract_dir , "no-x" )
124+ no_w = os .path .join (extract_dir , "no-w" )
125+ with_x = os .path .join (extract_dir , "with-x" )
126+
127+ assert not is_executable (no_x )
128+ assert not is_executable (no_w )
129+ assert is_executable (with_x )
74130
75- assert extract_perms ( one ) == extract_perms ( os . path . join ( extract_dir , "one" ))
76- assert extract_perms ( two ) == extract_perms ( os . path . join ( extract_dir , "two" ) )
131+ files = [ no_x , no_w , with_x ]
132+ assert all ( is_writeable ( f ) for f in files )
77133
78134
79135def assert_chroot_perms (copyfn ):
@@ -98,8 +154,8 @@ def assert_chroot_perms(copyfn):
98154 with contextlib .closing (ZipFileEx (zip_path )) as zf :
99155 zf .extractall (extract_dir )
100156
101- assert extract_perms ( one ) == extract_perms (os .path .join (extract_dir , "one" ))
102- assert extract_perms ( two ) == extract_perms (os .path .join (extract_dir , "two" ))
157+ assert not is_executable (os .path .join (extract_dir , "one" ))
158+ assert is_executable (os .path .join (extract_dir , "two" ))
103159
104160
105161def test_chroot_perms_copy ():
0 commit comments