fullfpcinstallationtests.pas 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635
  1. unit FullFPCInstallationTests;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes,
  6. SysUtils,
  7. fpcunit,
  8. testdecorator,
  9. testregistry,
  10. CustApp,
  11. process,
  12. fpmkunit,
  13. pkgFppkg,
  14. fprepos;
  15. type
  16. { TFullFPCInstallationTests }
  17. TFullFPCInstallationTests = class(TTestCase)
  18. protected
  19. procedure SetUp; override;
  20. procedure TearDown; override;
  21. published
  22. procedure TestListPackages;
  23. procedure IntTestListPackages;
  24. procedure IntTestMergeGlobalOptions;
  25. procedure TestPackageA;
  26. procedure TestLooseFPMFile;
  27. procedure TestMissingSource;
  28. procedure TestBuildWithInstalledDependency;
  29. procedure TestFakePackageDir;
  30. procedure TestSourceDependency;
  31. procedure TestTransmitOptions;
  32. procedure TestPackageVariantPackage;
  33. procedure TestFPMakeCommandLikePackageVariants;
  34. end;
  35. { TFullFPCInstallationSetup }
  36. TFullFPCInstallationSetup = class(TTestSetup)
  37. private
  38. class var
  39. FFPCSourcePath: string;
  40. FTestPath: string;
  41. FPackagesPath: string;
  42. FStartCompiler: string;
  43. FTargetCPU: string;
  44. FTargetOS: string;
  45. FCompilerVersion: string;
  46. protected
  47. procedure OneTimeSetup; override;
  48. procedure OneTimeTearDown; override;
  49. public
  50. class function GetCurrentTestPath: string;
  51. class function GetTemplatePath: string;
  52. class function GetTestPath: string;
  53. class function GetBasePackagesPath: string;
  54. class function GetSpecificPackagesPath: string;
  55. class function GetCurrentTestBasePackagesPath: string;
  56. class function GetTestBinPath: string;
  57. class function GetTargetString: string;
  58. class function GetCompilerVersion: string;
  59. class function SyncPackageIntoCurrentTest(APackageName: string; SpecificPackageDir: string = ''): string;
  60. end;
  61. implementation
  62. function RunTestCommandIndir(const Curdir:string; const Exename:string; const Commands:array of string; TaskDescription: string; ExpectedExitStatus: Integer = 0):string;
  63. var
  64. CommandOutput: string;
  65. i: integer;
  66. CommandLine: string;
  67. ExitStatus: Integer;
  68. begin
  69. if RunCommandInDir(Curdir, Exename, Commands, CommandOutput, ExitStatus, [poStderrToOutPut]) <> 0 then
  70. raise Exception.CreateFmt('Failed to run ''%s''', [exename]);
  71. if ExitStatus<>ExpectedExitStatus then
  72. begin
  73. for i := 0 to length(Commands) -1 do
  74. begin
  75. CommandLine := CommandLine + ' ' + Commands[i];
  76. end;
  77. raise Exception.CreateFmt('Failed to %s.' +sLineBreak+ 'Current directory: ' +Curdir+ sLineBreak + 'command line: ' + Exename + CommandLine + sLineBreak + ' Output: ' + sLineBreak + CommandOutput, [TaskDescription]);
  78. end;
  79. result := CommandOutput;
  80. end;
  81. function RunFppkgIndir(const Curdir:string; Commands: array of string; TaskDescription: string; ExpectedExitStatus: Integer = 0):string;
  82. var
  83. i: Integer;
  84. StrArr: array of string;
  85. begin
  86. i := length(Commands);
  87. SetLength(StrArr, i + 2);
  88. StrArr[i] := '-C';
  89. StrArr[i+1] := ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'etc','fppkg.cfg']);
  90. for i := 0 to length(Commands) -1 do
  91. StrArr[i] := Commands[i];
  92. Result := RunTestCommandIndir(Curdir, TFullFPCInstallationSetup.GetTestBinPath+'fppkg', StrArr, TaskDescription, ExpectedExitStatus);
  93. end;
  94. function RunFPMakeIndir(const Curdir:string; Commands: array of string; TaskDescription: string; ExpectedExitStatus: Integer = 0):string;
  95. var
  96. i: Integer;
  97. StrArr: array of string;
  98. CompilerStr, FpcSearchpath, PackageSearchPath: string;
  99. begin
  100. // Compile the package in the ProcVersion=VersionB variant
  101. CompilerStr := ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'bin', 'fpc']);
  102. FpcSearchpath := ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion]);
  103. PackageSearchpath := TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath;
  104. i := length(Commands);
  105. SetLength(StrArr, i + 6);
  106. StrArr[i] := '--nofpccfg';
  107. StrArr[i+1] := '--compiler='+CompilerStr;
  108. StrArr[i+2] := '--searchpath='+FpcSearchpath;
  109. StrArr[i+3] := '--searchpath='+PackageSearchpath;
  110. StrArr[i+4] := '--prefix='+TFullFPCInstallationSetup.GetCurrentTestPath + 'user';
  111. StrArr[i+5] := '--baseinstalldir=' + ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion]);
  112. for i := 0 to length(Commands) -1 do
  113. StrArr[i] := Commands[i];
  114. Result := RunTestCommandIndir(Curdir, ConcatPaths([Curdir, 'fpmake']), StrArr, TaskDescription, ExpectedExitStatus);
  115. end;
  116. function DeleteDirectory(const DirectoryName: string; OnlyChildren: boolean): boolean;
  117. const
  118. //Don't follow symlinks on *nix, just delete them
  119. DeleteMask = faAnyFile {$ifdef unix} or faSymLink{%H-} {$endif unix};
  120. var
  121. FileInfo: TSearchRec;
  122. CurSrcDir: String;
  123. CurFilename: String;
  124. begin
  125. Result:=false;
  126. CurSrcDir:=IncludeTrailingPathDelimiter(DirectoryName);
  127. if FindFirst(CurSrcDir+AllFilesMask,DeleteMask,FileInfo)=0 then begin
  128. repeat
  129. // check if special file
  130. if (FileInfo.Name='.') or (FileInfo.Name='..') or (FileInfo.Name='') then
  131. continue;
  132. CurFilename:=CurSrcDir+FileInfo.Name;
  133. if ((FileInfo.Attr and faDirectory)>0)
  134. {$ifdef unix} and ((FileInfo.Attr and faSymLink{%H-})=0) {$endif unix} then begin
  135. if not DeleteDirectory(CurFilename,false) then exit;
  136. end else begin
  137. if not DeleteFile(CurFilename) then exit;
  138. end;
  139. until FindNext(FileInfo)<>0;
  140. end;
  141. FindClose(FileInfo);
  142. if (not OnlyChildren) and (not RemoveDir(CurSrcDir)) then exit;
  143. Result:=true;
  144. end;
  145. { TFullFPCInstallationSetup }
  146. procedure TFullFPCInstallationSetup.OneTimeSetup;
  147. var
  148. TemplatePath: string;
  149. LocalBasePath: string;
  150. MakeParams: array of string;
  151. begin
  152. FFPCSourcePath := CustomApplication.GetOptionValue('f','fpcsrcpath');
  153. if FFPCSourcePath<>'' then
  154. FFPCSourcePath := ExpandFileName(FFPCSourcePath);
  155. FStartCompiler := CustomApplication.GetOptionValue('s','startcompiler');
  156. FTestPath := CustomApplication.GetOptionValue('t','testpath');
  157. if FTestPath='' then
  158. FTestPath := IncludeTrailingPathDelimiter(ConcatPaths([ExtractFilePath(ParamStr(0)),'testroot']))
  159. else
  160. FTestPath := ExpandFileName(FTestPath);
  161. FPackagesPath := CustomApplication.GetOptionValue('p','packagespath');
  162. if FPackagesPath='' then
  163. FPackagesPath := IncludeTrailingPathDelimiter(ConcatPaths([ExtractFilePath(ParamStr(0)),'packages']))
  164. else
  165. FPackagesPath := ExpandFileName(FPackagesPath);
  166. if not CustomApplication.HasOption('T', 'skipbuildtemplate') then
  167. begin
  168. TemplatePath := GetTemplatePath;
  169. if DirectoryExists(GetTestPath) and not DeleteDirectory(GetTestPath, False) then
  170. raise Exception.CreateFmt('Failed to remove source-path ''%s''', [GetTestPath]);
  171. ForceDirectories(GetTemplatePath);
  172. SetLength(MakeParams, 2);
  173. MakeParams[0] := 'clean';
  174. MakeParams[1] := 'all';
  175. if FStartCompiler<>'' then
  176. begin
  177. SetLength(MakeParams, length(MakeParams)+1);
  178. MakeParams[High(MakeParams)] := 'PP='+FStartCompiler;
  179. end;
  180. RunTestCommandIndir(FFPCSourcePath, 'make', MakeParams, 'compile FPC');
  181. MakeParams[0] := 'install';
  182. MakeParams[1] := 'PREFIX='+GetTemplatePath;
  183. RunTestCommandIndir(FFPCSourcePath, 'make', MakeParams, 'install FPC');
  184. LocalBasePath := IncludeTrailingPathDelimiter(ConcatPaths([GetTemplatePath, 'user','lib','fpc']));
  185. FCompilerVersion := Trim(RunTestCommandIndir(GetTemplatePath, GetTemplatePath+'bin'+PathDelim+'fpc', ['-iV'], 'get compiler-version'));
  186. ForceDirectories(LocalBasePath+FCompilerVersion);
  187. SetLength(MakeParams, 8);
  188. MakeParams[0] := '-o';
  189. MakeParams[1] := GetTemplatePath+PathDelim+'fpc.cfg';
  190. MakeParams[2] := '-d';
  191. MakeParams[3] := 'basepath='+ConcatPaths([GetCurrentTestPath, 'lib','fpc','$fpcversion']);
  192. MakeParams[4] := '-d';
  193. MakeParams[5] := 'sharepath='+ConcatPaths([GetCurrentTestPath, 'share','fpc','$fpcversion']);
  194. MakeParams[6] := '-d';
  195. MakeParams[7] := 'localbasepath='+LocalBasePath+'$fpcversion';
  196. RunTestCommandIndir(ConcatPaths([GetTemplatePath,'bin']), 'fpcmkcfg', MakeParams, 'create fpc.cfg');
  197. SetLength(MakeParams, 12);
  198. MakeParams[1] := ConcatPaths([GetTemplatePath, 'etc', 'fppkg.cfg']);
  199. MakeParams[8] := '-3';
  200. MakeParams[9] := '-p';
  201. MakeParams[3] := 'GlobalPath='+ConcatPaths([GetCurrentTestPath, 'lib', 'fpc']);
  202. MakeParams[5] := 'GlobalPrefix='+GetCurrentTestPath;
  203. MakeParams[10] := '-d';
  204. MakeParams[11] := 'LocalRepository='+ConcatPaths([GetCurrentTestPath, 'user'])+PathDelim;
  205. RunTestCommandIndir(ConcatPaths([GetTemplatePath,'bin']), 'fpcmkcfg', MakeParams, 'create fppkg.cfg');
  206. SetLength(MakeParams, 12);
  207. MakeParams[1] := ConcatPaths([TemplatePath, 'user', 'config', 'default']);
  208. MakeParams[8] := '-4';
  209. MakeParams[9] := '-p';
  210. MakeParams[3] := 'GlobalPath='+ConcatPaths([GetCurrentTestPath, 'lib','fpc']);
  211. MakeParams[5] := 'fpcbin='+ConcatPaths([GetCurrentTestPath, 'bin','fpc']);
  212. MakeParams[10] := '-d';
  213. MakeParams[11] := 'LocalRepository='+ConcatPaths([GetCurrentTestPath, 'user'])+PathDelim;
  214. RunTestCommandIndir(ConcatPaths([TemplatePath,'bin']), 'fpcmkcfg', MakeParams, 'create default fppkg compiler file');
  215. ForceDirectories(ConcatPaths([TemplatePath, 'user','config','conf.d']));
  216. end
  217. else
  218. begin
  219. FCompilerVersion := Trim(RunTestCommandIndir(GetTemplatePath, GetTemplatePath+'bin'+PathDelim+'fpc', ['-iV'], 'get compiler-version'));
  220. end;
  221. FTargetOS := Trim(RunTestCommandIndir(GetTemplatePath, GetTemplatePath+'bin'+PathDelim+'fpc', ['-iTO'], 'get target-OS'));
  222. FTargetCPU := Trim(RunTestCommandIndir(GetTemplatePath, GetTemplatePath+'bin'+PathDelim+'fpc', ['-iTP'], 'get target-CPU'));
  223. end;
  224. procedure TFullFPCInstallationSetup.OneTimeTearDown;
  225. begin
  226. end;
  227. class function TFullFPCInstallationSetup.GetCurrentTestPath: string;
  228. begin
  229. Result := IncludeTrailingPathDelimiter(ConcatPaths([FTestPath,'currenttest']));
  230. end;
  231. class function TFullFPCInstallationSetup.GetTemplatePath: string;
  232. begin
  233. Result := IncludeTrailingPathDelimiter(ConcatPaths([FTestPath,'templates','fullfpc']));
  234. end;
  235. class function TFullFPCInstallationSetup.GetTestPath: string;
  236. begin
  237. Result := FTestPath;
  238. end;
  239. class function TFullFPCInstallationSetup.GetBasePackagesPath: string;
  240. begin
  241. Result := IncludeTrailingPathDelimiter(ConcatPaths([FPackagesPath, 'base']));
  242. end;
  243. class function TFullFPCInstallationSetup.GetSpecificPackagesPath: string;
  244. begin
  245. Result := IncludeTrailingPathDelimiter(ConcatPaths([FPackagesPath, 'specific']));
  246. end;
  247. class function TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath: string;
  248. begin
  249. Result := IncludeTrailingPathDelimiter(ConcatPaths([GetCurrentTestPath, 'packages']));
  250. end;
  251. class function TFullFPCInstallationSetup.GetTestBinPath: string;
  252. begin
  253. Result := IncludeTrailingPathDelimiter(ConcatPaths([GetCurrentTestPath,'bin']));
  254. end;
  255. class function TFullFPCInstallationSetup.GetTargetString: string;
  256. begin
  257. Result := FTargetCPU + '-' + FTargetOS;
  258. end;
  259. class function TFullFPCInstallationSetup.GetCompilerVersion: string;
  260. begin
  261. Result := FCompilerVersion;
  262. end;
  263. class function TFullFPCInstallationSetup.SyncPackageIntoCurrentTest(APackageName: string; SpecificPackageDir: string): string;
  264. var
  265. PackagePath: string;
  266. begin
  267. ForceDirectories(ConcatPaths([TFullFPCInstallationSetup.GetTestPath, 'currenttest', 'packages']));
  268. if SpecificPackageDir='' then
  269. PackagePath := TFullFPCInstallationSetup.GetBasePackagesPath+APackageName+PathDelim
  270. else
  271. PackagePath := ConcatPaths([TFullFPCInstallationSetup.GetSpecificPackagesPath, SpecificPackageDir, APackageName])+PathDelim;
  272. RunTestCommandIndir(TFullFPCInstallationSetup.GetTestPath, 'rsync', ['-rtvu', '--delete', PackagePath, TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath+APackageName], 'sync template');
  273. end;
  274. procedure TFullFPCInstallationTests.SetUp;
  275. begin
  276. RunTestCommandIndir(TFullFPCInstallationSetup.GetTestPath, 'rsync', ['-rtvu', '--delete', 'templates/fullfpc/', 'currenttest/'], 'sync template');
  277. end;
  278. procedure TFullFPCInstallationTests.TearDown;
  279. begin
  280. end;
  281. procedure TFullFPCInstallationTests.TestListPackages;
  282. var
  283. s: String;
  284. begin
  285. s := RunFppkgIndir(TFullFPCInstallationSetup.GetTestPath, ['list'], 'fppkg list');
  286. Check(pos('rtl',s) > 0, 'Package rtl not found in fppkg-package list');
  287. end;
  288. procedure TFullFPCInstallationTests.IntTestListPackages;
  289. var
  290. FPpkg: TpkgFPpkg;
  291. RTLPackage: TFPPackage;
  292. begin
  293. FPpkg := TpkgFPpkg.Create(nil);
  294. try
  295. FPpkg.InitializeGlobalOptions(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'etc','fppkg.cfg']));
  296. FPpkg.Options.GlobalSection.Downloader := 'FPC';
  297. FPpkg.InitializeCompilerOptions;
  298. FPpkg.CompilerOptions.InitCompilerDefaults;
  299. FPpkg.FpmakeCompilerOptions.InitCompilerDefaults;
  300. FPpkg.CompilerOptions.CheckCompilerValues;
  301. FPpkg.FpmakeCompilerOptions.CheckCompilerValues;
  302. FPpkg.LoadLocalAvailableMirrors;
  303. FPpkg.ScanAvailablePackages;
  304. FPpkg.ScanPackages;
  305. RTLPackage := FPpkg.RepositoryByName('fpc').FindPackage('rtl');
  306. CheckNotNull(RTLPackage, 'RTL package not found');
  307. CheckEquals('3.1.1', RTLPackage.Version.AsString, 'RTL has not the same version as the compiler');
  308. finally
  309. FPpkg.Free;
  310. end;
  311. end;
  312. procedure TFullFPCInstallationTests.IntTestMergeGlobalOptions;
  313. var
  314. FPpkg: TpkgFPpkg;
  315. ExtraConfFile: Text;
  316. s: string;
  317. begin
  318. // When there are multiple global-sections, it's values should be merged.
  319. s := ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'config', 'conf.d', 'extrasettings.conf']);
  320. AssignFile(ExtraConfFile, ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'config', 'conf.d', 'extrasettings.conf']));
  321. Rewrite(ExtraConfFile);
  322. WriteLn(ExtraConfFile, '[global]');
  323. WriteLn(ExtraConfFile, 'FPMakeOptions="-T 4"');
  324. CloseFile(ExtraConfFile);
  325. FPpkg := TpkgFPpkg.Create(nil);
  326. try
  327. FPpkg.InitializeGlobalOptions(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'etc','fppkg.cfg']));
  328. FPpkg.Options.GlobalSection.Downloader := 'FPC';
  329. FPpkg.InitializeCompilerOptions;
  330. FPpkg.CompilerOptions.InitCompilerDefaults;
  331. FPpkg.FpmakeCompilerOptions.InitCompilerDefaults;
  332. FPpkg.CompilerOptions.CheckCompilerValues;
  333. FPpkg.FpmakeCompilerOptions.CheckCompilerValues;
  334. FPpkg.LoadLocalAvailableMirrors;
  335. CheckEquals('user', FPpkg.Options.GlobalSection.InstallRepository, 'The InstallRepository does not match the value in the original configuration file');
  336. CheckEquals('"-T 4"', FPpkg.Options.GlobalSection.CustomFPMakeOptions, 'The custom FPMakeOptions do not match the value in the extra configuration file');
  337. finally
  338. FPpkg.Free;
  339. end;
  340. end;
  341. procedure TFullFPCInstallationTests.TestPackageA;
  342. var
  343. s: String;
  344. begin
  345. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagea');
  346. // Build and install package
  347. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['build'], 'build PackageA');
  348. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['install'], 'install PackageA');
  349. // Test installation
  350. s := RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestPath, ['list'], 'list packages');
  351. Check(pos('packagea', s) > 0, 'Just installed PackageA is not in package-list');
  352. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'user','lib','fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea','PackageAUnitA.ppu'])), 'PackageAUnitA.ppu not found');
  353. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'user','lib','fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea','PackageAUnitA.o'])), 'PackageAUnitA.o not found');
  354. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'user','lib','fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'fpmkinst',TFullFPCInstallationSetup.GetTargetString,'packagea.fpm'])), 'PackageAUnitA.fpm not found');
  355. // uninstall package
  356. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['uninstall'], 'install PackageA');
  357. // check uninstallation
  358. s := RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestPath, ['list'], 'list packages');
  359. Check(pos('packagea', s) = 0, 'Just de-installed PackageA is still in package-list');
  360. CheckFalse(DirectoryExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'user','lib','fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea'])), 'PackageAUnitA-directory found after uninstall');
  361. CheckFalse(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'user','lib','fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'fpmkinst',TFullFPCInstallationSetup.GetTargetString,'packagea.fpm'])), 'PackageAUnitA.fpm found after uninstall');
  362. end;
  363. procedure TFullFPCInstallationTests.TestLooseFPMFile;
  364. var
  365. F: Text;
  366. s: string;
  367. begin
  368. System.Assign(F, ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'fpmkinst', TFullFPCInstallationSetup.GetTargetString,'empty.fpm']));
  369. System.Rewrite(F);
  370. System.Close(F);
  371. s := RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestPath, ['list'], 'list packages');
  372. Check(pos('Failed to load package "empty"', s) > 0, 'Missing warning that the invalid package is skipped')
  373. end;
  374. procedure TFullFPCInstallationTests.TestMissingSource;
  375. var
  376. s: String;
  377. begin
  378. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagea');
  379. // Build and install package
  380. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['build'], 'build PackageA');
  381. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['install'], 'install PackageA');
  382. // Destroy the installation
  383. DeleteFile(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'user','lib','fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea','PackageAUnitA.ppu']));
  384. // Re-install
  385. RunFppkgIndir(TFullFPCInstallationSetup.GetTestPath, ['install', 'packagea'], 're-install PackageA');
  386. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'user','lib','fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea','PackageAUnitA.ppu'])), 'PackageAUnitA.ppu not found after re-install');
  387. // Remove the original sources
  388. DeleteDirectory(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', False);
  389. s := RunFppkgIndir(TFullFPCInstallationSetup.GetTestPath, ['install', 'packagea'], 'Re-install PackageA without source', 1);
  390. Check(pos('Source of package packagea is not available', s) > 0, 'Missing warning that the package-source is unavailable. Fppkg-output: ' + s)
  391. end;
  392. procedure TFullFPCInstallationTests.TestBuildWithInstalledDependency;
  393. var
  394. s: String;
  395. begin
  396. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagea');
  397. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packageb');
  398. // Build and install package
  399. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['install'], 'install PackageA');
  400. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packageb', ['install'], 'install PackageB using the installed dependency PackageA');
  401. // Test installation
  402. s := RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestPath, ['list'], 'list packages');
  403. Check(pos('packagea', s) > 0, 'Just installed PackageA is not in package-list');
  404. Check(pos('PackageB', s) > 0, 'Just installed PackageB is not in package-list');
  405. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'user','lib','fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea','PackageAUnitA.ppu'])), 'PackageAUnitA.ppu not found');
  406. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'user','lib','fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'PackageB','PackageBUnitB.ppu'])), 'PackageBUnitB.ppu not found');
  407. end;
  408. procedure TFullFPCInstallationTests.TestFakePackageDir;
  409. var
  410. s: String;
  411. begin
  412. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagea');
  413. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packageb');
  414. // Build and install package
  415. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['install', '-i', 'fpc'], 'install PackageA');
  416. ForceDirectories(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units', TFullFPCInstallationSetup.GetTargetString, 'PackageA']));
  417. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packageb', ['install'], 'install PackageB using the installed dependency PackageA');
  418. // Test installation
  419. s := RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestPath, ['list'], 'list packages');
  420. Check(pos('packagea', s) > 0, 'Just installed PackageA is not in package-list');
  421. Check(pos('PackageB', s) > 0, 'Just installed PackageB is not in package-list');
  422. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'lib','fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea','PackageAUnitA.ppu'])), 'PackageAUnitA.ppu not found');
  423. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'user','lib','fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'PackageB','PackageBUnitB.ppu'])), 'PackageBUnitB.ppu not found');
  424. end;
  425. procedure TFullFPCInstallationTests.TestSourceDependency;
  426. var
  427. s: String;
  428. begin
  429. // This is to test if fpmkunit works correctly when a dependency is available
  430. // not as an installed but as a (compiled) source-package. This happens for
  431. // example if you try to compile _one_ fpmake-packages in fpcsrc/packages,
  432. // using 'make clean all' and it needs one of the other packages in
  433. // fpcsrc/packages.
  434. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagea');
  435. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packageb');
  436. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['build'], 'build PackageA');
  437. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packageb', ['build'], 'create fpmake-executable', 1);
  438. RunFPMakeIndir(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath,'packageb']), ['build'], 'build packageb');
  439. // When there is no .fpm file, fpmake should complain that the package is not
  440. // compiled. (Another possibility is that another packages is mistakenly being
  441. // used, for example when the package-name does not match the directory-name)
  442. // This has to be enforced because without the .fpm, the dependencies are
  443. // not handled.
  444. s := ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath,'packagea','packagea-'+TFullFPCInstallationSetup.GetTargetString+'.fpm']);
  445. DeleteFile(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath,'packagea','packagea-'+TFullFPCInstallationSetup.GetTargetString+'.fpm']));
  446. s := RunFPMakeIndir(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath,'packageb']), ['build', '-d'], 'build packageb without fpm', 1);
  447. Check(pos('the package is not compiled', s) > 0, 'Missing .fpm-file detection did not trigger');
  448. Check(pos('Could not find unit directory for dependency package', s) > 0, 'Incorrect error message');
  449. end;
  450. procedure TFullFPCInstallationTests.TestTransmitOptions;
  451. begin
  452. // Test the TransmitOptions settings. PackageA contain some TransmitOptions,
  453. // without which the other packages won't compile.
  454. // PackageC depends on both PackageB's, but should only add the TransmitOptions
  455. // from PackageA once.
  456. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagea', 'transmitoptions');
  457. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packageb1', 'transmitoptions');
  458. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packageb2', 'transmitoptions');
  459. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagec', 'transmitoptions');
  460. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['install'], 'build PackageA');
  461. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packageb1', ['install'], 'build PackageB1');
  462. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packageb2', ['install'], 'build PackageB2');
  463. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagec', ['install'], 'build PackageC');
  464. end;
  465. procedure TFullFPCInstallationTests.TestPackageVariantPackage;
  466. var
  467. s: String;
  468. begin
  469. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagevarianta');
  470. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagevariantp');
  471. // Compile the packages with their default variant
  472. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagevarianta', ['install'], 'install PackageVariantA');
  473. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagevariantp', ['install'], 'install PackageVariantP');
  474. // Check the usage of the versiona-subdirectory
  475. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units', TFullFPCInstallationSetup.GetTargetString, 'packagevarianta', 'versiona', 'packagevariantbaseunit.ppu'])), 'packagevariantbaseunit.ppu not found');
  476. // Check the output of the generated executable
  477. s := RunTestCommandIndir(TFullFPCInstallationSetup.GetCurrentTestPath, ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'bin', 'packagevariantp']), [], 'Run PackageVariantP');
  478. Check(pos('Hello version A', s) > 0, 'Package is not compiled with Version-A unit');
  479. RunFPMakeIndir(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath,'packagevarianta']), ['build', '+ProcVersion=versionb'], 'build PackageVariantA in the VersionB variant');
  480. RunFPMakeIndir(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath,'packagevariantp']), ['build', '+ProcVersion=versionb'], 'build PackageVariantP in the VersionB variant');
  481. // Check the usage of the versiona- & versionb-subdirectory
  482. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath, 'packagevarianta', 'units', TFullFPCInstallationSetup.GetTargetString, 'versiona', 'packagevariantbaseunit.ppu'])), 'packagevariantbaseunit.ppu versiona not found');
  483. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath, 'packagevarianta', 'units', TFullFPCInstallationSetup.GetTargetString, 'versionb', 'packagevariantbaseunit.ppu'])), 'packagevariantbaseunit.ppu versionb not found');
  484. // Check the output of the generated executable
  485. s := RunTestCommandIndir(TFullFPCInstallationSetup.GetCurrentTestPath, ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath, 'packagevariantp', 'bin', TFullFPCInstallationSetup.GetTargetString, 'packagevariantp']), [], 'Run PackageVariantP');
  486. Check(pos('Bye version B', s) > 0, 'Package is not compiled with Version-B unit');
  487. Check(pos('Now with extra unit!', s) > 0, 'Package is not compiled with extra Version-B unit');
  488. // Compile PackageVariantP again, but now with VersionA
  489. RunFPMakeIndir(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath,'packagevariantp']), ['build', '+ProcVersion=versiona'], 'build PackageVariantP in the VersionA variant');
  490. // Check the output of the generated executable
  491. s := RunTestCommandIndir(TFullFPCInstallationSetup.GetCurrentTestPath, ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath, 'packagevariantp', 'bin', TFullFPCInstallationSetup.GetTargetString, 'packagevariantp']), [], 'Run PackageVariantP');
  492. Check(pos('Hello version A', s) > 0, 'Package is not compiled with Version-A unit');
  493. end;
  494. procedure TFullFPCInstallationTests.TestFPMakeCommandLikePackageVariants;
  495. var
  496. s: String;
  497. begin
  498. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagea');
  499. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packageb');
  500. // Build packagea so that fpmake is compiled
  501. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['build'], 'build PackageA with fppkg');
  502. // Test some invalid command-line arguments
  503. s := RunFPMakeIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath+ 'packagea', ['build', '+buildvariant'], 'Test with invalid +buildvariant command line option', 1);
  504. Check(pos('needs an argument', s) > 0, 'FPMake did not check for the argument');
  505. s := RunFPMakeIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath+ 'packagea', ['build', '+buildvariant+'], 'Test with invalid +buildvariant+ command line option', 1);
  506. Check(pos('needs an argument', s) > 0, 'FPMake did not check for the argument +');
  507. s := RunFPMakeIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath+ 'packagea', ['build', '+buildvariant+='], 'Test with empty +buildvariant+ value', 1);
  508. Check(pos('should have at least one item', s) > 0, 'FPMake did not check for an empty argument');
  509. // Build PackageA with BuildVariants
  510. RunFPMakeIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath+ 'packagea', ['build', '+buildvariant+=debug,release', '--options_buildvariant_debug=-gl', '--options_buildvariant_release="-g- -CX -XX -O2"'], 'Build debug variant');
  511. // Build the release-variant
  512. RunFPMakeIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath+ 'packagea', ['build', '+buildvariant+=debug,release', '--options_buildvariant_debug=-gl', '--options_buildvariant_release="-g- -CX -XX -O2"', '+buildvariant=release'], 'Build release variant');
  513. // Check the usage of the debug- & release-subdirectory
  514. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath, 'packagea', 'units', TFullFPCInstallationSetup.GetTargetString, 'debug', 'PackageAUnitA.ppu'])), 'PackageAUnitA.ppu debug-version not found');
  515. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath, 'packagea', 'units', TFullFPCInstallationSetup.GetTargetString, 'release', 'PackageAUnitA.ppu'])), 'PackageAUnitA.ppu release-version not found');
  516. // Install PackageA with BuildVariants
  517. RunFPMakeIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath+ 'packagea', ['install', '+buildvariant+=debug,release', '--options_buildvariant_debug=-gl', '--options_buildvariant_release="-g- -CX -XX -O2"'], 'Build debug variant');
  518. // Install the release-variant
  519. RunFPMakeIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath+ 'packagea', ['install', '+buildvariant+=debug,release', '--options_buildvariant_debug=-gl', '--options_buildvariant_release="-g- -CX -XX -O2"', '+buildvariant=release'], 'Build release variant');
  520. // Check the usage of the debug-subdirectory
  521. s := ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units', TFullFPCInstallationSetup.GetTargetString, 'packagea', 'debug', 'PackageAUnitA.ppu']);
  522. Check(FileExists(s), 'installed PackageAUnitA.ppu debug-version not found');
  523. // Check that the debug-version has debug-information
  524. s := RunTestCommandIndir(TFullFPCInstallationSetup.GetCurrentTestPath, TFullFPCInstallationSetup.GetCurrentTestPath+'bin'+PathDelim+'ppudump', s, 'Dump the ppu-information of the debug unit');
  525. Check(pos('has_debug_info', s) > 0, 'The debug-unit does not have debug-info');
  526. // Check the usage of the release-subdirectory
  527. s := ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units', TFullFPCInstallationSetup.GetTargetString, 'packagea', 'release', 'PackageAUnitA.ppu']);
  528. Check(FileExists(s), 'installed PackageAUnitA.ppu release-version not found');
  529. // Check that the debug-version has debug-information
  530. s := RunTestCommandIndir(TFullFPCInstallationSetup.GetCurrentTestPath, TFullFPCInstallationSetup.GetCurrentTestPath+'bin'+PathDelim+'ppudump', s, 'Dump the ppu-information of the release unit');
  531. Check(pos('has_debug_info', s) = 0, 'The release-unit has debug-info');
  532. // Build packageb, use the default variant (debug)
  533. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packageb', ['build'], 'build PackageB with fppkg');
  534. end;
  535. Initialization
  536. RegisterTestDecorator(TFullFPCInstallationSetup, TFullFPCInstallationTests);
  537. end.