]>
Commit | Line | Data |
---|---|---|
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 | } |