Skip to content

Commit c49d2ca

Browse files
committed
orchestratord: Test defaults from our documentation
1 parent 1159af5 commit c49d2ca

File tree

5 files changed

+251
-1
lines changed

5 files changed

+251
-1
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,4 @@ flake.lock
5959
/src/testdrive/ci/protobuf-include
6060
/known-docker-images.txt
6161
/test/sqllogictest/sqlite
62+
my-local-mz/

ci/nightly/pipeline.template.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2295,6 +2295,18 @@ steps:
22952295
key: orchestratord-test
22962296
steps:
22972297
- id: orchestratord-defaults
2298+
label: "Orchestratord test (defaults from documentation)"
2299+
depends_on: build-aarch64
2300+
timeout_in_minutes: 120
2301+
plugins:
2302+
- ./ci/plugins/mzcompose:
2303+
composition: orchestratord
2304+
run: defaults
2305+
ci-builder: stable
2306+
agents:
2307+
queue: hetzner-aarch64-16cpu-32gb
2308+
2309+
- id: orchestratord-default-properties
22982310
label: "Orchestratord test (defaults for properties)"
22992311
depends_on: build-aarch64
23002312
timeout_in_minutes: 120

ci/test/lint-main/checks/check-mzcompose-files.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ check_default_workflow_references_others() {
4848
-not -wholename "./test/testdrive-old-kafka-src-syntax/mzcompose.py" `# Other workflow is run separately` \
4949
-not -wholename "./test/terraform/mzcompose.py" `# Handled differently` \
5050
-not -wholename "./test/cluster-spec-sheet/mzcompose.py" `# Handled differently` \
51+
-not -wholename "./test/orchestratord/mzcompose.py" `# Handled differently` \
5152
)
5253

5354
for file in "${MZCOMPOSE_TEST_FILES[@]}"; do

misc/helm-charts/testing/materialize.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ spec:
3131
environmentdImageRef: materialize/environmentd:v0.163.0-dev.0
3232
backendSecretName: materialize-backend
3333
authenticatorKind: None
34+
environmentId: 12345678-1234-1234-1234-123456789013
3435
#balancerdExternalCertificateSpec:
3536
# dnsNames:
3637
# - balancerd

test/orchestratord/mzcompose.py

Lines changed: 236 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import json
1818
import os
1919
import random
20+
import shutil
2021
import signal
2122
import subprocess
2223
import time
@@ -25,6 +26,7 @@
2526
from enum import Enum
2627
from typing import Any
2728

29+
import requests
2830
import yaml
2931
from semver.version import Version
3032

@@ -41,7 +43,10 @@
4143
from materialize.mzcompose.services.orchestratord import Orchestratord
4244
from materialize.mzcompose.services.testdrive import Testdrive
4345
from materialize.util import all_subclasses
44-
from materialize.version_list import get_all_self_managed_versions
46+
from materialize.version_list import (
47+
get_all_self_managed_versions,
48+
get_self_managed_versions,
49+
)
4550

