1414# See the License for the specific language governing permissions and
1515# limitations under the License.
1616
17- import itertools
1817import os
18+ import pathlib
1919import unittest
2020import stat
2121import subprocess
2424from pkg .private import manifest
2525
2626
27- class PkgInstallTest (unittest .TestCase ):
27+ class PkgInstallTestBase (unittest .TestCase ):
2828 @classmethod
2929 def setUpClass (cls ):
3030 cls .runfiles = runfiles .Create ()
@@ -36,8 +36,14 @@ def setUpClass(cls):
3636 cls .manifest_data = {}
3737
3838 for entry in manifest_entries :
39- cls .manifest_data [entry .dest ] = entry
40- cls .installdir = os .path .join (os .getenv ("TEST_TMPDIR" ), "installdir" )
39+ cls .manifest_data [pathlib .Path (entry .dest )] = entry
40+ cls .installdir = pathlib .Path (os .getenv ("TEST_TMPDIR" )) / "installdir"
41+
42+
43+ class PkgInstallTest (PkgInstallTestBase ):
44+ @classmethod
45+ def setUpClass (cls ):
46+ super ().setUpClass ()
4147 env = {}
4248 env .update (cls .runfiles .EnvVars ())
4349 subprocess .check_call ([
@@ -48,11 +54,11 @@ def setUpClass(cls):
4854 env = env )
4955
5056 def entity_type_at_path (self , path ):
51- if os . path .islink ( path ):
57+ if path .is_symlink ( ):
5258 return manifest .ENTRY_IS_LINK
53- elif os . path .isfile ( path ):
59+ elif path .is_file ( ):
5460 return manifest .ENTRY_IS_FILE
55- elif os . path .isdir ( path ):
61+ elif path .is_dir ( ):
5662 return manifest .ENTRY_IS_DIR
5763 else :
5864 # We can't infer what TreeArtifacts are by looking at them -- the
@@ -97,10 +103,13 @@ def assertEntryModeMatches(self, entry, actual_path,
97103
98104 def _find_tree_entry (self , path , owned_trees ):
99105 for tree_root in owned_trees :
100- if path == tree_root or path . startswith ( tree_root + "/" ):
106+ if self . _path_starts_with ( path , tree_root ):
101107 return tree_root
102108 return None
103109
110+ def _path_starts_with (self , path , other ):
111+ return path .parts [:len (other .parts )] == other .parts
112+
104113 def test_manifest_matches (self ):
105114 unowned_dirs = set ()
106115 owned_dirs = set ()
@@ -119,28 +128,17 @@ def test_manifest_matches(self):
119128 elif data .type == manifest .ENTRY_IS_TREE :
120129 owned_trees [dest ] = data
121130
122- # TODO(nacl): The initial stage of the accumulation returns an empty string,
123- # which end up in the set representing the root of the manifest.
124- # This may not be the best thing.
125- unowned_dirs .update ([p for p in itertools .accumulate (os .path .dirname (dest ).split ('/' ),
126- func = lambda accum , new : accum + '/' + new )])
131+ unowned_dirs .update (dest .parents )
127132
128133 # In the above loop, unowned_dirs contains all possible directories that
129134 # are in the manifest. Prune them here.
130135 unowned_dirs -= owned_dirs
131136
132137 # TODO: check for ownership (user, group)
133- found_entries = {dest : False for dest in self .manifest_data . keys () }
138+ found_entries = {dest : False for dest in self .manifest_data }
134139 for root , dirs , files in os .walk (self .installdir ):
135- rel_root_path = os .path .relpath (root , self .installdir )
136-
137- # The rest of this uses string comparison. To reduce potential
138- # confusion, ensure that the "." doesn't show up elsewhere.
139- #
140- # TODO(nacl) consider using pathlib here, which will reduce the
141- # need for path cleverness.
142- if rel_root_path == '.' :
143- rel_root_path = ''
140+ root = pathlib .Path (root )
141+ rel_root_path = root .relative_to (self .installdir )
144142
145143 # Directory ownership tests
146144 if len (files ) == 0 and len (dirs ) == 0 :
@@ -182,10 +180,10 @@ def test_manifest_matches(self):
182180 # needed. It maybe worth setting the keys in the manifest_data
183181 # dictionary to pathlib.Path or otherwise converting them to
184182 # native paths.
185- fpath = os . path . normpath ( "/" . join ([ root , f ]))
183+ fpath = root / f
186184 # The path inside the manifest (relative to the install
187185 # destdir).
188- rel_fpath = os . path . normpath ( "/" . join ([ rel_root_path , f ]))
186+ rel_fpath = rel_root_path / f
189187 entity_in_manifest = rel_fpath in self .manifest_data
190188 entity_tree_root = self ._find_tree_entry (rel_fpath , owned_trees )
191189 if not entity_in_manifest and not entity_tree_root :
@@ -211,5 +209,19 @@ def test_manifest_matches(self):
211209 self .assertEqual (num_missing , 0 )
212210
213211
212+ class WipeTest (PkgInstallTestBase ):
213+ def test_wipe (self ):
214+ self .installdir .mkdir (exist_ok = True )
215+ (self .installdir / "should_be_deleted.txt" ).touch ()
216+
217+ subprocess .check_call ([
218+ self .runfiles .Rlocation ("rules_pkg/tests/install/test_installer" ),
219+ "--destdir" , self .installdir ,
220+ "--wipe_destdir" ,
221+ ],
222+ env = self .runfiles .EnvVars ())
223+ self .assertFalse ((self .installdir / "should_be_deleted.txt" ).exists ())
224+
225+
214226if __name__ == "__main__" :
215227 unittest .main ()
0 commit comments