1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
|
summary: Check that auto-refresh with gate-auto-refresh hooks works.
details: |
Test auto-refresh with gate-auto-refresh hook support enabled
(experimental.gate-auto-refresh-hook feature) and verify the hook can control
automatic refreshes. The test uses two test snaps, one of them
being a content provider of the other. There are a few versions of these
snaps in the store (in stable/beta/edge channels) for this test.
environment:
SNAP_NAME: test-snapd-refresh-control
CONTENT_SNAP_NAME: test-snapd-refresh-control-provider
CONTROL_FILE: /var/snap/test-snapd-refresh-control/common/control
DEBUG_LOG_FILE: /var/snap/test-snapd-refresh-control/common/debug.log
prepare: |
snap set system experimental.gate-auto-refresh-hook=true
debug: |
gojq -r '.data["snaps-hold"]' < /var/lib/snapd/state.json || true
snap changes || true
snap refresh --time || true
execute: |
LAST_REFRESH_CHANGE_ID=1
echo "Install test snaps"
snap install "$SNAP_NAME"
snap install "$CONTENT_SNAP_NAME"
echo "Connecting the two test snaps with content interface"
snap connect "$SNAP_NAME:content" "$CONTENT_SNAP_NAME:content"
# precondition check
snap list | MATCH "$SNAP_NAME +1\.0\.0"
snap list | MATCH "$CONTENT_SNAP_NAME +1\.0\.0"
snap set core refresh.schedule="0:00-23:59"
# ensure there are no refresh holds, otherwise can't force auto-refresh
snap set system refresh.hold!
# scenario #1
"$TESTSTOOLS"/snapd-state change-snap-channel "$CONTENT_SNAP_NAME" beta
# force auto-refresh a few times, we expect the gate-auto-refresh
# hook of test-snapd-refresh-control to be executed because of the refresh
# of content provider snap. The refresh is expected to be held every time.
for _ in $(seq 1 3); do
systemctl stop snapd.{service,socket}
# Request the snap to hold the refresh (itself and its content provider).
# Writing into this file affects the command performed by the gate-auto-refresh hook
# in tests/lib/snaps/store/test-snapd-refresh-control.v*/meta/hooks/gate-auto-refresh.
echo "--hold" > "$CONTROL_FILE"
echo "Trigger auto-refresh of test-snapd-refresh-control-provider but hold it via test-snapd-refresh-control's hook"
"$TESTSTOOLS"/snapd-state force-autorefresh
systemctl reset-failed snapd.{service,socket}
systemctl start snapd.{service,socket}
LAST_REFRESH_CHANGE_ID=$("$TESTSTOOLS"/snapd-state wait-for-snap-autorefresh "$CONTENT_SNAP_NAME" "$LAST_REFRESH_CHANGE_ID")
snap change --last=auto-refresh | MATCH "Run auto-refresh for ready snaps"
snap change --last=auto-refresh | MATCH "Run hook gate-auto-refresh of snap \"$SNAP_NAME\""
echo "Check that the --pending information indicates restart due to the content slot"
MATCH "restart: +true" < "$DEBUG_LOG_FILE"
MATCH "base: +false" < "$DEBUG_LOG_FILE"
MATCH "channel: +latest/stable" < "$DEBUG_LOG_FILE"
# test-snapd-refresh-control doesn't have update, so pending/version are not
# available.
MATCH "pending: none" < "$DEBUG_LOG_FILE"
NOMATCH "version:" < "$DEBUG_LOG_FILE"
echo "Check that --hold output contains remaining hold time"
# we cannot match precisely, this might be 48h0m0s if we are lucky, or
# a tiny bit less depending on timing.
MATCH "hold: 4[78]h.*m.*s" < "$DEBUG_LOG_FILE"
echo "Ensure our content snap was held and is still at version 1"
snap list | MATCH "$CONTENT_SNAP_NAME +1\.0\.0"
# precondition check for the gating snap.
snap list | MATCH "$SNAP_NAME +1\.0\.0"
done
systemctl stop snapd.{service,socket}
# scenario #2
# force auto-refresh again but this time we expect content provider snap to be
# refreshed because the gating hook of test-snapd-refresh-control calls --proceed.
echo "Trigger auto-refresh of test-snapd-refresh-control-provider but unblock it via test-snapd-refresh-control's hook"
echo "--proceed" > "$CONTROL_FILE"
"$TESTSTOOLS"/snapd-state force-autorefresh
systemctl reset-failed snapd.{service,socket}
systemctl start snapd.{service,socket}
LAST_REFRESH_CHANGE_ID=$("$TESTSTOOLS"/snapd-state wait-for-snap-autorefresh "$CONTENT_SNAP_NAME" "$LAST_REFRESH_CHANGE_ID")
snap change --last=auto-refresh | MATCH "Run auto-refresh for ready snaps"
snap change --last=auto-refresh | MATCH "Run hook gate-auto-refresh of snap \"$SNAP_NAME\""
echo "Check that the --pending information indicates test-snapd-refresh-control is affected by the content snap"
MATCH "restart: +true" < "$DEBUG_LOG_FILE"
echo "Ensure our content snap was refreshed"
snap list | MATCH "$CONTENT_SNAP_NAME +2\.0\.0"
# precondition check for the gating snap.
snap list | MATCH "$SNAP_NAME +1\.0\.0"
systemctl stop snapd.{service,socket}
# scenario #3
# test the scenario where the test-snapd-refresh-control refresh is attempted
# and it holds itself.
echo "Trigger auto-refresh of test-snapd-refresh-control and hold it from its hook"
echo "--hold" > "$CONTROL_FILE"
"$TESTSTOOLS"/snapd-state change-snap-channel "$SNAP_NAME" beta
"$TESTSTOOLS"/snapd-state force-autorefresh
systemctl reset-failed snapd.{service,socket}
systemctl start snapd.{service,socket}
LAST_REFRESH_CHANGE_ID=$("$TESTSTOOLS"/snapd-state wait-for-snap-autorefresh "$SNAP_NAME" "$LAST_REFRESH_CHANGE_ID")
echo "Check that the --pending information contains test-snapd-refresh-control refresh info"
MATCH "pending: +ready" < "$DEBUG_LOG_FILE"
MATCH "channel: +beta" < "$DEBUG_LOG_FILE"
MATCH "version: +2\.0" < "$DEBUG_LOG_FILE"
MATCH "base: +false" < "$DEBUG_LOG_FILE"
MATCH "restart: +false" < "$DEBUG_LOG_FILE"
echo "Ensure our snap was held"
snap list | MATCH "$SNAP_NAME +1\.0\.0"
systemctl stop snapd.{service,socket}
# scenario #4
# test the scenario where the test-snapd-refresh-control refresh proceeds.
echo "Trigger auto-refresh of test-snapd-refresh-control and proceed from its hook"
echo "--proceed" > "$CONTROL_FILE"
"$TESTSTOOLS"/snapd-state force-autorefresh
systemctl reset-failed snapd.{service,socket}
systemctl start snapd.{service,socket}
LAST_REFRESH_CHANGE_ID=$("$TESTSTOOLS"/snapd-state wait-for-snap-autorefresh "$SNAP_NAME" "$LAST_REFRESH_CHANGE_ID")
echo "Ensure our snap was updated"
snap list | MATCH "$SNAP_NAME +2\.0\.0"
systemctl stop snapd.{service,socket}
# scenario #5
echo "Checking that error from the hook means hold"
echo "--unknown-flag-to-force-snapctl-error" > "$CONTROL_FILE"
"$TESTSTOOLS"/snapd-state change-snap-channel "$CONTENT_SNAP_NAME" edge
"$TESTSTOOLS"/snapd-state force-autorefresh
systemctl reset-failed snapd.{service,socket}
systemctl start snapd.{service,socket}
LAST_REFRESH_CHANGE_ID=$("$TESTSTOOLS"/snapd-state wait-for-snap-autorefresh "$CONTENT_SNAP_NAME" "$LAST_REFRESH_CHANGE_ID")
echo "Ensure our content snap was held"
snap list | MATCH "$CONTENT_SNAP_NAME +2\.0\.0"
snap change --last=auto-refresh | MATCH "ERROR ignoring hook error:"
MATCH "error: snapctl: unknown flag .unknown-flag-to-force-snapctl-error'" < "$DEBUG_LOG_FILE"
systemctl stop snapd.{service,socket}
# scenario #6
echo "Checking that if the hook does nothing (neither --proceed nor --hold), the refresh proceeds"
rm -f "$CONTROL_FILE"
"$TESTSTOOLS"/snapd-state change-snap-channel "$CONTENT_SNAP_NAME" edge
"$TESTSTOOLS"/snapd-state force-autorefresh
systemctl reset-failed snapd.{service,socket}
systemctl start snapd.{service,socket}
LAST_REFRESH_CHANGE_ID=$("$TESTSTOOLS"/snapd-state wait-for-snap-autorefresh "$CONTENT_SNAP_NAME" "$LAST_REFRESH_CHANGE_ID")
echo "Ensure our content snap was updated"
snap list | MATCH "$CONTENT_SNAP_NAME +3\.0\.0"
|