Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions caprover/gc-stack-deploy/src/gc_stack_deploy/apps_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,21 @@ def set_yaml_value(yaml_str: str | None, key: str | list[str], value: object) ->
return buf.getvalue()


def disable_healthcheck(suo: str | None) -> str:
"""
Return a serviceUpdateOverride YAML with the Docker healthcheck disabled.

HealthCheck gets nested under TaskTemplate.ContainerSpec; I can't find
documentation for that, you will have to trust me (from trial-and-error).

TaskTemplate:
ContainerSpec:
HealthCheck:
Test: ["NONE"]
"""
return set_yaml_value(suo, "TaskTemplate.ContainerSpec.HealthCheck.Test", ["NONE"])


def set_memory_limit(cap, appname, memory_bytes=1610612736):
app = cap.get_app(appname)
new_suo = set_yaml_value(
Expand Down Expand Up @@ -311,11 +326,7 @@ def _install(self) -> None:
f"{self.app_name}-worker",
):
worker_app = cap.get_app(appname)
new_suo = set_yaml_value(
worker_app["serviceUpdateOverride"],
"TaskTemplate.HealthCheck.Test",
["NONE"],
)
new_suo = disable_healthcheck(worker_app["serviceUpdateOverride"])
# Also set memory limit to workers
new_suo = set_yaml_value(
new_suo, "TaskTemplate.Resources.Limits.MemoryBytes", 1610612736
Expand Down
77 changes: 77 additions & 0 deletions caprover/gc-stack-deploy/tests/apps_registry_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import pytest
from ruamel.yaml import YAML

from gc_stack_deploy.apps_registry import disable_healthcheck, set_yaml_value


def load_yaml(s):
return YAML().load(s)


class TestSetYamlValue:
def test_creates_nested_keys_from_scratch(self):
result = set_yaml_value(None, "A.B.C", 42)
assert load_yaml(result) == {"A": {"B": {"C": 42}}}

def test_sets_value_in_existing_document(self):
existing = (
"A:\n"
" B:\n"
" C: 1\n"
)
result = set_yaml_value(existing, "A.B.C", 99)
assert load_yaml(result)["A"]["B"]["C"] == 99

def test_preserves_sibling_keys(self):
existing = (
"A:\n"
" X: kept\n"
" B:\n"
" C: 1\n"
)
result = set_yaml_value(existing, "A.B.C", 2)
data = load_yaml(result)
assert data["A"]["X"] == "kept"
assert data["A"]["B"]["C"] == 2

def test_accepts_list_key(self):
result = set_yaml_value(None, ["A", "B"], "v")
assert load_yaml(result) == {"A": {"B": "v"}}

def test_empty_string_treated_as_empty(self):
result = set_yaml_value("", "K", "v")
assert load_yaml(result) == {"K": "v"}

def test_list_value(self):
result = set_yaml_value(None, "A.B", ["NONE"])
assert load_yaml(result) == {"A": {"B": ["NONE"]}}


class TestDisableHealthcheck:
HEALTHCHECK_ONLY = (
"TaskTemplate:\n"
" ContainerSpec:\n"
" HealthCheck:\n"
" Test:\n"
" - NONE\n"
)

def test_none_input(self):
assert disable_healthcheck(None) == self.HEALTHCHECK_ONLY

def test_empty_string_input(self):
assert disable_healthcheck("") == self.HEALTHCHECK_ONLY

def test_disables_on_existing_suo(self):
existing = "TaskTemplate:\n Resources:\n Limits:\n MemoryBytes: 1024\n"
expected = (
"TaskTemplate:\n"
" Resources:\n"
" Limits:\n"
" MemoryBytes: 1024\n"
" ContainerSpec:\n"
" HealthCheck:\n"
" Test:\n"
" - NONE\n"
)
assert disable_healthcheck(existing) == expected
Loading