mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-10-27 11:52:51 +08:00
21 KiB
21 KiB
Manual UI Testing Plan
- xx
0. Authentication
- 0.1 Navigate to
http://<router>/cgi-bin/luci→ Redirected to login page - 0.2 Submit correct credentials → Redirected to LuCI dashboard
- 0.3 Navigate to
/admin/podman→ Overview page loads without re-auth - 0.4 Open browser Console tab → No JS errors
1. Overview (/admin/podman)
- 1.1 Load overview → Page loads; all counters visible (0 is fine)
- 1.2 Podman version string visible → Not empty, not "undefined"
- 1.3 System status indicator visible → Shows running (socket available)
- 1.4 Note all current counts → Baseline for comparison after later steps
1a. Auto-update modal - live progress
Prereq: at least one container with label io.containers.autoupdate=registry.
- 1.5 Click "Check for Updates" → Spinner per container → "Apply Updates" modal lists candidates
- 1.6 Tick a container with an actually-newer image upstream → Click Update → Modal switches to log view with
Update image: 1/N - <name>header, spinner running, Close button disabled - 1.7 Log shows
Pulling <ref>, then liveTrying to pull...,Copying blob ...lines - progress lines with CR overwrite the previous line (no flood of "Copying blob X 50%, 51%, 52%, ...") - 1.8 After pull, log shows stage markers:
→ Stopping container,→ Removing container,→ Creating container,→ Starting container,→ Reinstating init script,✓ Updated to <id-short> - 1.9 Multi-container update: each container delimited by
━━ <name> ━━; previous container's log remains visible above current one - 1.10 After loop ends, counter shows
Done., spinner stops, Close button enabled - 1.11 Click Close → modal dismisses → summary alert appears (
Containers updated successfullyfor full success, list of failures otherwise) - 1.12 Pull failure (rename the container's image to a non-existent registry before running, or change tag to bogus): log shows
✗ <error>, run continues to next container, summary marks failed - 1.13 Mid-flight failure (SSH
podman run -d --name <same-name> alpine sleep 3600between Stop and Create, or simulate by other means): log shows✗ Create failed: ...for that container, summary marks failed - 1.14 Old-image cleanup: after successful update of one container, log shows
━━ Cleaning up old images... ━━then either✓ Removed old image <id>or! Old image <name> could not be removed - still in use by another container - 1.15 Modal scroll: when log overflows visible area, content auto-scrolls to bottom on append; scroll up manually → new lines append at bottom but viewport stays where the user put it (sticky-scroll)
- 1.16 Long pull crossing uhttpd
script_timeout(~55s): server-side connection rotates transparently (auto-reconnect inModel._stream); log keeps growing, no spurious error
2. Images (/admin/podman/images)
- 2.1 Load images list → Page loads (may be empty)
- 2.2 Click "Pull Image" → Form/modal appears with name input
- 2.3 Submit empty form → Validation error, no request sent
- 2.4 Pull nonexistent image (e.g.
this-does-not-exist:fake) → Error notification shown, list unchanged - 2.5 Pull
alpine:latest→ Progress indicator → success notification →alpineappears in list - 2.6 Pull
alpine:latestagain (already exists) → Graceful result (no crash, may show "already up to date") - 2.7 Click inspect on
alpine→ Modal opens with JSON image data - 2.8 Return to overview → Image count incremented by 1
3. Containers (/admin/podman/containers)
Requires alpine:latest from step 2.5.
3a. Create
- 3.1 Load containers list → Page loads (may be empty)
- 3.2 Click "Create Container" → Form modal opens
- 3.3 Submit empty form → Validation errors on required fields
- 3.4 Fill name:
test-alpine, image:alpine:latest, no other changes → Submit → Container created;test-alpinevisible in list - 3.5 Return to overview → Container count incremented
3b. List operations
- 3.6 Verify
test-alpinerow shows correct Name, Image, State - 3.7 Select
test-alpinecheckbox → Only that row selected - 3.8 Click top "select all" checkbox → All rows selected
- 3.9 Click top checkbox again → All deselected
3c. Start / Stop / Restart
- 3.10 If container is stopped: select → Start → State changes to
Running; success notification - 3.11 Select running container → Stop → State changes to
Exited; success notification - 3.12 Select stopped container → Restart → State changes to
Running
3d. Detail view - Info tab
- 3.13 Click
test-alpinename link → Navigates to container detail page - 3.14 Name, image, state displayed → Matches list view
- 3.15 Edit container name to
test-alpine-renamed→ Save → Name updated; notification shown - 3.16 Change restart policy to
always→ Save → Policy updated; success notification - 3.17 Init script auto-generated → Auto-start indicator shows enabled
- 3.18 Click "Show Init Script" → Modal with script content; script references
test-alpine-renamed - 3.19 Toggle init script disabled → Indicator changes
- 3.20 Toggle init script enabled again → Indicator reverts
- 3.21 Change restart policy to
no→ Save → Init script removed/disabled - 3.22 Navigate back to list → Name shown as
test-alpine-renamed
3e. Detail view - Resources tab
- 3.23 Click Resources tab → Tab activates; current limits shown
- 3.24 Set CPU limit to
0.5→ Save → After page reload, Resources tab is active (tab persistence) - 3.25 Set Memory limit to
64m→ Save → Value persisted - 3.26 Enter invalid CPU value (e.g.
abc) → Save → Validation error; no save
3f. Detail view - Stats tab
- 3.27 Start container (if stopped)
- 3.28 Click Stats tab → CPU%, Memory, Net I/O data appears
- 3.29 Stop container; click Stats tab → Graceful empty/zero state, no JS crash
3g. Detail view - Logs tab
- 3.30 Click Logs tab → Log output area visible (may be empty for alpine)
- 3.31 Change line count to
50→ Apply → Fetches last 50 lines - 3.32 Enable live streaming toggle → Toggle activates
- 3.33 Disable live streaming → Streaming stops, toggle off
- 3.34 Click Clear → Log area clears
3h. Detail view - Processes tab
- 3.35 Start container; click Processes tab → Process table appears
- 3.36 Stop container; click Processes tab → Graceful empty/error state, no JS crash
3i. Network management (on detail page)
- 3.37 Note current networks attached → Baseline
- 3.38 Disconnect default network → Network removed from list
- 3.39 Reconnect the network → Network added back
- 3.40 Connect a network with valid static IP → Network added with IP shown
- 3.41 Connect a network with invalid IP → Validation error
3j. Pause / Unpause
- 3.42 List view: select a running container → click ⏸⏸ Pause → state changes to
paused; success notification - 3.43 List view: same paused container selected → click ▶ Start → state changes back to
running(Start polymorphically unpauses paused containers) - 3.44 Detail view: container is running → ▶ Start is highlighted as active, ⏸⏸ Pause is clickable
- 3.45 Detail view: click Pause → reload → state is
paused, ⏸⏸ Pause is now highlighted, ▶ Start is clickable - 3.46 Detail view: click Start while paused → reload → state is
running, ▶ Start highlighted again - 3.47 Detail view: streams (stats / logs / processes) stop before pause fires (no reconnect storm in DevTools Network panel)
- 3.48 Multi-select on list: mix of running + paused → click ▶ Start → running stays running, paused becomes running (per-container dispatch)
4. Volumes (/admin/podman/volumes)
- 4.1 Load volumes list → Page loads (may be empty)
- 4.2 Click "Create Volume" → Form appears
- 4.3 Submit empty form → Name will be generated
- 4.4 Create volume named
test-vol→ Appears in list with name, driver, created date - 4.5 Click inspect on
test-vol→ JSON modal shows volume data - 4.6 Return to overview → Volume count incremented
- 4.7 Select
test-vol→ Delete → Confirmation modal → confirm → removed from list - 4.8 Create volume
test-vol-pruneand leave it → Used in prune test (step 8.2)
5. Networks (/admin/podman/networks)
- 5.1 Load networks list → Default
podmannetwork visible - 5.2 Note OpenWrt column for default network → Status icon shown
- 5.3 Click "Create Network" → Form opens
- 5.4 Submit empty form → Validation error
- 5.5 Create
test_net, subnet10.220.0.0/24, gateway10.220.0.1, OpenWrt integration checked → Network created; OpenWrt column shows✓ - 5.6 Verify UCI config created → SSH:
uci show network.test_netreturns values - 5.7 Create
test_net_bwith no subnet, integration unchecked → Network created; OpenWrt column shows- - 5.8 If any network shows
X(incomplete integration): click it → setup → icon changes to✓ - 5.9 Return to overview → Network count incremented
- 5.10 Select
test_net→ Delete → Confirmation mentions OpenWrt cleanup → confirm → network removed; UCI config removed - 5.11 Select
test_net_bare→ Delete → Removed cleanly (no UCI to clean up)
6. Secrets (/admin/podman/secrets)
- 6.1 Load secrets list → Page loads (may be empty)
- 6.2 Click "Create Secret" → Form with name + value fields
- 6.3 Submit empty form → Validation error
- 6.4 Create secret name
test-secret, valuehunter2→ Appears in list; value NOT shown anywhere - 6.5 Click inspect on
test-secret→ Modal shows metadata;SecretDatafield hidden - 6.6 Delete
test-secret→ Removed from list
7. Pods (/admin/podman/pods)
Requires alpine:latest from step 2.5. If a user-defined network exists from section 5, note its name as <usernet>.
7a. List view
- 7.1 Load pods list → Page loads with empty/populated table; no "Work in progress…" stub
- 7.2 Toolbar visible → Create / Delete / Reload / ▶ / ■ / ⟳ / ⏸ / ⏵ buttons present
- 7.3 Click Reload with empty list → No error, indicator appears briefly
7b. Create - minimal
- 7.4 Click "Create" → Pod form modal opens with default fields populated
- 7.5 Submit empty form → No validation error (name auto-generates); pod appears with generated name
- 7.6 Create pod name
pod-min, all other defaults → Modal closes, success notification,pod-minrow appears - 7.7 Verify SSH
podman pod inspect pod-min→ Pod exists with one infra container - 7.8 Containers column shows
1 ▸forpod-min
7c. Create - full options
- 7.9 Open Create form → Name
pod-full, Hostnamepod-full-host, Shared Namespacescgroup,ipc,net,uts, Infra ON, Network<usernet>, DNS Servers1.1.1.1and9.9.9.9, DNS Searchlan, CPU Limit1.0, CPU Set0-1, Memory256m, Labelsapp=demo\nenv=test→ Submit - 7.10 SSH
podman pod inspect pod-full | jq '.Hostname'→pod-full-host - 7.11 SSH
podman pod inspect pod-full | jq '.InfraConfig.NetworkOptions'→ contains DNS server + search entries - 7.12 SSH
podman pod inspect pod-full | jq '.Labels'→app: demo,env: test - 7.13 Networks column for
pod-full→ shows<usernet>
7d. Status badges
- 7.14 New pod → Status badge
Created(gray) - 7.15 After Start → Badge
Running(green) - 7.16 After Pause → Badge
Paused(orange) - 7.17 After Stop → Badge
ExitedorStopped(red)
7e. Lifecycle - single select
- 7.18 Tick
pod-min, click ▶ Start → Loading "Starting pod: 1/1", refresh showsRunning - 7.19 Click ■ Stop → Status
Exited/Stopped - 7.20 Click ⟳ Restart → Status
Running - 7.21 Click ⏸ Pause → Status
Paused - 7.22 Click ⏵ Unpause → Status
Running
7f. Lifecycle - multi-select
- 7.23 Create
pod-aandpod-b(defaults), select both → ▶ Start - 7.24 Loading modal shows "Starting pod: 1/2" then "2/2"
- 7.25 Both pods end up
Running - 7.26 No JS console errors during multi-action
7g. Detail page navigation (from list)
- 7.27 Click pod Name in list → Navigates to
/admin/podman/pod/<id>(no more inspect modal) - 7.28 Browser back button → Returns to pods list with state preserved
7h. Containers expand modal
- 7.29 SSH
podman run -d --pod pod-min --name pod-min-c1 alpine sleep 3600→ container created in pod - 7.30 Reload pods list →
pod-minContainers column shows2 ▸ - 7.31 Click
2 ▸link → Modal "Containers in pod pod-min" opens with 2 rows (infra + new) - 7.32 Each row shows Name, truncated ID, Status badge, Restarts count
- 7.33 Click container ID link in modal → Navigates to
/admin/podman/container/<id>detail view
7i. Pod removal
- 7.34 Stop
pod-minfirst → StatusExited - 7.35 Tick
pod-min→ Delete → Confirm - 7.36 SSH
podman pod ls→pod-mingone - 7.37 SSH
podman ps -a→pod-min-c1also gone (cascade delete via force)
7j. Container form integration
- 7.38 Navigate Podman → Containers → Create → Form shows new Pod ListValue (after Image) with "(none)" + existing pod names
- 7.39 Select Pod =
pod-full→ Network, Hostname, Port Mappings, Expose Ports fields hide - 7.40 Select Pod = "(none)" → Hidden fields reappear
- 7.41 Create container with Pod
pod-full, Imagealpine:latest, Commandsleep 3600, Start ON → Success - 7.42 SSH
podman ps --filter pod=pod-full→ New container listed - 7.43 Pods list
pod-fullContainers column → count incremented
7k. Edge cases
- 7.44 Create pod with name
Bad Name!→ Validation error (uciname constraint) - 7.45 Toggle "Create Infra Container" OFF → Network/DNS/Infra Image fields hide
- 7.46 Submit pod with Infra OFF → Pod created without infra container; SSH
podman pod inspectconfirms - 7.47 Try Stop on already-stopped pod → No JS error (graceful handling of API 304/409)
- 7.48 Try Pause on stopped pod → Error notification, no JS crash
7l. Regression - non-pod container create
- 7.49 Create container with Pod = "(none)", port mapping
8080:80, network<usernet>, hostnamefreebee→ Success - 7.50 SSH inspect → port mapping, network and hostname present (confirms
if (!data.pod)guards don't break the non-pod path)
7m. Cleanup
- 7.51 SSH
podman pod rm -f pod-full pod-a pod-b→ All test pods removed - 7.52 SSH
podman ps -a→ No leftover test containers - 7.53 Reload pods list → Empty/clean state
7n. Detail page - load & header (/admin/podman/pod/<id>)
- 7.54 Direct URL
/admin/podman/pod/<podId>→ Detail page loads, no console errors - 7.55 Header shows pod name and back-arrow button → back button returns to pods list
- 7.56 Lifecycle buttons visible: ▶ Start, ■ Stop, ⟳ Restart, ⏸ Pause, ⏵ Unpause, 🗑 Delete
- 7.57 "Active" highlight reflects current state: Running pod → ▶ highlighted, Paused pod → ⏸ highlighted, Exited pod → ■ highlighted (semantic: button describes current state, not "available action")
- 7.58 Tabs visible: Info, Stats, Processes, Inspect
7o. Detail page - Info tab
- 7.59 Basic Information section: Name, ID (full 64-char), Status badge, Created date populated
- 7.60 Configuration section: Hostname, Cgroup parent, Exit policy, Restart policy, Shared namespaces (comma-joined), Infra container (clickable link to
/admin/podman/container/<infraId>) - 7.61 Resources section: CPU period (µs), CPU quota (µs or "Unlimited"), CPU shares, CPU set, Memory limit (formatted bytes or "Unlimited"). Description note "Resources are set at pod creation and cannot be edited here." present
- 7.62 Network section: Networks, Static IPv4, Static MAC, DNS servers, DNS search, DNS options, Extra hosts, Host network (Yes/No)
- 7.63 Containers section: table with Name, truncated ID (clickable → container detail), Status badge - one row per container including infra
- 7.64 Labels section: only rendered if pod has labels; otherwise omitted
- 7.65 All empty fields show
-placeholder
7p. Detail page - Stats tab (pod running)
- 7.66 Switch to Stats tab → Table with headers: Container, CID, CPU %, Memory, Memory %, Net I/O, Block I/O, PIDs
- 7.67 Rows update live (humanized strings from
PodStatsReport: e.g. "75.5%", "12mb / 24mb") - 7.68 Container name column resolves from pod's containers map (not the pod-name value the API returns)
- 7.69 Switch to another tab → Stream stops (verify in DevTools Network: stream connection closes)
- 7.70 Switch back to Stats → Stream restarts
- 7.71 Pod is stopped → Stats tab shows "Pod is not running" warning, no stream attempt
7q. Detail page - Processes tab (pod running)
- 7.72 Switch to Processes tab → Table with columns Podman's
pod topreturns (USER, PID, ..., CMD) plus a CONTAINER column (native to pod top) - 7.73 Rows update live as processes change
- 7.74 Switch away → Stream stops
- 7.75 Pod is stopped → Shows "Pod is not running" warning
7r. Detail page - Inspect tab
- 7.76 Switch to Inspect tab → Renders full raw JSON of
podman pod inspect - 7.77 Same content as old list-view inspect modal (sanity check no fields are lost)
7s. Detail page - lifecycle actions
- 7.78 Running pod → click ⏸ Pause → confirmation/loading → reload → status
Paused, ⏸ now highlighted as active - 7.79 Paused pod → click ⏵ Unpause → reload → status
Running - 7.80 Running pod → click ■ Stop → reload → status
Exited, ■ highlighted - 7.81 Stopped pod → click ▶ Start → reload → status
Running - 7.82 Click ⟳ Restart → reload → status briefly cycles to Running
- 7.83 Click 🗑 Delete → confirm dialog → confirm → redirects to
/admin/podman/pods, pod gone - 7.84 Before Stop/Pause/Restart, verify in DevTools Network: stats/processes streams close BEFORE the action fires (no reconnect storm)
7t. Detail page - edge cases
- 7.85 Pod with no containers (rare - infra-less or just created): Containers section shows "No containers in this pod"
- 7.86 Pod with no labels: Labels section is absent (not just empty)
- 7.87 Pod with
RestartPolicyunset: Configuration shows- - 7.88 Pod with
memory_limit: 0or unset: Resources shows "Unlimited" - 7.89 Pod with
cpu_quota: -1: Resources shows "Unlimited" - 7.90 Invalid pod ID in URL → Redirects to pods list (no crash)
- 7.91 Refresh page while stats stream active → No duplicate streams (Network panel shows single connection)
8. Modals
Prune Modal
- 8.1 Open prune modal → Options shown: containers, images, volumes, networks
- 8.2 Select only "Volumes" → Prune → Only unused volumes pruned (e.g.
test-vol-prunefrom step 4.8); containers/images untouched - 8.3 Select "Containers" → Prune → Only stopped/exited containers removed
Auto-Update Modal
- 8.4 Open auto-update modal → Container list shown with current digest info
- 8.5 Click "Check for Updates" → Digest comparison runs; up-to-date containers marked
- 8.6 If outdated container detected → Update → Pulls new image, recreates container
9. Error Handling
- 9.1 Stop Podman socket (
/etc/init.d/podman stop), load any list view → Clear RPC error message; no JS crash, no blank page - 9.2 Navigate to
/admin/podman/container/nonexistent-id→ Graceful error, not a blank page - 9.3 Start Podman again (
/etc/init.d/podman start); reload → Normal operation resumes - 9.4 Trigger two operations quickly in succession → No race-condition crash or duplicate requests
10. Cleanup Verification
- 10.1 Delete any remaining test containers (e.g.
test-alpine-renamed) - 10.2 Delete
alpineimage - 10.3 Containers list → Empty (or back to pre-test state)
- 10.4 Images list → Empty (or back to pre-test state)
- 10.5 Overview counters → Match baseline from step 1.4