blob: e784037593c5f54c1e25c5ca97b239c96e1a61cc [file]
# Copyright 2026 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Unit tests for gcloud.py."""
# Add our active parent directory to sys.path to enable flat, direct imports of sister modules
import pathlib
import sys
_SCRIPT_DIR = pathlib.Path(__file__).resolve().parent
sys.path.insert(0, str(_SCRIPT_DIR))
import shutil
import subprocess
import unittest
from unittest import mock
import gcloud
class GcloudTest(unittest.TestCase):
"""Unit tests for gcloud.py module-scoped functions."""
def setUp(self) -> None:
# Clear the module's functools cache to prevent cross-contamination between test cases
gcloud.path.cache_clear()
# path() falls back to looking for a system package install, which
# would make results depend on whether gcloud is installed on the host.
patcher = mock.patch("gcloud.apt.get_binary_path", return_value=None)
patcher.start()
self.addCleanup(patcher.stop)
@mock.patch.object(shutil, "which", return_value="/usr/bin/gcloud")
def test_path_true(self, mock_which: mock.Mock) -> None:
self.assertEqual(gcloud.path(), pathlib.Path("/usr/bin/gcloud"))
@mock.patch.object(shutil, "which", return_value=None)
def test_path_false(self, mock_which: mock.Mock) -> None:
self.assertIsNone(gcloud.path())
@mock.patch.object(shutil, "which", return_value="/bin/gcloud")
@mock.patch.object(subprocess, "run")
def test_login_success(
self, mock_run: mock.Mock, mock_which: mock.Mock
) -> None:
mock_proc = mock.Mock()
mock_proc.returncode = 0
mock_run.return_value = mock_proc
gcloud.login()
mock_run.assert_called_once_with(
["/bin/gcloud", "auth", "application-default", "login"],
stdin=mock.ANY,
stdout=mock.ANY,
stderr=mock.ANY,
check=True,
)
@mock.patch.object(shutil, "which", return_value=None)
def test_login_raises_runtime_error_if_gcloud_missing(
self, mock_which: mock.Mock
) -> None:
with self.assertRaises(RuntimeError) as ctx:
gcloud.login()
self.assertIn(
"Google Cloud SDK ('gcloud') is not installed.", str(ctx.exception)
)
@mock.patch.object(shutil, "which", return_value="/bin/gcloud")
@mock.patch.object(subprocess, "run")
def test_login_raises_runtime_error_on_failure(
self, mock_run: mock.Mock, mock_which: mock.Mock
) -> None:
mock_run.side_effect = subprocess.CalledProcessError(1, "gcloud")
with self.assertRaises(RuntimeError) as ctx:
gcloud.login()
self.assertIn("Interactive gcloud login failed", str(ctx.exception))
if __name__ == "__main__":
unittest.main()