From f0aeb220def22edfac9838288ad251f86da782c1 Mon Sep 17 00:00:00 2001 From: Gavin Mak Date: Tue, 8 Aug 2023 04:43:36 +0000 Subject: sync: Warn if partial sync state is detected Partial syncs are not supported and can lead to strange behavior like deleting files. Explicitly warn users on partial sync. Bug: b/286126621, b/271507654 Change-Id: I471f78ac5942eb855bc34c80af47aa561dfa61e8 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/382154 Reviewed-by: Jason Chang Reviewed-by: Aravind Vasudevan Tested-by: Gavin Mak Commit-Queue: Gavin Mak Reviewed-by: Mike Frysinger Reviewed-by: Josip Sokcevic --- tests/test_subcmds_sync.py | 61 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) (limited to 'tests/test_subcmds_sync.py') diff --git a/tests/test_subcmds_sync.py b/tests/test_subcmds_sync.py index 00c34852..7cc93e39 100644 --- a/tests/test_subcmds_sync.py +++ b/tests/test_subcmds_sync.py @@ -175,12 +175,73 @@ class LocalSyncState(unittest.TestCase): os.listdir(self.repodir), [".repo_localsyncstate.json"] ) + def test_partial_sync(self): + """Partial sync state is detected.""" + with open(self.state._path, "w") as f: + f.write( + """ + { + "projA": { + "last_fetch": 5, + "last_checkout": 5 + }, + "projB": { + "last_fetch": 5, + "last_checkout": 5 + } + } + """ + ) + + # Initialize state to read from the new file. + self.state = self._new_state() + projB = mock.MagicMock(relpath="projB") + self.assertEqual(self.state.IsPartiallySynced(), False) + + self.state.SetFetchTime(projB) + self.state.SetCheckoutTime(projB) + self.assertEqual(self.state.IsPartiallySynced(), True) + def test_nonexistent_project(self): """Unsaved projects don't have data.""" p = mock.MagicMock(relpath="projC") self.assertEqual(self.state.GetFetchTime(p), None) self.assertEqual(self.state.GetCheckoutTime(p), None) + def test_prune_removed_projects(self): + """Removed projects are pruned.""" + with open(self.state._path, "w") as f: + f.write( + """ + { + "projA": { + "last_fetch": 5 + }, + "projB": { + "last_fetch": 7 + } + } + """ + ) + + def mock_exists(path): + if "projA" in path: + return False + return True + + projA = mock.MagicMock(relpath="projA") + projB = mock.MagicMock(relpath="projB") + self.state = self._new_state() + self.assertEqual(self.state.GetFetchTime(projA), 5) + self.assertEqual(self.state.GetFetchTime(projB), 7) + with mock.patch("os.path.exists", side_effect=mock_exists): + self.state.PruneRemovedProjects() + self.assertIsNone(self.state.GetFetchTime(projA)) + + self.state = self._new_state() + self.assertIsNone(self.state.GetFetchTime(projA)) + self.assertEqual(self.state.GetFetchTime(projB), 7) + class GetPreciousObjectsState(unittest.TestCase): """Tests for _GetPreciousObjectsState.""" -- cgit v1.2.3-54-g00ecf