Skip to content

Commit c275232

Browse files
committed
feat: port OTP etcd test cases to Robot Framework
Port MicroShiftOnly OTP etcd test cases to Robot Framework as part of USHIFT-6690. Add the following tests to existing suite files: etcd.robot (standard1): - Etcd Database Defragment Manually (OCP-71790): run etcdctl defrag and verify db size does not grow - Etcd Runs As Transient Systemd Scope Unit (OCP-62738): verify microshift-etcd.scope is running, transient, and has correct systemd wiring (BindsTo/Before microshift.service) - Etcd Scope Follows MicroShift Lifecycle (OCP-60945): verify etcd scope stops/starts with MicroShift validate-certificate-rotation.robot (standard2): - Manual Rotation Of Etcd Signer Certs (OCP-75224): delete etcd signer certs, restart MicroShift, verify all 4 certs are regenerated with valid dates and different fingerprints Also improves Restore System Date to skip when chronyd is already active, preventing timeout when the etcd cert test runs without the clock change test. USHIFT-6745 pre-commit.check-secrets: ENABLED
1 parent 8882ae3 commit c275232

File tree

4 files changed

+150
-13
lines changed

4 files changed

+150
-13
lines changed

scripts/fetch_tools.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,26 @@ gettool_gomplate() {
160160
_install "${url}" "${checksum}" "${filename}" "gomplate_linux-${arch}"
161161
}
162162

