diff mbox series

[RFC,DO-NOT-MERGE] tests: add test that LFS objects are resolved also inside submodules

Message ID 20221018193746.3599845-1-Martin.Jansa@gmail.com
State New
Headers show
Series [RFC,DO-NOT-MERGE] tests: add test that LFS objects are resolved also inside submodules | expand

Commit Message

Martin Jansa Oct. 18, 2022, 7:37 p.m. UTC
* RFC because it will currently fail on hosts where LFS isn't
  enabled in .gitconfig or /etc/gitconfig, but it documents why
  people are seeing different results in repos with LFS objects
  e.g. vulkan-samples recipe failing in do_unpack

  I'm not sure what's the expected behavior here which would work
  for everybody, lets discuss.

[YOCTO #14938]

Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
---
 lib/bb/tests/fetch.py | 68 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 68 insertions(+)
diff mbox series

Patch

diff --git a/lib/bb/tests/fetch.py b/lib/bb/tests/fetch.py
index b4ed691f..a38df519 100644
--- a/lib/bb/tests/fetch.py
+++ b/lib/bb/tests/fetch.py
@@ -2199,6 +2199,7 @@  class GitLfsTest(FetcherTest):
 
         self.gitdir = os.path.join(self.tempdir, 'git')
         self.srcdir = os.path.join(self.tempdir, 'gitsource')
+        self.srcdirsm = os.path.join(self.tempdir, 'gitsource-submodule')
 
         self.d.setVar('WORKDIR', self.tempdir)
         self.d.setVar('S', self.gitdir)
@@ -2213,8 +2214,18 @@  class GitLfsTest(FetcherTest):
         self.git_init(cwd=self.srcdir)
         with open(os.path.join(self.srcdir, '.gitattributes'), 'wt') as attrs:
             attrs.write('*.mp3 filter=lfs -text')
+        with open(os.path.join(self.srcdir, 'lalala.mp3'), 'wt') as attrs:
+            attrs.write('lalala')
         self.git(['add', '.gitattributes'], cwd=self.srcdir)
         self.git(['commit', '-m', "attributes", '.gitattributes'], cwd=self.srcdir)
+        self.git(['add', 'lalala.mp3'], cwd=self.srcdir)
+        self.git(['commit', '-m', "lalala", 'lalala.mp3'], cwd=self.srcdir)
+
+        # set another git repo which will have the first 1 as a submodule
+        bb.utils.mkdirhier(self.srcdirsm)
+        self.git_init(cwd=self.srcdirsm)
+        self.git(['submodule', 'add', self.srcdir], cwd=self.srcdirsm)
+        self.git(['commit', '-am', "submodule"], cwd=self.srcdirsm)
 
     def fetch(self, uri=None, download=True):
         uris = self.d.getVar('SRC_URI').split()
@@ -2277,6 +2288,63 @@  class GitLfsTest(FetcherTest):
         shutil.rmtree(self.gitdir, ignore_errors=True)
         fetcher.unpack(self.d.getVar('WORKDIR'))
 
+    def test_lfs_in_submodule_enabled(self):
+        import shutil
+
+        uri = 'gitsm://%s;protocol=file;lfs=1;branch=master' % self.srcdirsm
+        self.d.setVar('SRC_URI', uri)
+
+        # In contrast to regular fetch() here the LFS isn't in the
+        # main repo, but in its submodule
+        fetcher, ud = self.fetch()
+        self.assertIsNotNone(ud.method._find_git_lfs)
+
+        # If git-lfs can be found, the unpack should be successful. A
+        # live copy of git-lfs is not required for this case, so
+        # unconditionally forge its presence.
+        ud.method._find_git_lfs = lambda d: True
+        shutil.rmtree(self.gitdir, ignore_errors=True)
+        fetcher.unpack(self.d.getVar('WORKDIR'))
+        self.assertTrue(os.path.exists(os.path.join(self.d.getVar('WORKDIR'), 'git', 'gitsource', 'lalala.mp3')))
+        self.assertEqual(open(os.path.join(self.d.getVar('WORKDIR'), 'git', 'gitsource', 'lalala.mp3'), 'r').read(), 'lalala')
+
+    def test_lfs_in_submodule_disabled(self):
+        import shutil
+
+        uri = 'gitsm://%s;protocol=file;lfs=0;branch=master' % self.srcdirsm
+        self.d.setVar('SRC_URI', uri)
+
+        # In contrast to regular fetch() here the LFS isn't in the
+        # main repo, but in its submodule
+        fetcher, ud = self.fetch()
+        self.assertIsNotNone(ud.method._find_git_lfs)
+
+        # If git-lfs can be found, the unpack should be successful. A
+        # live copy of git-lfs is not required for this case, so
+        # unconditionally forge its presence.
+        ud.method._find_git_lfs = lambda d: True
+        shutil.rmtree(self.gitdir, ignore_errors=True)
+        fetcher.unpack(self.d.getVar('WORKDIR'))
+        self.assertTrue(os.path.exists(os.path.join(self.d.getVar('WORKDIR'), 'git', 'gitsource', 'lalala.mp3')))
+        # There should be something like:
+        #     version https://git-lfs.github.com/spec/v1
+        #     oid sha256:3f29e1b2b05f8371595dc761fed8e8b37544b38d56dfce81a551b46c82f2f56b
+        #     size 6
+        # not the actual 'lalala' content, but that depends on git config
+        # with:
+        # [filter "lfs"]
+        #       smudge = git-lfs smudge -- %f
+        #       process = git-lfs filter-process
+        #       required = true
+        #       clean = git-lfs clean -- %f
+        # it works correctly, but might fail in git smudge when the objects aren't available
+        # and without smudge and process it fails with:
+        # fatal: lalala.mp3: smudge filter lfs failed
+        # fatal: unable to checkout submodule 'gitsource'
+        # and without this whole "lfs" section it will contain 'lalala' here instead of the link
+        # even when lfs is explicitly disabled in SRC_URI
+        self.assertNotEqual(open(os.path.join(self.d.getVar('WORKDIR'), 'git', 'gitsource', 'lalala.mp3'), 'r').read(), 'lalala')
+
 class GitURLWithSpacesTest(FetcherTest):
     test_git_urls = {
         "git://tfs-example.org:22/tfs/example%20path/example.git;branch=master" : {