From ecce837dd80abcb75bd88fa475fbf43bf9c3281d Mon Sep 17 00:00:00 2001 From: Sammi Chen Date: Mon, 11 May 2026 14:07:28 +0800 Subject: [PATCH 1/6] HDDS-15227. Add lifecycle robot test --- .../main/compose/ozonesecure-ha/docker-config | 6 + .../ozonesecure-ha/test-om-lifecycle.sh | 38 ++++++ .../smoketest/admincli/om-lifecycle.robot | 119 ++++++++++++++++++ .../main/smoketest/s3/bucketlifecycle.robot | 53 ++++++++ 4 files changed, 216 insertions(+) create mode 100644 hadoop-ozone/dist/src/main/compose/ozonesecure-ha/test-om-lifecycle.sh create mode 100644 hadoop-ozone/dist/src/main/smoketest/admincli/om-lifecycle.robot create mode 100644 hadoop-ozone/dist/src/main/smoketest/s3/bucketlifecycle.robot diff --git a/hadoop-ozone/dist/src/main/compose/ozonesecure-ha/docker-config b/hadoop-ozone/dist/src/main/compose/ozonesecure-ha/docker-config index 8133eb1073e6..dd89f7cae8b7 100644 --- a/hadoop-ozone/dist/src/main/compose/ozonesecure-ha/docker-config +++ b/hadoop-ozone/dist/src/main/compose/ozonesecure-ha/docker-config @@ -178,3 +178,9 @@ OZONE-SITE.XML_hdds.secret.key.expiry.duration=1h OZONE-SITE.XML_ozone.manager.delegation.token.max-lifetime=30m OZONE-SITE.XML_ozone.manager.delegation.token.renew-interval=5m OZONE-SITE.XML_ozone.manager.delegation.remover.scan.interval=1m + +# Enable Ozone lifecycle service +OZONE-SITE.XML_ozone.lifecycle.service.enabled=true +OZONE-SITE.XML_ozone.lifecycle.service.interval=30s +OZONE-SITE.XML_ozone.lifecycle.service.timeout=10s + diff --git a/hadoop-ozone/dist/src/main/compose/ozonesecure-ha/test-om-lifecycle.sh b/hadoop-ozone/dist/src/main/compose/ozonesecure-ha/test-om-lifecycle.sh new file mode 100644 index 000000000000..7d70973a9888 --- /dev/null +++ b/hadoop-ozone/dist/src/main/compose/ozonesecure-ha/test-om-lifecycle.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#suite:HA-secure + +set -u -o pipefail + +COMPOSE_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +export COMPOSE_DIR + +export SECURITY_ENABLED=true +export OM_SERVICE_ID="omservice" +export SCM=scm1.org + +# shellcheck source=/dev/null +source "$COMPOSE_DIR/../testlib.sh" + +start_docker_env + +execute_robot_test s3g kinit.robot + +execute_robot_test s3g admincli/om-lifecycle.robot + +execute_robot_test s3g s3/bucketlifecycle.robot diff --git a/hadoop-ozone/dist/src/main/smoketest/admincli/om-lifecycle.robot b/hadoop-ozone/dist/src/main/smoketest/admincli/om-lifecycle.robot new file mode 100644 index 000000000000..528ea88735b4 --- /dev/null +++ b/hadoop-ozone/dist/src/main/smoketest/admincli/om-lifecycle.robot @@ -0,0 +1,119 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +*** Settings *** +Documentation Ozone admin om lifecycle commands +Library OperatingSystem +Resource ../commonlib.robot +Test Timeout 5 minutes + +*** Variables *** +${OM_SERVICE_ID} om + +*** Test Cases *** +Test Lifecycle Status + ${output} = Execute ozone admin om lifecycle status + Should Contain ${output} IsEnabled + Should Contain ${output} IsSuspended + +Test Lifecycle Suspend And Resume + ${output} = Execute ozone admin om lifecycle suspend + Should Contain ${output} Lifecycle Service has been suspended + + ${output} = Execute ozone admin om lifecycle status + Should Contain ${output} IsSuspended: true + + ${output} = Execute ozone admin om lifecycle resume + Should Contain ${output} Lifecycle Service has been resumed + + ${output} = Execute ozone admin om lifecycle status + Should Contain ${output} IsSuspended: false + +Test Lifecycle Status After Leader Transfer + ${output} = Execute ozone admin om roles + ${is_ha} = Run Keyword And Return Status Should Contain ${output} FOLLOWER + IF ${is_ha} + ${output} = Execute ozone admin om lifecycle suspend + Should Contain ${output} Lifecycle Service has been suspended + + ${output} = Execute ozone admin om transfer -r + Should Contain ${output} Transfer leadership successfully + + ${output} = Execute ozone admin om lifecycle status + Should Contain ${output} IsSuspended: true + + ${output} = Execute ozone admin om lifecycle resume + Should Contain ${output} Lifecycle Service has been resumed + + ${output} = Execute ozone admin om lifecycle status + Should Contain ${output} IsSuspended: false + ELSE + Pass Execution Cluster is not HA, skipping leader transfer test + END + +Test Lifecycle Suspend And Resume Requires Admin + # This test verifies that suspend and resume commands require admin privileges + # while the status command does not. + # The Requires admin privilege keyword automatically switches to testuser2 via kinit + # in secure environments and verifies access is denied. + + Get Security Enabled From Config + IF '${SECURITY_ENABLED}' == 'true' + # First switch to non-admin user + Kinit test user testuser2 testuser2.keytab + + # Status should work for non-admin + ${output} = Execute and checkrc ozone admin om lifecycle status 0 + Should Contain ${output} IsEnabled + + # Suspend should fail for non-admin + Access should be denied ozone admin om lifecycle suspend + + # Resume should fail for non-admin + Access should be denied ozone admin om lifecycle resume + + # Switch back to admin user for subsequent tests + Kinit test user testuser testuser.keytab + + # Verify admin can suspend and resume + ${output} = Execute and checkrc ozone admin om lifecycle suspend 0 + Should Contain ${output} Lifecycle Service has been suspended + + ${output} = Execute and checkrc ozone admin om lifecycle resume 0 + Should Contain ${output} Lifecycle Service has been resumed + ELSE + # In non-secure environments, we can test by passing a different user via HADOOP_USER_NAME + + # Status should work for non-admin + ${output} = Execute and checkrc env HADOOP_USER_NAME=testuser2 ozone admin om lifecycle status 0 + Should Contain ${output} IsEnabled + + # Suspend should fail for non-admin + ${output} = Execute and checkrc env HADOOP_USER_NAME=testuser2 ozone admin om lifecycle suspend 255 + Should Contain ${output} Access denied + Should Contain ${output} Superuser privilege is required + + # Resume should fail for non-admin + ${output} = Execute and checkrc env HADOOP_USER_NAME=testuser2 ozone admin om lifecycle resume 255 + Should Contain ${output} Access denied + Should Contain ${output} Superuser privilege is required + + # Verify admin (default user) can suspend and resume + ${output} = Execute and checkrc ozone admin om lifecycle suspend 0 + Should Contain ${output} Lifecycle Service has been suspended + + ${output} = Execute and checkrc ozone admin om lifecycle resume 0 + Should Contain ${output} Lifecycle Service has been resumed + END diff --git a/hadoop-ozone/dist/src/main/smoketest/s3/bucketlifecycle.robot b/hadoop-ozone/dist/src/main/smoketest/s3/bucketlifecycle.robot new file mode 100644 index 000000000000..39b46c1b82a8 --- /dev/null +++ b/hadoop-ozone/dist/src/main/smoketest/s3/bucketlifecycle.robot @@ -0,0 +1,53 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +*** Settings *** +Documentation S3 gateway test with aws cli for bucket lifecycle +Library OperatingSystem +Library String +Resource ../commonlib.robot +Resource commonawslib.robot +Test Timeout 5 minutes +Suite Setup Setup s3 tests + +*** Variables *** +${ENDPOINT_URL} http://s3g:9878 +${BUCKET} generated + +*** Test Cases *** + +Set bucket lifecycle configuration + ${bucket} = Create bucket + ${lifecycle_json} = Set Variable {"Rules": [{"ID": "Rule1", "Prefix": "prefix1/", "Status": "Enabled", "Expiration": {"Days": 1}}]} + ${result} = Execute AWSS3APICli put-bucket-lifecycle-configuration --bucket ${bucket} --lifecycle-configuration '${lifecycle_json}' + Should Be Empty ${result} + +Get bucket lifecycle configuration + ${bucket} = Create bucket + ${lifecycle_json} = Set Variable {"Rules": [{"ID": "Rule1", "Prefix": "prefix1/", "Status": "Enabled", "Expiration": {"Days": 1}}]} + ${result} = Execute AWSS3APICli put-bucket-lifecycle-configuration --bucket ${bucket} --lifecycle-configuration '${lifecycle_json}' + ${result} = Execute AWSS3APICli get-bucket-lifecycle-configuration --bucket ${bucket} + Should contain ${result} Rule1 + Should contain ${result} prefix1/ + Should contain ${result} Enabled + +Delete bucket lifecycle configuration + ${bucket} = Create bucket + ${lifecycle_json} = Set Variable {"Rules": [{"ID": "Rule1", "Prefix": "prefix1/", "Status": "Enabled", "Expiration": {"Days": 1}}]} + ${result} = Execute AWSS3APICli put-bucket-lifecycle-configuration --bucket ${bucket} --lifecycle-configuration '${lifecycle_json}' + ${result} = Execute AWSS3APICli delete-bucket-lifecycle --bucket ${bucket} + Should Be Empty ${result} + ${result} = Execute AWSS3APICli and checkrc get-bucket-lifecycle-configuration --bucket ${bucket} 255 + Should contain ${result} NoSuchLifecycleConfiguration From 0aa839e0f9489637305065d74279e774d5b6beaa Mon Sep 17 00:00:00 2001 From: Sammi Chen Date: Mon, 11 May 2026 19:47:56 +0800 Subject: [PATCH 2/6] add --service-id --- .../smoketest/admincli/om-lifecycle.robot | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/hadoop-ozone/dist/src/main/smoketest/admincli/om-lifecycle.robot b/hadoop-ozone/dist/src/main/smoketest/admincli/om-lifecycle.robot index 528ea88735b4..a3d97b4b5316 100644 --- a/hadoop-ozone/dist/src/main/smoketest/admincli/om-lifecycle.robot +++ b/hadoop-ozone/dist/src/main/smoketest/admincli/om-lifecycle.robot @@ -24,40 +24,40 @@ ${OM_SERVICE_ID} om *** Test Cases *** Test Lifecycle Status - ${output} = Execute ozone admin om lifecycle status + ${output} = Execute ozone admin om lifecycle status --service-id '${OM_SERVICE_ID}' Should Contain ${output} IsEnabled Should Contain ${output} IsSuspended Test Lifecycle Suspend And Resume - ${output} = Execute ozone admin om lifecycle suspend + ${output} = Execute ozone admin om lifecycle suspend --service-id '${OM_SERVICE_ID}' Should Contain ${output} Lifecycle Service has been suspended - ${output} = Execute ozone admin om lifecycle status + ${output} = Execute ozone admin om lifecycle status --service-id '${OM_SERVICE_ID}' Should Contain ${output} IsSuspended: true - ${output} = Execute ozone admin om lifecycle resume + ${output} = Execute ozone admin om lifecycle resume --service-id '${OM_SERVICE_ID}' Should Contain ${output} Lifecycle Service has been resumed - ${output} = Execute ozone admin om lifecycle status + ${output} = Execute ozone admin om lifecycle status --service-id '${OM_SERVICE_ID}' Should Contain ${output} IsSuspended: false Test Lifecycle Status After Leader Transfer - ${output} = Execute ozone admin om roles + ${output} = Execute ozone admin om roles --service-id '${OM_SERVICE_ID}' ${is_ha} = Run Keyword And Return Status Should Contain ${output} FOLLOWER IF ${is_ha} - ${output} = Execute ozone admin om lifecycle suspend + ${output} = Execute ozone admin om lifecycle suspend --service-id '${OM_SERVICE_ID}' Should Contain ${output} Lifecycle Service has been suspended - ${output} = Execute ozone admin om transfer -r + ${output} = Execute ozone admin om transfer --service-id '${OM_SERVICE_ID}' -r Should Contain ${output} Transfer leadership successfully - ${output} = Execute ozone admin om lifecycle status + ${output} = Execute ozone admin om lifecycle status --service-id '${OM_SERVICE_ID}' Should Contain ${output} IsSuspended: true - ${output} = Execute ozone admin om lifecycle resume + ${output} = Execute ozone admin om lifecycle resume --service-id '${OM_SERVICE_ID}' Should Contain ${output} Lifecycle Service has been resumed - ${output} = Execute ozone admin om lifecycle status + ${output} = Execute ozone admin om lifecycle status --service-id '${OM_SERVICE_ID}' Should Contain ${output} IsSuspended: false ELSE Pass Execution Cluster is not HA, skipping leader transfer test @@ -75,45 +75,45 @@ Test Lifecycle Suspend And Resume Requires Admin Kinit test user testuser2 testuser2.keytab # Status should work for non-admin - ${output} = Execute and checkrc ozone admin om lifecycle status 0 + ${output} = Execute and checkrc ozone admin om lifecycle status --service-id '${OM_SERVICE_ID}' 0 Should Contain ${output} IsEnabled # Suspend should fail for non-admin - Access should be denied ozone admin om lifecycle suspend + Access should be denied ozone admin om lifecycle suspend --service-id '${OM_SERVICE_ID}' # Resume should fail for non-admin - Access should be denied ozone admin om lifecycle resume + Access should be denied ozone admin om lifecycle resume --service-id '${OM_SERVICE_ID}' # Switch back to admin user for subsequent tests Kinit test user testuser testuser.keytab # Verify admin can suspend and resume - ${output} = Execute and checkrc ozone admin om lifecycle suspend 0 + ${output} = Execute and checkrc ozone admin om lifecycle suspend --service-id '${OM_SERVICE_ID}' 0 Should Contain ${output} Lifecycle Service has been suspended - ${output} = Execute and checkrc ozone admin om lifecycle resume 0 + ${output} = Execute and checkrc ozone admin om lifecycle resume --service-id '${OM_SERVICE_ID}' 0 Should Contain ${output} Lifecycle Service has been resumed ELSE # In non-secure environments, we can test by passing a different user via HADOOP_USER_NAME # Status should work for non-admin - ${output} = Execute and checkrc env HADOOP_USER_NAME=testuser2 ozone admin om lifecycle status 0 + ${output} = Execute and checkrc env HADOOP_USER_NAME=testuser2 ozone admin om lifecycle status --service-id '${OM_SERVICE_ID}' 0 Should Contain ${output} IsEnabled # Suspend should fail for non-admin - ${output} = Execute and checkrc env HADOOP_USER_NAME=testuser2 ozone admin om lifecycle suspend 255 + ${output} = Execute and checkrc env HADOOP_USER_NAME=testuser2 ozone admin om lifecycle suspend --service-id '${OM_SERVICE_ID}' 255 Should Contain ${output} Access denied Should Contain ${output} Superuser privilege is required # Resume should fail for non-admin - ${output} = Execute and checkrc env HADOOP_USER_NAME=testuser2 ozone admin om lifecycle resume 255 + ${output} = Execute and checkrc env HADOOP_USER_NAME=testuser2 ozone admin om lifecycle resume --service-id '${OM_SERVICE_ID}' 255 Should Contain ${output} Access denied Should Contain ${output} Superuser privilege is required # Verify admin (default user) can suspend and resume - ${output} = Execute and checkrc ozone admin om lifecycle suspend 0 + ${output} = Execute and checkrc ozone admin om lifecycle suspend --service-id '${OM_SERVICE_ID}' 0 Should Contain ${output} Lifecycle Service has been suspended - ${output} = Execute and checkrc ozone admin om lifecycle resume 0 + ${output} = Execute and checkrc ozone admin om lifecycle resume --service-id '${OM_SERVICE_ID}' 0 Should Contain ${output} Lifecycle Service has been resumed END From 0f1f859ec87ed7b50fe490d68976ad1b2beb014f Mon Sep 17 00:00:00 2001 From: Sammi Chen Date: Tue, 12 May 2026 11:54:50 +0800 Subject: [PATCH 3/6] remove OM_SERVICE_ID redefinition --- .../dist/src/main/smoketest/admincli/om-lifecycle.robot | 3 --- 1 file changed, 3 deletions(-) diff --git a/hadoop-ozone/dist/src/main/smoketest/admincli/om-lifecycle.robot b/hadoop-ozone/dist/src/main/smoketest/admincli/om-lifecycle.robot index a3d97b4b5316..18c98d1536d2 100644 --- a/hadoop-ozone/dist/src/main/smoketest/admincli/om-lifecycle.robot +++ b/hadoop-ozone/dist/src/main/smoketest/admincli/om-lifecycle.robot @@ -19,9 +19,6 @@ Library OperatingSystem Resource ../commonlib.robot Test Timeout 5 minutes -*** Variables *** -${OM_SERVICE_ID} om - *** Test Cases *** Test Lifecycle Status ${output} = Execute ozone admin om lifecycle status --service-id '${OM_SERVICE_ID}' From b8406c64266056372ece94ebe1371149e11093a5 Mon Sep 17 00:00:00 2001 From: Sammi Chen Date: Tue, 12 May 2026 13:27:06 +0800 Subject: [PATCH 4/6] add back OM_SERVICE_ID definition --- .../dist/src/main/smoketest/admincli/om-lifecycle.robot | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hadoop-ozone/dist/src/main/smoketest/admincli/om-lifecycle.robot b/hadoop-ozone/dist/src/main/smoketest/admincli/om-lifecycle.robot index 18c98d1536d2..222c4de75a62 100644 --- a/hadoop-ozone/dist/src/main/smoketest/admincli/om-lifecycle.robot +++ b/hadoop-ozone/dist/src/main/smoketest/admincli/om-lifecycle.robot @@ -19,6 +19,9 @@ Library OperatingSystem Resource ../commonlib.robot Test Timeout 5 minutes +*** Variables *** +${OM_SERVICE_ID} %{OM_SERVICE_ID} + *** Test Cases *** Test Lifecycle Status ${output} = Execute ozone admin om lifecycle status --service-id '${OM_SERVICE_ID}' From 23741ea763c9bc1ede9912a142dfb0edba61b49a Mon Sep 17 00:00:00 2001 From: Sammi Chen Date: Tue, 12 May 2026 14:44:44 +0800 Subject: [PATCH 5/6] add new lifecycle directory and move robot test to it --- .../dist/src/main/compose/ozonesecure-ha/test-om-lifecycle.sh | 2 +- .../main/smoketest/{admincli => lifecycle}/om-lifecycle.robot | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename hadoop-ozone/dist/src/main/smoketest/{admincli => lifecycle}/om-lifecycle.robot (100%) diff --git a/hadoop-ozone/dist/src/main/compose/ozonesecure-ha/test-om-lifecycle.sh b/hadoop-ozone/dist/src/main/compose/ozonesecure-ha/test-om-lifecycle.sh index 7d70973a9888..35232b9ecabd 100644 --- a/hadoop-ozone/dist/src/main/compose/ozonesecure-ha/test-om-lifecycle.sh +++ b/hadoop-ozone/dist/src/main/compose/ozonesecure-ha/test-om-lifecycle.sh @@ -33,6 +33,6 @@ start_docker_env execute_robot_test s3g kinit.robot -execute_robot_test s3g admincli/om-lifecycle.robot +execute_robot_test s3g lifecycle/om-lifecycle.robot execute_robot_test s3g s3/bucketlifecycle.robot diff --git a/hadoop-ozone/dist/src/main/smoketest/admincli/om-lifecycle.robot b/hadoop-ozone/dist/src/main/smoketest/lifecycle/om-lifecycle.robot similarity index 100% rename from hadoop-ozone/dist/src/main/smoketest/admincli/om-lifecycle.robot rename to hadoop-ozone/dist/src/main/smoketest/lifecycle/om-lifecycle.robot From 1794ef0812f709d263cc96075d78e12d080b84dd Mon Sep 17 00:00:00 2001 From: Sammi Chen Date: Tue, 19 May 2026 17:37:06 +0800 Subject: [PATCH 6/6] address comments --- hadoop-ozone/dist/src/main/smoketest/s3/bucketlifecycle.robot | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hadoop-ozone/dist/src/main/smoketest/s3/bucketlifecycle.robot b/hadoop-ozone/dist/src/main/smoketest/s3/bucketlifecycle.robot index 39b46c1b82a8..c82e066dab58 100644 --- a/hadoop-ozone/dist/src/main/smoketest/s3/bucketlifecycle.robot +++ b/hadoop-ozone/dist/src/main/smoketest/s3/bucketlifecycle.robot @@ -29,12 +29,14 @@ ${BUCKET} generated *** Test Cases *** Set bucket lifecycle configuration + [tags] no-bucket-type ${bucket} = Create bucket ${lifecycle_json} = Set Variable {"Rules": [{"ID": "Rule1", "Prefix": "prefix1/", "Status": "Enabled", "Expiration": {"Days": 1}}]} ${result} = Execute AWSS3APICli put-bucket-lifecycle-configuration --bucket ${bucket} --lifecycle-configuration '${lifecycle_json}' Should Be Empty ${result} Get bucket lifecycle configuration + [tags] no-bucket-type ${bucket} = Create bucket ${lifecycle_json} = Set Variable {"Rules": [{"ID": "Rule1", "Prefix": "prefix1/", "Status": "Enabled", "Expiration": {"Days": 1}}]} ${result} = Execute AWSS3APICli put-bucket-lifecycle-configuration --bucket ${bucket} --lifecycle-configuration '${lifecycle_json}' @@ -42,8 +44,10 @@ Get bucket lifecycle configuration Should contain ${result} Rule1 Should contain ${result} prefix1/ Should contain ${result} Enabled + Should contain ${result} "Days": 1 Delete bucket lifecycle configuration + [tags] no-bucket-type ${bucket} = Create bucket ${lifecycle_json} = Set Variable {"Rules": [{"ID": "Rule1", "Prefix": "prefix1/", "Status": "Enabled", "Expiration": {"Days": 1}}]} ${result} = Execute AWSS3APICli put-bucket-lifecycle-configuration --bucket ${bucket} --lifecycle-configuration '${lifecycle_json}'