summaryrefslogtreecommitdiff
path: root/ext/testcase.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/testcase.c')
-rw-r--r--ext/testcase.c237
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;
}