| #!/usr/bin/env vpython3 |
| # Copyright 2022 The Chromium Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| """File for testing serve_repo.py.""" |
| |
| import argparse |
| import json |
| import unittest |
| import unittest.mock as mock |
| |
| from types import SimpleNamespace |
| |
| import serve_repo |
| |
| from common import REPO_ALIAS, register_device_args |
| |
| _REPO_DIR = 'test_repo_dir' |
| _REPO_NAME = 'test_repo_name' |
| _TARGET = 'test_target' |
| _NO_SERVERS_LIST = json.dumps({'ok': {'data': []}}) |
| _SERVERS_LIST = json.dumps( |
| {'ok': { |
| 'data': [{ |
| 'name': _REPO_NAME, |
| 'repo_path': _REPO_DIR |
| }] |
| }}) |
| _WRONG_SERVERS_LIST = json.dumps( |
| {'ok': { |
| 'data': [{ |
| 'name': 'wrong_name', |
| 'repo_path': _REPO_DIR |
| }] |
| }}) |
| |
| |
| # Tests private functions. |
| # pylint: disable=protected-access |
| class ServeRepoTest(unittest.TestCase): |
| """Unittests for serve_repo.py.""" |
| @mock.patch('serve_repo.run_ffx_command') |
| def test_start_server(self, mock_ffx) -> None: |
| """Test |_start_serving| function for start.""" |
| |
| mock_ffx.side_effect = [ |
| SimpleNamespace(returncode=1, stderr='err1', stdout=''), |
| SimpleNamespace(returncode=0, stdout=_SERVERS_LIST, stderr=''), |
| SimpleNamespace(returncode=0, stdout=_SERVERS_LIST, stderr=''), |
| SimpleNamespace(returncode=0, stdout='', stderr='') |
| ] |
| serve_repo._start_serving(_REPO_DIR, _REPO_NAME, _TARGET) |
| self.assertEqual(mock_ffx.call_count, 3) |
| first_call = mock_ffx.call_args_list[0] |
| |
| self.assertEqual( |
| mock.call(cmd=[ |
| 'repository', 'server', 'start', '--background', '--address', |
| '[::]:0', '--repository', _REPO_NAME, '--repo-path', _REPO_DIR, |
| '--no-device' |
| ], |
| check=False), first_call) |
| second_call = mock_ffx.call_args_list[1] |
| self.assertEqual( |
| mock.call(cmd=[ |
| '--machine', 'json', 'repository', 'server', 'list', '--name', |
| _REPO_NAME |
| ], |
| check=False, |
| capture_output=True), second_call) |
| |
| third_call = mock_ffx.call_args_list[2] |
| self.assertEqual( |
| mock.call(cmd=[ |
| 'target', 'repository', 'register', '-r', _REPO_NAME, |
| '--alias', REPO_ALIAS |
| ], |
| target_id=_TARGET), third_call) |
| |
| @mock.patch('serve_repo.run_ffx_command') |
| def test_assert_server_running(self, mock_ffx) -> None: |
| """Test |_assert_server_running| function for start.""" |
| |
| mock_ffx.side_effect = [ |
| SimpleNamespace(returncode=0, stdout=_SERVERS_LIST) |
| ] |
| # Raises an error if there is a problem, so no need to check for |
| # RuntimeError. |
| try: |
| serve_repo._assert_server_running(_REPO_NAME) |
| except RuntimeError as err: |
| self.fail(f'Unexpected error: {err}') |
| |
| @mock.patch('serve_repo.run_ffx_command') |
| def test_is_server_not_running(self, mock_ffx) -> None: |
| """Test |_assert_server_running| function for start with no server.""" |
| |
| mock_ffx.return_value = SimpleNamespace(returncode=0, |
| stdout=_NO_SERVERS_LIST, |
| stderr='') |
| |
| with self.assertRaises(RuntimeError): |
| serve_repo._assert_server_running(_REPO_NAME) |
| |
| @mock.patch('serve_repo.run_ffx_command') |
| def test_is_wrong_server_running(self, mock_ffx) -> None: |
| """Test |_assert_server_running| function for start with no server.""" |
| |
| mock_ffx.return_value = SimpleNamespace(returncode=0, |
| stdout=_WRONG_SERVERS_LIST, |
| stderr='') |
| |
| with self.assertRaises(RuntimeError): |
| serve_repo._assert_server_running(_REPO_NAME) |
| |
| @mock.patch('serve_repo.run_ffx_command') |
| def test_is_server_not_running_bad_ffx(self, mock_ffx) -> None: |
| """Test |_assert_server_running| function for start with bad ffx.""" |
| |
| mock_ffx.return_value = SimpleNamespace(returncode=1, |
| stderr='Some error', |
| stdout='') |
| |
| with self.assertRaises(RuntimeError): |
| serve_repo._assert_server_running(_REPO_NAME) |
| |
| @mock.patch('serve_repo.run_ffx_command') |
| def test_is_server_not_running_bad_json(self, mock_ffx) -> None: |
| """Test |_assert_server_running| function for start with bad ffx.""" |
| |
| mock_ffx.return_value = SimpleNamespace(returncode=0, |
| stderr='', |
| stdout='{"some": bad...') |
| |
| with self.assertRaises(RuntimeError): |
| serve_repo._assert_server_running(_REPO_NAME) |
| |
| @mock.patch('serve_repo.run_ffx_command') |
| def test_stop_server(self, mock_ffx) -> None: |
| """Test |_stop_serving| function for stop.""" |
| |
| serve_repo._stop_serving(_REPO_NAME, _TARGET) |
| self.assertEqual(mock_ffx.call_count, 2) |
| first_call = mock_ffx.call_args_list[0] |
| |
| self.assertEqual( |
| mock.call( |
| cmd=['target', 'repository', 'deregister', '-r', _REPO_NAME], |
| target_id=_TARGET, |
| check=False), first_call) |
| second_call = mock_ffx.call_args_list[1] |
| self.assertEqual( |
| mock.call(cmd=['repository', 'server', 'stop', _REPO_NAME], |
| check=False), second_call) |
| |
| @mock.patch('serve_repo._start_serving') |
| @mock.patch('serve_repo._stop_serving') |
| def test_serve_repository(self, mock_stop, mock_start) -> None: |
| """Tests |serve_repository| context manager.""" |
| |
| parser = argparse.ArgumentParser() |
| serve_repo.register_serve_args(parser) |
| register_device_args(parser) |
| with serve_repo.serve_repository( |
| parser.parse_args([ |
| '--repo', _REPO_DIR, '--repo-name', _REPO_NAME, |
| '--target-id', _TARGET |
| ])): |
| self.assertEqual(mock_start.call_count, 1) |
| self.assertEqual(mock_stop.call_count, 1) |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |