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