From af9c8b4575749c3d03afe6c704060661622199bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= Date: Tue, 3 Dec 2019 09:21:27 +0100 Subject: [PATCH 1/3] Add reboot_suggested field to UpdateRecord (RhBug:1772466) https://bugzilla.redhat.com/show_bug.cgi?id=1772466 --- src/python/updaterecord-py.c | 35 +++++++++++++++++++++++++++++++++++ src/updateinfo.c | 1 + src/updateinfo.h | 1 + src/xml_dump_updateinfo.c | 3 +++ src/xml_parser_updateinfo.c | 9 +++++++++ 5 files changed, 49 insertions(+) diff --git a/src/python/updaterecord-py.c b/src/python/updaterecord-py.c index 4f41019..b74bcb8 100644 --- a/src/python/updaterecord-py.c +++ b/src/python/updaterecord-py.c @@ -248,6 +248,16 @@ static ListConvertor list_convertors[] = { #define OFFSET(member) (void *) offsetof(cr_UpdateRecord, member) +static PyObject * +get_int(_UpdateRecordObject *self, void *member_offset) +{ + if (check_UpdateRecordStatus(self)) + return NULL; + cr_UpdateRecord *rec = self->record; + gint64 val = *((int *) ((size_t) rec + (size_t) member_offset)); + return PyLong_FromLongLong((long long) val); +} + static PyObject * get_str(_UpdateRecordObject *self, void *member_offset) { @@ -311,6 +321,29 @@ get_list(_UpdateRecordObject *self, void *conv) return list; } +static int +set_int(_UpdateRecordObject *self, PyObject *value, void *member_offset) +{ + long val; + if (check_UpdateRecordStatus(self)) + return -1; + if (PyLong_Check(value)) { + val = PyLong_AsLong(value); + } else if (PyFloat_Check(value)) { + val = (long long) 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_UpdateRecord *rec = self->record; + *((int *) ((size_t) rec + (size_t) member_offset)) = (int) val; + return 0; +} + static int set_str(_UpdateRecordObject *self, PyObject *value, void *member_offset) { @@ -388,6 +421,8 @@ static PyGetSetDef updaterecord_getsetters[] = { "List of UpdateReferences", &(list_convertors[0])}, {"collections", (getter)get_list, (setter)NULL, "List of UpdateCollections", &(list_convertors[1])}, + {"reboot_suggested", (getter)get_int, (setter)set_int, + "Suggested reboot", OFFSET(reboot_suggested)}, {NULL, NULL, NULL, NULL, NULL} /* sentinel */ }; diff --git a/src/updateinfo.c b/src/updateinfo.c index cdc4747..bef06f2 100644 --- a/src/updateinfo.c +++ b/src/updateinfo.c @@ -249,6 +249,7 @@ cr_updaterecord_copy(const cr_UpdateRecord *orig) rec->summary = cr_safe_string_chunk_insert(rec->chunk, orig->summary); rec->description = cr_safe_string_chunk_insert(rec->chunk, orig->description); rec->solution = cr_safe_string_chunk_insert(rec->chunk, orig->solution); + rec->reboot_suggested = orig->reboot_suggested; if (orig->references) { GSList *newlist = NULL; diff --git a/src/updateinfo.h b/src/updateinfo.h index 38883e0..2a69384 100644 --- a/src/updateinfo.h +++ b/src/updateinfo.h @@ -92,6 +92,7 @@ typedef struct { gchar *summary; /*!< Short summary */ gchar *description; /*!< Update description */ gchar *solution; /*!< Solution */ + gboolean reboot_suggested; /*!< Reboot suggested */ GSList *references; /*!< List of cr_UpdateReference */ GSList *collections;/*!< List of cr_UpdateCollection */ diff --git a/src/xml_dump_updateinfo.c b/src/xml_dump_updateinfo.c index fafe686..0beed96 100644 --- a/src/xml_dump_updateinfo.c +++ b/src/xml_dump_updateinfo.c @@ -165,6 +165,9 @@ cr_xml_dump_updateinforecord_internal(xmlNodePtr root, cr_UpdateRecord *rec) cr_xmlNewTextChild_c(update, NULL, BAD_CAST "description", BAD_CAST rec->description); cr_xmlNewTextChild_c(update, NULL, BAD_CAST "solution", BAD_CAST rec->solution); + if (rec->reboot_suggested) + xmlNewChild(update, NULL, BAD_CAST "reboot_suggested", NULL); + // References cr_xml_dump_updateinforecord_references(update, rec->references); diff --git a/src/xml_parser_updateinfo.c b/src/xml_parser_updateinfo.c index 5a2715a..3e458ec 100644 --- a/src/xml_parser_updateinfo.c +++ b/src/xml_parser_updateinfo.c @@ -58,6 +58,7 @@ typedef enum { STATE_PACKAGE, STATE_FILENAME, STATE_SUM, + STATE_UPDATERECORD_REBOOTSUGGESTED, STATE_REBOOTSUGGESTED, STATE_RESTARTSUGGESTED, // Not implemented STATE_RELOGINSUGGESTED, // Not implemented @@ -86,6 +87,7 @@ static cr_StatesSwitch stateswitches[] = { { STATE_UPDATE, "message", STATE_MESSAGE, 1 }, // NI { STATE_UPDATE, "references", STATE_REFERENCES, 0 }, { STATE_UPDATE, "pkglist", STATE_PKGLIST, 0 }, + { STATE_UPDATE, "reboot_suggested", STATE_UPDATERECORD_REBOOTSUGGESTED,0 }, { STATE_REFERENCES, "reference", STATE_REFERENCE, 0 }, { STATE_PKGLIST, "collection", STATE_COLLECTION, 0 }, { STATE_COLLECTION, "package", STATE_PACKAGE, 0 }, @@ -360,6 +362,12 @@ cr_start_handler(void *pdata, const char *element, const char **attr) package->sum_type = cr_checksum_type(val); break; + case STATE_UPDATERECORD_REBOOTSUGGESTED: + assert(pd->updateinfo); + assert(pd->updaterecord); + rec->reboot_suggested = TRUE; + break; + case STATE_REBOOTSUGGESTED: assert(pd->updateinfo); assert(pd->updaterecord); @@ -406,6 +414,7 @@ cr_end_handler(void *pdata, G_GNUC_UNUSED const char *element) case STATE_MODULE: case STATE_PKGLIST: case STATE_REBOOTSUGGESTED: + case STATE_UPDATERECORD_REBOOTSUGGESTED: // All elements with no text data and without need of any // post processing should go here break; -- 2.24.1 From d4fb876b4475c7ede4b49219229638bf32e9574d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= Date: Tue, 3 Dec 2019 09:32:18 +0100 Subject: [PATCH 2/3] Extend unit tests with reboot_suggested for UpdateRecord --- tests/python/tests/test_updateinfo.py | 6 ++++++ tests/python/tests/test_updaterecord.py | 5 +++++ tests/test_xml_parser_updateinfo.c | 8 ++++++++ tests/testdata/updateinfo_files/updateinfo_01.xml | 1 + tests/testdata/updateinfo_files/updateinfo_03.xml | 2 ++ 5 files changed, 22 insertions(+) diff --git a/tests/python/tests/test_updateinfo.py b/tests/python/tests/test_updateinfo.py index 727b707..7feaae9 100644 --- a/tests/python/tests/test_updateinfo.py +++ b/tests/python/tests/test_updateinfo.py @@ -36,6 +36,7 @@ class TestCaseUpdateInfo(unittest.TestCase): rec.summary = "summary" rec.description = "description" rec.solution = "solution" + rec.reboot_suggested = True ui.append(rec) @@ -57,6 +58,7 @@ class TestCaseUpdateInfo(unittest.TestCase): self.assertEqual(rec.summary, "summary") self.assertEqual(rec.description, "description") self.assertEqual(rec.solution, "solution") + self.assertEqual(rec.reboot_suggested, True) self.assertEqual(len(rec.references), 0) self.assertEqual(len(rec.collections), 0) @@ -92,6 +94,7 @@ class TestCaseUpdateInfo(unittest.TestCase): rec.summary = "summary" rec.description = "description" rec.solution = "solution" + rec.reboot_suggested = True ui.append(rec) xml = ui.xml_dump() @@ -111,6 +114,7 @@ class TestCaseUpdateInfo(unittest.TestCase): summary description solution + @@ -349,6 +353,7 @@ class TestCaseUpdateInfo(unittest.TestCase): rec.summary = "summary" rec.description = "description" rec.solution = "solution" + rec.reboot_suggested = True rec.append_collection(col) rec.append_reference(ref) @@ -372,6 +377,7 @@ class TestCaseUpdateInfo(unittest.TestCase): summary description solution + diff --git a/tests/python/tests/test_updaterecord.py b/tests/python/tests/test_updaterecord.py index 6777f04..7a1a191 100644 --- a/tests/python/tests/test_updaterecord.py +++ b/tests/python/tests/test_updaterecord.py @@ -32,6 +32,7 @@ class TestCaseUpdateRecord(unittest.TestCase): self.assertEqual(rec.severity, None) self.assertEqual(rec.summary, None) self.assertEqual(rec.description, None) + self.assertEqual(rec.reboot_suggested, 0) self.assertEqual(rec.solution, None) self.assertEqual(rec.references, []) self.assertEqual(rec.collections, []) @@ -60,6 +61,7 @@ class TestCaseUpdateRecord(unittest.TestCase): rec.severity = "severity" rec.summary = "summary" rec.description = "description" + rec.reboot_suggested = True rec.solution = "solution" rec.append_reference(ref) rec.append_collection(col) @@ -77,6 +79,7 @@ class TestCaseUpdateRecord(unittest.TestCase): self.assertEqual(rec.pushcount, "pushcount") self.assertEqual(rec.severity, "severity") self.assertEqual(rec.summary, "summary") + self.assertEqual(rec.reboot_suggested, True) self.assertEqual(rec.description, "description") self.assertEqual(rec.solution, "solution") self.assertEqual(len(rec.references), 1) @@ -115,6 +118,7 @@ class TestCaseUpdateRecord(unittest.TestCase): rec.summary = "summary" rec.description = "description" rec.solution = "solution" + rec.reboot_suggested = True xml = cr.xml_dump_updaterecord(rec) self.assertEqual(xml, @@ -130,6 +134,7 @@ class TestCaseUpdateRecord(unittest.TestCase): summary description solution + diff --git a/tests/test_xml_parser_updateinfo.c b/tests/test_xml_parser_updateinfo.c index 976922e..07ef50e 100644 --- a/tests/test_xml_parser_updateinfo.c +++ b/tests/test_xml_parser_updateinfo.c @@ -76,6 +76,7 @@ test_cr_xml_parse_updateinfo_01(void) g_assert_cmpstr(update->summary, ==, "summary_1"); g_assert_cmpstr(update->description, ==, "description_1"); g_assert_cmpstr(update->solution, ==, "solution_1"); + g_assert(update->reboot_suggested); g_assert_cmpint(g_slist_length(update->references), ==, 1); ref = update->references->data; @@ -137,6 +138,7 @@ test_cr_xml_parse_updateinfo_02(void) g_assert(!update->pushcount); g_assert(!update->severity); g_assert(!update->summary); + g_assert(!update->reboot_suggested); g_assert(!update->description); g_assert(!update->solution); @@ -186,6 +188,10 @@ test_cr_xml_parse_updateinfo_03(void) g_assert_cmpint(ret, ==, CRE_OK); g_assert_cmpint(g_slist_length(ui->updates), ==, 6); + + update = g_slist_nth_data(ui->updates, 2); + g_assert(!update->reboot_suggested); + update = g_slist_nth_data(ui->updates, 3); g_assert_cmpstr(update->from, ==, "errata@redhat.com"); @@ -195,6 +201,7 @@ test_cr_xml_parse_updateinfo_03(void) g_assert_cmpstr(update->id, ==, "RHEA-2012:0058"); g_assert_cmpstr(update->title, ==, "Gorilla_Erratum"); g_assert_cmpstr(update->description, ==, "Gorilla_Erratum"); + g_assert(update->reboot_suggested); update = g_slist_nth_data(ui->updates, 4); @@ -204,6 +211,7 @@ test_cr_xml_parse_updateinfo_03(void) 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(update->reboot_suggested); g_assert_cmpint(g_slist_length(update->references), ==, 0); diff --git a/tests/testdata/updateinfo_files/updateinfo_01.xml b/tests/testdata/updateinfo_files/updateinfo_01.xml index b757ef8..415140e 100644 --- a/tests/testdata/updateinfo_files/updateinfo_01.xml +++ b/tests/testdata/updateinfo_files/updateinfo_01.xml @@ -12,6 +12,7 @@ summary_1 description_1 solution_1 + True diff --git a/tests/testdata/updateinfo_files/updateinfo_03.xml b/tests/testdata/updateinfo_files/updateinfo_03.xml index ddbd99b..39dfbef 100644 --- a/tests/testdata/updateinfo_files/updateinfo_03.xml +++ b/tests/testdata/updateinfo_files/updateinfo_03.xml @@ -70,6 +70,7 @@ Gorilla_Erratum + True 1 @@ -87,6 +88,7 @@ Duck_Kangaro_Erratum description + coll_name1 -- 2.24.1 From c1ec192d14d751eed298ffff13fbbc76917d0b0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= Date: Thu, 9 Jan 2020 08:52:22 +0100 Subject: [PATCH 3/3] Switch updateinfo to explicitly include bool values (RhBug:1772466) Elements and both were previously outputed just as an empty element which meant they are true, this patch changes it to explicitly output: True. However we still don't output False values, in that case the element is simply omitted. https://bugzilla.redhat.com/show_bug.cgi?id=1772466 --- src/xml_dump_updateinfo.c | 4 ++-- tests/python/tests/test_updateinfo.py | 10 +++++----- tests/python/tests/test_updaterecord.py | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/xml_dump_updateinfo.c b/src/xml_dump_updateinfo.c index 0beed96..6974285 100644 --- a/src/xml_dump_updateinfo.c +++ b/src/xml_dump_updateinfo.c @@ -61,7 +61,7 @@ cr_xml_dump_updatecollectionpackages(xmlNodePtr collection, GSList *packages) } if (pkg->reboot_suggested) - xmlNewChild(package, NULL, BAD_CAST "reboot_suggested", NULL); + xmlNewChild(package, NULL, BAD_CAST "reboot_suggested", "True"); } } @@ -166,7 +166,7 @@ cr_xml_dump_updateinforecord_internal(xmlNodePtr root, cr_UpdateRecord *rec) cr_xmlNewTextChild_c(update, NULL, BAD_CAST "solution", BAD_CAST rec->solution); if (rec->reboot_suggested) - xmlNewChild(update, NULL, BAD_CAST "reboot_suggested", NULL); + xmlNewChild(update, NULL, BAD_CAST "reboot_suggested", "True"); // References cr_xml_dump_updateinforecord_references(update, rec->references); diff --git a/tests/python/tests/test_updateinfo.py b/tests/python/tests/test_updateinfo.py index 7feaae9..f5becfe 100644 --- a/tests/python/tests/test_updateinfo.py +++ b/tests/python/tests/test_updateinfo.py @@ -114,7 +114,7 @@ class TestCaseUpdateInfo(unittest.TestCase): summary description solution - + True @@ -207,7 +207,7 @@ class TestCaseUpdateInfo(unittest.TestCase): foo.rpm abcdef - + True @@ -293,7 +293,7 @@ class TestCaseUpdateInfo(unittest.TestCase): foo.rpm abcdef - + True @@ -377,7 +377,7 @@ class TestCaseUpdateInfo(unittest.TestCase): summary description solution - + True @@ -388,7 +388,7 @@ class TestCaseUpdateInfo(unittest.TestCase): foo.rpm abcdef - + True diff --git a/tests/python/tests/test_updaterecord.py b/tests/python/tests/test_updaterecord.py index 7a1a191..e8bc789 100644 --- a/tests/python/tests/test_updaterecord.py +++ b/tests/python/tests/test_updaterecord.py @@ -134,7 +134,7 @@ class TestCaseUpdateRecord(unittest.TestCase): summary description solution - + True -- 2.24.1