compareversion_test.cc 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. // -*- mode: cpp; mode: fold -*-
  2. // Description /*{{{*/
  3. /* ######################################################################
  4. Version Test - Simple program to run through a file and comare versions.
  5. Each version is compared and the result is checked against an expected
  6. result in the file. The format of the file is
  7. a b Res
  8. Where Res is -1, 1, 0. dpkg -D=1 --compare-versions a "<" b can be
  9. used to determine what Res should be. # at the start of the line
  10. is a comment and blank lines are skipped
  11. The runner will also call dpkg --compare-versions to check if APT and
  12. dpkg have (still) the same idea.
  13. ##################################################################### */
  14. /*}}}*/
  15. #include <apt-pkg/macros.h>
  16. #include <apt-pkg/error.h>
  17. #include <apt-pkg/version.h>
  18. #include <apt-pkg/debversion.h>
  19. #include <apt-pkg/fileutl.h>
  20. #include <iostream>
  21. #include <fstream>
  22. #include <stdlib.h>
  23. #include <unistd.h>
  24. #include <sys/types.h>
  25. #include <sys/wait.h>
  26. using namespace std;
  27. bool callDPkg(const char *val, const char *ref, const char &op) {
  28. pid_t Process = ExecFork();
  29. if (Process == 0)
  30. {
  31. const char * args[6];
  32. args[0] = "/usr/bin/dpkg";
  33. args[1] = "--compare-versions";
  34. args[2] = val;
  35. args[3] = (op == 1) ? ">>" : ( (op == 0) ? "=" : "<<");
  36. args[4] = ref;
  37. args[5] = 0;
  38. execv(args[0], (char**) args);
  39. exit(1);
  40. }
  41. int Ret;
  42. waitpid(Process, &Ret, 0);
  43. return WIFEXITED(Ret) == true && WEXITSTATUS(Ret) == 0;
  44. }
  45. void assertVersion(int const &CurLine, string const &A, string const &B, int const &Expected) {
  46. int Res = debVS.CmpVersion(A.c_str(), B.c_str());
  47. bool const dpkg = callDPkg(A.c_str(),B.c_str(), Expected);
  48. Res = (Res < 0) ? -1 : ( (Res > 0) ? 1 : Res);
  49. if (Res != Expected)
  50. _error->Error("Comparison failed on line %u. '%s' '%s' '%s' %i != %i",CurLine,A.c_str(),((Expected == 1) ? "<<" : ( (Expected == 0) ? "=" : ">>")) ,B.c_str(),Res,Expected);
  51. if (dpkg == false)
  52. _error->Error("DPkg differ with line: %u. '%s' '%s' '%s' == false",CurLine,A.c_str(),((Expected == 1) ? "<<" : ( (Expected == 0) ? "=" : ">>")),B.c_str());
  53. }
  54. bool RunTest(const char *File)
  55. {
  56. ifstream F(File,ios::in);
  57. if (!F != 0)
  58. return false;
  59. char Buffer[300];
  60. int CurLine = 0;
  61. while (1)
  62. {
  63. F.getline(Buffer,sizeof(Buffer));
  64. CurLine++;
  65. if (F.eof() != 0)
  66. return true;
  67. if (!F != 0)
  68. return _error->Error("Line %u in %s is too long",CurLine,File);
  69. // Comment
  70. if (Buffer[0] == '#' || Buffer[0] == 0)
  71. continue;
  72. // First version
  73. char *I;
  74. char *Start = Buffer;
  75. for (I = Buffer; *I != 0 && *I != ' '; I++);
  76. string A(Start, I - Start);
  77. if (*I == 0)
  78. return _error->Error("Invalid line %u",CurLine);
  79. // Second version
  80. I++;
  81. Start = I;
  82. for (I = Start; *I != 0 && *I != ' '; I++);
  83. string B(Start,I - Start);
  84. if (*I == 0 || I[1] == 0)
  85. return _error->Error("Invalid line %u",CurLine);
  86. // Result
  87. I++;
  88. int const Expected = atoi(I);
  89. assertVersion(CurLine, A, B, Expected);
  90. // Check the reverse as well
  91. assertVersion(CurLine, B, A, Expected*-1);
  92. }
  93. }
  94. int main(int argc, char *argv[])
  95. {
  96. if (argc <= 1)
  97. RunTest("../versions.lst");
  98. else
  99. RunTest(argv[1]);
  100. // Print any errors or warnings found
  101. _error->DumpErrors();
  102. return 0;
  103. }