1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/solver/detail/Testcase.cc
17 #include "zypp/solver/detail/Testcase.h"
18 #include "zypp/base/Logger.h"
19 #include "zypp/base/LogControl.h"
20 #include "zypp/PathInfo.h"
21 #include "zypp/Product.h"
22 #include "zypp/Package.h"
23 #include "zypp/Edition.h"
24 #include "zypp/target/store/xml_escape_parser.hpp"
25 #include "zypp/capability/VersionedCap.h"
26 #include "zypp/base/String.h"
27 #include "zypp/base/PtrTypes.h"
30 /////////////////////////////////////////////////////////////////////////
32 { ///////////////////////////////////////////////////////////////////////
33 ///////////////////////////////////////////////////////////////////////
35 { /////////////////////////////////////////////////////////////////////
36 /////////////////////////////////////////////////////////////////////
38 { ///////////////////////////////////////////////////////////////////
44 using namespace zypp::capability;
45 using namespace zypp::str;
47 IMPL_PTR_TYPE(HelixResolvable);
49 static std::string xml_escape( const std::string &text )
51 iobind::parser::xml_escape_parser parser;
52 return parser.escape(text);
55 static std::string xml_tag_enclose( const std::string &text, const std::string &tag, bool escape = false )
58 result += "<" + tag + ">";
61 result += xml_escape(text);
65 result += "</" + tag + ">";
71 std::string helixXML( const T &obj ); //undefined
74 std::string helixXML( const Edition &edition )
77 str << xml_tag_enclose(edition.version(), "version");
78 if (!edition.release().empty())
79 str << xml_tag_enclose(edition.release(), "release");
80 if (edition.epoch() != Edition::noepoch)
81 str << xml_tag_enclose(numstring(edition.epoch()), "epoch");
86 std::string helixXML( const Arch &arch )
89 str << xml_tag_enclose(arch.asString(), "arch");
94 std::string helixXML( const Capability &cap )
97 if (isKind<VersionedCap>(cap)
98 && cap.op() != Rel::NONE
99 && cap.op() != Rel::ANY
100 && !cap.edition().version().empty()) {
101 // version capability
102 str << "<dep name='" << xml_escape(cap.index()) << "' op='" << xml_escape(cap.op().asString()) <<
103 "' version='" << cap.edition().version() << "'";
104 if (!cap.edition().release().empty())
105 str << " release='" << cap.edition().release() << "'";
106 if (cap.edition().epoch() != Edition::noepoch)
107 str << " epoch='" << numstring(cap.edition().epoch()) << "'";
110 str << "<dep name='" << xml_escape(cap.asString()) << "'";
112 str << " kind=\"" << toLower (cap.refers().asString()) << "\""
119 std::string helixXML( const CapSet &caps )
122 CapSet::iterator it = caps.begin();
124 for ( ; it != caps.end(); ++it)
126 str << TAB2 << helixXML((*it));
133 std::string helixXML( const Dependencies &dep )
136 if ( dep[Dep::PROVIDES].size() > 0 )
137 str << TAB << xml_tag_enclose(helixXML(dep[Dep::PROVIDES]), "provides") << endl;
138 if ( dep[Dep::CONFLICTS].size() > 0 )
139 str << TAB << xml_tag_enclose(helixXML(dep[Dep::CONFLICTS]), "conflicts") << endl;
140 if ( dep[Dep::OBSOLETES].size() > 0 )
141 str << TAB << xml_tag_enclose(helixXML(dep[Dep::OBSOLETES]), "obsoletes") << endl;
142 if ( dep[Dep::FRESHENS].size() > 0 )
143 str << TAB << xml_tag_enclose(helixXML(dep[Dep::FRESHENS]), "freshens") << endl;
144 if ( dep[Dep::REQUIRES].size() > 0 )
145 str << TAB << xml_tag_enclose(helixXML(dep[Dep::REQUIRES]), "requires") << endl;
146 if ( dep[Dep::RECOMMENDS].size() > 0 )
147 str << TAB << xml_tag_enclose(helixXML(dep[Dep::RECOMMENDS]), "recommends") << endl;
148 if ( dep[Dep::ENHANCES].size() > 0 )
149 str << TAB << xml_tag_enclose(helixXML(dep[Dep::ENHANCES]), "enhances") << endl;
150 if ( dep[Dep::SUPPLEMENTS].size() > 0 )
151 str << TAB << xml_tag_enclose(helixXML(dep[Dep::SUPPLEMENTS]), "supplements") << endl;
152 if ( dep[Dep::SUGGESTS].size() > 0 )
153 str << TAB << xml_tag_enclose(helixXML(dep[Dep::SUGGESTS]), "suggests") << endl;
157 std::string helixXML( const Resolvable::constPtr &resolvable )
160 str << "<" << toLower (resolvable->kind().asString()) << ">" << endl;
161 str << TAB << xml_tag_enclose (resolvable->name(), "name", true) << endl;
162 if ( isKind<Package>(resolvable) ) {
163 str << TAB << "<history>" << endl << TAB << "<update>" << endl;
164 str << TAB2 << helixXML (resolvable->arch()) << endl;
165 str << TAB2 << helixXML (resolvable->edition()) << endl;
166 str << TAB << "</update>" << endl << TAB << "</history>" << endl;
168 str << TAB << helixXML (resolvable->arch()) << endl;
169 str << TAB << helixXML (resolvable->edition()) << endl;
171 str << helixXML (resolvable->deps());
173 str << "</" << toLower (resolvable->kind().asString()) << ">" << endl;
177 //---------------------------------------------------------------------------
180 :dumpPath("/var/log/YaST2/solverTestcase")
184 Testcase::Testcase(const std::string & path)
190 Testcase::~Testcase()
194 bool Testcase::createTestcase(Resolver & resolver)
196 PathInfo path (dumpPath);
198 if ( !path.isExist() ) {
199 if (zypp::filesystem::mkdir (dumpPath)!=0) {
200 ERR << "Cannot create directory " << dumpPath << endl;
205 ERR << dumpPath << " is not a directory." << endl;
209 zypp::filesystem::clean_dir (dumpPath);
212 zypp::base::LogControl::instance().logfile( dumpPath +"/y2log" );
213 zypp::base::LogControl::TmpExcessive excessive;
215 resolver.resolvePool();
217 zypp::base::LogControl::instance().logfile( "/var/log/YaST2/y2log" );
219 ResPool pool = resolver.pool();
220 SourceTable sourceTable;
221 PoolItemList items_to_install;
222 PoolItemList items_to_remove;
223 HelixResolvable system (dumpPath + "/solver-system.xml");
225 for ( ResPool::const_iterator it = pool.begin(); it != pool.end(); ++it )
227 Resolvable::constPtr res = it->resolvable();
229 if ( it->status().isInstalled() ) {
231 system.addResolvable (res);
234 ResObject::constPtr sourceItem = it->resolvable();
235 Source_Ref source = sourceItem->source();
236 if (sourceTable.find (source) == sourceTable.end()) {
237 sourceTable[source] = new HelixResolvable(dumpPath + "/"
238 + numstring(source.numericId())
241 sourceTable[source]->addResolvable (res);
244 if ( it->status().isToBeInstalled()
245 && !(it->status().isBySolver())) {
246 items_to_install.push_back (*it);
248 if ( it->status().isToBeUninstalled()
249 && !(it->status().isBySolver())) {
250 items_to_remove.push_back (*it);
254 // writing control file "*-test.xml"
256 HelixControl control (dumpPath + "/solver-test.xml",
258 resolver.architecture());
260 for (PoolItemList::const_iterator iter = items_to_install.begin(); iter != items_to_install.end(); iter++) {
261 control.installResolvable (iter->resolvable());
264 for (PoolItemList::const_iterator iter = items_to_remove.begin(); iter != items_to_remove.end(); iter++) {
265 control.deleteResolvable (iter->resolvable());
271 //---------------------------------------------------------------------------
273 HelixResolvable::HelixResolvable(const std::string & path)
276 file = new ofstream(path.c_str());
278 ZYPP_THROW (Exception( "Can't open " + path ) );
281 *file << "<channel><subchannel>" << endl;
284 HelixResolvable::~HelixResolvable()
286 *file << "</subchannel></channel>" << endl;
290 void HelixResolvable::addResolvable(const Resolvable::constPtr &resolvable)
292 *file << helixXML (resolvable);
295 //---------------------------------------------------------------------------
297 HelixControl::HelixControl(const std::string & controlPath,
298 const SourceTable & sourceTable,
299 const Arch & systemArchitecture,
300 const std::string & systemPath)
301 :dumpFile (controlPath)
303 file = new ofstream(controlPath.c_str());
305 ZYPP_THROW (Exception( "Can't open " + controlPath ) );
308 *file << "<?xml version=\"1.0\"?>" << endl
309 << "<!-- testcase generated by YaST -->" << endl
311 << "<setup arch=\"" << systemArchitecture << "\">" << endl
312 << TAB << "<system file=\"" << systemPath << "\"/>" << endl;
313 for ( SourceTable::const_iterator it = sourceTable.begin();
314 it != sourceTable.end(); ++it ) {
315 Source_Ref source = it->first;
316 *file << TAB << "<channel file=\"" << numstring(source.numericId())
317 << "-package.xml\" name=\"" << numstring(source.numericId())
320 *file << "</setup>" << endl
322 << "<showpool all=\"yes\"/>" << endl
323 << "<establish/>" << endl
324 << "<showpool all=\"true\" prefix=\">!> ESTABLISHED:\"/>" << endl;
327 HelixControl::HelixControl()
328 :dumpFile ("/var/log/YaST2/solverTestcase/solver-test.xml")
330 HelixControl (dumpFile);
333 HelixControl::~HelixControl()
335 *file << "</trial>" << endl
336 << "</test>" << endl;
339 void HelixControl::installResolvable(const ResObject::constPtr &resObject)
341 Source_Ref source = resObject->source();
342 *file << "<install channel=\"" << numstring(source.numericId()) << "\" kind=\"" << toLower (resObject->kind().asString()) << "\""
343 << " name=\"" << resObject->name() << "\"" << "/>" << endl;
346 void HelixControl::deleteResolvable(const ResObject::constPtr &resObject)
348 Source_Ref source = resObject->source();
349 *file << "<uninstall " << " kind=\"" << toLower (resObject->kind().asString()) << "\""
350 << " name=\"" << resObject->name() << "\"" << "/>" << endl;
354 ///////////////////////////////////////////////////////////////////
355 };// namespace detail
356 /////////////////////////////////////////////////////////////////////
357 /////////////////////////////////////////////////////////////////////
358 };// namespace solver
359 ///////////////////////////////////////////////////////////////////////
360 ///////////////////////////////////////////////////////////////////////
362 /////////////////////////////////////////////////////////////////////////