Summary: See D37139129 Reviewed By: lblasa Differential Revision: D37236435 fbshipit-source-id: 927e9f741bfedb65165f5d24f0acfb775925cdc7
110 lines
3.0 KiB
TypeScript
110 lines
3.0 KiB
TypeScript
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @format
|
|
*/
|
|
|
|
import {
|
|
logPlatformSuccessRate,
|
|
reportPlatformFailures,
|
|
FlipperDoctor,
|
|
} from 'flipper-common';
|
|
import {getRenderHostInstance} from 'flipper-frontend-core';
|
|
|
|
let healthcheckIsRunning: boolean;
|
|
let runningHealthcheck: Promise<void>;
|
|
|
|
export type HealthcheckEventsHandler = {
|
|
updateHealthcheckResult: (
|
|
categoryKey: string,
|
|
itemKey: string,
|
|
result: FlipperDoctor.HealthcheckResult,
|
|
) => void;
|
|
startHealthchecks: (healthchecks: FlipperDoctor.Healthchecks) => void;
|
|
finishHealthchecks: () => void;
|
|
};
|
|
|
|
export type HealthcheckSettings = {
|
|
settings: {
|
|
enableAndroid: boolean;
|
|
enableIOS: boolean;
|
|
enablePhysicalIOS: boolean;
|
|
idbPath: string;
|
|
};
|
|
};
|
|
|
|
export type HealthcheckOptions = HealthcheckEventsHandler & HealthcheckSettings;
|
|
|
|
async function launchHealthchecks(options: HealthcheckOptions): Promise<void> {
|
|
const {flipperServer} = getRenderHostInstance();
|
|
const healthchecks = await flipperServer.exec('doctor-get-healthchecks', {
|
|
settings: options.settings,
|
|
});
|
|
options.startHealthchecks(healthchecks);
|
|
let hasProblems = false;
|
|
for (const [categoryKey, category] of Object.entries(healthchecks)) {
|
|
if (category.isSkipped) {
|
|
continue;
|
|
}
|
|
for (const h of category.healthchecks) {
|
|
const checkResult: FlipperDoctor.HealthcheckResult = await flipperServer
|
|
.exec(
|
|
'doctor-run-healthcheck',
|
|
{settings: options.settings},
|
|
categoryKey as keyof FlipperDoctor.Healthchecks,
|
|
h.key,
|
|
)
|
|
.catch((e) => {
|
|
console.error('Failed to run doctor check', e);
|
|
return {
|
|
status: 'FAILED',
|
|
isAcknowledged: false,
|
|
message: 'Failed to run doctor check: ' + e,
|
|
};
|
|
});
|
|
const metricName = `doctor:${h.key.replace('.', ':')}.healthcheck`; // e.g. "doctor:ios:xcode-select.healthcheck"
|
|
if (checkResult.status !== 'SUCCESS') {
|
|
hasProblems = true;
|
|
logPlatformSuccessRate(metricName, {
|
|
kind: 'failure',
|
|
supportedOperation: true,
|
|
error: null,
|
|
});
|
|
} else {
|
|
logPlatformSuccessRate(metricName, {
|
|
kind: 'success',
|
|
});
|
|
}
|
|
options.updateHealthcheckResult(categoryKey, h.key, checkResult);
|
|
}
|
|
}
|
|
options.finishHealthchecks();
|
|
if (hasProblems) {
|
|
logPlatformSuccessRate('doctor.healthcheck', {
|
|
kind: 'failure',
|
|
supportedOperation: true,
|
|
error: null,
|
|
});
|
|
} else {
|
|
logPlatformSuccessRate('doctor.healthcheck', {
|
|
kind: 'success',
|
|
});
|
|
}
|
|
}
|
|
|
|
export default async function runHealthchecks(
|
|
options: HealthcheckOptions,
|
|
): Promise<void> {
|
|
if (healthcheckIsRunning) {
|
|
return runningHealthcheck;
|
|
}
|
|
runningHealthcheck = reportPlatformFailures(
|
|
launchHealthchecks(options),
|
|
'doctor:runHealthchecks',
|
|
);
|
|
return runningHealthcheck;
|
|
}
|