@@ -20,6 +20,7 @@ import tarfile
from bb.fetch2 import URI
from bb.fetch2 import FetchMethod
import bb
+import bb.utils
from bb.tests.support.httpserver import HTTPService
def skipIfNoNetwork():
@@ -27,6 +28,18 @@ def skipIfNoNetwork():
return unittest.skip("network test")
return lambda f: f
+
+@contextlib.contextmanager
+def hide_directory(directory):
+ """Hide the given directory and restore it after the context is left"""
+ temp_name = directory + ".bak"
+ os.rename(directory, temp_name)
+ try:
+ yield
+ finally:
+ os.rename(temp_name, directory)
+
+
class TestTimeout(Exception):
# Indicate to pytest that this is not a test suite
__test__ = False
@@ -2308,26 +2321,113 @@ class GitLfsTest(FetcherTest):
unpacked_lfs_file = os.path.join(self.d.getVar('WORKDIR'), 'git', "Cat_poster_1.jpg")
return unpacked_lfs_file
+ @skipIfNoGitLFS()
+ def test_gitsm_lfs(self):
+ """Test that the gitsm fetcher caches objects stored via LFS"""
+ self.git(["lfs", "install", "--local"], cwd=self.srcdir)
+
+ def fetch_and_verify(revision, filename, content):
+ self.d.setVar('SRCREV', revision)
+ fetcher, ud = self.fetch()
+
+ with hide_directory(submoduledir), hide_directory(self.srcdir):
+ workdir = self.d.getVar('WORKDIR')
+ fetcher.unpack(workdir)
+
+ with open(os.path.join(workdir, "git", filename)) as f:
+ self.assertEqual(f.read(), content)
+
+ # Create the git repository that will later be used as a submodule
+ submoduledir = self.tempdir + "/submodule"
+ bb.utils.mkdirhier(submoduledir)
+ self.git_init(submoduledir)
+ self.git(["lfs", "install", "--local"], cwd=submoduledir)
+ self.commit_file('.gitattributes', '*.mp3 filter=lfs -text', cwd=submoduledir)
+
+ submodule_commit_1 = self.commit_file("a.mp3", "submodule version 1", cwd=submoduledir)
+ _ = self.commit_file("a.mp3", "submodule version 2", cwd=submoduledir)
+
+ # Add the submodule to the repository at its current HEAD revision
+ self.git(["-c", "protocol.file.allow=always", "submodule", "add", submoduledir, "submodule"],
+ cwd=self.srcdir)
+ base_commit_1 = self.commit()
+
+ # Let the submodule point at a different revision
+ self.git(["checkout", submodule_commit_1], self.srcdir + "/submodule")
+ self.git(["add", "submodule"], cwd=self.srcdir)
+ base_commit_2 = self.commit()
+
+ # Add a LFS file to the repository
+ base_commit_3 = self.commit_file("a.mp3", "version 1")
+ # Update the added LFS file
+ base_commit_4 = self.commit_file("a.mp3", "version 2")
+
+ self.d.setVar('SRC_URI', "gitsm://%s;protocol=file;lfs=1;branch=master" % self.srcdir)
+
+ # Verify that LFS objects referenced from submodules are fetched and checked out
+ fetch_and_verify(base_commit_1, "submodule/a.mp3", "submodule version 2")
+ # Verify that the repository inside the download cache of a submodile is extended with any
+ # additional LFS objects needed when checking out a different revision.
+ fetch_and_verify(base_commit_2, "submodule/a.mp3", "submodule version 1")
+ # Verify that LFS objects referenced from the base repository are fetched and checked out
+ fetch_and_verify(base_commit_3, "a.mp3", "version 1")
+ # Verify that the cached repository is extended with any additional LFS objects required
+ # when checking out a different revision.
+ fetch_and_verify(base_commit_4, "a.mp3", "version 2")
+
+ @skipIfNoGitLFS()
+ def test_gitsm_lfs_disabled(self):
+ """Test that the gitsm fetcher does not use LFS when explicitly disabled"""
+ self.git(["lfs", "install", "--local"], cwd=self.srcdir)
+
+ def fetch_and_verify(revision, filename, content):
+ self.d.setVar('SRCREV', revision)
+ fetcher, ud = self.fetch()
+
+ with hide_directory(submoduledir), hide_directory(self.srcdir):
+ workdir = self.d.getVar('WORKDIR')
+ fetcher.unpack(workdir)
+
+ with open(os.path.join(workdir, "git", filename)) as f:
+ # Assume that LFS did not perform smudging when the expected content is
+ # missing.
+ self.assertNotEqual(f.read(), content)
+
+ # Create the git repository that will later be used as a submodule
+ submoduledir = self.tempdir + "/submodule"
+ bb.utils.mkdirhier(submoduledir)
+ self.git_init(submoduledir)
+ self.git(["lfs", "install", "--local"], cwd=submoduledir)
+ self.commit_file('.gitattributes', '*.mp3 filter=lfs -text', cwd=submoduledir)
+
+ submodule_commit_1 = self.commit_file("a.mp3", "submodule version 1", cwd=submoduledir)
+
+ # Add the submodule to the repository at its current HEAD revision
+ self.git(["-c", "protocol.file.allow=always", "submodule", "add", submoduledir, "submodule"],
+ cwd=self.srcdir)
+ base_commit_1 = self.commit()
+
+ # Add a LFS file to the repository
+ base_commit_2 = self.commit_file("a.mp3", "version 1")
+
+ self.d.setVar('SRC_URI', "gitsm://%s;protocol=file;lfs=1;branch=master;lfs=0" % self.srcdir)
+
+ # Verify that LFS objects referenced from submodules are not fetched nor checked out
+ fetch_and_verify(base_commit_1, "submodule/a.mp3", "submodule version 1")
+ # Verify that the LFS objects referenced from the base repository are not fetched nor
+ # checked out
+ fetch_and_verify(base_commit_2, "a.mp3", "version 1")
+
@skipIfNoGitLFS()
def test_fetch_lfs_on_srcrev_change(self):
"""Test if fetch downloads missing LFS objects when a different revision within an existing repository is requested"""
self.git(["lfs", "install", "--local"], cwd=self.srcdir)
- @contextlib.contextmanager
- def hide_upstream_repository():
- """Hide the upstream repository to make sure that git lfs cannot pull from it"""
- temp_name = self.srcdir + ".bak"
- os.rename(self.srcdir, temp_name)
- try:
- yield
- finally:
- os.rename(temp_name, self.srcdir)
-
def fetch_and_verify(revision, filename, content):
self.d.setVar('SRCREV', revision)
fetcher, ud = self.fetch()
- with hide_upstream_repository():
+ with hide_directory(self.srcdir):
workdir = self.d.getVar('WORKDIR')
fetcher.unpack(workdir)