Replaced requirementIsMet by requirementIsInstalledOrUnneeded
authorStefan Schubert <schubi@suse.de>
Thu, 14 Sep 2006 14:10:22 +0000 (14:10 +0000)
committerStefan Schubert <schubi@suse.de>
Thu, 14 Sep 2006 14:10:22 +0000 (14:10 +0000)
in QueueItemInstall and QueueItemRequire
Bug 192535/204913
removed fix:Thu Sep  7 18:31:46 CEST 2006 - schubi@suse.de
added body for generating testcases.

12 files changed:
package/libzypp.changes
testsuite/solver/data.deptestomatic/patch-tests/script-test.solution
zypp/solver/detail/Makefile.am
zypp/solver/detail/QueueItemEstablish.cc
zypp/solver/detail/QueueItemInstall.cc
zypp/solver/detail/QueueItemRequire.cc
zypp/solver/detail/QueueItemRequire.h
zypp/solver/detail/QueueItemUninstall.cc
zypp/solver/detail/ResolverContext.cc
zypp/solver/detail/ResolverContext.h
zypp/solver/detail/Testcase.cc [new file with mode: 0644]
zypp/solver/detail/Testcase.h [new file with mode: 0644]

index 8a618df..92a1f66 100644 (file)
@@ -1,4 +1,12 @@
 -------------------------------------------------------------------
+Thu Sep 14 15:59:47 CEST 2006 - schubi@suse.de
+
+- Replaced requirementIsMet by requirementIsInstalledOrUnneeded 
+  in QueueItemInstall and QueueItemRequire
+  Bug 192535/204913
+  removed fix:Thu Sep  7 18:31:46 CEST 2006 - schubi@suse.de
+
+-------------------------------------------------------------------
 Thu Sep 14 12:44:53 CEST 2006 - lslezak@suse.cz
 
 - fixed SourceFactory::createFrom() - don't loose alias,
index 79474ee..896d445 100644 (file)
@@ -2,18 +2,18 @@
 >!> Established context
 >!> atom:A-2.0-1.i586[message] UU_s_
 >!> message:message for patch-A1-1829-1.noarch[message] UU_s_
->!> patch:fetchmsttfonts.sh-1829-0.noarch[script] UI_s_
+>!> patch:fetchmsttfonts.sh-1829-0.noarch[script] US_s_
 >!> patch:patch-A1-2-0.noarch[message] UU_s_
 >!> script:fetchmsttfonts.sh-patch-fetchmsttfonts.sh-2-1829-1.noarch[script] US_s_
 >!> ESTABLISHED:1: U__s_[S3:0][package]A-2.0-1.i586
 >!> ESTABLISHED:2: UU_s_[S3:0][atom]A-2.0-1.i586
 >!> ESTABLISHED:3: I__s_[S1:0][package]glibc-0.0.8-100.i586
 >!> ESTABLISHED:4: UU_s_[S3:0][message]message for patch-A1-1829-1.noarch
->!> ESTABLISHED:5: UI_s_[S2:0][patch]fetchmsttfonts.sh-1829-0.noarch
+>!> ESTABLISHED:5: US_s_[S2:0][patch]fetchmsttfonts.sh-1829-0.noarch
 >!> ESTABLISHED:6: UU_s_[S3:0][patch]patch-A1-2-0.noarch
 >!> ESTABLISHED:7: US_s_[S2:0][script]fetchmsttfonts.sh-patch-fetchmsttfonts.sh-2-1829-1.noarch
 >!> ESTABLISHED:8: I_Lu_[S0:0][system]system-.noarch
->!> Installing fetchmsttfonts.sh from channel script
+>!> Installing patch:fetchmsttfonts.sh from channel script
 >!> Solution #1:
 >!> install patch:fetchmsttfonts.sh-1829-0.noarch[script]
 >!> install script:fetchmsttfonts.sh-patch-fetchmsttfonts.sh-2-1829-1.noarch[script]
index d879344..a981a1f 100644 (file)
@@ -45,7 +45,8 @@ solverdetailinclude_HEADERS = \
        ProblemSolutionUninstall.h      \
        ProblemSolutionIgnore.h         \
        ProblemSolutionUnlock.h         \
-       SolutionAction.h
+       SolutionAction.h                \
+       Testcase.h
 
 noinst_LTLIBRARIES =   lib@PACKAGE@_solver_detail.la
 
