Imported Upstream version 0.6.28
[platform/upstream/libsolv.git] / ext / testcase.c
index 52c139f..26acefa 100644 (file)
@@ -7,8 +7,6 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <limits.h>
-#include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -25,6 +23,9 @@
 #include "testcase.h"
 #include "selection.h"
 #include "solv_xfopen.h"
+#if ENABLE_TESTCASE_HELIXREPO
+#include "ext/repo_helix.h"
+#endif
 
 #define DISABLE_JOIN2
 #include "tools_util.h"
@@ -115,6 +116,9 @@ static struct solverflags2str {
   { SOLVER_FLAG_YUM_OBSOLETES,              "yumobsoletes", 0 },
   { SOLVER_FLAG_NEED_UPDATEPROVIDE,         "needupdateprovide", 0 },
   { SOLVER_FLAG_URPM_REORDER,               "urpmreorder", 0 },
+  { SOLVER_FLAG_FOCUS_BEST,                 "focusbest", 0 },
+  { SOLVER_FLAG_STRONG_RECOMMENDS,          "strongrecommends", 0 },
+  { SOLVER_FLAG_INSTALL_ALSO_UPDATES,       "installalsoupdates", 0 },
   { 0, 0, 0 }
 };
 
@@ -174,6 +178,9 @@ static const char *features[] = {
 #ifdef ENABLE_COMPLEX_DEPS
   "complex_deps",
 #endif
+#if ENABLE_TESTCASE_HELIXREPO
+  "testcase_helixrepo",
+#endif
   0
 };
 
@@ -384,41 +391,42 @@ struct oplist {
   { REL_COMPAT,  "compat >=" },
   { REL_KIND,  "<KIND>" },
   { REL_ELSE, "<ELSE>" },
+  { REL_ERROR, "<ERROR>" },
   { REL_LT, "<" },
   { 0, 0 }
 };
 
-static const char *
-testcase_dep2str_complex(Pool *pool, Id id, int addparens)
+static char *
+testcase_dep2str_complex(Pool *pool, char *s, Id id, int addparens)
 {
   Reldep *rd;
-  char *s;
   const char *s2;
   int needparens;
   struct oplist *op;
 
   if (!ISRELDEP(id))
-    return testcase_id2str(pool, id, 1);
+    {
+      s2 = testcase_id2str(pool, id, 1);
+      s = pool_tmpappend(pool, s, s2, 0);
+      pool_freetmpspace(pool, s2);
+      return s;
+    }
   rd = GETRELDEP(pool, id);
 
   /* check for special shortcuts */
   if (rd->flags == REL_NAMESPACE && !ISRELDEP(rd->name) && !strncmp(pool_id2str(pool, rd->name), "namespace:", 10))
     {
-      const char *ns = pool_id2str(pool, rd->name);
-      int nslen = strlen(ns);
-      /* special namespace formatting */
-      const char *evrs = testcase_dep2str_complex(pool, rd->evr, 0);
-      s = pool_tmpappend(pool, evrs, ns, "()");
-      memmove(s + nslen + 1, s, strlen(s) - nslen - 2);
-      memcpy(s, ns, nslen);
-      s[nslen] = '(';
-      return s;
+      s = pool_tmpappend(pool, s, pool_id2str(pool, rd->name), "(");
+      s = testcase_dep2str_complex(pool, s, rd->evr, 0);
+      return pool_tmpappend(pool, s, ")", 0);
     }
   if (rd->flags == REL_MULTIARCH && !ISRELDEP(rd->name) && rd->evr == ARCH_ANY)
     {
-      /* special :any suffix */
-      const char *ns = testcase_id2str(pool, rd->name, 1);
-      return pool_tmpappend(pool, ns, ":any", 0);
+      /* append special :any suffix */
+      s2 = testcase_id2str(pool, rd->name, 1);
+      s = pool_tmpappend(pool, s, s2, ":any");
+      pool_freetmpspace(pool, s2);
+      return s;
     }
 
   needparens = 0;
@@ -429,14 +437,11 @@ testcase_dep2str_complex(Pool *pool, Id id, int addparens)
       if (rd->flags > 7 && rd->flags != REL_COMPAT && rd2->flags && rd2->flags <= 7)
        needparens = 0;
     }
