Testcase.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include <iostream>
00013 #include <fstream>
00014 #include <sstream>
00015 #include <streambuf>
00016 
00017 #include "zypp/solver/detail/Testcase.h"
00018 #include "zypp/base/Logger.h"
00019 #include "zypp/base/LogControl.h"
00020 #include "zypp/PathInfo.h"
00021 #include "zypp/Product.h"
00022 #include "zypp/Package.h"
00023 #include "zypp/Edition.h"
00024 #include "zypp/target/store/xml_escape_parser.hpp"
00025 #include "zypp/capability/VersionedCap.h"
00026 #include "zypp/base/String.h"
00027 #include "zypp/base/PtrTypes.h"
00028 
00029 
00031 namespace zypp
00032 { 
00033 
00034   namespace solver
00035   { 
00036 
00037     namespace detail
00038     { 
00039         
00040 #define TAB "\t"
00041 #define TAB2 "\t\t"
00042         
00043 using namespace std;
00044 using namespace zypp::capability;
00045 using namespace zypp::str;
00046 
00047 IMPL_PTR_TYPE(HelixResolvable); 
00048 
00049 static std::string xml_escape( const std::string &text )
00050 {
00051   iobind::parser::xml_escape_parser parser;
00052   return parser.escape(text);
00053 }
00054 
00055 static std::string xml_tag_enclose( const std::string &text, const std::string &tag, bool escape = false )
00056 {
00057   string result;
00058   result += "<" + tag + ">";
00059 
00060   if ( escape)
00061    result += xml_escape(text);
00062   else
00063    result += text;
00064 
00065   result += "</" + tag + ">";
00066   return result;
00067 }
00068 
00069         
00070 template<class T>
00071 std::string helixXML( const T &obj ); //undefined
00072 
00073 template<> 
00074 std::string helixXML( const Edition &edition )
00075 {
00076     stringstream str;
00077     str << xml_tag_enclose(edition.version(), "version");
00078     if (!edition.release().empty())
00079         str << xml_tag_enclose(edition.release(), "release");
00080     if (edition.epoch() != Edition::noepoch)
00081         str << xml_tag_enclose(numstring(edition.epoch()), "epoch");    
00082     return str.str();
00083 }
00084 
00085 template<> 
00086 std::string helixXML( const Arch &arch )
00087 {
00088     stringstream str;
00089     str << xml_tag_enclose(arch.asString(), "arch");        
00090     return str.str();    
00091 }
00092 
00093 template<> 
00094 std::string helixXML( const Capability &cap )
00095 {
00096     stringstream str;
00097     if (isKind<VersionedCap>(cap)
00098         && cap.op() != Rel::NONE
00099         && cap.op() != Rel::ANY
00100         && !cap.edition().version().empty()) {
00101         // version capability
00102         str << "<dep name='" << xml_escape(cap.index()) << "' op='" << xml_escape(cap.op().asString()) <<
00103             "' version='" << cap.edition().version() << "'";
00104         if (!cap.edition().release().empty())
00105             str << " release='" << cap.edition().release() << "'";
00106         if (cap.edition().epoch() != Edition::noepoch)
00107             str << " epoch='" << numstring(cap.edition().epoch()) << "'";
00108     } else {
00109         // anything else
00110         str << "<dep name='" << xml_escape(cap.asString()) << "'";
00111     }
00112     str << " kind=\"" << toLower (cap.refers().asString()) << "\""
00113         << " />" << endl;
00114         
00115     return str.str();    
00116 }
00117 
00118 template<> 
00119 std::string helixXML( const CapSet &caps )
00120 {
00121     stringstream str;
00122     CapSet::iterator it = caps.begin();
00123     str << endl;
00124     for ( ; it != caps.end(); ++it)
00125     {
00126         str << TAB2 << helixXML((*it));
00127     }
00128     str << TAB;
00129     return str.str();
00130 }
00131 
00132 template<> 
00133 std::string helixXML( const Dependencies &dep )
00134 {
00135     stringstream str;
00136     if ( dep[Dep::PROVIDES].size() > 0 )
00137         str << TAB << xml_tag_enclose(helixXML(dep[Dep::PROVIDES]), "provides") << endl;
00138     if ( dep[Dep::CONFLICTS].size() > 0 )
00139         str << TAB << xml_tag_enclose(helixXML(dep[Dep::CONFLICTS]), "conflicts") << endl;
00140     if ( dep[Dep::OBSOLETES].size() > 0 )
00141         str << TAB << xml_tag_enclose(helixXML(dep[Dep::OBSOLETES]), "obsoletes") << endl;
00142     if ( dep[Dep::FRESHENS].size() > 0 )
00143         str << TAB << xml_tag_enclose(helixXML(dep[Dep::FRESHENS]), "freshens") << endl;
00144     if ( dep[Dep::REQUIRES].size() > 0 )
00145         str << TAB << xml_tag_enclose(helixXML(dep[Dep::REQUIRES]), "requires") << endl;  
00146     if ( dep[Dep::RECOMMENDS].size() > 0 )
00147         str << TAB << xml_tag_enclose(helixXML(dep[Dep::RECOMMENDS]), "recommends") << endl;
00148     if ( dep[Dep::ENHANCES].size() > 0 )
00149         str << TAB << xml_tag_enclose(helixXML(dep[Dep::ENHANCES]), "enhances") << endl;
00150     if ( dep[Dep::SUPPLEMENTS].size() > 0 )
00151         str << TAB << xml_tag_enclose(helixXML(dep[Dep::SUPPLEMENTS]), "supplements") << endl;
00152     if ( dep[Dep::SUGGESTS].size() > 0 )
00153         str << TAB << xml_tag_enclose(helixXML(dep[Dep::SUGGESTS]), "suggests") << endl;
00154     return str.str();    
00155 }
00156 
00157 std::string helixXML( const Resolvable::constPtr &resolvable )
00158 {
00159   stringstream str;
00160   str << "<" << toLower (resolvable->kind().asString()) << ">" << endl;
00161   str << TAB << xml_tag_enclose (resolvable->name(), "name", true) << endl;  
00162   if ( isKind<Package>(resolvable) ) {
00163       str << TAB << "<history>" << endl << TAB << "<update>" << endl;
00164       str << TAB2 << helixXML (resolvable->arch()) << endl;
00165       str << TAB2 << helixXML (resolvable->edition()) << endl;      
00166       str << TAB << "</update>" << endl << TAB << "</history>" << endl;
00167   } else {
00168       str << TAB << helixXML (resolvable->arch()) << endl;      
00169       str << TAB << helixXML (resolvable->edition()) << endl;            
00170   }
00171   str << helixXML (resolvable->deps());              
00172 
00173   str << "</" << toLower (resolvable->kind().asString()) << ">" << endl;  
00174   return str.str();
00175 }
00176 
00177 //---------------------------------------------------------------------------
00178 
00179 Testcase::Testcase()
00180     :dumpPath("/var/log/YaST2/solverTestcase")    
00181 {
00182 }
00183 
00184 Testcase::Testcase(const std::string & path)
00185     :dumpPath(path)
00186 {
00187 }
00188         
00189 
00190 Testcase::~Testcase()
00191 {
00192 }
00193 
00194 bool Testcase::createTestcase(Resolver & resolver)
00195 {
00196     PathInfo path (dumpPath);
00197 
00198     if ( !path.isExist() ) {
00199         if (zypp::filesystem::mkdir (dumpPath)!=0) {
00200             ERR << "Cannot create directory " << dumpPath << endl;
00201             return false;
00202         }
00203     } else {
00204         if (!path.isDir()) {
00205             ERR << dumpPath << " is not a directory." << endl;
00206             return false;
00207         }
00208         // remove old stuff
00209         zypp::filesystem::clean_dir (dumpPath);
00210     }
00211     
00212     zypp::base::LogControl::instance().logfile( dumpPath +"/y2log" );
00213     zypp::base::LogControl::TmpExcessive excessive;
00214     
00215     resolver.resolvePool();
00216 
00217     zypp::base::LogControl::instance().logfile( "/var/log/YaST2/y2log" );    
00218 
00219     ResPool pool        = resolver.pool();
00220     SourceTable         sourceTable;
00221     PoolItemList        items_to_install;
00222     PoolItemList        items_to_remove;    
00223     HelixResolvable     system (dumpPath + "/solver-system.xml");    
00224 
00225     for ( ResPool::const_iterator it = pool.begin(); it != pool.end(); ++it )
00226     {
00227         Resolvable::constPtr res = it->resolvable();
00228         
00229         if ( it->status().isInstalled() ) {
00230             // system channel
00231             system.addResolvable (res);
00232         } else {
00233             // source channels
00234             ResObject::constPtr sourceItem = it->resolvable();
00235             Source_Ref source  = sourceItem->source();
00236             if (sourceTable.find (source) == sourceTable.end()) {
00237                 sourceTable[source] = new HelixResolvable(dumpPath + "/"
00238                                                           + numstring(source.numericId())
00239                                                           + "-package.xml");
00240             }
00241             sourceTable[source]->addResolvable (res);
00242         }
00243         
00244         if ( it->status().isToBeInstalled()
00245              && !(it->status().isBySolver())) {
00246             items_to_install.push_back (*it);
00247         }
00248         if ( it->status().isToBeUninstalled()
00249              && !(it->status().isBySolver())) {
00250             items_to_remove.push_back (*it);
00251         }
00252     }
00253 
00254     // writing control file "*-test.xml"
00255 
00256     HelixControl control (dumpPath + "/solver-test.xml",
00257                           sourceTable,
00258                           resolver.architecture());
00259 
00260     for (PoolItemList::const_iterator iter = items_to_install.begin(); iter != items_to_install.end(); iter++) {
00261         control.installResolvable (iter->resolvable()); 
00262     }
00263 
00264     for (PoolItemList::const_iterator iter = items_to_remove.begin(); iter != items_to_remove.end(); iter++) {
00265         control.deleteResolvable (iter->resolvable());  
00266     }
00267 
00268     return true;
00269 }
00270 
00271 //---------------------------------------------------------------------------
00272 
00273 HelixResolvable::HelixResolvable(const std::string & path)
00274     :dumpFile (path)    
00275 {
00276     file = new ofstream(path.c_str());
00277     if (!file) {
00278         ZYPP_THROW (Exception( "Can't open " + path ) );
00279     }
00280 
00281     *file << "<channel><subchannel>" << endl;
00282 }
00283 
00284 HelixResolvable::~HelixResolvable()
00285 {
00286     *file << "</subchannel></channel>" << endl;
00287 }
00288     
00289 
00290 void HelixResolvable::addResolvable(const Resolvable::constPtr &resolvable)
00291 {
00292     *file << helixXML (resolvable);
00293 }
00294 
00295 //---------------------------------------------------------------------------
00296 
00297 HelixControl::HelixControl(const std::string & controlPath,
00298                            const SourceTable & sourceTable,
00299                            const Arch & systemArchitecture,                        
00300                            const std::string & systemPath)
00301     :dumpFile (controlPath) 
00302 {
00303     file = new ofstream(controlPath.c_str());
00304     if (!file) {
00305         ZYPP_THROW (Exception( "Can't open " + controlPath ) );
00306     }
00307 
00308     *file << "<?xml version=\"1.0\"?>" << endl
00309           << "<!-- testcase generated by YaST -->" << endl
00310           << "<test>" << endl
00311           << "<setup arch=\"" << systemArchitecture << "\">" << endl
00312           << TAB << "<system file=\"" << systemPath << "\"/>" << endl;
00313     for ( SourceTable::const_iterator it = sourceTable.begin();
00314           it != sourceTable.end(); ++it ) {
00315         Source_Ref source = it->first;
00316         *file << TAB << "<channel file=\"" << numstring(source.numericId())
00317               << "-package.xml\" name=\"" << numstring(source.numericId())
00318               << "\" />" << endl;
00319     }
00320     *file << "</setup>" << endl
00321           << "<trial>" << endl
00322           << "<showpool all=\"yes\"/>" << endl
00323           << "<establish/>" << endl
00324           << "<showpool all=\"true\" prefix=\">!> ESTABLISHED:\"/>" << endl;
00325 }
00326 
00327 HelixControl::HelixControl()
00328     :dumpFile ("/var/log/YaST2/solverTestcase/solver-test.xml")
00329 {
00330     HelixControl (dumpFile);
00331 }
00332 
00333 HelixControl::~HelixControl()
00334 {
00335     *file << "</trial>" << endl
00336           << "</test>" << endl;
00337 }
00338 
00339 void HelixControl::installResolvable(const ResObject::constPtr &resObject)
00340 {
00341     Source_Ref source  = resObject->source();
00342     *file << "<install channel=\"" << numstring(source.numericId()) << "\" kind=\"" << toLower (resObject->kind().asString()) << "\""
00343           << " name=\"" << resObject->name() << "\"" << "/>" << endl;
00344 }
00345     
00346 void HelixControl::deleteResolvable(const ResObject::constPtr &resObject)
00347 {
00348     Source_Ref source  = resObject->source();    
00349     *file << "<uninstall " << " kind=\"" << toLower (resObject->kind().asString()) << "\""
00350           << " name=\"" << resObject->name() << "\"" << "/>" << endl;    
00351 }
00352 
00353 
00355     };// namespace detail
00358   };// namespace solver
00361 };// namespace zypp

Generated on Tue Nov 28 16:49:31 2006 for zypp by  doxygen 1.5.0