@@ -81,4 +82,5 @@ lib@PACKAGE@_solver_detail_la_SOURCES =                       \
        ProblemSolutionUninstall.cc                     \
        ProblemSolutionIgnore.cc                        \
        ProblemSolutionUnlock.cc                        \
-       SolutionAction.cc
+       SolutionAction.cc                               \
+       Testcase.cc
index 41e4b74..741c99f 100644 (file)
@@ -199,7 +199,7 @@ QueueItemEstablish::process (ResolverContext_Ptr context, QueueItemList & qil)
        for (iter = requires.begin(); iter != requires.end(); iter++) {
            missing = *iter;
            bool unneeded;
-           if (!context->requirementIsMet (missing, false, &unneeded)) {
+           if (!context->requirementIsMet (missing, &unneeded)) {
                all_unneeded = false;
                break;
            }
index bbb43aa..766ffc7 100644 (file)
@@ -444,14 +444,21 @@ QueueItemInstall::process (ResolverContext_Ptr context, QueueItemList & qil)
 
            const Capability cap = *iter;
            _XDEBUG("this requires " << cap);
+           bool fulfilled = false;
+           
+           if (_item)
+           {
+               fulfilled = context->requirementIsInstalledOrUnneeded (_item->kind(), cap);
+           } else {
+               fulfilled = context->requirementIsMet (cap);
+           }
 
-           if (!context->requirementIsMet (cap)) {
+           if (!fulfilled) {
                _XDEBUG("this requirement is still unfulfilled");
                QueueItemRequire_Ptr req_item = new QueueItemRequire (pool(), cap );
                req_item->addPoolItem (_item);
                qil.push_front (req_item);
-           }
-
+           }           
        }
 
        caps = _item->dep (Dep::RECOMMENDS);
index 6a2404e..5668b56 100644 (file)
@@ -76,7 +76,6 @@ QueueItemRequire::dumpOn( std::ostream & os ) const
        os << ", Lost " << _lost_item;
     }
     if (_remove_only) os << ", Remove Only";
-    if (_is_child) os << ", Child";
     return os << "]";
 }
 
