auto-update tests: various fixes

Followup to #9740. Nice work, but the _confirm_update() helper
was dangerously broken and I just wasn't able to communicate
that. Given the time zone difference, and my weekly time cost
in reviewing, it's easier for me to fix it myself. (The problem
is that the function was a complete NOP, which would lead to
flakes).

Also: got rid of some clutter, restructured a few minor places
for maintainability.

Signed-off-by: Ed Santiago <santiago@redhat.com>
This commit is contained in:
Ed Santiago
2021-06-07 13:51:59 -06:00
parent 763abaea36
commit 5e7876089f

View File

@ -43,12 +43,12 @@ function teardown() {
# 5. Remove the origin container # 5. Remove the origin container
# 6. Start the container from service # 6. Start the container from service
function generate_service() { function generate_service() {
target_img_basename=$1 local target_img_basename=$1
autoupdate=$2 local autoupdate=$2
# Please keep variable name for cname and ori_image. The # Container name. Include the autoupdate type, to make debugging easier.
# scripts will use them directly in following tests. # IMPORTANT: variable 'cname' is passed (out of scope) up to caller!
cname=c_$(random_string) cname=c_${autoupdate//\'/}_$(random_string)
target_img="quay.io/libpod/$target_img_basename:latest" target_img="quay.io/libpod/$target_img_basename:latest"
run_podman tag $IMAGE $target_img run_podman tag $IMAGE $target_img
if [[ -n "$autoupdate" ]]; then if [[ -n "$autoupdate" ]]; then
@ -67,6 +67,8 @@ function generate_service() {
systemctl start container-$cname systemctl start container-$cname
systemctl status container-$cname systemctl status container-$cname
# Original image ID.
# IMPORTANT: variable 'ori_image' is passed (out of scope) up to caller!
run_podman inspect --format "{{.Image}}" $cname run_podman inspect --format "{{.Image}}" $cname
ori_image=$output ori_image=$output
} }
@ -76,8 +78,7 @@ function _wait_service_ready() {
local timeout=6 local timeout=6
while [[ $timeout -gt 1 ]]; do while [[ $timeout -gt 1 ]]; do
run systemctl is-active $sname if systemctl -q is-active $sname; then
if [[ $output == "active" ]]; then
return return
fi fi
sleep 1 sleep 1
@ -89,65 +90,63 @@ function _wait_service_ready() {
die "Timed out waiting for $sname to start" die "Timed out waiting for $sname to start"
} }
# Wait for container to update, as confirmed by its image ID changing
function _confirm_update() { function _confirm_update() {
local sname=$1 local cname=$1
local old_iid=$2
local timeout=6 # Image has already been pulled, so this shouldn't take too long
last_log="" local timeout=5
while [[ $timeout -gt 1 ]]; do while [[ $timeout -gt 0 ]]; do
run journalctl -u $sname -n 10 run_podman '?' inspect --format "{{.Image}}" $cname
if [[ "$output" == "$last_log" ]]; then if [[ $status != 0 ]]; then
if [[ $output =~ (no such object|does not exist in database): ]]; then
# this is ok, it just means the container is being restarted
:
else
die "podman inspect $cname failed unexpectedly"
fi
elif [[ $output != $old_iid ]]; then
return return
fi fi
last_log=$output
sleep 1 sleep 1
let timeout=$timeout-1
done done
die "Timed out waiting for $sname to update" die "Timed out waiting for $cname to update; old IID=$old_iid"
} }
# This test can fail in dev. environment because of SELinux. # This test can fail in dev. environment because of SELinux.
# quick fix: chcon -t container_runtime_exec_t ./bin/podman # quick fix: chcon -t container_runtime_exec_t ./bin/podman
@test "podman auto-update - label io.containers.autoupdate=image" { @test "podman auto-update - label io.containers.autoupdate=image" {
run_podman images
generate_service alpine image generate_service alpine image
_wait_service_ready container-$cname.service _wait_service_ready container-$cname.service
run_podman ps -a
run_podman auto-update run_podman auto-update
is "$output" "Trying to pull.*" "Image is updated." is "$output" "Trying to pull.*" "Image is updated."
run_podman ps -a _confirm_update $cname $ori_image
_confirm_update container-$cname.service
run_podman inspect --format "{{.Image}}" $cname
[[ "$output" != "$ori_image" ]]
} }
@test "podman auto-update - label io.containers.autoupdate=disabled" { @test "podman auto-update - label io.containers.autoupdate=disabled" {
generate_service alpine disabled generate_service alpine disabled
_wait_service_ready container-$cname.service _wait_service_ready container-$cname.service
run_podman ps -a
run_podman auto-update run_podman auto-update
is "$output" "" "Image is not updated with disabled." is "$output" "" "Image is not updated when autoupdate=disabled."
run_podman ps -a
_confirm_update container-$cname.service
run_podman inspect --format "{{.Image}}" $cname run_podman inspect --format "{{.Image}}" $cname
is "$output" "$ori_image" "Image hash should not changed." is "$output" "$ori_image" "Image ID should not change"
} }
@test "podman auto-update - label io.containers.autoupdate=fakevalue" { @test "podman auto-update - label io.containers.autoupdate=fakevalue" {
fakevalue=$(random_string) fakevalue=fake_$(random_string)
generate_service alpine $fakevalue generate_service alpine $fakevalue
_wait_service_ready container-$cname.service _wait_service_ready container-$cname.service
run_podman ps -a run_podman 125 auto-update
run_podman ? auto-update
is "$output" ".*invalid auto-update policy.*" "invalid policy setup" is "$output" ".*invalid auto-update policy.*" "invalid policy setup"
run_podman ps -a
_confirm_update container-$cname.service
run_podman inspect --format "{{.Image}}" $cname run_podman inspect --format "{{.Image}}" $cname
is "$output" "$ori_image" "Image hash should not changed." is "$output" "$ori_image" "Image ID should not change"
} }
@test "podman auto-update - label io.containers.autoupdate=local" { @test "podman auto-update - label io.containers.autoupdate=local" {
@ -155,25 +154,23 @@ function _confirm_update() {
podman commit --change CMD=/bin/bash $cname quay.io/libpod/localtest:latest podman commit --change CMD=/bin/bash $cname quay.io/libpod/localtest:latest
_wait_service_ready container-$cname.service _wait_service_ready container-$cname.service
run_podman ps -a
run_podman auto-update run_podman auto-update
run_podman ps -a _confirm_update $cname $ori_image
_confirm_update container-$cname.service
run_podman inspect --format "{{.Image}}" $cname
[[ "$output" != "$ori_image" ]]
} }
@test "podman auto-update with multiple services" { @test "podman auto-update with multiple services" {
fakevalue=$(random_string) # Preserve original image ID, to confirm that it changes (or not)
run_podman inspect --format "{{.Id}}" $IMAGE run_podman inspect --format "{{.Id}}" $IMAGE
img_id="$output" local img_id="$output"
cnames=()
local cnames=()
local -A expect_update local -A expect_update
local -A will_update=([image]=1 [registry]=1 [local]=1) local -A will_update=([image]=1 [registry]=1 [local]=1)
local fakevalue=fake_$(random_string)
for auto_update in image registry "" disabled "''" $fakevalue local for auto_update in image registry "" disabled "''" $fakevalue local
do do
img_base="alpine" local img_base="alpine"
if [[ $auto_update == "registry" ]]; then if [[ $auto_update == "registry" ]]; then
img_base="alpine_nginx" img_base="alpine_nginx"
elif [[ $auto_update == "local" ]]; then elif [[ $auto_update == "local" ]]; then
@ -184,6 +181,7 @@ function _confirm_update() {
if [[ $auto_update == "local" ]]; then if [[ $auto_update == "local" ]]; then
local_cname=$cname local_cname=$cname
fi fi
if [[ -n "$auto_update" && -n "${will_update[$auto_update]}" ]]; then if [[ -n "$auto_update" && -n "${will_update[$auto_update]}" ]]; then
expect_update[$cname]=1 expect_update[$cname]=1
fi fi
@ -192,30 +190,28 @@ function _confirm_update() {
# Only check the last service is started. Previous services should already actived. # Only check the last service is started. Previous services should already actived.
_wait_service_ready container-$cname.service _wait_service_ready container-$cname.service
run_podman commit --change CMD=/bin/bash $local_cname quay.io/libpod/localtest:latest run_podman commit --change CMD=/bin/bash $local_cname quay.io/libpod/localtest:latest
run_podman ? auto-update # Exit code is expected, due to invalid 'fakevalue'
run_podman 125 auto-update
update_log=$output update_log=$output
for cname in "${cnames[@]}"; do
_confirm_update container-$cname.service
done
count=0
while read line; do
if [[ "$line" =~ "Trying to pull" ]]; then
((count+=1))
fi
done <<< "$update_log"
is "$update_log" ".*invalid auto-update policy.*" "invalid policy setup" is "$update_log" ".*invalid auto-update policy.*" "invalid policy setup"
is "$update_log" ".*1 error occurred.*" "invalid policy setup" is "$update_log" ".*1 error occurred.*" "invalid policy setup"
is "$count" "2" "There are two images being updated from registry."
local n_updated=$(grep -c 'Trying to pull' <<<"$update_log")
is "$n_updated" "2" "Number of images updated from registry."
for cname in "${!expect_update[@]}"; do for cname in "${!expect_update[@]}"; do
is "$update_log" ".*$cname.*" "container with auto-update policy image updated" is "$update_log" ".*$cname.*" "container with auto-update policy image updated"
# Just because podman says it fetched, doesn't mean it actually updated
_confirm_update $cname $img_id
done done
# Final confirmation that all image IDs have/haven't changed
for cname in "${cnames[@]}"; do for cname in "${cnames[@]}"; do
run_podman inspect --format "{{.Image}}" $cname run_podman inspect --format "{{.Image}}" $cname
if [[ -n "${expect_update[$cname]}" ]]; then if [[ -n "${expect_update[$cname]}" ]]; then
[[ "$output" != "$img_id" ]] if [[ "$output" == "$img_id" ]]; then
die "$cname: image ID ($output) did not change"
fi
else else
is "$output" "$img_id" "Image should not be changed." is "$output" "$img_id" "Image should not be changed."
fi fi
@ -255,25 +251,24 @@ EOF
systemctl enable --now podman-auto-update-$cname.timer systemctl enable --now podman-auto-update-$cname.timer
systemctl list-timers --all systemctl list-timers --all
count=0 local expect='Finished Podman auto-update testing service'
failed_start=1 local failed_start=failed
local count=0
while [ $count -lt 120 ]; do while [ $count -lt 120 ]; do
run journalctl -n 15 -u podman-auto-update-$cname.service run journalctl -n 15 -u podman-auto-update-$cname.service
if [[ "$output" =~ "Finished Podman auto-update testing service" ]]; then if [[ "$output" =~ $expect ]]; then
failed_start=0 failed_start=
break break
fi fi
((count+=1)) ((count+=1))
sleep 1 sleep 1
done done
echo $output
_confirm_update container-$cname.service if [[ -n "$failed_start" ]]; then
run_podman inspect --format "{{.Image}}" $cname die "Did not find expected string '$expect' in journalctl output for $cname"
if [[ $failed_start == 1 ]]; then
die "Failed to get podman auto-update service finished"
fi fi
[[ "$output" != "$ori_image" ]]
_confirm_update $cname $ori_image
} }
# vim: filetype=sh # vim: filetype=sh