Some checks failed
Build and Release / build-and-release (push) Has been cancelled
- Adopt standard versioning: 1.0, 1.1, 1.1-1 (major.minor-revision) - Archive naming: comet-1.1-1-linux-x64.tar.gz (professional format) - Move test sources from src/ to test/ directory - Update Makefile, release script, and CI workflow to match
283 lines
7.6 KiB
ObjectPascal
283 lines
7.6 KiB
ObjectPascal
{
|
|
test_outbound.pas - Test BSO, FrontDoor .MSG, and D'Bridge Q-file outbound
|
|
}
|
|
program test_outbound;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
uses
|
|
SysUtils, Classes, cometdef, cometpath, cometbso, cometlog;
|
|
|
|
var
|
|
TestDir: string;
|
|
OK, AllOK: Boolean;
|
|
TestCount, PassCount: Integer;
|
|
|
|
procedure Check(const Name: string; Condition: Boolean);
|
|
begin
|
|
Inc(TestCount);
|
|
if Condition then
|
|
begin
|
|
Inc(PassCount);
|
|
WriteLn(Name, ' OK');
|
|
end
|
|
else
|
|
WriteLn(Name, ' FAIL');
|
|
end;
|
|
|
|
{ ---- BSO Tests ---- }
|
|
|
|
procedure TestBSO;
|
|
var
|
|
Items: TCometOutboundItemArray;
|
|
Entries: TCometFloEntryArray;
|
|
FloPath: string;
|
|
begin
|
|
WriteLn('--- BSO ---');
|
|
|
|
{ Create outbound structure: node 1:213/723 = 00D502D3 }
|
|
ForceDirectories(TestDir + '/outbound');
|
|
|
|
{ Create a .FLO with test files }
|
|
FloPath := TestDir + '/outbound/00d502d3.flo';
|
|
with TStringList.Create do
|
|
try
|
|
Add(TestDir + '/testfile.txt');
|
|
Add('^' + TestDir + '/killfile.txt');
|
|
Add('#' + TestDir + '/truncfile.txt');
|
|
Add('~' + TestDir + '/sentfile.txt');
|
|
SaveToFile(FloPath);
|
|
finally
|
|
Free;
|
|
end;
|
|
|
|
{ Create the test files }
|
|
with TStringList.Create do
|
|
try
|
|
Add('test data');
|
|
SaveToFile(TestDir + '/testfile.txt');
|
|
SaveToFile(TestDir + '/killfile.txt');
|
|
SaveToFile(TestDir + '/truncfile.txt');
|
|
SaveToFile(TestDir + '/sentfile.txt');
|
|
finally
|
|
Free;
|
|
end;
|
|
|
|
{ Test BSOReadFlo }
|
|
Entries := BSOReadFlo(FloPath);
|
|
Check('BSO: read .FLO entries', Length(Entries) = 4);
|
|
Check('BSO: normal entry action', Entries[0].Action = csaNone);
|
|
Check('BSO: delete entry action', Entries[1].Action = csaDelete);
|
|
Check('BSO: truncate entry action', Entries[2].Action = csaTruncate);
|
|
Check('BSO: sent entry marked', Entries[3].Sent = True);
|
|
|
|
{ Test BSOScanOutbound }
|
|
Items := BSOScanOutbound(TestDir + '/outbound', 1);
|
|
Check('BSO: scan found 1 node', Length(Items) = 1);
|
|
if Length(Items) > 0 then
|
|
begin
|
|
Check('BSO: correct net', Items[0].Address.Net = $00D5);
|
|
Check('BSO: correct node', Items[0].Address.Node = $02D3);
|
|
Check('BSO: has files', Items[0].HasFiles);
|
|
end;
|
|
end;
|
|
|
|
{ ---- FrontDoor .MSG Tests ---- }
|
|
|
|
procedure WriteWord(var Buf; Offset: Integer; W: Word);
|
|
begin
|
|
PByte(@Buf)[Offset] := W and $FF;
|
|
PByte(@Buf)[Offset + 1] := (W shr 8) and $FF;
|
|
end;
|
|
|
|
procedure TestFrontDoor;
|
|
var
|
|
MsgDir: string;
|
|
F: file;
|
|
Hdr: array[0..189] of Byte;
|
|
Items: TCometOutboundItemArray;
|
|
Addr: TCometAddress;
|
|
Files: TStringList;
|
|
KillSent: Boolean;
|
|
SubjStr: string;
|
|
begin
|
|
WriteLn('--- FrontDoor ---');
|
|
|
|
MsgDir := TestDir + '/fdmsg';
|
|
ForceDirectories(MsgDir);
|
|
|
|
{ Create a test file to attach }
|
|
with TStringList.Create do
|
|
try
|
|
Add('FrontDoor test file content');
|
|
SaveToFile(TestDir + '/fdtest.txt');
|
|
finally
|
|
Free;
|
|
end;
|
|
|
|
{ Build a Type-2 .MSG with file-attach attribute (190 byte header)
|
|
Offsets: From=0(36), To=36(36), Subject=72(72), DateTime=144(20),
|
|
TimesRead=164(2), DestNode=166(2), OrigNode=168(2), Cost=170(2),
|
|
OrigNet=172(2), DestNet=174(2), DateWritten=176(4), DateArrived=180(4),
|
|
ReplyTo=184(2), Attr=186(2), NextReply=188(2) }
|
|
FillChar(Hdr, SizeOf(Hdr), 0);
|
|
StrPCopy(PChar(@Hdr[0]), 'Test Sender'); { From }
|
|
StrPCopy(PChar(@Hdr[36]), 'Test Receiver'); { To }
|
|
SubjStr := TestDir + '/fdtest.txt';
|
|
Move(SubjStr[1], Hdr[72], Length(SubjStr)); { Subject = file path }
|
|
WriteWord(Hdr, 166, 723); { DestNode }
|
|
WriteWord(Hdr, 168, 725); { OrigNode }
|
|
WriteWord(Hdr, 172, 213); { OrigNet }
|
|
WriteWord(Hdr, 174, 213); { DestNet }
|
|
WriteWord(Hdr, 186, $0090); { Attr = FileAttach+KillSent }
|
|
|
|
AssignFile(F, MsgDir + '/1.MSG');
|
|
Rewrite(F, 1);
|
|
BlockWrite(F, Hdr, SizeOf(Hdr));
|
|
CloseFile(F);
|
|
|
|
{ Test FDReadMsg }
|
|
OK := FDReadMsg(MsgDir + '/1.MSG', Addr, Files, KillSent);
|
|
Check('FD: read msg success', OK);
|
|
if OK then
|
|
begin
|
|
Check('FD: dest net', Addr.Net = 213);
|
|
Check('FD: dest node', Addr.Node = 723);
|
|
Check('FD: kill sent flag', KillSent);
|
|
Check('FD: file count', Files.Count = 1);
|
|
if Files.Count > 0 then
|
|
Check('FD: file path', Pos('fdtest.txt', Files[0]) > 0);
|
|
Files.Free;
|
|
end;
|
|
|
|
{ Test FDScanOutbound }
|
|
Items := FDScanOutbound(MsgDir);
|
|
Check('FD: scan found 1 node', Length(Items) = 1);
|
|
if Length(Items) > 0 then
|
|
begin
|
|
Check('FD: scan dest net', Items[0].Address.Net = 213);
|
|
Check('FD: scan dest node', Items[0].Address.Node = 723);
|
|
Check('FD: scan has files', Items[0].HasFiles);
|
|
end;
|
|
|
|
{ Test that non-file-attach messages are ignored }
|
|
FillChar(Hdr, SizeOf(Hdr), 0);
|
|
StrPCopy(PChar(@Hdr[0]), 'Test');
|
|
StrPCopy(PChar(@Hdr[36]), 'Test');
|
|
StrPCopy(PChar(@Hdr[72]), 'Hello');
|
|
WriteWord(Hdr, 186, $0001); { Attr = Private, NOT file attach }
|
|
WriteWord(Hdr, 174, 213); { DestNet }
|
|
WriteWord(Hdr, 166, 724); { DestNode }
|
|
|
|
AssignFile(F, MsgDir + '/2.MSG');
|
|
Rewrite(F, 1);
|
|
BlockWrite(F, Hdr, SizeOf(Hdr));
|
|
CloseFile(F);
|
|
|
|
OK := FDReadMsg(MsgDir + '/2.MSG', Addr, Files, KillSent);
|
|
Check('FD: non-attach msg skipped', not OK);
|
|
end;
|
|
|
|
{ ---- D'Bridge Q-file Tests ---- }
|
|
|
|
procedure TestDBridge;
|
|
var
|
|
QDir, QPath: string;
|
|
Items: TCometOutboundItemArray;
|
|
Entries: TCometFloEntryArray;
|
|
begin
|
|
WriteLn('--- D''Bridge ---');
|
|
|
|
QDir := TestDir + '/dbridge';
|
|
ForceDirectories(QDir);
|
|
|
|
{ Create test file }
|
|
with TStringList.Create do
|
|
try
|
|
Add('D''Bridge test file');
|
|
SaveToFile(TestDir + '/dbtest.txt');
|
|
finally
|
|
Free;
|
|
end;
|
|
|
|
{ Create a Q-file for node 1:213/723
|
|
Zone 1 = base36 "001", Net 213 = base36 "5X", Node 723 = base36 "K3"
|
|
Actually let me compute: 213 = 5*36+33 = "5X", 723 = 20*36+3 = "K3"
|
|
Zone 1 = "001", but Base36Encode pads to 3 chars }
|
|
|
|
{ Use DBridgeAddQueue to create it properly }
|
|
with TStringList.Create do
|
|
try
|
|
{ Manual Q-file: flavour T filepath filename [K] }
|
|
Add('N T ' + TestDir + '/dbtest.txt dbtest.txt');
|
|
Add('C T ' + TestDir + '/dbtest.txt dbtest.txt K');
|
|
|
|
{ Build the Q-file path the same way DBridgeAddQueue does }
|
|
QPath := QDir + '/Q-' + Base36Encode(1) + Base36Encode(213) + '.' +
|
|
Base36Encode(723);
|
|
SaveToFile(QPath);
|
|
finally
|
|
Free;
|
|
end;
|
|
|
|
WriteLn(' Q-file: ', ExtractFileName(QPath));
|
|
|
|
{ Test DBridgeReadQueue }
|
|
Entries := DBridgeReadQueue(QPath);
|
|
Check('DB: read queue entries', Length(Entries) = 2);
|
|
if Length(Entries) >= 2 then
|
|
begin
|
|
Check('DB: entry 1 normal', Entries[0].Action = csaNone);
|
|
Check('DB: entry 2 kill', Entries[1].Action = csaDelete);
|
|
Check('DB: entry 1 path', Pos('dbtest.txt', Entries[0].FilePath) > 0);
|
|
end;
|
|
|
|
{ Test DBridgeScanOutbound }
|
|
Items := DBridgeScanOutbound(QDir);
|
|
Check('DB: scan found 1 node', Length(Items) = 1);
|
|
if Length(Items) > 0 then
|
|
begin
|
|
Check('DB: scan zone', Items[0].Address.Zone = 1);
|
|
Check('DB: scan net', Items[0].Address.Net = 213);
|
|
Check('DB: scan node', Items[0].Address.Node = 723);
|
|
Check('DB: scan has files', Items[0].HasFiles);
|
|
end;
|
|
|
|
{ Test Base36 round-trip }
|
|
Check('B36: encode 1', Base36Encode(1) = '001');
|
|
Check('B36: encode 213', Base36Encode(213) = '05X');
|
|
Check('B36: decode 001', Base36Decode('001') = 1);
|
|
Check('B36: decode 05X', Base36Decode('05X') = 213);
|
|
Check('B36: round-trip 723', Base36Decode(Base36Encode(723)) = 723);
|
|
end;
|
|
|
|
{ ---- Main ---- }
|
|
|
|
begin
|
|
TestCount := 0;
|
|
PassCount := 0;
|
|
|
|
TestDir := GetTempDir + 'comet-outbound-test';
|
|
ForceDirectories(TestDir);
|
|
|
|
try
|
|
TestBSO;
|
|
TestFrontDoor;
|
|
TestDBridge;
|
|
finally
|
|
{ Cleanup }
|
|
// Leave test dir for inspection if needed
|
|
end;
|
|
|
|
WriteLn;
|
|
WriteLn(PassCount, '/', TestCount, ' tests passed.');
|
|
|
|
if PassCount = TestCount then
|
|
WriteLn('All outbound tests passed.')
|
|
else
|
|
begin
|
|
WriteLn('SOME TESTS FAILED');
|
|
Halt(1);
|
|
end;
|
|
end.
|