-  s = (char *)testcase_dep2str_complex(pool, rd->name, needparens);
 
   if (addparens)
-    {
-      s = pool_tmpappend(pool, s, "(", 0);
-      memmove(s + 1, s, strlen(s + 1));
-      s[0] = '(';
-    }
+    s = pool_tmpappend(pool, s, "(", 0);
+  s = testcase_dep2str_complex(pool, s, rd->name, needparens);
+
   for (op = oplist; op->flags; op++)
     if (rd->flags == op->flags)
       break;
@@ -467,21 +472,27 @@ testcase_dep2str_complex(Pool *pool, Id id, int addparens)
        needparens = 0; /* chain */
     }
   if (!ISRELDEP(rd->evr))
-    s2 = testcase_id2str(pool, rd->evr, 0);
+    {
+      s2 = testcase_id2str(pool, rd->evr, 0);
+      s = pool_tmpappend(pool, s, s2, 0);
+      pool_freetmpspace(pool, s2);
+    }
   else
-    s2 = testcase_dep2str_complex(pool, rd->evr, needparens);
+    s = (char *)testcase_dep2str_complex(pool, s, rd->evr, needparens);
   if (addparens)
-    s = pool_tmpappend(pool, s, s2, ")");
-  else
-    s = pool_tmpappend(pool, s, s2, 0);
-  pool_freetmpspace(pool, s2);
+    s = pool_tmpappend(pool, s, ")", 0);
   return s;
 }
 
 const char *
 testcase_dep2str(Pool *pool, Id id)
 {
-  return testcase_dep2str_complex(pool, id, 0);
+  char *s;
+  if (!ISRELDEP(id))
+    return testcase_id2str(pool, id, 1);
+  s = pool_alloctmpspace(pool, 1);
+  *s = 0;
+  return testcase_dep2str_complex(pool, s, id, 0);
 }
 
 
@@ -767,6 +778,7 @@ testcase_str2solvid(Pool *pool, const char *str)
          evrid = pool_strn2id(pool, str + i + 1, repostart - (i + 1), 0);
          if (!evrid)
            continue;
+         /* first check whatprovides */
          FOR_PROVIDES(p, pp, nid)
            {
              Solvable *s = pool->solvables + p;
@@ -778,6 +790,31 @@ testcase_str2solvid(Pool *pool, const char *str)
                continue;
              return p;
            }
+         /* maybe it's not installable and thus not in whatprovides. do a slow search */
+         if (repo)
+           {
+             Solvable *s;
+             FOR_REPO_SOLVABLES(repo, p, s)
+               {
+                 if (s->name != nid || s->evr != evrid)
+                   continue;
+                 if (arch && s->arch != arch)
+                   continue;
+                 return p;
+               }
+           }
+         else
+           {
+             FOR_POOL_SOLVABLES(p)
+               {
+                 Solvable *s = pool->solvables + p;
+                 if (s->name != nid || s->evr != evrid)
+                   continue;
+                 if (arch && s->arch != arch)
+                   continue;
+                 return p;
+               }
+           }
        }
     }
   return 0;
@@ -1082,7 +1119,7 @@ testcase_str2job(Pool *pool, const char *str, Id *whatp)
   return job;
 }
 
