From d53691c3dc711ff1fb1cadb8e29736397025addf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kl=C3=B6tzke?= Date: Sun, 8 Dec 2024 21:35:23 +0100 Subject: [PATCH] test: add generic git refs tests --- test/unit/test_input_gitscm.py | 153 ++++++++++++++++++++++++++ test/unit/test_input_gitscm_status.py | 95 ++++++++++++++++ 2 files changed, 248 insertions(+) diff --git a/test/unit/test_input_gitscm.py b/test/unit/test_input_gitscm.py index fa0480bfc..c43130d1c 100644 --- a/test/unit/test_input_gitscm.py +++ b/test/unit/test_input_gitscm.py @@ -1009,3 +1009,156 @@ def testFastForwardUnknownTrackingOldState(self): self.invokeGit(workspace, scm) self.verify(workspace, "changed") + + +class TestGenericRef(TestCase): + + def setUp(self): + self.__repodir = tempfile.TemporaryDirectory() + self.repodir = self.__repodir.name + + # Create a commit and a new ref "refs/bob/foobar" that points to that + # commit. + cmds = """\ + git init . + git config user.email "bob@bob.bob" + git config user.name test + echo -n "hello world" > test.txt + git add test.txt + git commit -m "first commit" + git update-ref refs/bob/foo HEAD + + echo -n "update" > test.txt + git commit -a -m "second commit" + git update-ref refs/bob/bar HEAD + + echo -n "final" > test.txt + git commit -a -m "third commit" + """ + subprocess.check_call([getBashPath(), "-c", cmds], cwd=self.repodir) + + def tearDown(self): + self.__repodir.cleanup() + + def createGitScm(self, spec = {}): + s = { + 'scm' : "git", + 'url' : "file://" + os.path.abspath(self.repodir), + 'recipe' : "foo.yaml#0", + '__source' : "Recipe foo", + } + s.update(spec) + return GitScm(s) + + def invokeGit(self, workspace, scm): + spec = MagicMock(workspaceWorkspacePath=workspace, envWhiteList=set()) + invoker = Invoker(spec, True, True, True, True, True, False) + runInEventLoop(scm.invoke(invoker)) + + def switchGit(self, workspace, scm, oldScm): + spec = MagicMock(workspaceWorkspacePath=workspace, envWhiteList=set()) + invoker = Invoker(spec, True, True, True, True, True, False) + runInEventLoop(scm.switch(invoker, oldScm)) + + def verify(self, workspace, content, file="test.txt"): + with open(os.path.join(workspace, file)) as f: + self.assertEqual(f.read(), content) + + def testCheckout(self): + """Test simple checkout""" + scm = self.createGitScm({ 'rev' : "refs/bob/foo" }) + with tempfile.TemporaryDirectory() as workspace: + self.invokeGit(workspace, scm) + self.verify(workspace, "hello world") + # Should also work again + self.invokeGit(workspace, scm) + self.verify(workspace, "hello world") + + def testCheckoutRebase(self): + """Test checkout with rebase enabled""" + scm = self.createGitScm({ + 'rev' : "refs/bob/foo", + 'rebase' : True + }) + with tempfile.TemporaryDirectory() as workspace: + self.invokeGit(workspace, scm) + self.verify(workspace, "hello world") + # Should also work again + self.invokeGit(workspace, scm) + self.verify(workspace, "hello world") + + def testSwitch(self): + """Test switch from branch to ref and back""" + with tempfile.TemporaryDirectory() as workspace: + # default master branch + scm = self.createGitScm() + self.invokeGit(workspace, scm) + self.verify(workspace, "final") + + # switch to ref + oldScm = scm + scm = self.createGitScm({ 'rev' : "refs/bob/foo" }) + self.assertTrue(scm.canSwitch(oldScm)) + self.switchGit(workspace, scm, oldScm) + self.verify(workspace, "hello world") + + # switch to other ref + oldScm = scm + scm = self.createGitScm({ 'rev' : "refs/bob/bar" }) + self.assertTrue(scm.canSwitch(oldScm)) + self.switchGit(workspace, scm, oldScm) + self.verify(workspace, "update") + + # back to master branch + oldScm = scm + scm = self.createGitScm() + self.assertTrue(scm.canSwitch(oldScm)) + self.switchGit(workspace, scm, oldScm) + self.verify(workspace, "final") + + def testSwitchFailIfCommitted(self): + """That that switch fails if user moved away from ref""" + with tempfile.TemporaryDirectory() as workspace: + scm = self.createGitScm({ 'rev' : "refs/bob/foo" }) + self.invokeGit(workspace, scm) + + cmds = """\ + git config user.email "bob@bob.bob" + git config user.name test + echo -n "changed" > test.txt + git commit -a -m "user commit" + """ + subprocess.check_call([getBashPath(), "-c", cmds], cwd=workspace) + + oldScm = scm + scm = self.createGitScm() + self.assertTrue(scm.canSwitch(oldScm)) + with self.assertRaises(InvocationError): + self.switchGit(workspace, scm, oldScm) + + def testUpdateRef(self): + """Verify rebase works on moving refs""" + + with tempfile.TemporaryDirectory() as workspace: + scm = self.createGitScm({ 'rev' : "refs/bob/foo", 'rebase' : True }) + self.invokeGit(workspace, scm) + self.verify(workspace, "hello world") + + # make some local commit to provoke a real rebase + cmds = """\ + git config user.email "bob@bob.bob" + git config user.name test + echo -n "added" > new.txt + git add new.txt + git commit -a -m "user commit" + """ + subprocess.check_call([getBashPath(), "-c", cmds], cwd=workspace) + + # update ref in upstream repo + cmds = "git update-ref refs/bob/foo HEAD" + subprocess.check_call([getBashPath(), "-c", cmds], cwd=self.repodir) + + # checkout again, verify rebase + self.invokeGit(workspace, scm) + self.verify(workspace, "final") + self.verify(workspace, "added", "new.txt") diff --git a/test/unit/test_input_gitscm_status.py b/test/unit/test_input_gitscm_status.py index 671ede73a..b59134e16 100644 --- a/test/unit/test_input_gitscm_status.py +++ b/test/unit/test_input_gitscm_status.py @@ -470,3 +470,98 @@ def testSpecificUnexpectedSubmodule(self): self.assertEqual(status.flags, {ScmTaint.modified}) self.assertTrue(status.dirty) self.assertTrue(audit["dirty"]) + + +class TestRefStatus(TestCase): + + @classmethod + def setUpClass(cls): + cls.__repodir = tempfile.TemporaryDirectory() + cls.repodir = cls.__repodir.name + + cmds = """\ + git init . + git config user.email "bob@bob.bob" + git config user.name test + + echo -n "hello world" > test.txt + git add test.txt + git commit -m "first commit" + git update-ref refs/bob/foo HEAD + + echo -n "update" > test.txt + git commit -a -m "second commit" + """ + subprocess.check_call([getBashPath(), "-c", cmds], cwd=cls.repodir) + + @classmethod + def tearDownClass(cls): + cls.__repodir.cleanup() + + def setUp(self): + self.__workspaceDir = tempfile.TemporaryDirectory() + self.workspace = self.__workspaceDir.name + + def tearDown(self): + self.__workspaceDir.cleanup() + + def createGitScm(self, spec = {}): + s = { + 'scm' : "git", + 'url' : "file://" + os.path.abspath(self.repodir), + 'recipe' : "foo.yaml#0", + '__source' : "Recipe foo", + } + s.update(spec) + return GitScm(s) + + def invokeGit(self, scm): + spec = MagicMock(workspaceWorkspacePath=self.workspace, envWhiteList=set()) + invoker = Invoker(spec, True, True, True, True, True, False) + runInEventLoop(scm.invoke(invoker)) + + def statusGitScm(self, scm): + status = scm.status(self.workspace) + _git, dir, extra = scm.getAuditSpec() + audit = runInEventLoop(GitAudit.fromDir(self.workspace, dir, extra)).dump() + return status, audit + + def testClean(self): + scm = self.createGitScm({ "rev" : "refs/bob/foo" }) + self.invokeGit(scm) + status, audit = self.statusGitScm(scm) + + self.assertEqual(status.flags, set()) + self.assertTrue(status.clean) + self.assertFalse(audit["dirty"]) + + def testModified(self): + scm = self.createGitScm({ "rev" : "refs/bob/foo" }) + self.invokeGit(scm) + + with open(os.path.join(self.workspace, "test.txt"), "w") as f: + f.write("modified") + + status, audit = self.statusGitScm(scm) + self.assertEqual(status.flags, {ScmTaint.modified}) + self.assertTrue(status.dirty) + self.assertTrue(audit["dirty"]) + + def testCommitted(self): + scm = self.createGitScm({ "rev" : "refs/bob/foo" }) + self.invokeGit(scm) + + cmds = """\ + git config user.email "bob@bob.bob" + git config user.name test + + echo "test changed" > test.txt + git commit -a -m "user commit" + """ + subprocess.check_call([getBashPath(), "-c", cmds], cwd=self.workspace) + + status, audit = self.statusGitScm(scm) + self.assertEqual(status.flags, {ScmTaint.switched, ScmTaint.unpushed_local}) + self.assertTrue(status.dirty) + self.assertFalse(audit["dirty"]) +