163+
gettool_etcdctl() {
164+
# Version must match the etcd server embedded in microshift-etcd.
165+
# Check etcd/vendor/go.etcd.io/etcd/api/v3/version/version.go for the current version.
166+
local ver="3.6.5"
167+
declare -A checksums=(
168+
["x86_64"]="66bad39ed920f6fc15fd74adcb8bfd38ba9a6412f8c7852d09eb11670e88cac3"
169+
["aarch64"]="7010161787077b07de29b15b76825ceacbbcedcb77fe2e6832f509be102cab6b")
170+
171+
declare -A arch_map=(
172+
["x86_64"]="amd64"
173+
["aarch64"]="arm64")
174+
175+
local arch="${arch_map[${ARCH}]}"
176+
local checksum="${checksums[${ARCH}]}"
177+
local filename="etcdctl"
178+
local url="https://github.com/etcd-io/etcd/releases/download/v${ver}/etcd-v${ver}-linux-${arch}.tar.gz"
179+
180+
_install "${url}" "${checksum}" "${filename}" "${filename}"
181+
}
182+
163183
gettool_robotframework() {
164184
local venv
165185

test/bin/ci_phase_boot_and_test.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ cd "${TESTDIR}"
7070
if [ ! -d "${RF_VENV}" ]; then
7171
"${ROOTDIR}/scripts/fetch_tools.sh" robotframework
7272
fi
73+
"${ROOTDIR}/scripts/fetch_tools.sh" etcdctl
7374
if [[ "${SCENARIO_SOURCES:-}" =~ .*releases.* ]]; then
7475
"${ROOTDIR}/scripts/fetch_tools.sh" ginkgo
7576
fi

test/suites/standard1/etcd.robot

Lines changed: 81 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,76 @@ Library Collections
1010
Suite Setup Setup
1111
Suite Teardown Teardown
1212

13-
Test Tags configuration etcd restart slow
13+
Test Tags etcd
1414

1515

1616
*** Variables ***
17-
${ETCD_SYSTEMD_UNIT} microshift-etcd.scope
18-
${MEMLIMIT256} SEPARATOR=\n
19-
... ---
20-
... etcd:
21-
... \ \ memoryLimitMB: 256
22-
${MEMLIMIT0} SEPARATOR=\n
23-
... ---
24-
... etcd:
25-
... \ \ memoryLimitMB: 0
17+
${ETCD_SYSTEMD_UNIT} microshift-etcd.scope
18+
${ETCD_CA_CERT} /var/lib/microshift/certs/etcd-signer/ca.crt
19+
${ETCD_CLIENT_CERT} /var/lib/microshift/certs/etcd-signer/apiserver-etcd-client/client.crt
20+
${ETCD_CLIENT_KEY} /var/lib/microshift/certs/etcd-signer/apiserver-etcd-client/client.key
21+
${ETCD_ENDPOINT} https://localhost:2379
22+
${ETCDCTL_LOCAL_PATH} ${EXECDIR}/../_output/bin/etcdctl
23+
${ETCDCTL_BIN} /tmp/etcdctl
24+
${ETCDCTL_CMD} ${ETCDCTL_BIN} --cacert=${ETCD_CA_CERT} --cert=${ETCD_CLIENT_CERT} --key=${ETCD_CLIENT_KEY} --endpoints=${ETCD_ENDPOINT}
25+
${MEMLIMIT256} SEPARATOR=\n
26+
... ---
27+
... etcd:
28+
... \ \ memoryLimitMB: 256
29+
${MEMLIMIT0} SEPARATOR=\n
30+
... ---
31+
... etcd:
32+
... \ \ memoryLimitMB: 0
2633

2734

2835
*** Test Cases ***
36+
Etcd Database Defragment Manually
37+
[Documentation] Verify that etcd database can be manually defragmented
38+
... using etcdctl and the database size does not grow.
39+
${size_before}= Get Etcd Database Size
40+
Command Should Work ${ETCDCTL_CMD} defrag
41+
${size_after}= Get Etcd Database Size
42+
Should Be True ${size_after} <= ${size_before}
43+
... msg=DB size after defrag (${size_after}) should not exceed size before (${size_before})
44+
[Teardown] Command Should Work ${ETCDCTL_CMD} alarm disarm
45+
46+
Etcd Runs As Transient Systemd Scope Unit
47+
[Documentation] Verify that etcd runs as a transient systemd scope unit
48+
... managed by MicroShift with the expected systemd wiring.
49+
Systemctl Check Service SubState ${ETCD_SYSTEMD_UNIT} running
50+
${transient}= Get Systemd Setting ${ETCD_SYSTEMD_UNIT} Transient
51+
Should Be Equal As Strings ${transient} yes
52+
${pid}= MicroShift Etcd Process ID
53+
Should Not Be Empty ${pid}
54+
${binds_to}= Get Systemd Setting ${ETCD_SYSTEMD_UNIT} BindsTo
55+
Should Contain ${binds_to} microshift.service
56+
${before}= Get Systemd Setting ${ETCD_SYSTEMD_UNIT} Before
57+
Should Contain ${before} microshift.service
58+
59+
Etcd Scope Follows MicroShift Lifecycle
60+
[Documentation] Verify that etcd scope stops with MicroShift and restarts with it.
61+
[Tags] restart slow
62+
Stop MicroShift
63+
Wait Until Etcd Scope Is Inactive
64+
Start MicroShift
65+
Wait For MicroShift
66+
Systemctl Check Service SubState ${ETCD_SYSTEMD_UNIT} running
67+
[Teardown] Run Keywords Start MicroShift AND Wait For MicroShift
68+
2969
Set MemoryHigh Limit Unlimited
3070
[Documentation] The default configuration should not limit RAM
3171
...
3272
... Since we cannot assume that the default configuration file is
3373
... being used, the test explicitly configures a '0' limit, which
3474
... is equivalent to not having any configuration at all.
75+
[Tags] configuration restart slow
3576
[Setup] Setup With Custom Config ${MEMLIMIT0}
3677
Expect MemoryHigh infinity
78+
[Teardown] Restore Default Config
3779

3880
Set MemoryHigh Limit 256MB
3981
[Documentation] Set the memory limit for etcd to 256MB and ensure it takes effect
82+
[Tags] configuration restart slow
4083
[Setup] Setup With Custom Config ${MEMLIMIT256}
4184
# Expecting the setting to be 256 * 1024 * 1024
4285
Expect MemoryHigh 268435456
@@ -49,6 +92,7 @@ Setup
4992
Check Required Env Variables
5093
Login MicroShift Host
5194
Setup Kubeconfig # for readiness checks
95+
Install Etcdctl
5296

5397
Teardown
5498
[Documentation] Test suite teardown
@@ -70,7 +114,33 @@ Setup With Custom Config
70114
Expect MemoryHigh
71115
[Documentation] Verify that the MemoryHigh setting for etcd matches the expected value
72116
[Arguments] ${expected}
73-
${actual}= Get Systemd Setting microshift-etcd.scope MemoryHigh
117+
${actual}= Get Systemd Setting ${ETCD_SYSTEMD_UNIT} MemoryHigh
74118
# Using integer comparison is complicated here because sometimes
75119
# the returned or expected value is 'infinity'.
76120
Should Be Equal ${expected} ${actual}
121+
122+
Etcd Scope Is Inactive
123+
[Documentation] Check that the etcd scope unit is not active.
124+
... Transient scopes disappear when stopped, so is-active returns
125+
... "inactive" or an error.
126+
${stdout} ${rc}= Execute Command
127+
... systemctl is-active ${ETCD_SYSTEMD_UNIT}
128+
... sudo=True return_rc=True
129+
Should Match Regexp ${stdout.strip()} ^inactive$
130+
131+
Wait Until Etcd Scope Is Inactive
132+
[Documentation] Wait for the etcd scope to become inactive
133+
Wait Until Keyword Succeeds 30x 5s
134+
... Etcd Scope Is Inactive
135+
136+
Install Etcdctl
137+
[Documentation] Upload the pre-staged etcdctl binary to the remote host.
138+
... The binary is pre-downloaded with checksum verification by scripts/fetch_tools.sh.
139+
Put File ${ETCDCTL_LOCAL_PATH} ${ETCDCTL_BIN}
140+
141+
Get Etcd Database Size
142+
[Documentation] Return the current etcd database size in bytes
143+
${output}= Command Should Work ${ETCDCTL_CMD} endpoint status --write-out\=json
144+
${size}= Command Should Work
145+
... printf '%s' '${output}' | python3 -c "import sys,json; print(json.load(sys.stdin)[0]['Status']['dbSize'])"
146+
RETURN ${size}

test/suites/standard2/validate-certificate-rotation.robot

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,43 @@ Test Tags restart
1616

1717
*** Variables ***
1818
${KUBE_SCHEDULER_CLIENT_CERT} /var/lib/microshift/certs/kube-control-plane-signer/kube-scheduler/client.crt
19+
${ETCD_SIGNER_CA} /var/lib/microshift/certs/etcd-signer/ca.crt
20+
${ETCD_PEER_CERT} /var/lib/microshift/certs/etcd-signer/etcd-peer/peer.crt
21+
${ETCD_SERVING_CERT} /var/lib/microshift/certs/etcd-signer/etcd-serving/peer.crt
22+
${ETCD_APISERVER_CLIENT_CERT} /var/lib/microshift/certs/etcd-signer/apiserver-etcd-client/client.crt
1923
${OSSL_CMD} openssl x509 -noout -dates -in
2024
${OSSL_DATE_FORMAT} %b %d %Y
2125
${TIMEDATECTL_DATE_FORMAT} %Y-%m-%d %H:%M:%S
2226
${FUTURE_DAYS} 150
2327

2428

2529
*** Test Cases ***
30+
Manual Rotation Of Etcd Signer Certs
31+
[Documentation] Verify that deleting etcd signer certificates and restarting
32+
... MicroShift causes them to be regenerated.
33+
[Tags] etcd
34+
# Capture the original cert fingerprint before deletion
35+
${original_fp}= Get Cert Fingerprint ${ETCD_SIGNER_CA}
36+
Command Should Work bash -c 'rm -rf /var/lib/microshift/certs/etcd-signer/*'
37+
Restart MicroShift
38+
39+
VAR @{cert_files}=
40+
... ${ETCD_SIGNER_CA}
41+
... ${ETCD_PEER_CERT}
42+
... ${ETCD_SERVING_CERT}
43+
... ${ETCD_APISERVER_CLIENT_CERT}
44+
FOR ${cert_file} IN @{cert_files}
45+
Verify Remote File Exists With Sudo ${cert_file}
46+
Certificate Should Be Valid For Current Time ${cert_file}
47+
END
48+
49+
# Expiry comparison won't work: alignValidity() anchors all same-day
50+
# certs to the same notAfter (tomorrow_midnight + validity). Use
51+
# fingerprint instead — it covers key, serial, and all cert fields.
52+
${new_fp}= Get Cert Fingerprint ${ETCD_SIGNER_CA}
53+
Should Not Be Equal As Strings ${original_fp} ${new_fp}
54+
... msg=CA cert fingerprint should differ after regeneration
55+
2656
Certificate Rotation
2757
[Documentation] Performs Certificate Expiration Rotation test
2858
# Certificates expire at midnight of (tomorrow + validity). For short-lived certs,
@@ -53,7 +83,12 @@ Teardown
5383
Logout MicroShift Host
5484

5585
Restore System Date
56-
[Documentation] Reset Microshift date to current date
86+
[Documentation] Reset MicroShift date to current date.
87+
... Skips if chronyd is already active (date was never changed).
88+
${stdout} ${rc}= Execute Command
89+
... systemctl is-active chronyd
90+
... sudo=True return_rc=True
91+
IF '${stdout.strip()}' == 'active' RETURN
5792
${ushift_pid}= MicroShift Process ID
5893
Systemctl start chronyd
5994
Wait Until MicroShift Process ID Changes ${ushift_pid}
@@ -79,7 +114,7 @@ Compute Date After Days
79114
RETURN ${future_date}
80115

81116
Certs Should Expire On
82-
[Documentation] verify if the ceritifate expires at given date.
117+
[Documentation] verify if the certificate expires at given date.
83118
[Arguments] ${cert_file} ${cert_expected_date}
84119
${expiration_date}= Command Should Work
85120
... ${OSSL_CMD} ${cert_file} | grep notAfter | cut -f2 -d'=' | awk '{printf ("%s %02d %d",$1,$2,$4)}'
@@ -109,6 +144,17 @@ Certificate Should Be Valid For Current Time
109144

110145
${cert_not_before}= Command Should Work
111146
... ${OSSL_CMD} ${cert_file} | grep notBefore | cut -f2 -d'=' | xargs -I {} date -d "{}" +%s
147+
${cert_not_after}= Command Should Work
148+
... ${OSSL_CMD} ${cert_file} | grep notAfter | cut -f2 -d'=' | xargs -I {} date -d "{}" +%s
112149
${current_time}= Command Should Work date +%s
113150
Should Be True ${cert_not_before} <= ${current_time}
114151
... msg=Certificate NotBefore (${cert_not_before}) is after current time (${current_time})
152+
Should Be True ${current_time} <= ${cert_not_after}
153+
... msg=Certificate NotAfter (${cert_not_after}) is before current time (${current_time})
154+
155+
Get Cert Fingerprint
156+
[Documentation] Return the SHA256 fingerprint of a certificate
157+
[Arguments] ${cert_file}
158+
${fingerprint}= Command Should Work
159+
... openssl x509 -noout -fingerprint -sha256 -in ${cert_file}
160+
RETURN ${fingerprint}

0 commit comments

Comments
 (0)