diff --git a/x-pack/plugins/fleet/common/services/agent_status.test.ts b/x-pack/plugins/fleet/common/services/agent_status.test.ts new file mode 100644 index 0000000000000..5c64e2d023ddc --- /dev/null +++ b/x-pack/plugins/fleet/common/services/agent_status.test.ts @@ -0,0 +1,84 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Agent } from '../types'; + +import { isStuckInUpdating } from './agent_status'; + +describe('isStuckInUpdating', () => { + it('should return true if agent is active and in failed upgrade state', () => { + const agent = { + active: true, + status: 'online', + upgrade_details: { + state: 'UPG_FAILED', + }, + } as Agent; + + expect(isStuckInUpdating(agent)).toBe(true); + }); + + it('should return false if agent is active and in watching upgrade state', () => { + const agent = { + active: true, + status: 'online', + upgrade_details: { + state: 'UPG_WATCHING', + }, + } as Agent; + + expect(isStuckInUpdating(agent)).toBe(false); + }); + + it('should return false if agent is active and in rollback upgrade state', () => { + const agent = { + active: true, + status: 'online', + upgrade_details: { + state: 'UPG_ROLLBACK', + }, + } as Agent; + + expect(isStuckInUpdating(agent)).toBe(false); + }); + + it('should return false if agent is updating and in schedule upgrade state', () => { + const agent = { + active: true, + status: 'updating', + upgrade_started_at: '2022-11-21T12:27:24Z', + upgrade_details: { + state: 'UPG_SCHEDULED', + }, + } as Agent; + + expect(isStuckInUpdating(agent)).toBe(false); + }); + + it('should return false if agent is updating and in downloading upgrade state', () => { + const agent = { + active: true, + status: 'updating', + upgrade_started_at: '2022-11-21T12:27:24Z', + upgrade_details: { + state: 'UPG_DOWNLOADING', + }, + } as Agent; + + expect(isStuckInUpdating(agent)).toBe(false); + }); + + it('should return true if agent is updating no upgrade details state', () => { + const agent = { + active: true, + status: 'updating', + upgrade_started_at: '2022-11-21T12:27:24Z', + } as Agent; + + expect(isStuckInUpdating(agent)).toBe(true); + }); +}); diff --git a/x-pack/plugins/fleet/common/services/agent_status.ts b/x-pack/plugins/fleet/common/services/agent_status.ts index 78726667f3b13..42b586d7552ae 100644 --- a/x-pack/plugins/fleet/common/services/agent_status.ts +++ b/x-pack/plugins/fleet/common/services/agent_status.ts @@ -60,13 +60,15 @@ export function buildKueryForInactiveAgents() { export const AGENT_UPDATING_TIMEOUT_HOURS = 2; export function isStuckInUpdating(agent: Agent): boolean { + const hasTimedOut = (upgradeStartedAt: string) => + Date.now() - Date.parse(upgradeStartedAt) > AGENT_UPDATING_TIMEOUT_HOURS * 60 * 60 * 1000; return ( (agent.status !== 'offline' && agent.active && isAgentInFailedUpgradeState(agent)) || (agent.status === 'updating' && !!agent.upgrade_started_at && !agent.upgraded_at && - Date.now() - Date.parse(agent.upgrade_started_at) > - AGENT_UPDATING_TIMEOUT_HOURS * 60 * 60 * 1000) + hasTimedOut(agent.upgrade_started_at) && + !agent.upgrade_details?.state) ); }