X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=ext%2Ftestcase.c;h=3c404515dc28d30b7431dc23fa6131bf801cbf70;hb=70c6207bfdb27f170377015f65f22e8ba50f6a10;hp=f0057e6c7a9af86e22dd05fc49f27b653b4c2643;hpb=40d5592805eaa650df84c50b9fed3cbdc4823fc5;p=platform%2Fupstream%2Flibsolv.git diff --git a/ext/testcase.c b/ext/testcase.c index f0057e6..3c40451 100644 --- a/ext/testcase.c +++ b/ext/testcase.c @@ -33,18 +33,19 @@ static struct job2str { Id job; const char *str; } job2str[] = { - { SOLVER_NOOP, "noop" }, - { SOLVER_INSTALL, "install" }, - { SOLVER_ERASE, "erase" }, - { SOLVER_UPDATE, "update" }, - { SOLVER_WEAKENDEPS, "weakendeps" }, - { SOLVER_MULTIVERSION, "multiversion" }, - { SOLVER_MULTIVERSION, "noobsoletes" }, /* old name */ - { SOLVER_LOCK, "lock" }, - { SOLVER_DISTUPGRADE, "distupgrade" }, - { SOLVER_VERIFY, "verify" }, - { SOLVER_DROP_ORPHANED, "droporphaned" }, - { SOLVER_USERINSTALLED, "userinstalled" }, + { SOLVER_NOOP, "noop" }, + { SOLVER_INSTALL, "install" }, + { SOLVER_ERASE, "erase" }, + { SOLVER_UPDATE, "update" }, + { SOLVER_WEAKENDEPS, "weakendeps" }, + { SOLVER_MULTIVERSION, "multiversion" }, + { SOLVER_MULTIVERSION, "noobsoletes" }, /* old name */ + { SOLVER_LOCK, "lock" }, + { SOLVER_DISTUPGRADE, "distupgrade" }, + { SOLVER_VERIFY, "verify" }, + { SOLVER_DROP_ORPHANED, "droporphaned" }, + { SOLVER_USERINSTALLED, "userinstalled" }, + { SOLVER_ALLOWUNINSTALL, "allowuninstall" }, { 0, 0 } }; @@ -78,6 +79,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 +110,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 +129,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 +163,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 +336,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; @@ -365,6 +379,7 @@ struct oplist { { REL_COND, "" }, { REL_COMPAT, "compat >=" }, { REL_KIND, "" }, + { REL_ELSE, "" }, { REL_LT, "<" }, { 0, 0 } }; @@ -1668,6 +1683,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 +1916,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); @@ -1883,7 +2008,7 @@ testcase_solverresult(Solver *solv, int resultflags) int -testcase_write(Solver *solv, char *dir, int resultflags, const char *testcasename, const char *resultname) +testcase_write(Solver *solv, const char *dir, int resultflags, const char *testcasename, const char *resultname) { Pool *pool = solv->pool; Repo *repo; @@ -2209,7 +2334,7 @@ str2resultflags(Pool *pool, char *s) /* modifies the string! */ } Solver * -testcase_read(Pool *pool, FILE *fp, char *testcase, Queue *job, char **resultp, int *resultflagsp) +testcase_read(Pool *pool, FILE *fp, const char *testcase, Queue *job, char **resultp, int *resultflagsp) { Solver *solv; char *buf, *bufp; @@ -2221,6 +2346,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 +2471,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 +2657,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,11 +2741,18 @@ 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; } char * -testcase_resultdiff(char *result1, char *result2) +testcase_resultdiff(const char *result1, const char *result2) { Strqueue sq1, sq2, osq; char *r;