mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-07-09 16:00:59 +00:00
Fix demo verification and agent update recovery
Refs #1515 - restore demo runtime env and verify mock fixtures even when the target version is already installed - require recovered agent update state to include both URL and token before reporting success
This commit is contained in:
parent
6becdbf9db
commit
cd6b250ae6
7 changed files with 279 additions and 19 deletions
|
|
@ -1591,6 +1591,10 @@ apply_recovered_agent_arg_value() {
|
|||
esac
|
||||
}
|
||||
|
||||
recovered_connection_state_ready() {
|
||||
[[ -n "$PULSE_URL" && -n "$PULSE_TOKEN" ]]
|
||||
}
|
||||
|
||||
recover_connection_state_from_arg_stream() {
|
||||
local arg=""
|
||||
local pending_key=""
|
||||
|
|
@ -1688,7 +1692,7 @@ recover_connection_state_from_arg_stream() {
|
|||
esac
|
||||
done
|
||||
|
||||
[[ "$RECOVERED_AGENT_ARG_STATE" == "true" && -n "$PULSE_URL" ]]
|
||||
[[ "$RECOVERED_AGENT_ARG_STATE" == "true" ]] && recovered_connection_state_ready
|
||||
}
|
||||
|
||||
recover_connection_state_from_env_stream() {
|
||||
|
|
@ -1738,7 +1742,7 @@ recover_connection_state_from_env_stream() {
|
|||
esac
|
||||
done
|
||||
|
||||
[[ "$RECOVERED_AGENT_ENV_STATE" == "true" && -n "$PULSE_URL" ]]
|
||||
[[ "$RECOVERED_AGENT_ENV_STATE" == "true" ]] && recovered_connection_state_ready
|
||||
}
|
||||
|
||||
collect_running_agent_pids() {
|
||||
|
|
@ -1782,7 +1786,7 @@ recover_connection_state_from_running_agent() {
|
|||
recovered="true"
|
||||
fi
|
||||
fi
|
||||
if [[ "$recovered" == "true" && -n "$PULSE_URL" ]]; then
|
||||
if [[ "$recovered" == "true" ]] && recovered_connection_state_ready; then
|
||||
return 0
|
||||
fi
|
||||
done < <(collect_running_agent_pids)
|
||||
|
|
@ -1820,7 +1824,7 @@ recover_connection_state_from_systemd_unit() {
|
|||
;;
|
||||
esac
|
||||
done < "$candidate"
|
||||
if [[ "$recovered" == "true" && -n "$PULSE_URL" ]]; then
|
||||
if [[ "$recovered" == "true" ]] && recovered_connection_state_ready; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
|
|
|||
|
|
@ -807,6 +807,12 @@ func TestUpdateDemoWorkflowUsesGovernedNetworkPath(t *testing.T) {
|
|||
`-name "metrics.db"`,
|
||||
`Removing demo volatile store: %s`,
|
||||
`Demo host does not have enough free space to back up $CONFIG_DIR before install.`,
|
||||
`Restore demo runtime configuration`,
|
||||
`set_env_value DEMO_MODE true`,
|
||||
`set_env_value PULSE_MOCK_MODE true`,
|
||||
`/api/license/runtime-capabilities`,
|
||||
`Mock mode enabled`,
|
||||
`Demo server mock mode did not enable after entitlement sync`,
|
||||
`Verify public browser smoke`,
|
||||
`./scripts/run_demo_public_browser_smoke.sh`,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -645,6 +645,9 @@ func TestInstallSHSupportsSavedStateUpdateMode(t *testing.T) {
|
|||
`recover_connection_state_from_systemd_unit`,
|
||||
`recover_connection_state_from_arg_stream`,
|
||||
`recover_connection_state_from_env_stream`,
|
||||
`recovered_connection_state_ready() {`,
|
||||
`[[ "$RECOVERED_AGENT_ARG_STATE" == "true" ]] && recovered_connection_state_ready`,
|
||||
`[[ "$RECOVERED_AGENT_ENV_STATE" == "true" ]] && recovered_connection_state_ready`,
|
||||
`recover_connection_state_from_existing_agent || true`,
|
||||
`if [[ -n "$PULSE_URL" && -n "$PULSE_TOKEN" ]]; then`,
|
||||
`recover_agent_id_from_state_file() {`,
|
||||
|
|
@ -692,6 +695,7 @@ func TestInstallSHRecoversV5ProcessArgsForSavedStateUpdate(t *testing.T) {
|
|||
RUNTIME_TOKEN_FILE="/var/lib/pulse-agent/token"
|
||||
` + extractInstallShellFunction(t, "strip_recovered_arg_quotes") + `
|
||||
` + extractInstallShellFunction(t, "apply_recovered_agent_arg_value") + `
|
||||
` + extractInstallShellFunction(t, "recovered_connection_state_ready") + `
|
||||
` + extractInstallShellFunction(t, "recover_connection_state_from_arg_stream") + `
|
||||
` + extractInstallShellFunction(t, "build_exec_arg_items") + `
|
||||
` + extractInstallShellFunction(t, "join_exec_arg_items") + `
|
||||
|
|
@ -743,6 +747,144 @@ ARGS
|
|||
}
|
||||
}
|
||||
|
||||
func TestInstallSHRejectsPartialRecoveredProcessConnectionState(t *testing.T) {
|
||||
script := `
|
||||
PULSE_URL=""
|
||||
PULSE_TOKEN=""
|
||||
INTERVAL="30s"
|
||||
INTERVAL_EXPLICIT="false"
|
||||
ENABLE_HOST="true"
|
||||
HOST_EXPLICIT="false"
|
||||
ENABLE_DOCKER=""
|
||||
DOCKER_EXPLICIT="false"
|
||||
ENABLE_KUBERNETES=""
|
||||
KUBERNETES_EXPLICIT="false"
|
||||
KUBECONFIG_PATH=""
|
||||
ENABLE_PROXMOX=""
|
||||
PROXMOX_EXPLICIT="false"
|
||||
PROXMOX_TYPE=""
|
||||
INSECURE="false"
|
||||
ENABLE_COMMANDS="false"
|
||||
ENROLL="false"
|
||||
HEALTH_ADDR=""
|
||||
HEALTH_ADDR_SET="false"
|
||||
AGENT_ID=""
|
||||
HOSTNAME_OVERRIDE=""
|
||||
STATE_DIR="/var/lib/pulse-agent"
|
||||
CURL_CA_BUNDLE=""
|
||||
KUBE_INCLUDE_ALL_PODS="false"
|
||||
KUBE_INCLUDE_ALL_DEPLOYMENTS="false"
|
||||
DISK_EXCLUDES=()
|
||||
` + extractInstallShellFunction(t, "strip_recovered_arg_quotes") + `
|
||||
` + extractInstallShellFunction(t, "apply_recovered_agent_arg_value") + `
|
||||
` + extractInstallShellFunction(t, "recovered_connection_state_ready") + `
|
||||
` + extractInstallShellFunction(t, "recover_connection_state_from_arg_stream") + `
|
||||
if recover_connection_state_from_arg_stream <<'ARGS'
|
||||
/usr/local/bin/pulse-agent
|
||||
--url
|
||||
http://192.168.2.96:7655
|
||||
--enable-host
|
||||
--agent-id
|
||||
agent-123
|
||||
ARGS
|
||||
then
|
||||
echo "UNEXPECTED_SUCCESS"
|
||||
else
|
||||
echo "EXPECTED_FAILURE"
|
||||
fi
|
||||
printf 'URL=%s\nTOKEN=%s\nAGENT_ID=%s\n' "$PULSE_URL" "$PULSE_TOKEN" "$AGENT_ID"
|
||||
`
|
||||
|
||||
out, err := exec.Command("bash", "-c", script).CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("bash: %v\n%s", err, out)
|
||||
}
|
||||
got := string(out)
|
||||
if !strings.Contains(got, "EXPECTED_FAILURE") {
|
||||
t.Fatalf("partial recovered state should fail closed:\n%s", got)
|
||||
}
|
||||
if strings.Contains(got, "UNEXPECTED_SUCCESS") {
|
||||
t.Fatalf("partial recovered state reported success:\n%s", got)
|
||||
}
|
||||
if !strings.Contains(got, "URL=http://192.168.2.96:7655") || !strings.Contains(got, "AGENT_ID=agent-123") {
|
||||
t.Fatalf("partial recovery should still preserve non-secret fields for later sources:\n%s", got)
|
||||
}
|
||||
if !strings.Contains(got, "TOKEN=") {
|
||||
t.Fatalf("expected token to remain empty:\n%s", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInstallSHCombinesRecoveredProcessArgsAndEnvConnectionState(t *testing.T) {
|
||||
script := `
|
||||
PULSE_URL=""
|
||||
PULSE_TOKEN=""
|
||||
INTERVAL="30s"
|
||||
INTERVAL_EXPLICIT="false"
|
||||
ENABLE_HOST="true"
|
||||
HOST_EXPLICIT="false"
|
||||
ENABLE_DOCKER=""
|
||||
DOCKER_EXPLICIT="false"
|
||||
ENABLE_KUBERNETES=""
|
||||
KUBERNETES_EXPLICIT="false"
|
||||
KUBECONFIG_PATH=""
|
||||
ENABLE_PROXMOX=""
|
||||
PROXMOX_EXPLICIT="false"
|
||||
PROXMOX_TYPE=""
|
||||
INSECURE="false"
|
||||
ENABLE_COMMANDS="false"
|
||||
ENROLL="false"
|
||||
HEALTH_ADDR=""
|
||||
HEALTH_ADDR_SET="false"
|
||||
AGENT_ID=""
|
||||
HOSTNAME_OVERRIDE=""
|
||||
STATE_DIR="/var/lib/pulse-agent"
|
||||
CURL_CA_BUNDLE=""
|
||||
KUBE_INCLUDE_ALL_PODS="false"
|
||||
KUBE_INCLUDE_ALL_DEPLOYMENTS="false"
|
||||
DISK_EXCLUDES=()
|
||||
` + extractInstallShellFunction(t, "strip_recovered_arg_quotes") + `
|
||||
` + extractInstallShellFunction(t, "apply_recovered_agent_arg_value") + `
|
||||
` + extractInstallShellFunction(t, "recovered_connection_state_ready") + `
|
||||
` + extractInstallShellFunction(t, "recover_connection_state_from_arg_stream") + `
|
||||
` + extractInstallShellFunction(t, "recover_connection_state_from_env_stream") + `
|
||||
if recover_connection_state_from_arg_stream <<'ARGS'
|
||||
/usr/local/bin/pulse-agent
|
||||
--url
|
||||
http://192.168.2.96:7655
|
||||
ARGS
|
||||
then
|
||||
echo "ARGS_READY"
|
||||
else
|
||||
echo "ARGS_PARTIAL"
|
||||
fi
|
||||
if recover_connection_state_from_env_stream <<'ENV'
|
||||
PULSE_TOKEN=deadbeef
|
||||
ENV
|
||||
then
|
||||
echo "ENV_READY"
|
||||
else
|
||||
echo "ENV_PARTIAL"
|
||||
fi
|
||||
printf 'URL=%s\nTOKEN=%s\n' "$PULSE_URL" "$PULSE_TOKEN"
|
||||
`
|
||||
|
||||
out, err := exec.Command("bash", "-c", script).CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("bash: %v\n%s", err, out)
|
||||
}
|
||||
got := string(out)
|
||||
for _, needle := range []string{
|
||||
"ARGS_PARTIAL",
|
||||
"ENV_READY",
|
||||
"URL=http://192.168.2.96:7655",
|
||||
"TOKEN=deadbeef",
|
||||
} {
|
||||
if !strings.Contains(got, needle) {
|
||||
t.Fatalf("combined recovery missing %q:\n%s", needle, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestInstallSHUsesCanonicalServiceLifecycleHelpers(t *testing.T) {
|
||||
content, err := os.ReadFile(repoFile("scripts", "install.sh"))
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -735,6 +735,13 @@ class ReleasePromotionPolicyTest(unittest.TestCase):
|
|||
self.assertIn("DEMO_EXPECTED_HOSTNAME", demo)
|
||||
self.assertIn("Verify target host identity", demo)
|
||||
self.assertIn("Demo environment points at host $REMOTE_HOSTNAME but expected $DEMO_EXPECTED_HOSTNAME.", demo)
|
||||
self.assertIn("Restore demo runtime configuration", demo)
|
||||
self.assertIn("set_env_value DEMO_MODE true", demo)
|
||||
self.assertIn("set_env_value PULSE_MOCK_MODE true", demo)
|
||||
self.assertIn("Demo service restarted with governed demo runtime configuration.", demo)
|
||||
self.assertIn("/api/license/runtime-capabilities", demo)
|
||||
self.assertIn("Mock mode enabled", demo)
|
||||
self.assertIn("Demo server mock mode did not enable after entitlement sync", demo)
|
||||
self.assertIn(".resources | if type == \"array\" then length else 0 end", demo)
|
||||
self.assertNotIn(".nodes | length", demo)
|
||||
self.assertIn("Mock resources detected", demo)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue