1330 lines
48 KiB
Diff
1330 lines
48 KiB
Diff
From a48db44b73785b5d5fbe8ae827522695fa0fd9ce Mon Sep 17 00:00:00 2001
|
|
From: Aleš Matěj <amatej@redhat.com>
|
|
Date: Tue, 8 Jan 2019 15:44:55 +0100
|
|
Subject: [PATCH] Add support for modular errata (RhBug:1656584)
|
|
|
|
---
|
|
src/python/CMakeLists.txt | 1 +
|
|
src/python/__init__.py | 3 +++
|
|
src/python/createrepo_cmodule.c | 8 ++++++++
|
|
src/python/updatecollection-py.c | 43 +++++++++++++++++++++++++++++++++++++++++++
|
|
src/python/updatecollectionmodule-py.c | 274 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
src/python/updatecollectionmodule-py.h | 33 +++++++++++++++++++++++++++++++++
|
|
src/updateinfo.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
|
|
src/updateinfo.h | 24 ++++++++++++++++++++++++
|
|
src/xml_dump_updateinfo.c | 20 ++++++++++++++++++++
|
|
src/xml_parser_internal.h | 2 ++
|
|
src/xml_parser_updateinfo.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
tests/fixtures.h | 1 +
|
|
tests/python/tests/test_updatecollection.py | 16 ++++++++++++++++
|
|
tests/python/tests/test_updatecollectionmodule.py | 31 +++++++++++++++++++++++++++++++
|
|
tests/python/tests/test_updateinfo.py | 189 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
tests/test_xml_parser_updateinfo.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
tests/testdata/updateinfo_files/updateinfo_03.xml | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
17 files changed, 957 insertions(+)
|
|
create mode 100644 src/python/updatecollectionmodule-py.c
|
|
create mode 100644 src/python/updatecollectionmodule-py.h
|
|
create mode 100644 tests/python/tests/test_updatecollectionmodule.py
|
|
create mode 100644 tests/testdata/updateinfo_files/updateinfo_03.xml
|
|
|
|
diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt
|
|
index 9f1ac64..ebf4d4c 100644
|
|
--- a/src/python/CMakeLists.txt
|
|
+++ b/src/python/CMakeLists.txt
|
|
@@ -50,6 +50,7 @@ SET (createrepo_cmodule_SRCS
|
|
sqlite-py.c
|
|
typeconversion.c
|
|
updatecollection-py.c
|
|
+ updatecollectionmodule-py.c
|
|
updatecollectionpackage-py.c
|
|
updateinfo-py.c
|
|
updaterecord-py.c
|
|
diff --git a/src/python/__init__.py b/src/python/__init__.py
|
|
index 6c29e74..65d7f82 100644
|
|
--- a/src/python/__init__.py
|
|
+++ b/src/python/__init__.py
|
|
@@ -206,6 +206,9 @@ class OtherSqlite(Sqlite):
|
|
|
|
UpdateCollection = _createrepo_c.UpdateCollection
|
|
|
|
+# UpdateCollectionModule class
|
|
+
|
|
+UpdateCollectionModule = _createrepo_c.UpdateCollectionModule
|
|
|
|
# UpdateCollectionPackage class
|
|
|
|
diff --git a/src/python/createrepo_cmodule.c b/src/python/createrepo_cmodule.c
|
|
index fe4d2ad..9be5f46 100644
|
|
--- a/src/python/createrepo_cmodule.c
|
|
+++ b/src/python/createrepo_cmodule.c
|
|
@@ -35,6 +35,7 @@
|
|
#include "repomdrecord-py.h"
|
|
#include "sqlite-py.h"
|
|
#include "updatecollection-py.h"
|
|
+#include "updatecollectionmodule-py.h"
|
|
#include "updatecollectionpackage-py.h"
|
|
#include "updateinfo-py.h"
|
|
#include "updaterecord-py.h"
|
|
@@ -185,6 +186,13 @@ init_createrepo_c(void)
|
|
PyModule_AddObject(m, "UpdateCollection",
|
|
(PyObject *)&UpdateCollection_Type);
|
|
|
|
+ /* _createrepo_c.UpdateCollectionModule */
|
|
+ if (PyType_Ready(&UpdateCollectionModule_Type) < 0)
|
|
+ return FAILURE;
|
|
+ Py_INCREF(&UpdateCollectionModule_Type);
|
|
+ PyModule_AddObject(m, "UpdateCollectionModule",
|
|
+ (PyObject *)&UpdateCollectionModule_Type);
|
|
+
|
|
/* _createrepo_c.UpdateCollectionPackage */
|
|
if (PyType_Ready(&UpdateCollectionPackage_Type) < 0)
|
|
return FAILURE;
|
|
diff --git a/src/python/updatecollection-py.c b/src/python/updatecollection-py.c
|
|
index 3a791be..ca97657 100644
|
|
--- a/src/python/updatecollection-py.c
|
|
+++ b/src/python/updatecollection-py.c
|
|
@@ -22,6 +22,7 @@
|
|
#include <stddef.h>
|
|
|
|
#include "updatecollection-py.h"
|
|
+#include "updatecollectionmodule-py.h"
|
|
#include "updatecollectionpackage-py.h"
|
|
#include "exception-py.h"
|
|
#include "typeconversion.h"
|
|
@@ -188,6 +189,13 @@ typedef int (*ConversionToCheckFunc)(PyObject *);
|
|
typedef void *(*ConversionToFunc)(PyObject *, GStringChunk *);
|
|
|
|
PyObject *
|
|
+PyObject_FromUpdateCollectionModule(cr_UpdateCollectionModule *module)
|
|
+{
|
|
+ return Object_FromUpdateCollectionModule(
|
|
+ cr_updatecollectionmodule_copy(module));
|
|
+}
|
|
+
|
|
+PyObject *
|
|
PyObject_FromUpdateCollectionPackage(cr_UpdateCollectionPackage *pkg)
|
|
{
|
|
return Object_FromUpdateCollectionPackage(
|
|
@@ -249,6 +257,23 @@ get_list(_UpdateCollectionObject *self, void *conv)
|
|
return list;
|
|
}
|
|
|
|
+static PyObject *
|
|
+get_module(_UpdateCollectionObject *self, void *member_offset)
|
|
+{
|
|
+ if (check_UpdateCollectionStatus(self))
|
|
+ return NULL;
|
|
+
|
|
+ cr_UpdateCollection *collection = self->collection;
|
|
+
|
|
+ cr_UpdateCollectionModule *module = *((cr_UpdateCollectionModule **) ((size_t) collection + (size_t) member_offset));
|
|
+ if (module == NULL)
|
|
+ Py_RETURN_NONE;
|
|
+
|
|
+ PyObject *py_module = PyObject_FromUpdateCollectionModule(module);
|
|
+
|
|
+ return py_module;
|
|
+}
|
|
+
|
|
static int
|
|
set_str(_UpdateCollectionObject *self, PyObject *value, void *member_offset)
|
|
{
|
|
@@ -265,11 +290,29 @@ set_str(_UpdateCollectionObject *self, PyObject *value, void *member_offset)
|
|
return 0;
|
|
}
|
|
|
|
+static int
|
|
+set_module(_UpdateCollectionObject *self, PyObject *value, void *member_offset)
|
|
+{
|
|
+ if (check_UpdateCollectionStatus(self))
|
|
+ return -1;
|
|
+ if (!UpdateCollectionModuleObject_Check(value) && value != Py_None) {
|
|
+ PyErr_SetString(PyExc_TypeError, "Module or None expected!");
|
|
+ return -1;
|
|
+ }
|
|
+ cr_UpdateCollectionModule *module = UpdateCollectionModule_FromPyObject(value);
|
|
+ cr_UpdateCollection *collection = self->collection;
|
|
+ *((cr_UpdateCollectionModule **) ((size_t) collection + (size_t) member_offset)) = module;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static PyGetSetDef updatecollection_getsetters[] = {
|
|
{"shortname", (getter)get_str, (setter)set_str,
|
|
"Short name", OFFSET(shortname)},
|
|
{"name", (getter)get_str, (setter)set_str,
|
|
"Name of the collection", OFFSET(name)},
|
|
+ {"module", (getter)get_module, (setter)set_module,
|
|
+ "Module information", OFFSET(module)},
|
|
{"packages", (getter)get_list, (setter)NULL,
|
|
"List of packages", &(list_convertors[0])},
|
|
{NULL, NULL, NULL, NULL, NULL} /* sentinel */
|
|
diff --git a/src/python/updatecollectionmodule-py.c b/src/python/updatecollectionmodule-py.c
|
|
new file mode 100644
|
|
index 0000000..20b2d99
|
|
--- /dev/null
|
|
+++ b/src/python/updatecollectionmodule-py.c
|
|
@@ -0,0 +1,274 @@
|
|
+/* createrepo_c - Library of routines for manipulation with repodata
|
|
+ * Copyright (C) 2013 Tomas Mlcoch
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU General Public License
|
|
+ * as published by the Free Software Foundation; either version 2
|
|
+ * of the License, or (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
|
+ * USA.
|
|
+ */
|
|
+
|
|
+#include <Python.h>
|
|
+#include <assert.h>
|
|
+#include <stddef.h>
|
|
+
|
|
+#include "updatecollectionmodule-py.h"
|
|
+#include "exception-py.h"
|
|
+#include "typeconversion.h"
|
|
+#include "contentstat-py.h"
|
|
+
|
|
+typedef struct {
|
|
+ PyObject_HEAD
|
|
+ cr_UpdateCollectionModule *module;
|
|
+} _UpdateCollectionModuleObject;
|
|
+
|
|
+PyObject *
|
|
+Object_FromUpdateCollectionModule(cr_UpdateCollectionModule *mod)
|
|
+{
|
|
+ PyObject *py_rec;
|
|
+
|
|
+ if (!mod) {
|
|
+ PyErr_SetString(PyExc_ValueError, "Expected a cr_UpdateCollectionModule pointer not NULL.");
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ py_rec = PyObject_CallObject((PyObject *) &UpdateCollectionModule_Type, NULL);
|
|
+ cr_updatecollectionmodule_free(((_UpdateCollectionModuleObject *)py_rec)->module);
|
|
+ ((_UpdateCollectionModuleObject *)py_rec)->module = mod;
|
|
+
|
|
+ return py_rec;
|
|
+}
|
|
+
|
|
+cr_UpdateCollectionModule *
|
|
+UpdateCollectionModule_FromPyObject(PyObject *o)
|
|
+{
|
|
+ if (!UpdateCollectionModuleObject_Check(o)) {
|
|
+ PyErr_SetString(PyExc_TypeError, "Expected a UpdateCollectionModule object.");
|
|
+ return NULL;
|
|
+ }
|
|
+ return ((_UpdateCollectionModuleObject *)o)->module;
|
|
+}
|
|
+
|
|
+static int
|
|
+check_UpdateCollectionModuleStatus(const _UpdateCollectionModuleObject *self)
|
|
+{
|
|
+ assert(self != NULL);
|
|
+ assert(UpdateCollectionModuleObject_Check(self));
|
|
+ if (self->module == NULL) {
|
|
+ PyErr_SetString(CrErr_Exception, "Improper createrepo_c UpdateCollectionModule object.");
|
|
+ return -1;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/* Function on the type */
|
|
+
|
|
+static PyObject *
|
|
+updatecollectionmodule_new(PyTypeObject *type,
|
|
+ G_GNUC_UNUSED PyObject *args,
|
|
+ G_GNUC_UNUSED PyObject *kwds)
|
|
+{
|
|
+ _UpdateCollectionModuleObject *self = (_UpdateCollectionModuleObject *)type->tp_alloc(type, 0);
|
|
+ if (self) {
|
|
+ self->module = NULL;
|
|
+ }
|
|
+ return (PyObject *)self;
|
|
+}
|
|
+
|
|
+PyDoc_STRVAR(updatecollectionmodule_init__doc__,
|
|
+".. method:: __init__()\n\n");
|
|
+
|
|
+static int
|
|
+updatecollectionmodule_init(_UpdateCollectionModuleObject *self,
|
|
+ G_GNUC_UNUSED PyObject *args,
|
|
+ G_GNUC_UNUSED PyObject *kwds)
|
|
+{
|
|
+ /* Free all previous resources when reinitialization */
|
|
+ if (self->module)
|
|
+ cr_updatecollectionmodule_free(self->module);
|
|
+
|
|
+ /* Init */
|
|
+ self->module = cr_updatecollectionmodule_new();
|
|
+ if (self->module == NULL) {
|
|
+ PyErr_SetString(CrErr_Exception, "UpdateCollectionModule initialization failed");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void
|
|
+updatecollectionmodule_dealloc(_UpdateCollectionModuleObject *self)
|
|
+{
|
|
+ if (self->module)
|
|
+ cr_updatecollectionmodule_free(self->module);
|
|
+ Py_TYPE(self)->tp_free(self);
|
|
+}
|
|
+
|
|
+static PyObject *
|
|
+updatecollectionmodule_repr(G_GNUC_UNUSED _UpdateCollectionModuleObject *self)
|
|
+{
|
|
+ return PyUnicode_FromFormat("<createrepo_c.UpdateCollectionModule object>");
|
|
+}
|
|
+
|
|
+/* UpdateCollectionModule methods */
|
|
+
|
|
+PyDoc_STRVAR(copy__doc__,
|
|
+"copy() -> UpdateCollectionModule\n\n"
|
|
+"Return copy of the UpdateCollectionModule object");
|
|
+
|
|
+static PyObject *
|
|
+copy_updatecollectionmodule(_UpdateCollectionModuleObject *self,
|
|
+ G_GNUC_UNUSED void *nothing)
|
|
+{
|
|
+ if (check_UpdateCollectionModuleStatus(self))
|
|
+ return NULL;
|
|
+ return Object_FromUpdateCollectionModule(cr_updatecollectionmodule_copy(self->module));
|
|
+}
|
|
+
|
|
+static struct PyMethodDef updatecollectionmodule_methods[] = {
|
|
+ {"copy", (PyCFunction)copy_updatecollectionmodule, METH_NOARGS,
|
|
+ copy__doc__},
|
|
+ {NULL} /* sentinel */
|
|
+};
|
|
+
|
|
+/* getsetters */
|
|
+
|
|
+#define OFFSET(member) (void *) offsetof(cr_UpdateCollectionModule, member)
|
|
+
|
|
+static PyObject *
|
|
+get_str(_UpdateCollectionModuleObject *self, void *member_offset)
|
|
+{
|
|
+ if (check_UpdateCollectionModuleStatus(self))
|
|
+ return NULL;
|
|
+ cr_UpdateCollectionModule *module = self->module;
|
|
+ char *str = *((char **) ((size_t) module + (size_t) member_offset));
|
|
+ if (str == NULL)
|
|
+ Py_RETURN_NONE;
|
|
+ return PyUnicode_FromString(str);
|
|
+}
|
|
+
|
|
+static PyObject *
|
|
+get_uint(_UpdateCollectionModuleObject *self, void *member_offset)
|
|
+{
|
|
+ if (check_UpdateCollectionModuleStatus(self))
|
|
+ return NULL;
|
|
+ cr_UpdateCollectionModule *module = self->module;
|
|
+ guint64 val = *((guint64 *) ((size_t) module + (size_t) member_offset));
|
|
+ return PyLong_FromUnsignedLongLong((guint64) val);
|
|
+}
|
|
+
|
|
+static int
|
|
+set_str(_UpdateCollectionModuleObject *self, PyObject *value, void *member_offset)
|
|
+{
|
|
+ if (check_UpdateCollectionModuleStatus(self))
|
|
+ return -1;
|
|
+ if (!PyUnicode_Check(value) && !PyBytes_Check(value) && value != Py_None) {
|
|
+ PyErr_SetString(PyExc_TypeError, "Unicode, bytes, or None expected!");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (PyUnicode_Check(value)) {
|
|
+ value = PyUnicode_AsUTF8String(value);
|
|
+ }
|
|
+
|
|
+ cr_UpdateCollectionModule *module = self->module;
|
|
+ char *str = cr_safe_string_chunk_insert(module->chunk,
|
|
+ PyObject_ToStrOrNull(value));
|
|
+
|
|
+ *((char **) ((size_t) module + (size_t) member_offset)) = str;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int
|
|
+set_uint(_UpdateCollectionModuleObject *self, PyObject *value, void *member_offset)
|
|
+{
|
|
+ if (check_UpdateCollectionModuleStatus(self))
|
|
+ return -1;
|
|
+ guint64 val;
|
|
+
|
|
+ if (PyLong_Check(value)) {
|
|
+ val = PyLong_AsUnsignedLongLong(value);
|
|
+ } else if (PyFloat_Check(value)) {
|
|
+ val = (guint64) PyFloat_AS_DOUBLE(value);
|
|
+#if PY_MAJOR_VERSION < 3
|
|
+ } else if (PyInt_Check(value)) {
|
|
+ val = PyInt_AS_LONG(value);
|
|
+#endif
|
|
+ } else {
|
|
+ PyErr_SetString(PyExc_TypeError, "Number expected!");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ cr_UpdateCollectionModule *module = self->module;
|
|
+ *((guint64 *) ((size_t) module + (size_t) member_offset)) = (guint64) val;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static PyGetSetDef updatecollectionmodule_getsetters[] = {
|
|
+ {"name", (getter)get_str, (setter)set_str,
|
|
+ "Name", OFFSET(name)},
|
|
+ {"stream", (getter)get_str, (setter)set_str,
|
|
+ "Stream", OFFSET(stream)},
|
|
+ {"version", (getter)get_uint, (setter)set_uint,
|
|
+ "Version", OFFSET(version)},
|
|
+ {"context", (getter)get_str, (setter)set_str,
|
|
+ "Context", OFFSET(context)},
|
|
+ {"arch", (getter)get_str, (setter)set_str,
|
|
+ "Arch", OFFSET(arch)},
|
|
+ {NULL, NULL, NULL, NULL, NULL} /* sentinel */
|
|
+};
|
|
+
|
|
+/* Object */
|
|
+
|
|
+PyTypeObject UpdateCollectionModule_Type = {
|
|
+ PyVarObject_HEAD_INIT(NULL, 0)
|
|
+ "createrepo_c.UpdateCollectionModule", /* tp_name */
|
|
+ sizeof(_UpdateCollectionModuleObject), /* tp_basicsize */
|
|
+ 0, /* tp_itemsize */
|
|
+ (destructor) updatecollectionmodule_dealloc, /* tp_dealloc */
|
|
+ 0, /* tp_print */
|
|
+ 0, /* tp_getattr */
|
|
+ 0, /* tp_setattr */
|
|
+ 0, /* tp_compare */
|
|
+ (reprfunc) updatecollectionmodule_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 */
|
|
+ updatecollectionmodule_init__doc__, /* tp_doc */
|
|
+ 0, /* tp_traverse */
|
|
+ 0, /* tp_clear */
|
|
+ 0, /* tp_richcompare */
|
|
+ 0, /* tp_weaklistoffset */
|
|
+ PyObject_SelfIter, /* tp_iter */
|
|
+ 0, /* tp_iternext */
|
|
+ updatecollectionmodule_methods, /* tp_methods */
|
|
+ 0, /* tp_members */
|
|
+ updatecollectionmodule_getsetters, /* tp_getset */
|
|
+ 0, /* tp_base */
|
|
+ 0, /* tp_dict */
|
|
+ 0, /* tp_descr_get */
|
|
+ 0, /* tp_descr_set */
|
|
+ 0, /* tp_dictoffset */
|
|
+ (initproc) updatecollectionmodule_init,/* tp_init */
|
|
+ 0, /* tp_alloc */
|
|
+ updatecollectionmodule_new, /* tp_new */
|
|
+ 0, /* tp_free */
|
|
+ 0, /* tp_is_gc */
|
|
+};
|
|
diff --git a/src/python/updatecollectionmodule-py.h b/src/python/updatecollectionmodule-py.h
|
|
new file mode 100644
|
|
index 0000000..5847259
|
|
--- /dev/null
|
|
+++ b/src/python/updatecollectionmodule-py.h
|
|
@@ -0,0 +1,33 @@
|
|
+/* createrepo_c - Library of routines for manipulation with repodata
|
|
+ * Copyright (C) 2013 Tomas Mlcoch
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU General Public License
|
|
+ * as published by the Free Software Foundation; either version 2
|
|
+ * of the License, or (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
|
+ * USA.
|
|
+ */
|
|
+
|
|
+#ifndef CR_UPDATECOLLECTIONMODULE_PY_H
|
|
+#define CR_UPDATECOLLECTIONMODULE_PY_H
|
|
+
|
|
+#include "src/createrepo_c.h"
|
|
+
|
|
+extern PyTypeObject UpdateCollectionModule_Type;
|
|
+
|
|
+#define UpdateCollectionModuleObject_Check(o) \
|
|
+ PyObject_TypeCheck(o, &UpdateCollectionModule_Type)
|
|
+
|
|
+PyObject *Object_FromUpdateCollectionModule(cr_UpdateCollectionModule *rec);
|
|
+cr_UpdateCollectionModule *UpdateCollectionModule_FromPyObject(PyObject *o);
|
|
+
|
|
+#endif
|
|
diff --git a/src/updateinfo.c b/src/updateinfo.c
|
|
index 6e45229..cdc4747 100644
|
|
--- a/src/updateinfo.c
|
|
+++ b/src/updateinfo.c
|
|
@@ -74,6 +74,46 @@ cr_updatecollectionpackage_free(cr_UpdateCollectionPackage *pkg)
|
|
|
|
|
|
/*
|
|
+ * cr_UpdateCollectionModule
|
|
+ */
|
|
+
|
|
+cr_UpdateCollectionModule *
|
|
+cr_updatecollectionmodule_new(void)
|
|
+{
|
|
+ cr_UpdateCollectionModule *module = g_malloc0(sizeof(*module));
|
|
+ module->chunk = g_string_chunk_new(0);
|
|
+ return module;
|
|
+}
|
|
+
|
|
+cr_UpdateCollectionModule *
|
|
+cr_updatecollectionmodule_copy(const cr_UpdateCollectionModule *orig)
|
|
+{
|
|
+ cr_UpdateCollectionModule *module;
|
|
+
|
|
+ if (!orig) return NULL;
|
|
+
|
|
+ module = cr_updatecollectionmodule_new();
|
|
+
|
|
+ module->name = cr_safe_string_chunk_insert(module->chunk, orig->name);
|
|
+ module->stream = cr_safe_string_chunk_insert(module->chunk, orig->stream);
|
|
+ module->version = orig->version;
|
|
+ module->context = cr_safe_string_chunk_insert(module->chunk, orig->context);
|
|
+ module->arch = cr_safe_string_chunk_insert(module->chunk, orig->arch);
|
|
+
|
|
+ return module;
|
|
+}
|
|
+
|
|
+void
|
|
+cr_updatecollectionmodule_free(cr_UpdateCollectionModule *module)
|
|
+{
|
|
+ if (!module)
|
|
+ return;
|
|
+ g_string_chunk_free(module->chunk);
|
|
+ g_free(module);
|
|
+}
|
|
+
|
|
+
|
|
+/*
|
|
* cr_UpdateCollection
|
|
*/
|
|
|
|
@@ -97,6 +137,10 @@ cr_updatecollection_copy(const cr_UpdateCollection *orig)
|
|
col->shortname = cr_safe_string_chunk_insert(col->chunk, orig->shortname);
|
|
col->name = cr_safe_string_chunk_insert(col->chunk, orig->name);
|
|
|
|
+ if (orig->module) {
|
|
+ col->module = cr_updatecollectionmodule_copy(orig->module);
|
|
+ }
|
|
+
|
|
if (orig->packages) {
|
|
GSList *newlist = NULL;
|
|
for (GSList *elem = orig->packages; elem; elem = g_slist_next(elem)) {
|
|
diff --git a/src/updateinfo.h b/src/updateinfo.h
|
|
index dbf7807..38883e0 100644
|
|
--- a/src/updateinfo.h
|
|
+++ b/src/updateinfo.h
|
|
@@ -51,8 +51,19 @@ typedef struct {
|
|
} cr_UpdateCollectionPackage;
|
|
|
|
typedef struct {
|
|
+ gchar *name;
|
|
+ gchar *stream;
|
|
+ guint64 version;
|
|
+ gchar *context;
|
|
+ gchar *arch;
|
|
+
|
|
+ GStringChunk *chunk;
|
|
+} cr_UpdateCollectionModule;
|
|
+
|
|
+typedef struct {
|
|
gchar *shortname; /*!< e.g. rhn-tools-rhel-x86_64-server-6.5.aus */
|
|
gchar *name; /*!< e.g. RHN Tools for RHEL AUS (v. 6.5 for 64-bit x86_64) */
|
|
+ cr_UpdateCollectionModule *module;
|
|
GSList *packages; /*!< List of cr_UpdateCollectionPackage */
|
|
GStringChunk *chunk;
|
|
} cr_UpdateCollection;
|
|
@@ -106,6 +117,19 @@ void
|
|
cr_updatecollectionpackage_free(cr_UpdateCollectionPackage *pkg);
|
|
|
|
/*
|
|
+ * cr_UpdateCollectionModule
|
|
+ */
|
|
+
|
|
+cr_UpdateCollectionModule *
|
|
+cr_updatecollectionmodule_new(void);
|
|
+
|
|
+cr_UpdateCollectionModule *
|
|
+cr_updatecollectionmodule_copy(const cr_UpdateCollectionModule *orig);
|
|
+
|
|
+void
|
|
+cr_updatecollectionmodule_free(cr_UpdateCollectionModule *pkg);
|
|
+
|
|
+/*
|
|
* cr_UpdateCollection
|
|
*/
|
|
|
|
diff --git a/src/xml_dump_updateinfo.c b/src/xml_dump_updateinfo.c
|
|
index 4fb5720..fafe686 100644
|
|
--- a/src/xml_dump_updateinfo.c
|
|
+++ b/src/xml_dump_updateinfo.c
|
|
@@ -66,6 +66,24 @@ cr_xml_dump_updatecollectionpackages(xmlNodePtr collection, GSList *packages)
|
|
}
|
|
|
|
void
|
|
+cr_xml_dump_updatecollectionmodule(xmlNodePtr collection, cr_UpdateCollectionModule *module)
|
|
+{
|
|
+ if (!module)
|
|
+ return;
|
|
+
|
|
+ xmlNodePtr xml_module;
|
|
+ xml_module = xmlNewChild(collection, NULL, BAD_CAST "module", NULL);
|
|
+
|
|
+ cr_xmlNewProp_c(xml_module, BAD_CAST "name", BAD_CAST module->name);
|
|
+ cr_xmlNewProp_c(xml_module, BAD_CAST "stream", BAD_CAST module->stream);
|
|
+ gchar buf[21]; //20 + '\0' is max number of chars of guint64: G_MAXUINT64 (= 18,446,744,073,709,551,615)
|
|
+ snprintf(buf, 21, "%" G_GUINT64_FORMAT, module->version);
|
|
+ cr_xmlNewProp_c(xml_module, BAD_CAST "version", BAD_CAST buf);
|
|
+ cr_xmlNewProp_c(xml_module, BAD_CAST "context", BAD_CAST module->context);
|
|
+ cr_xmlNewProp_c(xml_module, BAD_CAST "arch", BAD_CAST module->arch);
|
|
+}
|
|
+
|
|
+void
|
|
cr_xml_dump_updateinforecord_pkglist(xmlNodePtr update, GSList *collections)
|
|
{
|
|
xmlNodePtr pkglist;
|
|
@@ -83,6 +101,8 @@ cr_xml_dump_updateinforecord_pkglist(xmlNodePtr update, GSList *collections)
|
|
BAD_CAST "name",
|
|
BAD_CAST col->name);
|
|
|
|
+ cr_xml_dump_updatecollectionmodule(collection, col->module);
|
|
+
|
|
cr_xml_dump_updatecollectionpackages(collection, col->packages);
|
|
}
|
|
}
|
|
diff --git a/src/xml_parser_internal.h b/src/xml_parser_internal.h
|
|
index 6b400eb..e079ece 100644
|
|
--- a/src/xml_parser_internal.h
|
|
+++ b/src/xml_parser_internal.h
|
|
@@ -151,6 +151,8 @@ typedef struct _cr_ParserData {
|
|
Update record object */
|
|
cr_UpdateCollection *updatecollection; /*!<
|
|
Update collection object */
|
|
+ cr_UpdateCollectionModule *updatecollectionmodule; /*!<
|
|
+ Update collection module object */
|
|
cr_UpdateCollectionPackage *updatecollectionpackage; /*!<
|
|
Update collection package object */
|
|
|
|
diff --git a/src/xml_parser_updateinfo.c b/src/xml_parser_updateinfo.c
|
|
index 18e5277..c6c6503 100644
|
|
--- a/src/xml_parser_updateinfo.c
|
|
+++ b/src/xml_parser_updateinfo.c
|
|
@@ -54,6 +54,7 @@ typedef enum {
|
|
STATE_PKGLIST, // <pkglist> ----------------------------
|
|
STATE_COLLECTION,
|
|
STATE_NAME,
|
|
+ STATE_MODULE,
|
|
STATE_PACKAGE,
|
|
STATE_FILENAME,
|
|
STATE_SUM,
|
|
@@ -89,6 +90,7 @@ static cr_StatesSwitch stateswitches[] = {
|
|
{ STATE_PKGLIST, "collection", STATE_COLLECTION, 0 },
|
|
{ STATE_COLLECTION, "package", STATE_PACKAGE, 0 },
|
|
{ STATE_COLLECTION, "name", STATE_NAME, 1 },
|
|
+ { STATE_COLLECTION, "module", STATE_MODULE, 0 },
|
|
{ STATE_PACKAGE, "filename", STATE_FILENAME, 1 },
|
|
{ STATE_PACKAGE, "sum", STATE_SUM, 1 },
|
|
{ STATE_PACKAGE, "reboot_suggested", STATE_REBOOTSUGGESTED, 0 },
|
|
@@ -141,6 +143,7 @@ cr_start_handler(void *pdata, const char *element, const char **attr)
|
|
// Shortcuts
|
|
cr_UpdateRecord *rec = pd->updaterecord;
|
|
cr_UpdateCollection *collection = pd->updatecollection;
|
|
+ cr_UpdateCollectionModule *module = pd->updatecollectionmodule;
|
|
cr_UpdateCollectionPackage *package = pd->updatecollectionpackage;
|
|
|
|
switch(pd->state) {
|
|
@@ -173,6 +176,7 @@ cr_start_handler(void *pdata, const char *element, const char **attr)
|
|
assert(pd->updateinfo);
|
|
assert(!pd->updaterecord);
|
|
assert(!pd->updatecollection);
|
|
+ assert(!pd->updatecollectionmodule);
|
|
assert(!pd->updatecollectionpackage);
|
|
|
|
rec = cr_updaterecord_new();
|
|
@@ -201,6 +205,7 @@ cr_start_handler(void *pdata, const char *element, const char **attr)
|
|
assert(pd->updateinfo);
|
|
assert(pd->updaterecord);
|
|
assert(!pd->updatecollection);
|
|
+ assert(!pd->updatecollectionmodule);
|
|
assert(!pd->updatecollectionpackage);
|
|
val = cr_find_attr("date", attr);
|
|
if (val)
|
|
@@ -211,6 +216,7 @@ cr_start_handler(void *pdata, const char *element, const char **attr)
|
|
assert(pd->updateinfo);
|
|
assert(pd->updaterecord);
|
|
assert(!pd->updatecollection);
|
|
+ assert(!pd->updatecollectionmodule);
|
|
assert(!pd->updatecollectionpackage);
|
|
val = cr_find_attr("date", attr);
|
|
if (val)
|
|
@@ -223,6 +229,7 @@ cr_start_handler(void *pdata, const char *element, const char **attr)
|
|
assert(pd->updateinfo);
|
|
assert(pd->updaterecord);
|
|
assert(!pd->updatecollection);
|
|
+ assert(!pd->updatecollectionmodule);
|
|
assert(!pd->updatecollectionpackage);
|
|
|
|
ref = cr_updatereference_new();
|
|
@@ -251,6 +258,7 @@ cr_start_handler(void *pdata, const char *element, const char **attr)
|
|
assert(pd->updateinfo);
|
|
assert(pd->updaterecord);
|
|
assert(!pd->updatecollection);
|
|
+ assert(!pd->updatecollectionmodule);
|
|
assert(!pd->updatecollectionpackage);
|
|
|
|
collection = cr_updatecollection_new();
|
|
@@ -263,6 +271,49 @@ cr_start_handler(void *pdata, const char *element, const char **attr)
|
|
|
|
break;
|
|
|
|
+ case STATE_MODULE:
|
|
+ assert(pd->updateinfo);
|
|
+ assert(pd->updaterecord);
|
|
+ assert(pd->updatecollection);
|
|
+ assert(!pd->updatecollectionmodule);
|
|
+ assert(!pd->updatecollectionpackage);
|
|
+
|
|
+ module = cr_updatecollectionmodule_new();
|
|
+ if (module)
|
|
+ collection->module = module;
|
|
+
|
|
+ val = cr_find_attr("name", attr);
|
|
+ if (val)
|
|
+ module->name = g_string_chunk_insert(module->chunk, val);
|
|
+
|
|
+ val = cr_find_attr("stream", attr);
|
|
+ if (val)
|
|
+ module->stream = g_string_chunk_insert(module->chunk, val);
|
|
+
|
|
+ val = cr_find_attr("version", attr);
|
|
+ if (val){
|
|
+ gchar *endptr;
|
|
+ errno = 0;
|
|
+ module->version = strtoull(val, &endptr, 10);
|
|
+ if ((errno == ERANGE && (module->version == ULLONG_MAX))
|
|
+ || (errno != 0 && module->version == 0)) {
|
|
+ perror("strtoull error when parsing module version");
|
|
+ module->version = 0;
|
|
+ }
|
|
+ if (endptr == val)
|
|
+ module->version = 0;
|
|
+ }
|
|
+
|
|
+ val = cr_find_attr("context", attr);
|
|
+ if (val)
|
|
+ module->context = g_string_chunk_insert(module->chunk, val);
|
|
+
|
|
+ val = cr_find_attr("arch", attr);
|
|
+ if (val)
|
|
+ module->arch = g_string_chunk_insert(module->chunk, val);
|
|
+
|
|
+ break;
|
|
+
|
|
case STATE_PACKAGE:
|
|
assert(pd->updateinfo);
|
|
assert(pd->updaterecord);
|
|
@@ -303,6 +354,7 @@ cr_start_handler(void *pdata, const char *element, const char **attr)
|
|
assert(pd->updateinfo);
|
|
assert(pd->updaterecord);
|
|
assert(pd->updatecollection);
|
|
+ assert(pd->updatecollectionmodule);
|
|
assert(pd->updatecollectionpackage);
|
|
val = cr_find_attr("type", attr);
|
|
if (val)
|
|
@@ -313,6 +365,7 @@ cr_start_handler(void *pdata, const char *element, const char **attr)
|
|
assert(pd->updateinfo);
|
|
assert(pd->updaterecord);
|
|
assert(pd->updatecollection);
|
|
+ assert(pd->updatecollectionmodule);
|
|
assert(pd->updatecollectionpackage);
|
|
package->reboot_suggested = TRUE;
|
|
break;
|
|
@@ -352,6 +405,7 @@ cr_end_handler(void *pdata, G_GNUC_UNUSED const char *element)
|
|
case STATE_UPDATED:
|
|
case STATE_REFERENCES:
|
|
case STATE_REFERENCE:
|
|
+ case STATE_MODULE:
|
|
case STATE_PKGLIST:
|
|
case STATE_REBOOTSUGGESTED:
|
|
// All elements with no text data and without need of any
|
|
diff --git a/tests/fixtures.h b/tests/fixtures.h
|
|
index ee374f5..8567714 100644
|
|
--- a/tests/fixtures.h
|
|
+++ b/tests/fixtures.h
|
|
@@ -83,5 +83,6 @@
|
|
#define TEST_UPDATEINFO_00 TEST_UPDATEINFO_FILES_PATH"updateinfo_00.xml"
|
|
#define TEST_UPDATEINFO_01 TEST_UPDATEINFO_FILES_PATH"updateinfo_01.xml"
|
|
#define TEST_UPDATEINFO_02 TEST_UPDATEINFO_FILES_PATH"updateinfo_02.xml.xz"
|
|
+#define TEST_UPDATEINFO_03 TEST_UPDATEINFO_FILES_PATH"updateinfo_03.xml"
|
|
|
|
#endif
|
|
diff --git a/tests/python/tests/test_updatecollection.py b/tests/python/tests/test_updatecollection.py
|
|
index f3433c0..71ac7dd 100644
|
|
--- a/tests/python/tests/test_updatecollection.py
|
|
+++ b/tests/python/tests/test_updatecollection.py
|
|
@@ -16,6 +16,13 @@ class TestCaseUpdateCollection(unittest.TestCase):
|
|
self.assertEqual(col.name, None)
|
|
self.assertEqual(col.packages, [])
|
|
|
|
+ module = cr.UpdateCollectionModule()
|
|
+ module.name = "kangaroo"
|
|
+ module.stream = "0"
|
|
+ module.version = 20180730223407
|
|
+ module.context = "deadbeef"
|
|
+ module.arch = "noarch"
|
|
+
|
|
pkg = cr.UpdateCollectionPackage()
|
|
pkg.name = "foo"
|
|
pkg.version = "1.2"
|
|
@@ -30,12 +37,21 @@ class TestCaseUpdateCollection(unittest.TestCase):
|
|
|
|
col.shortname = "short name"
|
|
col.name = "long name"
|
|
+ col.module = module
|
|
col.append(pkg)
|
|
|
|
self.assertEqual(col.shortname, "short name")
|
|
self.assertEqual(col.name, "long name")
|
|
self.assertEqual(len(col.packages), 1)
|
|
|
|
+ # Check if the appended module was appended properly
|
|
+ module = col.module
|
|
+ self.assertEqual(module.name, "kangaroo")
|
|
+ self.assertEqual(module.stream, "0")
|
|
+ self.assertEqual(module.version, 20180730223407)
|
|
+ self.assertEqual(module.context, "deadbeef")
|
|
+ self.assertEqual(module.arch, "noarch")
|
|
+
|
|
# Also check if the appended package was appended properly
|
|
pkg = col.packages[0]
|
|
self.assertEqual(pkg.name, "foo")
|
|
diff --git a/tests/python/tests/test_updatecollectionmodule.py b/tests/python/tests/test_updatecollectionmodule.py
|
|
new file mode 100644
|
|
index 0000000..1e92b12
|
|
--- /dev/null
|
|
+++ b/tests/python/tests/test_updatecollectionmodule.py
|
|
@@ -0,0 +1,31 @@
|
|
+import unittest
|
|
+import shutil
|
|
+import tempfile
|
|
+import os.path
|
|
+import createrepo_c as cr
|
|
+
|
|
+from .fixtures import *
|
|
+
|
|
+class TestCaseUpdateCollectionModule(unittest.TestCase):
|
|
+
|
|
+ def test_updatecollectionmodule_setters(self):
|
|
+ module = cr.UpdateCollectionModule()
|
|
+ self.assertTrue(module)
|
|
+
|
|
+ self.assertEqual(module.name, None)
|
|
+ self.assertEqual(module.stream, None)
|
|
+ self.assertEqual(module.version, 0)
|
|
+ self.assertEqual(module.context, None)
|
|
+ self.assertEqual(module.arch, None)
|
|
+
|
|
+ module.name = "foo"
|
|
+ module.stream = "0"
|
|
+ module.version = 20180730223407
|
|
+ module.context = "deadbeef"
|
|
+ module.arch = "noarch"
|
|
+
|
|
+ self.assertEqual(module.name, "foo")
|
|
+ self.assertEqual(module.stream, "0")
|
|
+ self.assertEqual(module.version, 20180730223407)
|
|
+ self.assertEqual(module.context, "deadbeef")
|
|
+ self.assertEqual(module.arch, "noarch")
|
|
diff --git a/tests/python/tests/test_updateinfo.py b/tests/python/tests/test_updateinfo.py
|
|
index f3b88e1..727b707 100644
|
|
--- a/tests/python/tests/test_updateinfo.py
|
|
+++ b/tests/python/tests/test_updateinfo.py
|
|
@@ -123,6 +123,100 @@ class TestCaseUpdateInfo(unittest.TestCase):
|
|
now = datetime(now.year, now.month, now.day, now.hour, now.minute,
|
|
now.second, 0)
|
|
|
|
+ mod = cr.UpdateCollectionModule()
|
|
+ mod.name = "kangaroo"
|
|
+ mod.stream = "0"
|
|
+ mod.version = 18446744073709551615
|
|
+ mod.context = "deadbeef"
|
|
+ mod.arch = "x86"
|
|
+
|
|
+ pkg = cr.UpdateCollectionPackage()
|
|
+ pkg.name = "foo"
|
|
+ pkg.version = "1.2"
|
|
+ pkg.release = "3"
|
|
+ pkg.epoch = "0"
|
|
+ pkg.arch = "x86"
|
|
+ pkg.src = "foo.src.rpm"
|
|
+ pkg.filename = "foo.rpm"
|
|
+ pkg.sum = "abcdef"
|
|
+ pkg.sum_type = cr.SHA1
|
|
+ pkg.reboot_suggested = True
|
|
+
|
|
+ col = cr.UpdateCollection()
|
|
+ col.shortname = "short name"
|
|
+ col.name = "long name"
|
|
+ col.module = mod
|
|
+ col.append(pkg)
|
|
+
|
|
+ ref = cr.UpdateReference()
|
|
+ ref.href = "href"
|
|
+ ref.id = "id"
|
|
+ ref.type = "type"
|
|
+ ref.title = "title"
|
|
+
|
|
+ rec = cr.UpdateRecord()
|
|
+ rec.fromstr = "from"
|
|
+ rec.status = "status"
|
|
+ rec.type = "type"
|
|
+ rec.version = "version"
|
|
+ rec.id = "id"
|
|
+ rec.title = "title"
|
|
+ rec.issued_date = now
|
|
+ rec.updated_date = now
|
|
+ rec.rights = "rights"
|
|
+ rec.release = "release"
|
|
+ rec.pushcount = "pushcount"
|
|
+ rec.severity = "severity"
|
|
+ rec.summary = "summary"
|
|
+ rec.description = "description"
|
|
+ rec.solution = "solution"
|
|
+ rec.append_collection(col)
|
|
+ rec.append_reference(ref)
|
|
+
|
|
+ ui = cr.UpdateInfo()
|
|
+ ui.append(rec)
|
|
+
|
|
+ xml = ui.xml_dump()
|
|
+
|
|
+ self.assertEqual(xml,
|
|
+"""<?xml version="1.0" encoding="UTF-8"?>
|
|
+<updates>
|
|
+ <update from="from" status="status" type="type" version="version">
|
|
+ <id>id</id>
|
|
+ <title>title</title>
|
|
+ <issued date="%(now)s"/>
|
|
+ <updated date="%(now)s"/>
|
|
+ <rights>rights</rights>
|
|
+ <release>release</release>
|
|
+ <pushcount>pushcount</pushcount>
|
|
+ <severity>severity</severity>
|
|
+ <summary>summary</summary>
|
|
+ <description>description</description>
|
|
+ <solution>solution</solution>
|
|
+ <references>
|
|
+ <reference href="href" id="id" type="type" title="title"/>
|
|
+ </references>
|
|
+ <pkglist>
|
|
+ <collection short="short name">
|
|
+ <name>long name</name>
|
|
+ <module name="kangaroo" stream="0" version="18446744073709551615" context="deadbeef" arch="x86"/>
|
|
+ <package name="foo" version="1.2" release="3" epoch="0" arch="x86" src="foo.src.rpm">
|
|
+ <filename>foo.rpm</filename>
|
|
+ <sum type="sha1">abcdef</sum>
|
|
+ <reboot_suggested/>
|
|
+ </package>
|
|
+ </collection>
|
|
+ </pkglist>
|
|
+ </update>
|
|
+</updates>
|
|
+""" % {"now": now.strftime("%Y-%m-%d %H:%M:%S")})
|
|
+
|
|
+ def test_updateinfo_xml_dump_04(self):
|
|
+ now = datetime.now()
|
|
+ # Microseconds are always 0 in updateinfo
|
|
+ now = datetime(now.year, now.month, now.day, now.hour, now.minute,
|
|
+ now.second, 0)
|
|
+
|
|
pkg = cr.UpdateCollectionPackage()
|
|
pkg.name = "foo"
|
|
pkg.version = "1.2"
|
|
@@ -135,6 +229,7 @@ class TestCaseUpdateInfo(unittest.TestCase):
|
|
pkg.sum_type = cr.SHA1
|
|
pkg.reboot_suggested = True
|
|
|
|
+ # Collection without module
|
|
col = cr.UpdateCollection()
|
|
col.shortname = "short name"
|
|
col.name = "long name"
|
|
@@ -167,6 +262,99 @@ class TestCaseUpdateInfo(unittest.TestCase):
|
|
|
|
ui = cr.UpdateInfo()
|
|
ui.append(rec)
|
|
+
|
|
+ xml = ui.xml_dump()
|
|
+
|
|
+ self.assertEqual(xml,
|
|
+"""<?xml version="1.0" encoding="UTF-8"?>
|
|
+<updates>
|
|
+ <update from="from" status="status" type="type" version="version">
|
|
+ <id>id</id>
|
|
+ <title>title</title>
|
|
+ <issued date="%(now)s"/>
|
|
+ <updated date="%(now)s"/>
|
|
+ <rights>rights</rights>
|
|
+ <release>release</release>
|
|
+ <pushcount>pushcount</pushcount>
|
|
+ <severity>severity</severity>
|
|
+ <summary>summary</summary>
|
|
+ <description>description</description>
|
|
+ <solution>solution</solution>
|
|
+ <references>
|
|
+ <reference href="href" id="id" type="type" title="title"/>
|
|
+ </references>
|
|
+ <pkglist>
|
|
+ <collection short="short name">
|
|
+ <name>long name</name>
|
|
+ <package name="foo" version="1.2" release="3" epoch="0" arch="x86" src="foo.src.rpm">
|
|
+ <filename>foo.rpm</filename>
|
|
+ <sum type="sha1">abcdef</sum>
|
|
+ <reboot_suggested/>
|
|
+ </package>
|
|
+ </collection>
|
|
+ </pkglist>
|
|
+ </update>
|
|
+</updates>
|
|
+""" % {"now": now.strftime("%Y-%m-%d %H:%M:%S")})
|
|
+
|
|
+ def test_updateinfo_xml_dump_05(self):
|
|
+ now = datetime.now()
|
|
+ # Microseconds are always 0 in updateinfo
|
|
+ now = datetime(now.year, now.month, now.day, now.hour, now.minute,
|
|
+ now.second, 0)
|
|
+
|
|
+ # Collection module with unset fields
|
|
+ mod = cr.UpdateCollectionModule()
|
|
+ mod.version = 18446744073709551615
|
|
+ mod.context = "deadbeef"
|
|
+ mod.arch = "x86"
|
|
+
|
|
+ pkg = cr.UpdateCollectionPackage()
|
|
+ pkg.name = "foo"
|
|
+ pkg.version = "1.2"
|
|
+ pkg.release = "3"
|
|
+ pkg.epoch = "0"
|
|
+ pkg.arch = "x86"
|
|
+ pkg.src = "foo.src.rpm"
|
|
+ pkg.filename = "foo.rpm"
|
|
+ pkg.sum = "abcdef"
|
|
+ pkg.sum_type = cr.SHA1
|
|
+ pkg.reboot_suggested = True
|
|
+
|
|
+ col = cr.UpdateCollection()
|
|
+ col.shortname = "short name"
|
|
+ col.name = "long name"
|
|
+ col.module = mod
|
|
+ col.append(pkg)
|
|
+
|
|
+ ref = cr.UpdateReference()
|
|
+ ref.href = "href"
|
|
+ ref.id = "id"
|
|
+ ref.type = "type"
|
|
+ ref.title = "title"
|
|
+
|
|
+ rec = cr.UpdateRecord()
|
|
+ rec.fromstr = "from"
|
|
+ rec.status = "status"
|
|
+ rec.type = "type"
|
|
+ rec.version = "version"
|
|
+ rec.id = "id"
|
|
+ rec.title = "title"
|
|
+ rec.issued_date = now
|
|
+ rec.updated_date = now
|
|
+ rec.rights = "rights"
|
|
+ rec.release = "release"
|
|
+ rec.pushcount = "pushcount"
|
|
+ rec.severity = "severity"
|
|
+ rec.summary = "summary"
|
|
+ rec.description = "description"
|
|
+ rec.solution = "solution"
|
|
+ rec.append_collection(col)
|
|
+ rec.append_reference(ref)
|
|
+
|
|
+ ui = cr.UpdateInfo()
|
|
+ ui.append(rec)
|
|
+
|
|
xml = ui.xml_dump()
|
|
|
|
self.assertEqual(xml,
|
|
@@ -190,6 +378,7 @@ class TestCaseUpdateInfo(unittest.TestCase):
|
|
<pkglist>
|
|
<collection short="short name">
|
|
<name>long name</name>
|
|
+ <module version="18446744073709551615" context="deadbeef" arch="x86"/>
|
|
<package name="foo" version="1.2" release="3" epoch="0" arch="x86" src="foo.src.rpm">
|
|
<filename>foo.rpm</filename>
|
|
<sum type="sha1">abcdef</sum>
|
|
diff --git a/tests/test_xml_parser_updateinfo.c b/tests/test_xml_parser_updateinfo.c
|
|
index 94768ce..3f0cfee 100644
|
|
--- a/tests/test_xml_parser_updateinfo.c
|
|
+++ b/tests/test_xml_parser_updateinfo.c
|
|
@@ -168,6 +168,90 @@ test_cr_xml_parse_updateinfo_02(void)
|
|
cr_updateinfo_free(ui);
|
|
}
|
|
|
|
+//Test for module support
|
|
+static void
|
|
+test_cr_xml_parse_updateinfo_03(void)
|
|
+{
|
|
+ GError *tmp_err = NULL;
|
|
+ cr_UpdateInfo *ui = cr_updateinfo_new();
|
|
+ cr_UpdateRecord *update;
|
|
+ cr_UpdateReference *ref;
|
|
+ cr_UpdateCollection *col;
|
|
+ cr_UpdateCollectionModule *module;
|
|
+ cr_UpdateCollectionPackage *pkg;
|
|
+
|
|
+ int ret = cr_xml_parse_updateinfo(TEST_UPDATEINFO_03, ui,
|
|
+ NULL, NULL, &tmp_err);
|
|
+
|
|
+ g_assert(tmp_err == NULL);
|
|
+ g_assert_cmpint(ret, ==, CRE_OK);
|
|
+
|
|
+ g_assert_cmpint(g_slist_length(ui->updates), ==, 6);
|
|
+ update = g_slist_nth_data(ui->updates, 3);
|
|
+
|
|
+ g_assert_cmpstr(update->from, ==, "errata@redhat.com");
|
|
+ g_assert_cmpstr(update->status, ==, "stable");
|
|
+ g_assert_cmpstr(update->type, ==, "enhancement");
|
|
+ g_assert_cmpstr(update->version, ==, "1");
|
|
+ g_assert_cmpstr(update->id, ==, "RHEA-2012:0058");
|
|
+ g_assert_cmpstr(update->title, ==, "Gorilla_Erratum");
|
|
+ g_assert_cmpstr(update->description, ==, "Gorilla_Erratum");
|
|
+
|
|
+ update = g_slist_nth_data(ui->updates, 4);
|
|
+
|
|
+ g_assert_cmpstr(update->id, ==, "RHEA-2012:0059");
|
|
+ g_assert_cmpstr(update->title, ==, "Duck_Kangaroo_Erratum");
|
|
+ g_assert_cmpstr(update->description, ==, "Duck_Kangaro_Erratum description");
|
|
+ g_assert_cmpstr(update->issued_date, ==, "2018-01-27 16:08:09");
|
|
+ g_assert_cmpstr(update->updated_date, ==, "2018-07-20 06:00:01 UTC");
|
|
+ g_assert_cmpstr(update->release, ==, "1");
|
|
+
|
|
+ g_assert_cmpint(g_slist_length(update->references), ==, 0);
|
|
+
|
|
+ g_assert_cmpint(g_slist_length(update->collections), ==, 2);
|
|
+ col = g_slist_nth_data(update->collections, 0);
|
|
+ g_assert_cmpstr(col->shortname, ==, "");
|
|
+ g_assert_cmpstr(col->name, ==, "coll_name1");
|
|
+
|
|
+ module = col->module;
|
|
+ g_assert_cmpstr(module->name, ==, "kangaroo");
|
|
+ g_assert_cmpstr(module->stream, ==, "0");
|
|
+ g_assert_cmpuint(module->version, ==, 20180730223407);
|
|
+ g_assert_cmpstr(module->context, ==, "deadbeef");
|
|
+ g_assert_cmpstr(module->arch, ==, "noarch");
|
|
+
|
|
+ g_assert_cmpint(g_slist_length(col->packages), ==, 1);
|
|
+ pkg = col->packages->data;
|
|
+ g_assert_cmpstr(pkg->name, ==, "kangaroo");
|
|
+ g_assert_cmpstr(pkg->version, ==, "0.3");
|
|
+ g_assert_cmpstr(pkg->release, ==, "1");
|
|
+ g_assert(!pkg->epoch);
|
|
+ g_assert_cmpstr(pkg->arch, ==, "noarch");
|
|
+ g_assert_cmpstr(pkg->src, ==, "http://www.fedoraproject.org");
|
|
+ g_assert_cmpstr(pkg->filename, ==, "kangaroo-0.3-1.noarch.rpm");
|
|
+ g_assert(!pkg->sum);
|
|
+ g_assert(!pkg->sum_type);
|
|
+
|
|
+ col = g_slist_nth_data(update->collections, 1);
|
|
+ g_assert_cmpstr(col->shortname, ==, "");
|
|
+ g_assert_cmpstr(col->name, ==, "coll_name2");
|
|
+
|
|
+ module = col->module;
|
|
+ g_assert_cmpstr(module->name, ==, "duck");
|
|
+ g_assert_cmpstr(module->stream, ==, "0");
|
|
+ g_assert_cmpuint(module->version, ==, 20180730233102);
|
|
+ g_assert_cmpstr(module->context, ==, "deadbeef");
|
|
+ g_assert_cmpstr(module->arch, ==, "noarch");
|
|
+
|
|
+ g_assert_cmpint(g_slist_length(col->packages), ==, 1);
|
|
+ pkg = col->packages->data;
|
|
+ g_assert_cmpstr(pkg->name, ==, "duck");
|
|
+ g_assert_cmpstr(pkg->version, ==, "0.7");
|
|
+ g_assert_cmpstr(pkg->filename, ==, "duck-0.7-1.noarch.rpm");
|
|
+
|
|
+ cr_updateinfo_free(ui);
|
|
+}
|
|
+
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
@@ -179,6 +263,8 @@ main(int argc, char *argv[])
|
|
test_cr_xml_parse_updateinfo_01);
|
|
g_test_add_func("/xml_parser_updateinfo/test_cr_xml_parse_updateinfo_02",
|
|
test_cr_xml_parse_updateinfo_02);
|
|
+ g_test_add_func("/xml_parser_updateinfo/test_cr_xml_parse_updateinfo_03",
|
|
+ test_cr_xml_parse_updateinfo_03);
|
|
|
|
return g_test_run();
|
|
}
|
|
diff --git a/tests/testdata/updateinfo_files/updateinfo_03.xml b/tests/testdata/updateinfo_files/updateinfo_03.xml
|
|
new file mode 100644
|
|
index 0000000..ddbd99b
|
|
--- /dev/null
|
|
+++ b/tests/testdata/updateinfo_files/updateinfo_03.xml
|
|
@@ -0,0 +1,128 @@
|
|
+<?xml version="1.0"?>
|
|
+<updates>
|
|
+<update from="errata@redhat.com" status="stable" type="security" version="1">
|
|
+ <id>RHEA-2012:0055</id>
|
|
+ <title>Sea_Erratum</title>
|
|
+ <release>1</release>
|
|
+ <issued date="2012-01-27 16:08:06"/>
|
|
+ <updated date="2012-01-27 16:08:06"/>
|
|
+ <description>Sea_Erratum</description>
|
|
+ <pkglist>
|
|
+ <collection short="">
|
|
+ <name>1</name>
|
|
+ <package arch="noarch" name="walrus" release="1" src="http://www.fedoraproject.org" version="5.21">
|
|
+ <filename>walrus-5.21-1.noarch.rpm</filename>
|
|
+ </package>
|
|
+ <package arch="noarch" name="penguin" release="1" src="http://www.fedoraproject.org" version="0.9.1">
|
|
+ <filename>penguin-0.9.1-1.noarch.rpm</filename>
|
|
+ </package>
|
|
+ <package arch="noarch" name="shark" release="1" src="http://www.fedoraproject.org" version="0.1">
|
|
+ <filename>shark-0.1-1.noarch.rpm</filename>
|
|
+ </package>
|
|
+ </collection>
|
|
+ </pkglist>
|
|
+</update>
|
|
+
|
|
+<update from="errata@redhat.com" status="stable" type="security" version="1">
|
|
+ <id>RHEA-2012:0056</id>
|
|
+ <title>Bird_Erratum</title>
|
|
+ <release>1</release>
|
|
+ <issued date="2013-01-27 16:08:08"/>
|
|
+ <updated date="2013-02-27 17:00:00"/>
|
|
+ <description>ParthaBird_Erratum</description>
|
|
+ <pkglist>
|
|
+ <collection short="">
|
|
+ <name>1</name>
|
|
+ <package arch="noarch" name="crow" release="1" src="http://www.fedoraproject.org" version="0.8">
|
|
+ <filename>crow-0.8-1.noarch.rpm</filename>
|
|
+ </package>
|
|
+ <package arch="noarch" name="stork" release="2" src="http://www.fedoraproject.org" version="0.12">
|
|
+ <filename>stork-0.12-2.noarch.rpm</filename>
|
|
+ </package>
|
|
+ <package arch="noarch" name="duck" release="1" src="http://www.fedoraproject.org" version="0.6">
|
|
+ <filename>duck-0.6-1.noarch.rpm</filename>
|
|
+ </package>
|
|
+ </collection>
|
|
+ </pkglist>
|
|
+</update>
|
|
+
|
|
+<update from="errata@redhat.com" status="stable" type="security" version="1">
|
|
+ <id>RHEA-2012:0057</id>
|
|
+ <title>Bear_ErratumPARTHA</title>
|
|
+ <release>1</release>
|
|
+ <issued date="2013-01-27 16:08:05"/>
|
|
+ <updated date="2013-01-27 16:08:05 UTC"/>
|
|
+ <description>Bear_Erratum</description>
|
|
+ <pkglist>
|
|
+ <collection short="">
|
|
+ <name>1</name>
|
|
+ <package arch="noarch" name="bear" release="1" src="http://www.fedoraproject.org" version="4.1">
|
|
+ <filename>bear-4.1-1.noarch.rpm</filename>
|
|
+ </package>
|
|
+ </collection>
|
|
+ </pkglist>
|
|
+</update>
|
|
+
|
|
+<update from="errata@redhat.com" status="stable" type="enhancement" version="1">
|
|
+ <id>RHEA-2012:0058</id>
|
|
+ <title>Gorilla_Erratum</title>
|
|
+ <release>1</release>
|
|
+ <issued date="2013-01-27 16:08:09"/>
|
|
+ <updated date="2014-07-20 06:00:01 UTC"/>
|
|
+ <description>Gorilla_Erratum</description>
|
|
+ <pkglist>
|
|
+ <collection short="">
|
|
+ <name>1</name>
|
|
+ <package arch="noarch" name="gorilla" release="1" src="http://www.fedoraproject.org" version="0.62">
|
|
+ <filename>gorilla-0.62-1.noarch.rpm</filename>
|
|
+ </package>
|
|
+ </collection>
|
|
+ </pkglist>
|
|
+</update>
|
|
+
|
|
+<update from="errata@redhat.com" status="stable" type="enhancement" version="1">
|
|
+ <id>RHEA-2012:0059</id>
|
|
+ <title>Duck_Kangaroo_Erratum</title>
|
|
+ <release>1</release>
|
|
+ <issued date="2018-01-27 16:08:09"/>
|
|
+ <updated date="2018-07-20 06:00:01 UTC"/>
|
|
+ <description>Duck_Kangaro_Erratum description</description>
|
|
+ <pkglist>
|
|
+ <collection short="">
|
|
+ <name>coll_name1</name>
|
|
+ <module name="kangaroo" stream="0" version="20180730223407" context="deadbeef" arch="noarch"/>
|
|
+ <package arch="noarch" name="kangaroo" release="1" src="http://www.fedoraproject.org"
|
|
+ version="0.3">
|
|
+ <filename>kangaroo-0.3-1.noarch.rpm</filename>
|
|
+ </package>
|
|
+ </collection>
|
|
+ <collection short="">
|
|
+ <name>coll_name2</name>
|
|
+ <module name="duck" stream="0" version="20180730233102" context="deadbeef" arch="noarch"/>
|
|
+ <package arch="noarch" name="duck" release="1" src="http://www.fedoraproject.org"
|
|
+ version="0.7">
|
|
+ <filename>duck-0.7-1.noarch.rpm</filename>
|
|
+ </package>
|
|
+ </collection>
|
|
+ </pkglist>
|
|
+</update>
|
|
+
|
|
+<update from="errata@redhat.com" status="stable" type="enhancement" version="1">
|
|
+ <id>RHEA-2012:0060</id>
|
|
+ <title>Duck_0.8_Erratum</title>
|
|
+ <release>1</release>
|
|
+ <issued date="2018-01-29 16:08:09"/>
|
|
+ <updated date="2018-07-29 06:00:01 UTC"/>
|
|
+ <description>Duck_0.8_Erratum description</description>
|
|
+ <pkglist>
|
|
+ <collection short="">
|
|
+ <name>coll_name</name>
|
|
+ <module name="duck" stream="0" version="201809302113907" context="deadbeef" arch="noarch"/>
|
|
+ <package arch="noarch" name="duck" release="1" src="http://www.fedoraproject.org"
|
|
+ version="0.8">
|
|
+ <filename>duck-0.8-1.noarch.rpm</filename>
|
|
+ </package>
|
|
+ </collection>
|
|
+ </pkglist>
|
|
+</update>
|
|
+</updates>
|
|
--
|
|
libgit2 0.27.8
|
|
|