10 #include "solverdebug.h"
13 static struct resultflags2str {
16 } resultflags2str[] = {
17 { TESTCASE_RESULT_TRANSACTION, "transaction" },
18 { TESTCASE_RESULT_PROBLEMS, "problems" },
19 { TESTCASE_RESULT_ORPHANED, "orphaned" },
20 { TESTCASE_RESULT_RECOMMENDED, "recommended" },
21 { TESTCASE_RESULT_UNNEEDED, "unneeded" },
22 { TESTCASE_RESULT_ALTERNATIVES, "alternatives" },
23 { TESTCASE_RESULT_RULES, "rules" },
24 { TESTCASE_RESULT_GENID, "genid" },
25 { TESTCASE_RESULT_REASON, "reason" },
26 { TESTCASE_RESULT_CLEANDEPS, "cleandeps" },
27 { TESTCASE_RESULT_JOBS, "jobs" },
34 fprintf(ex ? stderr : stdout, "Usage: testsolv <testcase>\n");
38 struct reportsolutiondata {
44 reportsolutioncb(Solver *solv, void *cbdata)
46 struct reportsolutiondata *sd = cbdata;
50 res = testcase_solverresult(solv, TESTCASE_RESULT_TRANSACTION);
55 sprintf(prefix, "callback%d:", sd->count);
56 while ((p2 = strchr(p, '\n')) != 0)
60 sd->result = solv_dupappend(sd->result, prefix, p);
70 free_considered(Pool *pool)
74 map_free(pool->considered);
75 pool->considered = solv_free(pool->considered);
80 main(int argc, char **argv)
85 Solver *solv, *reusesolv = 0;
90 char *writetestcase = 0;
96 int list_with_deps = 0;
101 while ((c = getopt(argc, argv, "vmrhL:l:s:T:")) >= 0)
126 if ((p = strchr(optarg, ':')))
127 queue_push2(&solq, atoi(optarg), atoi(p + 1));
129 queue_push2(&solq, 1, atoi(optarg));
132 writetestcase = optarg;
141 for (; optind < argc; optind++)
143 pool = pool_create();
144 pool_setdebuglevel(pool, debuglevel);
145 /* report all errors */
146 pool_setdebugmask(pool, pool->debugmask | SOLV_ERROR);
148 fp = fopen(argv[optind], "r");
151 perror(argv[optind]);
159 solv = testcase_read(pool, fp, argv[optind], &job, &result, &resultflags);
162 free_considered(pool);
165 exit(resultflags == 77 ? 77 : 1);
173 if (!multijob && !feof(fp))
177 printf("test %d:\n", multijob++);
181 int selflags = SELECTION_NAME|SELECTION_PROVIDES|SELECTION_CANON|SELECTION_DOTARCH|SELECTION_REL|SELECTION_GLOB|SELECTION_FLAT;
183 selflags |= SELECTION_FILELIST;
186 p = testcase_str2solvid(pool, list);
188 queue_push2(&job, SOLVER_SOLVABLE, p);
190 selection_make(pool, &job, list, selflags);
192 printf("No match\n");
198 selection_solvables(pool, &job, &q);
199 for (i = 0; i < q.count; i++)
201 printf(" - %s\n", testcase_solvid2str(pool, q.elements[i]));
207 SOLVABLE_PROVIDES, SOLVABLE_REQUIRES, SOLVABLE_CONFLICTS, SOLVABLE_OBSOLETES,
208 SOLVABLE_RECOMMENDS, SOLVABLE_SUGGESTS, SOLVABLE_SUPPLEMENTS, SOLVABLE_ENHANCES,
209 SOLVABLE_PREREQ_IGNOREINST,
212 vendor = pool_lookup_str(pool, q.elements[i], SOLVABLE_VENDOR);
214 printf(" %s: %s\n", pool_id2str(pool, SOLVABLE_VENDOR), vendor);
215 for (j = 0; deps[j]; j++)
219 pool_lookup_idarray(pool, q.elements[i], deps[j], &dq);
221 printf(" %s:\n", pool_id2str(pool, deps[j]));
222 for (k = 0; k < dq.count; k++)
223 printf(" %s\n", pool_dep2str(pool, dq.elements[k]));
231 else if (result || writeresult)
233 char *myresult, *resultdiff;
234 struct reportsolutiondata reportsolutiondata;
235 memset(&reportsolutiondata, 0, sizeof(reportsolutiondata));
238 solv->solution_callback = reportsolutioncb;
239 solv->solution_callback_data = &reportsolutiondata;
241 solver_solve(solv, &job);
242 solv->solution_callback = 0;
243 solv->solution_callback_data = 0;
244 if ((resultflags & ~TESTCASE_RESULT_REUSE_SOLVER) == 0)
245 resultflags |= TESTCASE_RESULT_TRANSACTION | TESTCASE_RESULT_PROBLEMS;
246 myresult = testcase_solverresult(solv, resultflags);
247 if (rescallback && reportsolutiondata.result)
249 reportsolutiondata.result = solv_dupjoin(reportsolutiondata.result, myresult, 0);
251 myresult = reportsolutiondata.result;
264 for (i = 0; resultflags2str[i].str; i++)
265 if ((resultflags & resultflags2str[i].flag) != 0)
267 printf(p, resultflags2str[i].str);
270 printf(" <inline>\n");
274 const char *p2 = strchr(p, '\n');
275 p2 = p2 ? p2 + 1 : p + strlen(p);
276 printf("#>%.*s", (int)(p2 - p), p);
281 printf("%s", myresult);
286 resultdiff = testcase_resultdiff(result, myresult);
289 printf("Results differ:\n%s", resultdiff);
291 solv_free(resultdiff);
299 int pcnt = solver_solve(solv, &job);
302 if (!testcase_write(solv, writetestcase, resultflags, 0, 0))
304 fprintf(stderr, "Could not write testcase: %s\n", pool_errstr(pool));
308 if (pcnt && solq.count)
311 for (i = 0; i < solq.count; i += 2)
313 if (solq.elements[i] > 0 && solq.elements[i] <= pcnt)
314 if (solq.elements[i + 1] > 0 && solq.elements[i + 1] <= solver_solution_count(solv, solq.elements[i]))
316 printf("problem %d: taking solution %d\n", solq.elements[i], solq.elements[i + 1]);
317 solver_take_solution(solv, solq.elements[i], solq.elements[i + 1], &job);
322 pcnt = solver_solve(solv, &job);
326 int problem, solution, scnt;
327 printf("Found %d problems:\n", pcnt);
328 for (problem = 1; problem <= pcnt; problem++)
330 printf("Problem %d:\n", problem);
332 solver_printprobleminfo(solv, problem);
338 solver_findallproblemrules(solv, problem, &pq);
339 for (j = 0; j < pq.count; j++)
340 solver_printproblemruleinfo(solv, pq.elements[j]);
345 scnt = solver_solution_count(solv, problem);
346 for (solution = 1; solution <= scnt; solution++)
348 printf("Solution %d:\n", solution);
349 solver_printsolution(solv, problem, solution);
356 Transaction *trans = solver_create_transaction(solv);
357 printf("Transaction summary:\n\n");
358 transaction_print(trans);
359 transaction_free(trans);
363 if ((resultflags & TESTCASE_RESULT_REUSE_SOLVER) != 0 && !feof(fp))
369 solver_free(reusesolv);
370 free_considered(pool);