4651
SERVICES = [
4752
Testdrive(),
@@ -1127,6 +1132,236 @@ class Action(Enum):
11271132
UpgradeChain = "upgrade-chain"
11281133

11291134

1135+
def workflow_defaults(c: Composition, parser: WorkflowArgumentParser) -> None:
1136+
parser.add_argument(
1137+
"--tag",
1138+
type=str,
1139+
help="Custom version tag to use",
1140+
)
1141+
args = parser.parse_args()
1142+
1143+
current_version = get_tag(args.tag)
1144+
1145+
# Following https://materialize.com/docs/self-managed/v25.2/installation/install-on-local-kind/
1146+
for version in reversed(get_self_managed_versions() + [current_version]):
1147+
dir = "my-local-mz"
1148+
if os.path.exists(dir):
1149+
shutil.rmtree(dir)
1150+
os.mkdir(dir)
1151+
spawn.runv(["kind", "delete", "cluster"])
1152+
spawn.runv(["kind", "create", "cluster"])
1153+
spawn.runv(
1154+
[
1155+
"kubectl",
1156+
"label",
1157+
"node",
1158+
"kind-control-plane",
1159+
"materialize.cloud/disk=true",
1160+
]
1161+
)
1162+
spawn.runv(
1163+
[
1164+
"kubectl",
1165+
"label",
1166+
"node",
1167+
"kind-control-plane",
1168+
"materialize.cloud/swap=true",
1169+
]
1170+
)
1171+
spawn.runv(
1172+
[
1173+
"kubectl",
1174+
"label",
1175+
"node",
1176+
"kind-control-plane",
1177+
"workload=materialize-instance",
1178+
]
1179+
)
1180+
1181+
shutil.copyfile(
1182+
"misc/helm-charts/operator/values.yaml",
1183+
os.path.join(dir, "sample-values.yaml"),
1184+
)
1185+
files = {
1186+
"sample-postgres.yaml": "misc/helm-charts/testing/postgres.yaml",
1187+
"sample-minio.yaml": "misc/helm-charts/testing/minio.yaml",
1188+
"sample-materialize.yaml": "misc/helm-charts/testing/materialize.yaml",
1189+
}
1190+
1191+
for file, path in files.items():
1192+
if version == current_version:
1193+
shutil.copyfile(path, os.path.join(dir, file))
1194+
else:
1195+
url = f"https://raw.githubusercontent.com/MaterializeInc/materialize/refs/tags/{version}/{path}"
1196+
response = requests.get(url)
1197+
assert (
1198+
response.status_code == 200
1199+
), f"Failed to download {file} from {url}: {response.status_code}"
1200+
with open(os.path.join(dir, file), "wb") as f:
1201+
f.write(response.content)
1202+
1203+
spawn.runv(
1204+
[
1205+
"helm",
1206+
"repo",
1207+
"add",
1208+
"materialize",
1209+
"https://materializeinc.github.io/materialize",
1210+
]
1211+
)
1212+
spawn.runv(["helm", "repo", "update", "materialize"])
1213+
spawn.runv(
1214+
[
1215+
"helm",
1216+
"install",
1217+
"my-materialize-operator",
1218+
MZ_ROOT / "misc" / "helm-charts" / "operator",
1219+
"--namespace=materialize",
1220+
"--create-namespace",
1221+
"--version",
1222+
"v25.3.0",
1223+
"--set",
1224+
"observability.podMetrics.enabled=true",
1225+
"-f",
1226+
os.path.join(dir, "sample-values.yaml"),
1227+
]
1228+
)
1229+
spawn.runv(
1230+
["kubectl", "apply", "-f", os.path.join(dir, "sample-postgres.yaml")]
1231+
)
1232+
spawn.runv(["kubectl", "apply", "-f", os.path.join(dir, "sample-minio.yaml")])
1233+
spawn.runv(["kubectl", "get", "all", "-n", "materialize"])
1234+
spawn.runv(
1235+
[
1236+
"helm",
1237+
"repo",
1238+
"add",
1239+
"metrics-server",
1240+
"https://kubernetes-sigs.github.io/metrics-server/",
1241+
]
1242+
)
1243+
spawn.runv(["helm", "repo", "update", "metrics-server"])
1244+
spawn.runv(
1245+
[
1246+
"helm",
1247+
"install",
1248+
"metrics-server",
1249+
"metrics-server/metrics-server",
1250+
"--namespace",
1251+
"kube-system",
1252+
"--set",
1253+
"args={--kubelet-insecure-tls,--kubelet-preferred-address-types=InternalIP,Hostname,ExternalIP}",
1254+
]
1255+
)
1256+
for i in range(120):
1257+
try:
1258+
spawn.capture(
1259+
[
1260+
"kubectl",
1261+
"get",
1262+
"crd",
1263+
"materializes.materialize.cloud",
1264+
"-n",
1265+
"materialize",
1266+
"-o",
1267+
"name",
1268+
],
1269+
stderr=subprocess.DEVNULL,
1270+
)
1271+
break
1272+
1273+
except subprocess.CalledProcessError:
1274+
pass
1275+
time.sleep(1)
1276+
else:
1277+
raise ValueError("Never completed")
1278+
1279+
with open(os.path.join(dir, "sample-materialize.yaml")) as f:
1280+
materialize_setup = list(yaml.load_all(f, Loader=yaml.Loader))
1281+
assert len(materialize_setup) == 3
1282+
1283+
if version == current_version:
1284+
materialize_setup[2]["spec"]["environmentdImageRef"] = get_image(
1285+
c.compose["services"]["environmentd"]["image"], args.tag
1286+
)
1287+
# Self-managed v25.1/2 don't require a license key yet
1288+
materialize_setup[1]["stringData"]["license_key"] = os.environ[
1289+
"MZ_CI_LICENSE_KEY"
1290+
]
1291+
else:
1292+
# TODO: Remove this part once environmentId is set in older versions
1293+
materialize_setup[2]["spec"][
1294+
"environmentId"
1295+
] = "12345678-1234-1234-1234-123456789013"
1296+
1297+
with open(os.path.join(dir, "sample-materialize.yaml"), "w") as f:
1298+
yaml.dump_all(materialize_setup, f, default_flow_style=False)
1299+
1300+
spawn.runv(
1301+
["kubectl", "apply", "-f", os.path.join(dir, "sample-materialize.yaml")]
1302+
)
1303+
1304+
for i in range(240):
1305+
try:
1306+
data = json.loads(
1307+
spawn.capture(
1308+
[
1309+
"kubectl",
1310+
"get",
1311+
"pod",
1312+
"-n",
1313+
"materialize-environment",
1314+
"-o",
1315+
"json",
1316+
]
1317+
)
1318+
)
1319+
expected_pods = {
1320+
"environmentd": 1,
1321+
"clusterd": 2,
1322+
"balancerd": 2,
1323+
"console": 2,
1324+
}
1325+
for item in data.get("items", []):
1326+
for container in item.get("status", {}).get(
1327+
"containerStatuses", []
1328+
):
1329+
name = container.get("name")
1330+
assert name in expected_pods, f"Unexpected pod {name}"
1331+
state = container.get("state", {})
1332+
if "running" in state:
1333+
expected_pods[name] -= 1
1334+
assert all(
1335+
value >= 0 for value in expected_pods.values()
1336+
), f"Incorrect number of pods of some type: {expected_pods}"
1337+
if all(value == 0 for value in expected_pods.values()):
1338+
spawn.runv(
1339+
[
1340+
"kubectl",
1341+
"get",
1342+
"pod",
1343+
"-n",
1344+
"materialize-environment",
1345+
]
1346+
)
1347+
break
1348+
1349+
except subprocess.CalledProcessError:
1350+
pass
1351+
time.sleep(1)
1352+
else:
1353+
spawn.runv(
1354+
[
1355+
"kubectl",
1356+
"get",
1357+
"pod",
1358+
"-n",
1359+
"materialize-environment",
1360+
]
1361+
)
1362+
raise ValueError("Never completed")
1363+
1364+
11301365
def workflow_default(c: Composition, parser: WorkflowArgumentParser) -> None:
11311366
parser.add_argument(
11321367
"--recreate-cluster",

0 commit comments

Comments
 (0)