Imported Upstream version 0.6.5
[platform/upstream/libsolv.git] / tools / testsolv.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4
5 #include "pool.h"
6 #include "repo.h"
7 #include "solver.h"
8 #include "selection.h"
9 #include "solverdebug.h"
10 #include "testcase.h"
11
12 static struct resultflags2str {
13   Id flag;
14   const char *str;
15 } resultflags2str[] = {
16   { TESTCASE_RESULT_TRANSACTION,        "transaction" },
17   { TESTCASE_RESULT_PROBLEMS,           "problems" },
18   { TESTCASE_RESULT_ORPHANED,           "orphaned" },
19   { TESTCASE_RESULT_RECOMMENDED,        "recommended" },
20   { TESTCASE_RESULT_UNNEEDED,           "unneeded" },
21   { 0, 0 }
22 };
23
24 static void
25 usage(ex)
26 {
27   fprintf(ex ? stderr : stdout, "Usage: testsolv <testcase>\n");
28   exit(ex);
29 }
30
31 struct reportsolutiondata {
32   int count;
33   char *result;
34 };
35
36 static int
37 reportsolutioncb(Solver *solv, void *cbdata)
38 {
39   struct reportsolutiondata *sd = cbdata;
40   char *res;
41
42   sd->count++;
43   res = testcase_solverresult(solv, TESTCASE_RESULT_TRANSACTION);
44   if (*res)
45     {
46       char prefix[64];
47       char *p2, *p = res;
48       sprintf(prefix, "callback%d:", sd->count);
49       while ((p2 = strchr(p, '\n')) != 0)
50         {
51           char c = p2[1];
52           p2[1] = 0;
53           sd->result = solv_dupappend(sd->result, prefix, p);
54           p2[1] = c;
55           p = p2 + 1;
56         }
57     }
58   solv_free(res);
59   return 0;
60 }
61
62 int
63 main(int argc, char **argv)
64 {
65   Pool *pool;
66   Queue job;
67   Queue solq;
68   Solver *solv;
69   char *result = 0;
70   int resultflags = 0;
71   int debuglevel = 0;
72   int writeresult = 0;
73   int multijob = 0;
74   int rescallback = 0;
75   int c;
76   int ex = 0;
77   const char *list = 0;
78   FILE *fp;
79   const char *p;
80
81   queue_init(&solq);
82   while ((c = getopt(argc, argv, "vmrhl:s:")) >= 0)
83     {
84       switch (c)
85       {
86         case 'v':
87           debuglevel++;
88           break;
89         case 'r':
90           writeresult++;
91           break;
92         case 'm':
93           rescallback = 1;
94           break;
95         case 'h':
96           usage(0);
97           break;
98         case 'l':
99           list = optarg;
100           break;
101         case 's':
102           if ((p = strchr(optarg, ':')))
103             queue_push2(&solq, atoi(optarg), atoi(p + 1));
104           else
105             queue_push2(&solq, 1, atoi(optarg));
106           break;
107         default:
108           usage(1);
109           break;
110       }
111     }
112   if (optind == argc)
113     usage(1);
114   for (; optind < argc; optind++)
115     {
116       pool = pool_create();
117       pool_setdebuglevel(pool, debuglevel);
118
119       fp = fopen(argv[optind], "r");
120       if (!fp)
121         {
122           perror(argv[optind]);
123           exit(0);
124         }
125       while (!feof(fp))
126         {
127           queue_init(&job);
128           result = 0;
129           resultflags = 0;
130           solv = testcase_read(pool, fp, argv[optind], &job, &result, &resultflags);
131           if (!solv)
132             {
133               pool_free(pool);
134               exit(1);
135             }
136
137           if (!multijob && !feof(fp))
138             multijob = 1;
139
140           if (multijob)
141             printf("test %d:\n", multijob++);
142           if (list)
143             {
144               int selflags = SELECTION_NAME|SELECTION_PROVIDES|SELECTION_CANON|SELECTION_DOTARCH|SELECTION_REL|SELECTION_GLOB|SELECTION_FLAT;
145               if (*list == '/')
146                 selflags |= SELECTION_FILELIST;
147               queue_empty(&job);
148               selection_make(pool, &job, list, selflags);
149               if (!job.elements)
150                 printf("No match\n");
151               else
152                 {
153                   Queue q;
154                   int i;
155                   queue_init(&q);
156                   selection_solvables(pool, &job, &q);
157                   for (i = 0; i < q.count; i++)
158                     printf("  - %s\n", testcase_solvid2str(pool, q.elements[i]));
159                   queue_free(&q);
160                 }
161             }
162           else if (result || writeresult)
163             {
164               char *myresult, *resultdiff;
165               struct reportsolutiondata reportsolutiondata;
166               memset(&reportsolutiondata, 0, sizeof(reportsolutiondata));
167               if (rescallback)
168                 {
169                   solv->solution_callback = reportsolutioncb;
170                   solv->solution_callback_data = &reportsolutiondata;
171                 }
172               solver_solve(solv, &job);
173               solv->solution_callback = 0;
174               solv->solution_callback_data = 0;
175               if (!resultflags)
176                 resultflags = TESTCASE_RESULT_TRANSACTION | TESTCASE_RESULT_PROBLEMS;
177               myresult = testcase_solverresult(solv, resultflags);
178               if (rescallback && reportsolutiondata.result)
179                 {
180                   reportsolutiondata.result = solv_dupjoin(reportsolutiondata.result, myresult, 0);
181                   solv_free(myresult);
182                   myresult = reportsolutiondata.result;
183                 }
184               if (writeresult)
185                 {
186                   if (*myresult)
187                     {
188                       if (writeresult > 1)
189                         {
190                           const char *p;
191                           int i;
192                           
193                           printf("result ");
194                           p = "%s";
195                           for (i = 0; resultflags2str[i].str; i++)
196                             if ((resultflags & resultflags2str[i].flag) != 0)
197                               {
198                                 printf(p, resultflags2str[i].str);
199                                 p = ",%s";
200                               }
201                           printf(" <inline>\n");
202                           p = myresult;
203                           while (*p)
204                             {
205                               const char *p2 = strchr(p, '\n');
206                               p2 = p2 ? p2 + 1 : p + strlen(p);
207                               printf("#>%.*s", (int)(p2 - p), p);
208                               p = p2;
209                             }
210                         }
211                       else
212                         printf("%s", myresult);
213                     }
214                 }
215               else
216                 {
217                   resultdiff = testcase_resultdiff(result, myresult);
218                   if (resultdiff)
219                     {
220                       printf("Results differ:\n%s", resultdiff);
221                       ex = 1;
222                       solv_free(resultdiff);
223                     }
224                 }
225               solv_free(result);
226               solv_free(myresult);
227             }
228           else
229             {
230               int pcnt = solver_solve(solv, &job);
231               if (pcnt && solq.count)
232                 {
233                   int i, taken = 0;
234                   for (i = 0; i < solq.count; i += 2)
235                     {
236                       if (solq.elements[i] > 0 && solq.elements[i] <= pcnt)
237                         if (solq.elements[i + 1] > 0 && solq.elements[i + 1] <=  solver_solution_count(solv, solq.elements[i]))
238                           {
239                             printf("problem %d: taking solution %d\n", solq.elements[i], solq.elements[i + 1]);
240                             solver_take_solution(solv, solq.elements[i], solq.elements[i + 1], &job);
241                             taken = 1;
242                           }
243                     }
244                   if (taken)
245                     pcnt = solver_solve(solv, &job);
246                 }
247               if (pcnt)
248                 {
249                   int problem, solution, scnt;
250                   printf("Found %d problems:\n", pcnt);
251                   for (problem = 1; problem <= pcnt; problem++)
252                     {
253                       printf("Problem %d:\n", problem);
254 #if 1
255                       solver_printprobleminfo(solv, problem);
256 #else
257                       {
258                         Queue pq;
259                         int j;
260                         queue_init(&pq);
261                         solver_findallproblemrules(solv, problem, &pq);
262                         for (j = 0; j < pq.count; j++)
263                           solver_printproblemruleinfo(solv, pq.elements[j]);
264                         queue_free(&pq);
265                       }
266 #endif
267                       printf("\n");
268                       scnt = solver_solution_count(solv, problem);
269                       for (solution = 1; solution <= scnt; solution++)
270                         {
271                           printf("Solution %d:\n", solution);
272                           solver_printsolution(solv, problem, solution);
273                           printf("\n");
274                         }
275                     }
276                 }
277               else
278                 {
279                   Transaction *trans = solver_create_transaction(solv);
280                   printf("Transaction summary:\n\n");
281                   transaction_print(trans);
282                   transaction_free(trans);
283                 }
284             }
285           queue_free(&job);
286           solver_free(solv);
287         }
288       pool_free(pool);
289       fclose(fp);
290     }
291   queue_free(&solq);
292   exit(ex);
293 }