fullfpcinstallationtests.pas 33 KB

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