fullfpcinstallationtests.pas 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032
  1. unit FullFPCInstallationTests;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes,
  6. SysUtils,
  7. fpcunit,
  8. IniFiles,
  9. testdecorator,
  10. testregistry,
  11. CustApp,
  12. process,
  13. fpmkunit,
  14. pkgFppkg,
  15. fprepos;
  16. type
  17. { TFullFPCInstallationTests }
  18. TFullFPCInstallationTests = class(TTestCase)
  19. protected
  20. procedure SetUp; override;
  21. procedure TearDown; override;
  22. procedure AlterChecksumOfPackageFPM(FPMFileName: string);
  23. procedure AlterChecksumOfDependencyInFPM(FPMFileName: string);
  24. procedure CheckBrokenPackages(ExpectBrokenPackages: Boolean);
  25. published
  26. procedure TestListPackages;
  27. procedure IntTestListPackages;
  28. procedure IntTestMergeGlobalOptions;
  29. procedure TestPackageA;
  30. procedure TestLooseFPMFile;
  31. procedure TestMissingSource;
  32. procedure TestBuildWithInstalledDependency;
  33. procedure TestFakePackageDir;
  34. procedure TestSourceDependency;
  35. procedure TestTransmitOptions;
  36. procedure TestPackageVariantPackage;
  37. procedure TestFPMakeCommandLikePackageVariants;
  38. procedure TestFpmakePluginDependencies;
  39. procedure TestCleanupOfTemporaryBuildpath;
  40. procedure TestDefaultInstallLocation;
  41. procedure TestSourceRepositoryInstallLocation;
  42. procedure TestConfiguredInstallLocation;
  43. procedure TestInstallationLocationOriginalSource;
  44. procedure TestUninstalledRepository;
  45. procedure TestBrokenPackagesBetweenRepos;
  46. procedure TestPackageDependenciesBetweenRepos;
  47. procedure TestBuildOfArchiveFile;
  48. end;
  49. { TFullFPCInstallationSetup }
  50. TFullFPCInstallationSetup = class(TTestSetup)
  51. private
  52. class var
  53. FFPCSourcePath: string;
  54. FTestPath: string;
  55. FPackagesPath: string;
  56. FStartCompiler: string;
  57. FTargetCPU: string;
  58. FTargetOS: string;
  59. FCompilerVersion: string;
  60. protected
  61. procedure OneTimeSetup; override;
  62. procedure OneTimeTearDown; override;
  63. public
  64. class function GetCurrentTestPath: string;
  65. class function GetTemplatePath: string;
  66. class function GetTestPath: string;
  67. class function GetBasePackagesPath: string;
  68. class function GetSpecificPackagesPath: string;
  69. class function GetCurrentTestBasePackagesPath: string;
  70. class function GetTestBinPath: string;
  71. class function GetTargetString: string;
  72. class function GetCompilerVersion: string;
  73. class function SyncPackageIntoCurrentTest(APackageName: string; SpecificPackageDir: string = ''): string;
  74. end;
  75. implementation
  76. function RunTestCommandIndir(const Curdir:string; const Exename:string; const Commands:array of string; TaskDescription: string; ExpectedExitStatus: Integer = 0):string;
  77. var
  78. CommandOutput: string;
  79. i: integer;
  80. CommandLine: string;
  81. ExitStatus: Integer;
  82. begin
  83. if RunCommandInDir(Curdir, Exename, Commands, CommandOutput, ExitStatus, [poStderrToOutPut]) <> 0 then
  84. raise Exception.CreateFmt('Failed to run ''%s''', [exename]);
  85. if ExitStatus<>ExpectedExitStatus then
  86. begin
  87. for i := 0 to length(Commands) -1 do
  88. begin
  89. CommandLine := CommandLine + ' ' + Commands[i];
  90. end;
  91. raise Exception.CreateFmt('Failed to %s.' +sLineBreak+ 'Current directory: ' +Curdir+ sLineBreak + 'command line: ' + Exename + CommandLine + sLineBreak + ' Output: ' + sLineBreak + CommandOutput, [TaskDescription]);
  92. end;
  93. result := CommandOutput;
  94. end;
  95. function RunFppkgIndir(const Curdir:string; Commands: array of string; TaskDescription: string; ExpectedExitStatus: Integer = 0):string;
  96. var
  97. i: Integer;
  98. StrArr: array of string;
  99. begin
  100. i := length(Commands);
  101. SetLength(StrArr, i + 2);
  102. StrArr[i] := '-C';
  103. StrArr[i+1] := ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'etc','fppkg.cfg']);
  104. for i := 0 to length(Commands) -1 do
  105. StrArr[i] := Commands[i];
  106. Result := RunTestCommandIndir(Curdir, TFullFPCInstallationSetup.GetTestBinPath+'fppkg', StrArr, TaskDescription, ExpectedExitStatus);
  107. end;
  108. function RunFPMakeIndir(const Curdir:string; Commands: array of string; TaskDescription: string; ExpectedExitStatus: Integer = 0):string;
  109. var
  110. i: Integer;
  111. StrArr: array of string;
  112. CompilerStr, FpcSearchpath, PackageSearchPath: string;
  113. begin
  114. // Compile the package in the ProcVersion=VersionB variant
  115. CompilerStr := ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'bin', 'fpc']);
  116. FpcSearchpath := ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion]);
  117. PackageSearchpath := TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath;
  118. i := length(Commands);
  119. SetLength(StrArr, i + 6);
  120. StrArr[i] := '--nofpccfg';
  121. StrArr[i+1] := '--compiler='+CompilerStr;
  122. StrArr[i+2] := '--searchpath='+FpcSearchpath;
  123. StrArr[i+3] := '--searchpath='+PackageSearchpath;
  124. StrArr[i+4] := '--prefix='+TFullFPCInstallationSetup.GetCurrentTestPath + 'user';
  125. StrArr[i+5] := '--baseinstalldir=' + ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion]);
  126. for i := 0 to length(Commands) -1 do
  127. StrArr[i] := Commands[i];
  128. Result := RunTestCommandIndir(Curdir, ConcatPaths([Curdir, 'fpmake']), StrArr, TaskDescription, ExpectedExitStatus);
  129. end;
  130. function DeleteDirectory(const DirectoryName: string; OnlyChildren: boolean): boolean;
  131. const
  132. //Don't follow symlinks on *nix, just delete them
  133. DeleteMask = faAnyFile {$ifdef unix} or faSymLink{%H-} {$endif unix};
  134. var
  135. FileInfo: TSearchRec;
  136. CurSrcDir: String;
  137. CurFilename: String;
  138. begin
  139. Result:=false;
  140. CurSrcDir:=IncludeTrailingPathDelimiter(DirectoryName);
  141. if FindFirst(CurSrcDir+AllFilesMask,DeleteMask,FileInfo)=0 then begin
  142. repeat
  143. // check if special file
  144. if (FileInfo.Name='.') or (FileInfo.Name='..') or (FileInfo.Name='') then
  145. continue;
  146. CurFilename:=CurSrcDir+FileInfo.Name;
  147. if ((FileInfo.Attr and faDirectory)>0)
  148. {$ifdef unix} and ((FileInfo.Attr and faSymLink{%H-})=0) {$endif unix} then begin
  149. if not DeleteDirectory(CurFilename,false) then exit;
  150. end else begin
  151. if not DeleteFile(CurFilename) then exit;
  152. end;
  153. until FindNext(FileInfo)<>0;
  154. end;
  155. FindClose(FileInfo);
  156. if (not OnlyChildren) and (not RemoveDir(CurSrcDir)) then exit;
  157. Result:=true;
  158. end;
  159. { TFullFPCInstallationSetup }
  160. procedure TFullFPCInstallationSetup.OneTimeSetup;
  161. var
  162. TemplatePath: string;
  163. LocalBasePath: string;
  164. MakeParams: array of string;
  165. begin
  166. FFPCSourcePath := CustomApplication.GetOptionValue('f','fpcsrcpath');
  167. if FFPCSourcePath<>'' then
  168. FFPCSourcePath := ExpandFileName(FFPCSourcePath);
  169. FStartCompiler := CustomApplication.GetOptionValue('s','startcompiler');
  170. FTestPath := CustomApplication.GetOptionValue('t','testpath');
  171. if FTestPath='' then
  172. FTestPath := IncludeTrailingPathDelimiter(ConcatPaths([ExtractFilePath(ParamStr(0)),'testroot']))
  173. else
  174. FTestPath := ExpandFileName(FTestPath);
  175. FPackagesPath := CustomApplication.GetOptionValue('p','packagespath');
  176. if FPackagesPath='' then
  177. FPackagesPath := IncludeTrailingPathDelimiter(ConcatPaths([ExtractFilePath(ParamStr(0)),'packages']))
  178. else
  179. FPackagesPath := ExpandFileName(FPackagesPath);
  180. if not CustomApplication.HasOption('T', 'skipbuildtemplate') then
  181. begin
  182. TemplatePath := GetTemplatePath;
  183. if DirectoryExists(GetTestPath) and not DeleteDirectory(GetTestPath, False) then
  184. raise Exception.CreateFmt('Failed to remove source-path ''%s''', [GetTestPath]);
  185. ForceDirectories(GetTemplatePath);
  186. SetLength(MakeParams, 2);
  187. MakeParams[0] := 'clean';
  188. MakeParams[1] := 'all';
  189. if FStartCompiler<>'' then
  190. begin
  191. SetLength(MakeParams, length(MakeParams)+1);
  192. MakeParams[High(MakeParams)] := 'PP='+FStartCompiler;
  193. end;
  194. RunTestCommandIndir(FFPCSourcePath, 'make', MakeParams, 'compile FPC');
  195. MakeParams[0] := 'install';
  196. MakeParams[1] := 'PREFIX='+GetTemplatePath;
  197. RunTestCommandIndir(FFPCSourcePath, 'make', MakeParams, 'install FPC');
  198. LocalBasePath := IncludeTrailingPathDelimiter(ConcatPaths([GetTemplatePath, 'user','lib','fpc']));
  199. FCompilerVersion := Trim(RunTestCommandIndir(GetTemplatePath, GetTemplatePath+'bin'+PathDelim+'fpc', ['-iV'], 'get compiler-version'));
  200. ForceDirectories(LocalBasePath+FCompilerVersion);
  201. SetLength(MakeParams, 8);
  202. MakeParams[0] := '-o';
  203. MakeParams[1] := GetTemplatePath+PathDelim+'fpc.cfg';
  204. MakeParams[2] := '-d';
  205. MakeParams[3] := 'basepath='+ConcatPaths([GetCurrentTestPath, 'lib','fpc','$fpcversion']);
  206. MakeParams[4] := '-d';
  207. MakeParams[5] := 'sharepath='+ConcatPaths([GetCurrentTestPath, 'share','fpc','$fpcversion']);
  208. MakeParams[6] := '-d';
  209. MakeParams[7] := 'localbasepath='+LocalBasePath+'$fpcversion';
  210. RunTestCommandIndir(ConcatPaths([GetTemplatePath,'bin']), 'fpcmkcfg', MakeParams, 'create fpc.cfg');
  211. SetLength(MakeParams, 12);
  212. MakeParams[1] := ConcatPaths([GetTemplatePath, 'etc', 'fppkg.cfg']);
  213. MakeParams[8] := '-3';
  214. MakeParams[9] := '-p';
  215. MakeParams[3] := 'GlobalPath='+ConcatPaths([GetCurrentTestPath, 'lib', 'fpc']);
  216. MakeParams[5] := 'GlobalPrefix='+GetCurrentTestPath;
  217. MakeParams[10] := '-d';
  218. MakeParams[11] := 'LocalRepository='+ConcatPaths([GetCurrentTestPath, 'user'])+PathDelim;
  219. RunTestCommandIndir(ConcatPaths([GetTemplatePath,'bin']), 'fpcmkcfg', MakeParams, 'create fppkg.cfg');
  220. SetLength(MakeParams, 12);
  221. MakeParams[1] := ConcatPaths([TemplatePath, 'user', 'config', 'default']);
  222. MakeParams[8] := '-4';
  223. MakeParams[9] := '-p';
  224. MakeParams[3] := 'GlobalPath='+ConcatPaths([GetCurrentTestPath, 'lib','fpc']);
  225. MakeParams[5] := 'fpcbin='+ConcatPaths([GetCurrentTestPath, 'bin','fpc']);
  226. MakeParams[10] := '-d';
  227. MakeParams[11] := 'LocalRepository='+ConcatPaths([GetCurrentTestPath, 'user'])+PathDelim;
  228. RunTestCommandIndir(ConcatPaths([TemplatePath,'bin']), 'fpcmkcfg', MakeParams, 'create default fppkg compiler file');
  229. ForceDirectories(ConcatPaths([TemplatePath, 'user','config','conf.d']));
  230. end
  231. else
  232. begin
  233. FCompilerVersion := Trim(RunTestCommandIndir(GetTemplatePath, GetTemplatePath+'bin'+PathDelim+'fpc', ['-iV'], 'get compiler-version'));
  234. end;
  235. FTargetOS := Trim(RunTestCommandIndir(GetTemplatePath, GetTemplatePath+'bin'+PathDelim+'fpc', ['-iTO'], 'get target-OS'));
  236. FTargetCPU := Trim(RunTestCommandIndir(GetTemplatePath, GetTemplatePath+'bin'+PathDelim+'fpc', ['-iTP'], 'get target-CPU'));
  237. end;
  238. procedure TFullFPCInstallationSetup.OneTimeTearDown;
  239. begin
  240. end;
  241. class function TFullFPCInstallationSetup.GetCurrentTestPath: string;
  242. begin
  243. Result := IncludeTrailingPathDelimiter(ConcatPaths([FTestPath,'currenttest']));
  244. end;
  245. class function TFullFPCInstallationSetup.GetTemplatePath: string;
  246. begin
  247. Result := IncludeTrailingPathDelimiter(ConcatPaths([FTestPath,'templates','fullfpc']));
  248. end;
  249. class function TFullFPCInstallationSetup.GetTestPath: string;
  250. begin
  251. Result := FTestPath;
  252. end;
  253. class function TFullFPCInstallationSetup.GetBasePackagesPath: string;
  254. begin
  255. Result := IncludeTrailingPathDelimiter(ConcatPaths([FPackagesPath, 'base']));
  256. end;
  257. class function TFullFPCInstallationSetup.GetSpecificPackagesPath: string;
  258. begin
  259. Result := IncludeTrailingPathDelimiter(ConcatPaths([FPackagesPath, 'specific']));
  260. end;
  261. class function TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath: string;
  262. begin
  263. Result := IncludeTrailingPathDelimiter(ConcatPaths([GetCurrentTestPath, 'packages']));
  264. end;
  265. class function TFullFPCInstallationSetup.GetTestBinPath: string;
  266. begin
  267. Result := IncludeTrailingPathDelimiter(ConcatPaths([GetCurrentTestPath,'bin']));
  268. end;
  269. class function TFullFPCInstallationSetup.GetTargetString: string;
  270. begin
  271. Result := FTargetCPU + '-' + FTargetOS;
  272. end;
  273. class function TFullFPCInstallationSetup.GetCompilerVersion: string;
  274. begin
  275. Result := FCompilerVersion;
  276. end;
  277. class function TFullFPCInstallationSetup.SyncPackageIntoCurrentTest(APackageName: string; SpecificPackageDir: string): string;
  278. var
  279. PackagePath: string;
  280. begin
  281. ForceDirectories(ConcatPaths([TFullFPCInstallationSetup.GetTestPath, 'currenttest', 'packages']));
  282. if SpecificPackageDir='' then
  283. PackagePath := TFullFPCInstallationSetup.GetBasePackagesPath+APackageName+PathDelim
  284. else
  285. PackagePath := ConcatPaths([TFullFPCInstallationSetup.GetSpecificPackagesPath, SpecificPackageDir, APackageName])+PathDelim;
  286. RunTestCommandIndir(TFullFPCInstallationSetup.GetTestPath, 'rsync', ['-rtvu', '--delete', PackagePath, TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath+APackageName], 'sync template');
  287. end;
  288. procedure TFullFPCInstallationTests.SetUp;
  289. begin
  290. RunTestCommandIndir(TFullFPCInstallationSetup.GetTestPath, 'rsync', ['-rtv', '--delete', 'templates/fullfpc/', 'currenttest/'], 'sync template');
  291. end;
  292. procedure TFullFPCInstallationTests.TearDown;
  293. begin
  294. end;
  295. procedure TFullFPCInstallationTests.AlterChecksumOfPackageFPM(FPMFileName: string);
  296. var
  297. SL: TStringList;
  298. Checksum: Int64;
  299. begin
  300. // Break packageb on purpose, by changing the checksum of packagea
  301. SL := TStringList.Create;
  302. try
  303. SL.LoadFromFile(FPMFilename);
  304. Checksum := StrToInt64Def(SL.Values['Checksum'], -1);
  305. Check(Checksum>-1, 'Determine checksum package');
  306. SL.Values['Checksum'] := IntToStr(Checksum+1);
  307. SL.SaveToFile(FPMFilename);
  308. finally
  309. SL.Free;
  310. end;
  311. end;
  312. procedure TFullFPCInstallationTests.AlterChecksumOfDependencyInFPM(FPMFileName: string);
  313. var
  314. SL: TStringList;
  315. Dependencies: string;
  316. begin
  317. // Break packageb on purpose, by changing the checksum of packagea
  318. SL := TStringList.Create;
  319. try
  320. SL.LoadFromFile(FPMFilename);
  321. Dependencies := SL.Values['Depends'];
  322. SL.Values['Depends'] := copy(Dependencies, 1, length(Dependencies)-2);
  323. SL.SaveToFile(FPMFilename);
  324. finally
  325. SL.Free;
  326. end;
  327. end;
  328. procedure TFullFPCInstallationTests.CheckBrokenPackages(ExpectBrokenPackages: Boolean);
  329. var
  330. SL: TStringList;
  331. FPpkg: TpkgFPpkg;
  332. begin
  333. FPpkg := TpkgFPpkg.Create(nil);
  334. try
  335. FPpkg.InitializeGlobalOptions(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'etc','fppkg.cfg']));
  336. FPpkg.Options.GlobalSection.Downloader := 'FPC';
  337. FPpkg.InitializeCompilerOptions;
  338. FPpkg.CompilerOptions.InitCompilerDefaults;
  339. FPpkg.FpmakeCompilerOptions.InitCompilerDefaults;
  340. FPpkg.CompilerOptions.CheckCompilerValues;
  341. FPpkg.FpmakeCompilerOptions.CheckCompilerValues;
  342. FPpkg.LoadLocalAvailableMirrors;
  343. FPpkg.ScanAvailablePackages;
  344. FPpkg.ScanPackages;
  345. SL := TStringList.Create;
  346. try
  347. FPpkg.FindBrokenPackages(SL);
  348. if ExpectBrokenPackages then
  349. check(SL.Count>0, 'There should be broken packages')
  350. else
  351. check(SL.Count=0, 'There should not be any broken packages');
  352. finally
  353. SL.Free;
  354. end;
  355. finally
  356. FPpkg.Free;
  357. end;
  358. end;
  359. procedure TFullFPCInstallationTests.TestFpmakePluginDependencies;
  360. begin
  361. // A fpmake-plugin could have it's own dependencies. These dependencies have
  362. // to be installed, and it's path must be used to compile the fpmake-executable.
  363. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packageusingplugin', 'plugindependencies');
  364. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('plugindependency', 'plugindependencies');
  365. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('pluginpackage', 'plugindependencies');
  366. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'plugindependency', ['install'], 'Install dependency');
  367. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'pluginpackage', ['install'], 'Install plugin');
  368. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packageusingplugin', ['install'], 'Install package that depends on plugin');
  369. end;
  370. procedure TFullFPCInstallationTests.TestInstallationLocationOriginalSource;
  371. var
  372. S: string;
  373. begin
  374. // Test whether a once installed package on a re-install is installed into the
  375. // right (original) location.
  376. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagea');
  377. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packageb');
  378. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['install'], 'Install package A');
  379. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packageb', ['install'], 'Install package B');
  380. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packageb', ['install', '-i', 'fpc'], 'Install package B');
  381. CheckBrokenPackages(False);
  382. // Break packageb on purpose, by changing the checksum of packagea
  383. AlterChecksumOfPackageFPM(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'fpmkinst', TFullFPCInstallationSetup.GetTargetString, 'packagea.fpm']));
  384. CheckBrokenPackages(True);
  385. S := RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestPath, ['fixbroken'], 'Fix broken packages');
  386. Check(pos('broken',s) = 0, 'Fix broken command should not give any warning that packages are still broken');
  387. CheckBrokenPackages(False);
  388. end;
  389. procedure TFullFPCInstallationTests.TestUninstalledRepository;
  390. var
  391. LocalPackagesRepoCfgFilename: String;
  392. ConfigFile: TIniFile;
  393. FPpkg: TpkgFPpkg;
  394. PackageA: TFPPackage;
  395. begin
  396. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagea');
  397. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packageb');
  398. // Create a setup with two repositories, one with the source of the packages,
  399. // and one repository where the packages are installed into. The trick is that
  400. // both repositories use the same location, which effectively means that there
  401. // is no need to install the packages. As soon as they are build, they are
  402. // installed.
  403. LocalPackagesRepoCfgFilename := ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'config', 'conf.d', 'uninstalledrepo.conf']);
  404. ConfigFile := TIniFile.Create(LocalPackagesRepoCfgFilename);
  405. try
  406. ConfigFile.WriteString('UninstalledSourceRepository', 'Name', 'localpackages');
  407. ConfigFile.WriteString('UninstalledSourceRepository', 'Description', 'Local packages');
  408. ConfigFile.WriteString('UninstalledSourceRepository', 'Path', ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'packages']));
  409. ConfigFile.WriteString('UninstalledSourceRepository', 'InstallRepository', 'installedlocalpackages');
  410. ConfigFile.WriteString('UninstalledRepository', 'Name', 'installedlocalpackages');
  411. ConfigFile.WriteString('UninstalledRepository', 'Description', 'Installed local packages');
  412. ConfigFile.WriteString('UninstalledRepository', 'Path', ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'packages']));
  413. ConfigFile.WriteString('UninstalledRepository', 'SourceRepository', 'localpackages');
  414. ConfigFile.UpdateFile;
  415. finally
  416. ConfigFile.Free;
  417. end;
  418. // Should install into fpc, as it is installed from the localpackages repository
  419. // which has fpc as install-repository
  420. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestPath, ['build', 'packagea'], 'Build package A, which will show as installed');
  421. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestPath, ['build', 'packageb'], 'Build package B, which will show as installed');
  422. // Check if packagea is installed
  423. FPpkg := TpkgFPpkg.Create(nil);
  424. try
  425. FPpkg.InitializeGlobalOptions(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'etc','fppkg.cfg']));
  426. FPpkg.Options.GlobalSection.Downloader := 'FPC';
  427. FPpkg.InitializeCompilerOptions;
  428. FPpkg.CompilerOptions.InitCompilerDefaults;
  429. FPpkg.FpmakeCompilerOptions.InitCompilerDefaults;
  430. FPpkg.CompilerOptions.CheckCompilerValues;
  431. FPpkg.FpmakeCompilerOptions.CheckCompilerValues;
  432. FPpkg.LoadLocalAvailableMirrors;
  433. FPpkg.ScanAvailablePackages;
  434. FPpkg.ScanPackages;
  435. PackageA := FPpkg.FindPackage('packagea', pkgpkInstalled);
  436. CheckNotNull(PackageA, 'Installed packagea found');
  437. CheckEquals('installedlocalpackages', PackageA.Repository.RepositoryName, 'Package is ''installed'' in local-repository');
  438. AlterChecksumOfPackageFPM(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'packages', 'packagea', 'packagea-'+TFullFPCInstallationSetup.GetTargetString+'.fpm']));
  439. CheckBrokenPackages(True);
  440. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestPath, ['fixbroken'], 'Fix PackageB by only re-compiling it, without installation');
  441. CheckBrokenPackages(False);
  442. PackageA := FPpkg.FindPackage('packagea', pkgpkInstalled);
  443. CheckNotNull(PackageA, 'Installed packagea found');
  444. CheckEquals('installedlocalpackages', PackageA.Repository.RepositoryName, 'Package is ''installed'' in local-repository');
  445. Check(not Assigned(FPpkg.FindRepository('user').FindPackage('packagea')),'PackageA should not be installed in user-repository');
  446. Check(not Assigned(FPpkg.FindRepository('user').FindPackage('PackageB')),'PackageB should not be installed in user-repository');
  447. Check(not Assigned(FPpkg.FindRepository('fpc').FindPackage('packagea')),'PackageA should not be installed in user-repository');
  448. Check(not Assigned(FPpkg.FindRepository('fpc').FindPackage('PackageB')),'PackageB should not be installed in user-repository');
  449. Check(Assigned(FPpkg.FindRepository('installedlocalpackages').FindPackage('packagea')),'PackageA should be installed in installedlocalpackages-repository');
  450. Check(Assigned(FPpkg.FindRepository('installedlocalpackages').FindPackage('PackageB')),'PackageB should be installed in installedlocalpackages-repository');
  451. finally
  452. FPpkg.Free;
  453. end;
  454. end;
  455. procedure TFullFPCInstallationTests.TestBrokenPackagesBetweenRepos;
  456. var
  457. s: String;
  458. begin
  459. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagea');
  460. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packageb');
  461. // Make sure that PackageB is not reported broken. (It could be that it marks
  462. // it as broken, because packages in the 'user'-repository could not be found
  463. // by the 'fpc'-repository. All wrong, but this was the case in earlier
  464. // versions.)
  465. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['install'], 'install PackageA');
  466. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packageb', ['install', '-i', 'fpc'], 'install PackageB');
  467. CheckBrokenPackages(False);
  468. s := RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath, ['list', '-l'], 'List all packages, none should be broken');
  469. Check(pos('(B)',s) = 0, 'There are no broken packages, fppkg should report so.');
  470. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packageb', ['install'], 'install PackageB into user-repository');
  471. // Now break the package in the fpc-repository on purpose. This package should
  472. // now be broken, but the 'whole' repository should not, because the
  473. // package in the 'user'-repository has precedence.
  474. AlterChecksumOfDependencyInFPM(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'fpmkinst', TFullFPCInstallationSetup.GetTargetString, 'PackageB.fpm']));
  475. CheckBrokenPackages(False);
  476. s := RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath, ['list', '-l'], 'List all packages, one should be broken');
  477. Check(pos('(B)',s) > 0, 'The PackageB in the fpc-repository should be broken.');
  478. end;
  479. procedure TFullFPCInstallationTests.TestPackageDependenciesBetweenRepos;
  480. var
  481. s: String;
  482. begin
  483. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagea');
  484. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packageb');
  485. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['install'], 'install PackageA');
  486. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packageb', ['install'], 'install PackageB');
  487. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['install', '-i', 'fpc'], 'install PackageA in fpc-repository');
  488. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packageb', ['install', '-i', 'fpc'], 'install PackageB in fpc-repository');
  489. CheckBrokenPackages(False);
  490. // Although Package-A's checksum in the fpc-repo is modified, there should not
  491. // be any packages reported as being broken, because the user-version of
  492. // PackageA should be used.
  493. AlterChecksumOfPackageFPM(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'fpmkinst', TFullFPCInstallationSetup.GetTargetString, 'packagea.fpm']));
  494. s := RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath, ['list', '-l'], 'List all packages, none should be broken');
  495. Check(pos('(B)',s) = 0, 'There are no broken packages, fppkg should report so.');
  496. end;
  497. procedure TFullFPCInstallationTests.TestBuildOfArchiveFile;
  498. var
  499. ArchiveFileName, s: String;
  500. begin
  501. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagea');
  502. // Build and install package
  503. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['archive'], 'Create archive for PackageA');
  504. ArchiveFileName := ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath, 'packagea', 'packagea-1.2.3.source.zip']);
  505. Check(FileExists(ArchiveFileName), 'Archive packagea-1.2.3.source.zip does exist');
  506. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestPath, ['build', ArchiveFileName], 'Build packagea-1.2.3.source.zip');
  507. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestPath, ['install', ArchiveFileName], 'install packagea-1.2.3.source.zip');
  508. // Test installation
  509. s := RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestPath, ['list'], 'list packages');
  510. Check(pos('packagea', s) > 0, 'Just installed PackageA is not in package-list');
  511. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'user','lib','fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea','PackageAUnitA.ppu'])), 'PackageAUnitA.ppu not found');
  512. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'user','lib','fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea','PackageAUnitA.o'])), 'PackageAUnitA.o not found');
  513. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'user','lib','fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'fpmkinst',TFullFPCInstallationSetup.GetTargetString,'packagea.fpm'])), 'PackageAUnitA.fpm not found');
  514. end;
  515. procedure TFullFPCInstallationTests.TestCleanupOfTemporaryBuildpath;
  516. var
  517. SR: TSearchRec;
  518. begin
  519. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('brokenpackage');
  520. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'brokenpackage', ['build'], 'Attempt to build brokenpackage', 1);
  521. if FindFirst(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'brokenpackage'+PathDelim+AllFilesMask, faAnyFile, sr) = 0 then
  522. begin
  523. repeat
  524. Check(not ((SR.Name<>'.') and (SR.Name<>'..') and (SR.Name<>'fpmake.pp') and (SR.Name<>'src')), 'Check for garbage-files after build ('+SR.Name+')');
  525. until FindNext(SR) <> 0;
  526. end;
  527. end;
  528. procedure TFullFPCInstallationTests.TestDefaultInstallLocation;
  529. var
  530. FPPKGFilename: String;
  531. ConfigFile: TIniFile;
  532. begin
  533. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagea');
  534. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packageb');
  535. // Remove the installrepository setting from fppkg.cfg
  536. FPPKGFilename := ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'etc', 'fppkg.cfg']);
  537. ConfigFile := TIniFile.Create(FPPKGFilename);
  538. try
  539. ConfigFile.DeleteKey('Defaults', 'InstallRepository');
  540. ConfigFile.UpdateFile;
  541. finally
  542. ConfigFile.Free;
  543. end;
  544. // Should install into user
  545. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['install'], 'Install package A');
  546. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea','PackageAUnitA.ppu'])), 'PackageAUnitA.ppu not found');
  547. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea','PackageAUnitA.o'])), 'PackageAUnitA.o not found');
  548. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'fpmkinst',TFullFPCInstallationSetup.GetTargetString,'packagea.fpm'])), 'packagea.fpm not found');
  549. // Command-line should override default, so install in fpc
  550. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packageb', ['install', '-i', 'fpc'], 'Install package B');
  551. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'PackageB','PackageBUnitB.ppu'])), 'PackageBUnitB.ppu not found');
  552. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'PackageB','PackageBUnitB.o'])), 'PackageBUnitB.o not found');
  553. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'fpmkinst',TFullFPCInstallationSetup.GetTargetString,'PackageB.fpm'])), 'PackageB.fpm not found');
  554. end;
  555. procedure TFullFPCInstallationTests.TestSourceRepositoryInstallLocation;
  556. var
  557. LocalPackagesRepoCfgFilename: String;
  558. ConfigFile: TIniFile;
  559. begin
  560. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagea');
  561. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packageb');
  562. LocalPackagesRepoCfgFilename := ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'config', 'conf.d', 'lazaruspackagesrepo.conf']);
  563. ConfigFile := TIniFile.Create(LocalPackagesRepoCfgFilename);
  564. try
  565. ConfigFile.WriteString('UninstalledSourceRepository', 'Name', 'localpackages');
  566. ConfigFile.WriteString('UninstalledSourceRepository', 'Description', 'Local packages');
  567. ConfigFile.WriteString('UninstalledSourceRepository', 'Path', ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'packages']));
  568. ConfigFile.WriteString('UninstalledSourceRepository', 'InstallRepository', 'fpc');
  569. ConfigFile.UpdateFile;
  570. finally
  571. ConfigFile.Free;
  572. end;
  573. // Should install into fpc, as it is installed from the localpackages repository
  574. // which has fpc as install-repository
  575. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestPath, ['install', 'packagea'], 'Install package A from source repository');
  576. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea','PackageAUnitA.ppu'])), 'PackageAUnitA.ppu not found');
  577. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea','PackageAUnitA.o'])), 'PackageAUnitA.o not found');
  578. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'fpmkinst',TFullFPCInstallationSetup.GetTargetString,'packagea.fpm'])), 'packagea.fpm not found');
  579. // Command-line should override default, so install in user
  580. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestPath, ['install', '-i', 'user', 'packageb'], 'Install package B from user repository');
  581. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'PackageB','PackageBUnitB.ppu'])), 'PackageBUnitB.ppu not found');
  582. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'PackageB','PackageBUnitB.o'])), 'PackageBUnitB.o not found');
  583. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'fpmkinst',TFullFPCInstallationSetup.GetTargetString,'PackageB.fpm'])), 'PackageB.fpm not found');
  584. end;
  585. procedure TFullFPCInstallationTests.TestConfiguredInstallLocation;
  586. var
  587. FPPKGFilename: String;
  588. ConfigFile: TIniFile;
  589. begin
  590. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagea');
  591. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packageb');
  592. // Remove the installrepository setting from fppkg.cfg
  593. FPPKGFilename := ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'etc', 'fppkg.cfg']);
  594. ConfigFile := TIniFile.Create(FPPKGFilename);
  595. try
  596. ConfigFile.WriteString('Defaults', 'InstallRepository', 'fpc');
  597. ConfigFile.UpdateFile;
  598. finally
  599. ConfigFile.Free;
  600. end;
  601. // Should install into fpc
  602. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['install'], 'Install package A');
  603. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea','PackageAUnitA.ppu'])), 'PackageAUnitA.ppu not found');
  604. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea','PackageAUnitA.o'])), 'PackageAUnitA.o not found');
  605. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'fpmkinst',TFullFPCInstallationSetup.GetTargetString,'packagea.fpm'])), 'packagea.fpm not found');
  606. // Command-line should override default, so install in user
  607. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packageb', ['install', '-i', 'user'], 'Install package B');
  608. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'PackageB','PackageBUnitB.ppu'])), 'PackageBUnitB.ppu not found');
  609. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'PackageB','PackageBUnitB.o'])), 'PackageBUnitB.o not found');
  610. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'fpmkinst',TFullFPCInstallationSetup.GetTargetString,'PackageB.fpm'])), 'PackageB.fpm not found');
  611. end;
  612. procedure TFullFPCInstallationTests.TestListPackages;
  613. var
  614. s: String;
  615. begin
  616. s := RunFppkgIndir(TFullFPCInstallationSetup.GetTestPath, ['list'], 'fppkg list');
  617. Check(pos('rtl',s) > 0, 'Package rtl not found in fppkg-package list');
  618. end;
  619. procedure TFullFPCInstallationTests.IntTestListPackages;
  620. var
  621. FPpkg: TpkgFPpkg;
  622. RTLPackage: TFPPackage;
  623. begin
  624. FPpkg := TpkgFPpkg.Create(nil);
  625. try
  626. FPpkg.InitializeGlobalOptions(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'etc','fppkg.cfg']));
  627. FPpkg.Options.GlobalSection.Downloader := 'FPC';
  628. FPpkg.InitializeCompilerOptions;
  629. FPpkg.CompilerOptions.InitCompilerDefaults;
  630. FPpkg.FpmakeCompilerOptions.InitCompilerDefaults;
  631. FPpkg.CompilerOptions.CheckCompilerValues;
  632. FPpkg.FpmakeCompilerOptions.CheckCompilerValues;
  633. FPpkg.LoadLocalAvailableMirrors;
  634. FPpkg.ScanAvailablePackages;
  635. FPpkg.ScanPackages;
  636. RTLPackage := FPpkg.RepositoryByName('fpc').FindPackage('rtl');
  637. CheckNotNull(RTLPackage, 'RTL package not found');
  638. CheckEquals('3.1.1', RTLPackage.Version.AsString, 'RTL has not the same version as the compiler');
  639. finally
  640. FPpkg.Free;
  641. end;
  642. end;
  643. procedure TFullFPCInstallationTests.IntTestMergeGlobalOptions;
  644. var
  645. FPpkg: TpkgFPpkg;
  646. ExtraConfFile: Text;
  647. s: string;
  648. begin
  649. // When there are multiple global-sections, it's values should be merged.
  650. s := ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'config', 'conf.d', 'extrasettings.conf']);
  651. AssignFile(ExtraConfFile, ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'config', 'conf.d', 'extrasettings.conf']));
  652. Rewrite(ExtraConfFile);
  653. WriteLn(ExtraConfFile, '[global]');
  654. WriteLn(ExtraConfFile, 'FPMakeOptions="-T 4"');
  655. CloseFile(ExtraConfFile);
  656. FPpkg := TpkgFPpkg.Create(nil);
  657. try
  658. FPpkg.InitializeGlobalOptions(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'etc','fppkg.cfg']));
  659. FPpkg.Options.GlobalSection.Downloader := 'FPC';
  660. FPpkg.InitializeCompilerOptions;
  661. FPpkg.CompilerOptions.InitCompilerDefaults;
  662. FPpkg.FpmakeCompilerOptions.InitCompilerDefaults;
  663. FPpkg.CompilerOptions.CheckCompilerValues;
  664. FPpkg.FpmakeCompilerOptions.CheckCompilerValues;
  665. FPpkg.LoadLocalAvailableMirrors;
  666. CheckEquals('user', FPpkg.Options.GlobalSection.InstallRepository, 'The InstallRepository does not match the value in the original configuration file');
  667. CheckEquals('"-T 4"', FPpkg.Options.GlobalSection.CustomFPMakeOptions, 'The custom FPMakeOptions do not match the value in the extra configuration file');
  668. finally
  669. FPpkg.Free;
  670. end;
  671. end;
  672. procedure TFullFPCInstallationTests.TestPackageA;
  673. var
  674. s: String;
  675. begin
  676. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagea');
  677. // Build and install package
  678. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['build'], 'build PackageA');
  679. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['install'], 'install PackageA');
  680. // Test installation
  681. s := RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestPath, ['list'], 'list packages');
  682. Check(pos('packagea', s) > 0, 'Just installed PackageA is not in package-list');
  683. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'user','lib','fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea','PackageAUnitA.ppu'])), 'PackageAUnitA.ppu not found');
  684. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'user','lib','fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea','PackageAUnitA.o'])), 'PackageAUnitA.o not found');
  685. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'user','lib','fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'fpmkinst',TFullFPCInstallationSetup.GetTargetString,'packagea.fpm'])), 'PackageAUnitA.fpm not found');
  686. // uninstall package
  687. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['uninstall'], 'install PackageA');
  688. // check uninstallation
  689. s := RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestPath, ['list'], 'list packages');
  690. Check(pos('packagea', s) = 0, 'Just de-installed PackageA is still in package-list');
  691. CheckFalse(DirectoryExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'user','lib','fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea'])), 'PackageAUnitA-directory found after uninstall');
  692. CheckFalse(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'user','lib','fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'fpmkinst',TFullFPCInstallationSetup.GetTargetString,'packagea.fpm'])), 'PackageAUnitA.fpm found after uninstall');
  693. end;
  694. procedure TFullFPCInstallationTests.TestLooseFPMFile;
  695. var
  696. F: Text;
  697. s: string;
  698. begin
  699. System.Assign(F, ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'fpmkinst', TFullFPCInstallationSetup.GetTargetString,'empty.fpm']));
  700. System.Rewrite(F);
  701. System.Close(F);
  702. s := RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestPath, ['list'], 'list packages');
  703. Check(pos('Failed to load package "empty"', s) > 0, 'Missing warning that the invalid package is skipped')
  704. end;
  705. procedure TFullFPCInstallationTests.TestMissingSource;
  706. var
  707. s: String;
  708. begin
  709. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagea');
  710. // Build and install package
  711. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['build'], 'build PackageA');
  712. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['install'], 'install PackageA');
  713. // Destroy the installation
  714. DeleteFile(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'user','lib','fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea','PackageAUnitA.ppu']));
  715. // Re-install
  716. RunFppkgIndir(TFullFPCInstallationSetup.GetTestPath, ['install', 'packagea'], 're-install PackageA');
  717. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'user','lib','fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea','PackageAUnitA.ppu'])), 'PackageAUnitA.ppu not found after re-install');
  718. // Remove the original sources
  719. DeleteDirectory(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', False);
  720. s := RunFppkgIndir(TFullFPCInstallationSetup.GetTestPath, ['install', 'packagea'], 'Re-install PackageA without source', 1);
  721. Check(pos('Source of package packagea is not available', s) > 0, 'Missing warning that the package-source is unavailable. Fppkg-output: ' + s)
  722. end;
  723. procedure TFullFPCInstallationTests.TestBuildWithInstalledDependency;
  724. var
  725. s: String;
  726. begin
  727. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagea');
  728. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packageb');
  729. // Build and install package
  730. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['install'], 'install PackageA');
  731. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packageb', ['install'], 'install PackageB using the installed dependency PackageA');
  732. // Test installation
  733. s := RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestPath, ['list'], 'list packages');
  734. Check(pos('packagea', s) > 0, 'Just installed PackageA is not in package-list');
  735. Check(pos('PackageB', s) > 0, 'Just installed PackageB is not in package-list');
  736. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'user','lib','fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea','PackageAUnitA.ppu'])), 'PackageAUnitA.ppu not found');
  737. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'user','lib','fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'PackageB','PackageBUnitB.ppu'])), 'PackageBUnitB.ppu not found');
  738. end;
  739. procedure TFullFPCInstallationTests.TestFakePackageDir;
  740. var
  741. s: String;
  742. begin
  743. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagea');
  744. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packageb');
  745. // Build and install package
  746. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['install', '-i', 'fpc'], 'install PackageA');
  747. ForceDirectories(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units', TFullFPCInstallationSetup.GetTargetString, 'PackageA']));
  748. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packageb', ['install'], 'install PackageB using the installed dependency PackageA');
  749. // Test installation
  750. s := RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestPath, ['list'], 'list packages');
  751. Check(pos('packagea', s) > 0, 'Just installed PackageA is not in package-list');
  752. Check(pos('PackageB', s) > 0, 'Just installed PackageB is not in package-list');
  753. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'lib','fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea','PackageAUnitA.ppu'])), 'PackageAUnitA.ppu not found');
  754. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath,'user','lib','fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'PackageB','PackageBUnitB.ppu'])), 'PackageBUnitB.ppu not found');
  755. end;
  756. procedure TFullFPCInstallationTests.TestSourceDependency;
  757. var
  758. s: String;
  759. begin
  760. // This is to test if fpmkunit works correctly when a dependency is available
  761. // not as an installed but as a (compiled) source-package. This happens for
  762. // example if you try to compile _one_ fpmake-packages in fpcsrc/packages,
  763. // using 'make clean all' and it needs one of the other packages in
  764. // fpcsrc/packages.
  765. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagea');
  766. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packageb');
  767. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['build'], 'build PackageA');
  768. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packageb', ['build'], 'create fpmake-executable', 1);
  769. RunFPMakeIndir(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath,'packageb']), ['build'], 'build packageb');
  770. // When there is no .fpm file, fpmake should complain that the package is not
  771. // compiled. (Another possibility is that another packages is mistakenly being
  772. // used, for example when the package-name does not match the directory-name)
  773. // This has to be enforced because without the .fpm, the dependencies are
  774. // not handled.
  775. s := ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath,'packagea','packagea-'+TFullFPCInstallationSetup.GetTargetString+'.fpm']);
  776. DeleteFile(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath,'packagea','packagea-'+TFullFPCInstallationSetup.GetTargetString+'.fpm']));
  777. s := RunFPMakeIndir(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath,'packageb']), ['build', '-d'], 'build packageb without fpm', 1);
  778. Check(pos('the package is not compiled', s) > 0, 'Missing .fpm-file detection did not trigger');
  779. Check(pos('Could not find unit directory for dependency package', s) > 0, 'Incorrect error message');
  780. end;
  781. procedure TFullFPCInstallationTests.TestTransmitOptions;
  782. begin
  783. // Test the TransmitOptions settings. PackageA contain some TransmitOptions,
  784. // without which the other packages won't compile.
  785. // PackageC depends on both PackageB's, but should only add the TransmitOptions
  786. // from PackageA once.
  787. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagea', 'transmitoptions');
  788. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packageb1', 'transmitoptions');
  789. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packageb2', 'transmitoptions');
  790. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagec', 'transmitoptions');
  791. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['install'], 'build PackageA');
  792. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packageb1', ['install'], 'build PackageB1');
  793. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packageb2', ['install'], 'build PackageB2');
  794. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagec', ['install'], 'build PackageC');
  795. end;
  796. procedure TFullFPCInstallationTests.TestPackageVariantPackage;
  797. var
  798. s: String;
  799. begin
  800. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagevarianta');
  801. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagevariantp');
  802. // Compile the packages with their default variant
  803. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagevarianta', ['install'], 'install PackageVariantA');
  804. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagevariantp', ['install'], 'install PackageVariantP');
  805. // Check the usage of the versiona-subdirectory
  806. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units', TFullFPCInstallationSetup.GetTargetString, 'packagevarianta', 'versiona', 'packagevariantbaseunit.ppu'])), 'packagevariantbaseunit.ppu not found');
  807. // Check the output of the generated executable
  808. s := RunTestCommandIndir(TFullFPCInstallationSetup.GetCurrentTestPath, ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'bin', 'packagevariantp']), [], 'Run PackageVariantP');
  809. Check(pos('Hello version A', s) > 0, 'Package is not compiled with Version-A unit');
  810. RunFPMakeIndir(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath,'packagevarianta']), ['build', '+ProcVersion=versionb'], 'build PackageVariantA in the VersionB variant');
  811. RunFPMakeIndir(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath,'packagevariantp']), ['build', '+ProcVersion=versionb'], 'build PackageVariantP in the VersionB variant');
  812. // Check the usage of the versiona- & versionb-subdirectory
  813. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath, 'packagevarianta', 'units', TFullFPCInstallationSetup.GetTargetString, 'versiona', 'packagevariantbaseunit.ppu'])), 'packagevariantbaseunit.ppu versiona not found');
  814. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath, 'packagevarianta', 'units', TFullFPCInstallationSetup.GetTargetString, 'versionb', 'packagevariantbaseunit.ppu'])), 'packagevariantbaseunit.ppu versionb not found');
  815. // Check the output of the generated executable
  816. s := RunTestCommandIndir(TFullFPCInstallationSetup.GetCurrentTestPath, ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath, 'packagevariantp', 'bin', TFullFPCInstallationSetup.GetTargetString, 'packagevariantp']), [], 'Run PackageVariantP');
  817. Check(pos('Bye version B', s) > 0, 'Package is not compiled with Version-B unit');
  818. Check(pos('Now with extra unit!', s) > 0, 'Package is not compiled with extra Version-B unit');
  819. // Compile PackageVariantP again, but now with VersionA
  820. RunFPMakeIndir(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath,'packagevariantp']), ['build', '+ProcVersion=versiona'], 'build PackageVariantP in the VersionA variant');
  821. // Check the output of the generated executable
  822. s := RunTestCommandIndir(TFullFPCInstallationSetup.GetCurrentTestPath, ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath, 'packagevariantp', 'bin', TFullFPCInstallationSetup.GetTargetString, 'packagevariantp']), [], 'Run PackageVariantP');
  823. Check(pos('Hello version A', s) > 0, 'Package is not compiled with Version-A unit');
  824. end;
  825. procedure TFullFPCInstallationTests.TestFPMakeCommandLikePackageVariants;
  826. var
  827. s: String;
  828. begin
  829. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagea');
  830. TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packageb');
  831. // Build packagea so that fpmake is compiled
  832. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['build'], 'build PackageA with fppkg');
  833. // Test some invalid command-line arguments
  834. s := RunFPMakeIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath+ 'packagea', ['build', '+buildvariant'], 'Test with invalid +buildvariant command line option', 1);
  835. Check(pos('needs an argument', s) > 0, 'FPMake did not check for the argument');
  836. s := RunFPMakeIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath+ 'packagea', ['build', '+buildvariant+'], 'Test with invalid +buildvariant+ command line option', 1);
  837. Check(pos('needs an argument', s) > 0, 'FPMake did not check for the argument +');
  838. s := RunFPMakeIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath+ 'packagea', ['build', '+buildvariant+='], 'Test with empty +buildvariant+ value', 1);
  839. Check(pos('should have at least one item', s) > 0, 'FPMake did not check for an empty argument');
  840. // Build PackageA with BuildVariants
  841. RunFPMakeIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath+ 'packagea', ['build', '+buildvariant+=debug,release', '--options_buildvariant_debug=-gl', '--options_buildvariant_release="-g- -CX -XX -O2"'], 'Build debug variant');
  842. // Build the release-variant
  843. RunFPMakeIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath+ 'packagea', ['build', '+buildvariant+=debug,release', '--options_buildvariant_debug=-gl', '--options_buildvariant_release="-g- -CX -XX -O2"', '+buildvariant=release'], 'Build release variant');
  844. // Check the usage of the debug- & release-subdirectory
  845. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath, 'packagea', 'units', TFullFPCInstallationSetup.GetTargetString, 'debug', 'PackageAUnitA.ppu'])), 'PackageAUnitA.ppu debug-version not found');
  846. Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath, 'packagea', 'units', TFullFPCInstallationSetup.GetTargetString, 'release', 'PackageAUnitA.ppu'])), 'PackageAUnitA.ppu release-version not found');
  847. // Install PackageA with BuildVariants
  848. RunFPMakeIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath+ 'packagea', ['install', '+buildvariant+=debug,release', '--options_buildvariant_debug=-gl', '--options_buildvariant_release="-g- -CX -XX -O2"'], 'Build debug variant');
  849. // Install the release-variant
  850. RunFPMakeIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath+ 'packagea', ['install', '+buildvariant+=debug,release', '--options_buildvariant_debug=-gl', '--options_buildvariant_release="-g- -CX -XX -O2"', '+buildvariant=release'], 'Build release variant');
  851. // Check the usage of the debug-subdirectory
  852. s := ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units', TFullFPCInstallationSetup.GetTargetString, 'packagea', 'debug', 'PackageAUnitA.ppu']);
  853. Check(FileExists(s), 'installed PackageAUnitA.ppu debug-version not found');
  854. // Check that the debug-version has debug-information
  855. s := RunTestCommandIndir(TFullFPCInstallationSetup.GetCurrentTestPath, TFullFPCInstallationSetup.GetCurrentTestPath+'bin'+PathDelim+'ppudump', s, 'Dump the ppu-information of the debug unit');
  856. Check(pos('has_debug_info', s) > 0, 'The debug-unit does not have debug-info');
  857. // Check the usage of the release-subdirectory
  858. s := ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units', TFullFPCInstallationSetup.GetTargetString, 'packagea', 'release', 'PackageAUnitA.ppu']);
  859. Check(FileExists(s), 'installed PackageAUnitA.ppu release-version not found');
  860. // Check that the debug-version has debug-information
  861. s := RunTestCommandIndir(TFullFPCInstallationSetup.GetCurrentTestPath, TFullFPCInstallationSetup.GetCurrentTestPath+'bin'+PathDelim+'ppudump', s, 'Dump the ppu-information of the release unit');
  862. Check(pos('has_debug_info', s) = 0, 'The release-unit has debug-info');
  863. // Build packageb, use the default variant (debug)
  864. RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packageb', ['build'], 'build PackageB with fppkg');
  865. end;
  866. Initialization
  867. RegisterTestDecorator(TFullFPCInstallationSetup, TFullFPCInstallationTests);
  868. end.