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