#include "zypp/solver/detail/Testcase.h"
#include "zypp/base/Logger.h"
#include "zypp/base/LogControl.h"
-#include "zypp/PathInfo.h"
-#include "zypp/Product.h"
-#include "zypp/Package.h"
-#include "zypp/Edition.h"
-#include "zypp/target/store/xml_escape_parser.hpp"
-#include "zypp/capability/VersionedCap.h"
+#include "zypp/base/GzStream.h"
#include "zypp/base/String.h"
#include "zypp/base/PtrTypes.h"
+#include "zypp/base/NonCopyable.h"
+#include "zypp/base/ReferenceCounted.h"
+
+#include "zypp/parser/xml/XmlEscape.h"
+
+#include "zypp/ZConfig.h"
+#include "zypp/PathInfo.h"
+#include "zypp/ResPool.h"
+#include "zypp/Repository.h"
+#include "zypp/target/modalias/Modalias.h"
+#include "zypp/sat/detail/PoolImpl.h"
+#include "zypp/solver/detail/SystemCheck.h"
/////////////////////////////////////////////////////////////////////////
namespace zypp
/////////////////////////////////////////////////////////////////////
namespace detail
{ ///////////////////////////////////////////////////////////////////
-
+
#define TAB "\t"
#define TAB2 "\t\t"
-
+
using namespace std;
-using namespace zypp::capability;
using namespace zypp::str;
-IMPL_PTR_TYPE(HelixResolvable);
+//---------------------------------------------------------------------------
-static std::string xml_escape( const std::string &text )
+inline std::string xml_escape( const std::string &text )
{
- iobind::parser::xml_escape_parser parser;
- return parser.escape(text);
+ return zypp::xml::escape(text);
}
-static std::string xml_tag_enclose( const std::string &text, const std::string &tag, bool escape = false )
+inline std::string xml_tag_enclose( const std::string &text, const std::string &tag, bool escape = false )
{
string result;
result += "<" + tag + ">";
return result;
}
-
template<class T>
std::string helixXML( const T &obj ); //undefined
-template<>
+template<>
std::string helixXML( const Edition &edition )
{
stringstream str;
if (!edition.release().empty())
str << xml_tag_enclose(edition.release(), "release");
if (edition.epoch() != Edition::noepoch)
- str << xml_tag_enclose(numstring(edition.epoch()), "epoch");
+ str << xml_tag_enclose(numstring(edition.epoch()), "epoch");
return str.str();
}
-template<>
+template<>
std::string helixXML( const Arch &arch )
{
stringstream str;
- str << xml_tag_enclose(arch.asString(), "arch");
- return str.str();
+ str << xml_tag_enclose(arch.asString(), "arch");
+ return str.str();
}
-template<>
+template<>
std::string helixXML( const Capability &cap )
{
stringstream str;
- VersionedCap::constPtr vercap = asKind<VersionedCap>(cap);
- if (vercap
- && vercap->op() != Rel::NONE
- && vercap->op() != Rel::ANY
- && !vercap->edition().version().empty() )
- {
- // version capability
- str << "<dep name='" << xml_escape(vercap->index()) << "' op='" << xml_escape(vercap->op().asString()) <<
- "' version='" << vercap->edition().version() << "'";
- if (!vercap->edition().release().empty())
- str << " release='" << vercap->edition().release() << "'";
- if (vercap->edition().epoch() != Edition::noepoch)
- str << " epoch='" << numstring(vercap->edition().epoch()) << "'";
+ CapDetail detail = cap.detail();
+ if (detail.isSimple()) {
+ if (detail.isVersioned()) {
+ str << "<dep name='" << xml_escape(detail.name().asString()) << "'"
+ << " op='" << xml_escape(detail.op().asString()) << "'"
+ << " version='" << xml_escape(detail.ed().version()) << "'";
+ if (!detail.ed().release().empty())
+ str << " release='" << xml_escape(detail.ed().release()) << "'";
+ if (detail.ed().epoch() != Edition::noepoch)
+ str << " epoch='" << xml_escape(numstring(detail.ed().epoch())) << "'";
+ str << " />" << endl;
+ } else {
+ str << "<dep name='" << xml_escape(cap.asString()) << "' />" << endl;
+ }
+ } else if (detail.isExpression()) {
+ if (detail.capRel() == CapDetail::CAP_AND
+ && detail.lhs().detail().isNamed()
+ && detail.rhs().detail().isNamed()) {
+ // packageand dependency
+ str << "<dep name='packageand("
+ << IdString(detail.lhs().id()) << ":"
+ << IdString(detail.rhs().id()) << ")' />" << endl;
+ } else if (detail.capRel() == CapDetail::CAP_NAMESPACE
+ && detail.lhs().id() == NAMESPACE_OTHERPROVIDERS) {
+ str << "<dep name='otherproviders("
+ << IdString(detail.rhs().id()) << ")' />" << endl;
+ } else {
+ // modalias ?
+ IdString packageName;
+ if (detail.capRel() == CapDetail::CAP_AND) {
+ packageName = IdString(detail.lhs().id());
+ detail = detail.rhs().detail();
+ }
+ if (detail.capRel() == CapDetail::CAP_NAMESPACE
+ && detail.lhs().id() == NAMESPACE_MODALIAS) {
+ str << "<dep name='modalias(";
+ if (!packageName.empty())
+ str << packageName << ":";
+ str << IdString(detail.rhs().id()) << ")' />" << endl;
+ } else {
+ str << "<!--- ignoring '" << xml_escape(cap.asString()) << "' -->" << endl;
+ }
+ }
+ } else {
+ str << "<!--- ignoring '" << xml_escape(cap.asString()) << "' -->" << endl;
}
- else
+
+ return str.str();
+}
+
+template<>
+std::string helixXML( const Capabilities &caps )
+{
+ stringstream str;
+ Capabilities::const_iterator it = caps.begin();
+ str << endl;
+ for ( ; it != caps.end(); ++it)
{
- str << "<dep name='" << xml_escape(cap.asString()) << "'";
+ str << TAB2 << helixXML((*it));
}
-
- str << " kind=\"" << toLower (cap.refers().asString()) << "\""
- << " />" << endl;
-
- return str.str();
+ str << TAB;
+ return str.str();
}
-template<>
-std::string helixXML( const CapSet &caps )
+template<>
+std::string helixXML( const CapabilitySet &caps )
{
stringstream str;
- CapSet::iterator it = caps.begin();
+ CapabilitySet::const_iterator it = caps.begin();
str << endl;
for ( ; it != caps.end(); ++it)
{
return str.str();
}
-template<>
-std::string helixXML( const Dependencies &dep )
+inline string helixXML( const Resolvable::constPtr &obj, Dep deptag_r )
{
- stringstream str;
- if ( dep[Dep::PROVIDES].size() > 0 )
- str << TAB << xml_tag_enclose(helixXML(dep[Dep::PROVIDES]), "provides") << endl;
- if ( dep[Dep::CONFLICTS].size() > 0 )
- str << TAB << xml_tag_enclose(helixXML(dep[Dep::CONFLICTS]), "conflicts") << endl;
- if ( dep[Dep::OBSOLETES].size() > 0 )
- str << TAB << xml_tag_enclose(helixXML(dep[Dep::OBSOLETES]), "obsoletes") << endl;
- if ( dep[Dep::FRESHENS].size() > 0 )
- str << TAB << xml_tag_enclose(helixXML(dep[Dep::FRESHENS]), "freshens") << endl;
- if ( dep[Dep::REQUIRES].size() > 0 )
- str << TAB << xml_tag_enclose(helixXML(dep[Dep::REQUIRES]), "requires") << endl;
- if ( dep[Dep::RECOMMENDS].size() > 0 )
- str << TAB << xml_tag_enclose(helixXML(dep[Dep::RECOMMENDS]), "recommends") << endl;
- if ( dep[Dep::ENHANCES].size() > 0 )
- str << TAB << xml_tag_enclose(helixXML(dep[Dep::ENHANCES]), "enhances") << endl;
- if ( dep[Dep::SUPPLEMENTS].size() > 0 )
- str << TAB << xml_tag_enclose(helixXML(dep[Dep::SUPPLEMENTS]), "supplements") << endl;
- if ( dep[Dep::SUGGESTS].size() > 0 )
- str << TAB << xml_tag_enclose(helixXML(dep[Dep::SUGGESTS]), "suggests") << endl;
- return str.str();
+ stringstream out;
+ Capabilities caps( obj->dep(deptag_r) );
+ if ( ! caps.empty() )
+ out << TAB << xml_tag_enclose(helixXML(caps), deptag_r.asString()) << endl;
+ return out.str();
}
-std::string helixXML( const PoolItem_Ref &item )
+std::string helixXML( const PoolItem &item )
{
const Resolvable::constPtr resolvable = item.resolvable();
stringstream str;
- if ( isKind<SystemResObject>(resolvable)
- || isKind<Language>(resolvable) ) {
- // system resolvable will be generated by the resolver
- // language dependencies will be written i another part
- return str.str();
- }
-
str << "<" << toLower (resolvable->kind().asString()) << ">" << endl;
str << TAB << xml_tag_enclose (resolvable->name(), "name", true) << endl;
- str << TAB << xml_tag_enclose (item->vendor(), "vendor", true) << endl;
+ str << TAB << xml_tag_enclose (item->vendor(), "vendor", true) << endl;
+ str << TAB << xml_tag_enclose (item->buildtime().asSeconds(), "buildtime", true) << endl;
if ( isKind<Package>(resolvable) ) {
str << TAB << "<history>" << endl << TAB << "<update>" << endl;
str << TAB2 << helixXML (resolvable->arch()) << endl;
- str << TAB2 << helixXML (resolvable->edition()) << endl;
+ str << TAB2 << helixXML (resolvable->edition()) << endl;
str << TAB << "</update>" << endl << TAB << "</history>" << endl;
} else {
- str << TAB << helixXML (resolvable->arch()) << endl;
- str << TAB << helixXML (resolvable->edition()) << endl;
+ str << TAB << helixXML (resolvable->arch()) << endl;
+ str << TAB << helixXML (resolvable->edition()) << endl;
}
- str << helixXML (resolvable->deps());
-
- str << "</" << toLower (resolvable->kind().asString()) << ">" << endl;
+ str << helixXML( resolvable, Dep::PROVIDES);
+ str << helixXML( resolvable, Dep::PREREQUIRES);
+ str << helixXML( resolvable, Dep::CONFLICTS);
+ str << helixXML( resolvable, Dep::OBSOLETES);
+ str << helixXML( resolvable, Dep::REQUIRES);
+ str << helixXML( resolvable, Dep::RECOMMENDS);
+ str << helixXML( resolvable, Dep::ENHANCES);
+ str << helixXML( resolvable, Dep::SUPPLEMENTS);
+ str << helixXML( resolvable, Dep::SUGGESTS);
+
+ str << "</" << toLower (resolvable->kind().asString()) << ">" << endl;
return str.str();
}
-//---------------------------------------------------------------------------
-
-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;
- }
- // remove old stuff
- zypp::filesystem::clean_dir (dumpPath);
- }
-
- zypp::base::LogControl::instance().logfile( dumpPath +"/y2log" );
- zypp::base::LogControl::TmpExcessive excessive;
-
- resolver.reset(true); // true = resetting all valid solverresults
- resolver.resolvePool();
+///////////////////////////////////////////////////////////////////
+//
+// CLASS NAME : HelixResolvable
+/**
+ * Creates a file in helix format which includes all available
+ * or installed packages,patches,selections.....
+ **/
+class HelixResolvable : public base::ReferenceCounted, private base::NonCopyable{
- zypp::base::LogControl::instance().logfile( "/var/log/YaST2/y2log" );
+ private:
+ std::string dumpFile; // Path of the generated testcase
+ ofgzstream *file;
- ResPool pool = resolver.pool();
- RepositoryTable repoTable;
- PoolItemList items_to_install;
- PoolItemList items_to_remove;
- PoolItemList items_locked;
- PoolItemList items_keep;
- PoolItemList language;
- HelixResolvable system (dumpPath + "/solver-system.xml");
+ public:
+ HelixResolvable (const std::string & path);
+ ~HelixResolvable ();
- for ( ResPool::const_iterator it = pool.begin(); it != pool.end(); ++it )
- {
- Resolvable::constPtr res = it->resolvable();
+ void addResolvable (const PoolItem item)
+ { *file << helixXML (item); }
- if (isKind<Language>(res)) {
- if ( it->status().isInstalled()
- || it->status().isToBeInstalled()) {
- language.push_back (*it);
- }
- } else {
- if ( it->status().isInstalled() ) {
- // system channel
- system.addResolvable (*it);
- } else {
- // repo channels
- ResObject::constPtr repoItem = it->resolvable();
- Repository repo = repoItem->repository();
- if (repoTable.find (repo) == repoTable.end()) {
- repoTable[repo] = new HelixResolvable(dumpPath + "/"
- + numstring(repo.numericId())
- + "-package.xml");
- }
- repoTable[repo]->addResolvable (*it);
- }
-
- if ( it->status().isToBeInstalled()
- && !(it->status().isBySolver())) {
- items_to_install.push_back (*it);
- }
- if ( it->status().isKept()
- && !(it->status().isBySolver())) {
- items_keep.push_back (*it);
- }
- if ( it->status().isToBeUninstalled()
- && !(it->status().isBySolver())) {
- items_to_remove.push_back (*it);
- }
- if ( it->status().isLocked()
- && !(it->status().isBySolver())
- && !isKind<SystemResObject>(res)) {
- items_locked.push_back (*it);
- }
-
- }
- }
+ std::string filename ()
+ { return dumpFile; }
+};
- // writing control file "*-test.xml"
+DEFINE_PTR_TYPE(HelixResolvable);
+IMPL_PTR_TYPE(HelixResolvable);
- HelixControl control (dumpPath + "/solver-test.xml",
- repoTable,
- resolver.architecture(),
- language);
-
- for (PoolItemList::const_iterator iter = items_to_install.begin(); iter != items_to_install.end(); iter++) {
- control.installResolvable (iter->resolvable());
- }
-
- for (PoolItemList::const_iterator iter = items_locked.begin(); iter != items_locked.end(); iter++) {
- control.lockResolvable (iter->resolvable());
- }
-
- for (PoolItemList::const_iterator iter = items_keep.begin(); iter != items_keep.end(); iter++) {
- control.keepResolvable (iter->resolvable());
- }
-
- for (PoolItemList::const_iterator iter = items_to_remove.begin(); iter != items_to_remove.end(); iter++) {
- control.deleteResolvable (iter->resolvable());
- }
-
- control.addDependencies (resolver.extraCapability(), resolver.extraConflicts());
-
- return true;
-}
-
-//---------------------------------------------------------------------------
+typedef std::map<Repository, HelixResolvable_Ptr> RepositoryTable;
HelixResolvable::HelixResolvable(const std::string & path)
- :dumpFile (path)
+ :dumpFile (path)
{
- file = new ofstream(path.c_str());
+ file = new ofgzstream(path.c_str());
if (!file) {
ZYPP_THROW (Exception( "Can't open " + path ) );
}
HelixResolvable::~HelixResolvable()
{
*file << "</subchannel></channel>" << endl;
+ delete(file);
}
-
-void HelixResolvable::addResolvable(const PoolItem_Ref item)
-{
- *file << helixXML (item);
-}
-
-//---------------------------------------------------------------------------
+///////////////////////////////////////////////////////////////////
+//
+// CLASS NAME : HelixControl
+/**
+ * Creates a file in helix format which contains all controll
+ * action of a testcase ( file is known as *-test.xml)
+ **/
+class HelixControl {
+
+ private:
+ std::string dumpFile; // Path of the generated testcase
+ std::ofstream *file;
+
+ public:
+ HelixControl (const std::string & controlPath,
+ const RepositoryTable & sourceTable,
+ const Arch & systemArchitecture,
+ const LocaleSet &languages,
+ const target::Modalias::ModaliasList & modaliasList,
+ const std::set<std::string> & multiversionSpec,
+ const std::string & systemPath,
+ const bool forceResolve,
+ const bool onlyRequires,
+ const bool ignorealreadyrecommended);
+ HelixControl ();
+ ~HelixControl ();
+
+ void installResolvable (const ResObject::constPtr &resObject,
+ const ResStatus &status);
+ void lockResolvable (const ResObject::constPtr &resObject,
+ const ResStatus &status);
+ void keepResolvable (const ResObject::constPtr &resObject,
+ const ResStatus &status);
+ void deleteResolvable (const ResObject::constPtr &resObject,
+ const ResStatus &status);
+ void addDependencies (const CapabilitySet &capRequire, const CapabilitySet &capConflict);
+ void addUpgradeRepos( const std::set<Repository> & upgradeRepos_r );
+
+ void distupgrade ();
+ void verifySystem ();
+ void update ();
+
+ std::string filename () { return dumpFile; }
+};
HelixControl::HelixControl(const std::string & controlPath,
const RepositoryTable & repoTable,
const Arch & systemArchitecture,
- const PoolItemList &languages,
- const std::string & systemPath)
- :dumpFile (controlPath)
+ const LocaleSet &languages,
+ const target::Modalias::ModaliasList & modaliasList,
+ const std::set<std::string> & multiversionSpec,
+ const std::string & systemPath,
+ const bool forceResolve,
+ const bool onlyRequires,
+ const bool ignorealreadyrecommended)
+ :dumpFile (controlPath)
{
file = new ofstream(controlPath.c_str());
if (!file) {
<< TAB << "<system file=\"" << systemPath << "\"/>" << endl << endl;
for ( RepositoryTable::const_iterator it = repoTable.begin();
it != repoTable.end(); ++it ) {
- Repository repo = it->first;
+ RepoInfo repo = it->first.info();
*file << TAB << "<!-- " << endl
- << TAB << "- alias : " << repo.info().alias() << endl;
- for ( RepoInfo::urls_const_iterator itUrl = repo.info().baseUrlsBegin();
- itUrl != repo.info().baseUrlsEnd();
+ << TAB << "- alias : " << repo.alias() << endl;
+ for ( RepoInfo::urls_const_iterator itUrl = repo.baseUrlsBegin();
+ itUrl != repo.baseUrlsEnd();
++itUrl )
{
*file << TAB << "- url : " << *itUrl << endl;
- }
- *file << TAB << "- path : " << repo.info().path() << endl;
- *file << TAB << "- type : " << repo.info().type() << endl;
+ }
+ *file << TAB << "- path : " << repo.path() << endl;
+ *file << TAB << "- type : " << repo.type() << endl;
+ *file << TAB << "- generated : " << (it->first.generatedTimestamp()).form( "%Y-%m-%d %H:%M:%S" ) << endl;
+ *file << TAB << "- outdated : " << (it->first.suggestedExpirationTimestamp()).form( "%Y-%m-%d %H:%M:%S" ) << endl;
*file << TAB << " -->" << endl;
-
- *file << TAB << "<channel file=\"" << numstring(repo.numericId())
- << "-package.xml\" name=\"" << numstring(repo.numericId())
+
+ *file << TAB << "<channel file=\"" << str::numstring((long)it->first.id())
+ << "-package.xml.gz\" name=\"" << repo.alias() << "\""
+ << " priority=\"" << repo.priority()
<< "\" />" << endl << endl;
}
- for (PoolItemList::const_iterator iter = languages.begin(); iter != languages.end(); iter++) {
- *file << TAB << "<locale name=\"" << iter->resolvable()->name()
+
+ for (LocaleSet::const_iterator iter = languages.begin(); iter != languages.end(); iter++) {
+ *file << TAB << "<locale name=\"" << iter->code()
<< "\" />" << endl;
- }
+ }
+
+ for_( it, modaliasList.begin(), modaliasList.end() ) {
+ *file << TAB << "<modalias name=\"" << *it
+ << "\" />" << endl;
+ }
+
+ for_( it, multiversionSpec.begin(), multiversionSpec.end() ) {
+ *file << TAB << "<multiversion name=\"" << *it
+ << "\" />" << endl;
+ }
+
+ if (forceResolve)
+ *file << TAB << "<forceResolve/>" << endl;
+ if (onlyRequires)
+ *file << TAB << "<onlyRequires/>" << endl;
+ if (ignorealreadyrecommended)
+ *file << TAB << "<ignorealreadyrecommended/>" << endl;
+
*file << "</setup>" << endl
- << "<trial>" << endl
- << "<showpool all=\"yes\"/>" << endl
- << "<establish/>" << endl
- << "<showpool all=\"true\" prefix=\">!> ESTABLISHED:\"/>" << endl;
+ << "<trial>" << endl;
}
HelixControl::HelixControl()
{
*file << "</trial>" << endl
<< "</test>" << endl;
+ delete(file);
}
-void HelixControl::installResolvable(const ResObject::constPtr &resObject)
+void HelixControl::installResolvable(const ResObject::constPtr &resObject,
+ const ResStatus &status)
{
- Repository repo = resObject->repository();
- *file << "<install channel=\"" << numstring(repo.numericId()) << "\" kind=\"" << toLower (resObject->kind().asString()) << "\""
+ *file << "<install channel=\"" << resObject->repoInfo().alias() << "\" kind=\"" << toLower (resObject->kind().asString()) << "\""
<< " name=\"" << resObject->name() << "\"" << " arch=\"" << resObject->arch().asString() << "\""
- << " version=\"" << resObject->edition().version() << "\"" << " release=\"" << resObject->edition().release() << "\""
+ << " version=\"" << resObject->edition().version() << "\"" << " release=\"" << resObject->edition().release() << "\""
+ << " status=\"" << status << "\""
<< "/>" << endl;
}
-void HelixControl::lockResolvable(const ResObject::constPtr &resObject)
+void HelixControl::lockResolvable(const ResObject::constPtr &resObject,
+ const ResStatus &status)
{
- Repository repo = resObject->repository();
- *file << "<lock channel=\"" << numstring(repo.numericId()) << "\" kind=\"" << toLower (resObject->kind().asString()) << "\""
+ *file << "<lock channel=\"" << resObject->repoInfo().alias() << "\" kind=\"" << toLower (resObject->kind().asString()) << "\""
<< " name=\"" << resObject->name() << "\"" << " arch=\"" << resObject->arch().asString() << "\""
- << " version=\"" << resObject->edition().version() << "\"" << " release=\"" << resObject->edition().release() << "\""
+ << " version=\"" << resObject->edition().version() << "\"" << " release=\"" << resObject->edition().release() << "\""
+ << " status=\"" << status << "\""
<< "/>" << endl;
}
-void HelixControl::keepResolvable(const ResObject::constPtr &resObject)
+void HelixControl::keepResolvable(const ResObject::constPtr &resObject,
+ const ResStatus &status)
{
- Repository repo = resObject->repository();
- *file << "<keep channel=\"" << numstring(repo.numericId()) << "\" kind=\"" << toLower (resObject->kind().asString()) << "\""
+ *file << "<keep channel=\"" << resObject->repoInfo().alias() << "\" kind=\"" << toLower (resObject->kind().asString()) << "\""
<< " name=\"" << resObject->name() << "\"" << " arch=\"" << resObject->arch().asString() << "\""
- << " version=\"" << resObject->edition().version() << "\"" << " release=\"" << resObject->edition().release() << "\""
+ << " version=\"" << resObject->edition().version() << "\"" << " release=\"" << resObject->edition().release() << "\""
+ << " status=\"" << status << "\""
<< "/>" << endl;
}
-
-void HelixControl::deleteResolvable(const ResObject::constPtr &resObject)
+
+void HelixControl::deleteResolvable(const ResObject::constPtr &resObject,
+ const ResStatus &status)
{
- Repository repo = resObject->repository();
*file << "<uninstall " << " kind=\"" << toLower (resObject->kind().asString()) << "\""
- << " name=\"" << resObject->name() << "\"" << "/>" << endl;
+ << " name=\"" << resObject->name() << "\""
+ << " status=\"" << status << "\""
+ << "/>" << endl;
}
-void HelixControl::addDependencies (const CapSet & capRequire, const CapSet & capConflict)
+void HelixControl::addDependencies (const CapabilitySet & capRequire, const CapabilitySet & capConflict)
{
- for (CapSet::const_iterator iter = capRequire.begin(); iter != capRequire.end(); iter++) {
- *file << "<addRequire " << " kind=\"" << toLower (iter->kind().asString()) << "\""
- << " name=\"" << iter->asString() << "\"" << "/>" << endl;
+ for (CapabilitySet::const_iterator iter = capRequire.begin(); iter != capRequire.end(); iter++) {
+ *file << "<addRequire " << " name=\"" << iter->asString() << "\"" << "/>" << endl;
+ }
+ for (CapabilitySet::const_iterator iter = capConflict.begin(); iter != capConflict.end(); iter++) {
+ *file << "<addConflict " << " name=\"" << iter->asString() << "\"" << "/>" << endl;
}
- for (CapSet::const_iterator iter = capConflict.begin(); iter != capConflict.end(); iter++) {
- *file << "<addConflict " << " kind=\"" << toLower (iter->kind().asString()) << "\""
- << " name=\"" << iter->asString() << "\"" << "/>" << endl;
- }
+}
+
+void HelixControl::addUpgradeRepos( const std::set<Repository> & upgradeRepos_r )
+{
+ for_( it, upgradeRepos_r.begin(), upgradeRepos_r.end() )
+ {
+ *file << "<upgradeRepo name=\"" << it->alias() << "\"/>" << endl;
+ }
+}
+
+void HelixControl::distupgrade()
+{
+ *file << "<distupgrade/>" << endl;
+}
+
+void HelixControl::verifySystem()
+{
+ *file << "<verify/>" << endl;
+}
+
+void HelixControl::update()
+{
+ *file << "<update/>" << endl;
+}
+
+//---------------------------------------------------------------------------
+
+Testcase::Testcase()
+ :dumpPath("/var/log/YaST2/solverTestcase")
+{}
+
+Testcase::Testcase(const std::string & path)
+ :dumpPath(path)
+{}
+
+Testcase::~Testcase()
+{}
+
+bool Testcase::createTestcase(Resolver & resolver, bool dumpPool, bool runSolver)
+{
+ PathInfo path (dumpPath);
+
+ if ( !path.isExist() ) {
+ if (zypp::filesystem::assert_dir (dumpPath)!=0) {
+ ERR << "Cannot create directory " << dumpPath << endl;
+ return false;
+ }
+ } else {
+ if (!path.isDir()) {
+ ERR << dumpPath << " is not a directory." << endl;
+ return false;
+ }
+ // remove old stuff if pool will be dump
+ if (dumpPool)
+ zypp::filesystem::clean_dir (dumpPath);
+ }
+
+ if (runSolver) {
+ zypp::base::LogControl::TmpLineWriter tempRedirect;
+ zypp::base::LogControl::instance().logfile( dumpPath +"/y2log" );
+ zypp::base::LogControl::TmpExcessive excessive;
+
+ resolver.resolvePool();
+ }
+
+ ResPool pool = resolver.pool();
+ RepositoryTable repoTable;
+ PoolItemList items_to_install;
+ PoolItemList items_to_remove;
+ PoolItemList items_locked;
+ PoolItemList items_keep;
+ HelixResolvable_Ptr system = NULL;
+
+ if (dumpPool)
+ system = new HelixResolvable(dumpPath + "/solver-system.xml.gz");
+
+ for ( ResPool::const_iterator it = pool.begin(); it != pool.end(); ++it )
+ {
+ Resolvable::constPtr res = it->resolvable();
+
+ if ( system && it->status().isInstalled() ) {
+ // system channel
+ system->addResolvable (*it);
+ } else {
+ // repo channels
+ Repository repo = it->resolvable()->satSolvable().repository();
+ if (dumpPool) {
+ if (repoTable.find (repo) == repoTable.end()) {
+ repoTable[repo] = new HelixResolvable(dumpPath + "/"
+ + str::numstring((long)repo.id())
+ + "-package.xml.gz");
+ }
+ repoTable[repo]->addResolvable (*it);
+ }
+ }
+
+ if ( it->status().isToBeInstalled()
+ && !(it->status().isBySolver())) {
+ items_to_install.push_back (*it);
+ }
+ if ( it->status().isKept()
+ && !(it->status().isBySolver())) {
+ items_keep.push_back (*it);
+ }
+ if ( it->status().isToBeUninstalled()
+ && !(it->status().isBySolver())) {
+ items_to_remove.push_back (*it);
+ }
+ if ( it->status().isLocked()
+ && !(it->status().isBySolver())) {
+ items_locked.push_back (*it);
+ }
+ }
+
+ // writing control file "*-test.xml"
+ HelixControl control (dumpPath + "/solver-test.xml",
+ repoTable,
+ ZConfig::instance().systemArchitecture(),
+ pool.getRequestedLocales(),
+ target::Modalias::instance().modaliasList(),
+ ZConfig::instance().multiversionSpec(),
+ "solver-system.xml.gz",
+ resolver.forceResolve(),
+ resolver.onlyRequires(),
+ resolver.ignoreAlreadyRecommended() );
+
+ for (PoolItemList::const_iterator iter = items_to_install.begin(); iter != items_to_install.end(); iter++) {
+ control.installResolvable (iter->resolvable(), iter->status());
+ }
+
+ for (PoolItemList::const_iterator iter = items_locked.begin(); iter != items_locked.end(); iter++) {
+ control.lockResolvable (iter->resolvable(), iter->status());
+ }
+
+ for (PoolItemList::const_iterator iter = items_keep.begin(); iter != items_keep.end(); iter++) {
+ control.keepResolvable (iter->resolvable(), iter->status());
+ }
+
+ for (PoolItemList::const_iterator iter = items_to_remove.begin(); iter != items_to_remove.end(); iter++) {
+ control.deleteResolvable (iter->resolvable(), iter->status());
+ }
+
+ control.addDependencies (resolver.extraRequires(), resolver.extraConflicts());
+ control.addDependencies (SystemCheck::instance().requiredSystemCap(),
+ SystemCheck::instance().conflictSystemCap());
+ control.addUpgradeRepos( resolver.upgradeRepos() );
+
+ if (resolver.isUpgradeMode())
+ control.distupgrade ();
+ if (resolver.isUpdateMode())
+ control.update();
+ if (resolver.isVerifyingMode())
+ control.verifySystem();
+
+ return true;
}