#include "src/createrepo_c.h"
+#include "xml_parser-py.h"
#include "typeconversion.h"
#include "package-py.h"
#include "exception-py.h"
-typedef struct {
- PyObject_HEAD
- PyObject *newpkgcb;
- PyObject *pkgcb;
- PyObject *warningcb;
-} _XmlParserObject;
-
-static int
-check_XmlParserStatus(const _XmlParserObject *self)
-{
- assert(self != NULL);
- assert(XmlParserObject_Check(self));
- return 0;
-}
-
-/* Functions on the type */
-
-static PyObject *
-xmlparser_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- CR_UNUSED(args);
- CR_UNUSED(kwds);
- _XmlParserObject *self = (_XmlParserObject *)type->tp_alloc(type, 0);
- if (self) {
- self->newpkgcb = NULL;
- self->pkgcb = NULL;
- self->warningcb = NULL;
- }
- return (PyObject *)self;
-}
-
-static int
-xmlparser_init(_XmlParserObject *self, PyObject *args, PyObject *kwds)
-{
- CR_UNUSED(args);
- CR_UNUSED(kwds);
-
- //if (!PyArg_ParseTuple(args, "|:xmlparser_init"))
- // return -1;
-
- /* Free all previous resources when reinitialization */
- Py_XDECREF(self->newpkgcb);
- Py_XDECREF(self->pkgcb);
- Py_XDECREF(self->warningcb);
-
- self->newpkgcb = NULL;
- self->pkgcb = NULL;
- self->warningcb = NULL;
-
- return 0;
-}
-
-static void
-xmlparser_dealloc(_XmlParserObject *self)
-{
- Py_XDECREF(self->newpkgcb);
- Py_XDECREF(self->pkgcb);
- Py_XDECREF(self->warningcb);
- Py_TYPE(self)->tp_free(self);
-}
-
-static PyObject *
-xmlparser_repr(_XmlParserObject *self)
-{
- return PyString_FromFormat("<createrepo_c.XmlParser object>");
-}
-
-/* XmlParser methods */
-
static int
c_newpkgcb(cr_Package **pkg,
const char *pkgId,
arglist = Py_BuildValue("(sss)", pkgId, name, arch);
result = PyObject_CallObject(cbdata, arglist);
Py_DECREF(arglist);
- // XXX Process and decref result
+
+ if (result == NULL) {
+ // Exception raised
+ PyErr_ToGError(err);
+ return CR_CB_RET_ERR;
+ }
+
+ if (!PackageObject_Check(result) && result != Py_None) {
+ PyErr_SetString(PyExc_TypeError,
+ "Expected a cr_Package or None as a callback return value");
+ return CR_CB_RET_ERR;
+ }
+
+ *pkg = Package_FromPyObject(result);
+
+ Py_DECREF(result);
return CR_CB_RET_OK;
}
static int
-c_pkgcb(cr_Package *pkg, void *cbdata, GError **err)
+c_pkgcb(cr_Package *pkg,
+ void *cbdata,
+ GError **err)
{
- PyObject *py_pkg, *arglist, *result;
+ PyObject *result;
- arglist = Py_BuildValue("(O)", py_pkg);
- result = PyObject_CallObject(cbdata, arglist);
- Py_DECREF(arglist);
- // XXX Process and decref result
+ CR_UNUSED(pkg);
+
+ result = PyObject_CallObject(cbdata, NULL);
+
+ if (result == NULL) {
+ // Exception raised
+ PyErr_ToGError(err);
+ return CR_CB_RET_ERR;
+ }
+
+ Py_DECREF(result);
return CR_CB_RET_OK;
}
arglist = Py_BuildValue("(is)", type, msg);
result = PyObject_CallObject(cbdata, arglist);
Py_DECREF(arglist);
- // XXX Process and decref result
+
+ if (result == NULL) {
+ // Exception raised
+ PyErr_ToGError(err);
+ return CR_CB_RET_ERR;
+ }
+
+ Py_DECREF(result);
return CR_CB_RET_OK;
}
return NULL;
}
- if (!PyCallable_Check(newpkgcb) || newpkgcb != Py_None) {
- PyErr_SetString(PyExc_TypeError, "newpkgcb must be callable or None");
+ if (!PyCallable_Check(newpkgcb)) {
+ PyErr_SetString(PyExc_TypeError, "newpkgcb must be callable");
return NULL;
}
- if (!PyCallable_Check(pkgcb) || pkgcb != Py_None) {
+ if (!PyCallable_Check(pkgcb) && pkgcb != Py_None) {
PyErr_SetString(PyExc_TypeError, "pkgcb must be callable or None");
return NULL;
}
- if (!PyCallable_Check(warningcb) || warningcb != Py_None) {
+ if (!PyCallable_Check(warningcb) && warningcb != Py_None) {
PyErr_SetString(PyExc_TypeError, "warningcb must be callable or None");
return NULL;
}
- /*
- Py_XDECREF(self->newpkgcb);
- Py_XDECREF(self->pkgcb);
- Py_XDECREF(self->warningcb);
- */
+ Py_XINCREF(newpkgcb);
+ Py_XINCREF(pkgcb);
+ Py_XINCREF(warningcb);
- cr_XmlParserNewPkgCb *ptr_c_newpkgcb = NULL;
- cr_XmlParserPkgCb *ptr_c_pkgcb = NULL;
- cr_XmlParserWarningCb *ptr_c_warningcb = NULL;
+ cr_XmlParserPkgCb ptr_c_pkgcb = NULL;
+ cr_XmlParserWarningCb ptr_c_warningcb = NULL;
- if (newpkgcb != Py_None)
- ptr_c_newpkgcb = c_newpkgcb;
if (pkgcb != Py_None)
ptr_c_pkgcb = c_pkgcb;
- if (newpkgcb != Py_None)
+ if (warningcb != Py_None)
ptr_c_warningcb = c_warningcb;
- /*
- self->newpkgcb = (newpkgcb == Py_None) ? NULL : newpkgcb;
- Py_XINCREF(self->newpkgcb);
- self->pkgcb = (pkgcb == Py_None) ? NULL : pkgcb;
- Py_XINCREF(self->pkgcb);
- self->warningcb = (warningcb == Py_None) ? NULL : warningcb;
- Py_XINCREF(self->warningcb);
- */
-
cr_xml_parse_primary(filename,
c_newpkgcb,
- &newpkgcb,
- c_pkgcb,
- &pkgcb,
- c_warningcb,
- &warningcb,
+ newpkgcb,
+ ptr_c_pkgcb,
+ pkgcb,
+ ptr_c_warningcb,
+ warningcb,
do_files,
&tmp_err);
+
+ Py_XDECREF(newpkgcb);
+ Py_XDECREF(pkgcb);
+ Py_XDECREF(warningcb);
+
+ if (tmp_err) {
+ PyErr_Format(CrErr_Exception, "%s", tmp_err->message);
+ g_clear_error(&tmp_err);
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
+}
+
+PyObject *
+py_xml_parse_filelists(PyObject *self, PyObject *args)
+{
+ CR_UNUSED(self);
+
+ char *filename;
+ PyObject *newpkgcb, *pkgcb, *warningcb;
+ GError *tmp_err = NULL;
+
+ if (!PyArg_ParseTuple(args, "sOOO:py_xml_parse_filelists",
+ &filename,
+ &newpkgcb,
+ &pkgcb,
+ &warningcb)) {
+ return NULL;
+ }
+
+ if (!PyCallable_Check(newpkgcb)) {
+ PyErr_SetString(PyExc_TypeError, "newpkgcb must be callable");
+ return NULL;
+ }
+
+ if (!PyCallable_Check(pkgcb) && pkgcb != Py_None) {
+ PyErr_SetString(PyExc_TypeError, "pkgcb must be callable or None");
+ return NULL;
+ }
+
+ if (!PyCallable_Check(warningcb) && warningcb != Py_None) {
+ PyErr_SetString(PyExc_TypeError, "warningcb must be callable or None");
+ return NULL;
+ }
+
+ Py_XINCREF(newpkgcb);
+ Py_XINCREF(pkgcb);
+ Py_XINCREF(warningcb);
+
+ cr_XmlParserPkgCb ptr_c_pkgcb = NULL;
+ cr_XmlParserWarningCb ptr_c_warningcb = NULL;
+
+ if (pkgcb != Py_None)
+ ptr_c_pkgcb = c_pkgcb;
+ if (warningcb != Py_None)
+ ptr_c_warningcb = c_warningcb;
+
+ cr_xml_parse_filelists(filename,
+ c_newpkgcb,
+ newpkgcb,
+ ptr_c_pkgcb,
+ pkgcb,
+ ptr_c_warningcb,
+ warningcb,
+ &tmp_err);
+
+ Py_XDECREF(newpkgcb);
+ Py_XDECREF(pkgcb);
+ Py_XDECREF(warningcb);
+
if (tmp_err) {
PyErr_Format(CrErr_Exception, "%s", tmp_err->message);
g_clear_error(&tmp_err);
Py_RETURN_NONE;
}
-static struct PyMethodDef xmlparser_methods[] = {
- {"parse_primary", (PyCFunction)py_xml_parse_primary, METH_VARARGS, NULL},
- {NULL} /* sentinel */
-};
-
-PyTypeObject XmlParser_Type = {
- PyObject_HEAD_INIT(NULL)
- 0, /* ob_size */
- "_librepo.XmlParser", /* tp_name */
- sizeof(_XmlParserObject), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor) xmlparser_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- (reprfunc) xmlparser_repr, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
- "XmlParser object", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- PyObject_SelfIter, /* tp_iter */
- 0, /* tp_iternext */
- xmlparser_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc) xmlparser_init, /* tp_init */
- 0, /* tp_alloc */
- xmlparser_new, /* tp_new */
- 0, /* tp_free */
- 0, /* tp_is_gc */
-};
+PyObject *
+py_xml_parse_other(PyObject *self, PyObject *args)
+{
+ CR_UNUSED(self);
+
+ char *filename;
+ PyObject *newpkgcb, *pkgcb, *warningcb;
+ GError *tmp_err = NULL;
+
+ if (!PyArg_ParseTuple(args, "sOOO:py_xml_parse_other",
+ &filename,
+ &newpkgcb,
+ &pkgcb,
+ &warningcb)) {
+ return NULL;
+ }
+
+ if (!PyCallable_Check(newpkgcb)) {
+ PyErr_SetString(PyExc_TypeError, "newpkgcb must be callable");
+ return NULL;
+ }
+
+ if (!PyCallable_Check(pkgcb) && pkgcb != Py_None) {
+ PyErr_SetString(PyExc_TypeError, "pkgcb must be callable or None");
+ return NULL;
+ }
+
+ if (!PyCallable_Check(warningcb) && warningcb != Py_None) {
+ PyErr_SetString(PyExc_TypeError, "warningcb must be callable or None");
+ return NULL;
+ }
+
+ Py_XINCREF(newpkgcb);
+ Py_XINCREF(pkgcb);
+ Py_XINCREF(warningcb);
+
+ cr_XmlParserPkgCb ptr_c_pkgcb = NULL;
+ cr_XmlParserWarningCb ptr_c_warningcb = NULL;
+
+ if (pkgcb != Py_None)
+ ptr_c_pkgcb = c_pkgcb;
+ if (warningcb != Py_None)
+ ptr_c_warningcb = c_warningcb;
+
+ cr_xml_parse_other(filename,
+ c_newpkgcb,
+ newpkgcb,
+ ptr_c_pkgcb,
+ pkgcb,
+ ptr_c_warningcb,
+ warningcb,
+ &tmp_err);
+
+ Py_XDECREF(newpkgcb);
+ Py_XDECREF(pkgcb);
+ Py_XDECREF(warningcb);
+
+ if (tmp_err) {
+ PyErr_Format(CrErr_Exception, "%s", tmp_err->message);
+ g_clear_error(&tmp_err);
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
+}
--- /dev/null
+import re
+import unittest
+import shutil
+import tempfile
+import os.path
+import createrepo_c as cr
+
+from fixtures import *
+
+class TestCaseXmlParserPrimary(unittest.TestCase):
+
+ def test_xml_parser_primary_repo01(self):
+
+ userdata = {
+ "pkgs": [],
+ "pkgcb_calls": 0,
+ "warnings": []
+ }
+
+ def newpkgcb(pkgId, name, arch):
+ pkg = cr.Package()
+ userdata["pkgs"].append(pkg)
+ return pkg
+
+ def pkgcb():
+ userdata["pkgcb_calls"] += 1
+
+ def warningcb(warn_type, msg):
+ userdata["warnings"].append((warn_type, msg))
+
+ cr.xml_parse_primary(REPO_01_PRIXML, newpkgcb, pkgcb, warningcb, 1)
+
+ self.assertEqual([pkg.name for pkg in userdata["pkgs"]],
+ ['super_kernel'])
+ self.assertEqual(userdata["pkgcb_calls"], 1)
+ self.assertEqual(userdata["warnings"], [])
+
+ pkg = userdata["pkgs"][0]
+ self.assertEqual(pkg.pkgId, "152824bff2aa6d54f429d43e87a3ff3a0286505c6d93ec87692b5e3a9e3b97bf")
+ self.assertEqual(pkg.name, "super_kernel")
+ self.assertEqual(pkg.arch, "x86_64")
+ self.assertEqual(pkg.version, "6.0.1")
+ self.assertEqual(pkg.epoch, "0")
+ self.assertEqual(pkg.release, "2")
+ self.assertEqual(pkg.summary, "Test package")
+ self.assertEqual(pkg.description, "This package has provides, requires, obsoletes, conflicts options.")
+ self.assertEqual(pkg.url, "http://so_super_kernel.com/it_is_awesome/yep_it_really_is")
+ self.assertEqual(pkg.time_file, 1334667003)
+ self.assertEqual(pkg.time_build, 1334667003)
+ self.assertEqual(pkg.rpm_license, "LGPLv2")
+ self.assertEqual(pkg.rpm_vendor, None)
+ self.assertEqual(pkg.rpm_group, "Applications/System")
+ self.assertEqual(pkg.rpm_buildhost, "localhost.localdomain")
+ self.assertEqual(pkg.rpm_sourcerpm, "super_kernel-6.0.1-2.src.rpm")
+ self.assertEqual(pkg.rpm_header_start, 280)
+ self.assertEqual(pkg.rpm_header_end, 2637)
+ self.assertEqual(pkg.rpm_packager, None)
+ self.assertEqual(pkg.size_package, 2845)
+ self.assertEqual(pkg.size_installed, 0)
+ self.assertEqual(pkg.size_archive, 404)
+ self.assertEqual(pkg.location_href, "super_kernel-6.0.1-2.x86_64.rpm")
+ self.assertEqual(pkg.location_base, None)
+ self.assertEqual(pkg.checksum_type, "sha256")
+ self.assertEqual(pkg.requires,
+ [('bzip2', 'GE', '0', '1.0.0', None, True),
+ ('expat', None, None, None, None, True),
+ ('glib', 'GE', '0', '2.26.0', None, False),
+ ('zlib', None, None, None, None, False)])
+ self.assertEqual(pkg.provides,
+ [('not_so_super_kernel', 'LT', '0', '5.8.0', None, False),
+ ('super_kernel', 'EQ', '0', '6.0.0', None, False),
+ ('super_kernel', 'EQ', '0', '6.0.1', '2', False),
+ ('super_kernel(x86-64)', 'EQ', '0', '6.0.1', '2', False)])
+ self.assertEqual(pkg.conflicts,
+ [('kernel', None, None, None, None, False),
+ ('super_kernel', 'EQ', '0', '5.0.0', None, False),
+ ('super_kernel', 'LT', '0', '4.0.0', None, False)])
+ self.assertEqual(pkg.obsoletes,
+ [('kernel', None, None, None, None, False),
+ ('super_kernel', 'EQ', '0', '5.9.0', None, False)])
+ self.assertEqual(pkg.files,
+ [(None, '/usr/bin/', 'super_kernel')])
+ self.assertEqual(pkg.changelogs, [])
+
+
+ def test_xml_parser_primary_repo02(self):
+
+ userdata = {
+ "pkgs": [],
+ "pkgcb_calls": 0,
+ "warnings": []
+ }
+
+ def newpkgcb(pkgId, name, arch):
+ pkg = cr.Package()
+ userdata["pkgs"].append(pkg)
+ return pkg
+
+ def pkgcb():
+ userdata["pkgcb_calls"] += 1
+
+ def warningcb(warn_type, msg):
+ userdata["warnings"].append((warn_type, msg))
+
+ cr.xml_parse_primary(REPO_02_PRIXML, newpkgcb, pkgcb, warningcb, 1)
+
+ self.assertEqual([pkg.name for pkg in userdata["pkgs"]],
+ ['fake_bash', 'super_kernel'])
+ self.assertEqual(userdata["pkgcb_calls"], 2)
+ self.assertEqual(userdata["warnings"], [])
+
+class TestCaseXmlParserFilelists(unittest.TestCase):
+
+ def test_xml_parser_filelists_repo01(self):
+
+ userdata = {
+ "pkgs": [],
+ "pkgcb_calls": 0,
+ "warnings": []
+ }
+
+ def newpkgcb(pkgId, name, arch):
+ pkg = cr.Package()
+ userdata["pkgs"].append(pkg)
+ return pkg
+
+ def pkgcb():
+ userdata["pkgcb_calls"] += 1
+
+ def warningcb(warn_type, msg):
+ userdata["warnings"].append((warn_type, msg))
+
+ cr.xml_parse_filelists(REPO_01_FILXML, newpkgcb, pkgcb, warningcb)
+
+ self.assertEqual([pkg.name for pkg in userdata["pkgs"]],
+ ['super_kernel'])
+ self.assertEqual(userdata["pkgcb_calls"], 1)
+ self.assertEqual(userdata["warnings"], [])
+
+ pkg = userdata["pkgs"][0]
+ self.assertEqual(pkg.pkgId, "152824bff2aa6d54f429d43e87a3ff3a0286505c6d93ec87692b5e3a9e3b97bf")
+ self.assertEqual(pkg.name, "super_kernel")
+ self.assertEqual(pkg.arch, "x86_64")
+ self.assertEqual(pkg.version, "6.0.1")
+ self.assertEqual(pkg.epoch, "0")
+ self.assertEqual(pkg.release, "2")
+ self.assertEqual(pkg.summary, None)
+ self.assertEqual(pkg.description, None)
+ self.assertEqual(pkg.url, None)
+ self.assertEqual(pkg.time_file, 0)
+ self.assertEqual(pkg.time_build, 0)
+ self.assertEqual(pkg.rpm_license, None)
+ self.assertEqual(pkg.rpm_vendor, None)
+ self.assertEqual(pkg.rpm_group, None)
+ self.assertEqual(pkg.rpm_buildhost, None)
+ self.assertEqual(pkg.rpm_sourcerpm, None)
+ self.assertEqual(pkg.rpm_header_start, 0)
+ self.assertEqual(pkg.rpm_header_end, 0)
+ self.assertEqual(pkg.rpm_packager, None)
+ self.assertEqual(pkg.size_package, 0)
+ self.assertEqual(pkg.size_installed, 0)
+ self.assertEqual(pkg.size_archive, 0)
+ self.assertEqual(pkg.location_href, None)
+ self.assertEqual(pkg.location_base, None)
+ self.assertEqual(pkg.checksum_type, None)
+ self.assertEqual(pkg.requires, [])
+ self.assertEqual(pkg.provides, [])
+ self.assertEqual(pkg.conflicts, [])
+ self.assertEqual(pkg.obsoletes, [])
+ self.assertEqual(pkg.files,
+ [(None, '/usr/bin/', 'super_kernel'),
+ (None, '/usr/share/man/', 'super_kernel.8.gz')])
+ self.assertEqual(pkg.changelogs, [])
+
+ def test_xml_parser_filelists_repo02(self):
+
+ userdata = {
+ "pkgs": [],
+ "pkgcb_calls": 0,
+ "warnings": []
+ }
+
+ def newpkgcb(pkgId, name, arch):
+ pkg = cr.Package()
+ userdata["pkgs"].append(pkg)
+ return pkg
+
+ def pkgcb():
+ userdata["pkgcb_calls"] += 1
+
+ def warningcb(warn_type, msg):
+ userdata["warnings"].append((warn_type, msg))
+
+ cr.xml_parse_filelists(REPO_02_FILXML, newpkgcb, pkgcb, warningcb)
+
+ self.assertEqual([pkg.name for pkg in userdata["pkgs"]],
+ ['fake_bash', 'super_kernel'])
+ self.assertEqual(userdata["pkgcb_calls"], 2)
+ self.assertEqual(userdata["warnings"], [])
+
+class TestCaseXmlParserOther(unittest.TestCase):
+
+ def test_xml_parser_other_repo01(self):
+
+ userdata = {
+ "pkgs": [],
+ "pkgcb_calls": 0,
+ "warnings": []
+ }
+
+ def newpkgcb(pkgId, name, arch):
+ pkg = cr.Package()
+ userdata["pkgs"].append(pkg)
+ return pkg
+
+ def pkgcb():
+ userdata["pkgcb_calls"] += 1
+
+ def warningcb(warn_type, msg):
+ userdata["warnings"].append((warn_type, msg))
+
+ cr.xml_parse_other(REPO_01_OTHXML, newpkgcb, pkgcb, warningcb)
+
+ self.assertEqual([pkg.name for pkg in userdata["pkgs"]],
+ ['super_kernel'])
+ self.assertEqual(userdata["pkgcb_calls"], 1)
+ self.assertEqual(userdata["warnings"], [])
+
+ pkg = userdata["pkgs"][0]
+ self.assertEqual(pkg.pkgId, "152824bff2aa6d54f429d43e87a3ff3a0286505c6d93ec87692b5e3a9e3b97bf")
+ self.assertEqual(pkg.name, "super_kernel")
+ self.assertEqual(pkg.arch, "x86_64")
+ self.assertEqual(pkg.version, "6.0.1")
+ self.assertEqual(pkg.epoch, "0")
+ self.assertEqual(pkg.release, "2")
+ self.assertEqual(pkg.summary, None)
+ self.assertEqual(pkg.description, None)
+ self.assertEqual(pkg.url, None)
+ self.assertEqual(pkg.time_file, 0)
+ self.assertEqual(pkg.time_build, 0)
+ self.assertEqual(pkg.rpm_license, None)
+ self.assertEqual(pkg.rpm_vendor, None)
+ self.assertEqual(pkg.rpm_group, None)
+ self.assertEqual(pkg.rpm_buildhost, None)
+ self.assertEqual(pkg.rpm_sourcerpm, None)
+ self.assertEqual(pkg.rpm_header_start, 0)
+ self.assertEqual(pkg.rpm_header_end, 0)
+ self.assertEqual(pkg.rpm_packager, None)
+ self.assertEqual(pkg.size_package, 0)
+ self.assertEqual(pkg.size_installed, 0)
+ self.assertEqual(pkg.size_archive, 0)
+ self.assertEqual(pkg.location_href, None)
+ self.assertEqual(pkg.location_base, None)
+ self.assertEqual(pkg.checksum_type, None)
+ self.assertEqual(pkg.requires, [])
+ self.assertEqual(pkg.provides, [])
+ self.assertEqual(pkg.conflicts, [])
+ self.assertEqual(pkg.obsoletes, [])
+ self.assertEqual(pkg.files, [])
+ self.assertEqual(pkg.changelogs,
+ [('Tomas Mlcoch <tmlcoch@redhat.com> - 6.0.1-1',
+ 1334664000L,
+ '- First release'),
+ ('Tomas Mlcoch <tmlcoch@redhat.com> - 6.0.1-2',
+ 1334664001L,
+ '- Second release')])
+
+ def test_xml_parser_other_repo02(self):
+
+ userdata = {
+ "pkgs": [],
+ "pkgcb_calls": 0,
+ "warnings": []
+ }
+
+ def newpkgcb(pkgId, name, arch):
+ pkg = cr.Package()
+ userdata["pkgs"].append(pkg)
+ return pkg
+
+ def pkgcb():
+ userdata["pkgcb_calls"] += 1
+
+ def warningcb(warn_type, msg):
+ userdata["warnings"].append((warn_type, msg))
+
+ cr.xml_parse_other(REPO_02_OTHXML, newpkgcb, pkgcb, warningcb)
+
+ self.assertEqual([pkg.name for pkg in userdata["pkgs"]],
+ ['fake_bash', 'super_kernel'])
+ self.assertEqual(userdata["pkgcb_calls"], 2)
+ self.assertEqual(userdata["warnings"], [])
+
+
+# TODO:
+# Test warnings