Files
kam-mobile/code/ProbeReport.pas
T
2026-09-11 18:19:50 +05:00

79 lines
2.5 KiB
ObjectPascal
Executable File

unit ProbeReport;
{$mode objfpc}{$H+}{$codepage utf8}
interface
uses SysUtils, fpjson;
type
TProbeReport = class
private
FRoot: TJSONObject;
FTests: TJSONArray;
public
constructor Create;
destructor Destroy; override;
procedure Add(const Id, Status, Detail: string);
procedure Check(const Id: string; const Ok: Boolean; const Detail: string);
procedure Save(const FileName: string);
function Status: string;
property Root: TJSONObject read FRoot;
end;
implementation
uses Classes, CastleLog, ProbeBuild;
constructor TProbeReport.Create;
begin
inherited;
FRoot := TJSONObject.Create;
FRoot.Add('schema', 'kam-android-runtime/1');
FRoot.Add('build_id', ProbeBuildId);
FRoot.Add('profile', ProbeProfile);
FRoot.Add('cpu_expected', ProbeCpu);
FRoot.Add('upstream_commit', ProbeUpstreamCommit);
FRoot.Add('scope', 'Android architecture smoke, not a running KaM world');
FRoot.Add('world_simulation', 'NOT_RUN');
FTests := TJSONArray.Create;
FRoot.Add('tests', FTests);
end;
destructor TProbeReport.Destroy;
begin
FRoot.Free;
inherited;
end;
procedure TProbeReport.Add(const Id, Status, Detail: string);
var J: TJSONObject; I: Integer;
begin
for I := FTests.Count - 1 downto 0 do
if FTests.Objects[I].Get('id', '') = Id then FTests.Delete(I);
J := TJSONObject.Create;
J.Add('id', Id); J.Add('status', Status); J.Add('detail', Detail);
FTests.Add(J);
WritelnLog('KaMProbe', Id + ': ' + Status + ' ' + Detail);
end;
procedure TProbeReport.Check(const Id: string; const Ok: Boolean; const Detail: string);
begin
if Ok then Add(Id, 'PASS', Detail) else Add(Id, 'FAIL', Detail);
end;
function TProbeReport.Status: string;
var I: Integer;
begin
Result := 'PASS';
for I := 0 to FTests.Count - 1 do
if FTests.Objects[I].Get('status','') = 'FAIL' then Exit('FAIL');
{ Optional NOT_RUN / OBSERVED rows do not make the automatic smoke fail.
They remain visible; PASS applies only to executed automatic checks. }
end;
procedure TProbeReport.Save(const FileName: string);
var S: TStringList;
begin
FRoot.Delete('automatic_smoke_status');
FRoot.Add('automatic_smoke_status', Status);
if not ForceDirectories(ExtractFileDir(FileName)) then
raise Exception.Create('Cannot create report directory');
S := TStringList.Create;
try
S.Text := FRoot.FormatJSON;
{ Evidence must not depend on the filesystem behaviour measured separately
by decision.persistence.rename_replace. }
S.SaveToFile(FileName);
finally S.Free; end;
end;
end.