Skip to content

Commit 02ffd44

Browse files
committed
chore: add integration tests
Signed-off-by: Dario Faccin <[email protected]>
1 parent 1c2a038 commit 02ffd44

File tree

2 files changed

+70
-5
lines changed

2 files changed

+70
-5
lines changed

charms/jupyter-controller/tests/integration/test_charm.py

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@
1414
assert_alert_rules,
1515
assert_logging,
1616
assert_metrics_endpoint,
17+
assert_security_context,
1718
deploy_and_assert_grafana_agent,
19+
generate_container_securitycontext_map,
1820
get_alert_rules,
21+
get_pod_names,
1922
)
2023
from charms_dependencies import ISTIO_GATEWAY, ISTIO_PILOT, JUPYTER_UI
2124
from httpx import HTTPStatusError
@@ -29,9 +32,17 @@
2932

3033
METADATA = yaml.safe_load(Path("./metadata.yaml").read_text())
3134
APP_NAME = METADATA["name"]
35+
CONTAINERS_SECURITY_CONTEXT_MAP = generate_container_securitycontext_map(METADATA)
3236
ISTIO_GATEWAY_APP_NAME = "istio-ingressgateway"
3337

3438

39+
@pytest.fixture(scope="session")
40+
def lightkube_client() -> Client:
41+
"""Returns lightkube Kubernetes client"""
42+
client = Client(field_manager=f"{APP_NAME}")
43+
return client
44+
45+
3546
@pytest.mark.abort_on_fail
3647
async def test_build_and_deploy(ops_test: OpsTest, request):
3748
"""Test build and deploy."""
@@ -142,9 +153,8 @@ def assert_replicas(client, resource_class, resource_name, namespace):
142153
assert replicas == 1, f"Waited too long for {resource_class_kind}/{resource_name}!"
143154

144155

145-
async def test_create_notebook(ops_test: OpsTest):
156+
async def test_create_notebook(ops_test: OpsTest, lightkube_client: Client):
146157
"""Test notebook creation."""
147-
lightkube_client = Client()
148158
this_ns = lightkube_client.get(res=Namespace, name=ops_test.model.name)
149159
lightkube_client.patch(res=Namespace, name=this_ns.metadata.name, obj=this_ns)
150160

@@ -172,8 +182,30 @@ async def test_create_notebook(ops_test: OpsTest):
172182
assert_replicas(lightkube_client, notebook_resource, "sample-notebook", ops_test.model.name)
173183

174184

185+
@pytest.mark.parametrize("container_name", list(CONTAINERS_SECURITY_CONTEXT_MAP.keys()))
186+
@pytest.mark.abort_on_fail
187+
async def test_container_security_context(
188+
ops_test: OpsTest,
189+
lightkube_client: Client,
190+
container_name: str,
191+
):
192+
"""Test container security context is correctly set.
193+
194+
Verify that container spec defines the security context with correct
195+
user ID and group ID.
196+
"""
197+
pod_name = get_pod_names(ops_test.model.name, APP_NAME)[0]
198+
assert_security_context(
199+
lightkube_client,
200+
pod_name,
201+
container_name,
202+
CONTAINERS_SECURITY_CONTEXT_MAP,
203+
ops_test.model.name,
204+
)
205+
206+
175207
@pytest.mark.abort_on_fail
176-
async def test_remove_with_resources_present(ops_test: OpsTest):
208+
async def test_remove_with_resources_present(ops_test: OpsTest, lightkube_client: Client):
177209
"""Test remove with all resources deployed.
178210
179211
Verify that all deployed resources that need to be removed are removed.
@@ -184,7 +216,6 @@ async def test_remove_with_resources_present(ops_test: OpsTest):
184216
assert APP_NAME not in ops_test.model.applications
185217

186218
# verify that all resources that were deployed are removed
187-
lightkube_client = Client()
188219

189220
# verify all CRDs in namespace are removed
190221
crd_list = lightkube_client.list(

charms/jupyter-ui/tests/integration/test_charm.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,20 @@
1616
from charmed_kubeflow_chisme.testing import (
1717
GRAFANA_AGENT_APP,
1818
assert_logging,
19+
assert_security_context,
1920
deploy_and_assert_grafana_agent,
21+
generate_container_securitycontext_map,
22+
get_pod_names,
2023
)
24+
from lightkube import Client
2125
from pytest_operator.plugin import OpsTest
2226

2327
logger = logging.getLogger(__name__)
2428

2529
METADATA = yaml.safe_load(Path("./metadata.yaml").read_text())
2630
CONFIG = yaml.safe_load(Path("./config.yaml").read_text())
27-
APP_NAME = "jupyter-ui"
31+
APP_NAME = METADATA["name"]
32+
CONTAINERS_SECURITY_CONTEXT_MAP = generate_container_securitycontext_map(METADATA)
2833
JUPYTER_IMAGES_CONFIG = "jupyter-images"
2934
VSCODE_IMAGES_CONFIG = "vscode-images"
3035
RSTUDIO_IMAGES_CONFIG = "rstudio-images"
@@ -66,6 +71,13 @@
6671
]
6772

6873

74+
@pytest.fixture(scope="session")
75+
def lightkube_client() -> Client:
76+
"""Return lightkube Kubernetes client."""
77+
client = Client(field_manager=f"{APP_NAME}")
78+
return client
79+
80+
6981
@pytest.mark.abort_on_fail
7082
async def test_build_and_deploy(ops_test: OpsTest, request):
7183
"""Build and deploy the charm.
@@ -189,6 +201,28 @@ async def test_logging(ops_test):
189201
await assert_logging(app)
190202

191203

204+
@pytest.mark.parametrize("container_name", list(CONTAINERS_SECURITY_CONTEXT_MAP.keys()))
205+
@pytest.mark.abort_on_fail
206+
async def test_container_security_context(
207+
ops_test: OpsTest,
208+
lightkube_client: Client,
209+
container_name: str,
210+
):
211+
"""Test container security context is correctly set.
212+
213+
Verify that container spec defines the security context with correct
214+
user ID and group ID.
215+
"""
216+
pod_name = get_pod_names(ops_test.model.name, APP_NAME)[0]
217+
assert_security_context(
218+
lightkube_client,
219+
pod_name,
220+
container_name,
221+
CONTAINERS_SECURITY_CONTEXT_MAP,
222+
ops_test.model.name,
223+
)
224+
225+
192226
RETRY_120_SECONDS = tenacity.Retrying(
193227
stop=tenacity.stop_after_delay(120),
194228
wait=tenacity.wait_fixed(2),

0 commit comments

Comments
 (0)