Files
cli/sunbeam/tests/test_kube.py
Sienna Meridian Satterwhite cdc109d728 feat: initial sunbeam CLI package
stdlib-only Python CLI replacing infrastructure/scripts/sunbeam.py.
Verbs: up, down, status, apply, seed, verify, logs, restart, get,
build, mirror, bootstrap. Service scoping via ns/name target syntax.
Auto-bundled kubectl/kustomize/helm (SHA256-verified, cached in
~/.local/share/sunbeam/bin). 63 unittest tests, all passing.
2026-03-02 20:59:57 +00:00

109 lines
4.3 KiB
Python

"""Tests for kube.py — domain substitution, target parsing, kubectl wrappers."""
import unittest
from unittest.mock import MagicMock, patch
class TestParseTarget(unittest.TestCase):
def setUp(self):
from sunbeam.kube import parse_target
self.parse = parse_target
def test_none(self):
self.assertEqual(self.parse(None), (None, None))
def test_namespace_only(self):
self.assertEqual(self.parse("ory"), ("ory", None))
def test_namespace_and_name(self):
self.assertEqual(self.parse("ory/kratos"), ("ory", "kratos"))
def test_too_many_parts_raises(self):
with self.assertRaises(ValueError):
self.parse("too/many/parts")
def test_empty_string(self):
result = self.parse("")
self.assertEqual(result, ("", None))
class TestDomainReplace(unittest.TestCase):
def setUp(self):
from sunbeam.kube import domain_replace
self.replace = domain_replace
def test_single_occurrence(self):
result = self.replace("src.DOMAIN_SUFFIX/foo", "192.168.1.1.sslip.io")
self.assertEqual(result, "src.192.168.1.1.sslip.io/foo")
def test_multiple_occurrences(self):
text = "DOMAIN_SUFFIX and DOMAIN_SUFFIX"
result = self.replace(text, "x.sslip.io")
self.assertEqual(result, "x.sslip.io and x.sslip.io")
def test_no_occurrence(self):
result = self.replace("no match here", "x.sslip.io")
self.assertEqual(result, "no match here")
class TestKustomizeBuild(unittest.TestCase):
def test_calls_run_tool_and_applies_domain_replace(self):
from pathlib import Path
mock_result = MagicMock()
mock_result.stdout = "image: src.DOMAIN_SUFFIX/foo\nimage: src.DOMAIN_SUFFIX/bar"
with patch("sunbeam.kube.run_tool", return_value=mock_result) as mock_rt:
from sunbeam.kube import kustomize_build
result = kustomize_build(Path("/some/overlay"), "192.168.1.1.sslip.io")
mock_rt.assert_called_once()
call_args = mock_rt.call_args[0]
self.assertEqual(call_args[0], "kustomize")
self.assertIn("build", call_args)
self.assertIn("--enable-helm", call_args)
self.assertIn("192.168.1.1.sslip.io", result)
self.assertNotIn("DOMAIN_SUFFIX", result)
def test_strips_null_annotations(self):
from pathlib import Path
mock_result = MagicMock()
mock_result.stdout = "metadata:\n annotations: null\n name: test"
with patch("sunbeam.kube.run_tool", return_value=mock_result):
from sunbeam.kube import kustomize_build
result = kustomize_build(Path("/overlay"), "x.sslip.io")
self.assertNotIn("annotations: null", result)
class TestKubeWrappers(unittest.TestCase):
def test_kube_passes_context(self):
with patch("sunbeam.kube.run_tool") as mock_rt:
mock_rt.return_value = MagicMock(returncode=0)
from sunbeam.kube import kube
kube("get", "pods")
call_args = mock_rt.call_args[0]
self.assertEqual(call_args[0], "kubectl")
self.assertIn("--context=sunbeam", call_args)
def test_kube_out_returns_stdout_on_success(self):
with patch("sunbeam.kube.run_tool") as mock_rt:
mock_rt.return_value = MagicMock(returncode=0, stdout=" output ")
from sunbeam.kube import kube_out
result = kube_out("get", "pods")
self.assertEqual(result, "output")
def test_kube_out_returns_empty_on_failure(self):
with patch("sunbeam.kube.run_tool") as mock_rt:
mock_rt.return_value = MagicMock(returncode=1, stdout="error text")
from sunbeam.kube import kube_out
result = kube_out("get", "pods")
self.assertEqual(result, "")
def test_kube_ok_returns_true_on_zero(self):
with patch("sunbeam.kube.run_tool") as mock_rt:
mock_rt.return_value = MagicMock(returncode=0)
from sunbeam.kube import kube_ok
self.assertTrue(kube_ok("get", "ns", "default"))
def test_kube_ok_returns_false_on_nonzero(self):
with patch("sunbeam.kube.run_tool") as mock_rt:
mock_rt.return_value = MagicMock(returncode=1)
from sunbeam.kube import kube_ok
self.assertFalse(kube_ok("get", "ns", "missing"))