@@ -87,7 +86,6 @@ QueueItemRequire::QueueItemRequire (const ResPool & pool, const Capability & cap
     , _capability (cap)
     , _soft (soft)
     , _remove_only (false)
-    , _is_child (false)
 {
     _XDEBUG("QueueItemRequire::QueueItemRequire(" << cap << (soft?", soft":"") << ")");
 }
@@ -417,7 +415,16 @@ QueueItemRequire::process (ResolverContext_Ptr context, QueueItemList & new_item
 {
     _XDEBUG("QueueItemRequire::process(" << *this << ")");
 
-    if (context->requirementIsMet (_capability, _is_child)) {
+    bool fulfilled = false;
+           
+    if (_requiring_item)
+    {
+       fulfilled = context->requirementIsInstalledOrUnneeded (_requiring_item->kind(),_capability);
+    } else {
+       fulfilled = context->requirementIsMet (_capability);
+    }
+    
+    if (fulfilled) {
        _XDEBUG("requirement is already met in current context");
        return true;
     }
@@ -436,7 +443,7 @@ QueueItemRequire::process (ResolverContext_Ptr context, QueueItemList & new_item
        }
     }
 
-    RequireProcess info (_requiring_item, _is_child ? _capability : Capability(), context,  pool());
+    RequireProcess info (_requiring_item,  Capability(), context,  pool());
 
     int num_providers = 0;
 
index dd6c0dc..175c2e4 100644 (file)
@@ -62,7 +62,6 @@ class QueueItemRequire : public QueueItem {
     PoolItem_Ref _lost_item;
 
     bool _remove_only;
-    bool _is_child;
 
   public:
 
index 1c852f6..2317a97 100644 (file)
@@ -190,7 +190,7 @@ struct UninstallProcess
        if (! context->isPresent (requirer))                            // its not installed -> dont care
            return true;
 
-       if (context->requirementIsMet( cai.cap, false ))                // its provided by another installed resolvable -> dont care
+       if (context->requirementIsMet( cai.cap ))               // its provided by another installed resolvable -> dont care
            return true;
 
        if (context->getStatus(requirer).isSatisfied()) {               // it is just satisfied, check freshens and supplements
index 0012b4a..26c536e 100644 (file)
@@ -627,25 +627,22 @@ ResolverContext::incomplete (PoolItem_Ref item, int other_penalty)
 
 //---------------------------------------------------------------------------
 
-// is it installed (after transaction) ?
+// is it installed (after transaction), is unneeded or satisfied
 // if yes, install/requires requests are considered done
 
 bool
-ResolverContext::isPresent (PoolItem_Ref item, bool *unneeded)
+ResolverContext::isPresent (PoolItem_Ref item, bool *unneeded, bool *installed)
 {
     ResStatus status = getStatus(item);
 
     bool res = ((status.staysInstalled() && !status.isIncomplete())
                || (status.isToBeInstalled() && !status.isNeeded())
                || status.isUnneeded()
-               || (status.isSatisfied()
-                   // regarding only resolvables where the status is useful Bug:192535
-                   && item->kind() != ResTraits<Package>::kind
-                   && item->kind() != ResTraits<Script>::kind
-                   && item->kind() != ResTraits<Message>::kind)
+               || status.isSatisfied()
                );
 
    if (unneeded) *unneeded = status.isUnneeded();
+   if (installed) *installed = status.staysInstalled() || status.isToBeInstalled();
 
 _XDEBUG("ResolverContext::itemIsPresent(<" << status << ">" << item << ") " << (res?"Y":"N"));
 
@@ -1431,15 +1428,15 @@ ResolverContext::spewInfo (void) const
 struct RequirementMet
 {
     ResolverContext_Ptr context;
-    const Capability capability;
     bool flag;
     bool unneeded;
+    bool *installed;
 
-    RequirementMet (ResolverContext_Ptr ctx, const Capability & c)
+    RequirementMet (ResolverContext_Ptr ctx, bool *inst)
        : context (ctx)
-       , capability (c)
        , flag (false)
        , unneeded( false )
+       , installed( inst )
     { }
 
 
@@ -1450,9 +1447,7 @@ struct RequirementMet
        // capability is set for item set children. If it is set, query the
        //   exact version only.
        bool my_unneeded = false;
-       if ((capability == Capability::noCap
-            || capability == match)
-           && context->isPresent( provider, &my_unneeded ))
+       if (context->isPresent( provider, &my_unneeded, installed ))
        {
            unneeded = my_unneeded;
            flag = true;
@@ -1460,16 +1455,20 @@ struct RequirementMet
 
 //     ERR << "RequirementMet(" <<  provider << ", " << match << ") [capability " <<
 //       capability << "] -> " <<  (flag ? "true" : "false") << endl;
-
+       
+       if ( installed // Checking as long as we have found an installed item
+            && !*installed )
+           return true;
+       
        return ! flag;
     }
 };
 
 
 bool
-ResolverContext::requirementIsMet (const Capability & capability, bool is_child, bool *unneeded)
+ResolverContext::requirementIsMet (const Capability & capability, bool *unneeded, bool *installed)
 {
-    RequirementMet info (this, is_child ? capability : Capability::noCap);
+    RequirementMet info (this, installed);
 
     //    world()->foreachProviding (capability, requirement_met_cb, (void *)&info);
 
@@ -1487,6 +1486,41 @@ _XDEBUG( "ResolverContext::requirementIsMet(" << capability << ") " << (info.fla
     return info.flag;
 }
 
+//---------------------------------------------------------------------------
+/**
+ *\return \c true if the requirement is already fulfilled.
+ *either by an installed item or the requirement is unneeded.
+ *The behaviour depends on the item kind (package,patch,..)
+ *which requires this capability.
+ */
+bool
+ResolverContext::requirementIsInstalledOrUnneeded (const ResObject::Kind & kind,
+                                                  const Capability & capability)
+{
+    bool fulfilled = false;
+           
+    if (kind != ResTraits<Package>::kind
+       || kind != ResTraits<Script>::kind
+       || kind != ResTraits<Message>::kind)
+    {
+       bool unneeded, installed;
+       fulfilled = requirementIsMet (capability, &unneeded, &installed);
+       if (!fulfilled
+           || (!unneeded
+               && !installed)) {
+           fulfilled = false;
+           _XDEBUG("Requirement is not unneeded and not installed.");
+           // "low" level resolvables will be installed if they are not unneeded
+           // Bug 192535/204913
+       }
+    }else {
+       fulfilled = requirementIsMet (capability);
+    }
+
+    return fulfilled;
+}
+
+
 
 //---------------------------------------------------------------------------
 
index 1da6533..0a1f585 100644 (file)
@@ -223,13 +223,23 @@ class ResolverContext : public base::ReferenceCounted, private base::NonCopyable
 
     /**
      *\return \c true if \c item is \a installed or \a to-be-installed */
-    bool isPresent (PoolItem_Ref item, bool *unneeded = NULL);
+    bool isPresent (PoolItem_Ref item, bool *unneeded = NULL,
+                   bool *installed = NULL);
 
     /**
      *\return \c true if \c item is \a uninstalled or \a to-be-uninstalled */
     bool isAbsent (PoolItem_Ref item);
 
-    bool requirementIsMet (const Capability & cap, bool is_child = false, bool *unneeded = NULL);
+    bool requirementIsMet (const Capability & cap, bool *unneeded = NULL,
+                          bool *installed = NULL);
+    /**
+     *\return \c true if the requirement is already fulfilled.
+     *either by an installed item or the requirement is unneeded.
+     *The behaviour depends on the item kind (package,patch,..)
+     *which requires this capability.
+     */
+    bool requirementIsInstalledOrUnneeded (const ResObject::Kind & kind,
+                                          const Capability & capability);
     bool requirementIsPossible (const Capability & cap);
     bool itemIsPossible (const PoolItem_Ref item);
     bool isParallelInstall (const PoolItem_Ref item) const;
diff --git a/zypp/solver/detail/Testcase.cc b/zypp/solver/detail/Testcase.cc
new file mode 100644 (file)
index 0000000..4d2779d
--- /dev/null
@@ -0,0 +1,77 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file       zypp/solver/detail/Testcase.cc
+ *
+*/
+#include "zypp/solver/detail/Testcase.h"
+#include "zypp/base/Logger.h"
+#include "zypp/base/LogControl.h"
+#include "zypp/PathInfo.h"
+
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////////
+  namespace solver
+  { /////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////
+    namespace detail
+    { ///////////////////////////////////////////////////////////////////
+
+using namespace std;
+
+//---------------------------------------------------------------------------
+
+Testcase::Testcase()
+    :dumpPath("/var/log/YaST2/solverTestcase")
+{
+}
+
+Testcase::Testcase(const std::string & path)
+    :dumpPath(path)
+{
+}
+       
+
+Testcase::~Testcase()
+{
+}
+
+bool Testcase::createTestcase(Resolver & resolver)
+{
+    PathInfo path (dumpPath);
+
+    if ( !path.isExist() ) {
+       if (zypp::filesystem::mkdir (dumpPath)!=0) {
+           ERR << "Cannot create directory " << dumpPath << endl;
+           return false;
+       }
+    } else {
+       if (!path.isDir()) {
+           ERR << dumpPath << " is not a directory." << endl;
+           return false;
+       }
+    }
+    zypp::base::LogControl::instance().logfile( dumpPath +"/y2log" );
+    zypp::base::LogControl::TmpExcessive excessive; // ZYPP_FULLLOG=1
+    
+    resolver.resolveDependencies();
+    
+    return true;
+}
+
+      ///////////////////////////////////////////////////////////////////
+    };// namespace detail
+    /////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////
+  };// namespace solver
+  ///////////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
diff --git a/zypp/solver/detail/Testcase.h b/zypp/solver/detail/Testcase.h
new file mode 100644 (file)
index 0000000..d43c47e
--- /dev/null
@@ -0,0 +1,61 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file       zypp/solver/detail/TestCase.h
+ *
+*/
+
+#ifndef ZYPP_SOLVER_DETAIL_TESTCASE_H
+#define ZYPP_SOLVER_DETAIL_TESTCASE_H
+
+#include <iosfwd>
+#include <string>
+#include "zypp/solver/detail/Resolver.h"
+
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////////
+  namespace solver
+  { /////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////
+    namespace detail
+    { ///////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+//
+//     CLASS NAME : Testcase
+/**
+ * Generating a testcase of the current pool and solver state
+ **/
+class Testcase {
+
+  private:
+    std::string dumpPath; // Path of the generated testcase
+    
+
+  public:
+    Testcase(const std::string & path);
+    Testcase();    
+    ~Testcase();
+
+    bool createTestcase(Resolver & resolver);
+
+};
+
+///////////////////////////////////////////////////////////////////
+    };// namespace detail
+    /////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////
+  };// namespace solver
+  ///////////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
+
+#endif // ZYPP_SOLVER_DETAIL_TESTCASE_H