[tests-only][full-ci] Test: run ocm test suite over k8s (#11869)

* test: run ocm tests over k8s setup

Signed-off-by: Ashim Shrestha <ashimshrestha2384@gmail.com>

* address review

Signed-off-by: Ashim Shrestha <ashimshrestha2384@gmail.com>

---------

Signed-off-by: Ashim Shrestha <ashimshrestha2384@gmail.com>
This commit is contained in:
Ashim Shrestha
2026-02-27 16:26:20 +05:45
committed by GitHub
parent 043fa7a129
commit d6ab9216b0
3 changed files with 179 additions and 55 deletions

View File

@@ -229,9 +229,9 @@ config = {
"ocm": {
"suites": [
"apiOcm",
"apiServiceAvailability",
],
"skip": False,
"k8s": True,
"withRemotePhp": [False],
"federationServer": True,
"emailNeeded": True,
@@ -279,6 +279,7 @@ config = {
"cliCommands": {
"suites": [
"cliCommands",
"apiServiceAvailability",
],
"skip": False,
"withRemotePhp": [False],
@@ -1110,8 +1111,28 @@ def localApiTestPipeline(ctx):
for run_with_remote_php in params["withRemotePhp"]:
run_on_k8s = params["k8s"] and ctx.build.event == "cron"
ocis_url = OCIS_URL
ocis_fed_url = OCIS_FED_URL
deployment_steps = []
if run_on_k8s:
ocis_url = "https://%s" % OCIS_SERVER_NAME
ocis_fed_url = "https://%s" % FED_OCIS_SERVER_NAME
deployment_steps = waitK3sCluster()
if params["federationServer"]:
deployment_steps += waitK3sCluster(name = FED_OCIS_SERVER_NAME)
if params["antivirusNeeded"]:
deployment_steps += enableAntivirusServiceK8s()
if params["emailNeeded"]:
deployment_steps += emailServiceK8s()
deployment_steps += prepareOcisDeployment() + setupOcisConfigMaps() + deployOcis() + waitForOcis(ocis_url = ocis_url)
if params["federationServer"]:
deployment_steps += setupOcisConfigMaps(name = FED_OCIS_SERVER_NAME) + deployOcis(name = FED_OCIS_SERVER_NAME) + waitForOcis(name = "federation-ocis", ocis_url = ocis_fed_url)
deployment_steps += ociswrapper() + waitForOciswrapper()
else:
deployment_steps = ocisServer(storage, extra_server_environment = params["extraServerEnvironment"], with_wrapper = True, tika_enabled = params["tikaNeeded"], volumes = [stepVolumeOcisStorage])
pipeline = {
"kind": "pipeline",
@@ -1125,16 +1146,17 @@ def localApiTestPipeline(ctx):
([] if run_on_k8s else restoreBuildArtifactCache(ctx, "ocis-binary-amd64", "ocis/bin")) +
(tikaService() if params["tikaNeeded"] and not run_on_k8s else tikaServiceK8s() if params["tikaNeeded"] and run_on_k8s else []) +
(waitForServices("online-offices", ["collabora:9980", "onlyoffice:443", "fakeoffice:8080"]) if params["collaborationServiceNeeded"] else []) +
(waitK3sCluster() + (enableAntivirusServiceK8s() if params["antivirusNeeded"] and run_on_k8s else []) + (emailServiceK8s() if params["emailNeeded"] and run_on_k8s else []) + prepareOcisDeployment() + setupOcisConfigMaps() + deployOcis() + waitForOcis(ocis_url = ocis_url) + ociswrapper() + waitForOciswrapper() if run_on_k8s else ocisServer(storage, extra_server_environment = params["extraServerEnvironment"], with_wrapper = True, tika_enabled = params["tikaNeeded"], volumes = ([stepVolumeOcisStorage]))) +
deployment_steps +
(waitForClamavService() if params["antivirusNeeded"] and not run_on_k8s else exposeAntivirusServiceK8s() if params["antivirusNeeded"] and run_on_k8s else []) +
(waitForEmailService() if params["emailNeeded"] and not run_on_k8s else exposeEmailServiceK8s() if params["emailNeeded"] and run_on_k8s else []) +
(ocisServer(storage, deploy_type = "federation", extra_server_environment = params["extraServerEnvironment"]) if params["federationServer"] else []) +
(ocisServer(storage, deploy_type = "federation", extra_server_environment = params["extraServerEnvironment"]) if params["federationServer"] and not run_on_k8s else []) +
((wopiCollaborationService("fakeoffice") + wopiCollaborationService("collabora") + wopiCollaborationService("onlyoffice")) if params["collaborationServiceNeeded"] else []) +
(ocisHealthCheck("wopi", ["wopi-collabora:9304", "wopi-onlyoffice:9304", "wopi-fakeoffice:9304"]) if params["collaborationServiceNeeded"] else []) +
localApiTests(name, params["suites"], storage, params["extraEnvironment"], run_with_remote_php, ocis_url = ocis_url, k8s = run_on_k8s) +
localApiTests(name, params["suites"], storage, params["extraEnvironment"], run_with_remote_php, ocis_url = ocis_url, ocis_fed_url = ocis_fed_url, k8s = run_on_k8s) +
apiTestFailureLog() +
(generateCoverageFromAPITest(ctx, name) if not run_on_k8s else []),
"services": (k3sCluster() if run_on_k8s else []) +
"services": (k3sCluster() if run_on_k8s and not params["federationServer"] else []) +
(k3sCluster(ocm = True) + k3sCluster(name = FED_OCIS_SERVER_NAME, ocm = True) if run_on_k8s and params["federationServer"] else []) +
(emailService() if params["emailNeeded"] and not run_on_k8s else []) +
(clamavService() if params["antivirusNeeded"] and not run_on_k8s else []) +
((fakeOffice() + collaboraService() + onlyofficeService()) if params["collaborationServiceNeeded"] else []),
@@ -1191,13 +1213,12 @@ def generateCoverageFromAPITest(ctx, name):
},
]
def localApiTests(name, suites, storage = "ocis", extra_environment = {}, with_remote_php = False, ocis_url = OCIS_URL, k8s = False):
def localApiTests(name, suites, storage = "ocis", extra_environment = {}, with_remote_php = False, ocis_url = OCIS_URL, ocis_fed_url = OCIS_FED_URL, k8s = False):
test_dir = "%s/tests/acceptance" % dirs["base"]
expected_failures_file = "%s/expected-failures-localAPI-on-%s-storage.md" % (test_dir, storage.upper())
environment = {
"TEST_SERVER_URL": ocis_url,
"TEST_SERVER_FED_URL": OCIS_FED_URL,
"TEST_SERVER_FED_URL": ocis_fed_url,
"OCIS_REVA_DATA_ROOT": "%s" % (dirs["ocisRevaDataRoot"] if storage == "owncloud" else ""),
"STORAGE_DRIVER": storage,
"BEHAT_SUITES": ",".join(suites),
@@ -1212,7 +1233,8 @@ def localApiTests(name, suites, storage = "ocis", extra_environment = {}, with_r
for item in extra_environment:
environment[item] = extra_environment[item]
if k8s:
environment["EMAIL_HOST"] = OCIS_SERVER_NAME
return [{
"name": "localApiTests-%s" % name,
"image": OC_CI_PHP % DEFAULT_PHP_VERSION,
@@ -3788,42 +3810,69 @@ def trivyScan(ctx):
},
}
def k3sCluster():
def k3sCluster(name = OCIS_SERVER_NAME, ocm = False):
peer_name = OCIS_SERVER_NAME if name == FED_OCIS_SERVER_NAME else FED_OCIS_SERVER_NAME
commands = []
commands.extend([
"if [ ! -d %s/ocis-charts ]; then git clone --single-branch --branch main --depth 1 https://github.com/owncloud/ocis-charts.git; fi" % dirs["base"],
"nohup dockerd-entrypoint.sh &",
"until docker ps 2>&1 > /dev/null; do sleep 1s; done",
# create cluster
"k3d cluster create %s --api-port %s:33199 " % (name, name) +
"-p '80:80@loadbalancer' -p '443:443@loadbalancer' -p '8025:32025@loadbalancer' -p '9100-9399:30100-30399@loadbalancer' " +
"--k3s-arg '--tls-san=k3d@server:*' --k3s-arg '--disable=metrics-server@server:*'",
# wait for services to be ready
"until kubectl get deployment coredns -n kube-system -o go-template='{{.status.availableReplicas}}' | grep -v -e '<no value>'; do sleep 1s; done",
"until kubectl get deployment traefik -n kube-system -o go-template='{{.status.availableReplicas}}' | grep -v -e '<no value>'; do sleep 1s; done",
"k3d kubeconfig get %s > kubeconfig-$${DRONE_BUILD_NUMBER}-%s.yaml" % (name, name),
"chmod 0600 kubeconfig-$${DRONE_BUILD_NUMBER}-%s.yaml" % name,
"printf '@@@@@@@@@@@@@@@@@@@@@@@\\n@@@@ k3d is ready @@@@\\n@@@@@@@@@@@@@@@@@@@@@@@\\n'",
# add dns rewrite rule
"kubectl create configmap coredns-custom -n kube-system " +
"--from-literal='rewritehost.override=rewrite name exact %s host.k3d.internal'" % name,
"kubectl -n kube-system rollout restart deployment coredns",
])
if ocm:
commands.extend([
# wait for peer
"echo 'Waiting for %s to be available...'" % peer_name,
"for i in {1..60}; do if getent hosts %s > /dev/null 2>&1; then break; fi; echo 'Waiting for %s... attempt '$i; sleep 2; done" % (peer_name, peer_name),
# get the IP of peer
"PEER_IP=$(getent hosts %s | awk '{ print $1 }')" % peer_name,
"echo \"%s IP: $PEER_IP\"" % peer_name,
# create namespace for ocis
"kubectl create namespace ocis --dry-run=client -o yaml | kubectl apply -f -",
# create service in the 'ocis' namespace
"cat <<EOF | kubectl apply -f -\napiVersion: v1\nkind: Service\nmetadata:\n name: %s\n namespace: ocis\nspec:\n type: ClusterIP\n clusterIP: None\n ports:\n - port: 443\n protocol: TCP\n---\napiVersion: v1\nkind: Endpoints\nmetadata:\n name: %s\n namespace: ocis\nsubsets:\n- addresses:\n - ip: $PEER_IP\n ports:\n - port: 443\n protocol: TCP\nEOF" % (peer_name, peer_name),
# verify
"kubectl get svc %s -n ocis" % peer_name,
"kubectl get endpoints %s -n ocis" % peer_name,
])
commands.extend([
"printf '@@@@@@@@@@@@@@@@@@@@@@@\\n@@@@ k3d is ready @@@@\\n@@@@@@@@@@@@@@@@@@@@@@@\\n'",
# watch events
"kubectl get events -Aw",
])
return [{
"name": OCIS_SERVER_NAME,
"name": name,
"image": K3D_IMAGE,
"user": "root",
"privileged": True,
"commands": [
"git clone --single-branch --branch main --depth 1 https://github.com/owncloud/ocis-charts.git",
"nohup dockerd-entrypoint.sh &",
"until docker ps 2>&1 > /dev/null; do sleep 1s; done",
# create cluster
"k3d cluster create drone --api-port %s:33199 " % OCIS_SERVER_NAME +
"-p '80:80@loadbalancer' -p '443:443@loadbalancer' -p '9100-9399:30100-30399@loadbalancer' " +
"--k3s-arg '--tls-san=k3d@server:*' --k3s-arg '--disable=metrics-server@server:*'",
# wait for services to be ready
"until kubectl get deployment coredns -n kube-system -o go-template='{{.status.availableReplicas}}' | grep -v -e '<no value>'; do sleep 1s; done",
"until kubectl get deployment traefik -n kube-system -o go-template='{{.status.availableReplicas}}' | grep -v -e '<no value>'; do sleep 1s; done",
"k3d kubeconfig get drone > kubeconfig-$${DRONE_BUILD_NUMBER}.yaml",
"chmod 0600 kubeconfig-$${DRONE_BUILD_NUMBER}.yaml",
"printf '@@@@@@@@@@@@@@@@@@@@@@@\n@@@@ k3d is ready @@@@\n@@@@@@@@@@@@@@@@@@@@@@@\n'",
# add dns rewrite rule
"kubectl create configmap coredns-custom -n kube-system " +
"--from-literal='rewritehost.override=rewrite name exact %s host.k3d.internal'" % OCIS_SERVER_NAME,
"kubectl -n kube-system rollout restart deployment coredns",
# watch events
"kubectl get events -Aw",
],
"commands": commands,
}]
def waitK3sCluster():
def waitK3sCluster(name = OCIS_SERVER_NAME):
step_name = "wait-cluster-" + name
return [{
"name": "wait-cluster",
"name": step_name,
"image": K3D_IMAGE,
"user": "root",
"commands": [
"export KUBECONFIG=kubeconfig-$${DRONE_BUILD_NUMBER}.yaml",
"export KUBECONFIG=kubeconfig-$${DRONE_BUILD_NUMBER}-" + OCIS_SERVER_NAME + ".yaml",
"timeout 300 bash -c 'until test -f $${KUBECONFIG}; do sleep 1; done'",
"kubectl config view",
"kubectl get pods -A",
@@ -3867,9 +3916,11 @@ def prepareOcisDeployment():
],
}]
def setupOcisConfigMaps():
def setupOcisConfigMaps(name = OCIS_SERVER_NAME):
step_name = "setup-configmaps-" + name
commands = [
"export KUBECONFIG=%s/kubeconfig-$${DRONE_BUILD_NUMBER}.yaml" % dirs["base"],
"export KUBECONFIG=%s/kubeconfig-$${DRONE_BUILD_NUMBER}-%s.yaml" % (dirs["base"], name),
# Create namespace for oCIS deployment
"kubectl create namespace ocis || true",
"kubectl create configmap -n ocis sharing-banned-passwords --from-file=banned-password-list.txt=%s/tests/config/drone/banned-password-list.txt" % dirs["base"],
@@ -3880,21 +3931,32 @@ def setupOcisConfigMaps():
]
return [{
"name": "setup-configmaps",
"name": step_name,
"image": K3D_IMAGE,
"user": "root",
"commands": commands,
}]
def deployOcis():
def deployOcis(name = OCIS_SERVER_NAME):
step_name = "deploy-" + name
commands = [
"export KUBECONFIG=%s/kubeconfig-$${DRONE_BUILD_NUMBER}-%s.yaml" % (dirs["base"], name),
"cd %s/ocis-charts" % dirs["base"],
]
if name == FED_OCIS_SERVER_NAME:
commands.extend([
"sed -i 's|externalDomain: ocis-server|externalDomain: %s|' ./charts/ocis/ci/deployment-values.yaml" % FED_OCIS_SERVER_NAME,
])
commands.extend([
"make helm-install-atomic",
])
return [{
"name": "deploy-ocis",
"name": step_name,
"image": "owncloudci/golang:1.25",
"commands": [
"export KUBECONFIG=%s/kubeconfig-$${DRONE_BUILD_NUMBER}.yaml" % dirs["base"],
"cd %s/ocis-charts" % dirs["base"],
"make helm-install-atomic",
],
"commands": commands,
"volumes": [
{
"name": "gopath",
@@ -3924,23 +3986,25 @@ def emailServiceK8s():
],
}]
def exposeEmailServiceK8s():
def exposeEmailServiceK8s(name = OCIS_SERVER_NAME):
return [{
"name": EMAIL_SMTP_HOST,
"image": K3D_IMAGE,
"commands": [
"kubectl port-forward svc/mailpit %s:%s -n ocis" % (EMAIL_PORT, EMAIL_PORT),
"kubectl port-forward svc/mailpit 9174:9174 -n ocis",
"export KUBECONFIG=%s/kubeconfig-$${DRONE_BUILD_NUMBER}-%s.yaml" % (dirs["base"], name),
"until test -f $${KUBECONFIG}; do sleep 1s; done",
"kubectl -n ocis expose deployment mailpit --type=NodePort --port=8025 --name=mailpit-np",
"kubectl -n ocis patch svc mailpit-np -p '{\"spec\":{\"ports\":[{\"port\":8025,\"nodePort\":32025,\"targetPort\":8025}]}}'",
],
"detach": True,
}]
def exposeAntivirusServiceK8s():
def exposeAntivirusServiceK8s(name = OCIS_SERVER_NAME):
return [{
"name": "expose-antivirus-service",
"image": K3D_IMAGE,
"commands": [
"export KUBECONFIG=kubeconfig-$${DRONE_BUILD_NUMBER}.yaml",
"export KUBECONFIG=kubeconfig-$${DRONE_BUILD_NUMBER}-%s.yaml" % name,
"until test -f $${KUBECONFIG}; do sleep 1s; done",
# expose antivirus service via NodePort
"kubectl -n ocis expose deployment antivirus --type=NodePort --port=9277 --name=antivirus-np",
@@ -3948,13 +4012,13 @@ def exposeAntivirusServiceK8s():
],
}]
def ociswrapper():
def ociswrapper(name = OCIS_SERVER_NAME):
return [{
"name": "ociswrapper",
"image": K3D_IMAGE,
"user": "root",
"commands": [
"export KUBECONFIG=kubeconfig-$${DRONE_BUILD_NUMBER}.yaml",
"export KUBECONFIG=kubeconfig-$${DRONE_BUILD_NUMBER}-%s.yaml" % name,
"until test -f $${KUBECONFIG}; do sleep 1s; done",
"kubectl get pods -A",
"kubectl get ingress -A",

View File

@@ -707,7 +707,10 @@ class FeatureContext extends BehatVariablesContext {
*/
public function removeSchemeFromUrl(string $url): string {
$parsedUrl = parse_url($url);
return $parsedUrl["host"] . ":" . $parsedUrl["port"];
if (isset($parsedUrl['port'])) {
return $parsedUrl["host"] . ":" . $parsedUrl["port"];
}
return $parsedUrl["host"];
}
/**

View File

@@ -7,7 +7,63 @@ ingress:
enabled: true
ingressClassName: traefik
externalDomain: ocis-server
extraResources: []
extraResources:
- |
apiVersion: v1
kind: ConfigMap
metadata:
name: ocmproviders
namespace: {{ template "ocis.namespace" . }}
labels:
{{- include "ocis.labels" . | nindent 8 }}
data:
ocmproviders.json: |
[
{
"name": "ocis",
"full_name": "ocis server",
"organization": "ownCloud",
"domain": "ocis-server",
"homepage": "https://ocis-server",
"services": [
{
"endpoint": {
"type": {
"name": "OCM",
"description": "ownCloud Open Cloud Mesh API"
},
"name": "ocis-server - OCM API",
"path": "https://ocis-server/ocm/",
"is_monitored": true
},
"api_version": "0.0.1",
"host": "https://ocis-server"
}
]
},
{
"name": "federation ocis",
"full_name": "federation ocis server",
"organization": "ownCloud",
"domain": "federation-ocis-server",
"homepage": "https://federation-ocis-server",
"services": [
{
"endpoint": {
"type": {
"name": "OCM",
"description": "federation ownCloud Open Cloud Mesh API"
},
"name": "federation-ocis-server - OCM API",
"path": "https://federation-ocis-server/ocm/",
"is_monitored": true
},
"api_version": "0.0.1",
"host": "https://federation-ocis-server"
}
]
}
]
logging:
level: error
@@ -34,7 +90,8 @@ features:
policies:
enabled: false
ocm:
enabled: false
enabled: true
providersConfigRef: "ocmproviders"
sharing:
passwordPolicies:
bannedPasswords: