|
10 | 10 | BatchLaunchResponseFormatter, |
11 | 11 | LaunchResponseFormatter, |
12 | 12 | ListCmdDisplay, |
| 13 | + ListStatusDisplay, |
13 | 14 | MetricsResponseFormatter, |
14 | 15 | StatusResponseFormatter, |
15 | 16 | ) |
@@ -521,3 +522,249 @@ def test_display_all_models_output_table(self): |
521 | 522 | with patch.object(console, "print") as mock_print: |
522 | 523 | display.display_all_models_output(model_infos) |
523 | 524 | mock_print.assert_called_once() |
| 525 | + |
| 526 | + |
| 527 | +class TestListStatusDisplay: |
| 528 | + """Test cases for ListStatusDisplay.""" |
| 529 | + |
| 530 | + def test_init(self): |
| 531 | + """Test ListStatusDisplay initialization.""" |
| 532 | + job_ids = ["12345", "67890"] |
| 533 | + statuses = [ |
| 534 | + StatusResponse( |
| 535 | + model_name="test-model-1", |
| 536 | + log_dir="/tmp/logs", |
| 537 | + server_status="READY", |
| 538 | + job_state="RUNNING", |
| 539 | + raw_output="JobState=RUNNING", |
| 540 | + base_url="http://localhost:8000", |
| 541 | + pending_reason=None, |
| 542 | + failed_reason=None, |
| 543 | + ), |
| 544 | + StatusResponse( |
| 545 | + model_name="test-model-2", |
| 546 | + log_dir="/tmp/logs", |
| 547 | + server_status="PENDING", |
| 548 | + job_state="PENDING", |
| 549 | + raw_output="JobState=PENDING", |
| 550 | + base_url=None, |
| 551 | + pending_reason="Waiting for resources", |
| 552 | + failed_reason=None, |
| 553 | + ), |
| 554 | + ] |
| 555 | + |
| 556 | + display = ListStatusDisplay(job_ids, statuses, json_mode=False) |
| 557 | + |
| 558 | + assert display.job_ids == job_ids |
| 559 | + assert display.statuses == statuses |
| 560 | + assert display.json_mode is False |
| 561 | + assert isinstance(display.table, Table) |
| 562 | + |
| 563 | + def test_init_json_mode(self): |
| 564 | + """Test ListStatusDisplay initialization with JSON mode.""" |
| 565 | + job_ids = ["12345"] |
| 566 | + statuses = [ |
| 567 | + StatusResponse( |
| 568 | + model_name="test-model", |
| 569 | + log_dir="/tmp/logs", |
| 570 | + server_status="READY", |
| 571 | + job_state="RUNNING", |
| 572 | + raw_output="JobState=RUNNING", |
| 573 | + base_url="http://localhost:8000", |
| 574 | + pending_reason=None, |
| 575 | + failed_reason=None, |
| 576 | + ) |
| 577 | + ] |
| 578 | + |
| 579 | + display = ListStatusDisplay(job_ids, statuses, json_mode=True) |
| 580 | + |
| 581 | + assert display.json_mode is True |
| 582 | + |
| 583 | + def test_display_multiple_status_output_table_mode(self): |
| 584 | + """Test displaying multiple statuses in table mode.""" |
| 585 | + console = Console() |
| 586 | + job_ids = ["12345", "67890"] |
| 587 | + statuses = [ |
| 588 | + StatusResponse( |
| 589 | + model_name="test-model-1", |
| 590 | + log_dir="/tmp/logs", |
| 591 | + server_status="READY", |
| 592 | + job_state="RUNNING", |
| 593 | + raw_output="JobState=RUNNING", |
| 594 | + base_url="http://localhost:8000", |
| 595 | + pending_reason=None, |
| 596 | + failed_reason=None, |
| 597 | + ), |
| 598 | + StatusResponse( |
| 599 | + model_name="test-model-2", |
| 600 | + log_dir="/tmp/logs", |
| 601 | + server_status="PENDING", |
| 602 | + job_state="PENDING", |
| 603 | + raw_output="JobState=PENDING", |
| 604 | + base_url=None, |
| 605 | + pending_reason="Waiting for resources", |
| 606 | + failed_reason=None, |
| 607 | + ), |
| 608 | + ] |
| 609 | + |
| 610 | + display = ListStatusDisplay(job_ids, statuses, json_mode=False) |
| 611 | + |
| 612 | + with patch.object(console, "print") as mock_print: |
| 613 | + display.display_multiple_status_output(console) |
| 614 | + mock_print.assert_called_once() |
| 615 | + # Verify the table was printed |
| 616 | + assert mock_print.call_args[0][0] == display.table |
| 617 | + |
| 618 | + def test_display_multiple_status_output_json_mode(self): |
| 619 | + """Test displaying multiple statuses in JSON mode.""" |
| 620 | + console = Console() |
| 621 | + job_ids = ["12345", "67890"] |
| 622 | + statuses = [ |
| 623 | + StatusResponse( |
| 624 | + model_name="test-model-1", |
| 625 | + log_dir="/tmp/logs", |
| 626 | + server_status="READY", |
| 627 | + job_state="RUNNING", |
| 628 | + raw_output="JobState=RUNNING", |
| 629 | + base_url="http://localhost:8000", |
| 630 | + pending_reason=None, |
| 631 | + failed_reason=None, |
| 632 | + ), |
| 633 | + StatusResponse( |
| 634 | + model_name="test-model-2", |
| 635 | + log_dir="/tmp/logs", |
| 636 | + server_status="FAILED", |
| 637 | + job_state="FAILED", |
| 638 | + raw_output="JobState=FAILED", |
| 639 | + base_url=None, |
| 640 | + pending_reason=None, |
| 641 | + failed_reason="Out of memory", |
| 642 | + ), |
| 643 | + ] |
| 644 | + |
| 645 | + display = ListStatusDisplay(job_ids, statuses, json_mode=True) |
| 646 | + |
| 647 | + with patch("click.echo") as mock_echo: |
| 648 | + display.display_multiple_status_output(console) |
| 649 | + mock_echo.assert_called_once() |
| 650 | + |
| 651 | + # Verify JSON output |
| 652 | + output = mock_echo.call_args[0][0] |
| 653 | + json_data = json.loads(output) |
| 654 | + assert isinstance(json_data, list) |
| 655 | + assert len(json_data) == 2 |
| 656 | + assert json_data[0]["model_name"] == "test-model-1" |
| 657 | + assert json_data[0]["model_status"] == "READY" |
| 658 | + assert json_data[0]["base_url"] == "http://localhost:8000" |
| 659 | + assert json_data[1]["model_name"] == "test-model-2" |
| 660 | + assert json_data[1]["model_status"] == "FAILED" |
| 661 | + assert json_data[1]["base_url"] is None |
| 662 | + |
| 663 | + def test_display_multiple_status_output_empty_list(self): |
| 664 | + """Test displaying empty status list.""" |
| 665 | + console = Console() |
| 666 | + job_ids = [] |
| 667 | + statuses = [] |
| 668 | + |
| 669 | + display = ListStatusDisplay(job_ids, statuses, json_mode=False) |
| 670 | + |
| 671 | + with patch.object(console, "print") as mock_print: |
| 672 | + display.display_multiple_status_output(console) |
| 673 | + mock_print.assert_called_once() |
| 674 | + |
| 675 | + def test_display_multiple_status_output_empty_list_json(self): |
| 676 | + """Test displaying empty status list in JSON mode.""" |
| 677 | + console = Console() |
| 678 | + job_ids = [] |
| 679 | + statuses = [] |
| 680 | + |
| 681 | + display = ListStatusDisplay(job_ids, statuses, json_mode=True) |
| 682 | + |
| 683 | + with patch("click.echo") as mock_echo: |
| 684 | + display.display_multiple_status_output(console) |
| 685 | + mock_echo.assert_called_once() |
| 686 | + |
| 687 | + output = mock_echo.call_args[0][0] |
| 688 | + json_data = json.loads(output) |
| 689 | + assert isinstance(json_data, list) |
| 690 | + assert len(json_data) == 0 |
| 691 | + |
| 692 | + def test_display_multiple_status_output_single_status(self): |
| 693 | + """Test displaying single status.""" |
| 694 | + console = Console() |
| 695 | + job_ids = ["12345"] |
| 696 | + statuses = [ |
| 697 | + StatusResponse( |
| 698 | + model_name="single-model", |
| 699 | + log_dir="/tmp/logs", |
| 700 | + server_status="READY", |
| 701 | + job_state="RUNNING", |
| 702 | + raw_output="JobState=RUNNING", |
| 703 | + base_url="http://localhost:8000", |
| 704 | + pending_reason=None, |
| 705 | + failed_reason=None, |
| 706 | + ) |
| 707 | + ] |
| 708 | + |
| 709 | + display = ListStatusDisplay(job_ids, statuses, json_mode=False) |
| 710 | + |
| 711 | + with patch.object(console, "print") as mock_print: |
| 712 | + display.display_multiple_status_output(console) |
| 713 | + mock_print.assert_called_once() |
| 714 | + # Verify table has one row |
| 715 | + assert len(display.table.rows) == 1 |
| 716 | + |
| 717 | + def test_display_multiple_status_output_with_none_base_url(self): |
| 718 | + """Test displaying statuses with None base_url.""" |
| 719 | + console = Console() |
| 720 | + job_ids = ["12345"] |
| 721 | + statuses = [ |
| 722 | + StatusResponse( |
| 723 | + model_name="pending-model", |
| 724 | + log_dir="/tmp/logs", |
| 725 | + server_status="PENDING", |
| 726 | + job_state="PENDING", |
| 727 | + raw_output="JobState=PENDING", |
| 728 | + base_url=None, |
| 729 | + pending_reason="Resource allocation", |
| 730 | + failed_reason=None, |
| 731 | + ) |
| 732 | + ] |
| 733 | + |
| 734 | + display = ListStatusDisplay(job_ids, statuses, json_mode=False) |
| 735 | + |
| 736 | + with patch.object(console, "print") as mock_print: |
| 737 | + display.display_multiple_status_output(console) |
| 738 | + mock_print.assert_called_once() |
| 739 | + # Verify the row was added (None base_url should be handled gracefully) |
| 740 | + assert len(display.table.rows) == 1 |
| 741 | + # Verify table has correct number of columns |
| 742 | + assert len(display.table.columns) == 4 # Job ID, Model Name, Status, Base URL |
| 743 | + |
| 744 | + def test_display_multiple_status_output_json_with_none_values(self): |
| 745 | + """Test JSON output with None values.""" |
| 746 | + console = Console() |
| 747 | + job_ids = ["12345"] |
| 748 | + statuses = [ |
| 749 | + StatusResponse( |
| 750 | + model_name="pending-model", |
| 751 | + log_dir="/tmp/logs", |
| 752 | + server_status="PENDING", |
| 753 | + job_state="PENDING", |
| 754 | + raw_output="JobState=PENDING", |
| 755 | + base_url=None, |
| 756 | + pending_reason="Waiting", |
| 757 | + failed_reason=None, |
| 758 | + ) |
| 759 | + ] |
| 760 | + |
| 761 | + display = ListStatusDisplay(job_ids, statuses, json_mode=True) |
| 762 | + |
| 763 | + with patch("click.echo") as mock_echo: |
| 764 | + display.display_multiple_status_output(console) |
| 765 | + mock_echo.assert_called_once() |
| 766 | + |
| 767 | + output = mock_echo.call_args[0][0] |
| 768 | + json_data = json.loads(output) |
| 769 | + assert json_data[0]["base_url"] is None |
| 770 | + assert json_data[0]["model_status"] == "PENDING" |
0 commit comments