-int
+static int
 addselectionjob(Pool *pool, char **pieces, int npieces, Queue *jobqueue)
 {
   Id job;
@@ -2235,7 +2272,7 @@ testcase_write_mangled(Solver *solv, const char *dir, int resultflags, const cha
       strqueue_push(&sq, cmd);
     }
 
-  if (resultflags)
+  if ((resultflags & ~TESTCASE_RESULT_REUSE_SOLVER) != 0)
     {
       char *result;
       cmd = 0;
@@ -2328,7 +2365,7 @@ testcase_write(Solver *solv, const char *dir, int resultflags, const char *testc
       Repo *repo = pool_id2repo(pool, repoid);
       char *buf = solv_malloc((repo->name ? strlen(repo->name) : 0) + 40);
       char *mp;
-      orignames[i] = repo->name;
+      orignames[repoid] = repo->name;
       if (!repo->name || !repo->name[0])
         sprintf(buf, "#%d", repoid);
       else
@@ -2353,7 +2390,7 @@ testcase_write(Solver *solv, const char *dir, int resultflags, const char *testc
     {
       Repo *repo = pool_id2repo(pool, repoid);
       solv_free((void *)repo->name);
-      repo->name = orignames[i];
+      repo->name = orignames[repoid];
     }
   solv_free(orignames);
   return r;
@@ -2480,7 +2517,12 @@ testcase_read(Pool *pool, FILE *fp, const char *testcase, Queue *job, char **res
   int missing_features = 0;
   Id *genid = 0;
   int ngenid = 0;
+  Queue autoinstq;
 
+  if (resultp)
+    *resultp = 0;
+  if (resultflagsp)
+    *resultflagsp = 0;
   if (!fp && !(fp = fopen(testcase, "r")))
     {
       pool_debug(pool, SOLV_ERROR, "testcase_read: could not open '%s'\n", testcase);
@@ -2495,6 +2537,7 @@ testcase_read(Pool *pool, FILE *fp, const char *testcase, Queue *job, char **res
   buf = solv_malloc(bufl);
   bufp = buf;
   solv = 0;
+  queue_init(&autoinstq);
   for (;;)
     {
       if (bufp - buf + 16 > bufl)
@@ -2584,10 +2627,9 @@ testcase_read(Pool *pool, FILE *fp, const char *testcase, Queue *job, char **res
                  repo_add_solv(repo, rfp, 0);
                  fclose(rfp);
                }
-#if 0
+#if ENABLE_TESTCASE_HELIXREPO
              else if (!strcmp(repotype, "helix"))
                {
-                 extern int repo_add_helix(Repo *repo, FILE *fp, int flags);
                  repo_add_helix(repo, rfp, 0);
                  fclose(rfp);
                }
@@ -2761,8 +2803,10 @@ testcase_read(Pool *pool, FILE *fp, const char *testcase, Queue *job, char **res
          if (resultflagsp)
            *resultflagsp = resultflags;
        }
-      else if (!strcmp(pieces[0], "nextjob") && npieces == 1)
+      else if (!strcmp(pieces[0], "nextjob"))
        {
+         if (npieces == 2 && resultflagsp && !strcmp(pieces[1], "reusesolver"))
+           *resultflagsp |= TESTCASE_RESULT_REUSE_SOLVER;
          break;
        }
       else if (!strcmp(pieces[0], "disable") && npieces == 3)
@@ -2849,6 +2893,15 @@ testcase_read(Pool *pool, FILE *fp, const char *testcase, Queue *job, char **res
            }
          genid[ngenid++] = id;
        }
+      else if (!strcmp(pieces[0], "autoinst") && npieces > 2)
+       {
+         if (strcmp(pieces[1], "name"))
+           {
+             pool_debug(pool, SOLV_ERROR, "testcase_read: autoinst: illegal mode\n");
+             break;
+           }
+         queue_push(&autoinstq, pool_str2id(pool, pieces[2], 1));
+       }
       else
        {
          pool_debug(pool, SOLV_ERROR, "testcase_read: cannot parse command '%s'\n", pieces[0]);
@@ -2856,6 +2909,9 @@ testcase_read(Pool *pool, FILE *fp, const char *testcase, Queue *job, char **res
     }
   while (job && ngenid > 0)
     queue_push2(job, SOLVER_NOOP | SOLVER_SOLVABLE_PROVIDES, genid[--ngenid]);
+  if (autoinstq.count)
+    pool_add_userinstalled_jobs(pool, &autoinstq, job, GET_USERINSTALLED_NAMES | GET_USERINSTALLED_INVERTED);
+  queue_free(&autoinstq);
   genid = solv_free(genid);
   buf = solv_free(buf);
   pieces = solv_free(pieces);