diff options
Diffstat (limited to 'ext/testcase.c')
-rw-r--r-- | ext/testcase.c | 237 |
1 files changed, 226 insertions, 11 deletions
diff --git a/ext/testcase.c b/ext/testcase.c index f0057e6..251cd2f 100644 --- a/ext/testcase.c +++ b/ext/testcase.c @@ -78,6 +78,8 @@ static struct resultflags2str { { TESTCASE_RESULT_RECOMMENDED, "recommended" }, { TESTCASE_RESULT_UNNEEDED, "unneeded" }, { TESTCASE_RESULT_ALTERNATIVES, "alternatives" }, + { TESTCASE_RESULT_RULES, "rules" }, + { TESTCASE_RESULT_GENID, "genid" }, { 0, 0 } }; @@ -107,6 +109,7 @@ static struct solverflags2str { { SOLVER_FLAG_BREAK_ORPHANS, "breakorphans", 0 }, { SOLVER_FLAG_FOCUS_INSTALLED, "focusinstalled", 0 }, { SOLVER_FLAG_YUM_OBSOLETES, "yumobsoletes", 0 }, + { SOLVER_FLAG_NEED_UPDATEPROVIDE, "needupdateprovide", 0 }, { 0, 0, 0 } }; @@ -125,6 +128,7 @@ static struct poolflags2str { { POOL_FLAG_HAVEDISTEPOCH, "havedistepoch", 0 }, { POOL_FLAG_NOOBSOLETESMULTIVERSION, "noobsoletesmultiversion", 0 }, { POOL_FLAG_ADDFILEPROVIDESFILTERED, "addfileprovidesfiltered", 0 }, + { POOL_FLAG_NOWHATPROVIDESAUX, "nowhatprovidesaux", 0 }, { 0, 0, 0 } }; @@ -158,6 +162,15 @@ static struct selflags2str { { 0, 0 } }; +static const char *features[] = { +#ifdef ENABLE_LINKED_PACKAGES + "linked_packages", +#endif +#ifdef ENABLE_COMPLEX_DEPS + "complex_deps", +#endif + 0 +}; typedef struct strqueue { char **str; @@ -322,13 +335,13 @@ testcase_id2str(Pool *pool, Id id, int isname) /* we need escaping! */ s2 = s2p = pool_alloctmpspace(pool, strlen(s) + bad * 2 + 1); - ss = s; if (!strncmp(s, "namespace:", 10)) { strcpy(s2p, "namespace\\3a"); s2p += 12; s += 10; } + ss = s; for (; *ss; ss++) { *s2p++ = *ss; @@ -1668,6 +1681,33 @@ static struct class2str { { 0, 0 } }; +static int +dump_genid(Pool *pool, Strqueue *sq, Id id, int cnt) +{ + struct oplist *op; + char cntbuf[20]; + const char *s; + + if (ISRELDEP(id)) + { + Reldep *rd = GETRELDEP(pool, id); + for (op = oplist; op->flags; op++) + if (rd->flags == op->flags) + break; + cnt = dump_genid(pool, sq, rd->name, cnt); + cnt = dump_genid(pool, sq, rd->evr, cnt); + sprintf(cntbuf, "genid %2d: genid ", cnt++); + s = pool_tmpjoin(pool, cntbuf, "op ", op->flags ? op->opname : "unknown"); + } + else + { + sprintf(cntbuf, "genid %2d: genid ", cnt++); + s = pool_tmpjoin(pool, cntbuf, id ? "lit " : "null", id ? pool_id2str(pool, id) : 0); + } + strqueue_push(sq, s); + return cnt; +} + char * testcase_solverresult(Solver *solv, int resultflags) { @@ -1874,7 +1914,90 @@ testcase_solverresult(Solver *solv, int resultflags) queue_free(&q); queue_free(&rq); } + if ((resultflags & TESTCASE_RESULT_RULES) != 0) + { + /* dump all rules */ + Id rid; + SolverRuleinfo rclass; + Queue q; + int i; + queue_init(&q); + for (rid = 1; (rclass = solver_ruleclass(solv, rid)) != SOLVER_RULE_UNKNOWN; rid++) + { + char *prefix; + switch (rclass) + { + case SOLVER_RULE_PKG: + prefix = "pkg "; + break; + case SOLVER_RULE_UPDATE: + prefix = "update "; + break; + case SOLVER_RULE_FEATURE: + prefix = "feature "; + break; + case SOLVER_RULE_JOB: + prefix = "job "; + break; + case SOLVER_RULE_DISTUPGRADE: + prefix = "distupgrade "; + break; + case SOLVER_RULE_INFARCH: + prefix = "infarch "; + break; + case SOLVER_RULE_CHOICE: + prefix = "choice "; + break; + case SOLVER_RULE_LEARNT: + prefix = "learnt "; + break; + case SOLVER_RULE_BEST: + prefix = "best "; + break; + case SOLVER_RULE_YUMOBS: + prefix = "yumobs "; + break; + default: + prefix = "unknown "; + break; + } + prefix = solv_dupjoin("rule ", prefix, testcase_ruleid(solv, rid)); + solver_ruleliterals(solv, rid, &q); + if (rclass == SOLVER_RULE_FEATURE && q.count == 1 && q.elements[0] == -SYSTEMSOLVABLE) + continue; + for (i = 0; i < q.count; i++) + { + Id p = q.elements[i]; + const char *s; + if (p < 0) + s = pool_tmpjoin(pool, prefix, " -", testcase_solvid2str(pool, -p)); + else + s = pool_tmpjoin(pool, prefix, " ", testcase_solvid2str(pool, p)); + strqueue_push(&sq, s); + } + solv_free(prefix); + } + queue_free(&q); + } + if ((resultflags & TESTCASE_RESULT_GENID) != 0) + { + for (i = 0 ; i < solv->job.count; i += 2) + { + Id id, id2; + if (solv->job.elements[i] != (SOLVER_NOOP | SOLVER_SOLVABLE_PROVIDES)) + continue; + id = solv->job.elements[i + 1]; + s = testcase_dep2str(pool, id); + strqueue_push(&sq, pool_tmpjoin(pool, "genid dep ", s, 0)); + if ((id2 = testcase_str2dep(pool, s)) != id) + { + s = pool_tmpjoin(pool, "genid roundtrip error: ", testcase_dep2str(pool, id2), 0); + strqueue_push(&sq, s); + } + dump_genid(pool, &sq, id, 1); + } + } strqueue_sort(&sq); result = strqueue_join(&sq); strqueue_free(&sq); @@ -2221,6 +2344,9 @@ testcase_read(Pool *pool, FILE *fp, char *testcase, Queue *job, char **resultp, int prepared = 0; int closefp = !fp; int poolflagsreset = 0; + int missing_features = 0; + Id *genid = 0; + int ngenid = 0; if (!fp && !(fp = fopen(testcase, "r"))) { @@ -2343,20 +2469,38 @@ testcase_read(Pool *pool, FILE *fp, char *testcase, Queue *job, char **resultp, else if (!strcmp(pieces[0], "system") && npieces >= 3) { int i; - prepared = 0; + /* must set the disttype before the arch */ - for (i = 0; disttype2str[i].str != 0; i++) - if (!strcmp(disttype2str[i].str, pieces[2])) - break; - if (!disttype2str[i].str) - pool_debug(pool, SOLV_ERROR, "testcase_read: system: unknown disttype '%s'\n", pieces[2]); - else if (pool->disttype != disttype2str[i].type) + prepared = 0; + if (strcmp(pieces[2], "*") != 0) { + char *dp = pieces[2]; + while (dp && *dp) + { + char *dpe = strchr(dp, ','); + if (dpe) + *dpe = 0; + for (i = 0; disttype2str[i].str != 0; i++) + if (!strcmp(disttype2str[i].str, dp)) + break; + if (dpe) + *dpe++ = ','; + if (disttype2str[i].str) + { #ifdef MULTI_SEMANTICS - pool_setdisttype(pool, disttype2str[i].type); -#else - pool_debug(pool, SOLV_ERROR, "testcase_read: system: cannot change disttype to '%s'\n", pieces[2]); + if (pool->disttype != disttype2str[i].type) + pool_setdisttype(pool, disttype2str[i].type); #endif + if (pool->disttype == disttype2str[i].type) + break; + } + dp = dpe; + } + if (!(dp && *dp)) + { + pool_debug(pool, SOLV_ERROR, "testcase_read: system: could not change disttype to '%s'\n", pieces[2]); + missing_features = 1; + } } if (strcmp(pieces[1], "unset") == 0) pool_setarch(pool, 0); @@ -2511,11 +2655,75 @@ testcase_read(Pool *pool, FILE *fp, char *testcase, Queue *job, char **resultp, else pool_debug(pool, SOLV_ERROR, "disable: unknown package '%s'\n", pieces[2]); } + else if (!strcmp(pieces[0], "feature")) + { + int i, j; + for (i = 1; i < npieces; i++) + { + for (j = 0; features[j]; j++) + if (!strcmp(pieces[i], features[j])) + break; + if (!features[j]) + { + pool_debug(pool, SOLV_ERROR, "testcase_read: missing feature '%s'\n", pieces[i]); + missing_features++; + } + } + if (missing_features) + break; + } + else if (!strcmp(pieces[0], "genid") && npieces > 1) + { + Id id; + /* rejoin */ + if (npieces > 2) + { + char *sp; + for (sp = pieces[2]; sp < pieces[npieces - 1]; sp++) + if (*sp == 0) + *sp = ' '; + } + genid = solv_extend(genid, ngenid, 1, sizeof(*genid), 7); + if (!strcmp(pieces[1], "op") && npieces > 2) + { + struct oplist *op; + for (op = oplist; op->flags; op++) + if (!strncmp(pieces[2], op->opname, strlen(op->opname))) + break; + if (!op->flags) + { + pool_debug(pool, SOLV_ERROR, "testcase_read: genid: unknown op '%s'\n", pieces[2]); + break; + } + if (ngenid < 2) + { + pool_debug(pool, SOLV_ERROR, "testcase_read: genid: out of stack\n"); + break; + } + ngenid -= 2; + id = pool_rel2id(pool, genid[ngenid] , genid[ngenid + 1], op->flags, 1); + } + else if (!strcmp(pieces[1], "lit")) + id = pool_str2id(pool, npieces > 2 ? pieces[2] : "", 1); + else if (!strcmp(pieces[1], "null")) + id = 0; + else if (!strcmp(pieces[1], "dep")) + id = testcase_str2dep(pool, pieces[2]); + else + { + pool_debug(pool, SOLV_ERROR, "testcase_read: genid: unknown command '%s'\n", pieces[1]); + break; + } + genid[ngenid++] = id; + } else { pool_debug(pool, SOLV_ERROR, "testcase_read: cannot parse command '%s'\n", pieces[0]); } } + while (job && ngenid > 0) + queue_push2(job, SOLVER_NOOP | SOLVER_SOLVABLE_PROVIDES, genid[--ngenid]); + genid = solv_free(genid); buf = solv_free(buf); pieces = solv_free(pieces); solv_free(testcasedir); @@ -2531,6 +2739,13 @@ testcase_read(Pool *pool, FILE *fp, char *testcase, Queue *job, char **resultp, } if (closefp) fclose(fp); + if (missing_features) + { + solver_free(solv); + solv = 0; + if (resultflagsp) + *resultflagsp = 77; /* hack for testsolv */ + } return solv; } |