diff --git a/api/controllers/app/apppreflight.go b/api/controllers/app/apppreflight.go index 793ca1b72d..d96db05bc4 100644 --- a/api/controllers/app/apppreflight.go +++ b/api/controllers/app/apppreflight.go @@ -8,6 +8,7 @@ import ( "time" apppreflightmanager "github.com/replicatedhq/embedded-cluster/api/internal/managers/app/preflight" + "github.com/replicatedhq/embedded-cluster/api/internal/statemachine" "github.com/replicatedhq/embedded-cluster/api/internal/states" "github.com/replicatedhq/embedded-cluster/api/types" ecv1beta1 "github.com/replicatedhq/embedded-cluster/kinds/apis/v1beta1" @@ -116,22 +117,30 @@ func (c *AppController) RunAppPreflights(ctx context.Context, opts RunAppPreflig return fmt.Errorf("run app preflights: %w", err) } + // Transition state machine based on whether there are failures + // This is used internally for workflow state tracking + var smState statemachine.State if output.HasFail() { - if err := c.stateMachine.Transition(lock, states.StateAppPreflightsFailed, output); err != nil { - return fmt.Errorf("transition states: %w", err) - } + smState = states.StateAppPreflightsFailed + } else { + smState = states.StateAppPreflightsSucceeded + } - if err := c.setAppPreflightStatus(types.StateFailed, "App preflights failed"); err != nil { - return fmt.Errorf("set status to failed: %w", err) - } + if err := c.stateMachine.Transition(lock, smState, output); err != nil { + return fmt.Errorf("transition states: %w", err) + } + + // Always set status to StateSucceeded to indicate execution completed successfully + // The output will contain failures/warnings for the caller to check + var statusDescription string + if output.HasFail() { + statusDescription = "App preflights completed with failures" } else { - if err := c.stateMachine.Transition(lock, states.StateAppPreflightsSucceeded, output); err != nil { - return fmt.Errorf("transition states: %w", err) - } + statusDescription = "App preflights succeeded" + } - if err := c.setAppPreflightStatus(types.StateSucceeded, "App preflights succeeded"); err != nil { - return fmt.Errorf("set status to succeeded: %w", err) - } + if err := c.setAppPreflightStatus(types.StateSucceeded, statusDescription); err != nil { + return fmt.Errorf("set status to succeeded: %w", err) } return nil diff --git a/api/controllers/linux/install/hostpreflight.go b/api/controllers/linux/install/hostpreflight.go index 2470d0b1c7..fe1ecbd1a5 100644 --- a/api/controllers/linux/install/hostpreflight.go +++ b/api/controllers/linux/install/hostpreflight.go @@ -7,6 +7,7 @@ import ( "time" "github.com/replicatedhq/embedded-cluster/api/internal/managers/linux/preflight" + "github.com/replicatedhq/embedded-cluster/api/internal/statemachine" "github.com/replicatedhq/embedded-cluster/api/internal/states" "github.com/replicatedhq/embedded-cluster/api/internal/utils" "github.com/replicatedhq/embedded-cluster/api/types" @@ -105,22 +106,30 @@ func (c *InstallController) RunHostPreflights(ctx context.Context, opts RunHostP return fmt.Errorf("run host preflights: %w", err) } + // Transition state machine based on whether there are failures + // This is used internally for workflow state tracking + var smState statemachine.State if output.HasFail() { - if err := c.stateMachine.Transition(lock, states.StateHostPreflightsFailed, output); err != nil { - return fmt.Errorf("transition states: %w", err) - } + smState = states.StateHostPreflightsFailed + } else { + smState = states.StateHostPreflightsSucceeded + } - if err := c.setHostPreflightStatus(types.StateFailed, "Host preflights failed"); err != nil { - return fmt.Errorf("set status to failed: %w", err) - } + if err := c.stateMachine.Transition(lock, smState, output); err != nil { + return fmt.Errorf("transition states: %w", err) + } + + // Always set status to StateSucceeded to indicate execution completed successfully + // The output will contain failures/warnings for the caller to check + var statusDescription string + if output.HasFail() { + statusDescription = "Host preflights completed with failures" } else { - if err := c.stateMachine.Transition(lock, states.StateHostPreflightsSucceeded, output); err != nil { - return fmt.Errorf("transition states: %w", err) - } + statusDescription = "Host preflights succeeded" + } - if err := c.setHostPreflightStatus(types.StateSucceeded, "Host preflights succeeded"); err != nil { - return fmt.Errorf("set status to succeeded: %w", err) - } + if err := c.setHostPreflightStatus(types.StateSucceeded, statusDescription); err != nil { + return fmt.Errorf("set status to succeeded: %w", err) } return nil diff --git a/cmd/installer/cli/headless/install/orchestrator.go b/cmd/installer/cli/headless/install/orchestrator.go index 0e7d312026..2284e2e7d6 100644 --- a/cmd/installer/cli/headless/install/orchestrator.go +++ b/cmd/installer/cli/headless/install/orchestrator.go @@ -253,8 +253,7 @@ func (o *orchestrator) runHostPreflights(ctx context.Context, ignoreFailures boo return fmt.Errorf("run linux install host preflights: %w", err) } - // For preflights, we poll until the operation completes (either succeeded or failed), - // then check if there are failures and decide whether to continue based on ignoreFailures + // Poll until the preflight execution completes state, message, err := pollUntilComplete(ctx, func() (apitypes.State, string, error) { resp, err = o.apiClient.GetLinuxInstallHostPreflightsStatus(ctx) if err != nil { @@ -267,15 +266,17 @@ func (o *orchestrator) runHostPreflights(ctx context.Context, ignoreFailures boo return fmt.Errorf("poll until complete: %w", err) } - if state == apitypes.StateFailed { - hasFailures := resp.Output != nil && resp.Output.HasFail() + // With the new behavior, preflights always return StateSucceeded when execution completes. + // We need to check the output for actual failures. + if state != apitypes.StateSucceeded { + loading.ErrorClosef("Host preflights execution failed") + return fmt.Errorf("host preflights execution failed: %s", message) + } - // If there are no failures, it means the execution failed - if !hasFailures { - loading.ErrorClosef("Host preflights execution failed") - return fmt.Errorf("host preflights execution failed: %s", message) - } + // Check if there are actual preflight failures + hasFailures := resp.Output != nil && resp.Output.HasFail() + if hasFailures { loading.ErrorClosef("Host preflights completed with failures") o.logger.Warn("\n⚠ Warning: Host preflight checks completed with failures\n") @@ -400,8 +401,7 @@ func (o *orchestrator) runAppPreflights(ctx context.Context, ignoreFailures bool return fmt.Errorf("run linux install app preflights: %w", err) } - // For preflights, we poll until the operation completes (either succeeded or failed), - // then check if there are failures and decide whether to continue based on ignoreFailures + // Poll until the preflight execution completes state, message, err := pollUntilComplete(ctx, func() (apitypes.State, string, error) { resp, err = o.apiClient.GetLinuxInstallAppPreflightsStatus(ctx) if err != nil { @@ -414,15 +414,17 @@ func (o *orchestrator) runAppPreflights(ctx context.Context, ignoreFailures bool return fmt.Errorf("poll until complete: %w", err) } - if state == apitypes.StateFailed { - hasFailures := resp.Output != nil && resp.Output.HasFail() + // With the new behavior, preflights always return StateSucceeded when execution completes. + // We need to check the output for actual failures. + if state != apitypes.StateSucceeded { + loading.ErrorClosef("App preflights execution failed") + return fmt.Errorf("app preflights execution failed: %s", message) + } - // If there are no failures, it means the execution failed - if !hasFailures { - loading.ErrorClosef("App preflights execution failed") - return fmt.Errorf("app preflights execution failed: %s", message) - } + // Check if there are actual preflight failures + hasFailures := resp.Output != nil && resp.Output.HasFail() + if hasFailures { loading.ErrorClosef("App preflights completed with failures") o.logger.Warn("\n⚠ Warning: Application preflight checks completed with failures\n") diff --git a/cmd/installer/cli/headless/install/orchestrator_test.go b/cmd/installer/cli/headless/install/orchestrator_test.go index 68ad5445fa..21a8dc4baf 100644 --- a/cmd/installer/cli/headless/install/orchestrator_test.go +++ b/cmd/installer/cli/headless/install/orchestrator_test.go @@ -295,7 +295,7 @@ func Test_orchestrator_runHostPreflights(t *testing.T) { mockGetStatusFunc: func(ctx context.Context) (apitypes.InstallHostPreflightsStatusResponse, error) { return apitypes.InstallHostPreflightsStatusResponse{ Status: apitypes.Status{ - State: apitypes.StateFailed, + State: apitypes.StateSucceeded, Description: "Completed with failures", }, Output: &apitypes.PreflightsOutput{ @@ -328,7 +328,7 @@ func Test_orchestrator_runHostPreflights(t *testing.T) { mockGetStatusFunc: func(ctx context.Context) (apitypes.InstallHostPreflightsStatusResponse, error) { return apitypes.InstallHostPreflightsStatusResponse{ Status: apitypes.Status{ - State: apitypes.StateFailed, + State: apitypes.StateSucceeded, Description: "Completed with failures", }, Output: &apitypes.PreflightsOutput{ @@ -645,7 +645,7 @@ func Test_orchestrator_runAppPreflights(t *testing.T) { mockGetStatusFunc: func(ctx context.Context) (apitypes.InstallAppPreflightsStatusResponse, error) { return apitypes.InstallAppPreflightsStatusResponse{ Status: apitypes.Status{ - State: apitypes.StateFailed, + State: apitypes.StateSucceeded, Description: "Completed with failures", }, Output: &apitypes.PreflightsOutput{ @@ -677,7 +677,7 @@ func Test_orchestrator_runAppPreflights(t *testing.T) { mockGetStatusFunc: func(ctx context.Context) (apitypes.InstallAppPreflightsStatusResponse, error) { return apitypes.InstallAppPreflightsStatusResponse{ Status: apitypes.Status{ - State: apitypes.StateFailed, + State: apitypes.StateSucceeded, Description: "Completed with failures", }, Output: &apitypes.PreflightsOutput{ diff --git a/tests/dryrun/v3_install_preflights_test.go b/tests/dryrun/v3_install_preflights_test.go index 2c712cbfcc..eede08a1e1 100644 --- a/tests/dryrun/v3_install_preflights_test.go +++ b/tests/dryrun/v3_install_preflights_test.go @@ -130,14 +130,13 @@ func TestV3Install_HostPreflights_WithFailuresBypass(t *testing.T) { }() runV3Install(t, v3InstallArgs{ - managerPort: 30080, - password: "password123", - isAirgap: false, - configValuesFile: configFile, - installationConfig: apitypes.LinuxInstallationConfig{}, - ignoreHostPreflights: true, // Bypass host preflight failures - ignoreAppPreflights: false, - shouldHostPreflightsFail: true, + managerPort: 30080, + password: "password123", + isAirgap: false, + configValuesFile: configFile, + installationConfig: apitypes.LinuxInstallationConfig{}, + ignoreHostPreflights: true, // Bypass host preflight failures + ignoreAppPreflights: false, }) require.NoError(t, dryrun.Dump(), "fail to dump dryrun output") @@ -332,14 +331,13 @@ func TestV3Install_AppPreflights_WithFailuresBypass(t *testing.T) { }() runV3Install(t, v3InstallArgs{ - managerPort: 30080, - password: "password123", - isAirgap: false, - configValuesFile: configFile, - installationConfig: apitypes.LinuxInstallationConfig{}, - ignoreHostPreflights: false, - ignoreAppPreflights: true, // Bypass app preflight failures - shouldAppPreflightsFail: true, + managerPort: 30080, + password: "password123", + isAirgap: false, + configValuesFile: configFile, + installationConfig: apitypes.LinuxInstallationConfig{}, + ignoreHostPreflights: false, + ignoreAppPreflights: true, // Bypass app preflight failures }) preflightRunner.AssertExpectations(t) diff --git a/web/src/components/wizard/installation/phases/AppPreflightCheck.tsx b/web/src/components/wizard/installation/phases/AppPreflightCheck.tsx index 67a771868f..fb84494baf 100644 --- a/web/src/components/wizard/installation/phases/AppPreflightCheck.tsx +++ b/web/src/components/wizard/installation/phases/AppPreflightCheck.tsx @@ -24,7 +24,8 @@ const AppPreflightCheck: React.FC = ({ onRun, onComplete const hasFailures = (output?: PreflightsOutput) => (output?.fail?.length ?? 0) > 0; const hasWarnings = (output?: PreflightsOutput) => (output?.warn?.length ?? 0) > 0; const hasStrictFailures = (response?: AppPreflightsResponse) => response?.hasStrictAppPreflightFailures ?? false; - const isSuccessful = (response?: AppPreflightsResponse) => response?.status?.state === "Succeeded"; + const isSuccessful = (response?: AppPreflightsResponse) => + response?.status?.state === "Succeeded" && !hasFailures(response?.output); const getErrorMessage = () => { if (runAppPreflights.error) { @@ -63,13 +64,18 @@ const AppPreflightCheck: React.FC = ({ onRun, onComplete // Handle preflight status changes useEffect(() => { - if (preflightResponse?.status?.state === "Succeeded" || preflightResponse?.status?.state === "Failed") { + if (preflightResponse?.status?.state === "Succeeded") { + // Execution completed successfully - check if there are preflight failures setIsPreflightsPolling(false); onComplete( !hasFailures(preflightResponse.output), preflightResponse.allowIgnoreAppPreflights ?? false, hasStrictFailures(preflightResponse) ); + } else if (preflightResponse?.status?.state === "Failed") { + // Execution failed - treat as failure regardless of output + setIsPreflightsPolling(false); + onComplete(false, false, false); } }, [preflightResponse]); diff --git a/web/src/components/wizard/installation/phases/LinuxPreflightCheck.tsx b/web/src/components/wizard/installation/phases/LinuxPreflightCheck.tsx index 5651b6e501..2d516b4811 100644 --- a/web/src/components/wizard/installation/phases/LinuxPreflightCheck.tsx +++ b/web/src/components/wizard/installation/phases/LinuxPreflightCheck.tsx @@ -24,7 +24,8 @@ const LinuxPreflightCheck: React.FC = ({ onRun, onComp const hasFailures = (output?: PreflightsOutput) => (output?.fail?.length ?? 0) > 0; const hasWarnings = (output?: PreflightsOutput) => (output?.warn?.length ?? 0) > 0; - const isSuccessful = (response?: HostPreflightResponse) => response?.status?.state === "Succeeded"; + const isSuccessful = (response?: HostPreflightResponse) => + response?.status?.state === "Succeeded" && !hasFailures(response?.output); const getErrorMessage = () => { if (runHostPreflights.error) { @@ -69,9 +70,14 @@ const LinuxPreflightCheck: React.FC = ({ onRun, onComp // Handle preflight status changes useEffect(() => { - if (preflightResponse?.status?.state === "Succeeded" || preflightResponse?.status?.state === "Failed") { + if (preflightResponse?.status?.state === "Succeeded") { + // Execution completed successfully - check if there are preflight failures setIsPreflightsPolling(false); onComplete(!hasFailures(preflightResponse.output), preflightResponse.allowIgnoreHostPreflights ?? false); + } else if (preflightResponse?.status?.state === "Failed") { + // Execution failed - treat as failure regardless of output + setIsPreflightsPolling(false); + onComplete(false, false); } }, [preflightResponse]); diff --git a/web/src/components/wizard/installation/tests/AppPreflightCheck.test.tsx b/web/src/components/wizard/installation/tests/AppPreflightCheck.test.tsx index 3026650e7d..3b270d6814 100644 --- a/web/src/components/wizard/installation/tests/AppPreflightCheck.test.tsx +++ b/web/src/components/wizard/installation/tests/AppPreflightCheck.test.tsx @@ -9,7 +9,7 @@ const TEST_TOKEN = "test-auth-token"; const createServer = (target: 'linux' | 'kubernetes') => setupServer( mockHandlers.preflights.app.getStatus({ - status: { state: "Failed" }, + status: { state: "Succeeded" }, output: { pass: [{ title: "CPU Check", message: "CPU requirements met" }], warn: [{ title: "Memory Warning", message: "Memory is below recommended" }], @@ -131,10 +131,10 @@ describe.each([ }); it("receives allowIgnoreAppPreflights field in preflight response", async () => { - // Mock preflight status endpoint with allowIgnoreAppPreflights: true + // Mock preflight status endpoint with allowIgnoreAppPreflights: true - execution succeeds but checks fail server.use( mockHandlers.preflights.app.getStatus({ - status: { state: "Failed" }, + status: { state: "Succeeded" }, output: { pass: [{ title: "CPU Check", message: "CPU requirements met" }], warn: [], @@ -161,10 +161,10 @@ describe.each([ }); it("passes allowIgnoreAppPreflights false to onComplete callback", async () => { - // Mock preflight status endpoint with allowIgnoreAppPreflights: false + // Mock preflight status endpoint with allowIgnoreAppPreflights: false - execution succeeds but checks fail server.use( mockHandlers.preflights.app.getStatus({ - status: { state: "Failed" }, + status: { state: "Succeeded" }, output: { pass: [{ title: "CPU Check", message: "CPU requirements met" }], warn: [], @@ -192,10 +192,10 @@ describe.each([ // New tests for strict preflight functionality it("displays strict failures with visual distinction", async () => { - // Mock preflight status endpoint with strict and non-strict failures + // Mock preflight status endpoint with strict and non-strict failures - execution succeeds but checks fail server.use( mockHandlers.preflights.app.getStatus({ - status: { state: "Failed" }, + status: { state: "Succeeded" }, output: { pass: [], warn: [], @@ -232,10 +232,10 @@ describe.each([ }); it("shows appropriate guidance for strict failures in What's Next section", async () => { - // Mock preflight status endpoint with strict failures + // Mock preflight status endpoint with strict failures - execution succeeds but checks fail server.use( mockHandlers.preflights.app.getStatus({ - status: { state: "Failed" }, + status: { state: "Succeeded" }, output: { pass: [], warn: [], @@ -262,10 +262,10 @@ describe.each([ }); it("passes hasStrictAppPreflightFailures from API response to onComplete", async () => { - // Mock preflight status endpoint with hasStrictAppPreflightFailures field + // Mock preflight status endpoint with hasStrictAppPreflightFailures field - execution succeeds but checks fail server.use( mockHandlers.preflights.app.getStatus({ - status: { state: "Failed" }, + status: { state: "Succeeded" }, output: { pass: [], warn: [], diff --git a/web/src/components/wizard/installation/tests/AppPreflightPhase.test.tsx b/web/src/components/wizard/installation/tests/AppPreflightPhase.test.tsx index 175aff86ad..67eced9849 100644 --- a/web/src/components/wizard/installation/tests/AppPreflightPhase.test.tsx +++ b/web/src/components/wizard/installation/tests/AppPreflightPhase.test.tsx @@ -37,10 +37,10 @@ describe.each([ }); it('enables Start Installation button when allowIgnoreAppPreflights is true and preflights fail', async () => { - // Mock preflight status endpoint - returns failures with allowIgnoreAppPreflights: true + // Mock preflight status endpoint - execution succeeds but checks fail server.use( mockHandlers.preflights.app.getStatus({ - status: { state: 'Failed' }, + status: { state: 'Succeeded' }, output: preflightPresets.failed('Not enough disk space available'), allowIgnoreAppPreflights: true }, target, 'install') @@ -73,10 +73,10 @@ describe.each([ }); it('disables Start Installation button when allowIgnoreAppPreflights is false and preflights fail', async () => { - // Mock preflight status endpoint - returns failures with allowIgnoreAppPreflights: false + // Mock preflight status endpoint - execution succeeds but checks fail server.use( mockHandlers.preflights.app.getStatus({ - status: { state: 'Failed' }, + status: { state: 'Succeeded' }, output: preflightPresets.failed('Not enough disk space available'), allowIgnoreAppPreflights: false }, target, 'install') @@ -115,10 +115,10 @@ describe.each([ }); it('shows modal when Start Installation clicked and allowIgnoreAppPreflights is true and preflights fail', async () => { - // Mock preflight status endpoint - returns failures with allowIgnoreAppPreflights: true + // Mock preflight status endpoint - execution succeeds but checks fail server.use( mockHandlers.preflights.app.getStatus({ - status: { state: 'Failed' }, + status: { state: 'Succeeded' }, output: preflightPresets.failed('Not enough disk space available'), allowIgnoreAppPreflights: true }, target, 'install') @@ -275,10 +275,10 @@ describe.each([ // Verify ignoreAppPreflights parameter is sent it('sends ignoreAppPreflights parameter when starting installation with failed preflights', async () => { - // Mock preflight status endpoint - returns failures with allowIgnoreAppPreflights: true + // Mock preflight status endpoint - execution succeeds but checks fail server.use( mockHandlers.preflights.app.getStatus({ - status: { state: 'Failed' }, + status: { state: 'Succeeded' }, output: preflightPresets.failed('Not enough disk space available'), allowIgnoreAppPreflights: true }, target, 'install'), @@ -372,10 +372,10 @@ describe.each([ // New tests for strict preflight blocking it('disables Start Installation button when strict failures exist regardless of allowIgnoreAppPreflights', async () => { - // Mock preflight status endpoint - returns strict failures with allowIgnoreAppPreflights: true + // Mock preflight status endpoint - execution succeeds but has strict failures server.use( mockHandlers.preflights.app.getStatus({ - status: { state: 'Failed' }, + status: { state: 'Succeeded' }, output: { fail: [ { title: 'Critical Security Check', message: 'Security requirement not met', strict: true }, @@ -416,10 +416,10 @@ describe.each([ }); it('does not show modal when strict failures exist because button is disabled', async () => { - // Mock preflight status endpoint - returns strict failures + // Mock preflight status endpoint - execution succeeds but has strict failures server.use( mockHandlers.preflights.app.getStatus({ - status: { state: 'Failed' }, + status: { state: 'Succeeded' }, output: { fail: [ { title: 'Critical Security Check', message: 'Security requirement not met', strict: true } @@ -543,10 +543,10 @@ describe.each([ }); it('calls onStateChange with "Failed" when preflights complete with failures', async () => { - // Mock preflight status endpoint - returns failures + // Mock preflight status endpoint - execution succeeds but checks fail server.use( mockHandlers.preflights.app.getStatus({ - status: { state: 'Failed' }, + status: { state: 'Succeeded' }, output: preflightPresets.failed('Not enough disk space available'), allowIgnoreAppPreflights: false }, target, 'install') @@ -576,10 +576,10 @@ describe.each([ }); it('calls onStateChange("Running") when rerun button is clicked', async () => { - // Mock preflight status to show failures initially + // Mock preflight status to show failures initially - execution succeeds but checks fail server.use( mockHandlers.preflights.app.getStatus({ - status: { state: 'Failed' }, + status: { state: 'Succeeded' }, output: preflightPresets.failed('Not enough disk space'), allowIgnoreAppPreflights: false }, target, 'install'), diff --git a/web/src/components/wizard/installation/tests/LinuxPreflightCheck.test.tsx b/web/src/components/wizard/installation/tests/LinuxPreflightCheck.test.tsx index b21436c754..9a27123f8b 100644 --- a/web/src/components/wizard/installation/tests/LinuxPreflightCheck.test.tsx +++ b/web/src/components/wizard/installation/tests/LinuxPreflightCheck.test.tsx @@ -9,7 +9,7 @@ const TEST_TOKEN = "test-auth-token"; const server = setupServer( mockHandlers.preflights.host.getStatus({ - status: { state: "Failed" }, + status: { state: "Succeeded" }, output: { pass: [{ title: "CPU Check", message: "CPU requirements met" }], warn: [{ title: "Memory Warning", message: "Memory is below recommended" }], @@ -118,10 +118,10 @@ describe("LinuxPreflightCheck", () => { }); it("receives allowIgnoreHostPreflights field in preflight response", async () => { - // Mock preflight status endpoint with allowIgnoreHostPreflights: true + // Mock preflight status endpoint with allowIgnoreHostPreflights: true - execution succeeds but checks fail server.use( mockHandlers.preflights.host.getStatus({ - status: { state: "Failed" }, + status: { state: "Succeeded" }, output: preflightPresets.failed("Insufficient disk space"), allowIgnoreHostPreflights: true, }) @@ -143,10 +143,10 @@ describe("LinuxPreflightCheck", () => { }); it("passes allowIgnoreHostPreflights false to onComplete callback", async () => { - // Mock preflight status endpoint with allowIgnoreHostPreflights: false + // Mock preflight status endpoint with allowIgnoreHostPreflights: false - execution succeeds but checks fail server.use( mockHandlers.preflights.host.getStatus({ - status: { state: "Failed" }, + status: { state: "Succeeded" }, output: preflightPresets.failed("Insufficient disk space"), allowIgnoreHostPreflights: false, }) diff --git a/web/src/components/wizard/installation/tests/LinuxPreflightPhase.test.tsx b/web/src/components/wizard/installation/tests/LinuxPreflightPhase.test.tsx index 13f5db707f..571d927a09 100644 --- a/web/src/components/wizard/installation/tests/LinuxPreflightPhase.test.tsx +++ b/web/src/components/wizard/installation/tests/LinuxPreflightPhase.test.tsx @@ -34,10 +34,10 @@ describe('LinuxPreflightPhase', () => { }); it('enables Start Installation button when allowIgnoreHostPreflights is true and preflights fail', async () => { - // Mock preflight status endpoint - returns failures with allowIgnoreHostPreflights: true + // Mock preflight status endpoint - execution succeeds but checks fail server.use( mockHandlers.preflights.host.getStatus({ - status: { state: 'Failed' }, + status: { state: 'Succeeded' }, output: preflightPresets.failed('Not enough disk space available'), allowIgnoreHostPreflights: true, }) @@ -69,10 +69,10 @@ describe('LinuxPreflightPhase', () => { }); it('disables Start Installation button when allowIgnoreHostPreflights is false and preflights fail', async () => { - // Mock preflight status endpoint - returns failures with allowIgnoreHostPreflights: false + // Mock preflight status endpoint - execution succeeds but checks fail server.use( mockHandlers.preflights.host.getStatus({ - status: { state: 'Failed' }, + status: { state: 'Succeeded' }, output: preflightPresets.failed('Not enough disk space available'), allowIgnoreHostPreflights: false, }) @@ -110,10 +110,10 @@ describe('LinuxPreflightPhase', () => { }); it('shows modal when Start Installation clicked and allowIgnoreHostPreflights is true and preflights fail', async () => { - // Mock preflight status endpoint - returns failures with allowIgnoreHostPreflights: true + // Mock preflight status endpoint - execution succeeds but checks fail server.use( mockHandlers.preflights.host.getStatus({ - status: { state: 'Failed' }, + status: { state: 'Succeeded' }, output: preflightPresets.failed('Not enough disk space available'), allowIgnoreHostPreflights: true, }) @@ -267,10 +267,10 @@ describe('LinuxPreflightPhase', () => { // Verify ignoreHostPreflights parameter is sent it('sends ignoreHostPreflights parameter when starting installation with failed preflights', async () => { - // Mock preflight status endpoint - returns failures with allowIgnoreHostPreflights: true + // Mock preflight status endpoint - execution succeeds but checks fail server.use( mockHandlers.preflights.host.getStatus({ - status: { state: 'Failed' }, + status: { state: 'Succeeded' }, output: preflightPresets.failed('Not enough disk space available'), allowIgnoreHostPreflights: true, }), @@ -372,10 +372,10 @@ describe('LinuxPreflightPhase - Error Handling & Edge Cases', () => { }); it('properly handles modal cancellation flow', async () => { - // Mock preflight status endpoint - returns failures + // Mock preflight status endpoint - execution succeeds but checks fail server.use( mockHandlers.preflights.host.getStatus({ - status: { state: 'Failed' }, + status: { state: 'Succeeded' }, output: preflightPresets.failed('Not enough disk space'), allowIgnoreHostPreflights: true, }) @@ -496,10 +496,10 @@ describe('LinuxPreflightPhase - onStateChange Tests', () => { }); it('calls onStateChange with "Failed" when preflights complete with failures', async () => { - // Mock preflight status endpoint - returns failures + // Mock preflight status endpoint - execution succeeds but checks fail server.use( mockHandlers.preflights.host.getStatus({ - status: { state: 'Failed' }, + status: { state: 'Succeeded' }, output: preflightPresets.failed('Not enough disk space available'), allowIgnoreHostPreflights: false, }) @@ -529,10 +529,10 @@ describe('LinuxPreflightPhase - onStateChange Tests', () => { }); it('calls onStateChange("Running") when rerun button is clicked', async () => { - // Mock preflight status to show failures initially + // Mock preflight status to show failures initially - execution succeeds but checks fail server.use( mockHandlers.preflights.host.getStatus({ - status: { state: 'Failed' }, + status: { state: 'Succeeded' }, output: preflightPresets.failed('Not enough disk space'), allowIgnoreHostPreflights: false, })