diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test_subcmds_sync.py | 181 |
1 files changed, 180 insertions, 1 deletions
diff --git a/tests/test_subcmds_sync.py b/tests/test_subcmds_sync.py index 60f283af..e7213ed9 100644 --- a/tests/test_subcmds_sync.py +++ b/tests/test_subcmds_sync.py | |||
| @@ -310,6 +310,16 @@ class FakeProject: | |||
| 310 | self.name = name or relpath | 310 | self.name = name or relpath |
| 311 | self.objdir = objdir or relpath | 311 | self.objdir = objdir or relpath |
| 312 | 312 | ||
| 313 | self.use_git_worktrees = False | ||
| 314 | self.UseAlternates = False | ||
| 315 | self.manifest = mock.MagicMock() | ||
| 316 | self.manifest.GetProjectsWithName.return_value = [self] | ||
| 317 | self.config = mock.MagicMock() | ||
| 318 | self.EnableRepositoryExtension = mock.MagicMock() | ||
| 319 | |||
| 320 | def RelPath(self, local=None): | ||
| 321 | return self.relpath | ||
| 322 | |||
| 313 | def __str__(self): | 323 | def __str__(self): |
| 314 | return f"project: {self.relpath}" | 324 | return f"project: {self.relpath}" |
| 315 | 325 | ||
| @@ -531,7 +541,11 @@ class InterleavedSyncTest(unittest.TestCase): | |||
| 531 | self.manifest.CloneBundle = False | 541 | self.manifest.CloneBundle = False |
| 532 | self.manifest.default.sync_j = 1 | 542 | self.manifest.default.sync_j = 1 |
| 533 | 543 | ||
| 534 | self.cmd = sync.Sync(manifest=self.manifest) | 544 | self.outer_client = mock.MagicMock() |
| 545 | self.outer_client.manifest.IsArchive = False | ||
| 546 | self.cmd = sync.Sync( | ||
| 547 | manifest=self.manifest, outer_client=self.outer_client | ||
| 548 | ) | ||
| 535 | self.cmd.outer_manifest = self.manifest | 549 | self.cmd.outer_manifest = self.manifest |
| 536 | 550 | ||
| 537 | # Mock projects. | 551 | # Mock projects. |
| @@ -549,6 +563,21 @@ class InterleavedSyncTest(unittest.TestCase): | |||
| 549 | mock.patch.object(sync, "_PostRepoUpgrade").start() | 563 | mock.patch.object(sync, "_PostRepoUpgrade").start() |
| 550 | mock.patch.object(sync, "_PostRepoFetch").start() | 564 | mock.patch.object(sync, "_PostRepoFetch").start() |
| 551 | 565 | ||
| 566 | # Mock parallel context for worker tests. | ||
| 567 | self.parallel_context_patcher = mock.patch( | ||
| 568 | "subcmds.sync.Sync.get_parallel_context" | ||
| 569 | ) | ||
| 570 | self.mock_get_parallel_context = self.parallel_context_patcher.start() | ||
| 571 | self.sync_dict = {} | ||
| 572 | self.mock_context = { | ||
| 573 | "projects": [], | ||
| 574 | "sync_dict": self.sync_dict, | ||
| 575 | } | ||
| 576 | self.mock_get_parallel_context.return_value = self.mock_context | ||
| 577 | |||
| 578 | # Mock _GetCurrentBranchOnly for worker tests. | ||
| 579 | mock.patch.object(sync.Sync, "_GetCurrentBranchOnly").start() | ||
| 580 | |||
| 552 | def tearDown(self): | 581 | def tearDown(self): |
| 553 | """Clean up resources.""" | 582 | """Clean up resources.""" |
| 554 | shutil.rmtree(self.repodir) | 583 | shutil.rmtree(self.repodir) |
| @@ -635,3 +664,153 @@ class InterleavedSyncTest(unittest.TestCase): | |||
| 635 | work_items_sets = {frozenset(item) for item in work_items} | 664 | work_items_sets = {frozenset(item) for item in work_items} |
| 636 | expected_sets = {frozenset([0, 2]), frozenset([1])} | 665 | expected_sets = {frozenset([0, 2]), frozenset([1])} |
| 637 | self.assertEqual(work_items_sets, expected_sets) | 666 | self.assertEqual(work_items_sets, expected_sets) |
| 667 | |||
| 668 | def _get_opts(self, args=None): | ||
| 669 | """Helper to get default options for worker tests.""" | ||
| 670 | if args is None: | ||
| 671 | args = ["--interleaved"] | ||
| 672 | opt, _ = self.cmd.OptionParser.parse_args(args) | ||
| 673 | # Set defaults for options used by the worker. | ||
| 674 | opt.quiet = True | ||
| 675 | opt.verbose = False | ||
| 676 | opt.force_sync = False | ||
| 677 | opt.clone_bundle = False | ||
| 678 | opt.tags = False | ||
| 679 | opt.optimized_fetch = False | ||
| 680 | opt.retry_fetches = 0 | ||
| 681 | opt.prune = False | ||
| 682 | opt.detach_head = False | ||
| 683 | opt.force_checkout = False | ||
| 684 | opt.rebase = False | ||
| 685 | return opt | ||
| 686 | |||
| 687 | def test_worker_successful_sync(self): | ||
| 688 | """Test _SyncProjectList with a successful fetch and checkout.""" | ||
| 689 | opt = self._get_opts() | ||
| 690 | project = self.projA | ||
| 691 | project.Sync_NetworkHalf = mock.Mock( | ||
| 692 | return_value=SyncNetworkHalfResult(error=None, remote_fetched=True) | ||
| 693 | ) | ||
| 694 | project.Sync_LocalHalf = mock.Mock() | ||
| 695 | project.manifest.manifestProject.config = mock.MagicMock() | ||
| 696 | self.mock_context["projects"] = [project] | ||
| 697 | |||
| 698 | with mock.patch("subcmds.sync.SyncBuffer") as mock_sync_buffer: | ||
| 699 | mock_sync_buf_instance = mock.MagicMock() | ||
| 700 | mock_sync_buf_instance.Finish.return_value = True | ||
| 701 | mock_sync_buffer.return_value = mock_sync_buf_instance | ||
| 702 | |||
| 703 | result_obj = self.cmd._SyncProjectList(opt, [0]) | ||
| 704 | |||
| 705 | self.assertEqual(len(result_obj.results), 1) | ||
| 706 | result = result_obj.results[0] | ||
| 707 | self.assertTrue(result.fetch_success) | ||
| 708 | self.assertTrue(result.checkout_success) | ||
| 709 | self.assertIsNone(result.fetch_error) | ||
| 710 | self.assertIsNone(result.checkout_error) | ||
| 711 | project.Sync_NetworkHalf.assert_called_once() | ||
| 712 | project.Sync_LocalHalf.assert_called_once() | ||
| 713 | |||
| 714 | def test_worker_fetch_fails(self): | ||
| 715 | """Test _SyncProjectList with a failed fetch.""" | ||
| 716 | opt = self._get_opts() | ||
| 717 | project = self.projA | ||
| 718 | fetch_error = GitError("Fetch failed") | ||
| 719 | project.Sync_NetworkHalf = mock.Mock( | ||
| 720 | return_value=SyncNetworkHalfResult( | ||
| 721 | error=fetch_error, remote_fetched=False | ||
| 722 | ) | ||
| 723 | ) | ||
| 724 | project.Sync_LocalHalf = mock.Mock() | ||
| 725 | self.mock_context["projects"] = [project] | ||
| 726 | |||
| 727 | result_obj = self.cmd._SyncProjectList(opt, [0]) | ||
| 728 | result = result_obj.results[0] | ||
| 729 | |||
| 730 | self.assertFalse(result.fetch_success) | ||
| 731 | self.assertFalse(result.checkout_success) | ||
| 732 | self.assertEqual(result.fetch_error, fetch_error) | ||
| 733 | self.assertIsNone(result.checkout_error) | ||
| 734 | project.Sync_NetworkHalf.assert_called_once() | ||
| 735 | project.Sync_LocalHalf.assert_not_called() | ||
| 736 | |||
| 737 | def test_worker_fetch_fails_exception(self): | ||
| 738 | """Test _SyncProjectList with an exception during fetch.""" | ||
| 739 | opt = self._get_opts() | ||
| 740 | project = self.projA | ||
| 741 | fetch_error = GitError("Fetch failed") | ||
| 742 | project.Sync_NetworkHalf = mock.Mock(side_effect=fetch_error) | ||
| 743 | project.Sync_LocalHalf = mock.Mock() | ||
| 744 | self.mock_context["projects"] = [project] | ||
| 745 | |||
| 746 | result_obj = self.cmd._SyncProjectList(opt, [0]) | ||
| 747 | result = result_obj.results[0] | ||
| 748 | |||
| 749 | self.assertFalse(result.fetch_success) | ||
| 750 | self.assertFalse(result.checkout_success) | ||
| 751 | self.assertEqual(result.fetch_error, fetch_error) | ||
| 752 | project.Sync_NetworkHalf.assert_called_once() | ||
| 753 | project.Sync_LocalHalf.assert_not_called() | ||
| 754 | |||
| 755 | def test_worker_checkout_fails(self): | ||
| 756 | """Test _SyncProjectList with an exception during checkout.""" | ||
| 757 | opt = self._get_opts() | ||
| 758 | project = self.projA | ||
| 759 | project.Sync_NetworkHalf = mock.Mock( | ||
| 760 | return_value=SyncNetworkHalfResult(error=None, remote_fetched=True) | ||
| 761 | ) | ||
| 762 | checkout_error = GitError("Checkout failed") | ||
| 763 | project.Sync_LocalHalf = mock.Mock(side_effect=checkout_error) | ||
| 764 | project.manifest.manifestProject.config = mock.MagicMock() | ||
| 765 | self.mock_context["projects"] = [project] | ||
| 766 | |||
| 767 | with mock.patch("subcmds.sync.SyncBuffer"): | ||
| 768 | result_obj = self.cmd._SyncProjectList(opt, [0]) | ||
| 769 | result = result_obj.results[0] | ||
| 770 | |||
| 771 | self.assertTrue(result.fetch_success) | ||
| 772 | self.assertFalse(result.checkout_success) | ||
| 773 | self.assertIsNone(result.fetch_error) | ||
| 774 | self.assertEqual(result.checkout_error, checkout_error) | ||
| 775 | project.Sync_NetworkHalf.assert_called_once() | ||
| 776 | project.Sync_LocalHalf.assert_called_once() | ||
| 777 | |||
| 778 | def test_worker_local_only(self): | ||
| 779 | """Test _SyncProjectList with --local-only.""" | ||
| 780 | opt = self._get_opts(["--interleaved", "--local-only"]) | ||
| 781 | project = self.projA | ||
| 782 | project.Sync_NetworkHalf = mock.Mock() | ||
| 783 | project.Sync_LocalHalf = mock.Mock() | ||
| 784 | project.manifest.manifestProject.config = mock.MagicMock() | ||
| 785 | self.mock_context["projects"] = [project] | ||
| 786 | |||
| 787 | with mock.patch("subcmds.sync.SyncBuffer") as mock_sync_buffer: | ||
| 788 | mock_sync_buf_instance = mock.MagicMock() | ||
| 789 | mock_sync_buf_instance.Finish.return_value = True | ||
| 790 | mock_sync_buffer.return_value = mock_sync_buf_instance | ||
| 791 | |||
| 792 | result_obj = self.cmd._SyncProjectList(opt, [0]) | ||
| 793 | result = result_obj.results[0] | ||
| 794 | |||
| 795 | self.assertTrue(result.fetch_success) | ||
| 796 | self.assertTrue(result.checkout_success) | ||
| 797 | project.Sync_NetworkHalf.assert_not_called() | ||
| 798 | project.Sync_LocalHalf.assert_called_once() | ||
| 799 | |||
| 800 | def test_worker_network_only(self): | ||
| 801 | """Test _SyncProjectList with --network-only.""" | ||
| 802 | opt = self._get_opts(["--interleaved", "--network-only"]) | ||
| 803 | project = self.projA | ||
| 804 | project.Sync_NetworkHalf = mock.Mock( | ||
| 805 | return_value=SyncNetworkHalfResult(error=None, remote_fetched=True) | ||
| 806 | ) | ||
| 807 | project.Sync_LocalHalf = mock.Mock() | ||
| 808 | self.mock_context["projects"] = [project] | ||
| 809 | |||
| 810 | result_obj = self.cmd._SyncProjectList(opt, [0]) | ||
| 811 | result = result_obj.results[0] | ||
| 812 | |||
| 813 | self.assertTrue(result.fetch_success) | ||
| 814 | self.assertTrue(result.checkout_success) | ||
| 815 | project.Sync_NetworkHalf.assert_called_once() | ||
| 816 | project.Sync_LocalHalf.assert_not_called() | ||
