diff --git a/src/c++/perf_analyzer/genai-pa/genai_pa/parser.py b/src/c++/perf_analyzer/genai-pa/genai_pa/parser.py index 76cf3f459..d4e0497b7 100644 --- a/src/c++/perf_analyzer/genai-pa/genai_pa/parser.py +++ b/src/c++/perf_analyzer/genai-pa/genai_pa/parser.py @@ -37,7 +37,6 @@ def prune_args(args: argparse.ArgumentParser) -> argparse.ArgumentParser: """ Prune the parsed arguments to remove args with None or False values. """ - print(args) return argparse.Namespace( **{k: v for k, v in vars(args).items() if v is not None if v is not False} ) diff --git a/src/c++/perf_analyzer/genai-pa/pyproject.toml b/src/c++/perf_analyzer/genai-pa/pyproject.toml index f6bfc850c..9e707fa1f 100644 --- a/src/c++/perf_analyzer/genai-pa/pyproject.toml +++ b/src/c++/perf_analyzer/genai-pa/pyproject.toml @@ -47,6 +47,7 @@ keywords = [] requires-python = ">=3.8,<4" dependencies = [ "numpy", + "pytest", "rich" ] diff --git a/src/c++/perf_analyzer/genai-pa/tests/test_cli.py b/src/c++/perf_analyzer/genai-pa/tests/test_cli.py index cddbb70f9..bc103acd4 100644 --- a/src/c++/perf_analyzer/genai-pa/tests/test_cli.py +++ b/src/c++/perf_analyzer/genai-pa/tests/test_cli.py @@ -24,14 +24,70 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +from pathlib import Path + import pytest -from genai_pa.main import run +from genai_pa import parser + + +class TestCLIArguments: + @pytest.mark.parametrize( + "arg, expected_output", + [ + (["-h"], "CLI to profile LLMs and Generative AI models with Perf Analyzer"), + ( + ["--help"], + "CLI to profile LLMs and Generative AI models with Perf Analyzer", + ), + ], + ) + def test_help_arguments_output_and_exit(self, arg, expected_output, capsys): + with pytest.raises(SystemExit) as excinfo: + _ = parser.parse_args(arg) + + # Check that the exit was successful + assert excinfo.value.code == 0 + + # Capture that the correct message was displayed + captured = capsys.readouterr() + assert expected_output in captured.out + + @pytest.mark.parametrize( + "arg, expected_attributes", + [ + (["-b", "2"], {"batch_size": 2}), + (["--batch-size", "2"], {"batch_size": 2}), + (["--concurrency", "3"], {"concurrency_range": "3"}), + (["--max-threads", "4"], {"max_threads": 4}), + ( + ["--profile-export-file", "text.txt"], + {"profile_export_file": Path("text.txt")}, + ), + (["--request-rate", "1.5"], {"request_rate_range": "1.5"}), + (["--service-kind", "triton"], {"service_kind": "triton"}), + (["--service-kind", "openai"], {"service_kind": "openai"}), + # TODO: Remove streaming from implementation. It is invalid with HTTP. + # (["--streaming"], {"streaming": True}), + (["--version"], {"version": True}), + (["-u", "test_url"], {"u": "test_url"}), + (["--url", "test_url"], {"u": "test_url"}), + ], + ) + def test_arguments_output(self, arg, expected_attributes, capsys): + combined_args = ["--model", "test_model"] + arg + args = parser.parse_args(combined_args) + + # Check that the attributes are set correctly + for key, value in expected_attributes.items(): + assert getattr(args, key) == value + + # Check that nothing was printed as a byproduct of parsing the arguments + captured = capsys.readouterr() + assert captured.out == "" + def test_arguments_model_not_provided(self): + with pytest.raises(SystemExit) as exc_info: + _ = parser.parse_args() -# NOTE: Placeholder -class TestHelp: - @pytest.mark.parametrize("arg", ["-h", "--help"]) - def test_help(self, arg): - args = [arg] - with pytest.raises(SystemExit): - run(args) + # Check that the exit was unsuccessful + assert exc_info.value.code != 0