[Notes] [Git][BuildStream/buildstream][jmac/cas_to_cas_oct] 4 commits: hack: remove files which previously blocked directory creation



Title: GitLab

Jim MacArthur pushed to branch jmac/cas_to_cas_oct at BuildStream / buildstream

Commits:

2 changed files:

Changes:

  • buildstream/storage/_casbaseddirectory.py
    ... ... @@ -387,7 +387,7 @@ class CasBasedDirectory(Directory):
    387 387
             return directory
    
    388 388
     
    
    389 389
         
    
    390
    -    def _resolve(self, name, absolute_symlinks_resolve=True, force_create=False):
    
    390
    +    def _resolve(self, name, absolute_symlinks_resolve=True, force_create=False, first_seen_object = None):
    
    391 391
             """ Resolves any name to an object. If the name points to a symlink in
    
    392 392
             this directory, it returns the thing it points to,
    
    393 393
             recursively. Returns a CasBasedDirectory, FileNode or
    
    ... ... @@ -406,6 +406,14 @@ class CasBasedDirectory(Directory):
    406 406
                 return index_entry.pb_object
    
    407 407
             
    
    408 408
             assert isinstance(index_entry.pb_object, remote_execution_pb2.SymlinkNode)
    
    409
    +
    
    410
    +        if first_seen_object is None:
    
    411
    +            first_seen_object = index_entry.pb_object
    
    412
    +        else:
    
    413
    +            if index_entry.pb_object == first_seen_object:
    
    414
    +                ### Infinite symlink loop detected ###
    
    415
    +                return None
    
    416
    +        
    
    409 417
             print("Resolving '{}': This is a symlink node in the current directory.".format(name))
    
    410 418
             symlink = index_entry.pb_object
    
    411 419
             components = symlink.target.split(CasBasedDirectory._pb2_path_sep)
    
    ... ... @@ -439,7 +447,7 @@ class CasBasedDirectory(Directory):
    439 447
                         directory = directory.parent
    
    440 448
                 else:
    
    441 449
                     if c in directory.index:
    
    442
    -                    f = directory._resolve(c, absolute_symlinks_resolve)
    
    450
    +                    f = directory._resolve(c, absolute_symlinks_resolve, first_seen_object=first_seen_object)
    
    443 451
                         # Ultimately f must now be a file or directory
    
    444 452
                         if isinstance(f, CasBasedDirectory):
    
    445 453
                             directory = f
    
    ... ... @@ -453,7 +461,10 @@ class CasBasedDirectory(Directory):
    453 461
                                 directory = directory.descend(c, create=True)
    
    454 462
                             elif components:
    
    455 463
                                 # Oh dear. We have components left to resolve, but the one we're trying to resolve points to a file.
    
    456
    -                            raise VirtualDirectoryError("Reached a file called {} while trying to resolve a symlink; cannot proceed".format(c))
    
    464
    +                            print("Trying to resolve {}, but found {} was a file.".format(symlink.target, c))
    
    465
    +                            self.delete_entry(c)
    
    466
    +                            directory = directory.descend(c, create=True)
    
    467
    +                            #raise VirtualDirectoryError("Reached a file called {} while trying to resolve a symlink; cannot proceed".format(c))
    
    457 468
                             else:
    
    458 469
                                 return f
    
    459 470
                     else:
    
    ... ... @@ -842,35 +853,34 @@ class CasBasedDirectory(Directory):
    842 853
             if self.parent:
    
    843 854
                 self.parent._recalculate_recursing_up(self)
    
    844 855
             
    
    845
    -        # Duplicate the current directory
    
    846
    -
    
    856
    +        duplicate_test = False
    
    847 857
             
    
    848 858
             print("Original CAS before CAS-based import: {}".format(self.show_files_recursive()))
    
    849 859
             print("Original CAS hash: {}".format(self.ref.hash))
    
    850 860
             duplicate_cas = None
    
    851 861
             self._verify_unique()
    
    852 862
             if isinstance(external_pathspec, CasBasedDirectory):
    
    853
    -            duplicate_cas = CasBasedDirectory(self.context, ref=copy.copy(self.ref))
    
    854
    -            duplicate_cas._verify_unique()
    
    863
    +            if duplicate_test:
    
    864
    +                duplicate_cas = CasBasedDirectory(self.context, ref=copy.copy(self.ref))
    
    865
    +                duplicate_cas._verify_unique()
    
    866
    +                print("Duplicated CAS before file-based import: {}".format(duplicate_cas.show_files_recursive()))
    
    867
    +                print("Duplicate CAS hash: {}".format(duplicate_cas.ref.hash))
    
    855 868
                 print("-"*80 + "Performing direct CAS-to-CAS import")
    
    856
    -            print("Duplicated CAS before file-based import: {}".format(duplicate_cas.show_files_recursive()))
    
    857
    -            print("Duplicate CAS hash: {}".format(duplicate_cas.ref.hash))
    
    858 869
                 result = self._import_cas_into_cas(external_pathspec, files=files)
    
    859 870
                 self._verify_unique()
    
    860 871
                 print("Result of cas-to-cas import: {}".format(self.show_files_recursive()))
    
    861 872
                 print("-"*80 + "Performing round-trip import via file system")
    
    862
    -            with tempfile.TemporaryDirectory(prefix="roundtrip") as tmpdir:
    
    863
    -                external_pathspec.export_files(tmpdir)
    
    864
    -                if files is None:
    
    865
    -                    files = list(list_relative_paths(tmpdir))
    
    866
    -                print("Importing from filesystem: filelist is: {}".format(files))
    
    867
    -                duplicate_cas._import_files_from_directory(tmpdir, files=files)
    
    868
    -                duplicate_cas._recalculate_recursing_down()
    
    869
    -                if duplicate_cas.parent:
    
    870
    -                    duplicate_cas.parent._recalculate_recursing_up(duplicate_cas)
    
    871
    -                print("Result of direct import: {}".format(duplicate_cas.show_files_recursive()))
    
    872
    -               
    
    873
    -
    
    873
    +            if duplicate_test:
    
    874
    +                with tempfile.TemporaryDirectory(prefix="roundtrip") as tmpdir:
    
    875
    +                    external_pathspec.export_files(tmpdir)
    
    876
    +                    if files is None:
    
    877
    +                        files = list(list_relative_paths(tmpdir))
    
    878
    +                    print("Importing from filesystem: filelist is: {}".format(files))
    
    879
    +                    duplicate_cas._import_files_from_directory(tmpdir, files=files)
    
    880
    +                    duplicate_cas._recalculate_recursing_down()
    
    881
    +                    if duplicate_cas.parent:
    
    882
    +                        duplicate_cas.parent._recalculate_recursing_up(duplicate_cas)
    
    883
    +                    print("Result of direct import: {}".format(duplicate_cas.show_files_recursive()))
    
    874 884
             else:
    
    875 885
                 print("-"*80 + "Performing initial import")
    
    876 886
                 if isinstance(external_pathspec, FileBasedDirectory):
    

  • tests/storage/virtual_directory_import.py
    ... ... @@ -20,11 +20,17 @@ class FakeContext():
    20 20
     # 'F' (file), 'S' (symlink) or 'D' (directory) with content being the contents
    
    21 21
     # for a file or the destination for a symlink.
    
    22 22
     root_filesets = [
    
    23
    +    # Arbitrary test sets
    
    23 24
         [('a/b/c/textfile1', 'F', 'This is textfile 1\n')],
    
    24 25
         [('a/b/c/textfile1', 'F', 'This is the replacement textfile 1\n')],
    
    25 26
         [('a/b/d', 'D', '')],
    
    26 27
         [('a/b/c', 'S', '/a/b/d')],
    
    27
    -    [('a/b/d', 'D', ''), ('a/b/c', 'S', '/a/b/d')]
    
    28
    +    [('a/b/d', 'S', '/a/b/c')],
    
    29
    +    [('a/b/d', 'D', ''), ('a/b/c', 'S', '/a/b/d')], 
    
    30
    +    [('a/b/c', 'D', ''), ('a/b/d', 'S', '/a/b/c')], 
    
    31
    +    [('a/b', 'F', 'This is textfile 1\n')],
    
    32
    +    [('a/b/c', 'F', 'This is textfile 1\n')],
    
    33
    +    [('a/b/c', 'D', '')]
    
    28 34
     ]
    
    29 35
     
    
    30 36
     empty_hash_ref = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
    
    ... ... @@ -178,8 +184,9 @@ def _import_test(tmpdir, original, overlay, generator_function, verify_contents=
    178 184
                         assert os.path.islink(realpath)
    
    179 185
                         assert os.readlink(realpath) == content
    
    180 186
                 elif typename == 'D':
    
    181
    -                # Note that isdir accepts symlinks to dirs, so a symlink to a dir is acceptable.
    
    182
    -                assert os.path.isdir(realpath)
    
    187
    +                # We can't do any more tests than this because it depends on things present in the original. Blank directories
    
    188
    +                # here will be ignored and the original left in place.
    
    189
    +                assert os.path.lexists(realpath)
    
    183 190
     
    
    184 191
         # Now do the same thing with filebaseddirectories and check the contents match
    
    185 192
         d3 = create_new_casdir(original, fake_context, tmpdir)
    
    ... ... @@ -187,14 +194,15 @@ def _import_test(tmpdir, original, overlay, generator_function, verify_contents=
    187 194
         d3.import_files(d2)
    
    188 195
         assert d.ref.hash == d3.ref.hash
    
    189 196
     
    
    190
    -@pytest.mark.parametrize("original,overlay", combinations(range(1,6)))
    
    197
    +@pytest.mark.parametrize("original,overlay", combinations(range(1,len(root_filesets)+1)))
    
    191 198
     def test_fixed_cas_import(cli, tmpdir, original, overlay):
    
    192 199
         _import_test(tmpdir, original, overlay, generate_import_roots, verify_contents=True)
    
    193 200
     
    
    194 201
     @pytest.mark.parametrize("original,overlay", combinations(range(1,11)))
    
    195
    -def test_random_cas_import(cli, tmpdir, original, overlay):
    
    202
    +def test_random_cas_import_fast(cli, tmpdir, original, overlay):
    
    196 203
         _import_test(tmpdir, original, overlay, generate_random_root, verify_contents=False)
    
    197 204
     
    
    205
    +    
    
    198 206
     def _listing_test(tmpdir, root, generator_function):
    
    199 207
         fake_context = FakeContext()
    
    200 208
         fake_context.artifactdir = tmpdir
    



  • [Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]