|
1 | 1 | import io |
| 2 | +import logging |
2 | 3 | import pathlib |
3 | 4 | import textwrap |
4 | 5 | from unittest.mock import Mock, patch |
@@ -541,6 +542,143 @@ def test_skip_constraints_cli_option() -> None: |
541 | 542 | assert "Skip generating constraints.txt file" in result.output |
542 | 543 |
|
543 | 544 |
|
| 545 | +@patch("fromager.commands.bootstrap.bootstrapper.Bootstrapper") |
| 546 | +@patch("fromager.commands.bootstrap.server.start_wheel_server") |
| 547 | +@patch("fromager.commands.bootstrap.progress.progress_context") |
| 548 | +@patch("fromager.commands.bootstrap.metrics.summarize") |
| 549 | +def test_multiple_versions_auto_disables_constraints( |
| 550 | + mock_metrics: Mock, |
| 551 | + mock_progress: Mock, |
| 552 | + mock_server: Mock, |
| 553 | + mock_bootstrapper: Mock, |
| 554 | + tmp_context: context.WorkContext, |
| 555 | + caplog: pytest.LogCaptureFixture, |
| 556 | +) -> None: |
| 557 | + """Test that --multiple-versions alone auto-disables constraints and logs message""" |
| 558 | + # Setup mocks |
| 559 | + mock_progress.return_value.__enter__.return_value = Mock() |
| 560 | + mock_progress.return_value.__exit__.return_value = None |
| 561 | + mock_bt_instance = Mock() |
| 562 | + mock_bt_instance.resolve_and_add_top_level.return_value = ("url", Version("1.0")) |
| 563 | + mock_bt_instance.finalize.return_value = 0 |
| 564 | + mock_bootstrapper.return_value = mock_bt_instance |
| 565 | + |
| 566 | + runner = CliRunner() |
| 567 | + with runner.isolated_filesystem(): |
| 568 | + # Create a temporary requirements file |
| 569 | + pathlib.Path("req.txt").write_text("setuptools>=60\n") |
| 570 | + |
| 571 | + # Invoke with --multiple-versions but NOT --skip-constraints |
| 572 | + with caplog.at_level(logging.INFO): |
| 573 | + result = runner.invoke( |
| 574 | + bootstrap.bootstrap, |
| 575 | + [ |
| 576 | + "-r", |
| 577 | + "req.txt", |
| 578 | + "--multiple-versions", |
| 579 | + ], |
| 580 | + obj=tmp_context, |
| 581 | + ) |
| 582 | + |
| 583 | + # Should succeed |
| 584 | + assert result.exit_code == 0 |
| 585 | + |
| 586 | + # Should log that constraints are auto-disabled |
| 587 | + assert "automatically disabling constraints generation" in caplog.text |
| 588 | + assert "incompatible with --multiple-versions" in caplog.text |
| 589 | + |
| 590 | + |
| 591 | +@patch("fromager.commands.bootstrap.bootstrapper.Bootstrapper") |
| 592 | +@patch("fromager.commands.bootstrap.server.start_wheel_server") |
| 593 | +@patch("fromager.commands.bootstrap.progress.progress_context") |
| 594 | +@patch("fromager.commands.bootstrap.metrics.summarize") |
| 595 | +def test_multiple_versions_with_skip_constraints_no_duplicate_log( |
| 596 | + mock_metrics: Mock, |
| 597 | + mock_progress: Mock, |
| 598 | + mock_server: Mock, |
| 599 | + mock_bootstrapper: Mock, |
| 600 | + tmp_context: context.WorkContext, |
| 601 | + caplog: pytest.LogCaptureFixture, |
| 602 | +) -> None: |
| 603 | + """Test that --multiple-versions --skip-constraints together doesn't log auto-disable message""" |
| 604 | + # Setup mocks |
| 605 | + mock_progress.return_value.__enter__.return_value = Mock() |
| 606 | + mock_progress.return_value.__exit__.return_value = None |
| 607 | + mock_bt_instance = Mock() |
| 608 | + mock_bt_instance.resolve_and_add_top_level.return_value = ("url", Version("1.0")) |
| 609 | + mock_bt_instance.finalize.return_value = 0 |
| 610 | + mock_bootstrapper.return_value = mock_bt_instance |
| 611 | + |
| 612 | + runner = CliRunner() |
| 613 | + with runner.isolated_filesystem(): |
| 614 | + # Create a temporary requirements file |
| 615 | + pathlib.Path("req.txt").write_text("setuptools>=60\n") |
| 616 | + |
| 617 | + # Invoke with BOTH --multiple-versions AND --skip-constraints |
| 618 | + with caplog.at_level(logging.INFO): |
| 619 | + result = runner.invoke( |
| 620 | + bootstrap.bootstrap, |
| 621 | + [ |
| 622 | + "-r", |
| 623 | + "req.txt", |
| 624 | + "--multiple-versions", |
| 625 | + "--skip-constraints", |
| 626 | + ], |
| 627 | + obj=tmp_context, |
| 628 | + ) |
| 629 | + |
| 630 | + # Should succeed |
| 631 | + assert result.exit_code == 0 |
| 632 | + |
| 633 | + # Should NOT log the auto-disable message (already disabled by user) |
| 634 | + assert "automatically disabling constraints generation" not in caplog.text |
| 635 | + |
| 636 | + |
| 637 | +@patch("fromager.commands.bootstrap.bootstrapper.Bootstrapper") |
| 638 | +@patch("fromager.commands.bootstrap.server.start_wheel_server") |
| 639 | +@patch("fromager.commands.bootstrap.progress.progress_context") |
| 640 | +@patch("fromager.commands.bootstrap.metrics.summarize") |
| 641 | +@patch("fromager.commands.bootstrap.write_constraints_file") |
| 642 | +def test_without_multiple_versions_constraints_not_disabled( |
| 643 | + mock_write_constraints: Mock, |
| 644 | + mock_metrics: Mock, |
| 645 | + mock_progress: Mock, |
| 646 | + mock_server: Mock, |
| 647 | + mock_bootstrapper: Mock, |
| 648 | + tmp_context: context.WorkContext, |
| 649 | +) -> None: |
| 650 | + """Test that without --multiple-versions, constraints are not auto-disabled""" |
| 651 | + # Setup mocks |
| 652 | + mock_progress.return_value.__enter__.return_value = Mock() |
| 653 | + mock_progress.return_value.__exit__.return_value = None |
| 654 | + mock_bt_instance = Mock() |
| 655 | + mock_bt_instance.resolve_and_add_top_level.return_value = ("url", Version("1.0")) |
| 656 | + mock_bt_instance.finalize.return_value = 0 |
| 657 | + mock_bootstrapper.return_value = mock_bt_instance |
| 658 | + mock_write_constraints.return_value = True |
| 659 | + |
| 660 | + runner = CliRunner() |
| 661 | + with runner.isolated_filesystem(): |
| 662 | + # Create a temporary requirements file |
| 663 | + pathlib.Path("req.txt").write_text("setuptools>=60\n") |
| 664 | + |
| 665 | + # Invoke WITHOUT --multiple-versions |
| 666 | + result = runner.invoke( |
| 667 | + bootstrap.bootstrap, |
| 668 | + [ |
| 669 | + "-r", |
| 670 | + "req.txt", |
| 671 | + ], |
| 672 | + obj=tmp_context, |
| 673 | + ) |
| 674 | + |
| 675 | + # Should succeed |
| 676 | + assert result.exit_code == 0 |
| 677 | + |
| 678 | + # write_constraints_file should have been called (constraints NOT disabled) |
| 679 | + assert mock_write_constraints.called |
| 680 | + |
| 681 | + |
544 | 682 | @patch("fromager.gitutils.git_clone") |
545 | 683 | def test_resolve_version_from_git_url_with_submodules_enabled( |
546 | 684 | mock_git_clone: Mock, |
|
0 commit comments